Čas a synchronizácia času
modul hodín reálneho času, synchronizácia pomocou protokolu NTP, štandard UTC, štandard ISO 8601
Práca s časom v jazyku MicroPython
Na prácu s časom a dátumom v jazyku MicroPython máme k
dispozícii modul time
. Tento modul je mikro
implementáciou modulu time
zo štandardnej knižnice jazyka
Python, ktorý má rovnakú funkcionalitu. Ak teda poznáte modul
time
zo štandardnej knižnice jazyka, práca s modulom
time
bude pre vás úplne prirodzená.
Modul time
poskytuje funkcie pre získanie aktuálneho
času a dútumu, pre meranie časových intervalov a taktiež funkcie pre
pozastavenie kódu.
Zistenie aktuálneho času
Aktuálny čas je možné zistiť zavolaním funkcie
localtime()
z modulu time
. Táto funkcia vráti
n-ticu pozostávajúcu z 8 prvkov, ktorých význam je nasledovný
(v poradí prvkov n-tice):
year
- rokmonth
- mesiac (1
-12
)mday
- deň v mesiaci (1
-31
)hour
- hodina (0
-23
)minute
- minúta (0
-59
)second
- sekunda (0
-59
)weekday
- deň v týždni (0
-6
, pričom hodnota0
pripadá na pondelok)yearday
- deň v roku (1
-366
)
Príklad použitia sa nachádza v nasledujúcom výpise:
>>> import time
>>> time.localtime()
2024, 10, 31, 11, 3, 25, 3, 305) (
Zistenie počiatku epochy
Moduly RTC reprezentujú čas ako počet sekúnd od počiatku epochy.
Tento modul teda obsahuje len počítadlo, ktoré každú sekundu zvýši o
1. Keď potom chceme zistiť, aký je aktuálny čas, dôjde k
prevedeniu tohto počtu sekúnd na zodpovedajúci dátum a čas, ktorý
dostaneme po zavolaní napr. funkcie localtime()
.
Za počiatok epochy považujeme dátum 1.1.1970, ktorý tiež poznáme pod názvom Unixový čas. Pokiaľ RTC modul počíta čas od tohto dátumu, hodnota 0 sekúnd zodpovedá presne dátumu 1.1.1970 o 00:00:00.
Ak chceme zisiť, aký počiatok epochy používa RTC modul vášho
zariadenia, môžeme tak urobiť zavolaním funkcie gmtime()
alebo localtime()
z modulu time
s parametrom
0
:
>>> import time
>>> time.gmtime(0)
1970, 1, 1, 0, 0, 0, 3, 1)
(>>> time.localtime(0)
1970, 1, 1, 0, 0, 0, 3, 1) (
Podľa výpisu je možné povedať, že 1. január 1970 pripadá na
štvrtok (deň v týždni má hodnotu 3
) a je to prvý deň v
roku. To si môžeme overiť napríklad príkazom cal
v
príkazovom riadku OS Linux:
$ cal 1 1 1970
január 1970
Po Ut St Št Pi So Ne
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Poznámka
Počiatok epochy môže byť v každom systéme alebo RTC module iný.
Zistenie počtu sekúnd od počiatku epochy
(slide) Ak chceme na mikrokontroléri získať aktuálny čas v počte sekúnd od počiatku epochy, zavoláme funkciu
time()
, ktorá sa nachádzame v moduleutime
:>>> import time >>> time.time() 669375512
Konverzia na štruktúru reprezentujúcu čas
Spätne konvertovať čas z počtu sekúnd od počiatku epochy na 8 prvkovú nticu je možné pomocou funkcie
gmtime()
:>>> import time >>> secs = time.time() >>> time.gmtime(secs) 2021, 3, 18, 9, 46, 33, 3, 77) (
Modul hodín reálneho času (RTC)
Aby mohol mikrokontrolér pracovať s aktuálnym časom, potrebuje modul hodín reálneho času (z angl. real time clock, skrátene RTC).
Niektoré mikrokontroléry, ako napr. ESP32 alebo RP2040, sú už RTC modulom vybavené. Nakoľko však nemajú k RTC modulom vyvedené aj osobitné napájanie, je pre mnohé riešenia aj tak potrebný externý RTC modul so samostatným napájaním.
Podpora pre hodiny reálneho času sa nachádza priamo v jazyku
MicroPython - v module machine
sa nachádza trieda
RTC
. Takže ak chceme začať s modulom pracovať, stačí
vytvoriť inštanciu tejto triedy:
>>> from machine import RTC
>>> rtc = RTC()
Zistenie aktuálneho dátumu a času
Pre získanie aktuálneho času stačí nad inštanciou RTC
zavolať metódu .datetime()
:
>>> rtc.datetime()
2021, 1, 1, 5, 0, 2, 32, 184) (
Výsledkom volania bude n-tica, ktorá obsahuje 8 prvkov. Ich význam je nasledovný (zľava doprava):
year
- rokmonth
- mesiacday
- deňweekday
- deň v týždni, pričom hodnota0
pripadá na pondelokhours
- hodinyminutes
- minútyseconds
- sekundysubseconds
- subsekundy, čiastkové sekundy
Poznámka
Hodnota poslednej položky entice subseconds
je závislá
od použitého hardvéru. Napr. na mikrokontroléri RP2040 bude
táto hodnota stále 0
. Ale na mikrokontroléri ESP32
bude mať konkrétnu hodnotu.
Poznámka
V dokumentácii je uvedené, že rozdiel medzi metódou
.gmtime()
a funkciou localtime()
je v tom, že
metóda .gmtime()
vracia hodnoty v UTC, pričom
funkcia localtime()
vracia hodnoty lokálneho času. Keďže
ale na mikrokontroléroch nie je možné nastaviť časovú zónu, budú tieto
hodnoty rovnaké.
Upozornenie
Niektoré nástroje nastavia aktuálny čas na mikrokontroléri automaticky bez toho, aby ste o tom vedeli. Jedná sa napr. o editor Thonny alebo o konzolového klienta rshell. Takže ak budete rozmýšľať nad tým, že ako je možné, že mikrokontrolér má aktuálny čas aj napriek tomu, že nie je napájaný a nie je pripojený do internetu, tak je za túto skutočnosť zodpovedný nástroj, ktorý používate na komunikáciu s mikrokontrolérom.
Manuálne nastavenie dátumu a času
Ak potrebujeme nastaviť aktuálny čas ručne, môžeme na to použiť opäť
metódu .datetime()
nad inštanciou triedy RTC
.
Jej parametrom bude n-tica, ktorá obsahuje aktuálny dátum a čas v tvare
(year, month, day, weekday, hours, minutes, seconds, subseconds)
:
>>> # aktuálny dátum a čas pred nastavením
>>> rtc.datetime()
2021, 1, 1, 5, 0, 2, 32, 184)
(>>> # nastavenie aktuálneho dátumu a času
>>> rtc.datetime((2024, 3, 13, 4, 22, 0, 0, 0))
>>> rtc.datetime()
2024, 3, 13, 4, 22, 0, 3, 964) (
Udržanie času po reštartovaní
Ak mikrokontrolér reštartnete tzv. mäkkým reštartom (z angl. soft reset), informácia o aktuálnom čase sa nestratí, pretože si ho bude modul hodín reálneho času pamätať:
>>> machine.reset()
...>>> rtc = machine.RTC()
>>> rtc.datetime()
2020, 3, 13, 4, 22, 2, 36, 700) (
Pokiaľ nemá mikrokontrolér externý modul hodín reálneho času a odpojíme ho od zdroja elektrického napätia (napr. odpojením USB kábla), dôjde k vynulovaniu hodín reálneho času:
>>> rtc = machine.RTC()
>>> rtc.datetime()
2021, 1, 1, 5, 0, 0, 13, 980) (
Synchronizácia času pomocou protokolu NTP
Pomocou protokolu NTP je možné synchronizovať čas zariadenia
prostredníctvom internetu. Pre zabezpečenie synchronizácie stačí, ak je
zariadenie pripojené do internetu a má modul ntptime
.
Pri práci s modulom ntptime
nás budú zaujímať dve
veci:
premenná
host
- Adresa NTP servera, voči ktorému sa bude zariadenie synchronizovať. Predvolenou hodnotou jepool.ntp.org
, ktorý reprezentuje virtuálny klaster časových serverov poskytujúcich čas miliónom klientov. Pokiaľ je zariadenie pripojené priamo k internetu, nie je nutné túto hodnotu meniť.funkcia
settime()
- Po zavolaní tejto funkcie dôjde k zosynchronizovaniu času. Nastavený čas bude v UTC. V prípade, že zariadenie nebude pripojené k internetu v dobe synchronizácie, dôjde k vyvolaniu výnimkyOSError
.
Príklad použitia modulu sa nachádza v nasledujúcom výpise:
>>> # pred synchronizáciou...
>>> import time
>>> time.localtime()
2021, 1, 1, 1, 26, 0, 4, 1)
(>>> # synchronizácia
>>> import ntptime
>>> ntptime.settime()
>>> time.localtime()
2024, 10, 31, 17, 23, 19, 3, 305) (
Práca s externým modulom RTC
V prípade, že používate externý RTC modul, na prácu s ním potrebujete potrebnú knižnicu. Ak hľadáte príslušný modul pre váš RTC modul, dobrý odrazový mostík môže zoznam Awesome MicroPython a v ňom časť venovaná RTC modulom.
Formátovanie času a dátumu
Na formátovanie času sa používa v rozličných jazykoch funkcia
strftime()
. Pomocou tejto funkcie je možné naformátovať
dátum a čas ľubovoľne. Táto funkcia sa však v štandardnom firmvéri
MicroPython-u nenachádza. Je ju však možné doinštalovať
osobitne z projektu micropython-lib.
Pre vlastné projekty si je teda potrebné vytvoriť vlastný formátovač času. Príkladom môže byť funkcia v nasledujúcom výpise, ktorá vráti čas v štandarde ISO 8601.
def to_iso8601(ts: int = None) -> str:
= gmtime(ts)
dt return f'{dt[0]:04}-{dt[1]:02}-{dt[2]:02}T{dt[3]:02}:{dt[4]:02}:{dt[5]:02}Z'
Ďalšie zdroje
- MicroPython:
time
– time related functions - dokumentácia modulutime
- MicroPython: class
RTC - real time clock - dokumentácia triedy
RTC
- MicroPython Lib: ntptime
- GitHub repozitár s implementáciou modulu
ntptime