9.16. Czas i NTP

Świeżo uruchomiona kamera nie ma pojęcia, która jest godzina. Wbudowany zegar zaczyna odliczać od jakiegoś dowolnego momentu (1970-01-01 na większości płytek) i liczy naprzód, dopóki coś nie powie mu inaczej. NTP – Network Time Protocol – to sposób, w jaki kamera pyta sieć o rzeczywisty czas zegarowy i ustawia na jego podstawie własny zegar.

9.16.1. Dlaczego kamera musi znać czas

W przypadku wielu skryptów zegar kamery nie ma znaczenia – pętli przechwytującej ramki nie obchodzi, jaki jest dzień. W kilku typowych sytuacjach ma to jednak ogromne znaczenie:

  • Znaczniki czasu w logach lub przesyłanych danych. Wpisy, które wszystkie podają 1970-01-01, trudno później zinterpretować.

  • Zadania zaplanowane. „Uruchom o 03:00” wymaga, by kamera wiedziała, czym jest 03:00.

9.16.2. Co robi NTP

NTP to niewielka usługa publiczna: sieć serwerów odpowiadających na pytanie „która jest godzina?” w ramach pojedynczej wymiany UDP. Kamera wysyła krótkie żądanie do znanego serwera NTP; serwer odpowiada precyzyjnym znacznikiem czasu (dokładnym do kilku milisekund w przypadku dowolnego popularnego serwera publicznego); kamera używa go, by ustawić własny zegar. Domyślnym serwerem, którego używa kamera, jest pool.ntp.org – globalnie zrównoważony obciążeniowo pool zaprojektowany właśnie dla tego rodzaju klientów.

9.16.3. API w Pythonie: ntptime

MicroPython opakowuje ten protokół w jedno wywołanie. Typowy wzorzec to najpierw zestawienie połączenia, a następnie zapytanie NTP o czas:

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 powrocie z ntptime.settime() wbudowany zegar czasu rzeczywistego oraz time.localtime() odzwierciedlają bieżący czas UTC. Dwa parametry pozwalają dostosować wartości domyślne:

  • ntptime.host to nazwa serwera, do którego kierowane jest zapytanie. Nadpisz ją (ntptime.host = "time.google.com") przed wywołaniem settime(), aby wskazać inny serwer.

  • ntptime.timeout to liczba sekund oczekiwania na odpowiedź, zanim nastąpi rezygnacja; wartość domyślna jest krótka.

9.16.4. Kiedy je wywoływać

  • Po zestawieniu połączenia sieciowego. NTP działa na UDP, które z kolei opiera się na skonfigurowanym połączeniu IP. Najpierw poczekaj, aż isconnected() zwróci True.

  • Okresowo w przypadku długo działających kamer. Wbudowany zegar dryfuje w ciągu godzin i dni. Codzienne lub cotygodniowe settime() utrzymuje go w ryzach.

9.16.5. Strefy czasowe

NTP zwraca czas UTC. MicroPython nie dostarcza bazy stref czasowych, więc przeliczenie UTC na czas lokalny należy do skryptu. Zwykle stosuje się stałe przesunięcie dla strefy wdrożenia:

import time

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

To podejście nie obsługuje czasu letniego, sekund przestępnych ani historycznych zmian stref. W przypadku większości wdrożeń kamer stałe przesunięcie wystarcza; jeśli skrypt rzeczywiście potrzebuje czasu cywilnego z uwzględnieniem czasu letniego, wykonaj przeliczenie po stronie serwera.

9.16.6. Co może pójść nie tak

  • Brak sieci. ntptime.settime() zgłasza OSError, jeśli nie może dotrzeć do serwera. Albo połączenie nie jest zestawione, albo nie powiodło się wyszukanie nazwy, albo serwer jest nieosiągalny, albo żadna odpowiedź nie nadeszła w czasie ntptime.timeout. Ponów próbę, gdy połączenie będzie stabilne.

  • Portale przechwytujące (captive portals). Sieć Wi-Fi, która przechwytuje DNS, może odpowiedzieć na nazwę serwera NTP własnym adresem IP portalu, a żądania NTP do niego zwracają bezsensowne dane. Kamera będzie myślała, że sieć działa, ale ustawienie czasu nie powiedzie się lub będzie całkowicie błędne. Przejdź do czystej sieci lub zakoduj adres IP na stałe.

  • Zarzucanie publicznych poolów. Publiczne poole NTP ograniczają częstotliwość żądań nadużywających klientów. Raz na godzinę w zupełności wystarczy; raz na minutę doprowadzi do zablokowania kamery.

Pełną dokumentację ntptime znajdziesz w ntptime — prosty klient NTP.