Closed blastar closed 4 years ago
Are you sure you got the correct IP address of the purifier?
I'm not, I see something like: mico.home (192.168.1.43) at b0:f8:93:67:f7:a6 [ether] on eth0 with arp -a, and this is only new device. IP scanner shows: IP: 192.168.1.43 Ping: 11 ms Hostname: mico.home Ports: [n/s] Web detect: [n/a] MAC Vendor: Shanghai MXCHIP Information NetBIOS Info: [n/a] Not sure how can I get IP another way, don't see anything usefull in AirMatters.
I got the same error but i'm sure the IP Is correct:
$ python3 airctrl.py 192.168.178.72 --debug
Exchanging secret key with the device ...
Traceback (most recent call last):
File "/usr/lib/python3.5/urllib/request.py", line 1254, in do_open
h.request(req.get_method(), req.selector, req.data, headers)
File "/usr/lib/python3.5/http/client.py", line 1107, in request
self._send_request(method, url, body, headers)
File "/usr/lib/python3.5/http/client.py", line 1152, in _send_request
self.endheaders(body)
File "/usr/lib/python3.5/http/client.py", line 1103, in endheaders
self._send_output(message_body)
File "/usr/lib/python3.5/http/client.py", line 934, in _send_output
self.send(msg)
File "/usr/lib/python3.5/http/client.py", line 877, in send
self.connect()
File "/usr/lib/python3.5/http/client.py", line 849, in connect
(self.host,self.port), self.timeout, self.source_address)
File "/usr/lib/python3.5/socket.py", line 712, in create_connection
raise err
File "/usr/lib/python3.5/socket.py", line 703, in create_connection
sock.connect(sa)
ConnectionRefusedError: [Errno 111] Connection refused
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "airctrl.py", line 310, in <module>
main()
File "airctrl.py", line 267, in main
c.load_key()
File "airctrl.py", line 87, in load_key
self._get_key()
File "airctrl.py", line 53, in _get_key
with urllib.request.urlopen(req) as response:
File "/usr/lib/python3.5/urllib/request.py", line 163, in urlopen
return opener.open(url, data, timeout)
File "/usr/lib/python3.5/urllib/request.py", line 466, in open
response = self._open(req, data)
File "/usr/lib/python3.5/urllib/request.py", line 484, in _open
'_open', req)
File "/usr/lib/python3.5/urllib/request.py", line 444, in _call_chain
result = func(*args)
File "/usr/lib/python3.5/urllib/request.py", line 1282, in http_open
return self.do_open(http.client.HTTPConnection, req)
File "/usr/lib/python3.5/urllib/request.py", line 1256, in do_open
raise URLError(err)
urllib.error.URLError: <urlopen error [Errno 111] Connection refused>
What happens when you do curl http://<purifier-ip>
? This is what I get:
$ curl http://192.168.0.91
{"error":"Badly formed (DI Comm) request "}
Is port 80 open on the device? You can also try putting the device into pairing mode and then connect to the "PHILIPS Setup" network.
I see: curl: (7) Failed to connect to 192.168.1.43 port 80: Connection refused So seems that port 80 is closed
This is really strange. Can you try and sniff the traffic between AirMatters and the device?
my connection is also refused, I'm trying to connect to a AC3036/10 btw.
Could it be that the initial configuration of the wifi has to be done with the pc (in my case a raspberry pi 2 with raspbian stretch ) i'm trying to run these commands from? I did the initial config via the air matters app.
Btw. i can't run the "airctrl" cmds from anywhere, i have to run the script directly, as you can see in my code from above.
Btw. i can't run the "airctrl" cmds from anywhere, i have to run the script directly, as you can see in my code from above.
You need to install the app with pip install py-air-control
and then you will have airctrl
executable
i think you mean pip3, pip throws an error. Installed it a few times didn't help though it "installed correctly".
pip
$ pip install py-air-control
Collecting py-air-control
Downloading https://files.pythonhosted.org/packages/53/1a/dcc775b86de43665097a9a9c7a99a0335b3bc9c38b9bf9adedaa8f10c91d/py-air-control-1.0.0.tar.gz
Complete output from command python setup.py egg_info:
Python 3.4 or newer is required.
----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-ar6Ow0/py-air-control/
pip3
$ pip3 install py-air-control
Collecting py-air-control
Using cached https://files.pythonhosted.org/packages/e9/7d/38ffb2f83313f53b539ae556e16ebcf439c43e2bf560216656ec673a5032/py_air_control-1.0.0-py3-none-any.whl
Collecting pycryptodome>=3.4.7 (from py-air-control)
Using cached https://www.piwheels.org/simple/pycryptodome/pycryptodome-3.9.4-cp35-cp35m-linux_armv7l.whl
Installing collected packages: pycryptodome, py-air-control
Successfully installed py-air-control-1.0.0 pycryptodome-3.9.4
Similar issue here with an AC3829/10, I'm getting an Errno 61.
airctrl 192.168.1.21
Exchanging secret key with the device ...
Traceback (most recent call last):
File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 1318, in do_open
encode_chunked=req.has_header('Transfer-encoding'))
File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1239, in request
self._send_request(method, url, body, headers, encode_chunked)
File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1285, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1234, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1026, in _send_output
self.send(msg)
File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 964, in send
self.connect()
File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 936, in connect
(self.host,self.port), self.timeout, self.source_address)
File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/socket.py", line 724, in create_connection
raise err
File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/socket.py", line 713, in create_connection
sock.connect(sa)
ConnectionRefusedError: [Errno 61] Connection refused
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/bin/airctrl", line 11, in <module>
sys.exit(main())
File "/usr/local/lib/python3.6/site-packages/pyairctrl/airctrl.py", line 267, in main
c.load_key()
File "/usr/local/lib/python3.6/site-packages/pyairctrl/airctrl.py", line 87, in load_key
self._get_key()
File "/usr/local/lib/python3.6/site-packages/pyairctrl/airctrl.py", line 53, in _get_key
with urllib.request.urlopen(req) as response:
File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 223, in urlopen
return opener.open(url, data, timeout)
File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 526, in open
response = self._open(req, data)
File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 544, in _open
'_open', req)
File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 504, in _call_chain
result = func(*args)
File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 1346, in http_open
return self.do_open(http.client.HTTPConnection, req)
File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 1320, in do_open
raise URLError(err)
urllib.error.URLError: <urlopen error [Errno 61] Connection refused>
Can someone try to put the purifier into pairing mode and then check if port 80 is open on the device?
Sorry my pc is connected via LAN, so it's not possible to access the wifi of the purifier.
If you are on Linux you can try to run SSDP discovery with the following command:
$ sudo apt-get install gupnp-tools
$ gssdp-discover -i eth0 --timeout=3
Used it on my raspberry, there is a lot of stuff shown, what am i looking for?
This is the response that I get:
resource available
USN: uuid:12345678-1234-1234-1234-************::upnp:rootdevice
Location: http://192.168.0.91/upnp/description.xml
resource available
USN: uuid:12345678-1234-1234-1234-************
Location: http://192.168.0.91/upnp/description.xml
resource available
USN: uuid:12345678-1234-1234-1234-************::urn:philips-com:device:DiProduct:1
Location: http://192.168.0.91/upnp/description.xml
There's nothing with "philips" in the USN :/
I have the same problem as @dokterdok.
When I connect my notebook to the SSID “PHILIPS Setup” on my AC3829 air purifier, I get the address 10.0.0.2. I conclude that the default address of the air purifier will be 10.0.0.1.
Unfortunately on port 80 it doesn't respond at all. That's why I tried port scanning.
sudo nmap -Pn -p- 10.0.0.1
Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-14 18:11 CET
Nmap scan report for 10.0.0.1
Host is up (0.31s latency).
Not shown: 65534 closed ports
PORT STATE SERVICE
30123/tcp open unknown
MAC Address: B0:F8:93:68:86:6B (Shanghai Mxchip Information Technology)
Nmap discovered an open tcp port 30123.
wget -O- http://10.0.0.1:30123
--2019-12-14 18:39:06-- http://10.0.0.1:30123/
Connecting to 10.0.0.1:30123... connected.
HTTP request sent, awaiting response... 200 No headers, assuming HTTP/0.9
Length: unspecified
Saving to: 'STDOUT'
{"type":"deviceinfo","meta":{"message":"check device info","code":100},"data":{"name":"Bedroom","type":"AC3829","modelid":"AC3829/10","swversion":"1.4.0"}}{"type":"config","meta":{"message":"no json","code":1000}}
wget -O- http://10.0.0.1:30123/di/v1/products/0/wifi
--2019-12-14 18:51:53-- http://10.0.0.1:30123/di/v1/products/0/wifi
Connecting to 10.0.0.1:30123... connected.
HTTP request sent, awaiting response... 200 No headers, assuming HTTP/0.9
Length: unspecified
Saving to: 'STDOUT'
{"type":"deviceinfo","meta":{"message":"check device info","code":100},"data":{"name":"Bedroom","type":"AC3829","modelid":"AC3829/10","swversion":"1.4.0"}}{"type":"config","meta":{"message":"no json","code":1000}}
The air purifier always responds in this way. Do you have any idea what to try next?
Edit: I have yet tried to eavesdrop on the communication between the AC3829 (192.168.1.37) and the Air Matters app (192.168.1.176). It looks like CoAP protocol is being used. tcpdump-ac3829-air_matters.pcap.zip
I have same issue with philips ac2729 (bought ~one month ago). I checked with nmap, all ports are closed :(
Starting Nmap 7.70 ( https://nmap.org ) at 2019-12-15 00:35 CET Nmap scan report for 172.16.0.140 Host is up (0.0053s latency). All 65535 scanned ports on 172.16.0.140 are closed MAC Address: XXXXXX (Shanghai Mxchip Information Technology)
Nmap done: 1 IP address (1 host up) scanned in 6404.26 seconds
Same with a new Series 1000i AC1214/10. No open ports and airctrl
is not working with same errors described above. In pairing mode with nmap:
30123/tcp open unknown
| fingerprint-strings:
| DNSStatusRequestTCP, DNSVersionBindReqTCP, GenericLines, GetRequest, HTTPOptions, RPCCheck, RTSPRequest:
| {"type":"deviceinfo","meta":{"message":"check device info","code":100},"data":{"name":"AirPurifier","type":"AC1214","modelid":"AC1214/10","swversion":"2.0.0"}}{"type":"config","meta":{"message":"no json","code":1000}}
| NULL:
|_ {"type":"deviceinfo","meta":{"message":"check device info","code":100},"data":{"name":"AirPurifier","type":"AC1214","modelid":"AC1214/10","swversion":"2.0.0"}}
Same problem with ac1214/10. There is no open port of the unit when I scan it. The host name is MiCO.
Can confirm that it doesn't work on a new AC2729/50 either. The device's IP is 10.0.0.1 and the only open TCP port is 30123.
~$ telnet 10.0.0.1 30123
Trying 10.0.0.1...
Connected to 10.0.0.1.
Escape character is '^]'.
{"type":"deviceinfo","meta":{"message":"check device info","code":100},"data":{"name":"AirPurifier","type":"AC2729","modelid":"AC2729/50","swversion":"0.2.1"}}
when trying to send something it replies:
{"type":"config","meta":{"message":"no json","code":1000}}
Nothing on SSDP discovery. The protocol has completely changed, it seems.
Yeah, it seems they switched to another protocol. If anyone that has such device manage to reverse it, patches are welcome! :) This is how I did it for the purifier that I have: https://xakcop.com/post/ctrl-air-purifier/ https://xakcop.com/post/cloud-air-purifier/
I think the new models use CoAP to communicate like @hoky24 said. The tricky thing is to open the CoAP port 5683. After sniffing the traffic it looks like the app sends a special ICMP packet to the device. This looks like: ICMP packet (type: 3, code 3) with payload: TCP (srcip: app, dstip: device) and UDP(srcport: 5683, dstport: 5683). Need to figure out the correct formatting and checksums.
Edit1: There is indeed a special communication needed, as a combination of special ICMP and CoAP messages! Got to the point were my device is finally talking to me in CoAP, currently resets the connection but it does something :) Going on
Edit2: Did it! Got status infos from my brand new AC2729 unit.
Next, refactoring code, send / dicover commands, think about if its good to integrate here or do a new project, because the protocol is totally different
@shexbeer Great! I will be happy to accept PRs if you decide to contribute.
@rgerganov Yes, i will create a PR as soon as i got everything in place 👍 Switching between old and new protocol via command line option is a possibility, what do you think?
Switching between old and new protocol via command line option is a possibility, what do you think?
Sure. I guess we can assume that if port 80 is closed on the device then we should use the CoAP protocol but let's keep it simple for now.
Pushed the code in #32 Yeah there are some improvements possible 👍 But for now, it works. Will do more research on initial pairing soon.
@shexbeer Thank you for your work on improving py-air-control. I tried your CoAP version with my AC3829, but I didn't get status:
sudo ./airctrl.py --ipaddr 192.168.1.37 --protocol 2 -d
2020-02-01 09:05:33,384 - MainThread - coapthon.layers.messagelayer - DEBUG - send_request - From None, To ('192.168.1.37', 5683), None-None, EMPTY-None, [] No payload
2020-02-01 09:05:33,385 - MainThread - coapthon.client.coap - DEBUG - send_datagram - From None, To ('192.168.1.37', 5683), CON-25755, EMPTY-None, [] No payload
2020-02-01 09:05:33,385 - Thread-1 - coapthon.client.coap - DEBUG - Start receiver Thread
2020-02-01 09:05:33,386 - MainThread - coapthon.layers.messagelayer - DEBUG - send_request - From None, To ('192.168.1.37', 5683), ACK-None, GET-fIpf, [Uri-Path: sys, Uri-Path: dev, Uri-Path: status, Observe: 0, ] No payload
2020-02-01 09:05:33,386 - MainThread - coapthon.client.coap - DEBUG - send_datagram - From None, To ('192.168.1.37', 5683), ACK-25756, GET-fIpf, [Uri-Path: sys, Uri-Path: dev, Uri-Path: status, Observe: 0, ] No payload
2020-02-01 09:05:33,386 - MainThread-Retry-25755 - coapthon.client.coap - DEBUG - retransmit loop ... enter
2020-02-01 09:05:33,390 - Thread-1 - coapthon.layers.messagelayer - DEBUG - receive_empty - From ('192.168.1.37', 5683), To None, RST-25755, EMPTY-None, [] No payload
2020-02-01 09:05:33,390 - MainThread-Retry-25755 - coapthon.client.coap - DEBUG - retransmit loop ... exit
2020-02-01 09:05:35,393 - Thread-1 - coapthon.client.coap - DEBUG - Exiting receiver Thread due to request
Raw status: {}
Hello @hoky24, great you had time to try it out.
My communication looks like this:
2020-02-01 11:41:40,739 - MainThread - coapthon.layers.messagelayer - DEBUG - send_request - From None, To ('192.168.179.76', 5683), None-None, EMPTY-None, [] No payload
2020-02-01 11:41:40,739 - MainThread - coapthon.client.coap - DEBUG - send_datagram - From None, To ('192.168.179.76', 5683), CON-48336, EMPTY-None, [] No payload
2020-02-01 11:41:40,740 - Thread-1 - coapthon.client.coap - DEBUG - Start receiver Thread
2020-02-01 11:41:40,740 - MainThread - coapthon.layers.messagelayer - DEBUG - send_request - From None, To ('192.168.179.76', 5683), ACK-None, GET-wGEM, [Uri-Path: sys, Uri-Path: dev, Uri-Path: status, Observe: 0, ] No payload
2020-02-01 11:41:40,740 - MainThread - coapthon.client.coap - DEBUG - send_datagram - From None, To ('192.168.179.76', 5683), ACK-48337, GET-wGEM, [Uri-Path: sys, Uri-Path: dev, Uri-Path: status, Observe: 0, ] No payload
2020-02-01 11:41:40,741 - MainThread-Retry-48336 - coapthon.client.coap - DEBUG - retransmit loop ... enter
2020-02-01 11:41:40,747 - Thread-1 - coapthon.layers.messagelayer - DEBUG - receive_empty - From ('192.168.179.76', 5683), To None, RST-48336, EMPTY-None, [] No payload
2020-02-01 11:41:40,747 - MainThread-Retry-48336 - coapthon.client.coap - DEBUG - retransmit loop ... exit
2020-02-01 11:41:40,749 - Thread-1 - coapthon.client.coap - DEBUG - receive_datagram - From ('192.168.179.76', 5683), To None, ACK-27092, CONTENT-wGEM, [Observe: 13554, Content-Type: 50, Max-Age: 60, ] {"state":{"reported"...588 bytes
2020-02-01 11:41:40,749 - Thread-1 - coapthon.layers.messagelayer - DEBUG - receive_response - From ('192.168.179.76', 5683), To None, ACK-27092, CONTENT-wGEM, [Observe: 13554, Content-Type: 50, Max-Age: 60, ] {"state":{"reported"...588 bytes
2020-02-01 11:41:40,851 - Thread-1 - coapthon.client.coap - DEBUG - Exiting receiver Thread due to request
I can see that your device is indeed talking to you:
2020-02-01 09:05:33,390 - Thread-1 - coapthon.layers.messagelayer - DEBUG - receive_empty - From ('192.168.1.37', 5683), To None, RST-25755, EMPTY-None, [] No payload
After the empty message the device should connect to you and send you the status because of the GET request with observe addin. I will take a second look into your posted pcap file and maybe spot a important difference to my unit here
PS: Do you have Philips cloud enabled? PPS: What happens if you send a command like --pw 0 or / --pw 1 ? PPS: After having second look onto your pcap file, it looks like your app/device sends different coap messages than mine does. Also i saw in your pcap that your device is using firmware 1.4 and mine use 0.2.1. When did you buy your device? Did you connect it to Cloud, did any OTA? (for comparison: I bought my device on Monday from Amazon, never connected to Cloud, never did OTA) PPPS: After taking a look into your responses from GET /sys/dev/status, it looks like the json response may be encrypted. Mine is plain
I have merged @shexbeer work into master. You can do a git pull and then test the CoAP support by adding --protocol coap
argument. Unfortunately I don't have such device and cannot do any testing but I will be happy to accept any patches from you guys.
I tried coAP w/ philips ac2729, but I didn't get status/response: ac2729-coap.zip
airctrl --ipaddr 172.16.0.140 --protocol coap --debug
2020-02-02 01:26:32,761 - MainThread - coapthon.layers.messagelayer - DEBUG - send_request - From None, To ('172.16.0.140', 5683), None-None, EMPTY-None, [] No payload 2020-02-02 01:26:32,762 - MainThread - coapthon.client.coap - DEBUG - send_datagram - From None, To ('172.16.0.140', 5683), CON-20162, EMPTY-None, [] No payload 2020-02-02 01:26:32,764 - Thread-1 - coapthon.client.coap - DEBUG - Start receiver Thread 2020-02-02 01:26:32,767 - MainThread - coapthon.layers.messagelayer - DEBUG - send_request - From None, To ('172.16.0.140', 5683), ACK-None, GET-BeGj, [Uri-Path: sys, Uri-Path: dev, Uri-Path: status, Observe: 0, ] No payload 2020-02-02 01:26:32,767 - MainThread-Retry-20162 - coapthon.client.coap - DEBUG - retransmit loop ... enter 2020-02-02 01:26:32,768 - MainThread - coapthon.client.coap - DEBUG - send_datagram - From None, To ('172.16.0.140', 5683), ACK-20163, GET-BeGj, [Uri-Path: sys, Uri-Path: dev, Uri-Path: status, Observe: 0, ] No payload 2020-02-02 01:26:32,770 - Thread-1 - coapthon.layers.messagelayer - DEBUG - receive_empty - From ('172.16.0.140', 5683), To None, RST-20162, EMPTY-None, [] No payload 2020-02-02 01:26:32,771 - MainThread-Retry-20162 - coapthon.client.coap - DEBUG - retransmit loop ... exit 2020-02-02 01:26:34,775 - Thread-1 - coapthon.client.coap - DEBUG - Exiting receiver Thread due to request Raw status: {}
~# airctrl --ipaddr 172.16.0.140 --protocol coap --debug --pw 1 2020-02-02 01:26:51,754 - MainThread - coapthon.layers.messagelayer - DEBUG - send_request - From None, To ('172.16.0.140', 5683), None-None, EMPTY-None, [] No payload 2020-02-02 01:26:51,755 - MainThread - coapthon.client.coap - DEBUG - send_datagram - From None, To ('172.16.0.140', 5683), CON-27954, EMPTY-None, [] No payload 2020-02-02 01:26:51,757 - Thread-1 - coapthon.client.coap - DEBUG - Start receiver Thread 2020-02-02 01:26:51,760 - MainThread - coapthon.layers.messagelayer - DEBUG - send_request - From None, To ('172.16.0.140', 5683), None-None, POST-BZ, [Uri-Path: sys, Uri-Path: dev, Uri-Path: control, ] {"state": {"desired"...36 bytes 2020-02-02 01:26:51,761 - MainThread-Retry-27954 - coapthon.client.coap - DEBUG - retransmit loop ... enter 2020-02-02 01:26:51,762 - MainThread - coapthon.client.coap - DEBUG - send_datagram - From None, To ('172.16.0.140', 5683), CON-27955, POST-BZ, [Uri-Path: sys, Uri-Path: dev, Uri-Path: control, ] {"state": {"desired"...36 bytes 2020-02-02 01:26:51,762 - Thread-1 - coapthon.layers.messagelayer - DEBUG - receive_empty - From ('172.16.0.140', 5683), To None, RST-27954, EMPTY-None, [] No payload 2020-02-02 01:26:51,765 - MainThread-Retry-27954 - coapthon.client.coap - DEBUG - retransmit loop ... exit 2020-02-02 01:26:51,766 - MainThread-Retry-27955 - coapthon.client.coap - DEBUG - retransmit loop ... enter 2020-02-02 01:26:51,767 - Thread-1 - coapthon.client.coap - DEBUG - receive_datagram - From ('172.16.0.140', 5683), To None, NON-27955, CONTENT-BZ, [Content-Type: 50, ] {"status":"failed"}...19 bytes 2020-02-02 01:26:51,768 - Thread-1 - coapthon.layers.messagelayer - DEBUG - receive_response - From ('172.16.0.140', 5683), To None, NON-27955, CONTENT-BZ, [Content-Type: 50, ] {"status":"failed"}...19 bytes 2020-02-02 01:26:51,771 - Thread-1 - coapthon.client.coap - DEBUG - Waiting for retransmit thread to finish ... 2020-02-02 01:26:51,772 - MainThread-Retry-27955 - coapthon.client.coap - DEBUG - retransmit loop ... exit 2020-02-02 01:26:51,883 - Thread-1 - coapthon.client.coap - DEBUG - Exiting receiver Thread due to request
@szogi Looks like you have a similar device like @hoky24.
I can see the device is talking to you. Also when you set the state, the device is answering you (but it was not successful: {"status":"failed"}
I guess your devices want to have some special formatting / encoding / encryption of the payloads, but iam still unsure
Can you please capture some packets while you are using the AirMatters App? Please follow this:
Just include the traffic between your mobile device and the purifier.
@shexbeer here's a pcap from communication between AirMatters and AC1214/10. There are 2 ICMP as you described and then CoAP messages.
Purifier IP: 172.25.1.72 Phone IP: 172.25.1.104
Operations performed, Child Lock ON + Off then Power OFF + ON
@shexbeer
PS: Do you have Philips cloud enabled?
Yes, I have Philips cloud enabled
PPS: What happens if you send a command like --pw 0 or / --pw 1 ?
sudo ./airctrl.py --ipaddr 192.168.1.37 --protocol coap -d --pw 0 2020-02-03 17:27:02,202 - MainThread - coapthon.layers.messagelayer - DEBUG - send_request - From None, To ('192.168.1.37', 5683), None-None, EMPTY-None, [] No payload 2020-02-03 17:27:02,203 - MainThread - coapthon.client.coap - DEBUG - send_datagram - From None, To ('192.168.1.37', 5683), CON-19242, EMPTY-None, [] No payload 2020-02-03 17:27:02,203 - Thread-1 - coapthon.client.coap - DEBUG - Start receiver Thread 2020-02-03 17:27:02,203 - MainThread - coapthon.layers.messagelayer - DEBUG - send_request - From None, To ('192.168.1.37', 5683), None-None, POST-NF, [Uri-Path: sys, Uri-Path: dev, Uri-Path: control, ] {"state": {"desired"...36 bytes 2020-02-03 17:27:02,204 - MainThread - coapthon.client.coap - DEBUG - send_datagram - From None, To ('192.168.1.37', 5683), CON-19243, POST-NF, [Uri-Path: sys, Uri-Path: dev, Uri-Path: control, ] {"state": {"desired"...36 bytes 2020-02-03 17:27:02,204 - MainThread-Retry-19242 - coapthon.client.coap - DEBUG - retransmit loop ... enter 2020-02-03 17:27:02,204 - MainThread-Retry-19243 - coapthon.client.coap - DEBUG - retransmit loop ... enter 2020-02-03 17:27:02,210 - Thread-1 - coapthon.layers.messagelayer - DEBUG - receive_empty - From ('192.168.1.37', 5683), To None, RST-19242, EMPTY-None, [] No payload 2020-02-03 17:27:02,211 - MainThread-Retry-19242 - coapthon.client.coap - DEBUG - retransmit loop ... exit 2020-02-03 17:27:02,212 - Thread-1 - coapthon.client.coap - DEBUG - receive_datagram - From ('192.168.1.37', 5683), To None, NON-19243, CONTENT-NF, [Content-Type: 50, ] {"status":"failed"}...19 bytes 2020-02-03 17:27:02,212 - Thread-1 - coapthon.layers.messagelayer - DEBUG - receive_response - From ('192.168.1.37', 5683), To None, NON-19243, CONTENT-NF, [Content-Type: 50, ] {"status":"failed"}...19 bytes 2020-02-03 17:27:02,212 - Thread-1 - coapthon.client.coap - DEBUG - Waiting for retransmit thread to finish ... 2020-02-03 17:27:02,212 - MainThread-Retry-19243 - coapthon.client.coap - DEBUG - retransmit loop ... exit 2020-02-03 17:27:02,323 - Thread-1 - coapthon.client.coap - DEBUG - Exiting receiver Thread due to request
sudo ./airctrl.py --ipaddr 192.168.1.37 --protocol coap -d --pw 1
2020-02-03 17:27:09,106 - MainThread - coapthon.layers.messagelayer - DEBUG - send_request - From None, To ('192.168.1.37', 5683), None-None, EMPTY-None, [] No payload
2020-02-03 17:27:09,106 - MainThread - coapthon.client.coap - DEBUG - send_datagram - From None, To ('192.168.1.37', 5683), CON-52185, EMPTY-None, [] No payload
2020-02-03 17:27:09,107 - Thread-1 - coapthon.client.coap - DEBUG - Start receiver Thread
2020-02-03 17:27:09,107 - MainThread - coapthon.layers.messagelayer - DEBUG - send_request - From None, To ('192.168.1.37', 5683), None-None, POST-CQ, [Uri-Path: sys, Uri-Path: dev, Uri-Path: control, ] {"state": {"desired"...36 bytes
2020-02-03 17:27:09,107 - MainThread-Retry-52185 - coapthon.client.coap - DEBUG - retransmit loop ... enter
2020-02-03 17:27:09,107 - MainThread - coapthon.client.coap - DEBUG - send_datagram - From None, To ('192.168.1.37', 5683), CON-52186, POST-CQ, [Uri-Path: sys, Uri-Path: dev, Uri-Path: control, ] {"state": {"desired"...36 bytes
2020-02-03 17:27:09,108 - MainThread-Retry-52186 - coapthon.client.coap - DEBUG - retransmit loop ... enter
2020-02-03 17:27:09,109 - Thread-1 - coapthon.layers.messagelayer - DEBUG - receive_empty - From ('192.168.1.37', 5683), To None, RST-52185, EMPTY-None, [] No payload
2020-02-03 17:27:09,109 - MainThread-Retry-52185 - coapthon.client.coap - DEBUG - retransmit loop ... exit
2020-02-03 17:27:09,111 - Thread-1 - coapthon.client.coap - DEBUG - receive_datagram - From ('192.168.1.37', 5683), To None, NON-52186, CONTENT-CQ, [Content-Type: 50, ] {"status":"failed"}...19 bytes
2020-02-03 17:27:09,111 - Thread-1 - coapthon.layers.messagelayer - DEBUG - receive_response - From ('192.168.1.37', 5683), To None, NON-52186, CONTENT-CQ, [Content-Type: 50, ] {"status":"failed"}...19 bytes
2020-02-03 17:27:09,112 - Thread-1 - coapthon.client.coap - DEBUG - Waiting for retransmit thread to finish ...
2020-02-03 17:27:09,112 - MainThread-Retry-52186 - coapthon.client.coap - DEBUG - retransmit loop ... exit
2020-02-03 17:27:09,222 - Thread-1 - coapthon.client.coap - DEBUG - Exiting receiver Thread due to request
PPS: After having second look onto your pcap file, it looks like your app/device sends different coap messages than mine does. Also i saw in your pcap that your device is using firmware 1.4 and mine use 0.2.1. When did you buy your device? Did you connect it to Cloud, did any OTA? (for comparison: I bought my device on Monday from Amazon, never connected to Cloud, never did OTA)
I bought my AC3829/10 on Amazon in November and connected to it using the Air Matters app from my Android phone. I've never confirmed any updates, but it's possible that it's running in the background.
PPPS: After taking a look into your responses from GET /sys/dev/status, it looks like the json response may be encrypted. Mine is plain
Yes, it looks like CoAP over TLS. I signed out of the Phillips account on Air Matters and tried to capture the communication again according to the recommended procedure:
- Start capturing from mobile device
- Open App
- Click on Device
- Set ChildLock On/Off + Power On/Off
- Stop Capturing from mobile device
I guess the key to encrypt the payloads is stored in the cloud now. Currently dont have an idea how to proceed. Would be interesting if anyone with philips cloud can sniff their http(s) traffic and decrypt their encrypted traffic via https://www.charlesproxy.com for example to see if my guess if correct. Maybe we can do calls to the cloud to get the key 🤔
Hi, I'm trying to comunicate with above script PHILIPS AC3829/10 (wifi) but when typing "--protocol coap" the code give me this: error: unrecognized arguments: --protocol coap Any idea why i cant change it?
Hi, I'm trying to comunicate with above script PHILIPS AC3829/10 (wifi) but when typing "--protocol coap" the code give me this: error: unrecognized arguments: --protocol coap Any idea why i cant change it?
I haven't released a pypi package with these changes because they are unstable and work only for one person so far. If you want to try it out, please use the latest code from GitHub.
Thx! Tried, but with no success. "--protocol coap" gives nothing for me also.
I guess the key to encrypt the payloads is stored in the cloud now. Currently dont have an idea how to proceed. Would be interesting if anyone with philips cloud can sniff their http(s) traffic and decrypt their encrypted traffic via https://www.charlesproxy.com for example to see if my guess if correct. Maybe we can do calls to the cloud to get the key 🤔
Ok, i got a AC3259/10 which seems to be also on the COAP Protocol, what do i need to do to get the neccessary information?
Ok i just did a port scan, everything is closed, any ideas?
I guess the key to encrypt the payloads is stored in the cloud now.
No, that is not possible. The AES-128-CBC key and IV is probably derived from the coap message ID. Otherwise the communication between the devices would not work offline.
Ok i just did a port scan, everything is closed, any ideas?
nmap -p U:5683 -sU --script coap-resources <target>
Capturing the network traffic won't be enough here. You need to reverse the mobile app like I did for the HTTP devices.
hi
thank you for your work today received 2 philips models it isvpossible to control it via cloud with support message generated from philips android apk? it is possible to use direct calls without cloud?
Appliance: Appliance Name: Biuro ID: 297a9a9aadd911e9a1e306... Paired: true Firmware Version: AWS_Philips_AIR@51.1 Device Version: 1.4.0 Model: AC3829/50Model: AC3829 - AC3829/50
Appliance: Appliance Name: Pokój ID: e975430aa3ba11e9a1e30... Paired: true Firmware Version: AWS_Philips_AIR@51.1 Device Version: 0.2.1 Model: AC2729/50Model: AC2729 - AC2729/50
@rgerganov as you can see I have 2 devices with two device versions ..how can I help you with your reverse eng?
@rgerganov as you can see I have 2 devices with two device versions ..how can I help you with your reverse eng?
If you are located in Europe you can borrow me a device for a week or two. I won't be able to do this remotely, sorry ...
@rgerganov Where do you live? I am located in the western part of germany.
@rgerganov Where do you live? I am located in the western part of germany.
I am based in Sofia, Bulgaria
It looks a little more complicated than that. The message itself is encrypted AES-CBC. The key and IV seems to be derived from the COAP message ID. However, a simple replay attack does not work here because the COAP Message ID is synchronized (POST /sys/dev/sync
). After every message, the client sends an empty message to the server to stay syncronized.
Hey guys. I've been observing this issue as well as I've just got the Philips AC2889 delivered about a week ago and I've not connected it to any wifi at all until now where I connected it to a 'jail' wifi network with no internet access for my home automation devices. Unfortunately, I am not able to control it via port 80 nor via port 30123 as both are closed. I had to use the app to get it to connect to the wifi. Considering that my device hasn't touched the internet yet. Is there a way I can help? I'd really like it to work with Home Assistant as otherwise the 'connected' feature is useless. I still don't understand why companies don't provide open APIs for their devices.
Hello there!
I have such error: "ConnectionRefusedError: [Errno 111] Connection refused" when trying to connect to AC5659. It is visible right after: Exchanging secret key with the device ...
It doesn't matter which command I'm trying to send (even --debug)
Does anyone know how to fix this? I see this device in AirMatter app and I can connect without any problems, so its connected to my wifi.