Lab #5: Komunikácia pomocou prokolu MQTT
organizácia tém, štruktúra správ, zmena konfigurácie zariadenia a jeho ovládanie na diaľku pomocou protokolu MQTT
Video pre cvičenie
Motivácia
Komunikačný protokol MQTT patrí medzi najčastejšie a najobľúbenejšie protokoly používané v oblasti IoT. Aj preto je hlavným komunikačným protokolom v architekúre projektu Smart Department, kde sa používa na komunikáciu medzi všetkými vrstami architektúry. Všetky správy, ktoré sa pomocou protokolu MQTT posielajú, sú vo formáte JSON.
Na tomto cvičení zabezpečíme odosielanie nameraných údajov zo senzoru, ako aj príjem správ na zmenu konfigurácie zariadenia a vzdialenú správu.
Ciele
naučiť sa ovládať chytré zariadenie pomocou protokolu MQTT
naučiť sa prijímať správy cez MQTT protokol
porozumieť významu príznaku
retainpri odosielaní MQTT správnaučiť sa zabezpečiť OTA aktualizáciu zmenou konfigurácie zariadenia
Postup
Inštalácia
knižnice umqtt.simple
V aktuálnom firmvéri jazyka MicroPython pre mikrokontroléry
z rodiny RP2 sa nenachádza modul pre prácu s protokolom
MQTT. V tomto kroku ju pridáme nainštalovaním balíka umqtt.simple.
Task
Nainštalujte na chytré zariadenie knižnicu umqtt.simple.
Knižnica umqtt.simple
je minimalistický klient protokolu MQTT zo štandardnej knižnice
jazyka MicroPython (micropython-lib).
Je navrhnutá pre zariadenia s obmedzenými zdrojmi, takže je malá a
podporuje len to najpodstatnejšie:
- pripojenie k brokeru
- podpora šifrovanej komunikácie pomocou TLS,
- publikovanie správ s úrovňou kvality služby QoS 0 alebo 1 (QoS 2 nepodporuje),
- prihlásenie na odber tém a spracovanie prijatých správ,
- nastavenie poslednej vôle (z angl. last will).
Knižnica je blokujúca a spojenie s brokerom sama neudržiava. Pri
dlhšom spojení je preto potrebné posielať brokeru správu
PING a po výpadku sa pripojiť znova. Automatické opätovné
pripojenie rieši nadstavba umqtt.robust.
Používateľské nastavenia pre MQTT
Chytré zariadenie bude komunikovať pomocou protokolu MQTT.
To, ku ktorému brokeru sa pripojí, aké prihlasovacie údaje použije a či
bude komunikácia šifrovaná, však závisí od toho, kde bude zariadenie
nasadené – iný broker použijete na cvičení, iný doma a iný bude mať
zákazník. Tieto údaje preto nemôžu byť súčasťou statickej konfigurácie v
module constants.py, ale musí ich byť možné zmeniť bez
zásahu do kódu.
V tomto kroku rozšírime triedu Settings o novú skupinu
nastavení pre pripojenie k MQTT brokeru.
Task
Rozšírte používateľské nastavenia o pripojenie k MQTT brokeru.
Nastavenia pripojenia budú v novej triede MQTT a v
triede Settings budú dostupné v členskej premennej
mqtt. Trieda MQTT bude vyzerať nasledovne:
class MQTT(BaseModel):
broker: str = Field(default=None, type=str, optional=True)
port: int = 1883
username: str = Field(default=None, type=str, optional=True)
password: str = Field(default=None, type=str, optional=True)
tls: bool = False
topic_prefix: str = 'thsensor'Význam jednotlivých premenných je nasledovný:
broker– adresa MQTT brokera,port– port, na ktorom broker počúva; štandardne1883, pri šifrovanej komunikácii8883,usernameapassword– prihlasovacie údaje k brokeru,tls– príznak šifrovanej komunikácie (ak ho zapnete, nezabudnite zmeniť aj port),topic_prefix– začiatok tém, do ktorých bude zariadenie publikovať.
Task
Navrhnite a implementujte vhodné validátory pre overenie hodnôt v nastaveniach pripojenia k MQTT brokeru.
Zamyslite sa nad tým, ktoré hodnoty môže používateľ zadať nesprávne a čo by to spôsobilo pri pripájaní k brokeru alebo pri publikovaní správ. Môžete sa inšpirovať napríklad týmito validátormi:
check_port()– overí, či je číslo portu v rozsahu1až65535,check_host()– overí, či je adresa brokera platný doménový názov alebo IP adresa (napr. nesmie obsahovať medzery, schému akomqtt://ani číslo portu),check_topic_prefix()– overí, či prefix tém neobsahuje zástupné znaky+a#a nezačína ani nekončí znakom/.
Ak hodnota nie je platná, validátor vyvolá výnimku
ValueError s vhodnou správou.
Task
Nastavte a uložte nastavenia pre pripojenie k MQTT brokeru, ktorý budeme používať na cvičeniach.
Broker má tieto parametre:
- adresa:
mother.fei.tuke.sk - port:
8883 - používateľské meno:
student - heslo:
dgRk9cQ8sU4fCO - šifrovaná komunikácia: áno
Nastavenia zmeňte v servisnom termináli pomocou príkazu
settings a uložte ich. Ak ste postupovali správne, výpis
nastavení bude vyzerať takto:
> settings get mqtt
broker: "mother.fei.tuke.sk"
port: 8883
username: "student"
password: "dgRk9cQ8sU4fCO"
tls: true
topic_prefix: "thsensor"
Overte aj to, že nastavenia zostanú zachované po reštarte zariadenia.
Príkaz mqtt
V tomto kroku vytvoríme príkaz mqtt, pomocou ktorého
bude možné pracovať s MQTT brokerom priamo zo servisného
terminálu. Technik si tak bude môcť ručne overiť, či sú nastavenia
pripojenia správne. Jednotlivé činnosti príkazu implementujeme ako operácie príkazu, aby ich neskôr mohli použiť
aj stavy zariadenia.
Task
V module commands/mqtt.py vytvorte triedu
MQTT, ktorá bude reprezentovať príkaz
mqtt.
O tejto triede bude platiť:
- bude potomkom triedy
BaseCommand, - názov príkazu bude
"mqtt", - opis príkazu bude
"Manage MQTT client.", - prvým parametrom príkazu bude názov podpríkazu
(
connect,disconnectalebopub) a ďalšie parametre dostane vybraný podpríkaz, - ak príkaz nedostane žiadny parameter alebo dostane neznámy
podpríkaz, vypíše správu
"Error: Wrong usage.", - klienta pre pripojenie k MQTT brokeru bude uchovávať v
členskej premennej kontextu
mqtt, aby s ním mohli pracovať aj ďalšie príkazy a stavy; túto premennú vytvorte v konštruktore kontextu s hodnotouNone.
Príkaz zaregistrujte rovnako ako ostatné príkazy.
Task
Vytvorte podpríkazy connect a disconnect na
pripojenie k MQTT brokeru a odpojenie od neho.
Pripojenie a odpojenie implementujte ako operácie príkazu
.connect() a .disconnect().
Operácia .connect() vytvorí klienta triedy
MQTTClient z knižnice umqtt.simple,
pripojí sa ním k brokeru a uloží ho do členskej premennej kontextu
mqtt. Pri vytváraní klienta použite:
- identifikátor zariadenia
device_idako identifikátor klienta, - adresu brokera, port a prihlasovacie údaje z nastavení
mqtt, - konštantu
MQTT_KEEPALIVEako interval udržiavania spojenia, - šifrovanie podľa nastavenia
tls.
Operácia .disconnect() sa od brokera odpojí a premennú
mqtt v kontexte nastaví na hodnotu None.
Podpríkazy vypíšu:
"Connecting to <broker>..."na začiatku pripájania a"Connected."po úspešnom pripojení,"Disconnected."po odpojení,"Error: Not connected.", ak sa podpríkazconnectvolá bez pripojenia do WiFi siete alebo podpríkazdisconnectbez pripojenia k brokeru,"Error: <text výnimky>", ak sa pripojenie nepodarí.
Pri pripájaní môžu vzniknúť dva typy výnimiek. Ak je broker
nedostupný alebo má nesprávnu adresu, vznikne výnimka
OSError. Ak broker pripojenie odmietne (napr. pre nesprávne
meno alebo heslo), vznikne výnimka MQTTException s
návratovým kódom brokera (napr. kód 5 znamená, že klient
nie je autorizovaný).
Poznámka
Šifrovanie sa v knižnici umqtt.simple
zapína parametrom ssl, hoci sa v skutočnosti používa jeho
nástupca, protokol TLS. Názov SSL sa udržal z
historických dôvodov, rovnako ako názov modulu ssl.
Parametru ssl odovzdajte objekt triedy
ssl.SSLContext (napr.
ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)). Staršia podoba
ssl=True je v knižnici ponechaná len kvôli spätnej
kompatibilite.
Príklad použitia podpríkazov môže vyzerať nasledovne:
> mqtt connect
Error: Not connected.
> net connect iot-lab Secret.Password
...
> mqtt connect
Connecting to mother.fei.tuke.sk...
Connected.
> mqtt disconnect
Disconnected.
> mqtt disconnect
Error: Not connected.
Task
Vytvorte podpríkaz pub na odosielanie správ, ktorého
činnosť implementujete ako operáciu príkazu .pub().
Pripojenie k a odpojenie od MQTT brokera
Pripojenie k MQTT brokeru bude úzko súvisieť so stavom
ConnectNetwork. Najprv sa zariadenie pripojí do WiFi siete
a hneď potom sa pripojí k MQTT brokeru.
Podobne to bude platiť aj pre stav DisconnectNetwork,
ktorého súčasťou sa stane odpojenie od MQTT brokera.
Task
Rozšírte funkcionalitu stavu ConnectNetwork o pripojenie
k MQTT brokeru.
Task
Rozšírte funkcionalitu stavu DisconnectNetwork o
odpojenie od MQTT brokera.
Aby bolo možné komunikovať pomocou protokolu MQTT s okolím, je potrebné pripojiť chytré zariadenie k MQTT broker-u. To zabezpečíme v tomto kroku.
Pre experimentovanie môžete použiť nasledovnú konfiguráciu, pomocou ktorej sa pripojíte na hlavný MQTT broker v architekúre Smart Department:
server = "147.232.205.176"port = 8883user = "student"password = "dgRk9cQ8sU4fCO"ssl = true
Nastavenie uvedených vlastností zabezpečte v stave
Configuration samostatným rozhraním a overte ich v stave
Commissioning. Ak sa zariadeniu nepodarí pripojiť k
MQTT brokeru, vráťte sa späť do stavu
Configuration.
Samotné pripojenie k MQTT brokeru pred odoslaním nameraných
dát, prebehne v stave Connect Network. Odpojenie od
MQTT brokera zasa v stave Sleep. V prípade
akéhokoľvek problému zariadenie prejde do stavu Error. Pri
odpájaní nezabudnite, že najprv sa treba odpojiť od MQTT
brokera a až potom sa môžete odpojiť od WiFi.
Publikovanie stavu zariadenia a posledná vôľa
Rovno po pripojení zariadenia k MQTT brokeru je potrebné vykonať dve veci:
- nastaviť tzv. poslednú vôľu, a
- vypublikovať, resp. aktualizovať stav zariadenia
Posledná vôľa ako aj stav zariadenia by mali mať nastavený
retain príznak, aby sa o stave zariadenia dozvedel
ktokoľvek, kto sa pripojí neskôr, ako daná správa vznikla.
Stav zariadenia ako aj posledná vôľa, sa budú posielať do rovnakej
témy a síce:
<department>/<room>/<type>/<id>/status.
V oboch prípadoch je dôležité, aby JSON dokument obsahoval jeden kľúč
s názvom status a hodnotou online alebo
offline vzhľadom na stav zariadenia:
{
"status": "offline"
}Keď sa zariadenie pripojí, môžete do stavu zariadenia publikovať aj ďalšie informácie, ako napr.:
- IP adresa zariadenia
- čas a dátum zapnutia
- vlastnosti zariadenia
- číslo firmvéru MicroPython-u
- číslo verzie vášho softvéru
- informácie o mikrokontroléri
- a pod.
Poznámka
Pre testovanie komunikácie si nainštalujte klientsku MQTT aplikáciu, ako napr.:
- MQTT Explorer - An all-round MQTT client that provides a structured topic overview.
- Mosquitto Clients - Príkazy pre príkazový riadok na komunikáciu s MQTT brokerom.
Publikovanie nameraných dát
Správanie chytrého senzora rozšírime o nový stav s názvom
PublishData, v ktorom dôjde k odoslaniu nameraných dát. Po
úspešnom odoslaní nameraných dát prejde zariadenie do stavu
Sleep.
Pre odosielanie správ môžete využiť triedu Payload v
balíku models. Táto trieda má dve premenné:
dt- čas odoslania reprezentovaný ako reťazec formátovaný podľa štandardu ISO 8601metrics- zoznam metrík, resp. zoznam meraní
Zariadenie bude svoje merania publikovať do témy
<department>/<room>/<type>/<id>/data.
Údaje budú publikované ako JSON dokument, ktorý bude vyzerať
napr. takto:
{
"dt": "2024-10-29T20:09:35Z",
"metrics": [
{
"dt": "2024-10-29T20:00:00Z",
"name": "temperature",
"value": 23.4,
"units": "metric"
},
{
"dt": "2024-10-29T20:00:00Z",
"name": "humidity",
"value": 70,
"units": "%"
}
]
}Merania reprezentujte ako inštanciu triedy Payload,
ktorá sa nachádza v module models.payload.
Pred odchodom z cvičenia…
Upozornenie
Ak máte dosku RPi Pico 2 WH požičanú od cvičiaceho, pred odchodom z cvičenia prosím:
- Uložte si kód, ktorý ste na cvičení vytvorili.
- Zmažte obsah Flash pamäte mikrokontroléra nahratím firmvéru flash_nuke.uf2. Pozor! Mikrokontrolér neodpájajte od počítača, kým sa vo vašom počítači znova neobjaví ako USB zariadenie.
- Nahrajte na mikrokontrolér najnovší firmvér.
Ďalšie úlohy
Ďalšie zdroje
MicroPython Lib: umqtt.simple - zdrojové kódy, ukážkové príklady a dokumentácia
MicroPython Chapters: Inštalácia balíkov
MicroPython Chapters: Práca s protokolom MQTT