Мы благодарим Алексея Присяжного из [УрФУ](https://urfu.ru/) за возможность использовать и адаптировать
его [Комплект материалов для мастер-класса по IoT](https://github.com/plazmer/lc_iot) для целей посвящения
школьников в мир Интернета вещей!
## Концепция связи
> Интернет вещей (Internet of Things, IoT) — концепция вычислительной сети физических предметов,
> оснащённых встроенными технологиями для взаимодействия друг с другом или с внешней средой,
> рассматривающая организацию таких сетей как явление, способное перестроить экономические и общественные процессы,
> исключающее из части действий и операций необходимость участия человека.
> [ [Wikipedia] ](https://ru.wikipedia.org/wiki/Интернет_вещей)
Итак, все наши устройства должны иметь возможность объединяться в сеть и взаимодействовать друг с другом.
Раз мы говорим об Интернете вещей, то устройства должны поддерживать протокол MQTT.
Мы поговорим об этом протоколе чуть позже.
Давайте посмотрим на наиболее часто используемые технологии связи в сфере IoT.
| Параметр | LoRa | NB-IoT | BLE | Wi-Fi |
|:-------------------|:--------:|:------:|:------:|:------:|
| Работа без шлюза | - | - | - | + |
| Высокая скорость | - | - | - | + |
| Mesh-топология | + | - | + | + |
| Низкая стоимость | +/- | - | +/- | + |
| Безопасность | - | + | + | + |
| Дальность связи | + | + | - | +/- |
| Распространенность | - | - | + | + |
Глядя на эту таблицу, Wi-Fi выглядит бесспорным лидером. Но это лидерство обманчиво!
Все же дальность связи Wi-Fi не так высока, а потребление энергии очень велико.
Когда мы говорим об Интернете вещей, то каждая «вещь» не обязана быть привязанной к розетке,
а значит должна обладать автономным питанием. И в этом случае Wi-Fi явно проигрывает.
Для «Умного дома» Wi-Fi еще сгодится, но если представить, что датчики и исполнительные механизмы
расположены на площади в несколько гектаров, то здесь уже без батареи точно не обойтись.
А еще потребуются повторители сигналов, которым также нужна энергия.
LoRa потребляет мало энергии и может передавать данные на расстояние в несколько километров.
С другой стороны, если вы хотите использовать LoRA, ZigBee, NB-IoT или что-то другое с «умным» названием, вам всегда понадобится шлюз.
Шлюз - это черный ящик с радиомодулем внутри, который преобразует сигналы датчиков в сигналы, которые может понять ваша домашняя сеть (пакеты TCP/IP).
Для нашей работы мы должны что-то выбрать.
LoRa, BLE и ZigBee пока не так распространены, их чипы стоят дорого (9-10 долларов каждый), а модули Wi-Fi - значительно дешевле (около 2 долларов).
Ну и поскольку мы фактически создаем прототип умного дома, то можно смело отказаться от устройств с батарейным питанием.
**Мы не будем экономить - мы будем использовать Wi-Fi!**
## WeMos D1 mini
WeMos D1 mini построена на базе 32 разрядного микроконтроллера ESP8266 (он входит в сборку ESP-12F установленную на плате)
с интегрированным WiFi модулем (802.11 b/g/n 2.4 ГГц). Так же на плате присутствуют стабилизатор напряжения на 3,3 В, разъем USB типа Micro-B
и USB-UART преобразователь на базе чипа CH340G.
Микроконтроллер ESP8266 работает на тактовой частоте 80 МГц и обладает оперативной памятью RAM данных на 80 КБ (для хранения значений переменных),
и памятью RAM инструкций на 32 КБ. Программы хранятся в flash памяти объемом 4 МБ.
На плате доступно 11 цифровых GPIO, аналоговый вход (3,3 В максимум).
![WeMos D1 mini](/assets/images/iot/wemos.png "WeMos D1 mini")
![WeMos D1 mini (pinout)](/assets/images/iot/wemos_pinout.png "WeMos D1 mini pinout")
Используя платы WeMos можно достаточно легко осуществить подключение к сети Wi-Fi.
Преимуществом платы является возможность сохранения соединения при низком потреблении энергии (1 мА).
Благодаря этому можно делать различные приборы, которые будут работать от батареек.
Программирование платы осуществляется с помощью стандартной среды разработки Arduino IDE.
### Node-RED
В 2016 году IBM опубликовала свой внутренний проект под названием [Node-RED](https://nodered.org) с открытым исходным кодом.
Это веб-приложение с визуальным редактором программирования, которое позволяет организовывать взаимодействие датчиков и исполнительных механизмов.
Конечно, создавая устройства Интернета вещей без программирования не обойтись, но с Node-RED можно тратить больше времени на создание классных вещей,
а не тратить бесчисленные часы на написание кода.
![Node-RED](/assets/images/iot/nodered_flow.png "Node-RED")
При помощи Node-RED можно легко:
- получить доступ к портам ввода/вывода микроконтроллера;
- устанавливать соединения с другими платами (Arduino, ESP8266 и т.д.);
- создавать адаптивный графический интерфейс пользователя для различных проектов;
- осуществлять связь со сторонними сервисами (IFTTT.com, Adafruit.io, Thing Speak и т.д.);
- получать данные из Интернета (прогноз погоды, цены на акции, электронные письма и т.д.);
- создавать события, запускаемые по времени;
- хранить и извлекать данные из баз данных.
Разработка в Node-RED ведется через обыкновенный браузер, а само ядро Node-RED можно запустить на различных платформах:
в облаке, на сервере, на обычном ПК или даже Raspberry Pi (или аналогичных).
Получившийся пользовательский интерфейс также доступен через браузер.
![Node-RED](/assets/images/iot/nodered_ui.png "Интерфейс пользователя, созданный в Node-RED")
Node-RED удобно использовать на шлюзах между различными сетями устройств Интернета вещей,
функционирующих на собственных, как правило, более простых протоколах и традиционным интернетом, построенных на TCP/IP, UDP.
В этом случае он позволит более оптимально использовать свободные ресурсы шлюза, работающего, как правило, на Linux.
Вы можете запустить это приложение на обычном компьютере (как x86, так и x64).
### Протокол MQTT
Интернет работает на сотнях различных протоколов: HTTP, FTP, SMTP, POP3, SSH и т.д. и т.д.
Какой же протокл наиболее предпочтительно использовать для Интернета вещей?
Наиболее распространенными являются HTTP RESTful, CoAP и MQTT. Каким же требованиям должен удовлетворять протокол, предназначенный для Интернета вещей?
С точки зрения безопасности было бы лучше, если бы связь устанавливалась по инициативе устройства, а не сервера.
Такая модель предотвращает возможные атаки - если злоумышленник взломает сервер, то это не окажет негативного воздействия на конечное устройство,
так как в этой модели устройство не может управляться входящим запросом.
Далее, датчики в Интернете вещей, как правило, автономны. Они работают от батареи - вот почему размер передаваемого пакета данных должен быть
как можно меньше. Чем меньше времени тратится на прием/передачу, тем меньше энергопотребление.
HTTP RESTful и CoAP являются документно-ориентированными протоколами, поэтому они имеют большие издержки, а MQTT - нет.
> MQTT (англ. message queuing telemetry transport) — упрощённый сетевой протокол, работающий поверх TCP/IP,
> ориентированный для обмена сообщениями между устройствами по принципу издатель-подписчик.
> Протокол ориентируется на простоту в использовании, невысокую нагрузку на каналы связи, работу в условиях постоянной потери связи,
> лёгкую встраиваемость в любую систему. Основное предназначение — работа с телеметрией от различных датчиков, устройств,
> использование шаблона подписчика обеспечивает возможность устройствам выходить на связь и публиковать сообщения,
> которые не были заранее известны или предопределены, в частности, протокол не вводит ограничений на формат передаваемых данных.
> [ [Wikipedia] ](https://ru.wikipedia.org/wiki/MQTT)
Протокол MQTT был разработан в 1999 году фирмой IBM для обмена данными между компьютерами (M2M).
Этот протокол хорош для применения в ситуациях, когда пропускная способность канала ограничена.
MQTT - это легкий, компактный и открытый протокол, основанный на модели **Издатель/Подписчик**.
Передающие устройства - это **Издатели**, а принимающие устройства - **Подписчики**.
Все они работают через сервер, называемый **брокером**. Он отвечает за получение, хранение и доставку сообщений.
Таким образом, этот подход хорошо и довольно эффективно подходит для приложений, в которых необходимо собирать данные и управлять простыми устройствами.
![MQTT](/assets/images/iot/mqtt.png "MQTT")
Все входящие сообщения в брокер попадают в очередь. Каждое сообщение имеет определенную тему - **топик (topic)**.
Топик - это основная единица хранения информации. Топики состоят из одного или нескольких уровней, которые разделены между собой символом «**/**»,
что в конечном итоге позволяет формировать дерево топиков.
В целом, базовые требования к структуре топиков неплохо описаны The HiveMQ Team в их [блоге](https://www.hivemq.com/blog/mqtt-essentials-part-5-mqtt-topics-best-practices/):
1. Уровни топиков разделяются с помощью "/"
2. Именем топика может быть любая UTF-8 строка
3. Имя каждого уровня топика должно содержать минимум один символ
4. Имена чувстВиТеЛьНы к РеГисТру
5. "/" тоже может быть именем топика, но это может запутать
Так что если у вас есть датчики температуры на кухне, в спальне и пара датчика в гостиной, то вы можете задать их так:
```
home/kitchen/temperature
home/bedroom/temperature
home/living_room/temperature1
home/living_room/temperature2
```
В топик можно опубликовать (PUBLISH) любой пакет информации и он будет доставлен всем, кто подписался (SUBSCRIBE) на этот топик.
Полная информация - http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html.
Подписчик может так же получать данные сразу с нескольких топиков, для этого существуют символы подстановок (wildcard).
Они бывают двух типов: одноуровневые (задаются символом «**+**») и многоуровневые (задаются символом «**#**»).
Если устройства подпишутся на топики так, как указано на рисунке ниже,
![MQTT_Wildcard](/assets/images/iot/mqtt_sub_wildcard.png "Подписка с подстановками")
то в итоге они буду принимать информацию от следующих датчиков:
| Подписчик | Топик | Сообщения от датчиков (id) |
|:----------|-------------------------:|:--------------------------:|
| 1 | home/kitchen/temperature | 1 |
| 2 | home/+/+ | 1, 2, 3, 4, 5 |
| 3 | home/+/temperature | 1, 2, 4 |
| 4 | home/living_room/# | 4, 5 |
# Подготовка и тестирование рабочего места
Запустите Arduino IDE и откройте окно **Файл > Настройки**.
Введите "https://arduino.esp8266.com/stable/package_esp8266com_index.json" в строку "**Дополнительные ссылки для менеджера плат**".
![arduino_preferences](/assets/images/iot/arduino/u/arduino_preferences.png)
Откройте менеджер плат из меню **Инструменты > Плата > Менеджер плат** и установите поддержку esp8266 (для простоты поиска воспользуйтесь фильтром)
![arduino_board_manager_install](/assets/images/iot/arduino/u/arduino_board_manager_esp8266.png)
Для работы с MQTT потребуется установить библиотеку https://github.com/knolleary/pubsubclient
Для этого нужно:
1. Скачать репозиторий как ZIP
![arduino_install_pubsub](/assets/images/iot/arduino/arduino_pubsub_download.png)
2. Установить библиотеку в среду Arduino с помощью меню **Скетч > Подключить библиотеку > Добавить ZIP библиотеку**
![arduino_pubsub_install](/assets/images/iot/arduino/u/arduino_sketch_add_zip.png)
Архив с библиотекой будет находиться там, куда вы его скачали. Вероятнее всего это `/home/student/Загрузки`
![arduino_add_zip_library](/assets/images/iot/arduino/u/arduino_add_zip_library.png)
Как вы уже поняли, мы работаем с платой WeMos D1 mini, поэтому прежде чем продолжить, выберем ее в меню **Инструменты > Плата > LOLIN (WEMOS) D1 R2 & mini**
![arduino_tools_board_lolin_wemos](/assets/images/iot/arduino/u/arduino_tools_board_lolin_wemos.png)
А теперь зальем простую программу (в терминах Arduino она называется "скетч") для проверки работоспособности системы и правильности настроек.
Готовый код можно получить из среды Ардуино: **Файл > Примеры > ESP8266 > Blink**
![blink_example](/assets/images/iot/arduino/u/arduino_file_examples_esp8266_blink.png )
Получившийся результат должен выглядеть примерно так:
![blink](/assets/images/iot/arduino/u/blink.png )
А готовый к работе контроллер с подключенным USB кабелем так:
![wemos_for_blink](/assets/images/iot/wemos_for_blink.png)
После подключения контроллера к компьютеру могут потребоваться дополнительные драйвера, в этом случае инструктор подскажет, что делать.
Когда всё установлено и настроено, надо:
1. Выбрать последовательный порт, к которому подключен контроллер.
![arduino_select_port](/assets/images/iot/arduino/u/arduino_tools_port.png)
Если портов несколько и вы не уверены в том, который нужен то спросите у инструктора, но скорее всего это будет **/dev/ttyUSB0**
![arduino_port_dev_tty_usb](/assets/images/iot/arduino/u/arduino_tools_port_tty_usb0.png)
2. Нажать кнопку **Загрузка** для компиляции и записи программы в контроллер.
![blink_compile](/assets/images/iot/arduino/u/blink_compile.png)
3. Если всё прошло хорошо и нет сообщений об ошибке, то скетч записался в память контроллера
![blink_downloading_compleate](/assets/images/iot/arduino/u/blink_downloading_compleate.png)
а синий светодиод на нём стал периодически мигать.
![blink_animated](/assets/images/iot/wemos_blink.gif)
[**Далее >>>**](iot/summer/quick_start)