Open xxcite opened 3 years ago
I can confirm this issue.
AFAIK: Philips released a new firmware version which installed without user interaction. My last FW version was 62.1 the new FW version is 64.3 You can check your FW version by selecting your air purifyer in the app -> wrench symbol top right corner -> scroll down and click "diagnostics via e-mail" it will create an e-mail (but not send it) where you can find "Firmware Version".
If anybody could give me any hint how to decode the new interaction. Help would be much appreciated.
My router supports packet capture and exporting to wireshark compatible file type. But i have no idea what to do from there on.
Best regards, Peter
TL;DR: Proposed hotfix at the end.
Unfortunately i have no aircleaner remaining with FW 62.1, the FW update on the last one started while i was starting troubleshooting hours ago (that's why i know the old FW was 62.1) so i have no way to know how the messages looked like while everything was working. However i can compare airctrl to the smartphone app.
In advance, please note the last ip.addr block of my devices:
Using airctrl to change the mode (/sys/dev/control) does work. Getting the new status does not work (/sys/dev/status). Airctrl does send /sys/dev/status without token and never gets an answer with corresponding MessageID. Successful control commands marked dark green, unsuccessful status commands marked red.
Comparing the behaviour to the smartphone app, the status request is sent with token but there is again no answer with corresponding MessageID. I get the feeling the problem is: "the aircleaner simply does not respond to status requests but instead answers to really old status requests" ... notice those "Retransmissions". To me it looks like Philips screwed up some queue handling... but again i have no aircleaner with old firmware to compare to.
If somebody wants to see the same packet snapshot sorted by time, starting with the first Message with MessageID 638 it looks like this:
I also noticed the aircleaner is no longer listed as "MICO" in my router but instead "mxchip".
I propose to implement a hotfix solution that, regarding /sys/dev/status, ignores the MessageID but instead accepts any message containing /sys/dev/status (and maybe /sys/dev/info).
Best regards, Peter
Fortunately, I blocked internet access for the cleaner some weeks ago and I still have the FW 62.1. I have never done such a network analysis, but if you could step me through, I would like to provide the data for the old firmware.
What ever you do, do not post the package capture file itself to the internet, it contains ANYTHING transmitted by WLAN in the regarding timeframe.
Best regards, Peter
P.S.: I really hope you don't hit a roadblock at step 1
I have the same error from yesterday. AC3829/50
airctrl --ipaddr 192.168.0.10 --protocol coap Unexpected error:'NoneType' object has no attribute 'payload' Give up on message From None, To ('192.168.0.10', 5683), CON-61742, GET-None, [Uri-Path: sys, Uri-Path: dev, Uri-Path: status, Observe: 0, ] No payload
I think philips updated firmware and something was changed.
All right, I did this packet sniffing, thanks for this awsome tutorial! Sorry, that it took some days, i was a little bit busy and needed to reset my linux :/
Here my snapshot of the sync
if you require further information please give me feedback :)
My snapshot of the sync
I have the same error from yesterday. AC3829/50
airctrl --ipaddr 192.168.0.10 --protocol coap Unexpected error:'NoneType' object has no attribute 'payload' Give up on message From None, To ('192.168.0.10', 5683), CON-61742, GET-None, [Uri-Path: sys, Uri-Path: dev, Uri-Path: status, Observe: 0, ] No payload
I think philips updated firmware and something was changed.
Yes, indeed, my AC1214/10 started to show the same error, right after performing the firmware update (WiFi WPA3).
I've been in the same situation, on the new firmware and I lost local control most of the time (it would occasionally work), so I took a closer look. It seems the requests are timing out so increasing the hard-coded timeouts to 10s in coap_client (and adding a timeout argument on line 177) restores operation for me.
I've been in the same situation, on the new firmware and I lost local control most of the time (it would occasionally work), so I took a closer look. It seems the requests are timing out so increasing the hard-coded timeouts to 10s in coap_client (and adding a timeout argument on line 177) restores operation for me.
Can you show what did you added?
The first couple of lines were just some trailing whitespace which was triggering syntastic, but the remainder is the relevant part:
index 9d5b142..d2f76eb 100644
--- a/pyairctrl/coap_client.py
+++ b/pyairctrl/coap_client.py
@@ -83,15 +83,15 @@ class CoAPAirClient(HTTPAirClientBase):
def __del__(self):
# TODO call a close method explicitly instead
if self.response:
- self.client.cancel_observing(self.response, True)
- self.client.stop()
+ self.client.cancel_observing(self.response, True)
+ self.client.stop()
def _create_coap_client(self, host, port):
return HelperClient(server=(host, port))
def _sync(self):
self.syncrequest = binascii.hexlify(os.urandom(4)).decode("utf8").upper()
- resp = self.client.post("/sys/dev/sync", self.syncrequest, timeout=5)
+ resp = self.client.post("/sys/dev/sync", self.syncrequest, timeout=10)
if resp:
self.client_key = resp.payload
else:
@@ -145,7 +145,7 @@ class CoAPAirClient(HTTPAirClientBase):
try:
request = self.client.mk_request(defines.Codes.GET, path)
request.observe = 0
- self.response = self.client.send_request(request, None, 2)
+ self.response = self.client.send_request(request, None, 10)
encrypted_payload = self.response.payload
decrypted_payload = self._decrypt_payload(encrypted_payload)
except WrongDigestException:
@@ -174,7 +174,7 @@ class CoAPAirClient(HTTPAirClientBase):
}
}
encrypted_payload = self._encrypt_payload(json.dumps(payload))
- response = self.client.post(path, encrypted_payload)
+ response = self.client.post(path, encrypted_payload, timeout=10)
if self.debug:
print(response)
return response.payload == '{"status":"success"}'
Ideally, I'd suggest using a defined constant but I thought I'd see what people thought before proposing something more concrete.
The first couple of lines were just some trailing whitespace which was triggering syntastic, but the remainder is the relevant part:
index 9d5b142..d2f76eb 100644 --- a/pyairctrl/coap_client.py +++ b/pyairctrl/coap_client.py @@ -83,15 +83,15 @@ class CoAPAirClient(HTTPAirClientBase): def __del__(self): # TODO call a close method explicitly instead if self.response: - self.client.cancel_observing(self.response, True) - self.client.stop() + self.client.cancel_observing(self.response, True) + self.client.stop() def _create_coap_client(self, host, port): return HelperClient(server=(host, port)) def _sync(self): self.syncrequest = binascii.hexlify(os.urandom(4)).decode("utf8").upper() - resp = self.client.post("/sys/dev/sync", self.syncrequest, timeout=5) + resp = self.client.post("/sys/dev/sync", self.syncrequest, timeout=10) if resp: self.client_key = resp.payload else: @@ -145,7 +145,7 @@ class CoAPAirClient(HTTPAirClientBase): try: request = self.client.mk_request(defines.Codes.GET, path) request.observe = 0 - self.response = self.client.send_request(request, None, 2) + self.response = self.client.send_request(request, None, 10) encrypted_payload = self.response.payload decrypted_payload = self._decrypt_payload(encrypted_payload) except WrongDigestException: @@ -174,7 +174,7 @@ class CoAPAirClient(HTTPAirClientBase): } } encrypted_payload = self._encrypt_payload(json.dumps(payload)) - response = self.client.post(path, encrypted_payload) + response = self.client.post(path, encrypted_payload, timeout=10) if self.debug: print(response) return response.payload == '{"status":"success"}'
Ideally, I'd suggest using a defined constant but I thought I'd see what people thought before proposing something more concrete.
I ping airtctl 10 times and 2 times I got Unexpected error:'NoneType' object has no attribute 'payload'
I changed to 15 sec timeout and 10 times ping airtctl and got 0 error.
Thanks.
Both changes seem to go into the right direction (thanks!!). Nevertheless, I found more timeouts than before. I use the connection to (a) change the level based on time of day and (b) track air quality via FHEM. As I send the change command three times in a row, that seems to be more stable. Tracking misses many data points, unfortunately.
FYI .. timeout with 60 does not help on my new Model: AC2889/10 (AC2889/10) Device Version: 1.0.7
Same problem here with the AC2939/10 and Firmware 64.3.
My AC2889/10 still only responds less than half of the time after changing timeouts to 60 seconds. When it does respond, the time taken seems to be totally random - occasionally it's almost immediate, other times anything up to the timeout limit. Most of my testing is done when the device is "off", and I'm wondering what else it's doing that would prevent it responding to a status inquiry.
[type] Type: AC2889
[modelid] ModelId: AC2889/10
[swversion] Version: 1.0.7
[range] range: Comfort
[Runtime] Runtime: 1.97 hours
[WifiVersion] WifiVersion: AWS_Philips_AIR@64.3
I've spent a few hours now looking into this, what's a tad more "reliable/speedy" than the increased timeout is a recursive call to establish the connection on error/timeout, but that's not really pretty either. I believe Philips or MXChip screwed this up and since the Philip's App seems to be having similar issues at times (device disappears as disconnected, then reappears, data not updating in a timely manner etc.)
Just got a new AC2889/10 with FW 1.0.7. The app doesn't even find the device in the lan: The whole communication is: 23:29:46.354185 IP 192.168.21.125.mdns > 224.0.0.251.mdns: 0 PTR (QM)? _philipscondor._tcp.local. (43) 23:29:46.354215 IP 192.168.21.125.mdns > 224.0.0.251.mdns: 0 PTR (QM)? _philipscondor._tcp.local. (43) 23:29:46.383845 IP 192.168.21.125.mdns > 224.0.0.251.mdns: 0 PTR (QM)? _philipscondor._tcp.local. (43) 23:29:46.383871 IP 192.168.21.125.mdns > 224.0.0.251.mdns: 0 PTR (QM)? _philipscondor._tcp.local. (43) 23:29:46.762127 IP 192.168.21.125.mdns > 224.0.0.251.mdns: 0 PTR (QM)? _philipscondor._tcp.local. (43) 23:29:46.762159 IP 192.168.21.125.mdns > 224.0.0.251.mdns: 0 PTR (QM)? _philipscondor._tcp.local. (43) 23:29:46.966910 IP 192.168.21.125.mdns > 224.0.0.251.mdns: 0 [1n] ANY (QM)? CommLib mDNS.local. (52) 23:29:47.581296 IP 192.168.21.125.mdns > 224.0.0.251.mdns: 0- [0q] 1/0/0 (Cache flush) A 192.168.21.125 (46) 23:29:48.416567 IP 192.168.21.125.mdns > 224.0.0.251.mdns: 0- [0q] 1/0/0 (Cache flush) A 192.168.21.125 (46) 23:29:49.424930 IP 192.168.21.125.mdns > 224.0.0.251.mdns: 0*- [0q] 1/0/0 (Cache flush) A 192.168.21.125 (46) 23:30:37.144549 IP 192.168.21.106 > 224.0.0.1: igmp v2 report 224.0.0.1 where .125 is the phone and .106 is the AC2889 After that some SoftAP timeout error.. On .106, all 65535 tcp-ports are closed but mdns is responding.
I have a workaround... using another package. Looks like the FW update from Philips is indeed a bugfix and not a bug. Looks like the purifier only sends a new message if something changed, els it will repeat the last message. So if you have good air quality the values will not change often and py-aircontrol will timeout.
I am now using this package https://github.com/betaboon/aioairctrl which has a small bug which i fixed here https://github.com/Peter-J/aioairctrl (output was not flushed so piping it to another script did not work). You can install it using
pip3 install -U git+https://github.com/......./.........
Biggest feature is that aioairctrl can continously listen to the air purifyer. Again, if your airquality is too god / does not change you will have to wait a long time for the first message. Changing your fanspeed will force new messages to be send.
I included my scripts in the examples folder. Don't expect too much in regards of code quality / readability and so on but i have not a single faild send or recieve. Zero user intervention since.
If you find any bugs / have suggestions please let me know. Will make a pull-request in a few days.
Best regards, Peter
Thanks, @Peter-J , for your efforts. Unfortunately, your version of aioairctrl
doesn't work for my AC2889 and AC2729. When I call the command, it just never returns.
Both devices are on firmware version 67.5
Edit: it sometimes does indeed work, and then again stops working.
both devices still don't work all the time (most of the time not)
The AC2889 is now on firmware 69.1
- The AC2729 is now on firmware 68.3
both devices still don't work all the time (most of the time not)
Im wondering if I have the same issue as you. Does your air purifier stay on the same readings for a long time? My replacement 2000i (1st one had a faulty sensor) is freezing on 4-IAI and 13-PM2.5 for a good 5 minutes before jumping to 2 on the Allergen Index and skipping 3. Is there some kind of buffer value built in so the fan speeds don't adjust too often when just above or below the thresholds for good and fair air quality? I'm trying to work out if its a fault or a feature but I'm getting nowhere with Philips support. Cheers
No, it doesn't freeze.
I'm pretty sure it is a bug in their implementation. When I capture the network traffic, at times the device stops sending CoaP telegrams, but keeps talking to some Amazon servers, which presumably are serving the cloud service of Philips.
The most stable solution would probably be to understand the cloud protocol.
https://github.com/betaboon/aioairctrl still works. But because its using the observer pattern as opposed to continously poll. Big reason I had to switch to this library instead. At least if my memory serves correctly...
Not working for me at the moment. But I guess, this is down to the Philips devices. If they don't transmit any CoaP, aioairctrl
obviously can't pick it up either.
both ours AC5659/10 and2889/10 on 69.1. I should have disconnected them from getting on the WAN.
I think there has to be a command to request state re-transmission. I've done the following test: Run something that's querying for state, like
airctrl --ipaddr 192.168.1.2 --protocol coap --filters
This is stuck, waiting for updates...
But when you then open the Clean Home+
app on your smart phone, the airctrl
command succeeds, showing the filter states.
@dfrommi, @kongo09: Peter and siren wrote solution, I will let myself provide some examples.
Looks like the purifier only sends a new message if something changed
siren meant reding status that way [1️⃣]:
python3 -u /usr/bin/aioairctrl --host 192.168.20.152 status-observe
I like airctrl
to setup things because of its option to set parameters as flags. In my case, I have AC2959/53
and if pm2.5 readings are standing still, so there are no messages.
You can force message to appear some while using cmd [※1️⃣] on another terminal/panel, as it have to have be running before next step, which is an attempt to control yours purifiers, e.g.:
airctrl --ipaddr 192.168.20.152 --protocol coap --uil 1
Unfortunately, sometimes I need to do it twice, so again:
airctrl --ipaddr 192.168.20.152 --protocol coap --uil 1
Which will result that the status-observe
handling in the aioairctl
from cmd [※1️⃣] will print in a new line a complete status:
{'name': 'Air Purifier', 'type': 'AC2959', 'modelid': 'AC2959/53', 'MCUBoot': True, 'swversion': 'Ms2104', 'language': 'EN', 'DeviceVersion': '1.0.4', 'range': 'MarsLE', 'Runtime': 1272165782, 'rssi': -52, 'otacheck': False, 'wifilog': False, 'free_memory': 53840, 'WifiVersion': 'AWS_Philips_AIR@71.3', 'ProductId': '...', 'DeviceId': '...', 'StatusType': 'control', 'ConnectType': 'Online', 'om': 's', 'pwr': '1', 'cl': False, 'aqil': 100, 'uil': '1', 'uaset': 'P', 'mode': 'AG', 'pm25': 1, 'iaql': 1, 'aqit': 4, ...}
I have a AC2889/10 with updated firmware of course (I guess). So far I couldn't execute any command to get any helpful information at all. I don't have the possibility and don't want to install the app.
Is there any way at all to at least set a wifi network+pw without the app? There are 49 forks of this repo. No idea if there is one that works better than the main one?
Currently it seems the default wifi is always active and I cannot do anything about that. Thank you Philips.
So far I couldn't execute any command to get any helpful information at all.
In that case you're probably stuck.
I was using py-air-control for some months to control my AC2889/10 without problems. Since today it does not work any longer although I have changed absolutely nothing. I can switch on and switch off the air purifier using
But when calling
airctrl --ipaddr 192.168.0.84 --protocol coap
I now get the following almost on every call:But this does not happen on every call. A small number of calls (roundabout 1 of 20) succeed and return the correct status:
Is this a known problem and there is a solution for that?