libdyson-wg / ha-dyson

Home Assistant custom integration for Wi-Fi connected Dyson devices
MIT License
208 stars 23 forks source link

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

Open myhome301 opened 1 year ago

myhome301 commented 1 year ago

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:

Any help would be greatly appreciated!

Screenshot 2023-06-11 at 20 09 23
dotvezz commented 1 year ago

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?

myhome301 commented 1 year ago

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?

jamesmorganti commented 1 year ago

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

jamesmorganti commented 1 year ago

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.

myhome301 commented 1 year ago

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.

jamesmorganti commented 1 year ago

@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:

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.

myhome301 commented 1 year ago

@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!

dotvezz commented 1 year ago

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.

jamesmorganti commented 1 year ago

@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.

myhome301 commented 1 year ago

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!

dotvezz commented 1 year ago

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

myhome301 commented 1 year ago

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'

dotvezz commented 9 months ago

@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.

Omar007 commented 9 months ago

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..

Omar007 commented 9 months ago

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 https://github.com/libdyson-wg/ha-dyson/blob/3c729d8e7c4968867e4d5ce908824f7c2729742f/custom_components/dyson_local/vendor/libdyson/dyson_pure_cool.py#L46 to
        if filter_life == "INV" or filter_life is None:
  2. Changed https://github.com/libdyson-wg/ha-dyson/blob/3c729d8e7c4968867e4d5ce908824f7c2729742f/custom_components/dyson_local/vendor/libdyson/dyson_pure_cool.py#L53 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)
  3. Changed https://github.com/libdyson-wg/ha-dyson/blob/3c729d8e7c4968867e4d5ce908824f7c2729742f/custom_components/dyson_local/vendor/libdyson/dyson_pure_cool.py#L130 to fall back to the minimum allowed value:
        return int(self._get_field_value(self._status, "osal") or 5)
  4. Change https://github.com/libdyson-wg/ha-dyson/blob/3c729d8e7c4968867e4d5ce908824f7c2729742f/custom_components/dyson_local/vendor/libdyson/dyson_pure_cool.py#L135 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).

fgonza2 commented 9 months ago

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