Начав конструировать умный дом, сложно бывает остановиться на продукции одного производителя. А это значит, что вас ждет зоопарк из стандартов, которые сложно увязать друг с другом, и рядок из хабов, каждый из которых занимает розетку (и место в вашей жизни). Нельзя ли сделать универсальный способ управления умными устройствами, которые работают по ZigBee и Z-Wave? Можно! И не придется даже покупать контроллер ZigBee за $50.
РЕКОМЕНДУЕМ:
Файловый сервер с блокировкой рекламы из Raspberry Pi и Pi Hole
Поводом для того, чтобы смешать дома умные устройства разных производителей может быть желание сэкономить, выбирая наиболее выгодные варианты, или наоборот — стремление взять все самое лучшее. Но чаще всего ответ более прозаичный: «так вышло». Сначала вы покупаете лампочки и датчики движения Philips, а потом обнаруживаете, что, к примеру, умных розеток эта компания не делает вовсе, а вам позарез нужна одна из них.
Опять же, если вы выбрали Xiaomi (а предложение этой компании одно из самых выгодных), то вас ждет хаб с китайским софтом, подключенный к фирменному сервису. С точки зрения безопасности — далеко не самый лучший вариант.
В этой статье я покажу, как сконструировать универсальный хаб на основе Raspberry Pi Zero W и экстремально дешевого контроллера. А поможет мне в этом программа под названием zigbee-shepherd. Она поддерживает множество устройств ZigBee, в том числе и выключатели Xiaomi на батарейках серии Aqara и позволяет писать скрипты на JavaScript.
Выбор и прошивка железа
Сначала нужно определиться, на каком железе собирать хаб. В принципе, вы можете взять что угодно (хоть свой основной компьютер, если вы его не выключаете), но Raspberry Pi Zero W — это сверхкомпактный, дешевый и достаточно производительный вариант.
Zigbee-shepherd совместим с чипами ZigBee производства Texas Instrument CC2530 и CC2531. У TI есть референсный USB-стик CC2531 USB Evaluation Module Kit за $49, но есть и полная документация и схемы по сборке такого стика, поэтому будет просто найти в Поднебесной такой же стик, но за $7.
Для работы стика с zigbee-shepherd потребуется файл прошивки с GitHub а чтобы ее зашить, понадобится программатор CC Debugger за $49 или его китайская копия за $12.
Прошивка USB-стика осуществляется с помощью официальной утилиты TI SmartRF Flash Programmer. Чтобы все заработало, нужно подключить CC Debugger в один порт компьютера, стик ZigBee — в другой, и шлейфом соединить их между собой.
В настройках программатора выбираем прошиваемое устройство (1), прошивку (2), задаем нужные действия (3) и прошиваем (4).
Проверить, что USB-стик удачно прошился и работает, можно, подключив его к Raspberry Pi Zero W, и выполнив команду:
1 |
$ ls /dev |
Устройство будет отображаться в системе как ttyACM0.
РЕКОМЕНДУЕМ:
Linux-сервер на микрокомпьютере Omega 2
Установка сервера zigbee-shepherd на Raspberry Pi Zero W
Установка zigbee-shepherd и сопутствующих пакетов будет проводиться на последней версии ОС Raspbian для Raspberry Pi Zero W — Stretch. Zigbee-shepherd написан на JavaScript и работает на Node.js.
Для начала ставим Node.js:
1 |
$ wget -O - https://raw.githubusercontent.com/sdesalas/node-pi-zero/master/install-node-v.lts.sh | bash` |
Для установки расширений из npm нужно установить утилиты для сборки:
1 |
$ sudo apt-get install -y build-essential |
И сама установка zigbee-shepherd:
1 |
$ npm install zigbee-shepherd - -save |
Для проверки правильности работы zigbee-shepherd можно запустить скрипт zigbee-server.js. Во время работы скрипт выводит информацию о каждом этапе добавления устройства и время выполнения операции.
1 2 3 4 5 6 7 8 9 10 11 12 |
var ZShepherd = require('zigbee-shepherd'); var zserver = new ZShepherd('/dev/ttyACM0'); // create a ZigBee server zserver.on('ready', function () { console.log('Server is ready. Allow devices to join the network within 60 seconds'); zserver.permitJoin(60); }); zserver.on('permitJoining', function (joinTimeLeft) { console.log(joinTimeLeft); }); zserver.start(function (err) { // start the server if (err) console.log(err); }); |
Запускаем zigbee-shepherd в режиме отладки:
1 |
$ sudo DEBUG=* node zigbee-server.js |
На этапе разработки скрипта для Node.js всегда используйте отладочный режим. Вывод при этом более подробный, легче отловить ошибки, а zigbee-shepherd показывает все данные, которые он отправляет и получает.
Работа с выключателями Xiaomi из zigbee-shepherd
Первым делом следует добавить устройство ZigBee в сеть. Для этого сначала нужно сбросить его настройки на заводские и тем самым удалить информацию о предыдущей сети, если оно было добавлено прежде. Комбинация сброса и добавления устройства для выключателей Xiaomi Aqara следующая: зажать кнопку на пять секунд, пока светодиоды не начнут мигать, после чего отпустить и ждать, когда закончится процесс добавления. Если включен дебаг, то при добавлении устройства выводится подробный лог. Добавление устройства может занять до одной минуты.
После добавления устройства нужно важно еще правильно с ним работать. Zigbee-shepherd не предоставляет веб-интерфейса для добавления и управления устройствами, вместо этого есть мощный JS API, который позволяет получить полный контроль над любым устройством и написать собственную систему автоматизации.
В вики есть полное описание всех функций. Но чтобы быстрее разобраться с ними, нужно понимать программную структуру устройства.
IEEE address. каждое устройство ZigBee имеет уникальный 48 битный MAC-адрес, он зашит в девайс, и сбросить его невозможно. По MAC-адресу можно обращаться к устройству и получать информацию о нем.
Endpoint. в устройстве может быть несколько функций, например датчик температуры и влажности или выключатель с двумя кнопками. Для каждой функции устройства создается отдельный Endpoint.
Clusters — группа команд, которые можно отправлять устройству, например, команда genOnOff включает или выключает устройство, а если это лампа с диммером, то присутствует еще команда genLevelCtrl, которая позволяет задать уровень яркости.
Attributes. У устройства можно запросить его текущее состояние, обратившись в интересующий Cluster. Например, командой genOnOff можно узнать состояние атрибута onOff — оно может быть 0 или 1.
Выключатель Xiaomi Aqara с одной кнопкой имеет следующую структуру:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
{ "profId": 260, "epId": 1, "devId": 24321, "inClusterList": [0, 3, 18, 25, 65535], "outClusterList": [0, 3, 4, 5, 18, 25, 65535], "clusters": { "genBasic": { "dir": { "value": 3 }, "attrs": {} }, "genIdentify": { "dir": { "value": 3 }, "attrs": {} }, "genGroups": { "dir": { "value": 2 }, "attrs": {} }, "genScenes": { "dir": { "value": 2 }, "attrs": {} }, "genMultistateInput": { "dir": { "value": 3 }, "attrs": {} }, "genOta": { "dir": { "value": 3 }, "attrs": {} }, "manuSpecificCluster": { "dir": { "value": 3 }, "attrs": {} } } } |
Чтобы обрабатывать нажатие кнопки, нужно отловить сообщение от выключателя. Делается это с помощью события ind. Изменим код следующим образом:
1 2 3 4 5 6 7 8 9 10 |
var ZShepherd = require('zigbee-shepherd'); var zserver = new ZShepherd('/dev/ttyACM0'); zserver.on('ind', function (msg) { console.log("msg"); }); zserver.start(function (err) { if (err) console.log(err); }); |
При нажатии кнопки придет сообщение:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
{ endpoints: [ Endpoint { isLocal: [Function], device: [Object], profId: 260, epId: 1, devId: 24321, inClusterList: [Array], outClusterList: [Array], clusters: [Object], onAfDataConfirm: null, onAfReflectError: null, onAfIncomingMsg: null, onAfIncomingMsgExt: null, onZclFoundation: null, onZclFunctional: null, foundation: [Function], functional: [Function], bind: [Function], unbind: [Function], read: [Function], write: [Function], report: [Function] } ], data: { cid: 'genOnOff', data: { onOff: 0 } } } |
Здесь:
- msg.endpoints[0].device.ieeeAddr — MAC-адрес устройства;
- msg.endpoints[0].epId — канал (endPoint) устройства;
- msg.data — id кластера и атрибут, в данном случае выключатель прислал команду genOnOff:0.
Если проверять эти данные, то нажатием на кнопку выключателя можно будет управлять другими устройствами ZigBee по определенному алгоритму. Например, при каждом нажатии включать-выключать или только выключать группу устройств.
Zigbee-shepherd полностью поддерживает работу с диммируемыми лампами Ikea Trådfri и Philips Hue, поэтому для примера можно настроить простой алгоритм включения лампы с помощью выключателя Xiaomi Aqara.
Добавляем в код обработчик нажатия кнопки и включение лампы Ikea Trådfri на максимальную яркость:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
var ZShepherd = require('zigbee-shepherd'); var zserver = new ZShepherd('/dev/ttyACM0'); zserver.on('ind', function (msg) { console.log(msg); switch (msg.type) { case 'attReport': var epId = msg.endpoints[0].epId; var ieeeAddr = msg.endpoints[0].device.ieeeAddr; var data = msg.data; if (ieeeAddr === "0x00158d00015efcef" && epId === 1 && data.cid === "genOnOff") { // get lamp endpoint var lamp = zserver.find(0x000b57fffe3298aa,1); // turn on lamp lamp.functional("genLevelCtrl", "moveToLevelWithOnOff", {level: 255, transtime: 0}, function (err, rsp) {}); } break; default: console.log(msg); break; } }); zserver.start(function (err) { if (err) console.log(err); }); |
Увязываем наше решение с другими
Zigbee-shepherd использует инфраструктуру Node.js, поэтому можно реализовать управление любыми объектами, для которых есть соответствующие библиотеки. Так протокол MQTT дает возможность интеграции со многими системами домашней автоматизации, такими как OpenHub и Home Assistant. Для последней существует готовый проект на GitHub.
Многие хабы и самостоятельные устройства Wi-Fi вроде розеток поддерживают управление через запросы HTTP. Узнать команды можно из документации, либо подглядеть в веб-интерфейсе хаба умного дома, либо проанализировать трафик от мобильного приложения.
Z-Wave контроллер RaZberry имеет хорошо документированный HTTP API, поэтому не составит труда написать запрос на выключение света.
Для отправки HTTP-запросов требуется установить библиотеку request:
1 |
$ npm install request --save |
Добавляем в код поддержку HTTP запросов и сам запрос на выключение света:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
var ZShepherd = require('zigbee-shepherd'); var zserver = new ZShepherd('/dev/ttyACM0'); var request = require('request'); zserver.on('ind', function (msg) { switch (msg.type) { case 'attReport': var epId = msg.endpoints[0].epId; var ieeeAddr = msg.endpoints[0].device.ieeeAddr; var data = msg.data; if (ieeeAddr === "0x00158d00015efcef" && epId === 1 && data.cid === "genOnOff") { request('http://admin:[email protected]:8083/ZAutomation/api/v1/devices/ZWayVDev_zway_7-0-37/command/off', function (error, response, body) { if (error) { console.log("--- Error send request:", error); } }); } break; default: console.log(msg); break; } }); zserver.start(function (err) { if (err) console.log(err); }); |
Минимальная домашняя автоматизации готова! В 26 строках кода запускается сервер ZigBee, отслеживается нажатие кнопки и исполняется команда управления светодиодной лампой или команда HTTP. Если подключить фреймворк веб-приложений для Node.js (например, express), то можно реализовать полноценное HTTP API для работы с устройствами ZigBee.
Zigbee-shepherd позволяет добавить к уже существующей домашней автоматизации на KNX, Z-Wave или Wi-Fi недорогие устройства ZigBee, которых с каждым годом выпускается все больше.
Здравствуйте. Можно получить Ваши координаты на предмет сотрудничества?
Как можно с вами связаться?