9.16. Idő és NTP

A frissen bekapcsolt kamera fogalma sincs róla, hány óra van. A beépített óra valamilyen tetszőleges pillanatban indul el (a legtöbb panelen 1970-01-01), és onnan számol tovább, amíg valami másra nem utasítja. Az NTP – a Network Time Protocol – az a mód, ahogyan a kamera lekérdezi a hálózattól a valós idejű pontos időt, és ennek alapján beállítja a saját óráját.

9.16.1. Miért kell a kamerának ismernie az időt

Sok szkriptnél a kamera órája nem számít – egy képkocka-rögzítő ciklusnak mindegy, milyen nap van. Néhány gyakori feladatnál azonban annál inkább számít:

  • Időbélyegek a naplókban vagy a feltöltött adatokban. A csupa 1970-01-01 dátumot tartalmazó bejegyzéseket utólag nehéz értelmezni.

  • Ütemezett feladatok. A „03:00-kor fusson” feladathoz a kamerának tudnia kell, mikor van 03:00.

9.16.2. Mit csinál az NTP

Az NTP egy kis nyilvános szolgáltatás: kiszolgálók hálózata, amely egyetlen UDP-üzenetváltáson keresztül válaszol a „hány óra van?” kérdésre. A kamera rövid kérést küld egy ismert NTP-kiszolgálónak; a kiszolgáló pontos időbélyeggel válaszol (bármely elterjedt nyilvános kiszolgáló esetén néhány ezredmásodperc pontossággal); a kamera ezt használja a saját órájának beállítására. A kamera által használt alapértelmezett kiszolgáló a pool.ntp.org, egy globálisan terheléselosztott pool, amelyet pontosan az ilyen kliensek számára terveztek.

9.16.3. A Python API: ntptime

A MicroPython a protokollt egyetlen hívásba csomagolja. A bevett minta szerint először létrejön a kapcsolat, majd a kamera lekéri az időt az NTP-től:

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())

Miután a ntptime.settime() visszatér, a beépített valós idejű óra és a time.localtime() az aktuális UTC-időt tükrözi. Két beállítással módosíthatók az alapértelmezések:

  • A ntptime.host a lekérdezendő kiszolgáló neve. Felülírásával (ntptime.host = "time.google.com") a settime() hívása előtt másik kiszolgálóra irányíthatod.

  • A ntptime.timeout az a másodpercben megadott idő, ameddig a kamera vár a válaszra, mielőtt feladná; az alapértelmezett érték rövid.

9.16.4. Mikor hívd meg

  • A hálózati kapcsolat létrejötte után. Az NTP az UDP-re épül, amely viszont egy létrehozott IP-beállításra. Először várd meg, amíg a isconnected() True értékkel tér vissza.

  • Hosszan futó kameráknál rendszeresen. A beépített óra órák és napok alatt elcsúszik. Egy napi vagy heti settime() pontosan tartja.

9.16.5. Időzónák

Az NTP UTC-időt ad vissza. A MicroPython nem tartalmaz időzóna-adatbázist, ezért az UTC helyi időre alakítása a szkript feladata. A telepítés zónájának megfelelő rögzített eltolás a szokásos megoldás:

import time

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

A nyári időszámítást, a szökőmásodperceket és a múltbeli zónaváltozásokat ez a megközelítés nem kezeli. A legtöbb kameratelepítéshez egy rögzített eltolás elegendő; ha egy szkriptnek valóban nyári időszámítást is figyelembe vevő polgári időre van szüksége, az átalakítást végezd a kiszolgáló oldalán.

9.16.6. Mi mehet félre

  • Még nincs hálózat. A ntptime.settime() OSError kivételt vált ki, ha nem éri el a kiszolgálót. Vagy nincs kapcsolat, vagy a névfeloldás sikertelen, vagy a kiszolgáló nem érhető el, vagy nem érkezett válasz a ntptime.timeout időn belül. Próbáld újra, amint a kapcsolat stabil.

  • Captive portálok. Egy DNS-t lehallgató Wi-Fi-hálózat az NTP-kiszolgáló nevére a portál saját IP-címével válaszolhat, és az oda küldött NTP-kérések értelmetlen választ adnak. A kamera azt fogja hinni, hogy van hálózat, de az időbeállítás sikertelen lesz, vagy teljesen hibás értéket ad. Válts tiszta hálózatra, vagy rögzítsd kódból az IP-címet.

  • A nyilvános poolok túlterhelése. A nyilvános NTP-poolok korlátozzák a visszaélő klienseket. Óránként egyszer bőven elég; percenként egyszer a kamera kitiltását eredményezi.

A teljes ntptime referenciát lásd: ntptime — egyszerű NTP-kliens.