IT Академия Samsung – MQTT клиент на Python # MQTT-клиент на Python До нынешнего момента работа с MQTT-сервером производилась просто в консоли при помощи команд `mosquitto_sub` и `mosquitto_pub` – это удобно для одноразовых задач вроде считывания данных или отправки тестовых команд. Также мы немного поработали с графическими клиентами. Но в любом случае вся работа по ораганизации подписки и получения сообщения от нас была фактически скрыта – за нас это делали сторонние компоненты. ## Взаимодействия с сервером на Python Для взаимодействия с MQTT-сервером существуют различные библиотеки. Мы рассмотрим библиотеки из проекта Eclipse Paho. Под крылом проекта Paho разрабатываются открытые реализации протокола MQTT в виде библиотек для почти всех популярных языков программирования: существуют реализации для C, C++, Java, Go, C#, Python, Javascript. Рассмотрим пример работы с Paho в Python. <div class="info"> В рамках этого практикума мы рассматриваем программирование на языке Python исключительно из-за достаточно простого синтаксиса самого языка программирования и минимума прикладываемых усилий для оснащения своего рабочего места средствами разработки программного обеспечения. При желанни вы можете выполнить все на своем любимом языке программирования. </div> <div class="best"> Существует великое множество бесплатных курсов, посвященных пазработке на языке Python. Например, https://www.coursera.org/learn/programming-in-python </div> Саму библиотеку Paho очень просто установить из командной строки (терминала): ```sh pip install paho-mqtt ``` Попробуйте запустить тестовую программу. Она взята из примера в [репозитории](https://github.com/eclipse/paho.mqtt.python) без изменений. Её функционал очень прост: вывод на экран сообщений из определённого топика. ```python import paho.mqtt.client as mqtt # The callback for when the client receives a CONNACK response from the server. def on_connect(client, userdata, flags, rc): print("Connected with result code "+str(rc)) # Subscribing in on_connect() means that if we lose the connection and # reconnect then subscriptions will be renewed. client.subscribe("$SYS/#") # The callback for when a PUBLISH message is received from the server. def on_message(client, userdata, msg): print(msg.topic+" "+str(msg.payload)) client = mqtt.Client() client.on_connect = on_connect client.on_message = on_message client.connect("iot.eclipse.org", 1883, 60) # Blocking call that processes network traffic, dispatches callbacks and # handles reconnecting. # Other loop*() functions are available that give a threaded interface and a # manual interface. client.loop_forever() ``` ### Задание 1. Изучите текст примера и выделите для себя ключевые моменты: - Где и в какой момент происходит подписка на топик? - Где происходит подключение к серверу? - Где обрабатывается входящее сообщение? 2. Модифицируйте программу так, чтобы она работала с вашим локальным сервером и подписывалась на тот топик, который вас интересует. 3. Модифицируйте программу так, чтобы она взаимодействовала с тем же MQTT-брокером, что и в предыдущем практикуме, и подписывалась на топик `iot_practice/<UserID>/servers/#` (не забудьте подставить ваш уникальный идентификатор пользователя, например, `iot_practice/5404/servers/#`). <div class="info"> Обратите внимание в [документации](https://eclipse.org/paho/clients/python/docs/) на метод `username_pw_set()` класса `Client` библиотеки Paho MQTT. Этот метод нужно вызвать **перед** установлением соединения! </div> 4. Проверьте работоспособность своей программы, отправляя каким-либо клиентом MQTT (mosquito_pub, MQTT.fx, и т.п.) сообщения в топики, расположенные ниже `servers`, например, `iot_practice/<UserID>/servers/yandex` ## Отправка сообщений в Python Из [документации](https://eclipse.org/paho/clients/python/docs/) библиотеки Paho можно узнать, что функция для отправки сообщения выглядит так: ```python publish(topic, payload=None, qos=0, retain=False) ``` Параметры этой функции достаточно очевидны и уже встречались нам ранее: * `topic` – топик, в который идет сообщение; * `payload` – текст сообщения; * `qos` – качество обслуживания (Quality of Service); * `retain` – флаг сообщения «до востребования». Если он имеет значение `True`, то сообщение будет «храниться до востребования», если подписчик сейчас отключен, то после подключения к брокеру он все равно это сообщение получит, поскольку оно будет храниться на сервере. Данный параметр хорош для передачи тех сообщений, которые не устаревают: например, ценные данные мониторинга, конфигурация подключения оборудования и т.д. В нашем случае информация может устареть, поэтому разумно установить его в `False`. ### Задача Добавьте в вашу программу на Python публикацию сообщений в топики `iot_practice/<UserID>/sensor/temperature`, `iot_practice/<UserID>/sensor/humidity`, `iot_practice/<UserID>/sensor/luminosity`. То есть сделайте некий программный генератор сообщений – раз в несколько секунд он должен отправлять данные о температуре, влажности и освещенности подобно тому, как это делает реальное устройство. Бесконечный цикл `loop_forever()` в начале программы можно заменить на `loop_start()` и `loop_stop()` (об этом написано в [документации](https://www.eclipse.org/paho/index.php?page=clients/python/docs/index.php#network-loop)). <div class="info"> <p>Чтобы организовать задержку в несколько секунд, можно воспользоваться функцией `sleep()` модуля [time](https://pythonworld.ru/moduli/modul-time.html)</p> <p>Можно добавить случайных значений, используя модуль [random](https://pythonworld.ru/moduli/modul-random.html)</p> <pre> import time import random ... while True sensor = 123 + random.uniform(-5, 5) client.publish("sensor/value", sensor) time.sleep(5) </pre> </div> <div class="success"> <p>В целом, мы уже достаточно много практиковались с протоколом MQTT, можно сказать, что стали **гуру** в этом вопросе.</p> <p>Как только справитесь с поставленной задачей, отправьте сообщение `guru` любым способом в топик `iot_practice/<UserID>/i_am` на сервер лаборатории, где `<UserID>` – ваш идентификатор в IT Академии Samsung.</p> </div>