Статья

Node-Red основные блоки и пример их использования в автоматизации

Предисловие

Добрый день, уже выложили множество статей для новичков про Node-Red. Я так же хочу дополнить эту нишу и описать основы для построения автоматизаций. К каждому примеру будет прикреплен flow, который вы можете импортировать себе и проверить. Давайте начнем.

P.S. рекомендую ознакомиться со статьями:

Node-RED - пошаговая инструкция для новичков. Часть 1Азы Node Red: Глобальные переменные (Global) - для чего они, как правильно использовать и пример автоматизации с нодой AND (логического И)

Термины

Нода (node) – "кубик", набор которых позволяет вам исполнить ваши желания. Вы можете их найти в правой части веб интерфейса.

Флоу (flow) – "вкладка" в веб интерфейсе Node-Red. Вы можете разнести логические части по разным флоу. Так, у меня, например, есть флоу с Deconz, Z-Way, Roborock.

Дебаг (debug) – термин из программирования, что значит отладка. С помощью дебага мы находим ошибки в нашем флоу.

Сообщение (message, msg) – набор данных, которые ноды принимают для обработки и отдают на выходе.

Пейлоад (payload) – термин, означающий полезную нагрузку. Сообщение может содержать в себе множество данных, но основные (наиболее полезные) передаются в объекте payload.

Деплой (deploy) – применение изменений.

Inject & Debug

Это две наиболее часто используемые ноды.

Давайте выведем в дебаг "Hello, sprut.ai!". Для этого нам необходимо настроить ноду inject так, чтобы она отсылала строку и нажать на кнопку (слева от ноды).

Работы с данными:

К примеру, нам нужно изменить какие-то данные из сообщения или перенести их в в другое место. Для этого нам поможет нода change.

Настройки этой ноды позволяют нам оперировать данными в соответствии с заданными нами правилами. Мы можем удалять данные по ключу, переносить из одного ключа в другой, изменять данные по ключу, устанавливать данные в новый ключ. Для примера, давайте заменим в строке из предыдущего примера подстроку "Hello," на "Welcome to". Для этого, в ноде change мы указываем, что данные нужно изменить (Change) в msg.payload, указываем необходимую строку для поиска и значение, на которые ее надо заменить.

[{"id":"1cd1d2cb.5b5fdd","type":"debug","z":"78eed68b.1d9708","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":566,"y":160,"wires":[]},{"id":"792fc03a.a8bd","type":"inject","z":"78eed68b.1d9708","name":"","topic":"","payload":"Hello, sprut.ai","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":154,"y":160,"wires":[["b4af3668.df4068"]]},{"id":"b4af3668.df4068","type":"change","z":"78eed68b.1d9708","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"Hello,","fromt":"str","to":"Welcome to","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":356,"y":160,"wires":[["1cd1d2cb.5b5fdd"]]}]

Своя логика:

Мы можем написать логику на языке javascript внутри ноды Function. Давайте с помощью Function выведем в дебаг знакомую нам строку "Hello, sprut.ai". Для этого в объект msg.payload запишем желаемое значение и отдадим на выход Function наше сообщение. Что посылает Inject нам значения не имеет, мы все равно перепишем это.

Настройки ноды Function:

[{"id":"c9e14b6b.790ca8","type":"function","z":"78eed68b.1d9708","name":"Hello","func":"msg.payload = \"Hello, sprut.ai\";\nreturn msg;","outputs":1,"noerr":0,"x":274,"y":544,"wires":[["f8ff175e.9f0f58"]]},{"id":"9e5270f7.ecfc6","type":"inject","z":"78eed68b.1d9708","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":112,"y":544,"wires":[["c9e14b6b.790ca8"]]},{"id":"f8ff175e.9f0f58","type":"debug","z":"78eed68b.1d9708","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":438,"y":544,"wires":[]}]

Разделяем логически данные:

Если нам нужно разделить данные логически, например, у нас есть текущее время и нужно определить, это день или ночь. Если значение часовой стрелки в интервале с 7 до 23, то мы считаем это за день, иначе – ночь. В этом нам поможет нода Switch. В примере ниже мы будем инжектить значение часовой стрелки вручную и проверять входит ли оно в интервал дня или ночи и выводить соответствующее слово в дебаг.

Настройки Switch:

[{"id":"9bba306c.4b5d9","type":"inject","z":"78eed68b.1d9708","name":"","topic":"","payload":"12","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":304,"wires":[["81a1c52b.cecc88"]]},{"id":"81a1c52b.cecc88","type":"switch","z":"78eed68b.1d9708","name":"","property":"payload","propertyType":"msg","rules":[{"t":"btwn","v":"7","vt":"num","v2":"23","v2t":"num"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":274,"y":336,"wires":[["7f0bdad4.352764"],["426756fe.57f708"]]},{"id":"bc35674c.a108d8","type":"debug","z":"78eed68b.1d9708","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":550,"y":336,"wires":[]},{"id":"92c17226.82811","type":"inject","z":"78eed68b.1d9708","name":"","topic":"","payload":"3","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":368,"wires":[["81a1c52b.cecc88"]]},{"id":"7f0bdad4.352764","type":"function","z":"78eed68b.1d9708","name":"Day","func":"msg.payload = \"Day\";\nreturn msg;","outputs":1,"noerr":0,"x":402,"y":304,"wires":[["bc35674c.a108d8"]]},{"id":"426756fe.57f708","type":"function","z":"78eed68b.1d9708","name":"Night","func":"msg.payload = \"Night\";\nreturn msg;","outputs":1,"noerr":0,"x":402,"y":368,"wires":[["bc35674c.a108d8"]]}]

Тригер:

Разберем последнюю ноду для нашей автоматизации – Trigger. Документация говорит нам следующее: "При срабатывании может отправить сообщение, а затем дополнительно второе сообщение, если оно не было расширено или сброшено." Давайте разберем на примере. Мы включили свет и через 30 секунд нам нужно его выключить.

С помощью Inject пошлем на вход строку "on", далее настроим триггер таким образом:

  1. Пропускает дальше входящее сообщение без изменений.
  2. Ждет 30 секунд.
  3. В случае получения еще одного сообщения, сбрасывает и начинает отсчет 30 секунд сначала.
  4. После окончания 30 секунд отсылает сообщение "off".

[{"id":"b62f13af.c90a7","type":"inject","z":"78eed68b.1d9708","name":"","topic":"","payload":"on","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":102,"y":720,"wires":[["a24b1ca0.f28a"]]},{"id":"a24b1ca0.f28a","type":"trigger","z":"78eed68b.1d9708","op1":"","op2":"off","op1type":"pay","op2type":"str","duration":"30","extend":true,"units":"s","reset":"","bytopic":"all","name":"","x":278,"y":720,"wires":[["d1d0958b.975098"]]},{"id":"d1d0958b.975098","type":"debug","z":"78eed68b.1d9708","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":470,"y":720,"wires":[]}]

Автоматизация:

Самое время применить наши знания и написать автоматизацию со следующими условиями:

  • Есть датчик движения Z-Wave и лампа ZigBee.
  • При срабатывании датчика движения мы включаем свет. Причем если это ночь, включаем на минимальную яркость, днем - на максимальную.
  • Через 30 секунд выключить свет.
  • При срабатывании движения, сбросить таймер и начать отсчет снова.
  • Значения датчика движения прокинуть в HomeKit.

Будем использовать плагины node-red-contrib-deconz, node-red-contrib-zway, node-red-contrib-homekit-bridged.

Логика проста:

  1. Берем значение из ноды Z-Way In и пропускаем с помощью Switch только сообщения, сигнализирующие о срабатывании датчика движения. Конец движения нас не интересует. Так же с нижнего выхода пробрасываем датчик в HomeKit.
  2. Далее берем в Function текущее время и нас интересуют конкретно часы. Записываем значение в msg.payload.hours.
  3. С помощью Switch разделяем день и ночь и задаем соответствующую яркость для лампы и команду включения.
  4. Срабатывает Trigger и отсылает команды ноде Deconz Out. Свет включается.
  5. Через 30 секунд Trigger шлет команду выключения света (если, конечно, он не был сброшен новым движением).

По своему желанию вы можете взять датчик движения с Deconz или же выключатель Z-Way и внести изменения во флоу самостоятельно. Вам поможет использование Debug, чтобы узнать, какие данные шлются и что фильтровать. С вопросами не стесняйтесь писать мне в телеграме.

[{"id":"b236678b.3ad3c8","type":"homekit-service","z":"78eed68b.1d9708","isParent":true,"bridge":"1584ebf8.19cfb4","parentService":"","name":"Прихожая Движение","serviceName":"MotionSensor","topic":"","filter":false,"manufacturer":"IKEA","model":"E1525","serialNo":"343","characteristicProperties":"{}","x":548,"y":1024,"wires":[[]]},{"id":"1ea951aa.83c1ee","type":"deconz-output","z":"78eed68b.1d9708","name":"","server":"3c5efaa8.983d86","device":"00:0d:6f:ff:fe:44:f5:3d-01","device_name":"Hallway : Dimmable light","command":"json","commandType":"object","payload":"payload","payloadType":"msg","transitionTime":"","x":1326,"y":960,"wires":[]},{"id":"b49ca030.52e41","type":"switch","z":"78eed68b.1d9708","name":"Day\\Night","property":"payload.hours","propertyType":"msg","rules":[{"t":"btwn","v":"6","vt":"num","v2":"22","v2t":"num"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":824,"y":960,"wires":[["8601f12d.7679c"],["4c3bf201.fa7dec"]]},{"id":"c8012ec4.a113a","type":"function","z":"78eed68b.1d9708","name":"Get time","func":"var date = new Date();\n// Hours part from the timestamp\nvar hours = date.getHours();\n\nmsg.payload.hours = hours;\n\nreturn msg;","outputs":1,"noerr":0,"x":664,"y":960,"wires":[["b49ca030.52e41"]]},{"id":"dae6bd4d.1b34c","type":"switch","z":"78eed68b.1d9708","name":"Presence","property":"payload.level","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":504,"y":960,"wires":[["c8012ec4.a113a"]]},{"id":"ca9979b1.332d78","type":"trigger","z":"78eed68b.1d9708","op1":"","op2":"{ \"on\" : false } ","op1type":"pay","op2type":"json","duration":"30","extend":true,"units":"s","reset":"","bytopic":"all","name":"","x":1126,"y":960,"wires":[["1ea951aa.83c1ee"]]},{"id":"8601f12d.7679c","type":"function","z":"78eed68b.1d9708","name":"Day","func":"msg.payload.on = true;\nmsg.payload.bri = 255;\nreturn msg;","outputs":1,"noerr":0,"x":978,"y":928,"wires":[["ca9979b1.332d78"]]},{"id":"4c3bf201.fa7dec","type":"function","z":"78eed68b.1d9708","name":"Night","func":"msg.payload.on = true;\nmsg.payload.bri = 10;\nreturn msg;","outputs":1,"noerr":0,"x":978,"y":992,"wires":[["ca9979b1.332d78"]]},{"id":"da89386e.b9a488","type":"zway-input","z":"78eed68b.1d9708","name":"","server":"264bd5f1.3ef27a","device":"ZWayVDev_zway_7-0-113-7-8-A","device_name":"Fibaro Motion","x":342,"y":992,"wires":[["dae6bd4d.1b34c"],["b236678b.3ad3c8"]]},{"id":"1584ebf8.19cfb4","type":"homekit-bridge","z":"","bridgeName":"Node-Red","pinCode":"111-11-111","port":"","allowInsecureRequest":false,"manufacturer":"Node-Red","model":"Default Model","serialNo":"Default Serial Number","customMdnsConfig":false,"mdnsMulticast":true,"mdnsInterface":"","mdnsPort":"","mdnsIp":"","mdnsTtl":"","mdnsLoopback":true,"mdnsReuseAddr":true},{"id":"3c5efaa8.983d86","type":"deconz-server","z":"","name":"Phoscon-GW","ip":"192.168.31.191","port":"80","apikey":"FDCB8BC824","ws_port":"8080","secure":false},{"id":"264bd5f1.3ef27a","type":"zway-server","z":"","name":"Z-Way","ip":"127.0.0.1","port":"80","login":"admin","pass":"3551640"}]

Заключение:

Все ноды с базового набора полезны. Их описание можете почитать в документации и также различные практические примеры можно посмотреть здесь.


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

Для молодых стараемся. 😀

Продолжайте....



Ребят, нужна помощь)

я уже извелся

беру ноду change, делаю как на картинке

https://sprut.ai/static/media/cache/00/42/05/5/2267182/47772/1000x_image.png?1576514407" alt="1000x_image.png?1576514407" />

на входе у меня json от датчика затопления сяоми, включенного на mqtt

после этого ченджа ставлю switch

https://sprut.ai/static/media/cache/00/42/05/5/2267182/47773/1000x_image.png?1576514527" alt="1000x_image.png?1576514527" />

на дебаге тишина. 

после change в дебаг приезжает только msg.payload с данными от датчика. 

flow не показывается и switch ничего не отдает. 

во всех дебагах выбран "complete msg object"

что я делаю не так?

я хочу затолкать ответ датчика в массив или отдельные переменные, так как данные мне нужны в других вкладках

уже третий день пробую разные варианты, ощущаю себя идиотом


Вернуться назад
Вернуться назад