В русскоязычном интернете пока мало статей о такой среде программирования как Node-RED. Данная статья приоткроет тайну завесы об этом продукте и покажет на примере создания алгоритма управления освещением по датчикам движения как просто с помощью Node-RED можно реализовать различные сценарии и правила автоматизации умного дома в полностью в графическом виде без написания какого-либо кода.



Что такое Node-RED


IBM, как и другие большие компании, пытаются занять свою нишу в развивающемся интернете вещей. Обычно это связано с выпуском open-source приложений и продуктов с целью популяризировать свои платные платформы. Например, в IBM платной платформой является Bluemix.

Node-RED – это open-source детище IBM и, как простенько написано на сайте, это инструмент, который служит для связи железа, API и сервисов новыми и интересными способами.

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

Разработка в Node-RED ведется через обыкновенный браузер, само ядро можно запустить на различных платформах – PC, RPi, cloud и т.д.

Node-RED для умного дома


Я решил попробовать Node-RED для написания сценариев и правил для умного дома. То есть для автоматизации. Сама связь с различными исполнительными устройствами, веб-сервисами и датчиками у меня сделана на OpenHAB. Почему я решил не делать автоматизацию там же? Несколько причин:
— В OpenHAB сценарии и правила пишутся на своем языке. Изучать его только ради одного применения мне не захотелось.
— Сама отладка правил практически невозможна – если правило не работает, сложно разобраться почему
— Я бы хотел, чтобы мои правила были независимы от железа, каналов связи, платформ и самого ПО для коммуникации с устройствами. Чтобы я мог легко перейти на другую платформу УД, например Domoticz, MajorDomo, FHEM и взять мои правила с собой, а не переписывать их заново под новую платформу УД.

Управление Освещением по датчикам движения и освещенности


Итак приступим к реализации. Собственно оригинальная задача проста и тривиальна:
У меня в коридоре есть управляемые LED споты для освещения. Хочу, чтобы свет загорался по движению и выключался сам через 10 секунд.

Немного усложним задачу:
— Свет должен включаться только когда на улице темно
— Интенсивность света должна зависеть от времени – до 9 часов вечера свет должен включаться с полной интенсивностью, а после только на 10%, как подсветка.

Датчики, исполнители и пр. железо


Сами протоколы и варианты связи с датчиками и актуаторами я описывать здесь не буду. Достаточно сказать, что в моем умном доме все эти протоколы приводятся к одному – MQTT, а через него уже происходит общение с Node-RED.
И так какие же датчики и исполнительные устройства у меня есть?
1. Датчик движения. Публикует сообщение OPEN в топик /myhome/state/Hall_motion, когда детектирует движение и CLOSED, если в течении 2-х секунд движения нет.
2. Датчик освещенности. Он измеряет яркость уличного освещения в диапазоне 0-1000 Люкс. Публикует раз в минуту сообщение в топик /myhome/state/Lumin_Hall с уровнем текущей освещенности.
3. Диммер управления LED лампами. Он подписан на топик /myhome/command/Light_Hall/state. Если записать туда 0 – свет выключится. 100 – включится на максимальную яркость. 1-99 – будут менять интенсивность освещения. Для ночной подсветки достаточно интенсивности 1.

Описание Flow в Node-RED


Предполагается, что Node-RED у вас уже установлен. Если нет — перейдите по ссылке выше и установите любой удобный для вас вариант — на компьютер, Raspberry, clowd и т.д. В моем случае Node-RED устновлен на RPi2 (помоему, он даже входит в поставку Raspbian, так что ничего вообще не нужно устанавливать). Данный flow не требует установки каких-либо дополнительных библиотек.

Входы и выходы


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

Примечание: Отображаемые названия блоков можно изменить в их настройках.

Для датчика освещенности создаем узел Hall Light Sensor из MQTT Input:



В его настройке достаточно прописать адрес MQTT брокера и топик.



У меня брокер крутится на той же платформе, поэтому достаточно оставить localhost.

Для датчика движения создаем узел Hall Motion Sensor:



У него все то же самое, только прописываем другой топик /myhome/state/Hall_motion.



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

Осталось добавить MQTT Output, чтобы сделать выход для LED диммера. Перетаскиваем MQTT Output и называем Hall Light Dimmer.



В параметрах надо опять же только указать нужный топик, в который будут слаться сообщения для управления диммером — /myhome/command/Light_Hall/state



В результате мы получили три узла для нашего Flow.



Не мешало бы их проверить на функциональность. Это легко.
К Input блокам подключаем Debug output.



А к выходному блоку подключаем Inject Input.



В настройках этого узла надо поменять payload на уровень желаемой яркости светильника. Например в данном случае это 100.



Мы можем путем copy-paste создать несколько идентичных Inject блоков, поменять яркость, и подключить к выходу вот так:



Так тоже будет работать. Пришло время проверить. Тыкаем кнопку Deploy:



Под MQTT узлами у вас должно появиться маленькое сообщение:



Это означает, что они подключились к MQTT брокеру. Если все прошло по плану, то в правой вкладке debug у вас должны начать появляться сообщения от датчиков, а если кликать мышкой по прямоугольникам слева от Inject узлов, должна меняться интенсивность освещения у светильника, подключенного к диммеру. Если все работает, можно идти дальше.

Цепь управления освещением по датчику движения


Для простоты я буду называть отдельные связанные между собой блоки цепями. В первую очередь попробуем сделать простую цепь, которая бы включала свет по датчику движения и отключала его спустя какое-то время. Для этого согласно концепции Node-RED нам нужно, чтобы нужное сообщение от датчика движения дошло до диммера через определенные блоки и имело определенный текст. Сначала разберемся с включением света.

В первую очередь выделим из всех сообщений от датчика движения сообщение с текстом OPEN — это значит, что движение появилось. Для этого используем блок switch. Подключим его к выходу уже созданного нами блока Hall Motion Sensor.



Настроим его так, чтобы блок пускал на выход только сообщения с текстом OPEN



Как видно из картинки, блок будет сравнивать payload с текстом OPEN и направлять сообщения на выход один, если текст совпадает.

Наш диммер требует, чтобы на вход ему подавались сообщения с нужной яркостью 0...100. Текст OPEN он не поймет. Поэтому используем блок Change, чтобы поменять текст сообщения.




В настройках этого блока записываем требуемое изменение – message payload изменяем на 100 — требуемую интенсивность освещения.

И наконец подключаем это все ко входу нашего диммера:



Если запустить данную цепь, то можно убедиться, что она работает – свет будет включаться по движению. Осталось сделать так, чтобы он еще и выключался.

Для этого используем блок Trigger и подключим его к выходу датчика движения.



Блок триггер позволяет генерировать сообщения с задержкой, а также может быть сброшен определенным сообщением. Настроим его так:



Данная настройка означает, что при поступлении первого сообщения триггер не посылает ничего, но запускает выдержку времени в 8с и по ее истечении посылает сообщение с текстом 0. Также триггер сбрасывается, если ему на вход поступает сообщение с текстом OPEN. Что же это означает в нашем случае?

Предположим что датчик движения выдал сообщение OPEN. Данное сообщение вернет триггер к исходному состоянию без какой либо реакции. Далее через какое-то время датчик движения выдаст сообщение CLOSED. Это сообщение запустит выдержку времени и через 8 секунд после этого триггер выдаст сообщение 0.

Если в течении этой выдержки времени опять поступит сообщение OPEN, то триггер опять вернется к исходному состоянию и будет ждать следующего сообщения(которое логично будет CLOSED). При этом триггер не выдаст никаких сообщений.
То есть таким образом мы создали таймер, который будет служить нам для автоматического отключения света после заданной выдержки. Если вспомнить описание датчика движения, то становится понятным почему здесь задается 8 секунд, а не 10 – 2 секунды добавляется за счет выдержки самого датчика движения.

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



Замечу, что для простоты я выкладываю скриншоты уже отлаженных цепей. Вы же можете обвешать вашу цепь Debug блоками, чтобы разобраться с принципом работы и ваша цепь может выглядеть и вот так:



И в этом нет ничего страшного.

А можно сделать вообще вот так:



И тогда клацая мышкой на прямоугольниках слева от Inject блоков вы можете отладить цепь вообще без железа – на своем лаптопе во время поездки в метро или даже планшете.

Цепь включения/отключения света в зависимости от яркости уличного освещения


Теперь нам надо сделать так, чтобы свет не включался, если на улице слишком светло. Для этого нам нужно добавить еще одну цепь и слегка изменить основную цепь, чтобы учесть данный фактор.

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



Настройку этого блока сделаем таким образом, чтобы он направлял сообщения от датчика освещения на один из выходов, в зависимости от текущей освещенности.



Условие выше означает, что если освещенность меньше 10 люкс, то сообщение будет направлено на выход 1. А иначе оно пойдет на выход 2. Не забываем, что надо выбрать



Опцию, чтобы сообщение было направлено только на один из выходов.

Исходя из принципа работы логично получается, что если сообщение появилось на первом(верхнем) выходе, нам надо включить детектирование движения, а если на втором, то выключить.

Тут, конечно, возможен 1000 и 1 способ, самый простой из которых – просто блокировать сообщение на включение света от датчика движения, если на улице светло. Реализуем это.

Следует отметить, что в Node-RED механизм исполнения реализован на основе сообщений. Т.е. нет сообщения – нет события, нет и реакции. Это накладывает определенную специфику в случае, если разные сообщения приходят асинхронно, т.е в разные моменты времени. Например в данном случае сообщение от датчика освещения асинхронно по отношению к с сообщениям от датчика движения. Поэтому, чтобы учесть эффект датчика освещения, нам надо запомнить информацию, которая была в его сообщении и затем применить ее в следующий раз, когда придет сообщение от датчика движения.

На помощь в этом случае приходит контекст – поле, где можно хранить информацию во время исполнения flow. Контекст бывает глобальным по отношению ко всей среде, или локальным по отношению к конкретному flow или вообще только по отношению к конкретному блоку.

В нашем случае мы будем использовать контекст, локальный по отношению к данному flow. Т.е. переменные будут видны всем блокам в этом flow. Создадим блок change и подключим его к первому выходу Light Threshold Detector



Как мы помним, на этом выходе появляется сообщение в том случае, если датчик освещенности отрапортовал, что освещение на улице менее 10 Люкс. Рассмотрим конфигурацию блока change



В данном случае мы используем правило Set, чтобы присвоить переменной flow.Light_enabled значение Yes. Таким образом мы присвоили значение глобальной переменной, которое мы можем использовать в других блоках.

Аналогичным образом создадим второй блок change и подключим его на второй выход.



Его конфигурация будет такой:



Чтобы узнать правильно ли работает такой детектор мы можем создать простую цепь с блоками Inject и Debug.



При этом в настройках блока Inject укажем, что он должен выдавать каждую секунду значение переменной flow.Light_enabled



Тогда результат работы датчика освещенности можно легко наблюдать в вкладке Debug



Общая цепь включения/отключения света по датчику освещения будет выглядеть следующим образом



Теперь, чтобы учесть этот эффект в цепи управления по датчику движения, нам достаточно вставить switch блок в цепь пути включения света.



И настроить его так, чтобы он пропускал сообщения от датчика движения только, если наша глобальная переменная flow.Light_enabled имеет значение Yes – т.е. на улице темно.



Готово! Теперь наш flow выглядит вот так:



Изменение яркости светильника в зависимости от времени


Осталось совсем немного. Мы хотим изменять интенсивность LED светильника. Т.е. если у нас темно, но время до 9 часов вечера, свет должен включаться на полную мощность. Но после девяти – только на малую мощность, как ночная подсветка.
Для этого создадим блок Inject:



Его можно настроить таким образом, чтобы он выдавал сообщение в определенное время. Настроим его на 21:00 каждого дня.



При этом заметим, что выдавать он будет сообщение со значением 1. Это будет нашей нужной интенсивностью подсветки в ночном режиме. Чтобы использовать это значение в цепи управления светом, используем тот же трюк с глобальными переменными. Создадим блок change:



И настроим его так, чтобы переменной flow.Light_Brightness присваивалось значение из сообщения.


Чтобы возвращать первоначальную яркость по утрам, создадим второй блок inject, который будет выполняться в 6 часов утра и выдавать значение яркости 100. Подключим его туда же.



Таким образом переменной flow.Light_brightness будет присваиваться значение 1 каждый вечер в 9 часов, и значение 100 каждое утро в 6 часов. Осталось только применить это в основной цепи. Для этого у нас уже есть блок Light Brightness Adjustment:



Для которого нам только нужно изменить настройку, чтобы он присваивал не константу, а значение переменной flow.Light_brightness.



Финальный результат


Итоговый flow, очищенный от отладочных блоков выглядит опрятно и чисто. При создании мы использовали только стандартные блоки из инсталляции Node-RED. На сайте flows.nodered.org, однако, существует более 800 дополнительных блоков и библиотек, которые позволяют добавить множество различных вещей.



Для тех, кто заинтересовался повторением данного алгоритма, выкладываю flow, который я использовал для отладки:



А также его json код, который можно легко импортировать в любую версию Node-RED и протестировать.
[{"id":"5afd41b4.d61318","type":"switch","z":"2384634b.17767c","name":"Movement detected?","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"OPEN","vt":"str"}],"checkall":"false","outputs":1,"x":562,"y":285,"wires":[["381b0d6d.a0bd7a"]]},{"id":"35bac8e.57dd5b8","type":"trigger","z":"2384634b.17767c","op1":"5","op2":"0","op1type":"nul","op2type":"val","duration":"8","extend":false,"units":"s","reset":"OPEN","name":"Switch off delay","x":750,"y":373,"wires":[["e995e130.1e2118","af1f191f.498098"]]},{"id":"d85623d1.29b058","type":"change","z":"2384634b.17767c","name":"Light Brightness Adjustment","rules":[{"t":"set","p":"payload","pt":"msg","to":"Light_brightness","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":1013.9999389648438,"y":284.63330078125,"wires":[["e995e130.1e2118","af1f191f.498098"]]},{"id":"934ff922.ca34f","type":"inject","z":"2384634b.17767c","name":"","topic":"","payload":"OPEN","payloadType":"str","repeat":"","crontab":"","once":false,"x":258.5,"y":408,"wires":[["5afd41b4.d61318"]]},{"id":"ea0e2e99.52a6f8","type":"inject","z":"2384634b.17767c","name":"","topic":"","payload":"CLOSED","payloadType":"str","repeat":"","crontab":"","once":false,"x":269,"y":459,"wires":[["35bac8e.57dd5b8","5afd41b4.d61318"]]},{"id":"4187db59.93c2dc","type":"mqtt in","z":"2384634b.17767c","name":"Hall Light Sensor","topic":"/myhome/state/Lumin_Hall","qos":"2","broker":"bfc8eee2.a46c9","x":243,"y":146,"wires":[["c94e7c4.849f48"]]},{"id":"c94e7c4.849f48","type":"switch","z":"2384634b.17767c","name":"Light Threshold Selector","property":"payload","propertyType":"msg","rules":[{"t":"lt","v":"10","vt":"num"},{"t":"else"}],"checkall":"false","outputs":2,"x":517.3333129882812,"y":145.7166748046875,"wires":[["48e6a07a.962798"],["ca8b6623.f11c7"]]},{"id":"381b0d6d.a0bd7a","type":"switch","z":"2384634b.17767c","name":"Light Enabled?","property":"Light_enabled","propertyType":"flow","rules":[{"t":"eq","v":"Yes","vt":"str"}],"checkall":"true","outputs":1,"x":775.5,"y":285,"wires":[["d85623d1.29b058"]]},{"id":"48e6a07a.962798","type":"change","z":"2384634b.17767c","name":"Enable Light","rules":[{"t":"set","p":"Light_enabled","pt":"flow","to":"Yes","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":822,"y":109,"wires":[[]]},{"id":"ca8b6623.f11c7","type":"change","z":"2384634b.17767c","name":"Disable Light","rules":[{"t":"set","p":"Light_enabled","pt":"flow","to":"No","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":824.6666259765625,"y":177.51666259765625,"wires":[[]]},{"id":"b6ea27c1.c33cd","type":"inject","z":"2384634b.17767c","name":"","topic":"","payload":"Light_enabled","payloadType":"flow","repeat":"1","crontab":"","once":false,"x":330.5,"y":678,"wires":[["db66aec8.b3abc"]]},{"id":"db66aec8.b3abc","type":"debug","z":"2384634b.17767c","name":"Light_enabled","active":false,"console":"false","complete":"payload","x":670.5,"y":679,"wires":[]},{"id":"fa4b50b8.e6e0f","type":"inject","z":"2384634b.17767c","name":"","topic":"","payload":"5","payloadType":"num","repeat":"","crontab":"","once":false,"x":233.5,"y":212,"wires":[["c94e7c4.849f48"]]},{"id":"e7b1a39.f9e596","type":"inject","z":"2384634b.17767c","name":"","topic":"","payload":"100","payloadType":"num","repeat":"","crontab":"","once":false,"x":235,"y":266,"wires":[["c94e7c4.849f48"]]},{"id":"4b2f3c6f.de9aac","type":"mqtt in","z":"2384634b.17767c","name":"Hall Motion Sensor","topic":"/myhome/state/Hall_motion","qos":"2","broker":"87b370d1.dd497","x":247,"y":334,"wires":[["5afd41b4.d61318","35bac8e.57dd5b8"]]},{"id":"e995e130.1e2118","type":"mqtt out","z":"2384634b.17767c","name":"Hall Light Dimmer ","topic":"/myhome/command/Light_Hall/state","qos":"0","retain":"true","broker":"87b370d1.dd497","x":1310,"y":315,"wires":[]},{"id":"781e72a7.3c0abc","type":"inject","z":"2384634b.17767c","name":"Reduce Brightness at 21:00","topic":"Night Brightness","payload":"1","payloadType":"str","repeat":"","crontab":"00 21 * * *","once":false,"x":339,"y":517,"wires":[["adbf1e2e.3f5ae"]]},{"id":"aa444315.a48ad8","type":"inject","z":"2384634b.17767c","name":"Normal Brightness at 6:00","topic":"Night Brightness","payload":"50","payloadType":"num","repeat":"","crontab":"00 6 * * *","once":false,"x":349.6666259765625,"y":604.683349609375,"wires":[["adbf1e2e.3f5ae"]]},{"id":"adbf1e2e.3f5ae","type":"change","z":"2384634b.17767c","name":"Light Brightness Adjustment","rules":[{"t":"set","p":"Light_brightness","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":692,"y":554,"wires":[[]]},{"id":"af1f191f.498098","type":"debug","z":"2384634b.17767c","name":"","active":true,"console":"false","complete":"false","x":1303.5,"y":429,"wires":[]},{"id":"bfc8eee2.a46c9","type":"mqtt-broker","z":"2384634b.17767c","broker":"localhost","port":"1883","clientid":"","usetls":false,"verifyservercert":true,"compatmode":true,"keepalive":"60","cleansession":true,"willTopic":"","willQos":"0","willRetain":null,"willPayload":"","birthTopic":"","birthQos":"0","birthRetain":null,"birthPayload":""},{"id":"87b370d1.dd497","type":"mqtt-broker","z":"2384634b.17767c","broker":"localhost","port":"1883","clientid":"","usetls":false,"verifyservercert":true,"compatmode":true,"keepalive":"60","cleansession":true,"willTopic":"","willQos":"0","willRetain":null,"willPayload":"","birthTopic":"","birthQos":"0","birthRetain":null,"birthPayload":""}]


Итоги


В данной статье я попытался продемострировать и рассказать как просто можно реализовать повседневные алгоритмы домашней автоматизации в среде Node-RED. Также я постарался показать основные преимущества данной среды программирования, такие как:
— логичное графическое представление связей и функций
— простоту программирования и легкость отладки пользовательских сценариев
— аппаратную и платформенную независимость полученных алгоритмов – данный сценарий будет одинаково хорошо работать и с OpenHAB, и с ioBroker и с любыми другими платформами умного дома, которые поддерживают протокол MQTT.
— простоту обмена готовыми алгоритмами между пользователями благодаря Copy-Paste JSON кода и наличию онлайн платформы для обмена удачными решениями.

Node-RED может и многое другое – например получать погоду из интернета, рассылать уведомления на твиттер или работать с термостатами Nest. И на основе этого можно создать множество других интересных и полезных алгоритмов автоматизации. Но это темы для следующих статей.
Поделиться с друзьями
-->

Комментарии (30)


  1. av0000
    25.08.2016 20:17

    Ситуация похожая — OpenHAB, правда, со скриптами (но там — боль! вернулся на 1.8 после 2х недель «любви» с 2.0), Node-Red пока для сбора и отправки на narodmon.ru через самопальный скрипт (есть готовый, но он по HTTP) с нескольких MQTT/Esp8266/MySensors.

    За русскоязычное описание — плюсую.
    За «развешивание лапши» из блоков… Даже не знаю — мне-то проще написать небольшую функцию, чем разбираться в применении десятка блоков, но это, видимо, не node-red way.

    Не помешало бы _вводное_ кратенькое введение о message-oriented логике и содержимом msg, flow, scope и т.п… ИМХО.


    1. lingvo
      26.08.2016 09:04
      +1

      За «развешивание лапши» из блоков… Даже не знаю — мне-то проще написать небольшую функцию, чем разбираться в применении десятка блоков, но это, видимо, не node-red way.

      Ну для меня написание ручного кода — вообще no way в домашней автоматизации. Преимущество таких графических сред заключается в том, что они быстро осваиваются — гораздо быстрее, чем тот же javascript. Причем рисовать такие блок-схемы могут даже люди без программистского прошлого — по-моему, они даже быстрее осваиваются, так как у них склад ума еще не перестроился на стройный кодерский лад. Ну а таким людям, как электронщики, вообще просто — тут такая же логика.
      Также важно то, что данный алгоритм у меня запущен в системе и вернусь к нему я, может быть, лет через 5, когда надо будет что-то добавить или изменить в моем УД. В этом случае мне будет важно быстро вспомнить, что собственно тут было сделано, и опять же графические блок-схемы помогают сделать это гораздо быстрее, чем исследование кода(который, как вы знаете, часто бывает spaghetti).
      По поводу введения — да, наверное. Но если честно, я еще сам с данной логикой полностью не разобрался, боюсь неправильно рассказать.


      1. av0000
        26.08.2016 21:38

        я еще сам с данной логикой полностью не разобрался, боюсь неправильно рассказать.

        во-во :)
        Для меня, как не только человека с «программистским прошлым», но и с настоящим, как программистским, так и радио-и-пром.контроллерным ;) и то не очень понятно, как и где настраивать эти блоки. Это при более десятка крупных проектов автоматизации зданий на «типа бейсике» и нескольких на «типа блок-схемах»… Надо вчитываться и думать )))

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

        ЗЫ: огромный плюс в карму индусам, сделавшим Menta (TAC, новые продукты Schenider Electric), ощутимо более лёгкий «конструктор» для любителей блок-схем, чем CoDeSys, Step7, IsaGraf и иже с ними…


    1. madrider
      26.08.2016 15:11
      +1

      помучавшись недельку с OpenHAB 2.0 в итоге написал свой велосипед (работает на малине) — https://github.com/kdudkov/tiny-home-automation


    1. AlexSam
      27.08.2016 00:31

      Не помешало бы _вводное_ кратенькое введение о message-oriented логике и содержимом msg, flow, scope и т.п… ИМХО.

      Да вводная собственно там простая. Весь принцип работы сводится к тому, что система через какой либо источник данных получает объект msg. Это обычный Javascript объект у которого поумолчанию есть одно поле payload — то что пришло извне.
      Далее добавляя блоки и связывая их между собой мы задаем функциональность. Т.е. то, что будет происходит с этим msg. Сам payload может быть строкой, массивом или объектом, смотря через что он был получен. При необходимости в msg можно добавлять свои поля через функции
      // msg.payload пришел из serial port в виде строки ">DATA:0001:01:123,456,789"
      if (msg.payload.indexOf('>DATA:') === 0) {
          var data = msg.payload.split(':');
          if (data.length > 2) {
              msg.deviceID = data[1];
              msg.deviceCMD = data[2];
              if (data.length > 3) {
                  msg.deviceParams = String(data[3]).split(',');
              }
          }
          console.log(msg);
      }
      return msg;
      

      или же через change.
      Объект можно посмотреть через обычный console.log(msg);
      flow — область видимости всей вкладки. Тоже JS объект.
      Ну и глобальный контект.


  1. mike7
    26.08.2016 08:34

    Пользуюсь уже очень давно, управляет системой отопления…
    В вашем случае при перезапуске не будет установлен параметр flow.Light_brightness, я делаю такие настройки с помощью блока inject или с сохранением параметров в MQTT (retain сообщения)


    1. lingvo
      26.08.2016 08:35

      За это мне и нравится MQTT — все сообщения от датчиков настроены как retain и мороки нет. Насчет flow.Light_Brightness вы правы. Можно добавить inject node при старте.


    1. lingvo
      26.08.2016 12:36

      Если можно, запустите ваш flow по отоплению на http://flows.nodered.org/.
      Просто, когда похолодает, мне тоже придется делать контроллер отопления на Node-RED и было бы неплохо посмотреть на Ваши наработки.


      1. mike7
        26.08.2016 20:17

        Постить не буду, это для себя и в вечном процессе доработки… ну и объяснять там много придется.
        В основном это система контроля, используется OpenTherm gateway, на батареях стоят электронные термоголовки с термостатами, датчиками открывания окон и кубом, их мониторинг с помощью Ардуины
        Т.е. в основном контроль, но добавил управление горячей водой по расписанию, регулировку температуры котла (у меня нельзя управлять термостатом), мониторинг электрической сети с помощью NUT, сбор статистики в emoncms и т.п.
        Сделан watchdog для датчиков, т.е. при отсутствии сообщений либо извещение, либо «эмуляция», сейчас делаю управление по СМС и Telegram…
        Из железа в планах реализовать термостат, переведя OpenTherm gateway в интерфейсный режим, заменить eQ3 Cube на что-то свое, сделать управление насосами и клапанами, а также панель управления на планшете и телефоне с помощью node-red-dashboard или node-red-vis
        Если есть вопросы, спрашивайте, готов поделиться


        1. lingvo
          26.08.2016 23:56

          Панель управления на планшете у меня уже есть. Работает на MQTT, кстати, тоже. Следующая статья будет о ней.


  1. superyarik
    26.08.2016 08:38

    датчики соединены с сервером по проводам?


    1. yvm
      26.08.2016 11:47

      По проводам — это не удобно. esp8266 <-mqtt-> Node-RED


      1. lingvo
        26.08.2016 12:26

        У меня вообще все на Z-Wave сделано. Но в случае с NodeRed не важно, как подключены датчики. Главное, чтобы в конце концов все коммуникации с ними сводились к MQTT протоколу. Это легко сделать, используя любой софт для умного дома — OpenHAB, MajorDomo, ioBroker, наверное тоже. Вы просто используете тот софт, в котором лучше сделаны драйвера для нужной вам системы связи с датчиками.


        1. past
          26.08.2016 17:16

          А что в качестве z-wave контроллера используете?


          1. lingvo
            26.08.2016 17:42

            Aeon Z-Wave Stick 5 gen + OpenHAB на RPi2.


            1. past
              26.08.2016 17:50

              На openzwave? Я долго ел этот кактус, в итоге вернулся к z-way, благо у меня RaZberry. Они недавно запилили плагин, позволяющий общаться с их стеком через MQTT и стало все совсем хорошо.


              1. lingvo
                26.08.2016 18:02

                Честно говоря, я не знаю, на чем крутится Z-wave в OpenHAB, да и в принципе мне все равно. Будет доставлять проблемы, перелезу на что-то другое. А пока он работает нормально — у меня всего около 20 модулей в сети.


        1. superyarik
          31.08.2016 21:54

          очень интересно как организовывается питание у модулей. каждый в разетку через блок питания?


  1. beho1der
    26.08.2016 09:28

    А какие датчики используете?


  1. Bluefox
    26.08.2016 10:46

    Мне процитировать ваши заявления по поводу не "реалтаймности" node.js?
    https://geektimes.ru/post/277154/#comment_9460130
    Но я рад, что вы отбросили предрассудки. :)
    Отличная статья.


    1. lingvo
      26.08.2016 12:38

      Спасибо. От предрассудков я не отказался, но мне надо было на чем-то остановиться для реализации сценариев. Решил пока на Node-RED, пока не найду что-то лучшее.


  1. past
    26.08.2016 17:15

    Отличная статья, спасибо!
    Хочу только заметить, что топик совершенно не обязательно начинать со слеша.


  1. Vcoderlab
    27.08.2016 19:55

    А есть возможность сделать так, чтобы свет включался плавно?

    На работе на лестнице светодиодные лампы с датчиком движения. И когда резко включается в темноте — сильно бьёт по глазам.


    1. lingvo
      27.08.2016 19:57

      Это зависит от того, чем управляются светильники. У меня диммер, и в нем запрограммировано плавное включение. Или не проблема сделать так, чтобы выдавалась рампа из нескольких сообщений с увеличивающайся яркостью. Но как у вас сделано, не знаю.


      1. Vcoderlab
        27.08.2016 22:20

        Разумеется я не про наш, а про ваш случай.

        Можно ли с помощью Node-Red, управляющего диммером, реализовать плавное включение светильника? В случае, если в самом диммере отсутствует такая функция.


  1. apivovarov
    29.08.2016 10:54
    +1

    Я тоже использую NR в своем умном доме, но у меня осталось двоякое впечатление. Во-первых, совсем без программирования обойти не получается. Например, достаточно простой алгоритм включение и выключение света в аквариуме требует подготовки сообщения для z-wave контроллера. Во-вторых, как-раз переносить проект в NR не очень удобно. У меня был опыт переноса действующего проекта с одного сервера на другой — выделять все элементы и копировать их, не очень удобно. Наверное, проще было бы перенести файл проекта. Далее нужно заново устанавливать все узлы — нет файла с зависимостями, чтобы можно было сказать install и все установить. После переноса необходимо прописать в разных местах логины и пароли, что вообще, как мне кажется очень не удобно — не помнишь, где что менять и не понимаешь, почему что-то не работает. Узлы, которые нужно настраивать оказываются разбросанными по разным flow и sub-flow. В третьих, когда проект разрастается и количество flow и sub-flow становится значительным, то навигация по ним не очень удобна. Ну и наконец, обработка ошибок. То, как это реализовано мне очень не нравится. Когда хочешь не просто сделать простую связь, а добавить обработку ошибок, то диаграммы становятся уже запутанными и совсем не такими красивыми.

    Вот так например выглядит отправка команд в z-wave


    У меня складывается впечатление, что пока Node Red — это лабораторная экспериментальная среда, (еще) не платформа для сложных коммерческих проектов.


    1. lingvo
      01.09.2016 10:02

      Я думаю это потому, что Вы используете Node-Red немного не так, как предлагаю использовать его я. У вас в Node-Red выполняется связь с внешими устройствами, например z-wave. В моей же философии умного дома я считаю, что эти вещи лучше оставить другим, более подходящим приложениям-конвертерам протоколов. А Node-Red должен использоваться только для реализации управляющих алгоритмов со связью с конвертером через один простой протокол — в данном случае MQTT. В итоге подготавливать сообщения не нужно и все проблемы с третими протоколами отлавливать в NR не нужно. Также если у вас возникнут проблемы с каким либо протоколом — например Z-Wave, то нужно просто сменить программу-конвертер или драйвер в ней. В Node-Red это будет сложнее.


      1. apivovarov
        01.09.2016 10:27

        MQTT — вещь интересная, но пока далеко не всем оборудованием она поддерживается. Например, мой контроллер z-wave пока не поддерживает MQTT. Тоже самое с готовыми узлами (с этим возможно проще — можно написать свой узел). Например, отправление уведомление в Телеграмм или на почту.


        1. past
          01.09.2016 11:39

          С контроллерами дело потихоньку исправляется Вот, например модуль для z-way.
          Отправка уведомления из MQTT куда угодно (Телеграм, слэк, фейсбук, почта...) с помощью node-red делается в 5 кликов мышью.


          1. apivovarov
            01.09.2016 13:07

            У меня z-wave — это маленькая часть умного дома. Он используется только для тех мест, куда не проведены провода. )

            я отправляю сообщения из NR, не из контроллера. Мне кажется, это более правильным.