Как стать автором
Обновить

Автоматизация homebridge с помощью Node-Red

Время на прочтение4 мин
Количество просмотров14K
На мой взгляд, одним из главных минусов homebridge является отсутсвие возможности создавать продвинутые сценарии. Вся автоматизация возлагается на домашний центр, которым может быть Ipad (подключенный к зарядке), Apple TV или HomePod. Не у всех эти устройства есть, вдобавок у HomeKit очень скудная автоматизация. Исправить данную ситуацию можно с помощью Node-Red. Статья рассчитана на пользователей, у которых уже установлен и настроен homebridge.



Коротко: Node-RED — это инструмент для связи железа, API-интерфейсов и онлайн-сервисов с помощью выстраивания цепочек связей различных узлов (блоков).

Определение на официальном сайте:
Node-RED is a programming tool for wiring together hardware devices, APIs and online services in new and interesting ways.
It provides a browser-based editor that makes it easy to wire together flows using the wide range of nodes in the palette that can be deployed to its runtime in a single-click.


На Raspbian устанавливается так:

sudo apt-get install nodered
sudo systemctl enable nodered.service
sudo service nodered start

По умолчанию Node-Red работает на порту 1880.

Существует огромная библиотека модулей с наборами блоков различного функционала. Не обошли стороной и homebridge. Устанавливаем node-red-contrib-homebridge-automation:

cd ~/.node-red
npm install node-red-contrib-homebridge-automation
sudo service nodered restart

Попробуем включить лампочку. Для этого перетащим на рабочую область блок hb-control, function (этот блок будет посылать команду включиться) и inject (в рамках этой статьи нужен только для ручной активации сценария). Первый раз для hb-блоков необхоимо указать PIN и обновить список устройств. После чего можно добавить нужные блоки:



Теперь по нажатию на кнопку в блоке inject должна загореться лампочка. По мимо hb-contoll есть так же блоки hb-event, hb-status и hb-resume. Подробное описание блоков можно найти в официальном репозитории.

Код блока function
var ret_msg={};
ret_msg.payload = {};
ret_msg.payload.On = true;
return ret_msg;


Блок function создан для манипуляции данными с использованием возможностей языка JavaScript. Блок принимает на вход переменную msg вместе с параметром payload, по умолчанию большая часть блоков в Node-Red работает именно с параметром payload.

Стоит рассказать про блок Debug, с помощью него можно увидеть, выходные данные блоков, что бы понимать в чем ошибка, если ваша задумка не работает.

Теперь сделаем что нибудь интересное, например заставим свет менять состояние после поворота MagicCube на 90 градусов. В прошлой статье, я показывал как подружить zigbee устройства с homebridge. MagicCube, как и прочие zigbee устройства, после паринга появится в MQTT брокере.

Node-Red поддерживает MQTT протокол «из коробки». Добавляем блок MQTT, указываем адрес сервера и Topic кубика.



Кубик может передавать следующие состояния:
shake, wakeup, fall, tap, slide, flip180, flip90, rotate_left и rotate_right

Добавляем блок switch, чтобы отделить одно состояние от другого. Определим в switch условия flip90, shake и tap. Верхний выход соединим с hb-status, для получения текущего состояния лампочки. Блок hb-status соединим с блоком Invert On Value инвертирующим состояние, а его выход соединим с hb-controll и при повороте кубика лампочка будет менять состояние вкл/выкл. Должно получиться примерно так:



Код Invert On Value
var ret_msg=msg;
ret_msg.payload.On = !msg.payload.On;
return ret_msg;


Flow можно ипортировать от сюда:

Flow
[
    {
        "id": "f0f31eb6.22f16",
        "type": "tab",
        "label": "Flow 1",
        "disabled": false,
        "info": ""
    },
    {
        "id": "e0f72465.9e4fb8",
        "type": "mqtt in",
        "z": "f0f31eb6.22f16",
        "name": "",
        "topic": "zigbee2mqtt/0x00158d00010f0528",
        "qos": "2",
        "datatype": "auto",
        "broker": "8ec472b.e73e29",
        "x": 160,
        "y": 80,
        "wires": [
            [
                "43f74679.730588"
            ]
        ]
    },
    {
        "id": "8539109.d872ff",
        "type": "debug",
        "z": "f0f31eb6.22f16",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "x": 670,
        "y": 60,
        "wires": []
    },
    {
        "id": "c5db7c5b.399f4",
        "type": "hb-status",
        "z": "f0f31eb6.22f16",
        "name": "Room1",
        "Homebridge": "HomeBridge",
        "Manufacturer": "YeeLight",
        "Service": "Lightbulb",
        "device": "HomeBridgeA1:23:AD:E3:CD:32YeeLightRoom100000043",
        "conf": "7948a496.505c2c",
        "x": 340,
        "y": 180,
        "wires": [
            [
                "9ef696d9.51a378"
            ]
        ]
    },
    {
        "id": "43f74679.730588",
        "type": "switch",
        "z": "f0f31eb6.22f16",
        "name": "CubeActions",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "cont",
                "v": "flip90",
                "vt": "str"
            },
            {
                "t": "cont",
                "v": "tap",
                "vt": "str"
            },
            {
                "t": "cont",
                "v": "shake",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 3,
        "x": 150,
        "y": 240,
        "wires": [
            [
                "c5db7c5b.399f4"
            ],
            [],
            []
        ]
    },
    {
        "id": "f476dcba.a6511",
        "type": "hb-control",
        "z": "f0f31eb6.22f16",
        "name": "Room1",
        "Homebridge": "HomeBridge",
        "Manufacturer": "YeeLight",
        "Service": "Lightbulb",
        "device": "HomeBridgeA1:23:AD:E3:CD:32YeeLightRoom100000043",
        "conf": "7948a496.505c2c",
        "x": 700,
        "y": 180,
        "wires": []
    },
    {
        "id": "9ef696d9.51a378",
        "type": "function",
        "z": "f0f31eb6.22f16",
        "name": "Invert On Value",
        "func": "var ret_msg=msg;\nret_msg.payload.On = !msg.payload.On;\nreturn ret_msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 520,
        "y": 180,
        "wires": [
            [
                "f476dcba.a6511"
            ]
        ]
    },
    {
        "id": "8ec472b.e73e29",
        "type": "mqtt-broker",
        "z": "",
        "name": "mosquitto",
        "broker": "127.0.0.1",
        "port": "1883",
        "clientid": "",
        "usetls": false,
        "compatmode": true,
        "keepalive": "60",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "willTopic": "",
        "willQos": "0",
        "willPayload": ""
    },
    {
        "id": "7948a496.505c2c",
        "type": "hb-conf",
        "z": "",
        "username": "111-11-111"
    }
]


Таким образом можно «лепить» из блоков сложнейшие схемы автоматизации. В библиотеке можно найти модули с наборами блоков под совершенно разные задачи, например для записи с камер видео наблюдения или работы с файлами.

P.S. Мысли вслух:
Мне не дает покоя мысль о том, что как бы не развивались технологии, по прежнему многие очень далеки от банальной автоматизации рабочих и жизненных процессов с помощью программирования. Я очень надеюсь, что с появлением таких инструментов как Node-Red или Blockly, порог вхождения сильно уменьшится. Научившись, в том же Node-Red строить систему из кубиков, люди, возможно, будут добираться до блока function и с интересом учить JS, а дальше все произойдет само собой.
Теги:
Хабы:
+9
Комментарии2

Публикации

Истории

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн