Miele@home, miele@mobile component

One more thing: you need to

pip3 install requests_oauthlib

I’ll try to write a more complete installation guide later this week, if time permits.

Now it works thatnks, the oauthlib was for some reason already installed. I see that a whole device is in one sensor, having on/off as a state and the rest as attributes. Is this the correct way? Is it possible to get a history about the attributes and display them easily (the most important thing I guess is to show a remaining time counter in home assistant) or should each value be exposed as an own sensor/binary_sensor?

Glad you got it up and running, @Roemer.

As I said, the current is a little bit of a hack. Here’s what I am thinking though: each device should be exposed as miele.<device-name>. That entity would expose all the information that the Miele developer documentation has under ident. In addition, information available from state should be exposed like this:

  • signalInfo, signalFailure, signalDoor: individual binary_sensors
  • *temperature: individual sensors showing the temperature with unit of measurement
  • *time: individual sensors showing the indicated time value
  • programType, programPhase: sensors showing program information, once it has been properly documented by Miele

In the meantime, you should be able to do all of that via template sensors. For example:

binary_sensor:
  - platform: template
    sensors:
      dishwasher_door:
        friendly_name: "Dishwasher door"
        value_template:  {{ states.sensor.dishwasher.attributes.signalDoor }}

should expose the state of the dishwasher door for sensor.dishwasheras separate attribute, if I didn’t make any mistake.

Sounds great how you plan to expose the devices / sensors. I’m getting btw some errors from time to time:

Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/src/app/homeassistant/helpers/entity.py", line 210, in async_update_ha_state
    state = self.state
  File "/config/custom_components/sensor/miele.py", line 213, in state
    state = DeviceState(self._home_device['state']['status']['value_raw'])
  File "/usr/local/lib/python3.6/enum.py", line 291, in __call__
    return cls.__new__(cls, value)
  File "/usr/local/lib/python3.6/enum.py", line 533, in __new__
    return cls._missing_(value)
  File "/usr/local/lib/python3.6/enum.py", line 546, in _missing_
    raise ValueError("%r is not a valid %s" % (value, cls.__name__))
ValueError: 10 is not a valid DeviceState

It is probably when the dishwasher is open as that is the only thing we did today :wink:

Okay, I did some refactoring today and pushed that to GitHub. The change does require some configuration change:

miele:
  client_id: <client id received from Miele>
  client_secret: <client id received from Miele>
  lang: <either en or de>

This should expose binary_sensors and sensors as described above.

The error you were reporting should be gone because that mapping was removed for now. However, I’ve never seen a state of 10 with any of my devices, so it would in general be interesting to see what it means. But that has to wait for when that mapping gets back into the code.

Works great :+1:
Although it is adding quite some sensors and most are only interested in a few. Maybe it should be configurable which sensors are loaded like in https://community.home-assistant.io/t/writing-a-component-for-luxtronik-heatpumps?

State 10 is “On” on my dishwasher:

"state": {
    "status": {
    "key_localized": "Status",
    "value_raw": 10,
    "value_localized": "Ein"
    },

Edit: That is when the dishwasher is just opened and the LEDs are on. When i actively turn it on, the state changes to 3: Programm choosen

Yes, it’s pretty verbose now. I think I’ll merge programType, programPhase and the device state as they seem to be tightly coupled.

Not sure about the best way to filter though. Perhaps there’s also an option to hide some sensors via the customizer…

I see that you reworked it quite a bit. Will install the newest version and test it. Yesterday the error log was flodded with the error:

2018-08-22 15:08:56 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
File “/usr/src/app/homeassistant/helpers/entity.py”, line 210, in async_update_ha_state
state = self.state
File “/config/custom_components/sensor/miele.py”, line 163, in state
state_value = self._device[‘state’][self._key][self._index][‘value_raw’]

and

2018-08-22 15:09:02 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved

Traceback (most recent call last):
File “/usr/src/app/homeassistant/helpers/entity.py”, line 210, in async_update_ha_state
state = self.state
File “/usr/src/app/homeassistant/components/binary_sensor/init.py”, line 81, in state
return STATE_ON if self.is_on else STATE_OFF
File “/config/custom_components/binary_sensor/miele.py”, line 66, in is_on
return bool(self._device[‘state’][self._key])
KeyError: ‘signalInfo’

with KeyError ‘signalInfo’, ‘signalDoor’ and ‘signalFailure’.

I will observe if this happens with the new version as well.

Interesting. The responses from the cloud service are pretty static in their structure. If there was a sensor for e.g. signalInfo, that value should always be present.

Said that, it might be possible that some outage or connection error resulted in this downstream error. If so, I would suspect those errors to go away due to the recent changes.

Let me know how things go.

Hmm the error started when the devices switched from “Off” (Aus) to “Not Connected” (Nicht Verbunden) (state_raw: 255). When I manually get the data with the API the devices still show “Off”. I checked the token, it should still be valid. Do you know how this can happen? Also turning a device off didn’t change a thing, still “Not connected” but with my own API call, they work correctly.

The code polls the Miele service every five seconds. So a little bit of a delay would be expected when compared to directly calling the API. If you set the log level to debug by adding the following to your config, you should the some output whenever a request to the cloud service is made.

logger:
  default: info
  logs:
    custom_components.miele.miele_at_home: debug

I did notice one device (connected via zigbee) to switch to “Not connected” from time to time, but that’s consistent with what I see in the mobile app. Plus, I’ve seen this before, so it didn’t come as a surprise.

They are “Not connected” for almost a day now and never went back to “off”. I now deleted the miele-token-cache, restarted HA, logged in into miele again and now the devices are back to “off”. I will observe this an check if this happens again (this time it happened after 18 hours after logging in).

Sounds as if the OAuth token expired. I’ll have a look later to see if this can be properly simulated. Did you see any other messages in the log? The device request should fail with Unauthorized in that case.

Also, if that happens again could you try to use the token from the cache file?

No other messages in the log. The tokens are valid for about 1 month (according to the unixtime that was in the file). Yes, next time I see this I’ll try the token from the cache file in a manual api call.

I believe token refresh should work properly now.

I also added ‘progress’ and ‘finishTime’ as attributes to status. For now, both can be extracted into distinct sensors by using a template sensor as described above.

Need to replace the custom attributes with something homegrown. But it’s a start…

2 Likes

Wow nice :slight_smile:
I think I know why my devices suddenly got a not connected:
I generated a new token with my other script. I guess that this token replaced the old one and therefore Home Assistant could not connect to it anymore.
Are you also planning on adding kind of “events”, like when a programm is finished? Or should this be done with automations / scripts?

Many thanks for driving this development. I have copied the files to customs_components, installed requests_oauthlib and added the following to my configuration.yaml:

sensor:

  • platform: miele
    client_id: <client_id>
    client_secret: <client_secret>
    lang: en

When pressing ‘Check config’ in HA, the wait icon appears but there is never a response.

I have anyways restarted HA. It works but there is no link to Miele shown. Also, I have the following text in the log file:

File “/srv/homeassistant/lib/python3.5/site-packages/aiohttp/helpers.py”, line 462, in log
for key, value in fmt_info:
File “/srv/homeassistant/lib/python3.5/site-packages/aiohttp/helpers.py”, line 454, in
for key, method in self._methods)
File “/srv/homeassistant/lib/python3.5/site-packages/aiohttp/helpers.py”, line 412, in _format_a
ip = request.remote
File “aiohttp_helpers.pyx”, line 32, in aiohttp._helpers.reify.get
File “aiohttp_helpers.pyx”, line 26, in aiohttp._helpers.reify.get
File “/srv/homeassistant/lib/python3.5/site-packages/aiohttp/web_request.py”, line 343, in remote
peername = self.transport.get_extra_info(‘peername’)
File “/usr/lib/python3.5/asyncio/sslproto.py”, line 306, in get_extra_info
return self._ssl_protocol._get_extra_info(name, default)
File “/usr/lib/python3.5/asyncio/sslproto.py”, line 546, in _get_extra_info
return self._transport.get_extra_info(name, default)
AttributeError: ‘NoneType’ object has no attribute ‘get_extra_info’

Any ideas on what can be wrong?