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

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.
На мой взгляд, одним из главных минусов 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. Мысли вслух:
Я начал увлекаться программированием в школе. Сначала это пыл Pascal, затем Delphi. Позже увлекся «олимпиадным» программированием и мне объяснили, что на Pascal далеко не уедешь. Начал изучать C++. Потом пошло-поехало и пришло осознание того, что я зык программирования особо не важен, его выбирают под конкретные задачи.
Конечно есть гуру которые «собаку съели» и могут на любимом языке написать что угодно

Мне не дает покоя мысль о том, что как бы не развивались технологии, по прежнему многие очень далеки от банальной автоматизации рабочих и жизненных процессов с помощью программирования. Я очень надеюсь, что с появлением таких инструментов как Node-Red или Blockly, порог вхождения сильно уменьшится. Научившись, в том же Node-Red строить систему из кубиков, люди, возможно, будут добираться до блока function и с интересом учить JS, а дальше все произойдет само собой.
Источник: https://habr.com/ru/post/462775/


Интересные статьи

Интересные статьи

Подкасты – канал, который активно развивается весь 2020 год. Растет объем аудитории, да и самих подкастов становится все больше. При этом единого аудиторного измерителя слушателей не суще...
Всем привет! В этой статье пойдет речь о том как ускорить запись большого объема информации в реляционную базу данных для приложений, написанных с использованием Spring Boot. При запис...
Сегодня делимся с вами пошаговым руководством создания интерактивных карт для веб-приложения или блога. Просто сохраните эту статью в закладках. Хоть и существует, например, библиот...
Приветствую всех, кто интересуется качеством воздуха в помещении и хочет это контролировать и управлять. Я сам заинтересовался этим вопросом недавно и решил пощупать датчик CO2 MH-Z19B своими ...
Хотите использовать линукс на работе, но корпоративный VPN не даёт? Тогда эта статья может помочь, хотя это не точно. Хочу заранее предупредить, что вопросы администрирования сетей я понимаю плох...