9.16. Čas a NTP

Čerstvě zapnutá kamera netuší, kolik je hodin. Vestavěné hodiny začínají v nějakém libovolném okamžiku (1970-01-01 na většině desek) a od něj počítají dopředu, dokud jim něco neřekne jinak. NTP – Network Time Protocol – je způsob, jak se kamera zeptá sítě na skutečný reálný čas a podle odpovědi si nastaví vlastní hodiny.

9.16.1. Proč kamera potřebuje znát čas

U mnoha skriptů na hodinách kamery nezáleží – smyčce snímající snímky je jedno, jaký je den. U několika běžných věcí to ovšem záleží hodně:

  • Časová razítka v logách nebo nahraných datech. Záznamy, které všechny uvádějí 1970-01-01, je dodatečně těžké rozumně interpretovat.

  • Naplánované úlohy. „Spustit ve 03:00“ vyžaduje, aby kamera věděla, kolik je 03:00.

9.16.2. Co NTP dělá

NTP je malá veřejná služba: síť serverů, které přes jediný UDP přenos odpovídají na otázku „kolik je hodin?“. Kamera pošle krátký požadavek na známý NTP server; server odpoví přesným časovým razítkem (s přesností na několik milisekund u libovolného běžného veřejného serveru); kamera podle něj nastaví své vlastní hodiny. Výchozí server, který kamera používá, je pool.ntp.org, globálně vyvažovaný pool navržený přesně pro tento druh klientů.

9.16.3. Python API: ntptime

MicroPython balí celý protokol do jediného volání. Běžný postup je nejprve navázat spojení a poté se zeptat NTP na čas:

import network
import ntptime
import time

wlan = network.WLAN(network.WLAN.IF_STA)
wlan.active(True)
wlan.connect("my-network", "my-password")

while not wlan.isconnected():
    time.sleep_ms(100)

ntptime.settime()                 # cam's clock is now UTC
print(time.localtime())

Po návratu z ntptime.settime() odráží vestavěné hodiny reálného času i time.localtime() aktuální čas UTC. Výchozí hodnoty lze upravit dvěma parametry:

  • ntptime.host je název serveru, na který se má dotazovat. Před voláním settime() jej přepište (ntptime.host = "time.google.com"), chcete-li směřovat na jiný server.

  • ntptime.timeout je počet sekund, po které se čeká na odpověď, než se to vzdá; výchozí hodnota je krátká.

9.16.4. Kdy ji volat

  • Až po navázání síťového spojení. NTP jede na UDP, které jede na ustaveném IP nastavení. Nejprve počkejte, až isconnected() vrátí True.

  • Periodicky u dlouhoběžících kamer. Vestavěné hodiny se během hodin a dnů rozcházejí. Denní nebo týdenní settime() je udržuje přesné.

9.16.5. Časová pásma

NTP vrací UTC. MicroPython neobsahuje databázi časových pásem, takže převod UTC na místní čas je úkolem skriptu. Obvyklým přístupem je pevný posun pro pásmo daného nasazení:

import time

offset = -5 * 3600                  # hours -> seconds, US Eastern
local = time.localtime(time.time() + offset)
print(local)

Letní čas, přestupné sekundy a historické změny pásem tento přístup neřeší. Pro většinu nasazení kamer pevný posun stačí; pokud skript skutečně potřebuje občanský čas s letním časem, proveďte převod na straně serveru.

9.16.6. Co se může pokazit

  • Síť ještě není dostupná. ntptime.settime() vyvolá OSError, pokud server nelze kontaktovat. Buď není spojení navázáno, selhalo vyhledání názvu, server je nedostupný, nebo žádná odpověď nedorazila během ntptime.timeout. Zopakujte pokus, jakmile je spojení stabilní.

  • Captive portály. Wi-Fi síť, která zachytává DNS, může na název NTP serveru odpovědět vlastní IP adresou portálu a NTP požadavky na ni vracejí nesmysly. Kamera si bude myslet, že je síť dostupná, ale nastavení času selže nebo bude zcela chybné. Přejděte do čisté sítě nebo natvrdo zadejte IP adresu.

  • Bombardování veřejných poolů. Veřejné NTP pooly omezují rychlost zneužívajících klientů. Jednou za hodinu bohatě stačí; jednou za minutu kameře zajistí zákaz.

Úplnou referenci k ntptime najdete v ntptime — jednoduchý NTP klient.