
Новый датчик температуры/влажности с часами на электронных чернилах с BLE от Xiaomi появился в продаже относительно недавно. На вид это скорее часы, нежели датчик температуры и влажности – большую часть экрана занимают показания часов, а показания температуры и влажности пристроились скромно внизу вместе с индикатором комфорта, стилизованного под рожицу. Обзоров этих часов в инете хватает, здесь, например.
Часы довольно симпатичные, мне понравились. К Mihome подключились без проблем. Стало интересно, можно ли передавать показания датчиков в систему «умного дома» Domoticz.
Поиск вывел на сайт, где автор подробно расписал, как получить данные с этих часов.
У меня Domoticz установлен на raspberry pi 3 и первое, что попробовал — связаться с часами по блютузу, для этого наколхозил скрипт на python3:
#!/usr/bin/env python3 # -*- coding: utf-8 -*- from bluepy import btle import struct mac_addr_LYWSD02 = ‘3F:59:C8:61:10:CF’ class MyDelegate(btle.DefaultDelegate): def handleNotification(self, cHandle, data): global HUM global TEMP HUM = data[2] TEMP = struct.unpack(‘h’, data[:2])[0] / 100 p = btle.Peripheral(mac_addr_LYWSD02) p.setDelegate(MyDelegate()) uuid = ‘EBE0CCC1-7A0A-4B0C-8A1A-6FF2997DA3A6’ ch = p.getCharacteristics(uuid=uuid)[0] desc = ch.getDescriptors(forUUID=0x2902)[0] desc.write(0x01.to_bytes(2, byteorder=»little»), withResponse=True) print («LYWSD02″) i = 0 while True: HUM = 0 TEMP = 0 p.waitForNotifications(1) i += 1 print(i,»T =»,TEMP,»*C, H =», HUM,»%») if i >= 20 : break p.disconnect()

Bluetooth часы Xiaomi Mijia с Е-Ink экраном и датчиком температуры и влажности (LYWSD02MMC)
В строке mac_addr_LYWSD02 = ‘xx:xx:xx:xx:xx:xx’ необходимо прописать MAC адрес своих часов, его можно посмотреть в приложении Mihome:
В результате (не сразу, конечно 🙂 увидел следующие:
[email protected]:/home/pi/domoticz/devices/lywsd02mmc# python3 test.py LYWSD02 1 T = 0 *C, H = 0 % 2 T = 0 *C, H = 0 % 3 T = 26.11 *C, H = 44 % 4 T = 0 *C, H = 0 % 5 T = 0 *C, H = 0 % 6 T = 0 *C, H = 0 % 7 T = 0 *C, H = 0 % 8 T = 0 *C, H = 0 % 9 T = 26.08 *C, H = 44 % 10 T = 0 *C, H = 0 % 11 T = 0 *C, H = 0 % 12 T = 0 *C, H = 0 % 13 T = 0 *C, H = 0 % 14 T = 0 *C, H = 0 % 15 T = 26.08 *C, H = 44 % 16 T = 0 *C, H = 0 % 17 T = 0 *C, H = 0 % 18 T = 0 *C, H = 0 % 19 T = 0 *C, H = 0 % 20 T = 0 *C, H = 0 % [email protected]:/home/pi/domoticz/devices/lywsd02mmc#
Нулевые значения получились, потому что 1 сек мало для времени ожидания ответа в waitForNotifications(timeout). Подробнее можно посмотреть здесь.Теперь можно было подумать о связке с Domoticz. В оборудовании добавил Dummy (Does nothing, use for virtual switches only): 
Затем создал виртуальный датчик температуры/влажности:
Градусник Xiaomi lywsd03mmc. Прошивка и настройка его в Home Assistant.
В устройствах надо посмотреть Idx датчика, в моем случае 27:
Теперь попробуем новому датчику передать данные. В адресной строке браузера пишем:
http://192.168.8.10:8080/json.htm?type=commandidx=27svalue=25;38;0
192.168.8.10:8080 – адрес Domoticz; idx=27 – индекс датчика. Подробнее можно почитать здесь. В результате должны получить: 
А в датчике появятся переданные значения температуры и влажности:
Все функционирует, осталось собрать воедино. Опять же наколхозил скрипт:
#!/usr/bin/env python3 # -*- coding: utf-8 -*- domoticzserver = ‘127.0.0.1:8080’ domoticzusername = ‘Admin’ domoticzpassword = ‘admin’ IDX = ’27’ mac_addr_LYWSD02 = ‘3F:59:C8:61:10:CF’ from bluepy import btle import struct import urllib.request import base64 class MyDelegate(btle.DefaultDelegate): def handleNotification(self, cHandle, data): global HUM global TEMP HUM = data[2] TEMP = struct.unpack(‘h’, data[:2])[0] / 100 def _encodeBase64(consumer_key, consumer_secret): dummy_param_name = ‘bla’ key_url_encoded = urllib.parse.urlencode()[len(dummy_param_name) + 1:] secret_url_encoded = urllib.parse.urlencode()[len(dummy_param_name) + 1:] credentials = ‘<>:<>’.format(key_url_encoded, secret_url_encoded) bytes_base64_encoded_credentials = base64.encodebytes(credentials.encode(‘utf-8’)) return bytes_base64_encoded_credentials.decode(‘utf-8’).replace(‘n’, ») def domoticzrequest (url): request = urllib.request.Request(url) request.add_header(«Authorization», «Basic %s» % base64string) response = urllib.request.urlopen(request) respond = response.read() response.close() return respond p = btle.Peripheral(mac_addr_LYWSD02) p.setDelegate(MyDelegate()) uuid = ‘EBE0CCC1-7A0A-4B0C-8A1A-6FF2997DA3A6’ ch = p.getCharacteristics(uuid=uuid)[0] desc = ch.getDescriptors(forUUID=0x2902)[0] desc.write(0x01.to_bytes(2, byteorder=»little»), withResponse=True) print («LYWSD02″) i = 0 HUM = 0 TEMP = 0 while not p.waitForNotifications(5): i += 1 if i >= 20 : break p.disconnect() print(i,»T =»,TEMP,»*C, H =», HUM,»%») base64string = _encodeBase64(domoticzusername, domoticzpassword) HUM_STAT = «0» # Норма if HUM > 85: HUM_STAT = «3» # Влажно elif HUM < 20: HUM_STAT = «2» # Сухо elif HUM = 40: HUM_STAT = «1» # Комфортно print(domoticzrequest(«http://» + domoticzserver + «/json.htm?type=commandidx=» + IDX + «svalue=» + str(TEMP)[:4] + «;» + str(HUM) + «;» + HUM_STAT))

В начале скрипта необходимо прописать свои данные:
Скрипт я назвал lywsd02.py и поместил в :/home/pi/domoticz/devices/lywsd02mmc. При запуске, если все хорошо, в датчике отобразятся данные с часов, а в консоли увидим:
[email protected]:/home/pi/domoticz/devices/lywsd02mmc# python3 lywsd02.py LYWSD02 0 T = 26.12 *C, H = 44 % b’n’ [email protected]:/home/pi/domoticz/devices/lywsd02mmc# # Здесь во второй строчке данные полученные от часов, в третьей строчке ответ от Domoticz
Ну и осталась самая малость — прописать запуск скрипта каждый час в cron:
# Даем права на исполение: [email protected]:~/domoticz/devices/lywsd02mmc $ sudo chmod 755 lywsd02.py # Теперь пропишем запуск скрипта в cron: [email protected]:~/domoticz/devices/lywsd02mmc $ sudo crontab -e # В nano правим: в начале вставляем строчку MAILTO=»» # в конце дописывам: 0 * * * * /home/pi/domoticz/devices/lywsd02mmc/lywsd02.py > /dev/null 2>>:<>’.format(key_url_encoded, secret_url_encoded) bytes_base64_encoded_credentials = base64.encodebytes(credentials.encode(‘utf-8’)) return bytes_base64_encoded_credentials.decode(‘utf-8’).replace(‘n’, ») def domoticzrequest (url): request = urllib.request.Request(url) request.add_header(«Authorization», «Basic %s» % base64string) response = urllib.request.urlopen(request) respond = response.read() response.close() return respond p = btle.Peripheral(mac_addr_LYWSD02) p.setDelegate(MyDelegate()) uuid = ‘EBE0CCC1-7A0A-4B0C-8A1A-6FF2997DA3A6’ ch = p.getCharacteristics(uuid=uuid)[0] desc = ch.getDescriptors(forUUID=0x2902)[0] desc.write(0x01.to_bytes(2, byteorder=»little»), withResponse=True) print («LYWSD02″) i = 0 HUM = 0 TEMP = 0 while not p.waitForNotifications(5): i += 1 if i >= 20 : break batt = p.readCharacteristic(0x0052) battlev = struct.unpack(‘B’, batt)[0] p.disconnect() print(i,»T =»,TEMP,»*C, H =», HUM,»% BATT = «, battlev, «%» ) base64string = _encodeBase64(domoticzusername, domoticzpassword) HUM_STAT = «0» # Норма if HUM > 85: HUM_STAT = «3» # Влажно elif HUM < 20: HUM_STAT = «2» # Сухо elif HUM = 40: HUM_STAT = «1» # Комфортно print(domoticzrequest(«http://» + domoticzserver + «/json.htm?type=commandidx=» + IDX + «svalue=» + str(TEMP)[:4] + «;» + str(HUM) + «;» + HUM_STAT + » + str(battlev)))
Отобразить значение температуры на экране часов в градусах Фарингейта можно записав по handle: 0x0049 значение 0x01 (0xFF — отображение в градусах Цельсия).
Ну и собственно, значение текущего времени можно прочитать по handle: 0x003e. Получим 5 bytes, первые четыре — время в секундах от 00:00:00 01.01.1970, последний байт — временная зона.
Вот пример скрипта для синхронизации часов с от RTC малинки
#!/usr/bin/env python3 import time from bluepy import btle import struct tzlocal = 3 print(«LYWSD02 time update») mac = ‘3F:59:C8:61:10:CF’ p = btle.Peripheral(mac) data_r = p.readCharacteristic(0x003e) print(«Read(0x003e) = «, data_r) print («LYWSD02 time: «, time.ctime(struct.unpack(‘I’, data_r[:4])[0])) print(«Sistem time:», time.ctime()) sis_time = int(time.time()) data_w = struct.pack(»
Добавить в избранное Понравилось +67 +110
- 03 ноября 2019, 21:57
- автор: 0poK
- просмотры: 11705
Источник: mysku.me
Xiaomi датчики температуры и влажности Bluetooth в HomeBridge, получение bindKey
В начале года я писал статью «Сравнение датчиков температуры и влажности (Bluetooth)», а сегодня я расскажу, как добавить эти датчики в HomeBridge (по аналогии можно добавить и в Home Assistant).
Первое, что необходимо сделать — это установить плагин Homebridge Mi Hygrothermograph, можно через Web-интерфейс самого бриджа.

Далее необходимо установить библиотеки и их зависимости, необходимые для Noble и обеспечивающие доступ к подсистеме Bluetooth:
sudo apt-get install bluetooth bluez libbluetooth-dev libudev-dev
После чего, нам необходимо получить MAC-адреса наших датчиков, тут можно пойти по одному из двух путей.
- Посмотреть в приложении Mi Home. Для этого открываем приложение Mi Home, находим наш датчик, в правом верхнем углу три точки, About -> MAC adress.
- Отсканировать BLE устройства. Открываем терминал нашей малины, пишем команду:
sudo hcitool lescan

Видим перечень всех Bluetooth устройств в зоне видимости нашей Raspberry Pi.
Если после ввода команды sudo hcitool lescan мы видим ошибку, а она возникает из-за того, что интерфейс Bluetooth занят, нам необходимо перезагрузить этот интерфейс.
Делается это командой:
sudo systemctl restart bluetooth

Итак, приступим к добавлению устройств в HomeBridge.
Пойдем по пути от простого к сложному. А простым у нас, как ни странно, является добавление часов LYWSD02MMC.
Для добавления часов в HomeBridge, нам необходимо всего лишь знать его MAC-адрес. После чего добавляем в конфиг новый аксессуар:
Далее перезагружаем HomeBridge и ждем, пока у устройства обновится температура, это происходит 1 раз в 10 минут.
Для добавления Датчика LYWSD03MMC, нам необходим не только MAC-адрес, но и bindKey.
Получение bindKey
Для получение bindKey необходимо проделать следующее.
Первое, что необходимо, — установить приложение Stream на наше iOS устройство. Далее:
Откройте Stream -> HTTPS Sniffing -> CA Install. Затем вы будете перенаправлены в браузер для загрузки профиля VPN. Перейдите в Общие -> Профиль -> Stream Generated CA. -> Установите профиль VPN.
После установки профиля VPN:
Открываем Stream -> HTTPS Sniffing -> нажимаем «CA Installed Об этом устройстве -> Доверие сертификатам -> Stream Generated CA… в положение включено.



Второе. Открываем Mi Home, логинимся (если это еще не было сделано), обязательно указываем регион материковый Китай.
- Открываем приложение Stream, нажимаем «Sniff Now». Сразу же переходим в Mi Home, начинаем добавление датчика (процедура добавления стандартная). Дождитесь, пока в плагине отобразится температура и влажность.
- Возвращаемся в Stream и нажимаем «Stop Sniffing». На все про все у меня тратится чуть больше минуты.
- Далее нажимаем «Sniff History» и выполняем поиск по ключевому слову «bltbind». Если поиск дал положительный результат, нажимаем «Edit» -> выделяем все файлы и нажимаем «Export HAR». Экспортируем любым привычным способом на свой компьютер.
Третье, уже на компьютере. На сайте Charles Proxy скачиваем свежую версию программы. Запускаем (триал версия на 30 дней).
- Файл -> открыть наш архив HAR, экспортированный с iOS.
- Далее в поиске пишем bind_key.
Чтобы не описывать, где и что нужно выбрать, приведу скриншот.

Я вас поздравляю, это было долгое и мучительное получение заветного ключа, но мы это сделали и можем приступать к добавлению датчика в HomeBridge.
Открываем конфиг и добавляем новый аксессуар.
Для добавление в Home Assistant, добавляем в конфиг:
— platform: mitemp_bt encryptors: ‘A4:C1:38:07:A6:6C’: ‘697F650A6599839DF96A68B84D2C1841’
Xiaomi ClearGrass CGD1
Будильник Xiaomi ClearGrass CGD1 добавляется абсолютно так же, как и предыдущее устройство (для добавления необходимо получить bindKey). В приложении Apple HomeKit отображается как датчик температуры/влажности.
Mi Home
Неоспоримым преимуществом является то, что эти датчики, после добавления в альтернативную систему автоматизации, остаются в приложении Mi Home и могут участвовать в автоматизациях.
Небольшая ложка дегтя
Не обошлось и без недостатков. Привязанные датчики в Raspberry Pi не могут создавать BLE Mesh, датчики подключаются напрямую к малине. Поэтому важно, чтобы малинка располагалась в непосредственной близости к датчикам.
Итог
У меня четыре датчика, расположенных в квартире, один из них находится в ванной. Малинка находится на балконе. Вот именно тот датчик, который в ванной, и не достает. В дальнейшем думаю решить проблему внешним Bluetooth — USB свистком. В остальном меня все устраивает, за три месяца не было ни одного сбоя.
При этом в Mi Home они продолжают работать и участвовать в автоматизациях.
Источник: sprut.ai
Lywsd02mmc xiaomi не подключается
Опция BT HUB для приема данных с разнообразных Bluetooth датчиков и устройств через GATT (Generic Attribute Profile) — профиль общих атрибутов.
ESP32 и ESP32C3: Опция использует встроенный в чип Bluetooth контроллер. В SDK 4.3 и выше или при включенной PSRAM используется стек NimBLE.
Linux: На данный момент поддерживается только на ARM профилях. Поддержки шифрования Xiaomi на данный момент нет. В ОС должна быть поддержка bluetooth.
Принятые данные видны подробно в UART отладке. Поддерживаемые датчики доступны на главной странице и на всех серверах/сервисах. В Free режиме доступно только UART вывод информации, включая вывод данных с поддерживаемых датчиков.







На данный момент доступно чтение Xiaomi устройств: MJ_HT_V1, CGG1, MiFlora, LYWSD02, LYWSD03(LYWSD03MMC), CGD1, MiKettle, а также BLE датчики фирмы Inkbird и датчики Tilt гидрометр/термометр (включается в шестеренке). Возможна частичная или полноценная работа и других датчиков и устройств Xiaomi — может требоваться доработка. Жду от пользователей отладочных данных от других устройств для добавления в проект.
Для включения опции требуется переразметка памяти, если модуль прошит с нуля до 09.05.20, чтобы опция влезла в модуль с 4 мб flash . Документация по ESP32 Опция очень ресурсоёмкая, занимает много flash памяти и ОЗУ. ОЗУ может не хватать при работе с другими ресурсоёмкими опциями (icq, telegram, Email, интернет-радио, mqtt и др.) — в таком случае могут быть ошибки сборки или не стабильность в работе.
Последние новости и обновления опции
30.05.2020 — добавлена поддержка шифрованных датчиков LYWSD03MMC.
10.07.2020 — добавлена поддержка MiKettle
23.01.2021 — добавлена поддержка датчиков Inkbird
06.10.2021 — добавлена поддержка приема от сторонних прошивок LYWSD03MMC, MHO-C401, CGG1.
Настройка BT HUB в Веб
В веб модуле имеются следующие настройки:

Enable BLE Hub — Включение опции.
Enable auto added device — Автоматический поиск и добавление поддерживаемых опцией датчиков, новый датчик добавляется в список ниже в первую пустую ячейку (пустая — это ячейка заполненная 00 или FF). Не работает с шифрованными датчиками. Ждать добавления датчика можно до 11 минут — такой интервал чаще всего у Xiaomi датчиков с родной прошивкой.
Enable RAW filter — Фильтр МАС адресов для режима приема RAW (не определенных) данных в UART отладке и в MQTT. Список адресов по ссылке: filter
Filter black list mode — Использование черного списка вместо белого в фильтре.
Debug UART level — Уровень вывода отладки в UART:
1 — Только знакомые датчики;
2 — Все несущие полезную информацию типы данных;
Debug print RAW level — Уровень вывода RAW отладки на веб вкладке модуля:
2 — Все несущие полезную информацию типы данных;
Send Mqtt RAW level — Уровень отправки RAW в MQTT:
1 — Все несущие полезную информацию типы данных;
2 — Все типы данных;
3 — Полный пакет данных с устройства.
Если в эфире находится очень большое количество устройств, то их данные при включенной отправке в UART и в MQTT может приводить к сбоям в работе прошивки, используйте фильтры, чтобы отделить полезную информацию и снизить нагрузку на модуль. Крайне рекомендуется в опции MQTT включать отдельные топики при приеме большого потока данных.
В нижней части странички находится список устройств, которые поддерживает опция. Для очистки ячейки достаточно удалить её содержимое и сохранить.
Сторонние прошивки на LYWSD03MMC, MHO-C401, CGG1
Сторонние прошивки позволяют реализовать обмен данными по более оптимальном режиму отправки данных и экономии батареи. Прошивки по умолчанию не используют шифрование данных.
Для LYWSD03MMC существует 2 варианта прошивок:
1. Автор Atc1441, ссылка на прошивку. Веб программатор TelinkFlasher. Настройки интервала.
2. Автор pvvx, ссылка на прошивки. Веб программатор. Можно установить пин код для защиты. Множество настроек. + Доступны прошивки для MHO-C401 и CGG1
Обратите внимание, что сейчас в продаже появились другие аппаратные версии LYWSD03MMC HW: B1.6 и B1.9 — новые прошивки от pvvx их сейчас поддерживают.
Чтение зашифрованных данных датчиков Xiaomi
Испытано на LYWSD03MMC и CGD1, возможно сейчас все новые устройства идут с шифрованием. Опция включается дополнительно в шестеренке. Ключ требуется ввести на специальной странице ключей в соответствующее поля по номеру устройства.
Если заменить прошивку на неофициальную, то ключ не требуется.
Считать ключ можно 2 способами:
1. Использовать веб приложение Telink Flasher . Проверено работает на Андроид в Chrome , может работать и в других операционных системах (при разрешенных правах доступа к блютузу). Для получения ключа требуется на странице нажать Connect , далее выбрать устройство у которого требуется получить ключ, после успешного подключения нажимаем кнопку Do Activation — после этого ключ мы увидим в поле Mi Bind Key . Каждое нажатие на кнопку Do Autorization меняет ключ.
2. Патченное приложение Mi Home. (После установки приложения, не забываем проверить разрешения на запись, чтоб записались логи в телефон). Каждая синхронизация устройства меняет ключ датчика.
После сопряжения датчика со смартфоном в папке /vevs/logs/, которую предварительно там создали появятся файлы.


Bindkey вставить в поле с соответствующим Mac адресом!


Описание формата принимаемых данных GATT
Эта документация поможет пользователям для добавления устройств в проект или самостоятельной их обработки.
Принятый пакет содержит несколько типов данных с данными, его формат и далее данные повторяются, пока не встретиться длина равная 0 байт. Длина — это 1 байт тип + данные. Весь пакет можно принять через MQTT RAW level 3
От типа зависит назначение данных, документацию можно почитать на официальном сайте Bluetooth. В проекте в выводе RAW пакетов на данный момент полезными(несущими полезные данные) считаются типы:
0x16 — Service Data — 16-bit UUID. Узнать чей UUID можно тут.
0xFF — Manufacturer Specific Data.
Возможно и есть и другие типы, которые могут пригодиться, но пока такие не встречались.
Работа с данными в конструкторе кода
Пример кода для самостоятельной обработки данных с устройств через GATT:
void myBleHub(uint8_t *mac,uint8_t ad_type ,uint8_t len,uint8_t *data) < if(mac[4]==0xAA mac[5]==0xBB) // можно сравнивать МАС только последние 2 байта < if(ad_type==0x16) // принимаем Service Data — 16-bit UUID < if(*(uint16_t*)(data)==0xFEFF) // первые 2 байта — это номер UUID < //тут уже работаем с массивом data[] начиная с 2 байта uint32_t val1=*(uint32_t*)(data+2); // если первые данные в пакете это uint32_t число >> if(ad_type==0x48) // принимаем не опознанные данные на примере HA11 battery balancer equalize < valdes[0] = data[10]*256 + data[11]; valdes[1] = data[12]*256 + data[13]; >if(ad_type==0xFF) // принимаем Manufacturer Specific Data < //тут уже работаем с массивом data[] >> >
В стартовой функции задать строку cb_bthub_funs=myBleHub;
По порядку параметры принятые в функции: MAC адрес 6 байт, тип данных, длина принятых данных, сами данные.
Источник: wifi-iot.com

