IT Академия Samsung – Графические MQTT-клиенты + Виртуальная лампочка <div class="copyright"> Это авторский материал IoT лаборатории ЮУрГУ, представленный в дополнение к существующему практикуму. </div> # Клиенты MQTT (Виртуальная лампочка) ## Введение Для отработки практических навыков по организации взаимодействия по протоколу MQTT давайте поэксперементируем с другими клиентами MQTT. Утилиты `mosquitto_pub` и `mosquitto_sub` в некоторых случаях использовать неудобно. В рамках этой части практикума будем использовать графические приложения. ### Идентификатор пользователя В некоторых наших заданиях понадобится ваш уникальный идентификатор пользователя в [IT Академии Samsung](https://innovationcampus.ru/). Для этого перейдите к нашему электронному курсу на сайте https://myitschool.ru/edu/, и рядом со своим именем в правом верхнем углу нажмите на стрелку&nbsp;(1), а в раскрывшемся меню выберите пункт «О пользователе»&nbsp;(2). ![about_user](/assets/images/iot-academy/about_user.png ) Посмотрите в браузере на адресную строку. В ней вы увидите запись **id=число**&nbsp;(3). Вот это число и будет тем самым `<UserID>` (на рисунке 5404), который вам и нужно будет использовать во всех тех случаях, где говорится об идентификаторе пользователя в IT Академии Samsung. <!-- ## Графический клиент MQTTX ![under_construction](/assets/images/iot-academy/under_construction.png) /--> ## Графический клиент MQTT.fx ### Установка MQTT.fx Одним из самых простых и удобных клиентов для работы с MQTT является приложение **MQTT.fx**. К сожалению, новый владелец этого программного продукта предоставляет его на платной основе, но всегда есть возможность воспользоваться прежней бесплатной версией! Бесплатная версия (1.7.1) приложения **MQTT.fx** скорее всего уже установлена у нас в лаборатории, и можно смело переходить к следующему пункту, но если нет, то **MQTT.fx** можно скачать из [репозитория](https://github.com/iot-academy/mqttfx171-backup/tree/master/Binaries). Для наших компьютеров понадобится 64-разрядный пакет для Debian (если вы работаете со своим компьютером, то выберите соответствующую версию и установите ее самостоятельно). ![mqttfx_download](/assets/images/iot-academy/mqttfx/mqttfx_download.png) Скачиваем файл `mqttfx-1.7.1-64bit.deb` в каталог **Загрузки**: ![mqttfx_saveas](/assets/images/iot-academy/mqttfx/mqttfx_saveas.png) В терминале устанавливаем скачанный файл, для чего наберем (для переключения на русский язык и обратно используется сочетание клавиш **Win**+**Пробел**): ```sh sudo dpkg -i ~/Загрузки/mqttfx-1.7.1-64bit.deb ``` ### Настройка подключения Запускаем **MQTT.fx**. Теперь необходимо настроить подключения к серверу, для чего следует нажать на иконку с шестерёнкой. ![mqttfx_properties](/assets/images/iot-academy/mqttfx/mqttfx_properties.png) Далее введём информацию о MQTT-брокере: 1. Добавить новое соединение; 2. Указать его название (например, **IoT Course**); 3. Ввести адрес брокера (предоставит преподаватель); 4. Ввести порт брокера (предоставит преподаватель); 5. Сгенерировать уникальный идентификатор клиента (это **НЕ** `<UserID>`!); 6. Переключиться на ввод учетных данных пользователя (логина и пароля); ![mqttfx_broker](/assets/images/iot-academy/mqttfx/mqttfx_broker.png) 7. Ввести логин (предоставит преподаватель); 8. Ввести пароль (предоставит преподаватель); 9. Сохранить изменения нажатием кнопки **ОК**. ![mqttfx_user](/assets/images/iot-academy/mqttfx/mqttfx_user.png) Теперь убедимся, что выбран созданный профиль&nbsp;(1), и подключимся к серверу нажатием кнопки **Connect**&nbsp;(2) ![mqttfx_connect](/assets/images/iot-academy/mqttfx/mqttfx_connect.png) Если всё настроено правильно, и подключение к брокеру установлено, то загорится зелёный индикатор ![mqttfx_connected](/assets/images/iot-academy/mqttfx/mqttfx_connected.png) ### Публикация и подписка Переключимся на вкладку **Subscribe**&nbsp;(1), оформим подписку на все топики. Для этого в текстовое поле&nbsp;(2) введём символ `#` и нажмём **Subscribe**&nbsp;(3) ![mqttfx_subscribe](/assets/images/iot/mqttfx/mqttfx_subscribe.png) После этого мы станем получать данные с реального сервера. В верхней части&nbsp;(1) приложения можно видеть сами топики, а выбрав один из них, в нижней части&nbsp;(2) – сами сообщения ![mqttfx_sub_data](/assets/images/iot-academy/mqttfx/mqttfx_sub_data.png) Для публикации сообщений перейдём во вкладку **Publish**&nbsp;(1). Зададим имя топика&nbsp;(2), введём текст для отправки&nbsp;(3) и нажмём кнопку **Publish**&nbsp;(4). Давайте в топик `iot_practice/<ваша_фамилия>` отправим сообщение «My UserID is &lt;UserID&gt;», только вместо `<UserID>` укажите ваш идентификатор, который вы нашли ранее: ![mqttfx_pub](/assets/images/iot-academy/mqttfx/mqttfx_pub.png) Теперь вернемся на вкладку **Subscribe**&nbsp;(1) и проверим, что действительно появился такой топик, и в нём находится наше сообщение&nbsp;(3). ![mqttfx_check_userid](/assets/images/iot-academy/mqttfx/mqttfx_check_userid.png) <div class="info"> Если вы не видите своё сообщение, то прокрутите список топиков. Мы работаем с сервером, на который приходит много данных, и ваше сообщение где-то среди них. </div> Чтобы всё-таки не терять свои сообщения среди других, отпишемся (**Unsubscribe**) от приема всех сообщений. ![mqttfx_unsubscribe](/assets/images/iot-academy/mqttfx/mqttfx_unsubscribe.png) Далее мы будем работать только с сообщениями топика `iot_practice` и всех его субтопиков, поэтому имеет смысл подписаться только на них. ![mqttfx_subscribe_iotpractice](/assets/images/iot-academy/mqttfx/mqttfx_subscribe_iotpractice.png) ## Виртуальная лампочка Хорошо, с топиками работать мы научились. Но в целом топик – это достаточно абстрактное понятие. Давайте наделим их полезной нагрузкой – придадим топикам смысл! Если у вас на компьютере установлена система контроля версий Git (на компьютерах лаборатории – точно установлена), то клонируем репозиторий https://github.com/iot-academy/fake_lamp ```sh git clone https://github.com/iot-academy/fake_lamp ``` ![term_git_fake_lamp](/assets/images/iot-academy/fake_lamp/term_git_fake_lamp.png) Если же Git не установлен, то заходим в любом браузере по тому же адресу https://github.com/iot-academy/fake_lamp, скачиваем код в виде ZIP-архива, ![github_fake_lamp_web_download](/assets/images/iot-academy/fake_lamp/github_fake_lamp_web_download.png) и распаковываем его в какой-нибудь каталог. Под Linux запускаем приложение **Файлы**&nbsp;(1), переходим в домашнюю папку&nbsp;(2) (или ту, в которую распаковали архив) и открываем папку `fake_lamp`&nbsp;(3). ![desktop_fake_lamp](/assets/images/iot-academy/fake_lamp/desktop_fake_lamp.png) В каталоге `js` выбираем файл `app.js` ![fake_lamp_files_app_js](/assets/images/iot-academy/fake_lamp/fake_lamp_files_app_js.png) и открываем его в текстовом редакторе (правая кнопка мыши, **Открыть в Текстовый редактор**). В самом начале находятся настройки подключения к MQTT-брокеру ![fake_lamp_app_js](/assets/images/iot-academy/fake_lamp/fake_lamp_app_js.png) Исправьте значения для полей: - `host` – адрес MQTT-брокера; - `client` – идентификатор пользователя в IT Академии Samsung (`UserID`); - `username` – имя пользователя для подключения к MQTT-броекеру; - `password` – пароль для подключения к MQTT-броекеру. Номер порта 1884 – это не ошибка, так и должно быть! Сохраняем файл, и закрываем его. В основном каталоге нашей виртуальной лампочки открываем файл `index.html` (или у вас он может отображаться просто как `index`) в браузере. ![fake_lamp_files_index](/assets/images/iot-academy/fake_lamp/fake_lamp_files_index.png) У вас должен запуститься браузер, в котором будет отображаться лампочка ![fake_lamp_firefox](/assets/images/iot-academy/fake_lamp/fake_lamp_firefox.png) <div class="danger"> **Внимание!**<br /> Если вы работаете с ноутбуком, то у вас на клавише **F12** может находиться функция включения/отключения беспроводной сети WiFi – проверьте положение переключателя **Fn**, чтобы внезапно не отключиться от сети! </div> Нажмем клавишу **F12** на клавиатуре (или сочетание клавиш **Ctrl**+**Shift**+**I**), после чего на вкладке **Console**/**Консоль**&nbsp;(1) убедимся, что наша лампочка подключилась к MQTT-брокеру (должна быть надпись «connected»&nbsp;(2)) ![fake_lamp_firefox_f12](/assets/images/iot-academy/fake_lamp/fake_lamp_firefox_f12.png) Повторным нажатием **F12** (или **Ctrl**+**Shift**+**I**) можно вернуть браузер к привычному виду, или чтобы панель разработчика не мешалась и не перекрывала изображение лампочки её можно закрепить справа (или слева) ![fake_lamp_firefox_stick_right](/assets/images/iot-academy/fake_lamp/fake_lamp_firefox_stick_right.png) Чтобы включить эту лампочку, нужно отправить сообщение `on` в топик `iot_practice/<UserID>/lamp`, где вместо `<UserID>` нужно указать свой идентификатор пользователя в IT Академии Samsung (`UserID`), например, для пользователя с `UserID = 5404` имя этого топика будет `iot_practice/5404/lamp`. Если вернуться в браузер к нашей лампочке, то можно увидеть, что она включилась ![fake_lamp_firefox_on](/assets/images/iot-academy/fake_lamp/fake_lamp_firefox_on.png) Чтобы выключить лампу, нужно отправить сообщение `off` в тот же топик. Проделайте это самостоятельно. На самом деле наша лампочка еще более «умная» – в нее встроен диммер, позволяющий регулировать яркость ее свечения! Отправим сообщение с желаемым процентом яркости, например, 61, в топик `iot_practice/<UserID>/lamp/value`, и если посмотреть в браузере на лампочку, то увидим, что ее яркость стала соответствовать переданному значению. ![fake_lamp_61](/assets/images/iot-academy/fake_lamp/fake_lamp_61.png) Если лампочку выключить, а потом снова включить, то ее яркость останется на прежнем уровне. Таким образом, у нас есть устройство (лампочка), которое подписалось на сообщения MQTT-брокера, и управляется командами в этих сообщениях. ## Мобильное приложение Современные смартфоны по своим техническим характеристикам во многом превосходят многие персональные компьютеры. Более того, рынок мобильных приложений сейчас развивается значительно стремительнее, чем desktop, а потому совершенно не удивительно, что MQTT-клиент может быть установлен на смартфоне, а значит управлять нашей лампочкой можно прямо с него. Для Android есть достаточно много таких клиентов, а вот с iOS дела обстоят значительно хуже. Некоторые MQTT-клиенты позволяют создавать графические элементы управления (*виджеты*), чтобы не вводить текстовые сообщения в топики, и не запоминать их все – это гораздо удобнее! Есть достаточно простой и бесплатный графический клиент **IoT&nbsp;OnOff**, работающий как под Android, так и iOS. Мы будем рассматривать его на примере версии под Android (под iOS должно быть все крайне похоже). Сначала приложение нужно установить. Можно это сделать через GooglePlay, поискав в нем приложение **IoT&nbsp;OnOff** (для iOS поступить следует также – поискать приложение в AppStore). У приложения **IoT&nbsp;OnOff** достаточно очевидная иконка: ![onoff_google_play](/assets/images/iot-academy/onoff/onoff_google_play.png) После установки находим это приложение и запускаем его&nbsp;(1). При первом запуске нажимаем кнопку **Next&nbsp;step**&nbsp;(2). ![onoff_01_start](/assets/images/iot-academy/onoff/onoff_01_start.png) На следующем экране знакомимся с условиями использования программы, проматывая экран до конца&nbsp;(1), после чего нажимаем на кнопку **I&nbsp;agree**&nbsp;(2). ![onoff_02_disclaimer](/assets/images/iot-academy/onoff/onoff_02_disclaimer.png) В результате приложение запустится и произведёт демонстрацию возможностей своих элементов на панели **Garden**. Зайдем в основное меню программы&nbsp;(1). Мы можем переключиться на разные панели (Dashboards), например, давайте выберем панель **Swimming pool**&nbsp;(2). Как можно увидеть, в бесплатной версии доступно только 10 виджетов — графических элементов. ![onoff_03_demo](/assets/images/iot-academy/onoff/onoff_03_demo.png) Давайте сначала удалим всё лишнее, чтобы ограничения не сказывались на нашей работе. Снова зайдем в меню приложения&nbsp;(1), нажмем на **Edit**&nbsp;(2), тем самым перейдем в режим редактирования списка панелей. Для удаления существующей панели, сдвинем её влево&nbsp;(3). ![onoff_04_prepare](/assets/images/iot-academy/onoff/onoff_04_prepare.png) Нажмём на кнопку **Delete**&nbsp;(4), и подтвердим своё решение нажатием кнопки **OK**&nbsp;(5). Повторим действия (3)–(5) со всеми оставшимися панелями. ![onoff_05_delete](/assets/images/iot-academy/onoff/onoff_05_delete.png) После удаления всех панелей нажмите на надписи **Done** в правом верхнем углу&nbsp;(1) – этим мы завершим процесс редактирования. Снова войдем в главное меню приложения&nbsp;(2), и перейдем к пункту настроек – **Settings**&nbsp;(3). ![onoff_06_nogroups](/assets/images/iot-academy/onoff/onoff_06_nogroups.png) Далее выбираем пункт **Configuration**&nbsp;(1), отключаемся от текущего MQTT-брокера&nbsp;(2), и заходим в настройки **MQTT&nbsp;Broker**(3). Нужно заменить значения **Host**&nbsp;(4), **Port**&nbsp;(5), и отключить **WebSockets**&nbsp;(6). ![onoff_07_configuration](/assets/images/iot-academy/onoff/onoff_07_configuration.png) После чего нажмите **Ready**&nbsp;(7) в правом верхнем углу. К сожалению, это дефект этой программы, и без такой операции мы не сможем изменить дальнейшие настройки (хотя может быть разработчики уже и исправили эту ошибку). Снова заходим в настройки **MQTT Broker**&nbsp;(8), и выбираем пункт **Authentication**&nbsp;(9). ![onoff_08_authentication](/assets/images/iot-academy/onoff/onoff_08_authentication.png) Заполняем параметры аутентификации: **User**&nbsp;(1), **Password**&nbsp;(2), включаем параметр **Use authentication**&nbsp;(3). Подтверждаем корректность ввода нажатием на **Ready**&nbsp;(4). Затем в самом низу экрана нажимаем кнопку **Save broker to list**&nbsp;(5). При желании можно посмотреть список сохраненных брокеров&nbsp;(6), но это не обязательно. Завершаем редактирование нажатием на **Ready**&nbsp;(7), переводим переключатель **Connect**&nbsp;(8) в положение включено. Если параметры соединения указаны верно, то в поле **Status** должна будет появиться надпись **Connected**&nbsp;(9). После чего выходим в главное меню программы&nbsp;(10). ![onoff_09_connected](/assets/images/iot-academy/onoff/onoff_09_connected.png) Переключимся из режима настроек в режим работы с панелями **Dashboards**&nbsp;(1), включим режим редактирования, нажимая на **Edit** в левом верхнем углу&nbsp;(2), а затем на **Edit** в правом верхнем углу&nbsp;(3). ![onoff_10_dashdoards](/assets/images/iot-academy/onoff/onoff_10_dashdoards.png) Добавим группу, нажимая на **Add**&nbsp;(1). Введём имя группы (**Name**), например, **IoT Course**&nbsp;(2), и подтвердим изменения, нажав на **Ready**&nbsp;(3). Закончим редактирования списка групп панелей – нажмём **Done**&nbsp;(4), после чего вернёмся в главное меню приложения&nbsp;(5). ![onoff_11_iot_course](/assets/images/iot-academy/onoff/onoff_11_iot_course.png) Выберем нашу панель&nbsp;(1), включим режим редактирования&nbsp;(2), и добавим наш первый виджет&nbsp;(3). ![onoff_12_add_widget](/assets/images/iot-academy/onoff/onoff_12_add_widget.png) Пролистайте&nbsp;(1) библиотеку доступных виджетов, и выберите виджет **Switch**&nbsp;(2). В его настройках укажите имя **Lamp**&nbsp;(3), так нам будет удобнее пользоваться итоговым результатом. В полях **Subscribe values** и **Publish values** установите значения для состояния **True** как `on` и `off` для **False**&nbsp;(4). После чего настроим подписку (**Subscribe**) для этого элемента&nbsp;(5). ![onoff_13_switch](/assets/images/iot-academy/onoff/onoff_13_switch.png) Каждый виджет обязательно должен быть связан с каким-либо MQTT топиком, иначе теряется смысл их использования. Для нашего виджета **switch** в поле **Topic filter**&nbsp;(1) запишем топик для управления нашей лампой `iot_practice/<UserID>/lamp`, где `<UserID>` – это уникальный идентификатор пользователя в учебной системе IT Академии Samsung . После ввода имени топика&nbsp;(2) нужно нажать на символ&nbsp;˅ в правом верхнем углу&nbsp;(3). Далее проверим, что имя топика введено верно&nbsp;(4), и нажмём на **Ready**&nbsp;(5). ![onoff_14_switch_sub](/assets/images/iot-academy/onoff/onoff_14_switch_sub.png) Подобным образом настроим и топик, в который виджет будет публиковать свои значения&nbsp;(1). У нас это будет все тот же топик `iot_practice/<UserID>/lamp`. В настройках виджета нужно разрешить публиковать сообщения&nbsp;(2), задать имя топика&nbsp;(3). Мы не будем использовать префикс устройства, поэтому параметр **Prefix device name** нужно отключить&nbsp;(4). Остальные параметры не меняем, и заканчиваем редактирование, нажимая **Ready**&nbsp;(5) сначала в окне настройки подписки, а затем и в окне настройки параметров виджета&nbsp;(6). ![onoff_15_switch_pub](/assets/images/iot-academy/onoff/onoff_15_switch_pub.png) Созданный виджет можно снова отредактировать&nbsp;(1), или удалить&nbsp;(2), но мы не будем этого делать! Нажмите на значок в форме сетки&nbsp;(3) – это режим размещения виджета на экране. Размер виджета можно уменьшить&nbsp;(4) или увеличить&nbsp;(5), а за центральную кнопку&nbsp;(6) виджет можно перемещать по экрану. Просто сделаем наш виджет поменьше&nbsp;(7), и завершим редактирование&nbsp;(8). ![onoff_16_switch_resize](/assets/images/iot-academy/onoff/onoff_16_switch_resize.png) В итоге мы получим мобильный интерфейс управления нашей лампочкой, и нажимая на переключатель **Lamp**&nbsp;(1) сможем включать и отключать её. ![fake_lamp_onoff](/assets/images/iot-academy/onoff/fake_lamp_onoff.png) Снова вернёмся в режим редактирования&nbsp;(1), добавим&nbsp;(2) новый виджет, а именно **led**&nbsp;(3). ![onoff_17_led](/assets/images/iot-academy/onoff/onoff_17_led.png) Изменим параметры этого виджета: имя&nbsp;(4) – **Lamp**, **Subscribe**&nbsp;(5) – `iot_practice/<UserID>/lamp`, **Value&nbsp;1**&nbsp;(6) – `off`, **Color value&nbsp;1**&nbsp;(7) – серый цвет, **Value&nbsp;2**&nbsp;(8) – `on`, **Color value&nbsp;2**&nbsp;(9) – желтый цвет. Завершаем редактирование&nbsp;(10). Обратите внимание, что когда задаёте имя топика, в нижней части предлагаются ранее вводимые значения&nbsp;(11). Изменим размер виджета&nbsp;(12), и поместим его рядом с переключателем, перемещая за среднюю кнопку&nbsp;(13). ![onoff_18_led](/assets/images/iot-academy/onoff/onoff_18_led.png) Для управления яркостью свечения лампы добавим&nbsp;(1) еще один виджет – **Slider**&nbsp;(2). В его настройках зададим имя&nbsp;(3) **dimmer**, проверим, что параметры **Min** и **Max** в разделе **Expected Values** равны 0 и 100 соответственно&nbsp;(4). В разделе **MQTT** оформим подписку&nbsp;(5) на топик `iot_practice/<UserID>/lamp/value`, и настроим поведение виджета для публикации сообщений&nbsp;(6) в тот же топик. По окончании редактирования нажимаем на **Ready**&nbsp;(7). ![onoff_19_slider](/assets/images/iot-academy/onoff/onoff_19_slider.png) Настройки подписки и публикации, а также законченный результат приведены далее. ![onoff_20_slider](/assets/images/iot-academy/onoff/onoff_20_slider.png) Чтобы визуально видеть, как меняется уровень яркости свечения нашей лампочки, добавим&nbsp;(1) график – виджет Graph&nbsp;(2). В его настройках зададим имя&nbsp;(3) **Percent**, проверим, что параметры **Min** и **Max** в разделе **Expected Values** равны 0 и 100 соответственно&nbsp;(4). В разделе **MQTT** оформим подписку&nbsp;(5) на топик `iot_practice/<UserID>/lamp/value`. При необходимости в разделе **Graph settings**&nbsp;(6) можно изменить цвет выводимого графика, а также настроить другие параметры. По окончании редактирования нажимаем на **Ready**&nbsp;(7). ![onoff_21_graph](/assets/images/iot-academy/onoff/onoff_21_graph.png) Настройки подписки, параметров графика, а также законченный результат приведены далее. ![onoff_22_graph_sub](/assets/images/iot-academy/onoff/onoff_22_graph_sub.png) ![onoff_80_ok_lamp](/assets/images/iot-academy/onoff/onoff_80_ok_lamp.png) ## Скрытые возможности виртуальной лампочки Наша виртуальная лампочка может не только светиться с разной яркостью, она может ещё и менять цвет, то есть является RGB-лампой, но этот режим нужно активировать! Если в топик `iot_practice/<UserID>/lamp/mode`, передать значение `rgb`, то лампа превратится в многоцветную. Её точно так же можно включать и отключать, посылая команды `on` и `off` в топик `iot_practice/<UserID>/lamp`. Но в этом случае диммер не работает, то есть передавать данные в топик `iot_practice/<UserID>/lamp/value` – бессмысленно. Для задания цвета используется топик `iot_practice/<UserID>/lamp/color`, в который надо передавать значение цвета в формате RGBA (альфа-канал при этом не используется). Например, значение `rgba(255, 0, 0, 0)` – сделает нашу лампочку абсолютно красной, `rgba(0, 255, 0, 0)` – зелёной, а `rgba(0, 0, 255, 0)` – синей. Допустимые значения каждого из цветовых компонентов от 0 до 255. ![fake_lamp_rgb](/assets/images/iot-academy/fake_lamp/fake_lamp_rgb.png) Чтобы вернуться к прежнему состоянию управления яркостью свечения, необходимо в топик `iot_practice/<UserID>/lamp/mode` передать значение `dimmer`. ### Задача Доработайте интерфейс в приложении **IoT&nbsp;OnOff** так, чтобы была возможность переключать лампу в режим диммирования и в режим RGB. Кроме того, в режиме RGB цвет лампы должен задаваться при помощи элемента **color**. ![onoff_99_ok_lamp](/assets/images/iot-academy/onoff/onoff_99_ok_lamp.png ) <div class="danger"> В программе **IoT&nbsp;OnOff** (как минимум в версии под Android) есть **ошибка** при работе с элементом **color** – если неправильно указать настройки этого элемента, то сколько бы вы его не редактировали, подписки и публикация будут осуществляться для **первоначально** указанных топиков! Единственное решение на текущий момент – удалить виджет и создать его заново не ошибаясь в параметрах подписки и публикации. И написать баг-репорт разработчикам! </div>