libdyson-wg / ha-dyson

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

Enhancement: Empty water tank sensor for humidifiers #34

Open richlawson opened 1 year ago

richlawson commented 1 year ago

Would it be possible possible to add the ability to add a sensor for when the water tank is empty on humidifiers? It would be great to be able to automate notifications for this.

Someone had raised this issue in the past in the upstream repo: https://github.com/shenxn/ha-dyson/issues/129

I took a look at https://github.com/libdyson-wg/libdyson-neon/blob/main/libdyson/dyson_pure_humidify_cool.py (as well as any relevant issues), and I didn't see any mention/support. I think something would probably need to be added there, so I can open up an issue in that project if it makes more sense.

I also did some checking to see if there's any sort of API documentation or anything for Dyson, and I wasn't able to find anything. Was everything discovered for this integration by monitoring network communication locally, or did I completely miss something?

By the way, I just switched over today from shenxn/ha-dyson, and everything went very smoothly. Thanks for forking and updating this!

dotvezz commented 1 year ago

Oh yeah, this is a good enhancement for sure. I don't have any of these devices but I'll dig around in the Android app's code to see if I can figure out the mqtt sensor label for the water tank.

dotvezz commented 1 year ago

Okay, did some digging and it appears to send a fault code tnke when the tank is empty. I'll look into supporting this into the integration.

dotvezz commented 1 year ago

@richlawson come to think of it, if you own one of the humidifier devices then you could help a lot here!

I have a tool called dyson-mqtt-listen. You can grab the release here: https://github.com/dotvezz/dyson-mqtt-listen/releases/tag/v1.0.0

If you happen to have Go installed, you can just use it to install.

go install github.com/dotvezz/dyson-mqtt-listen/cmd/dyson-mqtt-listen@v1.0.0

Once you've downloaded or installed the binary, run it with the -address, -ssid, and -wifi-password flags using the values from your stickers. It should look something like

# if you used `go install`
dyson-mqtt-listen -address "192.168.1.207" -ssid "DYSON-NM7-US-REA2128R-475" -wifi-password "zxcvasdf" 

# if you downloaded the linux binary
chmod +r ./dyson-mqtt-listen
./dyson-mqtt-listen -address "192.168.1.207" -ssid "DYSON-NM7-US-REA2128R-475" -wifi-password "zxcvasdf" 

# if you downloaded the macOS binary
chmod +r ./dyson-mqtt-listen-darwin
./dyson-mqtt-listen -address "192.168.1.207" -ssid "DYSON-NM7-US-REA2128R-475" -wifi-password "zxcvasdf" 

# if you downloaded the Windows binary
dyson-mqtt-listen.exe -address "192.168.1.207" -ssid "DYSON-NM7-US-REA2128R-475" -wifi-password "zxcvasdf" 

Let it run for a few minutes. Hopefully you see something like the following:

00:46:35: Connected to device...
00:46:35: Subscribed to 475/NM7-US-REA2128R/status/current
00:46:35: Subscribed to 475/NM7-US-REA2128R/command
00:46:35: Press Ctrl+C to exit.
00:46:49|475/NM7-US-REA2128R/status/current: {"msg":"ENVIRONMENTAL-CURRENT-SENSOR-DATA","time":"2023-06-18T04:46:50.000Z","data":{"tact":"2930","hact":"0062","pact":"0004","vact":"0000","sltm":"OFF"}}
00:47:19|475/NM7-US-REA2128R/status/current: {"msg":"ENVIRONMENTAL-CURRENT-SENSOR-DATA","time":"2023-06-18T04:47:20.000Z","data":{"tact":"2930","hact":"0062","pact":"0004","vact":"0000","sltm":"OFF"}}

Once you see the mqtt data flowing, pull out the water tank, empty it, and put it back in. Let it keep running for a few minutes, then if you can paste the results in a gist or something for me to analyze, that would be AWESOME.

dotvezz commented 1 year ago

Ahh, and if your device didn't ship with the wifi password stickers, you can use the flags -serial, -password, and -device. The values for those flags can be found using the get_devices.py script in libdyson-neon: https://github.com/libdyson-wg/libdyson-neon/blob/main/get_devices.py

richlawson commented 1 year ago

Hi @dotvezz , thanks for the clear instructions for how to get everything running. I ran the get_devices.py script a long time ago, but I lost track of where I stored the information, since I didn't receive those stickers.

Here's a regularly-reported status message:

11:35:38|358/C4C-US-NMA*****/status/current: {"msg":"ENVIRONMENTAL-CURRENT-SENSOR-DATA","time":"0000-00-00T00:00:00.000Z","data":{"tact":"2942","hact":"0055","pm25":"0004","pm10":"0002","va10":"0015","noxl":"0000","p25r":"0005","p10r":"0005","sltm":"OFF"}}

This was where it was briefly running the humidifier and then stopped due to the tank not having enough water:

11:44:16|358/C4C-US-NMA*****/status/current: {"msg":"STATE-CHANGE","time":"0000-00-00T00:00:00.000Z","mode-reason":"PUI","state-reason":"MODE","product-state":{"fpwr":["ON","ON"],"auto":["ON","ON"],"oscs":["OFF","IDLE"],"oson":["OFF","OFF"],"nmod":["OFF","OFF"],"rhtm":["ON","ON"],"fnst":["OFF","OFF"],"ercd":["14II","14II"],"wacd":["NONE","NONE"],"nmdv":["0004","0004"],"fnsp":["AUTO","AUTO"],"bril":["0002","0002"],"corf":["OFF","OFF"],"cflr":["INV","INV"],"hflr":["0056","0056"],"cflt":["NONE","NONE"],"hflt":["GCOM","GCOM"],"sltm":["OFF","OFF"],"osal":["0180","0180"],"osau":["0180","0180"],"ancp":["0090","0090"],"hume":["HUMD","HUMD"],"haut":["OFF","OFF"],"humt":["0070","0070"],"rect":["0045","0045"],"msta":["OFF","OFF"],"clcr":["CLNO","CLNO"],"cdrr":["0060","0060"],"cltr":["0661","0661"],"wath":["0675","0675"],"psta":["CLNG","CLNG"],"fdir":["ON","ON"]},"scheduler":{"srsc":"0000000000000000","dstv":"0001","tzid":"0001"}}

That said, this is based on what you suggested. It basically doesn't run when it's waiting for the tank to be filled (displays an icon) unless you turn off the humidifier portion.

Instead I slowly filled the tank and kept filling it up a little bit to where it would start running, and I'm going to continue running until it runs out.

In case it's helpful, here's a snippet of what it output as I was turning it off, filling up the tank a little bit more, and then running it again, until it started running:

11:46:27|358/C4C-US-NMA*****/status/current: {"msg":"STATE-CHANGE","time":"0000-00-00T00:00:00.000Z","mode-reason":"PUI","state-reason":"MODE","product-state":{"fpwr":["ON","OFF"],"auto":["ON","ON"],"oscs":["IDLE","OFF"],"oson":["OFF","OFF"],"nmod":["OFF","OFF"],"rhtm":["ON","ON"],"fnst":["OFF","OFF"],"ercd":["14II","14II"],"wacd":["NONE","NONE"],"nmdv":["0004","0004"],"fnsp":["AUTO","AUTO"],"bril":["0002","0002"],"corf":["OFF","OFF"],"cflr":["INV","INV"],"hflr":["0056","0056"],"cflt":["NONE","NONE"],"hflt":["GCOM","GCOM"],"sltm":["OFF","OFF"],"osal":["0180","0180"],"osau":["0180","0180"],"ancp":["0090","0090"],"hume":["HUMD","HUMD"],"haut":["OFF","OFF"],"humt":["0070","0070"],"rect":["0045","0045"],"msta":["OFF","OFF"],"clcr":["CLNO","CLNO"],"cdrr":["0060","0060"],"cltr":["0661","0661"],"wath":["0675","0675"],"psta":["CLNG","CLNG"],"fdir":["ON","ON"]},"scheduler":{"srsc":"0000000000000000","dstv":"0001","tzid":"0001"}}
11:46:28|358/C4C-US-NMA*****/status/current: {"msg":"STATE-CHANGE","time":"0000-00-00T00:00:00.000Z","mode-reason":"PUI","state-reason":"MODE","product-state":{"fpwr":["OFF","OFF"],"auto":["ON","ON"],"oscs":["OFF","ON"],"oson":["OFF","OFF"],"nmod":["OFF","OFF"],"rhtm":["ON","ON"],"fnst":["OFF","OFF"],"ercd":["14II","14II"],"wacd":["NONE","NONE"],"nmdv":["0004","0004"],"fnsp":["AUTO","AUTO"],"bril":["0002","0002"],"corf":["OFF","OFF"],"cflr":["INV","INV"],"hflr":["0056","0056"],"cflt":["NONE","NONE"],"hflt":["GCOM","GCOM"],"sltm":["OFF","OFF"],"osal":["0180","0180"],"osau":["0180","0180"],"ancp":["0090","0090"],"hume":["HUMD","HUMD"],"haut":["OFF","OFF"],"humt":["0070","0070"],"rect":["0045","0045"],"msta":["OFF","OFF"],"clcr":["CLNO","CLNO"],"cdrr":["0060","0060"],"cltr":["0661","0661"],"wath":["0675","0675"],"psta":["CLNG","CLNG"],"fdir":["ON","ON"]},"scheduler":{"srsc":"0000000000000000","dstv":"0001","tzid":"0001"}}
11:46:28|358/C4C-US-NMA*****/status/current: {"msg":"STATE-CHANGE","time":"0000-00-00T00:00:00.000Z","mode-reason":"PUI","state-reason":"MODE","product-state":{"fpwr":["OFF","OFF"],"auto":["ON","ON"],"oscs":["ON","ON"],"oson":["OFF","OFF"],"nmod":["OFF","OFF"],"rhtm":["ON","ON"],"fnst":["OFF","OFF"],"ercd":["14II","14II"],"wacd":["NONE","NONE"],"nmdv":["0004","0004"],"fnsp":["AUTO","AUTO"],"bril":["0002","0002"],"corf":["OFF","OFF"],"cflr":["INV","INV"],"hflr":["0056","0056"],"cflt":["NONE","NONE"],"hflt":["GCOM","GCOM"],"sltm":["OFF","OFF"],"osal":["0180","0180"],"osau":["0180","0180"],"ancp":["0090","0090"],"hume":["HUMD","HUMD"],"haut":["OFF","OFF"],"humt":["0070","0070"],"rect":["0045","0045"],"msta":["OFF","OFF"],"clcr":["CLNO","CLNO"],"cdrr":["0060","0060"],"cltr":["0661","0661"],"wath":["0675","0675"],"psta":["CLNG","OFF"],"fdir":["ON","ON"]},"scheduler":{"srsc":"0000000000000000","dstv":"0001","tzid":"0001"}}
11:46:31|358/C4C-US-NMA*****/status/current: {"msg":"STATE-CHANGE","time":"0000-00-00T00:00:00.000Z","mode-reason":"PUI","state-reason":"MODE","product-state":{"fpwr":["OFF","OFF"],"auto":["ON","ON"],"oscs":["ON","OFF"],"oson":["OFF","OFF"],"nmod":["OFF","OFF"],"rhtm":["ON","ON"],"fnst":["OFF","OFF"],"ercd":["14II","14II"],"wacd":["NONE","NONE"],"nmdv":["0004","0004"],"fnsp":["AUTO","AUTO"],"bril":["0002","0002"],"corf":["OFF","OFF"],"cflr":["INV","INV"],"hflr":["0056","0056"],"cflt":["NONE","NONE"],"hflt":["GCOM","GCOM"],"sltm":["OFF","OFF"],"osal":["0180","0180"],"osau":["0180","0180"],"ancp":["0090","0090"],"hume":["HUMD","HUMD"],"haut":["OFF","OFF"],"humt":["0070","0070"],"rect":["0045","0045"],"msta":["OFF","OFF"],"clcr":["CLNO","CLNO"],"cdrr":["0060","0060"],"cltr":["0661","0661"],"wath":["0675","0675"],"psta":["OFF","OFF"],"fdir":["ON","ON"]},"scheduler":{"srsc":"0000000000000000","dstv":"0001","tzid":"0001"}}
11:46:38|358/C4C-US-NMA*****/status/current: {"msg":"ENVIRONMENTAL-CURRENT-SENSOR-DATA","time":"0000-00-00T00:00:00.000Z","data":{"tact":"2944","hact":"0055","pm25":"0004","pm10":"0002","va10":"0017","noxl":"0000","p25r":"0005","p10r":"0005","sltm":"OFF"}}
11:47:05|358/C4C-US-NMA*****/status/current: {"msg":"STATE-CHANGE","time":"0000-00-00T00:00:00.000Z","mode-reason":"PUI","state-reason":"MODE","product-state":{"fpwr":["OFF","ON"],"auto":["ON","ON"],"oscs":["OFF","OFF"],"oson":["OFF","OFF"],"nmod":["OFF","OFF"],"rhtm":["ON","ON"],"fnst":["OFF","FAN"],"ercd":["14II","14II"],"wacd":["NONE","NONE"],"nmdv":["0004","0004"],"fnsp":["AUTO","AUTO"],"bril":["0002","0002"],"corf":["OFF","OFF"],"cflr":["INV","INV"],"hflr":["0056","0056"],"cflt":["NONE","NONE"],"hflt":["GCOM","GCOM"],"sltm":["OFF","OFF"],"osal":["0180","0180"],"osau":["0180","0180"],"ancp":["0090","0090"],"hume":["HUMD","HUMD"],"haut":["OFF","OFF"],"humt":["0070","0070"],"rect":["0045","0045"],"msta":["OFF","HUMD"],"clcr":["CLNO","CLNO"],"cdrr":["0060","0060"],"cltr":["0661","0661"],"wath":["0675","0675"],"psta":["OFF","OFF"],"fdir":["ON","ON"]},"scheduler":{"srsc":"0000000000000000","dstv":"0001","tzid":"0001"}}
11:47:05|358/C4C-US-NMA*****/status/current: {"msg":"STATE-CHANGE","time":"0000-00-00T00:00:00.000Z","mode-reason":"PUI","state-reason":"MODE","product-state":{"fpwr":["ON","ON"],"auto":["ON","ON"],"oscs":["OFF","OFF"],"oson":["OFF","OFF"],"nmod":["OFF","OFF"],"rhtm":["ON","ON"],"fnst":["FAN","FAN"],"ercd":["14II","14II"],"wacd":["NONE","NONE"],"nmdv":["0004","0004"],"fnsp":["AUTO","AUTO"],"bril":["0002","0002"],"corf":["OFF","OFF"],"cflr":["INV","INV"],"hflr":["0056","0056"],"cflt":["NONE","NONE"],"hflt":["GCOM","GCOM"],"sltm":["OFF","OFF"],"osal":["0180","0180"],"osau":["0180","0180"],"ancp":["0090","0090"],"hume":["HUMD","HUMD"],"haut":["OFF","OFF"],"humt":["0070","0070"],"rect":["0045","0045"],"msta":["HUMD","HUMD"],"clcr":["CLNO","CLNO"],"cdrr":["0060","0060"],"cltr":["0661","0661"],"wath":["0675","0675"],"psta":["OFF","CLNG"],"fdir":["ON","ON"]},"scheduler":{"srsc":"0000000000000000","dstv":"0001","tzid":"0001"}}
11:47:08|358/C4C-US-NMA*****/status/current: {"msg":"STATE-CHANGE","time":"0000-00-00T00:00:00.000Z","mode-reason":"PUI","state-reason":"MODE","product-state":{"fpwr":["ON","ON"],"auto":["ON","ON"],"oscs":["OFF","OFF"],"oson":["OFF","OFF"],"nmod":["OFF","OFF"],"rhtm":["ON","ON"],"fnst":["FAN","FAN"],"ercd":["14II","14II"],"wacd":["NONE","NONE"],"nmdv":["0004","0004"],"fnsp":["AUTO","AUTO"],"bril":["0002","0002"],"corf":["OFF","OFF"],"cflr":["INV","INV"],"hflr":["0056","0056"],"cflt":["NONE","NONE"],"hflt":["GCOM","GCOM"],"sltm":["OFF","OFF"],"osal":["0180","0180"],"osau":["0180","0180"],"ancp":["0090","0090"],"hume":["HUMD","HUMD"],"haut":["OFF","OFF"],"humt":["0070","0070"],"rect":["0045","0045"],"msta":["HUMD","HUMD"],"clcr":["CLNO","CLNO"],"cdrr":["0060","0060"],"cltr":["0661","0661"],"wath":["0675","0675"],"psta":["CLNG","CLNG"],"fdir":["ON","ON"]},"scheduler":{"srsc":"0000000000000000","dstv":"0001","tzid":"0001"}}
11:47:08|358/C4C-US-NMA*****/status/current: {"msg":"ENVIRONMENTAL-CURRENT-SENSOR-DATA","time":"0000-00-00T00:00:00.000Z","data":{"tact":"2944","hact":"0054","pm25":"0004","pm10":"0002","va10":"0016","noxl":"0000","p25r":"0005","p10r":"0005","sltm":"OFF"}}
11:47:38|358/C4C-US-NMA*****/status/current: {"msg":"ENVIRONMENTAL-CURRENT-SENSOR-DATA","time":"0000-00-00T00:00:00.000Z","data":{"tact":"2944","hact":"0054","pm25":"0004","pm10":"0003","va10":"0019","noxl":"0000","p25r":"0005","p10r":"0005","sltm":"OFF"}}

I didn't see any instances of tnke, unfortunately.

I'll let you know when it runs out of water and send the message.

dotvezz commented 1 year ago

Even if we don't see tnke, this is still really good information! It's always valuable to see little quirks in different devices' MQTT data, and it can help debug other issues down the line.

I see your ercd value is 14II which I don't see in the Android app at all. It just so happens my HP04 constantly reports an ercd value of 32U2 which also doesn't show up in the Android app. There's definitely some work to do in understanding/decoding this field.

richlawson commented 1 year ago

It just ran out of water. This is the corresponding state change:

12:08:30|358/C4C-US-NMA*****/status/current: {"msg":"STATE-CHANGE","time":"0000-00-00T00:00:00.000Z","mode-reason":"PUI","state-reason":"MODE","product-state":{"fpwr":["ON","ON"],"auto":["ON","ON"],"oscs":["OFF","IDLE"],"oson":["OFF","OFF"],"nmod":["OFF","OFF"],"rhtm":["ON","ON"],"fnst":["FAN","OFF"],"ercd":["14II","14II"],"wacd":["NONE","NONE"],"nmdv":["0004","0004"],"fnsp":["AUTO","AUTO"],"bril":["0002","0002"],"corf":["OFF","OFF"],"cflr":["INV","INV"],"hflr":["0056","0056"],"cflt":["NONE","NONE"],"hflt":["GCOM","GCOM"],"sltm":["OFF","OFF"],"osal":["0180","0180"],"osau":["0180","0180"],"ancp":["0090","0090"],"hume":["HUMD","HUMD"],"haut":["OFF","OFF"],"humt":["0070","0070"],"rect":["0045","0045"],"msta":["HUMD","OFF"],"clcr":["CLNO","CLNO"],"cdrr":["0060","0060"],"cltr":["0661","0661"],"wath":["0675","0675"],"psta":["CLNG","CLNG"],"fdir":["ON","ON"]},"scheduler":{"srsc":"0000000000000000","dstv":"0001","tzid":"0001"}}

In case it helps, here are the 2 status messages sent out immediately before and afterward, along with a repeat of the state change to provide the context:

12:07:38|358/C4C-US-NMA*****/status/current: {"msg":"ENVIRONMENTAL-CURRENT-SENSOR-DATA","time":"0000-00-00T00:00:00.000Z","data":{"tact":"2952","hact":"0055","pm25":"0004","pm10":"0003","va10":"0028","noxl":"0000","p25r":"0005","p10r":"0005","sltm":"OFF"}}
12:08:08|358/C4C-US-NMA*****/status/current: {"msg":"ENVIRONMENTAL-CURRENT-SENSOR-DATA","time":"0000-00-00T00:00:00.000Z","data":{"tact":"2952","hact":"0055","pm25":"0004","pm10":"0002","va10":"0029","noxl":"0000","p25r":"0005","p10r":"0005","sltm":"OFF"}}
12:08:30|358/C4C-US-NMA*****/status/current: {"msg":"STATE-CHANGE","time":"0000-00-00T00:00:00.000Z","mode-reason":"PUI","state-reason":"MODE","product-state":{"fpwr":["ON","ON"],"auto":["ON","ON"],"oscs":["OFF","IDLE"],"oson":["OFF","OFF"],"nmod":["OFF","OFF"],"rhtm":["ON","ON"],"fnst":["FAN","OFF"],"ercd":["14II","14II"],"wacd":["NONE","NONE"],"nmdv":["0004","0004"],"fnsp":["AUTO","AUTO"],"bril":["0002","0002"],"corf":["OFF","OFF"],"cflr":["INV","INV"],"hflr":["0056","0056"],"cflt":["NONE","NONE"],"hflt":["GCOM","GCOM"],"sltm":["OFF","OFF"],"osal":["0180","0180"],"osau":["0180","0180"],"ancp":["0090","0090"],"hume":["HUMD","HUMD"],"haut":["OFF","OFF"],"humt":["0070","0070"],"rect":["0045","0045"],"msta":["HUMD","OFF"],"clcr":["CLNO","CLNO"],"cdrr":["0060","0060"],"cltr":["0661","0661"],"wath":["0675","0675"],"psta":["CLNG","CLNG"],"fdir":["ON","ON"]},"scheduler":{"srsc":"0000000000000000","dstv":"0001","tzid":"0001"}}
12:08:38|358/C4C-US-NMA*****/status/current: {"msg":"ENVIRONMENTAL-CURRENT-SENSOR-DATA","time":"0000-00-00T00:00:00.000Z","data":{"tact":"2952","hact":"0054","pm25":"0005","pm10":"0003","va10":"0028","noxl":"0000","p25r":"0006","p10r":"0005","sltm":"OFF"}}
12:09:08|358/C4C-US-NMA*****/status/current: {"msg":"ENVIRONMENTAL-CURRENT-SENSOR-DATA","time":"0000-00-00T00:00:00.000Z","data":{"tact":"2952","hact":"0054","pm25":"0006","pm10":"0004","va10":"0026","noxl":"0000","p25r":"0007","p10r":"0007","sltm":"OFF"}}

Thank you for working on this!

dotvezz commented 11 months ago

@Paul-McNeice this thread covers one of the questions I had for you. As far as I can tell, there doesn't seem to be a way to read water level over MQTT. Can you confirm whether that's the case or if I'm just missing something?

edit: Ohhh and I was curious about that ercd value - I haven't been able to figure that one out.

Paul-McNeice commented 11 months ago

@dotvezz there's no way to read the water level - just the fault that's raised when it's empty as you've already discovered.

I don't remember ever doing anything with ercd I'm afraid.

dotvezz commented 11 months ago

there's no way to read the water level - just the fault that's raised when it's empty as you've already discovered.

Thanks for the confirm - one thing that I've struggled to figure out is how to read that fault code. Digging in decompiled Kotlin only gets me so far. Is there any chance the empty error isn't available through MQTT, but it actually requires an internet connection to pull from appapi like the robot cleaning maps (and I think fan sensor history)?

Paul-McNeice commented 11 months ago

You should be able to get it by looking at MQTT messages on the status/faults topic. I think there's CURRENT-FAULTS which is sent when the device is powered on, and FAULTS-CHANGE when something happens - e.g. tank empty - which gives you the old and new values for each type of fault.

dotvezz commented 11 months ago

Interesting, interesting! That could be super helpful. I'll dig around a bit.

RC-Thoughts commented 7 months ago

Hi, did yo have any further progress on this?

lgladdy commented 6 months ago

status/faults messages contain a string like:

{
  "msg": "CURRENT-FAULTS",
  "time": "2023-12-20T15:57:48.000Z",
  "product-errors": {
    "amf1": "OK",
    ...a bunch more...
    "uled": "OK"
  },
  "product-warnings": {
    "fltr": "OK",
    "tnke": "FAIL",
    "tnkp": "OK",
    "cldu": "OK",
    "etwd": "OK"
  },
  "module-errors": {
    "szme": "OK",
    ...a bunch more...
    "szav": "OK"
  },
  "module-warnings": {
    "srnk": "OK",
    ...a bunch more...
    "nwss": "OK"
  }
}

product-warnings contains tnke which is set to FAIL when empty.

I'm happy to try and figure out how to add support for this and open a PR, but will need a bit of time to figure out where the mqtt subscriptions happen in the first place and how to add one!

lgladdy commented 6 months ago

I think to support this, we'll need to subscribe to the faults event channel. I threw together adding a _faults_topic which is also subscribed to on_connect and populated that data into a new self._faults_data = {} assuming that the sensor could then be added to the specific humidifier device. But, that did at least show the data coming in the debug logs.

I'm not sure if it's safe to just always subscribe to status/faults on every device, even though none of the other devices would read it (at least initially?) - it looks like it would need a much bigger refactor of dyson_device.py in order to only subscribe to that channel on specific devices. [Edit: Although, we could add the product-warnings attribute fltr as a sensor too for other fans, assuming that's the filter reaching end of capacity]

Also, the most reliable way to get a new set of CURRENT-FAULTS is to open the Dyson app, so they must be sending a command which triggers that being sent to subscribers. Maybe REQUEST-CURRENT-FAULTS exists?

Also not sure if/how to make a new self._faults_data_available = threading.Event() property as I'm new to this library and don't really understand what that's doing 😅

dotvezz commented 6 months ago

@lgladdy thanks, that mqtt dump is exactly what I needed!

jangshik commented 5 months ago

hoping this enhancement is figured out good luck

RC-Thoughts commented 3 months ago

Just checking if this is worked on?

RC-Thoughts commented 2 days ago

Any progress here?

dotvezz commented 15 hours ago

@RC-Thoughts Hey! I haven't forgotten about this, but time has been precious lately (my toddler has been toddlering). Between life and work, I've mostly been handling compatibility fixes for new Home Assistant versions over here.

That said, I promise this is still something I want to do.

Edit: And of course, if anyone wants to help contribute, that would be awesome too!