Работаем с датчиком CO₂ Xiaomi ClearGrass Air Detector локально, без китайских серверов

  • Tutorial


Давно планировал внедрить в домашнюю автоматизацию датчик углекислого газа CO₂. По соотношению цена/качество/функции/внешний вид лучшим для меня оказался Xiaomi ClearGrass Air Detector. Анализатор качества воздуха содержит датчики:

  1. CO₂
  2. tVOC (летучие органические соединения)
  3. PM2.5
  4. Температуры
  5. Влажности

У ClearGrass качественный экран с большими углами обзора и аккумулятор на 6 часов автономной работы. Цена в районе 130$ за такой девайс переводит его в сегмент маст хэв! Большой обзор можно почитать на mysku.ru.

Анализатор можно добавить в родное приложение qingping+ или MiHome, в обоих случаях данные ходят через китайские сервера, что меня категорически не устраивало. Я решил разобраться, как можно получить данные с датчика локально без использования сторонних удаленных серверов.

1. Изучение трафика


Первым делом нужно было посмотреть, как ClearGrass передает данные в приложение qingping+. ClearGrass подключается к интернет по Wi-Fi. Чтобы слушать трафик я поднял на Raspberry Pi Wi-Fi точку доступа и запустил tcpdump собирать информацию:

sudo tcpdump -i wlan0 -vv -s0 -X -n port 1883 -s 65535 -w cleargrass.pcap

Анализ трафика показал, что ClearGrass обращается примерно к 5 разным IP адресам, а на 154.8.191.174 передает в незашифрованном виде по протоколу MQTT данные о качестве воздуха.



2. Заворачиваем трафик с ClearGrass на Raspberry Pi


Немного поэкспериментировав с iptables я пришел к такому правилу:

sudo iptables -i wlan0 -t nat -A PREROUTING -s 192.168.115.19 -j REDIRECT

Читается оно так: «Весь новый трафик на интерфейсе wlan0 от 192.168.115.19 (IP ClearGrass) перенаправлять локально». Я не большой знаток iptables, поэтому буду рад предложениям и улучшениям. В этом правиле есть минус, если анализатор уже подключен к Raspberry Pi, то трафик не будет перенаправляться. Сначала нужно запустить правило и только затем подключить ClearGrass к Raspberry Pi по Wi-Fi.

В итоге, подняв MQTT брокер mosquitto на Raspberry Pi я увидел, что анализатор передает данные о качестве воздуха раз в минуты.

3. MQTT нано-брокер на JS для домашней автоматизации Z-Way


В качестве сервера домашней автоматизации я использую Z-Way, который поддерживает множество Z-Wave устройств и возможность писать скрипты на JS.



К сожалению для Z-Way нет MQTT брокера на JS (в отличие от систем на базе node.js), поэтому я решил написать минимальные брокер, который только принимает данные от этого анализатора и ничего больше не умеет. Не читая особо документацию я посмотрел на общение между анализатором и mosquitto и составил следующую последовательность:

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

В итоге родился простой JS скрипт:

mqttSocket.reusable();
mqttSocket.bind(1883);
mqttSocket.onrecv = function(data, host, port) {
	var arr = new Uint8Array(data);

	switch(arr[0]) {
		// PING
		case 0xC0:
			console.log("---------- MQTT PING RESPONSE");
			this.send([0xD0, 0x00]);
			break;
		// CONNECT
		case 0x10:
			console.log("---------- MQTT CONNECT ACK");
			this.send([0x20, 0x02, 0x00, 0x00]);
			break;
		// SUBSCRIBE
		case 0x82:
			console.log("---------- MQTT SUBSCRIBE ACK");
			this.send([0x90, 0x03, arr[2], arr[3], 0x00]);
			break;
		// PUBLISH
		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();

Конечно пока многое не учитывается, например в одной посылке, может прийти и PING, и MESSAGE, а я что-то из этого пропущу. Возможно в будущем я использую кодовую базу aedes для создания MQTT брокера для Z-Way. А на данный момент целью была принципиальная возможность получить локально данные о качестве воздуха с анализатора Xiaomi ClearGrass Air Detector и эта цель достигнута.

В перспективе хочу установить Z-Wave версию бризера TION S3 и управлять им основываясь на данных от ClearGrass.
Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 17

    0
    На хабре упоминали, что можно снимать показания с помощью python-miio. Не пробовали такой подход?
      0
      python-miio это то, что я попробовал первым делом. Чтобы заработала python-miio нужно из приложения mihome на телефоне вытащить токен, для этого на комп нужно сделать не зашифрованный бэкап, у меня выходило 50 Гб, столько места не было на компе и проще оказалось найти другой телефон. Я вытащил бэкап, с помощью токена подключился к 1 раз ClearGrass и второй раз уже не смогу. Я опять сделал бэкап и вытащил токен, но он уже был другой. Опять подключился успешно 1 раз, на второй раз уже не подключалось. Третий раз сделал бэкап, токен поменялся. Возможно это защита. Т.е. python-miio не работает с ClearGrass таким способом. Хотелось бы, конечно вариант попроще.
        0
        Есть модифицированная версия Mi Home, которая в информации об устройстве указывает токен.
          0

          Это работает только на Android.

            +1

            Токен можно вытащить при помощи mitm на телефон. Я использовал sslsplit. Тоже не хотелось запариваться с бэкапом.

          0

          А как работает эта библиотека? Перехватывает трафик от устройства на китайский сервер? Т.е. при использовании библиотеки, что мешает устройству слать телеметрию в Китай?

            0
            Устройство так и шлет данные в китай, но еще должно отвечать на локальные запросы.
              0
              Я своим запретил выходить в интернет, разрешена только локальная сеть. Все данные у меня собираются в InfluxDB, что даёт визуализировать их в графане. Минус — сценарии тоже на питоне писать надо, родные только через облако работают.

              Графана


              Мой проект есть на github, но там всё не очень красиво. Сначала написал свою обёртку над gateway LAN API, потом увидел готовые реализации :)
                0
                Обновился на днях до версии 3.4.5_0142, заметил
                Settings — Server
                — China Mainland
                — Abroad
                Вот только непонятно, что во втором пункте имеется ввиду.
          0

          Кажется, должны быть варианты попроще, потому что вот тут люди брали готовую библиотеку на python и тащили данные к себе в прометей: https://habr.com/ru/post/482352/#comment_21085236
          Возможно, есть вариант опрашивать сам девайс.
          P.S> Меня уже опередили выше с таким же комментарием!

            0
            Мне кажется проще и дешевле датчики на рассыпухе взять и описание к ним есть сразу…
              0
              Ну нет, хороший дизайн, качественный экран, профессиональный датчик CO2, вряд ли самому дешевле получится. Еще и время сколько. Я в свое время уже надел датчиков, сейчас уже лень.
                0
                за 130$ можно купить пару scd30 или гору s8… И зачем там экран, если вы хотите куда-то интегрировать?
                  0
                  Так и экран полезен, иногда поглядываю на него.
                    0
                    За сотку можно китайский смартфон купить и гору датчиков на него вывести.
              0

              Я правильно понимаю, что трюк с заворачиванием трафика можно в любом случае провернуть только после регистрации устройства у китайцев (чтобы оно начало отправлять данные)?

                0
                Не могу точно сказать, как минимум я один раз проверил, что что анализатор работает с оригинальным приложением. А потом уже посмотрел трафик и он постоянно передает данные на китайский сервер, хотя сейчас анализатор ни к чему не привязан.

              Only users with full accounts can post comments. Log in, please.