Accessory not responding
JekleFPV opened this issue ยท 21 comments
I'm running air control on a raspi zero W running the homebridge image, along with homebridge Philips Air but Homekit keeps giving telling me "No response".
I've tried to figure it out with the maker of homebridge air control (https://github.com/Sunoo/homebridge-philips-air/issues/31#issue-678654254), but it seems it has to do with py air control.
When I run airctrl --ipaddr 192.168.1.18 --protocol coap
, what I get is below, any clues as to how to fix this?
Give up on message From None, To ('192.168.1.18', 5683), CON-56159, POST-cx, [Uri-Path: sys, Uri-Path: dev, Uri-Path: sync, ] C543FAD1...8 bytes
Traceback (most recent call last):
File "/usr/local/bin/airctrl", line 10, in
sys.exit(main())
File "/usr/local/lib/python3.7/dist-packages/pyairctrl/airctrl.py", line 448, in main
c = CoAPCli(device["ip"], debug=args.debug)
File "/usr/local/lib/python3.7/dist-packages/pyairctrl/airctrl.py", line 15, in init
self._client = CoAPAirClient(host, port, debug)
File "/usr/local/lib/python3.7/dist-packages/pyairctrl/coap_client.py", line 80, in init
self._sync()
File "/usr/local/lib/python3.7/dist-packages/pyairctrl/coap_client.py", line 91, in _sync
self.client_key = self.client.post("/sys/dev/sync", self.syncrequest).payload
AttributeError: 'NoneType' object has no attribute 'payload'
Got the same, airctrl
works for a while and then gives Give up on message
. Any further runs of the tool give the same error.
The device is PHILIPS 3000i AC3829/10.
I run the following command every 2 minutes to get actual pm2.5 and humidity.
airctrl --ipaddr 192.168.1.101 --protocol coap
It works fine for less than an hour and then starts giving the error.
More interesting is that the AC3829/10 also stops responding to the Air matters app.
So it seems airctrl
makes the device hang after a while.
If i turn off and on the device it starts working and everything repeats after a while.
That sounds a lot like issue #63. Unfortunately I don't have a coap device and I can't troubleshoot myself.
I did not see this issue before opening #63, so just to keep it here, I had exactly the same problem with AC1214 using coap protocol.
I have experienced the same issue as @inwaar explained it. Some people on the HA forum see similar messages.
By looking at the CoAPthon3 repo, it hasn't been maintained well for the past 3 years, and has some old unresolved issues:
Quite similar to this issue:
Tanganelli/CoAPthon3#6
And maybe matching the previous issue with this one:
Tanganelli/CoAPthon3#16
Otherwise there are a few forks which are a bit ahead of the original one:
https://github.com/8749236/CoAPthon3/commits/master
https://github.com/jnoor/CoAPthon3/commits/master
https://github.com/michieldwitte/CoAPthon3/commits/master
https://github.com/magnev/CoAPthon3/commits/master
https://github.com/tadodotcom/CoAPthon3/commits/master
(This is TADO's branch!!!)
https://github.com/WAvdBeek/CoAPthon3/commits/master
Some of them tries to fix the aforementioned issues, so has other improvements. It might would worth to change the CoAPthon3 to another branch and use it to fix this issue.
Agree, there are many issues with CoAPthon3 and apparently it's no longer maintained.
People with CoAP devices feel free to experiment with these forks and let me know if any them solves this particular issue.
Just don't forget to add the fix for the length of the "increase reception buffer size" commit if it wasn't implemented yet. ;)
I have also noticed this issue and I have made an additional observation. Instead of calling the "py-air-control" script periodically, i made a local copy where i "loop-sleep" around .get_status(..). This way I have been able to poll the PPM2.5 for days without the issue triggering. This seem to result in other problems, like the fan speed not updating, but the PPM2.5 looks okay.
Without knowing anything about the underlying protocol, but could it be that the "py-air-control" leaves like "half-open sessions" against the air purifier when closing? Perhaps the air purifier only have a fixed number of "concurrent sessions" and don't utilize any like "timeout cleanup". Once the sessions are out it doesn't accept any new connections until the air-purifier is power cycled. Just a theory.
@flash447 This is an interesting observation, thanks. I see that the CoAP client is stopped in a __del__
method and there is a TODO:
class CoAPAirClient(HTTPAirClientBase):
def __del__(self):
# TODO call a close method explicitly instead
self.client.stop()
I guess the original idea was that this client is created once and then destroyed when the object is garbage collected.
You can try two things:
- Call
self.client.stop()
explicitly at the end and see if this fixes the problem - Instead of creating the client once in the constructor, create and destroy it for each and every operation. This is how the
PlainCoAPAirClient
works. I don't know if reusing the same client for multiple operations is OK or not.
This code was contributed by other people and I have no way to debug and test it because I don't have CoAP device. If any of the above fixes the problem, submit a PR and I will merge it.
You can try two things:
I have tried your suggestions, but neither helped.
Is this issue a problem for all devices using the "encrypted coap client" or is it device/firmware specific?
I am just leaving this here, this is the documentation of the COAP protocol:
The problem is not related to the COAP library but to the fundamental wrong way that py-air-control deals with the COAP protocol.
After capturing some network packets and using Wireshark I noticed that the observe option is set on each request. This means that the device expects the client to keep receiving packets for updates about the sensor values. This seems to be the only way to get the sensor values from the device.
How this is implemented in py-air-control is wrong. If you don't explicitly close the connection the update messages will get pushed on a queue. Only one item of the (FIFO) queue is read for each time the get_status is called. Which makes no sense since this queue contains after an hour about 100 messages. This will result in a get_status call that provides you old data.
If you do explicitly close the connection by either stopping the software or explicitly calling stop, the connection will be closed and the handshake will start again. Somehow the Philips device doesn't like this if you do this too often. The network stack of the device might crash and you have to disconnect it from power to recover.
Conclusion: py-air-ctrl in combination with COAP is nice if you use it only once in a while.
Don't use it for continuously polling like homebridge, Domoticz or other domtica software that wants to receive updated sensor values. For this you need to implement an observer that will keep listening for updates. There is no easy way to modify py-air-control to this behavior.
I pushed my solution for Domoticz on https://github.com/roldoe/domoticz-philips-air
Oh great, so looks like my homebridge-philips-air would require updates.
I should probably try to find a new maintainer, as I never had access to a CoAP unit, and I have gotten rid of my HTTP unit at this point as well.
@roldoe Thanks for the analysis! We need to implement a py-air-control daemon which runs in the background and listens for updates. The CLI tool will query the daemon instead of opening connections to the device. I don't think this is hard to implement but I don't have a CoAP device and I cannot do it myself. If anyone is willing to implement and contribute this, PRs are welcome!
Maybe a daemon running in background providing the data per rest-api and/or mqqt would be the best solution. The cli could interact via the rest-interface (for example), this should work for coap and non coap devices.
Maybe this would diminish the need of an own library #34, since rest/mqqt would be well known and can be losely coupled to homeautomation-servers.
I'll look into this the next few days, other thoughts are welcome.
@Cyber1000, this Home Assistant integration works like that. No issues with non responding device anymore. It subscribes to changes from the airpurifier.
Thanks for pointing that out, it seems to have a more up-to-date coap implementation (https://github.com/chrysn/aiocoap) too. The fan is "home assistant"-centric, I think, but will be a good starting point for me.
Well I looked deeper in the code:
- I think I left the TODO there last year, cause I was a little bit uncertain, if this works. But as far as I see this seems to work (client created at init, client stopped at stopping). "request.observe = 0" seems to create a observable without using a callback for this observable. So the observable is never closed as @roldoe pointed out, I somehow expected that a client.stop of coapthon will do that. Which leads me to the next point ...
- I've reused "request.observe = 0" out of PlainCoAPAirClient, the only difference is that in PlainCoAPAirClient create-client, read and client.stop is within _get and in CoAPAirClient it is splitted over init, _get and del which shouldn't make a big difference, since a single run of airctrl doesn't run that long (init, get and del will run timely closely together)
I would expect PlainCoAPAirClient having exact the same problems, has someone experienced similar issues with plain_coap?
- Anyway I've now added a client.cancel_observing into the _get-method (not checked in right now) hoping that this will solve the problem (will run it over the night every 2 minutes).
- rest/mqqt will be still a plan for me, but that will be a bigger change.
I'll give a update soon
I've added (hopefully) a fix in PR #85 , If someone could try it before merge:
pip3 uninstall py-air-control
git clone https://github.com/Cyber1000/py-air-control.git -b observe
cd py-air-control
pip3 install .
Afterwards you could do pip3 uninstall py-air-control
and install the official plugin again with pip3 install py-air-control
My problem is that I have a coap device, but it doesn't run into this problem. Model is AC2889/10 and swversion is 1.0.7
Maybe my device cleans up unused observes over the time, at least it doesn't brick and always returns the wanted information.
@Cyber1000 thanks for looking into this, I think PR #85 has all the chances to fix this issue but I cannot test it myself.
I'd ask people having the issue to try this patch and tell us if it works.