For a long time I planned to introduce a carbon dioxide sensor CO₂ in home automation. In terms of price / quality / function / appearance, Xiaomi ClearGrass Air Detector turned out to be the best for me. The air quality analyzer contains sensors:- CO₂
- tVOC (volatile organic compounds)
- PM2.5
- Temperature
- Humidity
ClearGrass has a high-quality screen with large viewing angles and a battery for 6 hours of battery life. The price in the region of $ 130 for such a device translates it into the must-have segment! Great review can be read on mysku.ru .The analyzer can be added to the native qingping + or MiHome application , in both cases the data goes through Chinese servers, which categorically did not suit me. I decided to figure out how to get data from the sensor locally without using third-party remote servers.1. Study traffic
The first step was to see how ClearGrass transfers data to the qingping + application . ClearGrass connects to the Internet via Wi-Fi. To listen to traffic, I raised an access point on the Raspberry Pi Wi-Fi and started tcpdump to collect information:sudo tcpdump -i wlan0 -vv -s0 -X -n port 1883 -s 65535 -w cleargrass.pcap
Analysis of traffic showed that ClearGrass accesses approximately 5 different IP addresses, and on 154.8.191.174 it transmits air quality data unencrypted using the MQTT protocol .
2. We wrap traffic from ClearGrass on the Raspberry Pi
Having experimented a bit with iptables, I came to this rule:sudo iptables -i wlan0 -t nat -A PREROUTING -s 192.168.115.19 -j REDIRECT
It reads like this: "All new traffic on the wlan0 interface from 192.168.115.19 (IP ClearGrass) should be redirected locally." I am not a big connoisseur of iptables, so I will be glad to suggestions and improvements. There is a minus in this rule, if the analyzer is already connected to the Raspberry Pi, then the traffic will not be redirected. First you need to run the rule and only then connect ClearGrass to the Raspberry Pi via Wi-Fi.As a result, having picked up the MQTT mosquitto broker on the Raspberry Pi, I saw that the analyzer transmits air quality data once a minute.3. MQTT nano-broker on JS for home automation Z-Way
As a home automation server, I use Z-Way, which supports many Z-Wave devices and the ability to write scripts in JS.
Unfortunately for Z-Way there is no MQTT broker in JS (unlike systems based on node.js), so I decided to write a minimal broker that only accepts data from this analyzer and can’t do anything else. Without particularly reading the documentation, I looked at the communication between the analyzer and mosquitto and compiled the following sequence:MQTT PROTOCOL
Connect Command (sensor -> broker)
0x10 - Connect Command
Connect Ack (broker -> sensor)
0x20 - Connect Ack
0x02 - Len 2
0x00
0x00 - Connection Accepted
Subscribe Request (sensor -> broker)
0x82 - 0b1000 0010; 0b1000 - Subscribe Request
Subscribe Ack (broker -> sensor)
0x90 - 0b1001 0000; 0b1001 - Subscribe Ack
0x03 - Len 3
0x00
0x08 - Message identifier 8
0x00 - Fire and Forget
Ping Request (sensor -> broker)
0xC0 - Ping Request
0x00 - Len 0
Ping Response (broker -> sensor)
0xD0 - Ping Response
0x00 - Len 0
Publish Message (sensor -> broker)
0x30 - Publish Message
0x96
0x04 - Len 534
As a result, a simple JS script was born:mqttSocket.reusable();
mqttSocket.bind(1883);
mqttSocket.onrecv = function(data, host, port) {
var arr = new Uint8Array(data);
switch(arr[0]) {
case 0xC0:
console.log("---------- MQTT PING RESPONSE");
this.send([0xD0, 0x00]);
break;
case 0x10:
console.log("---------- MQTT CONNECT ACK");
this.send([0x20, 0x02, 0x00, 0x00]);
break;
case 0x82:
console.log("---------- MQTT SUBSCRIBE ACK");
this.send([0x90, 0x03, arr[2], arr[3], 0x00]);
break;
case 0x30:
var sensorPayload = self.getPayload(arr);
var sensorMessage = sensorPayload.substr(sensorPayload.indexOf('{'), sensorPayload.lastIndexOf('}'));
var sensorObj = JSON.parse(sensorMessage);
console.logJS("---------- MQTT MESSAGE:", sensorObj);
console.logJS("---------- CO2: ", sensorObj.data.co2);
self.vDevCO2.set("metrics:level", sensorObj.data.co2);
break;
}
};
mqttSocket.listen();
Of course, while much is not taken into account, for example, in one premise, both PING and MESSAGE may come, but I will miss some of this. Perhaps in the future I will use the aedes code base to create an MQTT broker for Z-Way. And at the moment, the goal was the fundamental opportunity to get locally air quality data from the Xiaomi ClearGrass Air Detector analyzer and this goal was achieved.In the future I want to install the Z-Wave version of the TION S3 breather and control it based on data from ClearGrass.