9.16. Час та NTP

Щойно увімкнена камера не знає, котра година. Вбудований годинник запускається з довільного моменту (1970-01-01 на більшості плат) і рахує час вперед звідти, доки щось не скаже йому інакше. NTP – мережевий протокол часу – це спосіб, за допомогою якого камера запитує мережу про реальний час і встановлює власний годинник на основі відповіді.

9.16.1. Навіщо камері знати час

Для більшості скриптів годинник камери не має значення – цикл захоплення кадрів не перймається, який зараз день. Але для деяких поширених задач це дуже важливо:

  • Мітки часу в журналах або завантажених даних. Записи, де всюди написано 1970-01-01, важко осмислити після їх накопичення.

  • Заплановані задачі. «Запустити о 03:00» вимагає, щоб камера знала, що таке 03:00.

9.16.2. Що робить NTP

NTP – це невелика публічна служба: мережа серверів, що відповідають на запит «котра година?» через одиночний обмін UDP. Камера надсилає короткий запит на відомий NTP-сервер; сервер відповідає точною міткою часу (точність кількох мілісекунд для будь-якого публічного сервера); камера використовує її для встановлення власного годинника. Сервер за замовчуванням, який використовує камера, – pool.ntp.org, глобально балансований пул, розроблений саме для таких клієнтів.

9.16.3. Python API: ntptime

MicroPython обертає протокол в один виклик. Типова схема – спочатку підняти з’єднання, а потім запитати NTP про час:

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() вбудований годинник реального часу та time.localtime() відображають поточний час UTC. Два параметри дозволяють змінити значення за замовчуванням:

  • ntptime.host – ім’я сервера для запиту. Перевизначте його (ntptime.host = "time.google.com") перед викликом settime(), щоб вказати інший сервер.

  • ntptime.timeout – кількість секунд очікування відповіді перед скасуванням; значення за замовчуванням невелике.

9.16.4. Коли викликати

  • Після встановлення мережевого з’єднання. NTP працює поверх UDP, який працює поверх налаштованого IP. Спочатку дочекайтесь, поки isconnected() поверне True.

  • Periodично на камерах з тривалою роботою. Вбудований годинник відстає протягом годин і днів. Щоденний або щотижневий виклик settime() утримує його точним.

9.16.5. Часові пояси

NTP повертає UTC. MicroPython не постачається з базою даних часових поясів, тому перетворення UTC на місцевий час є завданням скрипта. Зазвичай використовується фіксоване зміщення для часового поясу розгортання:

import time

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

Цей підхід не обробляє літній час, високосні секунди та históричні зміни поясів. Для більшості розгортань камери фіксованого зміщення достатньо; якщо скрипту справді потрібен цивільний час з літнім часом, виконуйте перетворення на стороні сервера.

9.16.6. Що може піти не так

  • Мережа ще не готова. ntptime.settime() викидає OSError, якщо не може досягти сервера. Або з’єднання ще не встановлено, або пошук імені не вдався, або сервер недоступний, або відповідь не надійшла в межах ntptime.timeout. Повторіть спробу після стабілізації з’єднання.

  • Captive-портали. Wi-Fi мережа, що перехоплює DNS, може відповідати на ім’я NTP-сервера IP-адресою порталу, і NTP-запити до нього повертатимуть нісенітницю. Камера вважатиме, що мережа доступна, але встановлення часу зазнає невдачі або буде грубо помилковим. Перейдіть на чисту мережу або вкажіть IP-адресу вручну.

  • Перевантаження публічних пулів. Публічні NTP-пули обмежують надмірних клієнтів. Раз на годину – цілком достатньо; раз на хвилину – і камеру заблокують.

Повний довідник ntptime дивіться в ntptime — простий NTP-клієнт.