## Серверное приложение
В 2016 году IBM опубликовала свой внутренний проект под названием [Node-RED](https://nodered.org) с открытым исходным кодом.
Это веб-приложение с визуальным редактором программирования, которое позволяет организовывать взаимодействие датчиков и исполнительных механизмов.
Конечно, создавая устройства Интернета вещей без программирования не обойтись, но с Node-RED можно тратить больше времени на создание классных вещей,
а не тратить бесчисленные часы на написание кода.

При помощи Node-RED можно легко:
- получить доступ к портам ввода/вывода микроконтроллера;
- устанавливать соединения с другими платами (Arduino, ESP8266 и т.д.);
- создавать адаптивный графический интерфейс пользователя для различных проектов;
- осуществлять связь со сторонними сервисами (IFTTT.com, Adafruit.io, Thing Speak и т.д.);
- получать данные из Интернета (прогноз погоды, цены на акции, электронные письма и т.д.);
- создавать события, запускаемые по времени;
- хранить и извлекать данные из баз данных.
Разработка в Node-RED ведется через обыкновенный браузер, а само ядро Node-RED можно запустить на различных платформах:
в облаке, на сервере, на обычном ПК или даже Raspberry Pi (или аналогичных).
Получившийся пользовательский интерфейс также доступен через браузер.

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
```

В нашем случае - это **192.168.1.41**.
Запустим Node-RED командой
```bash
node-red
```
В терминале появится приветственное сообщение типа *Welcome to Node-RED* и информационное сообщение **Server now running**.

Теперь запускаем любой браузер и переходим по адресу, который мы определили ранее (**192.168.1.41**),
и задаем номер порта 1880:

Чтобы остановить сервер, в терминале, в котором запускали Node-RED, нужно нажать сочетание клавиш Ctrl+C. Но мы пока этого **делать не будем**.
### Интерфейс Node-RED
Основная единица работы с логикой приложения для Node-RED - это **поток** (**flow**).
Он состоит из **узлов** (**node**) - блоков (минимальных единиц логики), которые можно собирать вместе в большую и сложную систему обработки событий.
С левой стороны экрана находится палитра элементов с группой блоков. Группы блоков разделены на подгруппы по функциональности.
Если выбрать узел, то справа на **боковой панели**, во вкладке **info** будет показана информация о том, как этот узел работает.
В центре экрана находится основная рабочая область, где создаются потоки.
Над боковой панелью имеется кнопка **Deploy**, предназначенная для развертывания системы автоматизации - запуска получившейся программы на исполнение.

Нам нужно будет сделать еще несколько предварительных настроек.
Сначала надо установить дополнение `node-red-dashboard`. В правом верхнем углу страницы расположена кнопка вызова меню. Нас интересует
меню **Manage palette**.

В появившемся окне по вертикали выберем раздел **Palette**, а по горизонтали - раздел **Install**

В поле поиска введите `node-red-dashboard` и нажмите **Install**, расположенную рядом с найденным компонентом.
В появившемся окне нажмите **Install**

После завершения установки можно закрыть всплывающие окна (кнопка **Close**) и перейти к созданию приложения.
### Базовые узлы
Узлы в палитре группируются по разделам. Самые важные для работы приложения разделы:
- **input** - поступление входящих сигналов;
- **output** - отправляют сигналы в результате принятых решений;
- **function** - позволяют применить дополнительные преобразования к данным и принимать решения;
- **social** - отсылка/прием сообщений (в базовой поставке) с email и twitter, после установки дополнительных плагинов можно расширить возможности еще больше;
- **dashboard** - появляется после установки `node-red-dashboard`, содержит компоненты для построения визуального интерфейса.
### Наш первый поток
Ранее мы уже работали с "умной лампочкой" (она могла быть как реальной, так и виртуальной - это не принципиально), которая управлялась при помощи различных команд по протоколу MQTT.


Мы также создавали приложение, которое могло управлять этой лампой со смартфона. Теперь же сделаем простое управление при помощи серверной программы и визуального программирования!
Первым делом надо добавить кнопку, которая будет включать лампочку.
Из палитры в разделе **dashboard** с помощью перетаскивания добавляем два узла **button**  - для включения и выключения,
а из раздела **output** узел **mqtt out** 
Потом соединяем выходы узлов **button** со входом узла **mqtt** мышкой.

Двойным щелчком по верхнему узлу **button** откроем диалог редактирования.

Выбираем **Add new ui_group...** и кнопкой  открываем диалог создания новой группы элементов, в которой будет размещаться наша кнопка.

Дадим этой группе имя **First ROW** и аналогичным образом добавим колонку (**Tab**)

Указываем имя (**Home**) и жмем **Add**, закрывая диалог добавления колонки. Аналогично, нажатием **Add** закроем диалог создания группы элементов.
Теперь для элемента **button**, с которым мы работаем, укажем метку (**Label**), подсказку (**Tooltip**),
и самое главное - значение, которое будет отсылаться при нажатии на эту кнопку - **Payload**, а также **Name**.
В итоге диалог будет выглядеть так:

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

Для узла MQTT потребуется настроить **Server** - аналогично рассмотренным выше случаям выбираем **Add new mqtt-brocker...**

И настраиваем его параметры на вкладке **Connection**

и вкладке **Security**

Эти значения вам уже должны быть известны - они использовались уже много раз (**На рисунках приведены неверные значения(!)** во избежание неправомерных подключений к серверу).
Также для узла **mqtt** необходимо указать **Topic**, куда он будет отсылать значения
(например, виртуальная лампочка, обсуждаемая в предыдущих заданиях курса, для управления использует топик `iot_practice/5404/lamp`,
где 5404 - уникальный идентификатор лампочки, совпадающий с идентификатором пользователя в системе обучения IT Академии Samsung).
И еще укажем имя (**Name**), чтобы легко отыскать этот блок в потоке.

Чтобы сразу посмотреть на результат, можно нажать кнопку **Deploy** .
Это сохраняет текущий поток и применяет настройки на сервере.

Чтобы посмотреть результат выберите в меню пункт **View > Dashboard**

а затем на боковой панели на вкладке **Site** воспользуйтесь кнопкой  для перехода к графическому интерфейсу.
Заодно на этой же панели **dashboard** во вкладках можно настроить дополнительные параметры отображения.

Вообще, хорошей идеей будет держать две вкладки открытыми одновременно - с редактором и графическим интерфейсом.

Если запустить **MQTT.fx**, то можно будет наблюдать как при нажатии кнопок в браузере на MQTT сервер отправляется значение нажатой кнопки,
а сама лампочка включается и выключается в зависимости от переданной команды.
Конечно, более простой метод сделать управление лампой - это управление при помощи одной кнопки.
Для этого в **Node-RED** есть **dashboard/switch** , разобраться в применении которого самостоятельно не составит большого труда.
### Добавим график
Так как наша "умная лампочка" может менять уровень своей яркости, то добавим в наше серверное приложение возможность отображать этот уровень.
К нашему потоку потребуется добавить узел для приёма сообщений - **mqtt in**  в разделе **input** и
узел для вывода графики **chart**  в разделе **dashboard**.
В итоге должно получиться так (**параметры сервера и топика не забываем использовать свои**):
**input/mqtt:**

**dashboard/chart:**

Соединяем выход узла **mqtt in** со входом **chart**, и после нажатия кнопки **Deploy**  должно получиться примерно так:

А в графическом интерфейсе (не забываем обновить страницу нажатием **F5** на клавиатуре):

Если потребуется изменить порядок, добавить группы, колонки или ссылки, изменить размещение визуальных компонентов на экране, можно использовать **sidebar dashboard** и на вкладке **Layout** настроить всё:

### Автоматическое изменение яркости
Во время одного из предыдущих практикумов у вас было организовано взаимодействие "вещей".
Тогда мы использовали приложение **Sensor Node Free** для передачи показаний с датчика освещенности смартфона под управлением операционной системы Android.
При этом чем ярче освещен датчик телефона, тем тусклее светила лампочка.

На самом деле за реализацию этого эффекта на сервере отвечала небольшая функция, которую мы сейчас и повторим.
Добавим два узла **mqtt**. Только один - это вход, а второй - выход.
Вход свяжем с топиком, в который отправляет сообщения телефон (`iot_practice/5404/sensornode/LightIntensity/x`):

Выходной узел **mqtt** будет передавать сообщения в топик управления яркостью нашей лампочки (`iot_practice/5404/lamp/value`):

Добавим еще один блок - **function/function** , зададим ему имя 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;
```
Должно получится так:

Не забываем про **Deploy** 
Результат:

### Задание
Доработайте серверное приложение таким образом, чтобы работа с виртуальной "умной" лампочкой была полнофункциональна (включение, отключение, ручное диммирование, режим RGB с возможностью задания цвета).