Synchronizácia času
prečo je čas dôležitý v IoT riešeniach, hodiny reálneho času, problém synchronizácie času, Unixový čas, počiatok epochy, NTP protokol, podpora NTP a hodiny reálneho času v mikrokontroléri ESP32
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ý. Aj napriek tomu však niektoré riešenia využívajúce tento mikrokontrolér majú osobitný RTC modul hlavne kvôli neustálemu externému napájaniu.
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
(slide) 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.
utime
- Time
Related Functions
- (slide)
Time Epoch
(slide)
Získať počet sekúnd od počiatku epochy je možné pomocou metódy
.time()
:>>> import utime >>> utime.time() 669375512
Spätne konvertovať čas z počtu sekúnd od počiatku epochy na 8 prvkovú nticu je možné pomocou metód
.gmtime()
a.localtime()
:>>> import utime >>> secs = utime.time() >>> utime.gmtime(secs) 2021, 3, 18, 9, 46, 33, 3, 77) (