MQTT на практике: publish и subscribe из MicroPython

Подключаем плату к брокеру и обмениваемся реальными сообщениями.

umqtt.simple — компактная библиотека MQTT для MicroPython, дающая методы connect, publish и subscribe.

Подготовка

Нужен брокер. Для учёбы подойдёт публичный (например, test.mosquitto.org) или свой Mosquitto, поднятый дома. Библиотека umqtt.simple ставится через менеджер пакетов mip или копируется на плату вручную.

Публикуем температуру

from umqtt.simple import MQTTClient
from machine import Pin
import dht, time

sensor = dht.DHT22(Pin(4))
client = MQTTClient("esp32-livingroom", "test.mosquitto.org")
client.connect()
print("Подключено к брокеру")

while True:
    sensor.measure()
    temp = sensor.temperature()
    client.publish(b"home/livingroom/temp", str(temp).encode())
    print("Опубликовано:", temp)
    time.sleep(30)

Подписываемся на команды

from umqtt.simple import MQTTClient
from machine import Pin

led = Pin(2, Pin.OUT)

def on_message(topic, msg):
    if msg == b"ON":
        led.on()
    elif msg == b"OFF":
        led.off()
    print("Команда:", topic, msg)

client = MQTTClient("esp32-lamp", "test.mosquitto.org")
client.set_callback(on_message)
client.connect()
client.subscribe(b"home/livingroom/light")

while True:
    client.check_msg()   # проверяем входящие
    time.sleep(1)

Теперь любой клиент, опубликовавший ON в home/livingroom/light, включит светодиод.

Формируем полезную нагрузку JSON

Часто в одном сообщении шлют несколько величин в JSON. Это чистый stdlib, поэтому пример исполним:

import json

def make_payload(temp, hum, battery):
    return json.dumps({"t": temp, "h": hum, "bat": battery})

msg = make_payload(23.5, 45, 87)
print("Публикуем в home/livingroom/state:")
print(msg)

# приёмная сторона разбирает обратно
state = json.loads(msg)
print("Температура:", state["t"], "заряд:", state["bat"], "%")

Вывод:

Публикуем в home/livingroom/state:
{"t": 23.5, "h": 45, "bat": 87}
Температура: 23.5 заряд: 87 %

Как работает под капотом

При connect() библиотека открывает TCP-соединение с брокером и шлёт пакет CONNECT с именем клиента (оно должно быть уникальным). publish отправляет пакет с топиком и данными — заметьте, и топик, и сообщение это байты (отсюда b"..." и .encode()). subscribe регистрирует интерес к топику, а check_msg() читает входящие пакеты и вызывает ваш callback. В umqtt.simple приём неблокирующий — нужно регулярно звать check_msg() в цикле.

Частые ошибки

  • Передавать строку вместо байтов. Топик и payload должны быть bytes — используйте b"..." или .encode().
  • Одинаковый client_id. Два устройства с одним именем выбивают друг друга из брокера.
  • Не звать check_msg(). Без регулярного вызова входящие команды не обрабатываются.

Итог

  • umqtt.simple даёт connect, publish, subscribe, check_msg.
  • Топики и сообщения передаются как байты.
  • Несколько величин удобно слать одним JSON-сообщением.
  • Имя клиента уникально; для приёма команд регулярно вызывайте check_msg().
Проверьте себя
1. В каком виде передаются топик и сообщение в umqtt.simple?
AКак обычные строки
BКак байты (bytes), например b"home/temp"
CКак числа
DКак словари
2. Зачем регулярно вызывать client.check_msg()?
AЧтобы публиковать данные
BЧтобы прочитать входящие сообщения и вызвать callback
CЧтобы подключиться к Wi-Fi
DЧтобы перезагрузить плату
3. Что будет, если два устройства подключатся к брокеру с одинаковым client_id?
AНичего, это норма
BОни будут выбивать друг друга из соединения
CСкорость удвоится
DБрокер их объединит