Closed Bascht74 closed 3 years ago
Hmm that is weird, on my install this works and it's also in the code the same way as elapsed and finish time:
if 'remainingTime' in device_state:
sensors.append(MieleTimeSensor(hass, device, 'remainingTime'))
if 'startTime' in device_state:
sensors.append(MieleTimeSensor(hass, device, 'startTime'))
if 'elapsedTime' in device_state:
sensors.append(MieleTimeSensor(hass, device, 'elapsedTime'))
What you can try is replacing sensor.py with the following code :
import logging
from datetime import timedelta, datetime
from homeassistant.helpers.entity import Entity
from custom_components.miele import DOMAIN as MIELE_DOMAIN, DATA_DEVICES
PLATFORMS = ['miele']
_LOGGER = logging.getLogger(__name__)
ALL_DEVICES = []
def _map_key(key):
if key == 'status':
return 'Status'
elif key == 'programType':
return 'Program Type'
elif key == 'programPhase':
return 'Program Phase'
elif key == 'targetTemperature':
return 'Target Temperature'
elif key == 'temperature':
return 'Temperature'
elif key == 'remainingTime':
return 'Remaining Time'
elif key == 'elapsedTime':
return 'Elapsed Time'
elif key == 'startTime':
return 'Start Time'
def _to_seconds(time_array):
if len(time_array) == 3:
return time_array[0] * 3600 + time_array[1] * 60 + time_array[2]
elif len(time_array) == 2:
return time_array[0] * 3600 + time_array[1] * 60
else:
return 0
# pylint: disable=W0612
def setup_platform(hass, config, add_devices, discovery_info=None):
global ALL_DEVICES
devices = hass.data[MIELE_DOMAIN][DATA_DEVICES]
for k, device in devices.items():
device_state = device['state']
sensors = []
if 'status' in device_state:
sensors.append(MieleStatusSensor(hass, device, 'status'))
if 'targetTemperature' in device_state:
for i, val in enumerate(device_state['targetTemperature']):
sensors.append(MieleTemperatureSensor(hass, device, 'targetTemperature', i))
if 'temperature' in device_state:
for i, val in enumerate(device_state['temperature']):
sensors.append(MieleTemperatureSensor(hass, device, 'temperature', i))
if 'remainingTime' in device_state:
_LOGGER.debug(' trying to add remaining time, device_state is : {}'.format(device_state))
sensors.append(MieleTimeSensor(hass, device, 'remainingTime'))
if 'startTime' in device_state:
sensors.append(MieleTimeSensor(hass, device, 'startTime'))
if 'elapsedTime' in device_state:
sensors.append(MieleTimeSensor(hass, device, 'elapsedTime'))
add_devices(sensors)
ALL_DEVICES = ALL_DEVICES + sensors
def update_device_state():
for device in ALL_DEVICES:
device.async_schedule_update_ha_state(True)
class MieleRawSensor(Entity):
def __init__(self, hass, device, key):
self._hass = hass
self._device = device
self._key = key
@property
def device_id(self):
"""Return the unique ID for this sensor."""
return self._device['ident']['deviceIdentLabel']['fabNumber']
@property
def unique_id(self):
"""Return the unique ID for this sensor."""
return self.device_id + '_' + self._key
@property
def name(self):
"""Return the name of the sensor."""
ident = self._device['ident']
result = ident['deviceName']
if len(result) == 0:
return ident['type']['value_localized'] + ' ' + _map_key(self._key)
else:
return result + ' ' + _map_key(self._key)
@property
def state(self):
"""Return the state of the sensor."""
return self._device['state'][self._key]['value_raw']
async def async_update(self):
if not self.device_id in self._hass.data[MIELE_DOMAIN][DATA_DEVICES]:
_LOGGER.debug('Miele device disappeared: {}'.format(self.device_id))
else:
self._device = self._hass.data[MIELE_DOMAIN][DATA_DEVICES][self.device_id]
class MieleStatusSensor(MieleRawSensor):
def __init(self, client, device, key):
pass
@property
def state(self):
"""Return the state of the sensor."""
result = self._device['state']['status']['value_localized']
if result == None:
result = self._device['state']['status']['value_raw']
return result
@property
def device_state_attributes(self):
"""Attributes."""
device_state = self._device['state']
attributes = {}
if 'programType' in device_state:
attributes['programType'] = device_state['programType']['value_localized']
attributes['rawProgramType'] = device_state['programType']['value_raw']
if 'programPhase' in device_state:
attributes['programPhase'] = device_state['programPhase']['value_localized']
attributes['rawProgramPhase'] = device_state['programPhase']['value_raw']
if 'dryingStep' in device_state:
attributes['dryingStep'] = device_state['dryingStep']['value_localized']
attributes['rawDryingStep'] = device_state['dryingStep']['value_raw']
if 'spinningSpeed' in device_state:
attributes['spinningSpeed'] = device_state['spinningSpeed']['value_localized']
attributes['rawSpinningSpeed'] = device_state['spinningSpeed']['value_raw']
if 'ventilationStep' in device_state:
attributes['ventilationStep'] = device_state['ventilationStep']['value_localized']
attributes['rawVentilationStep'] = device_state['ventilationStep']['value_raw']
if 'plateStep' in device_state:
plate_steps = 1
for plateStep in device_state['plateStep']:
attributes['plateStep'+str(plate_steps)] = plateStep['value_localized']
attributes['rawPlateStep'+str(plate_steps)] = plateStep['value_raw']
plate_steps += 1
if 'ecoFeedback' in device_state and device_state['ecoFeedback'] is not None:
if 'currentWaterConsumption' in device_state['ecoFeedback']:
attributes['currentWaterConsumption'] = device_state['ecoFeedback']['currentWaterConsumption']['value']
attributes['currentWaterConsumptionUnit'] = device_state['ecoFeedback']['currentWaterConsumption']['unit']
if 'currentEnergyConsumption' in device_state['ecoFeedback']:
attributes['currentEnergyConsumption'] = device_state['ecoFeedback']['currentEnergyConsumption']['value']
attributes['currentEnergyConsumptionUnit'] = device_state['ecoFeedback']['currentEnergyConsumption']['unit']
if 'waterForecast' in device_state['ecoFeedback']:
attributes['waterForecast'] = device_state['ecoFeedback']['waterForecast']
if 'energyForecast' in device_state['ecoFeedback']:
attributes['energyForecast'] = device_state['ecoFeedback']['energyForecast']
# Programs will only be running of both remainingTime and elapsedTime indicate
# a value > 0
if 'remainingTime' in device_state and 'elapsedTime' in device_state:
remainingTime = _to_seconds(device_state['remainingTime'])
elapsedTime = _to_seconds(device_state['elapsedTime'])
if 'startTime' in device_state:
startTime = _to_seconds(device_state['startTime'])
else:
startTime = 0
# Calculate progress
if (elapsedTime + remainingTime) == 0:
attributes['progress'] = None
else:
attributes['progress'] = round(elapsedTime / (elapsedTime + remainingTime) * 100, 1)
# Calculate end time
if remainingTime == 0:
attributes['finishTime'] = None
else:
now = datetime.now()
attributes['finishTime'] = (now + timedelta(seconds=startTime) + timedelta(seconds=remainingTime)).strftime('%H:%M')
# Calculate start time
if startTime == 0:
now = datetime.now()
attributes['kickoffTime'] = (now - timedelta(seconds=elapsedTime)).strftime('%H:%M')
else:
now = datetime.now()
attributes['kickoffTime'] = (now + timedelta(seconds=startTime)).strftime('%H:%M')
return attributes
class MieleTimeSensor(MieleRawSensor):
def __init(self, hass, device, key):
pass
@property
def state(self):
"""Return the state of the sensor."""
state_value = self._device['state'][self._key]
if len(state_value) != 2:
return None
else:
return '{:02d}:{:02d}'.format(state_value[0], state_value[1])
class MieleTemperatureSensor(Entity):
def __init__(self, hass, device, key, index):
self._hass = hass
self._device = device
self._key = key
self._index = index
"""Fix for assertion error by removing None from device"""
value_raw = self._device['state'][self._key][self._index]['value_raw']
value_localized = self._device['state'][self._key][self._index]['value_localized']
if value_raw == "-32768":
self._device['state'][self._key][self._index]['value_raw'] = 0
if value_localized == "null":
self._device['state'][self._key][self._index]['value_localized'] = 0
@property
def device_id(self):
"""Return the unique ID for this sensor."""
return self._device['ident']['deviceIdentLabel']['fabNumber']
@property
def unique_id(self):
"""Return the unique ID for this sensor."""
return self.device_id + '_' + self._key + '_{}'.format(self._index)
@property
def name(self):
"""Return the name of the sensor."""
ident = self._device['ident']
result = ident['deviceName']
if len(result) == 0:
return '{} {} {}'.format(ident['type']['value_localized'], _map_key(self._key), self._index)
else:
return '{} {} {}'.format(result, _map_key(self._key), self._index)
@property
def state(self):
"""Return the state of the sensor."""
state_value = self._device['state'][self._key][self._index]['value_raw']
if state_value == -32768:
return None
else:
return state_value / 100
@property
def unit_of_measurement(self):
"""Return the unit of measurement of this entity, if any."""
if self._device['state'][self._key][self._index]['unit'] == 'Celsius':
return "°C"
elif self._device['state'][self._key][self._index]['unit'] == 'Fahrenheit':
return "°F"
@property
def device_class(self):
return "temperature"
async def async_update(self):
if not self.device_id in self._hass.data[MIELE_DOMAIN][DATA_DEVICES]:
_LOGGER.debug(' Miele device disappeared: {}'.format(self.device_id))
else:
self._device = self._hass.data[MIELE_DOMAIN][DATA_DEVICES][self.device_id]
this should put a logging output of : trying to add remaining time, device_state is
if this line is present it does try to add it.
You can also try to get additional log output by adding this to configuration.yaml :
logger:
default: critical
logs:
custom_components.miele: debug
also i wouldn't share your client_id and client_secret add github ;-)!
also i wouldn't share your client_id and client_secret add github ;-)!
I didn't do that completly (lot of xxxxxxxxx). Or should I delete everything?
client_id: 7cc5649a-af44-4ee3-bf74-b0axxxxxxxxx
client_secret: pZdgX2qXQo2MmXExL3aDSR7bTTxxxxxxxxx
language: de
Trying right now. Thanks for your help.
I replaced the sensor.py
code in /config/custom_components/miele/
with your new code.
Result so far:
But i see nothing in the log about it.
logger:
default: critical
logs:
custom_components.miele: debug
How did you install this software? Could you please try to install this by HACS (manually add this repo for now, I'm currently waiting to get included in the dafault) and try again? Because what you showed me happens I cannot explain this with the current code...
You have devices like _start and _elapsed but these never get made by the software, however _start_time does get made. But that's not what I see in your screenshots. If you want you could also send me your miele token privately and I can check what happens if I run your devices on my test environment.
How did you install this software? Could you please try to install this by HACS (manually add this repo for now, I'm currently waiting to get included in the dafault) and try again?
I did via HACS (manual added repro, as I remember). I will delete it via HACS, clean up the files and re-install again...
miele:
client_id: 7cc5649a-af44-4ee3-bf74-....
client_secret: pZdgX2qXQo2MmXE....
language: de
Configuration invalid
Invalid config for [miele]: [language] is an invalid option for [miele]. Check: miele->miele->language. (See /config/configuration.yaml, line 21).
5. Leave out the language setting right now.
miele: client_id: 7cc5649a-af44-4ee3-bf74-.... client_secret: pZdgX2qXQo2MmXE....
6. Checked configuration again. Now: valid
7. Restarted
8. Opened the configurator, logged in at Miele.
9. Entities are there, so is the remaining time.
I don't know how, but doing everything from scratsch it is there:
Washing Machine Remaining Time sensor.washing_machine_remaining_time Miele@home
So it works now! Thanks for your help.
Two Questions:
1. How do I set the language right?
2. Are you planing to list the devices at devices as well? Right now I can only see entities.
Sebastian
First question: nevermind. RTFM ... lang insteat of language...
Hi Sebastian, possibly in the future. My first priority is fixing a bug where some devices will not show up if they did not have a valid value when home assistant started. At the same time, I'm also working on making the installation simpler for everyone! Currently trying to get added to the HACS default repo. If you have it working now and want to help you can go over: https://github.com/hacs/default/pull/718 to review and then approve this integration to be added to the HACS default repo ;-)!
Hi there,
I tried the new integration, but I don’t get entites for the remaining time. Is there something wront or am I looking at the wrong spot…?
here is the dishwasher:
configuration.yaml: miele:
Log:
As you can see the remainint time is there in Miele API, but the integration doesn't create an entity for it. I have no clue... Maybe you could look into that problem. Thx
Sebastian