Open richlawson opened 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.
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.
@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.
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
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.
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.
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!
@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.
@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.
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)?
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.
Interesting, interesting! That could be super helpful. I'll dig around a bit.
Hi, did yo have any further progress on this?
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!
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 😅
@lgladdy thanks, that mqtt dump is exactly what I needed!
hoping this enhancement is figured out good luck
Just checking if this is worked on?
Any progress here?
@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!
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!