libdyson-wg/ha-dyson

Dyson Pure Cool error "This entity is unavailable" but "Night Mode" works.

Opened this issue · 16 comments

Hi everyone. I manage to add my Dyson Pure Cool (438) using credentials from libdyson-main, but then I get a "This entity is unavailable" error for the fan. What is strange is that if I toggle "Night Mode", I do see the change happening on the device, which indicates that the credentials are correct and the connection is established. See the screenshot below.

Some additional information:

  • The air quality entities (PM2.5, PM10 etc) are not added to HA.
  • I tried adding and removing the device/integration few times.
  • Tried hard rebooting in between steps.
  • Tried moving to this repo from the no longer maintained shenxn/ha-dyson repo (and used the instructions here on how to migrate).
  • I previously managed to have everything working with a previous Dyson Pure Cool (same model). Unfortunately, I had to return that one because it had a physical problem. I removed that device from my Dyson account before trying any of this. With this new Dyson, I never managed to get it to work.
  • Home Assistant version is 2023.6.1 (but I have been having this issue since before upgrading)
  • Dyson Integration version is v0.20.1

Any help would be greatly appreciated!

Screenshot 2023-06-11 at 20 09 23

Hey, thanks for sharing your issues. Just for my information, your previous device (same model) worked fine before, but your replacement doesn't work. And the replacement didn't work whether you were using shenxn's repo or this one?

Hey @dotvezz. Thanks for the reply.

your previous device (same model) worked fine before, but your replacement doesn't work.

That is correct.

And the replacement didn't work whether you were using shenxn's repo or this one?

With the old one, I only tried shenxn, and it did work without any issues (could control the fan, and got the right air quality statistics as entities). With the new one, I tried both shenxn and this one, and there were no appreciable differences, i.e. neither one worked.

Considering it is quite unlikely that the two machines would respond differently (I updated the firmware on both as soon as I got them, and that was a few days from each other) I suspect the issue might have to do with some remaining configuration from the old machine?

Hi,

I'm getting the same issue.

Home Assistant version 2023.06.2 running on Home Assistant OS version 10.2 on a Raspberry Pi 4. A slight quirk of my setup is my Home Assistant Pi is in the 10.0.3.0/24 subnet and the fan is on the 10.0.4.0/24 subnet (but the home assistant pi has a NIC in 10.0.4.0/24) - but reading the logs it doesn't seem to be related.

I'm using v0.20.1 of dyson_local and v0.19.1 of dyson_cloud installed via HACS.

dyson_cloud finds the fan after a restart. dyson_local prompts for configuration with the host of the fan input manually. The fan entity appears but as unavailable; switches for both continuous monitoring and night mode appear and work.

The fan is a refurbished TP04. I had previously set it up with my-email+dyson@gmail.com but the integration said the account didn't exist; I created a new account my-email@gmail.com and moved the fan to it, whereupon the integration would set up correctly and find the fan.

The relevant logs seem to be:

Logger: homeassistant.components.fan
Source: custom_components/dyson_local/vendor/libdyson/dyson_pure_cool.py:130
Integration: Fan (documentation, issues)
First occurred: 11:32:50 (2 occurrences)
Last logged: 11:32:50

Error adding entities for domain fan with platform dyson_local
Error while setting up dyson_local platform for fan
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 471, in async_add_entities
    await asyncio.gather(*tasks)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 749, in _async_add_entity
    await entity.add_to_platform_finish()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 850, in add_to_platform_finish
    self.async_write_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 590, in async_write_ha_state
    self._async_write_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 657, in _async_write_ha_state
    attr.update(self.extra_state_attributes or {})
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/dyson_local/fan.py", line 231, in extra_state_attributes
    ATTR_ANGLE_LOW: self.angle_low,
                    ^^^^^^^^^^^^^^
  File "/config/custom_components/dyson_local/fan.py", line 220, in angle_low
    return self._device.oscillation_angle_low
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/dyson_local/vendor/libdyson/dyson_pure_cool.py", line 130, in oscillation_angle_low
    return int(self._get_field_value(self._status, "osal"))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'

and

This error originated from a custom integration.

Logger: homeassistant
Source: custom_components/dyson_local/vendor/libdyson/dyson_pure_cool.py:130
Integration: Dyson Local (documentation, issues)
First occurred: 11:32:50 (2 occurrences)
Last logged: 11:32:50

Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 970, in _async_registry_updated
    self.async_write_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 590, in async_write_ha_state
    self._async_write_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 657, in _async_write_ha_state
    attr.update(self.extra_state_attributes or {})
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/dyson_local/fan.py", line 231, in extra_state_attributes
    ATTR_ANGLE_LOW: self.angle_low,
                    ^^^^^^^^^^^^^^
  File "/config/custom_components/dyson_local/fan.py", line 220, in angle_low
    return self._device.oscillation_angle_low
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/dyson_local/vendor/libdyson/dyson_pure_cool.py", line 130, in oscillation_angle_low
    return int(self._get_field_value(self._status, "osal"))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'

and

Logger: homeassistant.components.sensor
Source: custom_components/dyson_local/vendor/libdyson/dyson_pure_cool.py:48
Integration: Sensor (documentation, issues)
First occurred: 11:32:50 (1 occurrences)
Last logged: 11:32:50

Error while setting up dyson_local platform for sensor
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 320, in _async_setup_platform
    await asyncio.shield(task)
  File "/config/custom_components/dyson_local/sensor.py", line 68, in async_setup_entry
    if device.carbon_filter_life is None:
       ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/dyson_local/vendor/libdyson/dyson_pure_cool.py", line 48, in carbon_filter_life
    return int(filter_life)
           ^^^^^^^^^^^^^^^^
TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'

Subscribing to 438/serial/status/current gives:
{"msg":"CURRENT-STATE","time":"2023-06-15T13:58:35.000Z","mode-reason":"LAPP","state-reason":"NONE","dial":"OFF","rssi":"47","product-state":{"fpwr":"ON","fdir":"ON","auto":"OFF","fnsp":"0008","qtar":"0001","sltm":"OFF","oson":"OFF","nmod":"OFF","rhtm":"ON","fnst":"FAN","filf":"0000","ercd":"NONE","wacd":"NONE"},"scheduler":{"srsc":"0000","dstv":"0000","tzid":"0000"}}

and
{"msg":"ENVIRONMENTAL-CURRENT-SENSOR-DATA","time":"2023-06-15T13:58:35.000Z","data":{"tact":"2977","hact":"0044","pm25":"0010","pm10":"0007","va10":"0004","noxl":"0037","p25r":"0011","p10r":"0011","sltm":"OFF"}}

Thanks

Okay, so a quick and dirty hack is just adding a check for whether the values are None, and returning None (instead of trying to convert None to an integer).

Fan speed/power/direction become controllable, and the air quality sensors report. It looks like it's hanging on the setup because it's trying to convert None into an integer for three of the attributes. None is there because for whatever reason the MQTT payload from the fan doesn't include osal (oscillation min angle), osau (oscillation max angle), and cflr (carbon filter life). This is annoying as setting the oscillation angles from home assistant was one of the reasons I bought the thing in the first place.

This has some.. unintended consequences including losing control of oscillation (unless nonsense values are hard-coded into the enable_oscillation function). I'll try and find a less hacky solution next week. Another slightly odd aspect is that values hardcoded in appear to be applied when fan.set_angle is called (ignoring the attributes with the service, but this is to be expected as these are defaults applied if the current value for high/low angle is None). It looks to me like the fan still obeys the command, but for whatever reason is not reporting it back.

Hi @jamesmorganti! Thank you! Looking forward to what you come up with next week. In the meantime, just wanted to confirm that I looked at the logs, and I am seeing the same errors as you are.

@myhome301 can you see what firmware version your 438 is running through the app? I've just tried with a 520 (desk pure cool) which is exposing the missing attributes. The firmwares are:

  • Desk fan 520: ECG2PF.02.05.002.0018
  • Tower fan 438: ECG2PF.02.04.010.0039

And the desk fan reports everything properly in home assistant without any hacks. Given both our fans are refurbished from Dyson, I'm wondering if (hoping!) Dyson is shipping refurbished units on an old firmware that doesn't expose the oscillation angle/carbon filter lifespan which is where the integration is tripping up. If that's the case, getting the newest firmware (which I gather can take some time..) is probably the best way forward.

I've sent a message to Dyson on WhatsApp so hopefully they'll get back to me with an answer.

Failing that, I suppose the best alternative is to write a new class representing a rotation/filter attribute-less fan and extending the logic that chooses which class to use.

@jamesmorganti Indeed, my firmware is also ECG2PF.02.04.010.0039. If I untoggle "Auto-update software" a message appears after a second stating "Update scheduled", which seems to suggest that an update is available (but then why didn't it auto update?). Thanks for following up on this!

Aha, so your issues are also related to the None to int conversions? There's actually a PR (#27) that @nhulsch opened and I still need to test and merge.

In the meantime, on my side I'm working on an overhaul of the sensor discovery process that should eliminate these errors and be more flexible future devices as part of the effort for #24. Short term hopefully #27 improves things though when I finally get it through.

@myhome301 thanks - I've spoken to Dyson and annoyingly this fan doesn't seem to support setting an angle via MQTT regardless of the software version. It will be going back for a different one! Setting the angle only appeared to work because it was enabling oscillation and I'd previously set it to oscillate at roughly the same angle I'd provided in call service 🤦🏻

@dotvezz Yeah it seems to be. I'm working over the weekend but I'll pull the code in #27 and have a go at testing myself in the week.

Hi @jamesmorganti . Just wondering if there are any updates on this? I am wondering whether I should return the unit, and not being able to control it from Home Assistant is a variable in that decision. Thank you!

@myhome301 and @jamesmorganti, I just released v0.21.0 which I'm hoping addresses this! Let me know if you have any issues.

Hi @dotvezz. Thanks a lot for your work! Unfortunately, I am seeing the same issue as before. See logs below. Perhaps the issue is that the units affected by this issue are not correctly identified? My firmware is still ECG2PF.02.04.010.0039 (still couldn't update it to a newer version).

Logger: homeassistant.components.sensor
Source: custom_components/dyson_local/vendor/libdyson/dyson_pure_cool.py:48
Integration: Sensor (documentation, issues)
First occurred: 07:13:47 (1 occurrences)
Last logged: 07:13:47

Error while setting up dyson_local platform for sensor
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 320, in _async_setup_platform
await asyncio.shield(task)
File "/config/custom_components/dyson_local/sensor.py", line 68, in async_setup_entry
if device.carbon_filter_life is None:
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/dyson_local/vendor/libdyson/dyson_pure_cool.py", line 48, in carbon_filter_life
return int(filter_life)
^^^^^^^^^^^^^^^^
TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'

Logger: homeassistant.components.fan
Source: custom_components/dyson_local/vendor/libdyson/dyson_pure_cool.py:130
Integration: Fan (documentation, issues)
First occurred: 07:13:47 (2 occurrences)
Last logged: 07:13:47

Error adding entities for domain fan with platform dyson_local
Error while setting up dyson_local platform for fan
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 471, in async_add_entities
await asyncio.gather(*tasks)
File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 749, in _async_add_entity
await entity.add_to_platform_finish()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 850, in add_to_platform_finish
self.async_write_ha_state()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 590, in async_write_ha_state
self._async_write_ha_state()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 657, in _async_write_ha_state
attr.update(self.extra_state_attributes or {})
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/dyson_local/fan.py", line 231, in extra_state_attributes
ATTR_ANGLE_LOW: self.angle_low,
^^^^^^^^^^^^^^
File "/config/custom_components/dyson_local/fan.py", line 220, in angle_low
return self._device.oscillation_angle_low
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/dyson_local/vendor/libdyson/dyson_pure_cool.py", line 130, in oscillation_angle_low
return int(self._get_field_value(self._status, "osal"))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'

@myhome301 Been a while since I followed up here. The recent updates haven't done much to address this, but I wonder if any of them have miraculously fixed your issue.

If not, let me know and I'll take a look this weekend for you.

I'm seeing the described behaviour/problem using the 1.2.0 release of a few hours ago so it does not seem to be fixed yet.

As in the OP, my HA only shows the 2 switches Continuous Monitoring and Night Mode; the latter changes the fan in/out of Night Mode no problem (the connection info is correct). Nothing else shows and the fan entity itself says This entity is unavailable..

Going by the errors for fields osal, osau, cflr and hflr (all due to attempting to convert a NoneType to int), I tried some quick and dirty changes locally:

  1. Changed to
        if filter_life == "INV" or filter_life is None:
  1. Changed
    return int(self._get_field_value(self._status, "hflr"))
    function to be similar to cflr function:
        filter_life = self._get_field_value(self._status, "hflr")
        if filter_life is None:
            return None
        return int(filter_life)
  1. Changed
    return int(self._get_field_value(self._status, "osal"))
    to fall back to the minimum allowed value:
        return int(self._get_field_value(self._status, "osal") or 5)
  1. Change
    return int(self._get_field_value(self._status, "osau"))
    to fall back to the maximum allowed value:
        return int(self._get_field_value(self._status, "osau") or 355)

This enabled the fan entity in HA and I can now turn it on and off. Humidity, PM2.5, PM10, Temperature seem fine. Aside from the filter life, VOC and NO2 are also Unknown for some reason...
EDIT: just took a moment for them to come online, VOC and NO2 have values now. Filter stays Unknown.

It does not take the angles on the Set Angle function at all but this was already established earlier. I don't know what angles it uses, nor can oscillation be turned off again.

The integration does not seem to have any option to control/set the fan mode/direction (blow/filter only) or speed (auto, 1-10).

same issue here, with a TP04 temperature and humidity not working. They were working with shenx integration until 2023.6 i think. I was hoping that switching t this new one will fix the issue, but the problem with the same symptoms remain