OTA Updates

o aktualizácii zariadení na diaľku a synchronizácii času

Záznam z prednášky

Illustration

  • (slide) Začať tému voľnou diskusiou s niekoľkými otázkami:
    • Koľkí máte mobilný telefón? Alebo presnejšie - koľkí máte chytrý telefón?
    • Koľkokrát ste už dostali upozornenie o tom, že sa váš mobilný telefón chce aktualizovať na najnovšiu verziu operačného systému?
    • Prečo je dobré aktualizovať niečo, čo funguje a je už overené?
  • Vieme, že softvér a rovnako tak aj operačný systém časom zastaráva. Síce nehrdzavie, ale prestáva konkurovať alebo postačovať svojimi vlastnosťami. V horšom prípade sa v ňom začnú objavovať bezpečnostné problémy.
  • Pomocou softvérových aktualizácií dokážeme distribuovať na koncové zariadenia nové vlastnosti ako aj opravovať zistené chyby. Práve vo svete IoT, kde môže byť do internetu pripojené obrovské množstvo zariadení, je otázka aktualizácie zariadení doslova kľúčová.
  • Dnes sa teda pozrieme na to, akú úlohu zohrávajú vo svete IoT aktualizácie a čo všetko s aktualizáciami súvisí. A keďže IoT zariadenia sú najčastejšie pripájané do internetu bezdrôtovo, budeme sa zaoberať problematikou softvérovej bezdrôtovej, tzv. OTA aktualizácie.

What is OTA?

  • (slide) Gartner definuje “Over-the-air” (OTA) ako

    the ability to download applications, services and configurations through a mobile or cellular network

  • Obecne sa jedná o aktualizáciu odoslanú “vzduchom” (over the air), resp. o mechanizmus schopný vykonať diaľkovú bezdrôtovú aktualizáciu hardvéru pripojeného do internetu novou verziou softvéru, nastavení alebo firmvéru.

  • V rozsiahlych IoT riešeniach nie je reálne vykonávať aktualizácie “starým” káblovým spôsobom, ktorý si vyžaduje pripojiť sa fyzicky s počítačom ku každému jednému zariadeniu. Tento spôsob aktualizácie môže neúmerne zvýšiť cenu celého riešenia a so zvyšujúcim sa počtom ako zariadení, tak aj aktualizácií môže odrádzať od ich pravidelného aktualizovania.

  • Schopnosť IoT zariadení dostávať aktualizácie je kritická pri odstraňovaní problémov so zraniteľnosťami.

  • Na druhej strane zle navrhnutý mechanizmus aktualizácií ponúka priestor pre vznik rozličných bezpečnostných problémov. Tým je možné ohroziť koncových klientov, ale rovnako dokáže utrpieť aj reputácia dodávateľa. Pri miliónoch zariadení totiž aj malé percento neúspešných aktualizácií predstavuje tisíce postihnutých zariadení.

  • OTA mechanizmus je teda možné považovať za jeden z kľúčových komponentov pre akúkoľvek IoT architektúru.

Benefits of OTA Updates

  • (slide) OTA aktualizácie so sebo uprinášajú množstvo výhod. Medzi tie hlavné patria:
    • zlepšovanie vlastností zariadení - A to či už pridávaním nových alebo rozširovaním existujúcich vlastností. A to aj v prípade, že sú už zariadenia nasadené a používané u koncových zákazníkov.
    • zvyšovanie bezpečnosti - Pomocou bezdrôtových aktualizácií je možné veľmi rýchlo zareagovať aj na prípadné objavené bezpečnostné chyby vydaním rýchlej opravy a jej následnej distribúcie na koncové zariadenia.
    • zníženie nákladov - Vo svete, kde je potrebné aktualizovať obrovské množstvo zariadení, nie je reálne, aby bol použitý konvenčný spôsob pomocou laptopu a USB kábla. Robiť výjazd ku každému kontajneru osobitne by celú službu dokázalo neúmerne predražiť.

Simle OTA Update Example

  • (slide) Ak by sme programovali v jazyku C++ v prostredí Arduino IDE, tak si vieme vybrať už hotové riešenie. My sa však pozrieme pod kapotu a jednoduché riešenie na mikrokontroléri ESP32 v jazyku MicroPython si vytvoríme sami.
  • Myšlienka bude veľmi jednoduchá: V rámci aktualizácie budeme aktualizovať len súbor boot.py, ktorý sa spustí ako prvý pri štarte mikrokontroléra ESP32. Na notifikáciu o nových verziách využijeme komunikačný protokol MQTT. Pomocou neho v prípade distribúcie novej aktualizácie bude distribuovaná priamo linka na stiahnutie novej aktualizácie.
  • Aby bolo riešenie zaujímavejšie, v mikrokontroléri bude celý čas bežať program Blink, ktorý budeme postupne upravovať a refaktorovať. Ten teda bude každú sekundu blikať a okrem toho bude prihlásený do potrebného kanála, kde sa budú šíriť informácie o nových aktualizáciách.

  • Jednoduchá podoba môže vyzerať nasledovne:

    from time import sleep
    from machine import Pin
    
    if __name__ == '__main__':
        led = Pin(2, Pin.OUT, Pin.PULL_UP)
        print(">> running...")
    
        while True:
            led.on()
            sleep(1)
            led.off()
            sleep(1)

Connecting to Network and MQTT Broker

  • Konfiguráciu budeme udržiavať v samostatnom súbore, ktorý sa bude volať config.py. Jeho podoba bude nasledovná:

    # settings
    client_id = "the-thing"
    ssid = ""
    password = ""
    broker_url = ""
    broker_port = 1443
  • Konfiguráciu následne môžeme importovať do nášho programu jednoducho pomocou:

    from config import *
  • Na pripojenie do siete využijeme skúsenosti z minulého týždňa - použijeme ukážkovú funkciu do_connect() z dokumentácie jazyka MicroPython:

    def do_connect(ssid, password):
        import network
    
        sta_if = network.WLAN(network.STA_IF)
        if not sta_if.isconnected():
            print("connecting to network...")
            sta_if.active(True)
            sta_if.connect(ssid, password)
            while not sta_if.isconnected():
                pass
        print("network config:", sta_if.ifconfig())
  • Do siete sa následne pripojíme volaním tejto funkcie s parametrami z konfigurácie:

    do_connect(ssid, password)
  • Po úspešnom pripojení do siete sa môžeme pripojiť k MQTT brokeru pomocou série nasledovných riadkov:

    client = MQTTClient(client_id, broker_url, broker_port)
    client.connect()
  • Aby všetko fungovalo ako má, je potrebné sa prihlásiť do príslušnej témy. V našom prípade to bude téma iotlab/update. A rovnako tak potrebujeme nastaviť callback funkciu, ktorá bude zavolaná, keď sa v téme iotlab/update objaví nová správa. Upravíme teda predchádzajúce dva riadky nasledovne:

    client = MQTTClient(client_id, broker_url, broker_port)
    client.set_callback(on_message)
    client.connect()
    client.subscribe("iotlab/update")
  • Nakoniec treba vytvoriť callback funkciu on_message(). Jej základná podoba môže vyzerať takto:

    def on_message(topic, message):
        url = message.decode("utf-8")
        print(">> New update available at {}".format(url))
  • Aby všetko fungovalo ako má, v nekonečnej slučke, kde sa realizuje blikanie diódy, je potrebné pri každej iterácii zavolať funkciu client.check_msg(). Ak by sme ju totiž nevolali, neboli by sme notifikovaní o nových aktualizáciách. Náš “superloop” bude teda vyzerať nasledovne:

    while True:
        client.check_msg()
    
        led.on()
        sleep(1)
        led.off()
        sleep(1)
  • Teraz môžeme overiť funkcionalitu tým, že nejakú správu do kanála s informáciami o aktualizácii pošleme. Momentálne nie je podstatný obsah, ale to, či naše zariadenie bude správne notifikované. Overiť správanie môžeme rovno z príkazového riadku pomocou nástroja mosquitto_pub:

    $ mosquitto_pub -h BROKER -p PORT -t "iotlab/update" -m "New version available for download."

Downloading New Versions

  • To najpodstatnejšie sa však udeje vo funkcie on_message(). Tu zabezpečíme stiahnutie novej aktualizácie, prepísanie pôvodného súboru boot.py novou verziou a následne aplikujeme aktualizáciu tým, že celé zariadenie reštartneme.

    def on_message(topic, message):
        url = message.decode("utf-8")
        print(">> New update available at {}".format(url))
    
        # download update
        print(">> Downloading...")
        response = urequests.get(url)
    
        # save
        f = open('boot.py', 'wb')
        f.write(response.content)
        f.close()
        response.close()
    
        # reset
        machine.reset()

Testing

  • Následne už zostáva len riešenie otestovať. Pre potreby prednášky som pripravil niekoľko verzií, ktoré sa nachádzajú v priečinku resources/ na stránke s materiálmi.

  • Na samotné testovanie opäť použijeme nástroj mosquitto_pub:

    $ mosquitto_pub -h BROKER -p PORT -t "iotlab/update" \ 
      -m "https://kurzy.kpi.fei.tuke.sk/iot1/2020/resources/boot.hacked.py"
  • Pokiaľ sme postupovali správne, po reštarte uvidíte správu s aktuálnou verziou a samozrejme premenná VERSION bude po celý čas dostupná.

The Solution

from machine import Pin
import machine
from umqtt.robust import MQTTClient
from time import sleep
import urequests
from config import *


def do_connect(ssid, password):
    import network

    sta_if = network.WLAN(network.STA_IF)
    if not sta_if.isconnected():
        print("connecting to network...")
        sta_if.active(True)
        sta_if.connect(ssid, password)
        while not sta_if.isconnected():
            pass
    print("network config:", sta_if.ifconfig())


def on_message(topic, message):
    url = message.decode("utf-8")
    print(">> New update available at {}".format(url))

    # download
    print(">> Downloading...")
    response = urequests.get(url)

    # save
    f = open("boot.py", "wb")
    f.write(response.content)
    f.close()
    response.close()

    # reset
    machine.reset()


if __name__ == "__main__":
    # connect to internet
    do_connect(ssid, password)

    # setup MQTT
    client = MQTTClient(client_id, broker_url, broker_port)
    client.set_callback(on_message)
    client.connect()
    client.subscribe("iotlab/update")

    # use builtin LED
    led = Pin(2, Pin.OUT, Pin.PULL_UP)

    # superloop
    print(">> running...")
    while True:
        client.check_msg()

        # the blink
        led.on()
        sleep(1)
        led.off()
        sleep(1)

Important OTA Design Considerations

  • Vytvorené riešenie bolo veľmi jednoduché. Síce funguje, ale za veľmi špecifických okolností a určite by ste ho nechceli nasadiť do reálnej prevádzky.
  • (slide) V čom všetkom vidíte problém alebo potenciálny problém tohto riešenia?
  • (slide) O systéme aktualizácií by malo obecne platiť, že by mal byť rýchly, bezpečný a jednoduchý na používanie.
  • (slide) Pozrime sa teraz na niekoľko odporúčaní, na ktoré je dobré nezabudnúť v prípade návrhu mechanizmu bezdrôtových aktualizácií. Ich zoznam určite nie je kompletný a ich poradie nezohľadňuje ich dôležitosť.

Incremental Roll-Out of OTA Updates

  • (slide) Nezabúdajme na to, že v IoT riešení môže byť naraz zapojených obrovské množstvo zariadení. Ak všetkým naraz oznámime, že je k dispozícii nová aktualizácia, začnú všetci naraz aktualizáciu sťahovať. To môže mať neželané následky v podobe preťaženia serverov poskytujúcich aktualizáciu na stiahnutie. Ich zahltenie požiadavkami môže viesť až k znefunkčneniu služby (DDoS “útok”).
  • Schopnosť systému umožniť aktualizovať len vybranú skupinu zariadení, umožní tomuto problému predísť. Rovnako tak umožní znížiť riziko šírenia chybnej aktualizácie. Ak sa totiž začne distribuovať chybná aktualizácia, tak skupina poškodených zariadení zostane relatívne malá.

Recovery of Versions

  • (slide) Aktualizácia nemusí byť vždy úspešná. O neúspešných aktualizáciách (ne)pravidelne čítame napr. pri nových vydaniach OS Windows. Nemusí sa to teda stať len vám ;) V prípade zle vykonanej aktualizácie v prostredí IoT môžu byť však výsledky oveľa horšie, ako napr.
  • Je niekoľko miest, kde môže vzniknúť problém s chybnou aktualizáciou:
    • na serveri poskytujúcom aktualizáciu - napr. vydavateľ môže uvoľniť chybnú aktualizáciu.
    • počas prenosu/sťahovania - napr. výpadok sieťového pripojenia.
    • v procese aktualizácie - napr. výpadok elektrickej energie, alebo prerušenie aktualizácie aj nedočkavým používateľom.
  • Zlá aktualizácia môže napáchať veľké škody a v najhoršom prípade môže viesť až k znefunkčneniu zariadenia (brick). Preto je dobré mechanizmus navrhnúť tak, aby sa v ideálnom prípade zariadenie dokázalo samo zotaviť z neúspešnej aktualizácie, napr. obnovením predchádzajúcej verzie systému alebo prepísaním zlej aktualizácie. Tým sa vyhneme podobným situáciám, aké boli predstavené vyššie.

Code Compatibility Verification

  • (slide) Pokiaľ vaše riešenie zahŕňa použitie rozličných typov zariadení (napr. RPi, ESP32, Arduino, …) alebo aspoň rozličných verzií zariadení (napr. RPi 1, 2, 3, 4), budete musieť distribuovať rozdielne aktualizácie pre každý typ použitého zriadenia. Musíte si teda dať pozor na to, aby bola aplikovaná správa aktualizácia na správne zariadenie.
  • Odporúča sa, aby ste pred aplikovaním prebranej aktualizácie overili, že sa jedná naozaj o aktualizáciu pre dané zariadenie. A to ako pri sťahovaní (stiahnutie správneho obrazu pre dané zariadenie), tak aj pred spustením aktualizácie zariadenia (overenie, či stiahnutý súbor má naozaj správnu verziu).
  • Aplikovaním nesprávnej aktualizácie na zariadenie môže mať fatálne následky, z ktorých bude náročné sa zotaviť. V najhoršom prípade môže dôjsť k znefunkčneniu zariadenia.

Secure Communication

  • (slide) Pri aktualizácii je veľmi dôležitá aj otázka použitia bezpečného komunikačného kanála/linky, prostredníctvom ktorého bude aktualizácia na zariadenie sťahovaná.
  • To však nestačí. Zariadenia, ktoré budú aktualizácie preberať, musia zdroju, z ktorého bude aktualizácia preberaná, dôverovať. Zdroj aktualizácie teda musí byť overený a dôveryhodný. Tým sa zabráni prípadnej modifikácii aktualizácie či už na samotnom úložisku alebo počas jeho preberania.

Partial Updates

  • (slide) Súbory s aktualizáciou môžu byť obrovské aj napriek tomu, že sa samotná aktualizácia môže týkať len jednej konkrétnej malej časti systému (napr. zmena jedného riadku kódu). Miesto sťahovania celého obrazu systému je teda výhodnejšie, ak sa preberie len konkrétna aktualizovaná časť systému.
  • Tento mechanizmus sa nazýva čiastočná alebo aj inkrementálna aktualizácia (z angl. partial update). Týmto spôsobom dokážeme znížiť množstvo preberaných údajov ako aj čas spracovania aktualizácie. Vo výsledku sa jedná o zrýchlenie celého procesu aktualizácie.

Authenticating the OTA Update Image

  • (slide) Ak sa zariadenie aj pripojí k dôveryhodnému serveru pre stiahnutie aktualizácie, samotný súbor s aktualizáciou nakoniec nemusí byť správny. Súbor sa môže poškodiť pri prenose alebo prípadný útočník môže podvrhnúť iný obraz (Man-in-the-middle). Preto je potrebné, aby IoT zariadenie dokázalo overiť, že sa jedná o súbor vydaný organizáciou.

  • Overenie pravosti si vyžaduje podpísanie obrazu na strane poskytovateľa služby pomocou súkromného kľúča a jeho overenie na zariadení pomocou verejného kľúča. Rovnako tak je dobré podpísať aj metaúdaje obrazu napr. informáciu o verzii obrazu. Tým pádom zariadenie dokáže overiť ako obraz tak aj jeho verziu a tým minimalizovať možnosť jeho podvrhnutia treťou stranou alebo podvrhnutia síce podpísaného obrazu, ale s predchádzajúcou verziou, ktorá obsahuje známu neopravenú bezpečnostnú chybu.

  • Zariadenie by taktiež malo odmietnuť bootovať obraz, ktorý nie je podpísaný.

Security from Physical Attacks

  • (slide) Okrem zabezpečenia prenosu aktualizácie na zariadenie je rovnako dôležité aj fyzické zabezpečenie zariadenia. To môže byť dôležité so zvyšujúcou sa popularitou zariadenia, vďaka čomu môže byť oň väčší záujem aj u útočníkov.
  • IoT zariadenie je potrebné v prvom rade zabezpečiť pred možnosťou čítať útočníkom údaje priamo z pamäte. Príkladom môžu byť JTAG porty, ktoré je dôležité vypnúť v produkčnom prostredí.
  • Rovnako je potrebné, aby zariadenie uchovávalo citlivé údaje, ako prihlasovacie údaje, certifikáty a pod. v zašifrovanej podobe.

Minimizing Intrusion

  • (slide) Prebiehajúca aktualizácia samozrejme nesmie narušiť bežnú prevádzku zariadenia. Preto je žiaduce vykonať aktualizáciu na pozadí a počas nej zabezpečiť očakávanú funkcionalitu.
  • Toto nie je problém v prípade vzdialených senzorov, ktoré napr. snímajú hodnoty len raz za niekoľko minút. Tu je možné si dovoliť výpadok potrebný na aktualizovanie zariadenia.
  • Aktualizácia sa však nesmie spustiť uprostred vykonávania činnosti zariadenia, ako napr. uprostred varenia kávy kávovarom. V istých situáciách môže ísť aj o život človeka, napr. inzulínová pumpa alebo bezpečnostný systém, ktorý je počas prebiehajúcej aktualizácie vyradený z činnosti.

OTA Architectures

  • (slide) Neexistuje len jediný prístup k riešeniu problematiky výstavby architektúry pre zabezpečenie OTA. To je podmienené vlastnosťami a individualitou samotných projektov. Vzhľadom na architektúru IoT, ktorú sme si priblížili už skôr (viď obrázok), môžeme však uvažovať niekoľko prístupov: IoT Architecture
    • Thing-to-Cloud OTA Updates - Veci pripojené do internetu preberajú aktualizácie z jedného vzdialeného servera. Keďže sa jedná len o jeden server, správa takéhoto riešenia je jednoduchá. Na druhej strane môže viesť k problému zahltenia, keď všetky veci sa v najhoršom prípade pripájajú k tomuto serveru naraz a naraz aj preberajú aktualizácie.
    • Thing-to-Gateway-to-Cloud OTA Updates - V tomto prípade do architektúry vstupuje prvok navyše, ktorým je gateway (brána). Toto zariadenie predstavuje bránu medzi vecami nainštalovanými napríklad v inteligentnej domácnosti a internetom samotným. Aktualizáciu v tomto scenári preberá gateway zariadenie, z ktorého ju následne sťahujú samotné veci. Tým je možné ušetriť ako čas tak aj množstvo údajov preberaných z centrálneho servera. Preberané aktualizácie sa samozrejme môžu týkať aj aktualizácií gateway zariadení samotných.
    • Thing-to-Edge-to-Cloud OTA Updates - Medzi veci a aktualizačné servery v tomto prípade vstupuje vrstva Edge Computing-u. Princíp je veľmi podobný predchádzajúcej architektúre. Aktualizácie sú preberané zariadeniami vo vrstve edge, odkiaľ sú sťahované samotnými vecami. Rozdiel je v tom, že tieto zariadenia sú umiestnené mimo napr. domácej siete (inteligentnej domácnosti) a vyžaduje sa, aby veci boli vybavené pripojením do internetu. Záťaž na servery s aktualizáciami sa výrazne zníži, pretože aktualizačných serverov v edge vrstve bude menej, ako gateway zariadení v predchádzajúcej architektúre. Zvýši sa však počet požiadaviek na zariadenia poskytujúce aktualizácie v edge vrstve.
    • Thing-to-Gateway-to-Edge-to-Cloud OTA Updates - V tejto architektúre je záťaž rozložená rovnomerne na všetkých vrstvách. Aktualizácie sú distribuované z cloud-u na zariadenia vo vrstve edge. Odtiaľ si ich budú následne sťahovať gateway zariadenia, ktoré ich budú distribuovať na koncové zariadenia.

Existing Solutions

Time Synchronization

  • (slide) Koľkí z vás máte hodinky? Ideálne - koľkí z vás nemáte inteligentné hodinky, proste len klasické “digitálky” alebo ručičkové hodinky? Tak mi teraz povedzte, koľko je hodín.
  • No a máme tu problém - toľkí z vás majú hodinky a aj tak mi neviete povedať, koľko je hodín. Pretože každému ukazujú čas s nejakou odchýlkou, ktorá sa v niektorých prípadoch dá rátať na sekundy a v niektorých na minúty. A potom sú niektorí, ktorí majú schválne čas posunutý o pár minút dopredu, aby všetko stihli. To všetko prispieva k tomu, že nevieme presne určiť aktuálny čas.
  • Poznať správny čas je veľmi dôležité. Hlavne ak uchovávate, resp. logujete údaje spolu s ich časovou značkou (časozberné údaje). Preto je veľmi dôležité, aby komunikujúce zariadenia poznali nie len správny čas, ale mali všetky aj rovnaký čas nastavený. Nemôže nastať situácia, keď čas odoslania v prijatej správe je z pohľadu prijímajúceho klienta v budúcnosti.
  • Pozrieme sa teda na to, ako si aktuálny čas zapamätať a samozrejme - ako zabezpečiť synchronizáciu času medzi zariadeniami v sieti.

Real Time Clock

  • (slide) Real-Time Clock (RTC) alebo hodiny reálneho času sú počítačové hodiny, ktoré sledujú aktuálny čas. Najčastejšie sú realizované vo forme samostatného integrovaného obvodu.
  • (slide) Takýto obvod sa nachádza aj na základných doskách počítačov. Spoznáte ho napr. aj podľa toho, že v jeho blízkosti sa nachádza gombíková baterka, ktorá ho zásobuje energiou aj v prípade, ak je počítač vypnutý. RTC sleduje čas stále, ale iba ak má elektrickú energiu.
  • (slide) V prípade, že chcete funkcionalitu hodín reálneho času použiť aj s niektorým mikrokontrolérom, musíte si overiť, či ho ten mikrokontrolér má alebo nie. Ak nie, môžete k nemu taký modul pripojiť. Príkladom takéhoto modulu môže byť napr. modul DS1302 alebo DS3231. Tieto moduly sa líšia prevedením, vlastnosťami ako aj spôsobom komunikácie s mikrokontrolérom. Súčasťou týchto modulov je však samozrejme aj miesto pre batériu, aby modul nezabudol aktuálny čas.

RTC and ESP32

  • (slide) V prípade mikrokontroléra ESP32 nie je potrebné používať osobitný externý modul, pretože mikrokontrolér je takýmto modulom už vybavený. ESP32 Block Diagram

  • Podpora pre hodiny reálneho času sa nachádza priamo v jazyku MicroPython - v module machine sa priamo nachádza trieda RTC. Takže ak chceme začať s modulom pracovať, tak importneme uvedenú triedu a vytvoríme objekt z triedy RTC:

    >>> from machine import RTC
    >>> rtc = RTC()
  • Aktuálny dátum a čas získame volaním metódy .datetime():

    >>> rtc.datetime()
    (2000, 1, 1, 5, 0, 2, 32, 184)
  • Nastaviť aktuálny čas je možné manuálne zavolaním rovnakej metódy s parametrom n-tice obsahujúcej aktuálny dátum a čas v tvare (year, month, day, weekday, hours, minutes, seconds, subseconds), pričom weekday začína s pondelkom ako s hodnotou 0:

    >>> rtc.datetime((2020, 3, 13, 4, 22, 0, 0, 0))
    >>> rtc.datetime()
    (2020, 3, 13, 4, 22, 0, 3, 964)
  • Ak náhodou mikrokontrolér reštartnete, informácia o aktuálnom čase sa nestratí, pretože si ho modul hodín reálneho času bude pamätať:

    >>> machine.reset()
    ...
    >>> rtc = machine.RTC()
    >>> rtc.datetime()
    (2020, 3, 13, 4, 22, 2, 36, 700)
  • Ak však mikrokontrolér odpojíme od zdroja elektrickej energie (napr. vypojíme USB kábel), tak modul hodín reálneho času stratí informáciu o aktuálnom čase a resetne sa do pôvodných nastavení:

    >>> rtc = machine.RTC()
    >>> rtc.datetime()
    (2000, 1, 1, 5, 0, 0, 13, 980)

Network Time Protocol

  • Problém však je, že hodiny treba nastaviť manuálne zakaždým, keď dôjde k výmene batérie. To však nie je veľmi praktické, nakoľko je potrebné vykonať ručný zásah do kódu, kde nastavíme čas a dátum podľa aktuálnych hodnôt.

  • (slide) Pokiaľ je však zariadenie pripojené do internetu, je možné za týmto účelom použiť Network Time Protocol (NTP). Network Time Protocol je sieťový protokol pre synchronizáciu času v zariadeniach pripojených do siete. Protokol NTP bol vytvorený už pred rokom 1985, vďaka čomu je jedným z najstarších v súčasnosti stále používaných protokolov.

  • (slide) Aby protokol NTP pracoval, niekto musí poznať správny čas. Ak by však všetci klienti pristupovali len k jednému zdroju presného času, odozva by trvala veľmi dlho. Miesto toho NTP protokol používa hierarchickú sieť zariadení.

    NTP Servers and Clients
  • Každá vrstva v tejto stieti sa nazýva stratum. Na najvyššej vrstve, tzv. stratum 0 sa nachádza zdroj reálneho času, čo môžu byť napr. atómové hodiny, GPS a iné. Tieto hodiny sú pripojené k zariadeniam na vrstve stratum 1 priamo, napr. cez rozhranie USB. Zariadenia na vrstve stratum 0 sa tiež označujú ako referenčné hodiny (z angl. reference clocks), resp. referenčný čas.

  • Čas sa dá následne získavať až z vrstvy stratum 1. Zariadenia na tejto vrstve sú tiež označované ako primary time servers. Z pohľadu získania času budú mať tieto zariadenia najnižšiu odchýlku oproti reálnemu času.

  • Zisťovať čas zo zariadení na vrstve stratum 1 však nie je odporúčaný spôsob. Opäť by hrozilo, že zariadenie bude zahltené požiadavkami a nebude ich stíhať všetky obsluhovať. Preto je odporúčané čas na klientskych zariadeniach získavať až z vrstiev stratum 2 a vyšších.

  • Tu je však jeden problém - čím je úroveň vrstvy stratum vyššia, tým väčšia bude aj časová odchýlka od zdroja reálneho času. Aby bola táto odchýlka čo najmenšia, dokážu sa jednotlivé zariadenia synchronizovať na základe údajov z viacerých zariadení. A to nie len vertikálne (smerom k nižším vrstvám stratum), ale aj horizontálne.

  • (slide) Podpora protokolu NTP sa nachádza aj v bežných operačných systémoch. V linuxových máte možnosť si dokonca vybrať aj z viacerých démonov, ktorí sa o synchronizáciu času pomocou starajú.

  • Aktuálne sa vo veľkých distribúciách používa chrony. Klient z príkazového riadku sa volá chronyc a vypísať aktuálne informácie o hodinách môžete pomocou príkazu tracking:

    $ chronyc tracking 
    Reference ID    : 2E1D02AB (ns0.govps.gr)
    Stratum         : 3
    Ref time (UTC)  : Tue Mar 24 19:05:29 2020
    System time     : 0.001544221 seconds fast of NTP time
    Last offset     : +0.000488482 seconds
    RMS offset      : 0.004124337 seconds
    Frequency       : 9.526 ppm fast
    Residual freq   : +0.001 ppm
    Skew            : 0.168 ppm
    Root delay      : 0.034044463 seconds
    Root dispersion : 0.021502025 seconds
    Update interval : 1041.6 seconds
    Leap status     : Normal
  • Problém však môže nastať v momente konfigurácie služby, pretože je potrebné zadať adresu zariadenia, voči ktorému sa chcete synchronizovať. Za tým účelom existuje stránka www.ntppool.org/, kde nájdete konfiguráciu v podobe zoznamu adries zariadení, voči ktorým sa bude to vaše synchronizovať. Obecne stačí zadať adresu pool.ntp.org, ale rovnako je možné si vybrať zoznam serverov pre konkrétnu krajinu.

NTP Support in Micropython

  • (slide) Micropython obsahuje modul ntptime, ktorý zabezpečuje podporu protokolu NTP. Pre jeho použitie je potrebné ho najprv importovať:

    >>> import ntptime
  • Tento modul obsahuje niekoľko metód a vlastností. Ak si napr. necháme zobraziť obsah premennej .host, uvidíme adresu zariadenia, voči ktorému sa bude náš mikrokontrolér synchronizovať:

    >>> ntptime.host
    'pool.ntp.org'
  • Samotnú synchronizáciu času zabezpečíme volaním metódy .settime():

    >>> ntptime.settime()
  • Čas následne overíme zavolaním metódy .datetime() nad inštanciou triedy RTC:

    >>> rtc = machine.RTC()
    >>> rtc.datetime()
    (2020, 3, 14, 5, 13, 4, 11, 807)

Time Synchronization

  • Podobne ako v prípade bežných hodiniek, aj tu dochádza k rozsynchronizovaniu času. Ak teda čas zosynchronizujete pri štarte zariadenia a jeho následnom pripojení do siete, nemusí to znamenať, že rovnakú odchýlku bude mať aj o týždeň po nepretržitej prevádzke. Je preto dobré plánovať ďalšiu synchronizáciu.
  • Linuxové systémy tento problém riešia tak, že k časovej synchronizácii dôjde zakaždým, keď dochádza k pripojeniu do internetu. To je dôležité napr. pri mobilných zariadeniach, ako sú napr. laptopy. Podobne teda môžu fungovať aj IoT zariadenia, keďže aj tie nepotrebujú sieťovú konektivitu neustále, ale len v (ne)pravidelných intervaloch. Samotná synchronizácia netrvá dlho, čo čas potrebný pre zotrvanie v sieti predĺži max. o niekoľko sekúnd.

Conclusion

Aditional Resources