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.
The Blink
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__': = Pin(2, Pin.OUT, Pin.PULL_UP) led print(">> running...") while True: led.on()1) sleep( led.off()1) sleep(
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 = "the-thing" client_id = "" ssid = "" password = "" broker_url = 1443 broker_port
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 = network.WLAN(network.STA_IF) sta_if if not sta_if.isconnected(): print("connecting to network...") True) sta_if.active(connect(ssid, password) sta_if.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:
= MQTTClient(client_id, broker_url, broker_port) client connect() client.
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émeiotlab/update
objaví nová správa. Upravíme teda predchádzajúce dva riadky nasledovne:= MQTTClient(client_id, broker_url, broker_port) client client.set_callback(on_message)connect() client."iotlab/update") client.subscribe(
Nakoniec treba vytvoriť callback funkciu
on_message()
. Jej základná podoba môže vyzerať takto:def on_message(topic, message): = message.decode("utf-8") url 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()1) sleep( led.off()1) sleep(
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úboruboot.py
novou verziou a následne aplikujeme aktualizáciu tým, že celé zariadenie reštartneme.def on_message(topic, message): = message.decode("utf-8") url print(">> New update available at {}".format(url)) # download update print(">> Downloading...") = urequests.get(url) response # save = open('boot.py', 'wb') f 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
= network.WLAN(network.STA_IF)
sta_if if not sta_if.isconnected():
print("connecting to network...")
True)
sta_if.active(connect(ssid, password)
sta_if.while not sta_if.isconnected():
pass
print("network config:", sta_if.ifconfig())
def on_message(topic, message):
= message.decode("utf-8")
url print(">> New update available at {}".format(url))
# download
print(">> Downloading...")
= urequests.get(url)
response
# save
= open("boot.py", "wb")
f
f.write(response.content)
f.close()
response.close()
# reset
machine.reset()
if __name__ == "__main__":
# connect to internet
do_connect(ssid, password)
# setup MQTT
= MQTTClient(client_id, broker_url, broker_port)
client
client.set_callback(on_message)connect()
client."iotlab/update")
client.subscribe(
# use builtin LED
= Pin(2, Pin.OUT, Pin.PULL_UP)
led
# superloop
print(">> running...")
while True:
client.check_msg()
# the blink
led.on()1)
sleep(
led.off()1) sleep(
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ý.
Poznámka
Overenie podpisu si môže vyžadovať dodatočnú hardvérovú alebo softvérovú podporu, čo môže limitovať možnosti a schopnosti niektorých hardvérových architektúr.
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:
- 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
- Existujúce riešenia poskytujú hotové riešenia, kde je možné aktualizáciu vykonávať takmer na jedno kliknutie.
- Príklady
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ý.
Podpora pre hodiny reálneho času sa nachádza priamo v jazyku MicroPython - v module
machine
sa priamo nachádza triedaRTC
. Takže ak chceme začať s modulom pracovať, tak importneme uvedenú triedu a vytvoríme objekt z triedyRTC
:>>> 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čomweekday
začína s pondelkom ako s hodnotou0
:>>> 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í.
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íkazutracking
:$ 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()
Upozornenie
Aby bola synchronizácia času úspešná, je potrebné, aby bolo zariadenie pripojené do internetu. V prípade, že to tak nie je, k synchronizácii nedôjde a bude len vyvolaná výnimka. Čas na zariadení zostane nezmenený!
Upozornenie
Metóda vráti, resp. nastaví čas na hodnotu GMT. Preto je potrebné prípadné rozdiely upraviť manuálne!
Čas následne overíme zavolaním metódy
.datetime()
nad inštanciou triedyRTC
:>>> 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
A more secure and reliable OTA update architecture for IoT devices
Real-time clock - A real-time clock (RTC) is a computer clock (most often in the form of an integrated circuit) that keeps track of the current time.
Micropython Real time clock (RTC) - Quick reference for the ESP32 Real time clock module
Powering the Intelligent Edge: HPE’s Strategy and Direction for IoT & Big Data
A more secure and reliable OTA update architecture for IoT devices
ESP32 NTP Client-Server: Get Date and Time (Arduino IDE) - Learn how to request date and time from an NTP Server using the ESP32 with Arduino IDE.