Python a BigClown

Kompilátor
6 min readNov 5, 2022

--

MQTT

MQTT je komunikačný protokol na predávanie informácií/správ medzi klientami z jedného hlavného centrálneho bodu — ktorý sa označuje anglicky ako broker. Prenos prebieha pomocou TCP a funguje na základe vzoru publisher-subscriber.

V MQTT sa broker (centrálny bod) stará o výmenu správ medzi zariadeniami/klientami. Správy sú triedené do rôznych tém (topicov), pričom zariadenie buď správu prijíma alebo publikuje. Každá správa patrí do jednej témy. Témy sú oddelené lomítkami.

V našom prípade potrebujeme prijať správu zo zariadenia (buttonu), čiže zariadenie publikuje správu do zvoleného topicu a posiela do brokeru, ktorý správu následne distribuuje ďalším zariadeniam podľa zvoleného topicu, ku ktorému sme sa subscribli/prihlásili.

Naše zariadenie — PC sa k nemu prihlási/subscribne, kedy pošle brokeru špeciálnu správu s názvami tém, ktoré chce odoberať.

Výmena správ:

  1. na začiatku dôjde k naviazaniu spojenia s brokerom pomocou TCP. Najčastejšie sa používa port 1883.
  2. funkcia connect()
  3. globálna premenná client — v ktorej máme uložený názov klienta — v našom prípade je to meal-notification
  4. následne nastavíme callback on_message, ktorý sa stará o vypísanie informácií/správy potom, čo dostaneme informáciu zo zariadenia
  5. pripojenie ku klientovi je prostredníctvom connect() metódy definovanej v paho knižnici, ktorá sa stará o naviazanie spojenia s brokerom, kedy vstupným parametrom je práve broker- v ktorom je uložená adresa nášho mqtt servera
  6. po naviazaní spojenia connect posiela broker správu o úspešnom spojení
  7. následne nastavíme asynchrónne čakanie pomocou loop.start(), kedy program kód nečaká na správu, ale beží ďalej na hlavnom alebo vedľajšom vlákne
  8. následne nasleduje jedna alebo viacero tém — subscribe, ktoré chce zariadenie odoberať
  9. v našom prípadne sme sa prihlásili k odberu dvoch topicov event-count a push-count
  10. 2ka exactly once — publisher pošle správu brokeru, ten správu prijme a pošle publisherovi správu o prijatí. Publisher odpovie a potvrdí prijatie tejto správy a následne správu zmaže.

Príklad programu sa nachádza tu — https://github.com/SvetlanaM/hardwario-projects

Program

  • program je séria príkazov/inštrukcií, ktoré hovoria počítaču alebo inému zariadeniu, čo má vykonať. Musí mať presnú postupnosť krokov, ktoré počítač číta zhora nadol. Program môže byť naprogramovaný v rôznych programovacích jazykoch.
  • Program je možné uložiť a následne spustiť. Kód v programe je zapísaný formou zdrojového kódu — na ten sa pozeráme. Tento zdrojový kód následne komplikátor prevedie do strojového kódu, ktorému rozumie počítač.

Python

  • Python patrí medzi populárne programovacie jazyky, jedná sa o skriptovací programovací jazyk. Využíva sa na programovanie webových stránok, aplikácií, data analýzu, machine learning a má mnoho ďalších využití.

Knižnice

  • Knižnica je zoznam hotových funkcií/metód, vďaka ktorým môžeme v kóde vykonávať rôzne úlohy a akcie bez nutnosti ich naprogramovať (už ich naprogramoval niekto za nás). Knižnice v Pythone rozdeľujeme na:
  • štandardné — sú nainštalované spolu s inštaláciou Pythonu a nie je potrebné ich dodatočne inštalovať — napríklad knižnica datetime na prácu s dátumovými a časovými údajmi
  • externé — knižnice iných firiem/vývojárov, ktoré je potrebné najprv nainštalovať. Externými knižnicami v našom projekte sú paho — MQTT klient a pynput umožňujúci pracovať so vstupmi z klávesnice
  • aby sme mohli kód z knižnice použiť je potrebné si ho na začiatku importnúť. Importnúť môžeme celú knižnicu, alebo iba špecifické funkcie a metódy, ktoré chceme použiť
  • inštalácia knižníc pomocou pip alebo pip3, program, ktorý sa stará a správu a inštaláciu knižníc pre jazyk Python

Premenné

  • sú hlavným pilierom programovania. Vďaka premennej si vieme uložiť hodnotu/informáciu a použiť ju až vo chvíli keď ju potrebujeme. Taktiež je možné hodnotu v premennej prepísať. Príkladom premennej je napríklad premenná s názvom broker, kde si ukladáme adresu servera. Hodnotu do premennej priraďujeme pomocou =. Následne je možné premennú v kóde použiť na ľubovoľnom mieste. Premenné by mali byť v anglickom jazyku a mali by vypovedať z názvu o hodnote, ktorú uchovávajú. Premennú si môžeme predstaviť ako kontajner/krabičku, ktorá uchováva informácie.

Premenné môžu byť:

  • lokálne — je definovaná v danom bloku/kóde a môže v ňom byť použitá
  • globálne — je definovaná mimo danej funkcie a je možné ju použiť na ľubovoľnom mieste v danom kóde

Funkcie/Metódy

Funkcie nám umožňujú v programovaní zabaliť menšie časti kódu, ktoré spolu súvisia do znovupoužiteľných blokov. Funkcia by sa mala starať o čo najmešiu logiku, aby bolo z nej hneď jasné čo má na starosti a mala by mať taktiež výstižné meno. Funkcia je taktiež blok kódu, ktorý sa vykoná iba vo chvíli, kedy je zavolaná. Do funkcie môžeme vložiť dáta ako parametre, ktoré slúžia ako vstupy a sú v danej funkcii použité. Počet parametrov je neobmedzený ale môže byť aj nula. Funkcia taktiež môže vrátiť výslednú/návratovú hodnotu pomocou príkazu return, napríklad výsledok nejakého výpočtu.

Funkcia je použitá jej zavolaním pomocou mena funkcie. V pythone sa definuje pomocou slova def a názov funkcie(). V zátvorkách sú parametre funkcie. U nás máme viacero funkcií, napríklad funkciu connect(), ktorá sa stará o pripojenie k nášmu MQTT brokeru a subscribnutiu k danej téme/topicu.

Funkcie môžeme vytvoriť buď vlastné, alebo použiť funkcie hotové dostupné v danom programovacom jazyku alebo z knižnice, ktorú sme si importli.

Príkladom hotovej funkcie je napríklad client.connect(broker), ktorá na vstupe načítava hodnotu z premennej broker.

Okrem funkcií máme v programovaní aj metódy. Metóda je taktiež funkcia, no narozdiel od funkcie je možné ju použiť iba nad objektom, nad ktorým bola definovaná.

Datetime je knižnica, ktorá nám umožňuje pracovať s dátumami. Má v sebe definované rôzne typy, metódy a funkcie.

Datetime.datetime — nám umožňuje pracovať s kombináciou dátumu a času, pričom je nad nimi dostupná metóda now() — vracia aktuálny lokálny dátum a čas. Vráti nám v zátvorkách datetime objekt, ktorý obsahuje v zátvorke, čiarkami oddelený rok, mesiac, deň a čas. Aby sme získali napríklad konkrétnu hodinu môžeme použiť hotový atribút hour, ktorý vráti konkrétnu hodinu.

Príkladom často používanej funkcie je funkcia print, ktorá je bez parametrov. Je to funkcia preto, že ju môžeme univerzálne použiť nad rozličnými objektami. Slúži na výpis dát/hodnot na obrazovku, pričom na vstupe je potrebné zadať textové hodnoty. Ak objekt nie je v textovom formáte, pred vstupom do funkcie print je potrebné ho pretypovať. Do printu môžeme zadať aj viacero výrazov naraz a oddeliť ich čiarkou.

Taktiež je možné výpis rôzne formátovať. Napríklad ‘{} {}’.format(‘one’, ‘two’)

alebo pomocou {:d} pre formátovanie čísel a podobne.

Rôzne funkcie, metódy a výrazy môžeme volať aj za sebou prostredníctvom bodky a týmto ich spájať. Pričom sa príkazy vykonávajú postupne v poradí, v akom sú spojené.

Podmienky

V programovaní niekedy potrebujeme usmerňovať tok programu na základe rozhodovania/podmienok. V Pythone a aj v iných jazykoch využívame podmienku IF, ktorá už ako z názvu hovorí AK. Za podmienkou if je vždy potrebné definovať, čo porovnávame alebo chceme vyhodnotiť napríklad ak aktuálna hodina je viac ako 7. Následne definuje čo sa má stať, ak je podmienka pravdivá. Pravdivosť podmienky je vyhodnotená pravdivostnou návratovou hodnotou — True. V našom kóde sme si definovali, ak je viac ako 7 hodín ráno, poď raňajkovať. Ako v kóde ale vidíte, je tam ďalšia podmienka ak je zároveň menej alebo 9 hodín. Podmienky môžeme definovať pomocou pravdivostných operátorov — and — a zároveň — obe/všetky podmienky musia byť splnené naraz alebo or — alebo — stačí ak aspoň jedna z podmienok je splnená.

Taktiež môžeme nastaviť pre program viacero rozhodovacích podmienok naraz, ako keď tvoríme rozhodovací strom. Každú ďalšiu podmienku pridáme pomocou výrazu elif, kde definujeme podmienku novú.

Finálne môžeme definovať, čo sa má stať, ak ani jedna z nami definovaných podmienok nie je splnená pomocou príkazu else. Ak program nájde zhodu v danej podmienke prejde do jej vyhodnotenia a na ďalšie podmienky nepozerá.

Taktiež máme v programovaní cykly, v prípade, že potrebujeme určitú časť kódu vykonávať opakovane. Najvyužívanejšie cykly v Pythone sú:

  • for cyklus — používa sa , keď máme dopredu známy počet opakovaní
  • while cyklus — používa sa, keď nepoznáme počet opakovaní, ale je definovaná podmienka, počas ktorej cyklus beží, kým je splnená. Treba si dávať pozor, aby nedošlo k nekonečnému cyklu.

Do cyklov sa často vkladajú taktiež podmienky, ktoré lepšie flow cyklu koordinujú. Cyklus môžeme ukončiť pomocou príkazu break, alebo nastaviť jeho pokračovanie pomocou príkazu continue.

CallBack

je funkcia, ktorá sa vykoná potom, čo iná funkcia pred ňou bola vykonaná. V programovaní môže byť argumentom funkcie, iná funkcia a vtedy hovoríme o callbackoch. No namiesto toho, aby sme čakali na jej spracovanie a dokončenie, beh programu beží ďalej a čaká na rôzne eventy a signáli. Keď dostaneme signál, že funkcia je spracovaná, ďalej na ňu reagujeme. Keď potrebujeme spustiť kód, ktorý nemôže byť hneď vykonaný, napríklad odpoved zo zariadenia po stlačení buttonu. Vdaka callbackom zaručíme, že sa nevykoná spracovanie druhej funkcie predtým, ako sa dokončí spracovanie prvej funkcie.

Paho

v paho knižnici je definovaná trieda Client, ktorú môžeme použiť ako jej inštanciu — umožňuje nám pripojiť sa ku klientovi — MQTT brokeru pomocou metódy/funkcie connect() — pripojí klienta k brokeru, kde na vstupe uvedieme meno hosta/adresu, kde klient/broker beží.

  • subscribe(téma, qos) — umožní nám subscribnúť sa k danej téme

vytvorenie aliasu as v knižnici

  • mqtt = paho.Client() — unikátne ID klienta, názov ku ktorému sa pripájame

keď klient dostane potvrdenie o prijatí spojenia s brokerom — takzvanú connack správu

následne nastavíme loop_start(), ktorá sa volá hneď po pripojení a stará sa o volanie loopu() , pripojenia neustále na pozadí automaticky a zároveň nám umožní pracovať na hlavnom vlákne.

on_message() sa zavolá vo chvíli, keď bola správa doručená do topicu, ktorý odoberáme.

time.sleep() — pozastaví spracovanie v kódu na nami definovaný čas v sekundách. — čas kedy sa znovu pripája k brokeru, zabezpečí neustály beh funkcie.

Bez loopu callbacky nie sú volané, loop_start() sa stará o spracovanie callbackov.

--

--