IT Академия Samsung ## Серверное приложение В 2016&nbsp;году IBM опубликовала свой внутренний проект под названием [Node-RED](https://nodered.org) с открытым исходным кодом. Это веб-приложение с визуальным редактором программирования, которое позволяет организовывать взаимодействие датчиков и исполнительных механизмов. Конечно, создавая устройства Интернета вещей без программирования не обойтись, но с Node-RED можно тратить больше времени на создание классных вещей, а не тратить бесчисленные часы на написание кода. ![Node-RED](/assets/images/iot/nodered_flow.png "Node-RED") При помощи Node-RED можно легко: - получить доступ к портам ввода/вывода микроконтроллера; - устанавливать соединения с другими платами (Arduino, ESP8266 и&nbsp;т.д.); - создавать адаптивный графический интерфейс пользователя для различных проектов; - осуществлять связь со сторонними сервисами (IFTTT.com, Adafruit.io, Thing Speak и&nbsp;т.д.); - получать данные из Интернета (прогноз погоды, цены на акции, электронные письма и&nbsp;т.д.); - создавать события, запускаемые по времени; - хранить и извлекать данные из баз данных. Разработка в Node-RED ведется через обыкновенный браузер, а само ядро Node-RED можно запустить на различных платформах: в облаке, на сервере, на обычном ПК или даже Raspberry&nbsp;Pi (или аналогичных). Получившийся пользовательский интерфейс также доступен через браузер. ![Node-RED](/assets/images/iot/nodered_ui.png "Интерфейс пользователя, созданный в Node-RED") Node-RED удобно использовать на шлюзах между различными сетями устройств Интернета вещей, функционирующих на собственных, как правило, более простых протоколах и традиционным интернетом, построенных на TCP/IP, UDP. В этом случае он позволит более оптимально использовать свободные ресурсы шлюза, работающего, как правило, на Linux. Тем не менее, Node-RED можно запустить и на обычном компьютере (как x86, так и x64) под управлением операционной системы [Windows](https://nodered.org/docs/getting-started/windows). В рамках же данного практикума рассмотрим работу с Node-RED под Linux (в нашем случае установлена Ubuntu 18.04 LTS). ### Установка Node-RED Возможно, что **Node-RED** уже был установлен, и часть действий, описанных ниже - пустая трата времени. Тем не менее пройти все шаги все равно будет полезным. Чтобы предыдущие настройки нам не мешались - удалим их командой ```bash rm -rf ~/.node-red/ ``` Также удалим (если установлена) предыдуущую версию `nodejs` ```bash sudo apt remove nodejs ``` Теперь установим последнюю версию **NodeJS** с долгосрочной поддержкой и программу управления пакетами **npm**, для чего в терминале введем: ```bash curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - sudo apt install -y nodejs ``` Далее установим собственно сервер **Node-RED** и вспомогательную утилиту **node-red-admin**. ```bash sudo npm install -g --unsafe-perm node-red node-red-admin ``` Менеджер **npm** обычно устанавливает пакеты в текущий каталог. В данной команде использован флаг `–g (globally)`, который выполнит глобальную установку указанных пакетов и поместит их в стандартный каталог системы, например в `/usr/local/bin`. Флаг `—unsafe-perm` помогает избежать некоторых ошибок, которые могут возникнуть при попытке `npm` скомпилировать встроенные модули (написанные на компилируемых языках, например C или C++). Node-RED использует порт 1880 - разрешим подключения по этому порту ```bash sudo ufw allow 1880 ``` Заодно узнаем какой у нашего компьютера IP-адрес: ```bash hostname -I ``` ![hostname](/assets/images/iot/hostname.png) В нашем случае - это **192.168.1.41**. Запустим Node-RED командой ```bash node-red ``` В терминале появится приветственное сообщение типа *Welcome to Node-RED* и информационное сообщение **Server now running**. ![nodered_run](/assets/images/iot/nodered_run.png) Теперь запускаем любой браузер и переходим по адресу, который мы определили ранее (**192.168.1.41**), и задаем номер порта 1880: <http://192.168.1.41:1880> ![nodered_browser](/assets/images/iot/nodered_browser.png) Чтобы остановить сервер, в терминале, в котором запускали Node-RED, нужно нажать сочетание клавиш Ctrl+C. Но мы пока этого **делать не будем**. ### Интерфейс Node-RED Основная единица работы с логикой приложения для Node-RED - это **поток** (**flow**). Он состоит из **узлов** (**node**) - блоков (минимальных единиц логики), которые можно собирать вместе в большую и сложную систему обработки событий. С левой стороны экрана находится палитра элементов с группой блоков. Группы блоков разделены на подгруппы по функциональности. Если выбрать узел, то справа на **боковой панели**, во вкладке **info** будет показана информация о том, как этот узел работает. В центре экрана находится основная рабочая область, где создаются потоки. Над боковой панелью имеется кнопка **Deploy**, предназначенная для развертывания системы автоматизации - запуска получившейся программы на исполнение. ![nodered_sections](/assets/images/iot/nodered_sections.png) Нам нужно будет сделать еще несколько предварительных настроек. Сначала надо установить дополнение `node-red-dashboard`. В правом верхнем углу страницы расположена кнопка вызова меню. Нас интересует меню **Manage palette**. ![nodered_add_ui_menu](/assets/images/iot/nodered_add_ui_menu.png) В появившемся окне по вертикали выберем раздел **Palette**, а по горизонтали - раздел **Install** ![nodered_add_ui_install](/assets/images/iot/nodered_add_ui_install.png) В поле поиска введите `node-red-dashboard` и нажмите **Install**, расположенную рядом с найденным компонентом. В появившемся окне нажмите **Install** ![nodered_add_ui_confirm](/assets/images/iot/nodered_add_ui_confirm.png) После завершения установки можно закрыть всплывающие окна (кнопка **Close**) и перейти к созданию приложения. ### Базовые узлы Узлы в палитре группируются по разделам. Самые важные для работы приложения разделы: - **input** - поступление входящих сигналов; - **output** - отправляют сигналы в результате принятых решений; - **function** - позволяют применить дополнительные преобразования к данным и принимать решения; - **social** - отсылка/прием сообщений (в базовой поставке) с email и twitter, после установки дополнительных плагинов можно расширить возможности еще больше; - **dashboard** - появляется после установки `node-red-dashboard`, содержит компоненты для построения визуального интерфейса. ### Наш первый поток Ранее мы уже работали с "умной лампочкой" (она могла быть как реальной, так и виртуальной - это не принципиально), которая управлялась при помощи различных команд по протоколу MQTT. ![](/assets/images/iot/wemos_rgb.png ) ![](/assets/images/iot/fake_lamp/fake_lamp_logo.png) Мы также создавали приложение, которое могло управлять этой лампой со смартфона. Теперь же сделаем простое управление при помощи серверной программы и визуального программирования! Первым делом надо добавить кнопку, которая будет включать лампочку. Из палитры в разделе **dashboard** с помощью перетаскивания добавляем два узла **button** ![](/assets/images/iot/nodered/node_dashboard_button.png) - для включения и выключения, а из раздела **output** узел **mqtt out** ![](/assets/images/iot/nodered/node_output_mqtt.png) Потом соединяем выходы узлов **button** со входом узла **mqtt** мышкой. ![](/assets/images/iot/nodered/flow_two_button_mqtt.png) Двойным щелчком по верхнему узлу **button** откроем диалог редактирования. ![](/assets/images/iot/nodered/node_input_button_edit_before_on.png) Выбираем **Add new ui_group...** и кнопкой ![](/assets/images/iot/nodered/node_input_button_pencil.png) открываем диалог создания новой группы элементов, в которой будет размещаться наша кнопка. ![](/assets/images/iot/nodered/node_input_button_add_dashboard_group.png) Дадим этой группе имя **First ROW** и аналогичным образом добавим колонку (**Tab**) ![](/assets/images/iot/nodered/node_input_button_add_dashboard_tab.png) Указываем имя (**Home**) и жмем **Add**, закрывая диалог добавления колонки. Аналогично, нажатием **Add** закроем диалог создания группы элементов. Теперь для элемента **button**, с которым мы работаем, укажем метку (**Label**), подсказку (**Tooltip**), и самое главное - значение, которое будет отсылаться при нажатии на эту кнопку - **Payload**, а также **Name**. В итоге диалог будет выглядеть так: ![](/assets/images/iot/nodered/node_input_button_edit_after_on-2.png) Закрываем его нажатием **Done**. Аналогичным образом нужно настроить нижнюю кнопку (только создавать новые группы и столбцы не надо, достаточно их просто выбрать из выпадающего меню): ![](/assets/images/iot/nodered/node_input_button_edit_after_off-2.png) Для узла MQTT потребуется настроить **Server** - аналогично рассмотренным выше случаям выбираем **Add new mqtt-brocker...** ![](/assets/images/iot/nodered/node_output_mqtt_edit_before.png) И настраиваем его параметры на вкладке **Connection** ![](/assets/images/iot/nodered/node_output_mqtt_server_connection.png) и вкладке **Security** ![](/assets/images/iot/nodered/node_output_mqtt_server_security.png) Эти значения вам уже должны быть известны - они использовались уже много раз (**На рисунках приведены неверные значения(!)** во избежание неправомерных подключений к серверу). Также для узла **mqtt** необходимо указать **Topic**, куда он будет отсылать значения (например, виртуальная лампочка, обсуждаемая в предыдущих заданиях курса, для управления использует топик `iot_practice/5404/lamp`, где 5404 - уникальный идентификатор лампочки, совпадающий с идентификатором пользователя в системе обучения IT Академии Samsung). И еще укажем имя (**Name**), чтобы легко отыскать этот блок в потоке. ![](/assets/images/iot/nodered/node_output_mqtt_edit_after-2.png) Чтобы сразу посмотреть на результат, можно нажать кнопку **Deploy** ![](/assets/images/iot/nodered/menu_deploy.png). Это сохраняет текущий поток и применяет настройки на сервере. ![](/assets/images/iot/nodered/flow_two_button_mqtt_connected-2.png) Чтобы посмотреть результат выберите в меню пункт **View > Dashboard** ![](/assets/images/iot/nodered/menu_view_dashboard.png) а затем на боковой панели на вкладке **Site** воспользуйтесь кнопкой ![](/assets/images/iot/nodered/button_dashboard_out.png) для перехода к графическому интерфейсу. Заодно на этой же панели **dashboard** во вкладках можно настроить дополнительные параметры отображения. ![](/assets/images/iot/nodered/menu_dashboard_site.png) Вообще, хорошей идеей будет держать две вкладки открытыми одновременно - с редактором и графическим интерфейсом. ![](/assets/images/iot/nodered/dashboard_two_buttons.png) Если запустить **MQTT.fx**, то можно будет наблюдать как при нажатии кнопок в браузере на MQTT сервер отправляется значение нажатой кнопки, а сама лампочка включается и выключается в зависимости от переданной команды. Конечно, более простой метод сделать управление лампой - это управление при помощи одной кнопки. Для этого в **Node-RED** есть **dashboard/switch** ![](/assets/images/iot/nodered/node_dashboard_switch.png), разобраться в применении которого самостоятельно не составит большого труда. ### Добавим график Так как наша "умная лампочка" может менять уровень своей яркости, то добавим в наше серверное приложение возможность отображать этот уровень. К нашему потоку потребуется добавить узел для приёма сообщений - **mqtt in** ![](/assets/images/iot/nodered/node_input_mqtt.png) в разделе **input** и узел для вывода графики **chart** ![](/assets/images/iot/nodered/node_dashboard_chart.png) в разделе **dashboard**. В итоге должно получиться так (**параметры сервера и топика не забываем использовать свои**): **input/mqtt:** ![](/assets/images/iot/nodered/node_input_mqtt_edit-2.png) **dashboard/chart:** ![](/assets/images/iot/nodered/node_dashboard_chart_edit-2.png) Соединяем выход узла **mqtt in** со входом **chart**, и после нажатия кнопки **Deploy** ![](/assets/images/iot/nodered/menu_deploy.png) должно получиться примерно так: ![](/assets/images/iot/nodered/flow_two_button_mqtt_chart-2.png) А в графическом интерфейсе (не забываем обновить страницу нажатием **F5** на клавиатуре): ![](/assets/images/iot/nodered/dashboard_two_buttons_chart-2.png) Если потребуется изменить порядок, добавить группы, колонки или ссылки, изменить размещение визуальных компонентов на экране, можно использовать **sidebar dashboard** и на вкладке **Layout** настроить всё: ![](/assets/images/iot/nodered/menu_dashboard_layout.png) ### Автоматическое изменение яркости Во время одного из предыдущих практикумов у вас было организовано взаимодействие "вещей". Тогда мы использовали приложение **Sensor Node Free** для передачи показаний с датчика освещенности смартфона под управлением операционной системы Android. При этом чем ярче освещен датчик телефона, тем тусклее светила лампочка. ![](/assets/images/iot/sensor_node/sensor_node_diagramm.png) На самом деле за реализацию этого эффекта на сервере отвечала небольшая функция, которую мы сейчас и повторим. Добавим два узла **mqtt**. Только один - это вход, а второй - выход. Вход свяжем с топиком, в который отправляет сообщения телефон (`iot_practice/5404/sensornode/LightIntensity/x`): ![](/assets/images/iot/nodered/node_input_mqtt2_edit-2.png) Выходной узел **mqtt** будет передавать сообщения в топик управления яркостью нашей лампочки (`iot_practice/5404/lamp/value`): ![](/assets/images/iot/nodered/node_output_mqtt_edit-2.png) Добавим еще один блок - **function/function** ![](/assets/images/iot/nodered/node_function_function.png), зададим ему имя Dimmer, и напишем для него небольшой код на javascript: ```javascript var sensor_max = 10000; //The really max value is 32768 var sensor = Math.floor(msg.payload); var topics = msg.topic.split('/'); topics.splice(2); topic = topics.join('/'); msg.topic = topic + '/lamp/value'; var val = sensor_max - sensor; val = (val < 0)? 0 : val; msg.payload = Math.floor((100.0/sensor_max)*val); return msg; ``` Должно получится так: ![](/assets/images/iot/nodered/node_function_function_edit-2.png) Не забываем про **Deploy** ![](/assets/images/iot/nodered/menu_deploy.png) Результат: ![](/assets/images/iot/nodered/dashboard_two_buttons_chart_function-2.png) ### Задание Доработайте серверное приложение таким образом, чтобы работа с виртуальной "умной" лампочкой была полнофункциональна (включение, отключение, ручное диммирование, режим RGB с возможностью задания цвета).