9.16. Zaman ve NTP

Yeni açılmış bir kamera saatin kaç olduğunu bilmez. Yerleşik saat rastgele bir andan (çoğu kartta 1970-01-01) başlar ve aksini söyleyen bir şey olana kadar oradan ileriye doğru sayar. NTP – Network Time Protocol – kameranın gerçek dünyadaki duvar saati zamanını ağdan sorup kendi saatini yanıta göre ayarlamasını sağlayan yöntemdir.

9.16.1. Kameranın neden zamanı bilmesi gerekir

Birçok betik için kameranın saati önemli değildir – bir çerçeve yakalama döngüsü günün ne olduğunu umursamaz. Ancak birkaç yaygın durumda çok önemlidir:

  • Günlüklerdeki veya yüklenen verilerdeki zaman damgaları. Hepsi 1970-01-01 diyen girdileri sonradan anlamlandırmak zordur.

  • Zamanlanmış görevler. “03:00’te çalıştır” için kameranın 03:00’ün ne olduğunu bilmesi gerekir.

9.16.2. NTP ne yapar

NTP küçük bir genel hizmettir: tek bir UDP alışverişiyle “saat kaç?” sorusunu yanıtlayan bir sunucu ağı. Kamera bilinen bir NTP sunucusuna kısa bir istek gönderir; sunucu hassas bir zaman damgasıyla yanıt verir (herhangi bir yaygın genel sunucu için birkaç milisaniye doğrulukta); kamera bunu kendi saatini ayarlamak için kullanır. Kameranın kullandığı varsayılan sunucu, tam olarak bu tür istemciler için tasarlanmış, küresel olarak yük dengeli bir havuz olan pool.ntp.org‘dur.

9.16.3. Python API’si: ntptime

MicroPython protokolü tek bir çağrıda sarmalar. Yaygın desen önce bağlantıyı kurmak, ardından NTP’den zamanı istemektir:

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

ntptime.settime() döndükten sonra, yerleşik gerçek zamanlı saat ve time.localtime() geçerli UTC zamanını yansıtır. İki ayar düğmesi varsayılanları değiştirir:

  • ntptime.host sorgulanacak sunucu adıdır. Farklı bir sunucuya yönlendirmek için settime() çağrılmadan önce onu geçersiz kılın (ntptime.host = "time.google.com").

  • ntptime.timeout vazgeçmeden önce bir yanıt için beklenecek saniye sayısıdır; varsayılan değer kısadır.

9.16.4. Ne zaman çağrılır

  • Ağ bağlantısı kurulduktan sonra. NTP, yerleşik bir IP kurulumu üzerinde çalışan UDP üzerinde çalışır. Önce isconnected()‘in True döndürmesini bekleyin.

  • Uzun süre çalışan kameralarda periyodik olarak. Yerleşik saat saatler ve günler boyunca kayar. Günlük veya haftalık bir settime() onu doğru tutar.

9.16.5. Saat dilimleri

NTP UTC döndürür. MicroPython bir saat dilimi veritabanı içermez, bu nedenle UTC’yi yerel saate dönüştürmek betiğin işidir. Dağıtımın bulunduğu dilim için sabit bir kaydırma değeri kullanmak olağan yaklaşımdır:

import time

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

Yaz Saati Uygulaması, artık saniyeler ve geçmişteki dilim değişiklikleri bu yaklaşımla ele alınmaz. Çoğu kamera dağıtımı için sabit bir kaydırma yeterlidir; bir betiğin gerçekten Yaz Saati Uygulamasıyla birlikte sivil zamana ihtiyacı varsa, dönüşümü sunucu tarafında yapın.

9.16.6. Neler ters gidebilir

  • Henüz ağ yok. ntptime.settime() sunucuya ulaşamazsa OSError yükseltir. Ya bağlantı kurulmamıştır, ya ad araması başarısız olmuştur, ya sunucuya ulaşılamamıştır ya da ntptime.timeout içinde hiç yanıt gelmemiştir. Bağlantı kararlı olduğunda yeniden deneyin.

  • Yakalama portalları. DNS’i ele geçiren bir Wi-Fi ağı, NTP sunucu adını portalın kendi IP’siyle yanıtlayabilir ve buna gönderilen NTP istekleri anlamsız sonuçlar döndürür. Kamera ağın kurulu olduğunu düşünür ancak zaman ayarı başarısız olur veya tamamen yanlış olur. Temiz bir ağa geçin veya bir IP’yi sabit kodlayın.

  • Genel havuzları zorlamak. Genel NTP havuzları kötüye kullanan istemcileri hız sınırlar. Saatte bir kez fazlasıyla yeterlidir; dakikada bir kez kameranın yasaklanmasına yol açar.

Tam ntptime başvurusu için bkz. ntptime — basit NTP istemcisi.