Хабрахабр

[Из песочницы] Беспроводные устройства Xiaomi в умном доме ioBroker

Приветствую всех любителей домашней автоматизации. Решил поделиться опытом использования беспроводных Xiaomi устройств с интерфейсом ZigBee. Я, честно говоря, против применения любых беспроводных устройств в любой автоматизации, от серьезных АСУТП больших объектов до малой автоматики типа охранно-пожарной сигнализации или умного дома, но… Решения Xiaomi подкупили дешевизной, доступностью, отличным дизайном и множеством положительных отзывов от пользователей, решил попробовать.

Описанное здесь ни в коем случае не является аксиомой и можно найти много других способов подключения ZigBee устройств. Этот пост следует воспринимать, как пошаговую инструкцию для интеграции ZigBee устройств в инфраструктуру умного дома. Я расскажу в этой статье, как подключить устройства к умному дому, отобразить информацию с них на планшете или просто в браузере и отправить сообщения через телеграм о смене состояния устройств. Если всё же пропускать детальное описание, то можно составить впечатление о сложности или легкости объединения устройств от разных производителей в одну локальную платформу на примере ZigBee и ioBroker (о нём чуть позже). Однако уже давно известен способ активации режима разработчика в приложении для получения управляющего токена. Если я вас заинтересовал, то прошу под кат.
По замыслу производителя Xiaomi, пользователи должны использовать родное приложение с облачным подключением и Wi-Fi шлюз для устройств ZigBee. Таким образом внутри локальной сети можно общаться со шлюзом, что и позволяет проделать драйвер mihome, который идет в составе ioBroker.

Что такое ioBroker можно почитать в предыдущей статье. ioBroker — это открытая платформа для IoT, в том числе для построения систем типа «умный дом».

ОС Armbian установлена на жесткий диск с переносом корневого раздела, на карте памяти microSD остался только загрузчик. Сейчас мой умный дом «крутится» на ARM-плате Cubietruck с некоторым «обвесом» в виде жесткого диска на 80Гб, аккумуляторной батарей на 5000мАч, USB-мастера сети 1-wire, USB-RS485 преобразователя для опроса устройств по протоколу modbus.

На тот момент была единственная возможность их интеграции — драйвер mihome, который упоминался выше. Своё знакомство с беспроводными устройствами Xiaomi я начал с покупки датчиков температуры и влажности.

Драйвер mihome

Добавить драйвер в систему очень просто, нужно кликнуть на кнопке “+” в списке доступных драйверов и наблюдать процесс установки.

Итак, режим разработчика активирован, токен получен, настраиваем адаптер mihome, сохраняем и запускаем, если он не был запущен. Установку и первоначальную настройку родного Android-приложения Mi Home описывать не буду, можно посмотреть на странице github драйвера или в интернете.

В дереве объектов должен появиться шлюз Xiaomi и подключенные в приложении Mi Home устройства.

К примеру, хранение истории датчиков температуры и влажности. Далее можно настроить только что созданные объекты. Я использую для исторических данных драйвер SQL с настройкой на БД SQLite.

На вкладке «Настройки» у меня по сенсорам активировано хранение истории — только изменения переменной. Настройка хранения истории переменной производится в окне объектов системы: нужно в иерархии объектов добраться до самой переменной и нажать справа кнопку с гаечным ключом.

Другие настройки:

  • минимальный интервал 10 секунд — если переменная будет изменяться чаще, то запись в БД будет игнорироваться
  • запись значений каждые 300 секунд (5 минут) — если переменная не изменяется более 5 минут, в БД все равно запишется текущее значение
  • тип значения — число
  • срок хранения — 1 год

Т.е. Добавление новых устройств происходит через родное приложение. надо осуществить сопряжение нового девайса со шлюзом согласно прилагаемой инструкции и после этого он автоматически появится в списке объектов ioBroker.

Драйвер zigbee

Мне было неудобно пользоваться родным приложением Xiaomi, тем более что надо покупать шлюз с китайским штекером, который в моем случае, кроме как для общения с устройствами, ни для чего не пригодился. Да, его можно использовать как подсветку-ночник или задействовать в каких то сценариях датчик освещенности. В интернете можно найти инструкции как «скормить» шлюзу плейлист для воспроизведения собственных радиостанций, но у меня ничего из этого не прижилось. Плюс к этому, не давала покоя мысль, что мои данные куда-то утекают, где-то обрабатываются и хранятся.

На её базе был написан драйвер для ioBroker, причем автор этого драйвера не ограничился только устройствами Xiaomi, список поддерживаемых устройств постоянно дополняется и доступен на github странице проекта. Один из активных пользователей платформы ioBroker нашел в интернете библиотеку zigbee-shepherd на node.js, в которой было упоминание о подключении устройств Xiaomi.

Можно купить готовые ZigBee-модули как с подключением по USB и встроенной антенной, так и модели подороже-посерьезнее: с внешней антенной, усилителем, подключением через UART. В качестве координатора сети предполагается использовать недорогие готовые устройства на базе чипов CC25хх от TI.

Таким образом получается, что для работы этого драйвера не нужен дорогостоящий шлюз, не нужны сети Wi-Fi. Для работы с драйвером, надо только сменить прошивку. Через координатор происходит непосредственное общение zigbee-устройств и системы «Умный дом», а также привязка новых устройств. «Точкой входа» является координатор — устройство на базе чипа СС25хх со специальной прошивкой.

В качестве координатора я использую готовую плату на базе чипа СС2530 с внешней антенной, которую подключил к серверу через UART.

Для прошивки устройства был куплен специальный дебагер SmartRF04EB, порт microUSB которого я подключил к компьютеру, а модуль ZigBee подключил с помощью проводков для отладки по схеме:

СС2530

Плата SmartRF04EB

P22

DC

P21

DD

RST

RESET

GND

GND

VCC

3.3V

Нужно только указать путь к файлу-прошивке и нажать кнопку “Perform Actions” На странице github проекта качаем прошивку (именно для этого устройства файл называется CC2530ZNP-Pro-Secure_LinkKeyJoin.hex) и программу для прошивки (flash-programmer), после установки которой в систему добавляются нужные драйвера.
При подключении платы-дебагера в USB-порт компьютера в программе сразу отобразится подключенное устройство.

Для устойчивой работы еще надо порты P20, P4, P5 самого координатора подтянуть к земле. ZigBee-модуль портами P03 (Rx) и Р02 (Tx) подключен в UART4 (в ОС как ttyS4) платы cubietruck, питание 3V3, GND взял на соседних pin. Как писал выше, я использую ОС Armbian, порт UART активируется очень просто, с помощью команды armbian-config в разделе SystemHardware нужно активировать нужный порт и перезагрузить систему.

Драйвер zigbee добавляется из админки одним кликом.

В моем случае координатор подключен в порт /dev/ttyS4 (как писал выше), указываем его в настройках.

После первого запуска драйвера, нужно провести сопряжение (добавление) устройств. Остальные настройки можно оставить по-умолчанию. Полная инструкция на github, сопряжение через этот драйвер немного сложнее чем через родное приложение, но у меня не возникло проблем.

Итак, для примера добавим кнопку Xiaomi (серия Mijia), для этого нажимаем зеленую кнопку в настройках драйвера и, следуя инструкции, сначала зажимаем кнопку сопряжения на тыльной стороне скрепкой, пока не начнет мигать светодиод, затем кликаем этой кнопкой примерно раз в 2 секунды, видим прогресс сопряжения.

Проблемы начались, когда я решил добавить датчик температуры и влажности уличного воздуха, который установил на наружней стене дома со стороны утепленной лоджии. Квартира у меня не большая, со всеми устройствами связь стабильная, даже с датчиком открытия двери на лестничной площадке (ЖБ стена в 100мм и расстояние 5м по прямой). Решить проблему можно просто — надо добавить роутер в состав сети ZigBee и расположить его ближе к датчику. Сигнал слабого датчика, который к тому же находился на улице, не добивал до шкафа автоматики. Покупать дорогую розетку или управляемую лампочку только для “проброса” данных от датчика на улице я не хотел. Некоторые беспроводные устройства, к примеру, розетка Xiaomi могут работать в качестве роутера, но у меня не было подобных устройств. В итоге я добавил роутер на базе чипа СС2531 с подключением USB. Как оказалось, для тех же оконечных девайсов на базе чипа СС25хх есть специальная прошивка, которая позволяет их использовать как роутер в системе. Подробно на процессе прошивки останавливаться не буду, схему и сам файл прошивки можно найти на странице github проекта.

В ближайшем будущем планирую расположить стационарно в нормальном корпусе на лоджии и с нормальным питанием от домашнего ИБП. Так как по сути, общение с модулем через USB-порт не происходит, я его временно включил в зарядку с USB-портом и вставил в розетку на кухне.

Процесс добавления роутера в систему прост: нажимаем кнопку сопряжения в драйвере и на включенном роутере несколько раз нажимаем кнопку S2, пока устройства не соединятся.

Добавим для примера датчик температуры/влажности, который я расположил на лоджии снаружи и который должен работать через роутер.

Но можно принудительно указать чтобы сопряжение шло через конкретный роутер, для этого в списке устройств на иконке роутера надо нажать зеленую кнопку сопряжения. Можно просто сделать сопряжение через драйвер и датчик должен подключиться через роутер, если он ближе.

Убедимся что датчик правильно подключился — посмотрим карту сети.

Как писал выше, у меня небольшая однушка 35 кв.м., поэтому карта довольно скромная. На карте показаны линии сопряжения устройств с указанием качества сигнала между сегментами сети. С разрешения других пользователей, опубликую возможные варианты с картой побольше.

В будущем хочу расширить немного сеть и попробовать новые устройства, в частности умный привод для штор и сенсор-кубик. Функционал некоторых устройств Xiaomi через этот адаптер даже немного больше, чем через родное приложение и драйвер mihome.

Драйвер Material

Данные мы получили, исполнительные механизмы привязали, что теперь с ними делать? Для начала давайте отобразим в красивом интерфейсе. У меня есть большой проект в драйвере VIS, который существует в нескольких версиях под разные разрешения, но там материала достаточно на отдельную статью. Возможно она будет следующей.

Установка как обычно в пару кликов. Для простого и быстрого вывода на экран данных и управления различными устройствами, я использую драйвер material. Список категорий ограничен только фантазией, я использую схему «комната-функция», по ним и происходит группировка. Плитки интерфейса отображают данные исходя из настроек категорий, которые добавляются в одноименном окне админки интерфейса. Добавил все комнаты (кухня, коридор, комната, балкон и т.п.) и функции (освещение, датчики, системные и т.п.).

Пример — комнатный настенный датчик температуры и влажности Xiaomi, подключенный через Bluetooth. Теперь в окне настройки объектов системы, нужно для переменных, которые будут выводиться на экран, указать комнату, функцию и назначить роль (для правильного отображения).

Исходя из этих настроек, плитка будет выводить на экран данные, подтянется иконка, и у объектов определенного типа будет доступно управление.

Освещение во всей квартире. Пример 1. Вывод всей информации по одной категории — функции.

Пример 2. Вывод всей информации по комнате — Ванная комната.

Пример 3. Вольтаж и уровень разряда батарей всех беспроводных устройств Xiaomi.

Иногда я подключаюсь через VPN. Этот драйвер у меня работает для локального управления системой с мобильного телефона, стационарного планшета на стене. Для управления и просмотра состояний удаленно, получения уведомлений, я использую драйвер telegram.

Драйвер Telegram

Установку уже описывать не буду, сразу пробежимся по настройкам. Я использую режим работы через периодический опрос (по-умолчанию 300мс) и соединение через прокси-сервер. Чтобы получить token, нужно немного «пообщаться» с создателем ботов — BotFather. Процесс простой — находите поиском этого бота, даете команду на создание нового, указываете его уникальное имя и ключ ваш, указываем его в настройках драйвера и, для безопасности, обязательно указываем пароль «приветствия». Его ваш бот будет спрашивать при общении с новым пользователем.

Для этого можно использовать драйвер text2command или JavaScript. Теперь нужно настроить кейсы общения через бота. Установка драйвера JS не должна вызвать трудностей, настройка в данном кейсе не нужна. Так исторически сложилось, что я использую JavaScript как в виде текста, так и блоками Blockly. После установки и запуска нужно включить отображение меню для создания и редактирования скриптов.

Пример 1. Оповещения.

У меня стоит датчик-геркон беспроводной Xiaomi на входной двери. Для начала давайте попробуем отправить уведомление об открытии, к примеру, входной двери. Создадим новый скрипт в группе common. Мониторю как жена гуляет с мелким пока я на работе.

Укажем что будет «рисовать» в blockly и назовем «telegram_bot».

В группе «События» возьмем блок реакции на изменение переменной и перетащим на рабочее поле.

В итоге должно получится примерно следующее. Далее выберем ID объекта на который подписываемся, вставим проверку объекта через «если» — «иначе если» на значение true/false.

Отлично, теперь бежим, открываем дверь — закрываем дверь и видим сообщения в telegram.

Здесь уже придется немного покодить, т.е. Пример 2. Управление освещением через меню.
Пример посложнее, сделаем управление освещением кнопками меню в telegram. Задача примерно такая: сделать кнопки в виде меню с выводом статуса светильников сразу в текст подписи кнопок. при создании скрипта нужно выбрать JS. Плюс к тому, если меню уже запущено и вручную клавишей включили/выключили свет, нужно чтобы меню также обновлялось со статусами светильников. Еще постараться сделать так, чтобы при нажатии на кнопку, состояние освещения инвертировалось и статус тут же обновлялся в тексте кнопки появлением/исчезновением лампочки.

Код примерно следующий у меня получился:

//Подписи кнопок меню и ID каналов управления освещением
const LIGHT1 = 'Комн ночн', CH_LIGHT1 = 'mqtt.0.PLC55_Lighting.lighting.MainRoom_main1';
const LIGHT2 = 'Комн осн', CH_LIGHT2 = 'mqtt.0.PLC55_Lighting.lighting.MainRoom_main2';
const LIGHT3 = 'Комн подсв', CH_LIGHT3 = 'mqtt.0.PLC55_Lighting.lighting.MainRoom_sec';
const LIGHT4 = 'Кух свет', CH_LIGHT4 = 'mqtt.0.PLC55_Lighting.lighting.Kitchen_main';
const LIGHT5 = 'Кух подсв1', CH_LIGHT5 = 'mqtt.0.PLC55_Lighting.lighting.Kitchen_sec_top';
const LIGHT6 = 'Кух подсв2', CH_LIGHT6 = 'mqtt.0.PLC55_Lighting.lighting.Kitchen_sec_bottom';
const LIGHT7 = 'Ванна осн', CH_LIGHT7 = 'mqtt.0.PLC55_Lighting.lighting.BathRoom_main';
const LIGHT8 = 'Кор осн', CH_LIGHT8 = 'mqtt.0.PLC55_Lighting.lighting.Hall_main';
const LIGHT9 = 'Балкон осн', CH_LIGHT9 = 'mqtt.0.PLC55_Lighting.lighting.Balcon_main'; //Отправка самого меню в телеграм
function sendLightMenu(message_text) });
}
//Изменение состояния освещения
function changeLight(room, channel) { //Проверяем доступность контроллера освещения var alive = getState("mqtt.0.info.connection").val; if (alive.includes("PLC55_Lighting")) { if (getState(channel).val) { setState(channel, false, false, function () { sendLightMenu(room+' ВЫКЛ'); }); } else { setState(channel, true, false, function () { sendLightMenu(room+' ВКЛ'); }); } } else { sendLightMenu('Контроллер освещения OFFLINE'); }
}
//Подписываемся на переменную request драйвера телеграмм, любое изменения без подтверждения
on({id: "telegram.0.communicate.request", ack: false, change: 'any'}, function (obj) { var msg = obj.state.val; var command = obj.state.val.substring(obj.state.val.indexOf(']')+1); var user = obj.state.val.substring(obj.state.val.indexOf('[')+1,obj.state.val.indexOf(']')); var chat_id = getState("telegram.0.communicate.requestChatId").val; var message_id = getState("telegram.0.communicate.requestMessageId").val; var handled = false; //Выводим меню по типичным начальным командам if (command == '/start' || command == '/menu' || command == 'меню' || command == 'Меню') { sendLightMenu("Меню"); handled = true; }
//######################## Lighting menu and commands ################ if (command == LIGHT1 || command == LIGHT1+'') { changeLight(LIGHT1, CH_LIGHT1); handled = true; } if (command == LIGHT2 || command == LIGHT2+'') { changeLight(LIGHT2, CH_LIGHT2); handled = true; } if (command == LIGHT3 || command == LIGHT3+'') { changeLight(LIGHT3, CH_LIGHT3); handled = true; } if (command == LIGHT4 || command == LIGHT4+'') { changeLight(LIGHT4, CH_LIHT4); handled = true; } if (command == LIGHT5 || command == LIGHT5+'') { changeLight(LIGHT5, CH_LIGHT5); handled = true; } if (command == LIGHT6 || command == LIGHT6+'') { changeLight(LIGHT6, CH_LIGHT6); handled = true; } if (command == LIGHT7 || command == LIGHT7+'') { changeLight(LIGHT7, CH_LIGHT7); handled = true; } if (command == LIGHT8 || command == LIGHT8+'') { changeLight(LIGHT8, CH_LIGHT8); handled = true; } if (command == LIGHT9 || command == LIGHT9+'') { changeLight(LIGHT9, CH_LIGHT9); handled = true; } //Если команда не совпала ни с одним вариантом, то передаем её в драйвер text2command if (!handled) { sendTo('text2command.0', { text: command.replace(/\//g, '#').replace(/_/g, ' '), id: chat_id, user: user }, function (response) { if (response && response.response) { sendTo('telegram.0', {user: user, text: response.response}); } }); }
});
//Если вручную переключили свет, просто обновим меню
on({id: /^mqtt\.0\.PLC55_Lighting\.lighting\..*$/, ack: true, change: 'ne'}, function (obj) { sendLightMenu("Ручное управление");
});
//При рестарте драйвера или скрипта сразу отправляем меню
sendLightMenu("Меню");

В итоге должно получиться примерно так:

Заключение

Статья получилась длинной, но надеюсь полезной, и может она облегчит некоторым пользователям жизнь или сподвигнет кого-нибудь на создание своего умного дома.
На данный момент моя система умного дома на базе ioBroker «крутится» уже 4 года и я вполне ей доволен. К ней кроме ZigBee ещё подключено несколько самодельных контроллеров по MQTT и HTTP для управления освещением, вентиляцией и прочими системами, сеть температурных датчиков по шине 1-wire, устройство мониторинга параметров электросети по шине RS485 и протоколу modbus RTU и много чего еще.

Оставляйте свои пожелания в комментариях, чтобы помочь мне определиться с темой следующей статьи. В моей копилке решений для умного дома накопилось много идей, хотя, наверное их надо воспринимать скорее, как копилка проблем для умного дома (те кто в теме поймут, о чём я).

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть