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.hostto nazwa serwera, do którego kierowane jest zapytanie. Nadpisz ją (ntptime.host = "time.google.com") przed wywołaniemsettime(), aby wskazać inny serwer.ntptime.timeoutto 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óciTrue.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łaszaOSError, 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 czasientptime.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.