Начав конструировать умный дом, сложно бывает остановиться на продукции одного производителя. А это значит, что тебя ждет зоопарк стандартов, которые сложно увязать друг с другом, и рядок хабов, каждый из которых занимает розетку (и место в твоей жизни). Нельзя ли сделать универсальный способ управления умными устройствами, которые работают по ZigBee и Z-Wave? Можно! И не придется даже покупать контроллер ZigBee за 50 долларов.

Поводом для того, чтобы смешать дома умные устройства разных производителей, может быть желание сэкономить, выбирая наиболее выгодные варианты, или наоборот — стремление взять все самое лучшее. Но чаще всего ответ более прозаичный: «так вышло». Сначала ты покупаешь лампочки и датчики движения Philips, а потом обнаруживаешь, что, к примеру, умных розеток эта компания не делает вовсе, а тебе позарез нужна одна из них.

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

В этой статье я покажу, как сконструировать универсальный хаб на основе Raspberry Pi Zero W и экстремально дешевого контроллера. А поможет мне в этом программа под названием zigbee-shepherd. Она поддерживает множество устройств ZigBee, в том числе и выключатели Xiaomi на батарейках серии Aqara, и позволяет писать скрипты на JavaScript.

 

Выбираем и прошиваем железо

Сначала нужно определиться, на каком железе собирать хаб. В принципе, ты можешь взять что угодно (хоть свой основной компьютер, если ты его не выключаешь), но Raspberry Pi Zero W — это сверхкомпактный, дешевый и достаточно производительный вариант.

Микрокомпьютер Raspberry Pi Zero W
Микрокомпьютер Raspberry Pi Zero W

Zigbee-shepherd совместим с чипами ZigBee производства Texas Instrument CC2530 и CC2531. У TI есть референсный USB-стик CC2531 USB Evaluation Module Kit за 49 долларов, но есть и полная документация и схемы по сборке такого стика, поэтому будет несложно найти в Поднебесной такой же стик, но за 7 долларов.

Фирменный стик Texas Instrument на чипе CC2531
Фирменный стик Texas Instrument на чипе CC2531

Для работы стика с zigbee-shepherd потребуется файл прошивки с GitHub, а чтобы ее зашить, понадобится программатор CC Debugger за 49 долларов или его китайская копия за 12.

Texas Instrument CC Debugger
Texas Instrument CC Debugger

Прошивают USB-стик с помощью официальной утилиты TI SmartRF Flash Programmer. Чтобы все заработало, нужно подключить CC Debugger в один порт компьютера, стик ZigBee — в другой и шлейфом соединить их между собой.

Подключение CC Debugger к стику ZigBee для прошивки
Подключение CC Debugger к стику ZigBee для прошивки

В настройках программатора выбираем прошиваемое устройство (1), прошивку (2), задаем нужные действия (3) и прошиваем (4).

SmartRF Flash Programmer для прошивки стика ZigBee
SmartRF Flash Programmer для прошивки стика ZigBee

Проверить, что USB-стик удачно прошился и работает, можно, подключив его к Raspberry Pi Zero W и выполнив команду

$ ls /dev

Устройство будет отображаться в системе как ttyACM0.

При подключении стика появляется устройство ttyACM0
При подключении стика появляется устройство ttyACM0
 

Ставим сервер zigbee-shepherd на Raspberry Pi Zero W

Установка zigbee-shepherd и сопутствующих пакетов будет проводиться на последней версии ОС Raspbian для Raspberry Pi Zero W — Stretch.

Zigbee-shepherd написан на JavaScript и работает на Node.js. Для начала ставим Node.js:

$ wget -O - https://raw.githubusercontent.com/sdesalas/node-pi-zero/master/install-node-v.lts.sh | bash`

Для установки расширений из npm нужно установить утилиты для сборки:

$ sudo apt-get install -y build-essential

И сама установка zigbee-shepherd:

$ npm install zigbee-shepherd - -save

Проверить, правильно ли работает zigbee-shepherd, можно, запустив скрипт zigbee-server.js. Во время работы скрипт выводит информацию о каждом этапе добавления устройства и время выполнения операции.

var ZShepherd = require('zigbee-shepherd');
// Create a ZigBee server
var zserver = new ZShepherd('/dev/ttyACM0');
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);
});
// Start the server
zserver.start(function (err) {
    if (err) console.log(err);
});

Запускаем zigbee-shepherd в режиме отладки:

$ sudo DEBUG=* node zigbee-server.js
Debug-вывод при добавлении устройства ZigBee
Debug-вывод при добавлении устройства ZigBee

INFO

На этапе разработки скрипта для Node.js всегда используй отладочный режим. Вывод при этом более подробный, легче отловить ошибки, а zigbee-shepherd показывает все данные, которые он отправляет и получает.

 

Работаем с выключателями Xiaomi из zigbee-shepherd

Выключатели Xiaomi Aqara на батарейках, работающие по протоколу ZigBee
Выключатели Xiaomi Aqara на батарейках, работающие по протоколу ZigBee

Первым делом следует добавить устройство 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 с одной кнопкой имеет следующую структуру:

{
  "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. Изменим код следующим образом:

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);
});

При нажатии кнопки придет сообщение:

{
  endpoints: [
    {
      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 на максимальную яркость:

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:

$ npm install request --save

Добавляем в код поддержку HTTP-запросов и сам запрос на выключение света:

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:admin@192.168.1.108: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, которых с каждым годом выпускается все больше.

6 комментариев

  1. Аватар

    bsd_conqueror

    12.10.2018 в 18:21

    Как связаться с автором?

  2. Аватар

    Виталий Юркин

    14.10.2018 в 14:55

  3. Аватар

    iMiF

    09.01.2019 в 17:59

    Виталий, а используемый вами стик разве совместим с Z-wave?

  4. Аватар

    vicheadmiral

    12.09.2019 в 20:57

    Добрый день подскажите какое максимальное число устройств удалось подключить на этот хаб? Спасибо

Оставить мнение