Pripojenie do internetu
o pripojení do internetu, synchronizácii času, stiahnutí a nainštalovaní rozširujúcich modulov pre MicroPython a pripojení k MQTT brokeru
Video pre cvičenie
Motivácia
Na minulom cvičení sme vytvorili základnú podobu stavového stroja nášho chytrého zariadenia. V rámci neho sme vytvorili niekoľko stavov a zabezpečili sme, že zariadenie po spustení vykoná samodiagnostiku, overí, či nemá obnoviť výrobné nastavenia, a nakoniec odmerá teplotu a vlhkosť a uloží ich do súboru. Posledný krok, ktorý nám chýba k zabezpečeniu základnej činnosti zariadenia, je tieto údaje poslať do “cloudu” pomocou protokolu MQTT. No a presne tomu sa budeme venovať na tomto cvičení.
Ciele
naučiť sa pripojiť mikrokontrolér k WiFi v jazyku MicroPython
naučiť sa nainštalovať rozširujúce moduly na MicroPython zariadenie
naučiť sa synchronizovať čas pomocou prokolu NTP
naučiť sa základy práce s komunikačným protokolom MQTT
Postup
Pripojenie k WiFi
Dnešným cieľom je zabezpečiť komunikáciu pomocou protokolu MQTT. Tento protokol patrí medzi aplikačné protokoly ISO/OSI modelu. Takže ak ho chceme využiť na komunikáciu, musíme sa najprv pripojiť do siete pomocou WiFi modulu.
Task
Rozšírte podobu konfiguračného súboru o konfiguráciu WiFi pripojenia.
Na koreňovej úrovni slovníka pridajte kľúč wifi
a do
neho pridajte slovník s kľúčmi ssid
a key
.
Výsledná konfigurácia teda bude vyzerať nasledovne:
{
...
"wifi": {
"ssid": "<ssid>",
"key": "<key>"
}
}
Upozornenie
Nezabudnite aktualizovať aj podobu predvoleného konfiguračného
súboru. Miesto konkrétnych hodnôt použite hodnotu None
.
Task
Do stavového stroja pridajte kostru nového stavu s názvom
ConnectToWiFi
, do ktorého sa zariadenie dostane po ukončení
stavu Measurement
, a z ktorého zariadenie prejde do stavu
Sleep
.
Task
V novovytvorenom stave sa pripojte do WiFi siete pomocou hodnôt uložených v konfiguračnom súbore.
Na pripojenie do siete použijeme funkciu s názvom
do_connect()
, ktorá sa nachádza priamo v dokumentácii
jazyka MicroPython.
Funkciu akurát mierne upravíme, aby:
- bola inštančnou metódou stavu
- mala dva parametre pre názov siete a kľúč do siete
Výsledná metóda bude vyzerať takto:
def _do_connect(self, ssid, key):
import network
= network.WLAN(network.STA_IF)
wlan if not wlan.isconnected():
print(f'Connecting to network {ssid}...')
True)
wlan.active(connect(ssid, key)
wlan.while not wlan.isconnected():
pass
print('network config:', wlan.ipconfig('addr4'))
Task
Aktualizujte stav Sleep
tak, aby sa nakoniec zariadenie
od siete WiFi odpojilo.
Odpojiť od WiFi je možné zavolaním metódy
.disconnect()
nad sieťovým rozhraním. Rovnako je však možné
zavolať aj metódu .deinit()
, ktorá modul vypne. Tým dôjde
aj k zníženiu spotreby zariadenia.
Task
Overte svoju implementáciu.
Ak ste postupovali správne, po úspešnom pripojení sa vám vypíše IP
adresa a maska sieťového rozhrania, a pri prechode stavom
Sleep
sa zariadenie od siete odpojí a vypne WiFi
modul.
Správny čas
Pri odosielaní nameraných dát budeme do správy pridávať aj informáciu o čase, kedy k meraniu došlo. To, kedy boli údaje namerané, je dôležité vedieť najmä vtedy, keď budeme údaje merať, alebo ich pošleme neskôr ako súbor meraní.
Mikrokontrolér RP2040, ktorý je osadený na doske Raspberry Pi Pico WH je už vybavený modulom hodín reálneho času (RTC). V tomto kroku teda urobíme všetko preto, aby sme ho vedeli nastaviť a rovnako tak využívať pre naše merania.
Pre úplnosť je potrebné dodať, že čas pri odosielaní, prijímaní a ukladaní do databázy budeme reprezentovať v štandarde UTC.
Task
Rozšírte svoj konfiguračný súbor o nový kľúč ntpHost
,
ktorý bude obsahovať názov servera, voči ktorému bude mikrokontrolér
synchronizovať svoj čas.
Predvolenú hodnotu nastavte na pool.ntp.org
.
Task
V stave inicializujúcom zariadenie nastavte hodnotu premennej
npttime.host
podľa aktuálnej hodnoty v konfigurácii.
Task
Aktualizujte stav ConnectToWifi
tak, aby sa po pripojení
do internetu automaticky zosynchronizoval aj čas pomocou protokolu
NTP.
Task
Aktualizujte proces meraní o pridanie časovej značky k jednotlivým meraniam.
Upravte svoju implementáciu vzhľadom na to, ako v akom formáte údaje lokálne ukladáte.
Inštalácia modulu pre prácu s protokolom MQTT
V aktuálnom firmvéri jazyka MicroPython pre mikrokontrolér RP2040 sa nenachádza modul pre prácu s protokolom MQTT. V tomto kroku ho nainštalujeme.
Na inštaláciu máme dve možnosti:
Inštalácia priamo z prostredia editora Thonny
prejdite do menu
Tools > Package management...
v dialógovom okne vyhľadajte modul
umqtt.simple
kliknite na tlačidlo
Install
, pomocou ktorého modul nainštalujete
Výhodou tohto prístupu je, že na inštaláciu modulu nie je potrebné, aby bol mikrokontrolér pripojený do siete. Problém však je, že ak máte na vašom počítači nainštalovaný Python vo verzii 3.12 a vyššie, inštalácia skončí s chybou. Ak je to váš prípad, na inštaláciu modulu použite druhú možnosť.
Inštalácia z rozhrania REPL mikrokontroléra
pripojte sa s vašim mikrokontrolérom do siete WiFi
v rozhraní REPL (terminál, príkazový riadok mikrokontroléra) importujte modul
mip
:>>> import mip
nad modulom
mip
spustite inštaláciu modulu zavolaním funkcie.install()
s názvom inštalovaného modulu:>>> mip.install('umqtt.simple')
Umiestnenie nainštalovaného modulu bude
/lib/umqtt/simple.mpy
.
Pripojenie k MQTT brokeru
V tomto kroku zabezpečíme všetko potrebné pre pripojenie k MQTT brokeru - od úpravy konfiguračného súboru, cez vytvorenie klienta až po pripojenie a odpojenie od MQTT broker-a.
Task
Rozšírte podobu konfiguračného súboru o konfiguráciu pre pripojenie k MQTT broker-u.
Na koreňovej úrovni slovníka pridajte kľúč mqtt
a do
neho pridajte slovník s kľúčmi clientId
,
server
, port
, user
a
password
. Výsledná konfigurácia teda bude vyzerať
nasledovne:
{
...
"mqtt": {
"client_id": "unique client id",
"server": "mqtt broker ip address",
"port": 1883,
"user": "username",
"password": "password for user",
}
}
Význam jednotlivých položiek je nasledovný:
client_id
- jedinečný identifikátor MQTT klienta (ak sa k brokeru pripojí viac klientov s rovnakým id, spôsobí to problémy pri doručovaní správ)server
- adresa MQTT brokeraport
- port, na ktorom počúva MQTT broker, štandardne sa jedná o port1883
user
- meno používateľapassword
- heslo používateľa
Pre experimentovanie môžete použiť nasledovnú konfiguráciu, pomocou ktorej sa pripojíte na hlavný MQTT broker v architekúre Smart Department:
{
...
"mqtt": {
"client_id": "unique-client-id",
"server": "147.232.205.176",
"port": 1883,
"user": "maker",
"password": "mother.mqtt.password",
}
}
Upozornenie
Nezabudnite aktualizovať aj podobu predvoleného konfiguračného
súboru. Miesto konkrétnych hodnôt použite hodnotu None
.
Task
Do stavového stroja pridajte kostru nového stavu s názvom
PublishData
, do ktorého sa zariadenie dostane po ukončení
stavu ConnectToWifi
, a z ktorého zariadenie prejde do stavu
Sleep
.
Task
Vytvorte inštanciu MQTT klienta z triedy MQTTClient
MQTT klienta vytvoríte týmto fragmentom kódu:
from umqtt.simple import MQTTClient
= MQTTClient(client_id, server, port, user, password) client
Význam jednotlivých parametrov zodpovedá významu konfiguračných parametrov.
Task
Pripojte sa vytvoreným klientom k MQTT brokeru a následne sa odpojte.
Pripojenie zabezpečíte metódou .connect()
a odpojenie
zabezpečíte metódou .disconnect()
. Výsledný fragment kódu,
pomocou ktorého vytvoríte MQTT klienta, pripojíte sa k brokeru a
následne sa od neho odpojíte, bude vyzerať takto:
from umqtt.simple import MQTTClient
= MQTTClient(client_id, server, port, user, password)
client connect()
client.# tu príde vaša komunikácia s MQTT brokerom
client.disconnect()
Task
Overte svoju implementáciu.
Ak ste postupovali správne, vaše zariadenie prejde všetkými stavmi bez chyby. Otestujte aj prípadnú chybu napr. nesprávnymi prihlasovacími údajmi alebo nesprávnou identifikáciou MQTT brokera.
Pred odchodom z cvičenia…
Upozornenie
Ak máte požičanú dosku Raspberry Pi Pico WH od cvičiaceho, tak pred odchodom z cvičenia prosím:
- zmažte obsah Flash pamäte mikrokontroléra nahratím fimrvéru flash_nuke.uf2
- nahrajte na mikrokontrolér najnovší firmvér
Ďalšie úlohy
Aktuálna implementácia funkcie na pripojenie do siete WiFi nie je dobrá, pretože pokiaľ sa funkcii nepodarí pripojiť do siete, funkcia uviazne v nekonečnej slučke. Upravte preto túto funkciu tak, aby sa o pripojenie pokúsila 3x v niekoľkosekundových intervaloch. Pokiaľ k pripojeniu do siete nedôjde, ukončite funkciu zariadenia prechodom do stavu
Error
.Aktualizujte implementáciu stavu
FactoryReset
tak, aby vygeneroval náhodnú hodnotu identifikátora klienta pre komunikáciu s MQTT protokolom.Zabezpečte, aby v prípade vzniku akejkoľvek chyby vaše zariadenie prešlo do stavu
Error
.V module
helpers.py
vytvorte funkciuto_iso8601()
, ktorá prevedie n-ticu reprezentujúcu aktuálny dátum a čas alebo časovú značku na reťazec reprezentujúci dátum a čas vo formáte podľa štandardu ISO 8601.
Ďalšie zdroje
- MicroPython: Network basics
- MicroPython Lib: umqtt.simple - zdrojové kódy, ukážkové príklady a dokumentácia
- ISO 8601 - medzinárodný štandard pre zápis dátumu a času