9.16. Время и NTP

Только что включённая камера не имеет ни малейшего представления о текущем времени. Встроенные часы стартуют с некоторого произвольного момента (1970-01-01 на большинстве плат) и отсчитывают время вперёд от него, пока что-нибудь не сообщит им иное. NTP – Network Time Protocol – это то, как камера запрашивает у сети реальное астрономическое время и устанавливает по полученному ответу собственные часы.

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.

  • Периодически на долгоработающих камерах. Встроенные часы уходят за часы и дни. Ежедневный или еженедельный вызов 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)

Этот подход не учитывает переход на летнее время, високосные секунды и исторические изменения часовых поясов. Для большинства развёртываний камер фиксированного смещения достаточно; если скрипту действительно нужно гражданское время с переходом на летнее время, выполняйте преобразование на стороне сервера.

9.16.6. Что может пойти не так

  • Сеть ещё не готова. ntptime.settime() вызывает OSError, если не может достучаться до сервера. Возможно, соединение не поднято, не удалось разрешить имя, сервер недоступен или ответ не пришёл в течение ntptime.timeout. Повторите попытку, когда соединение станет стабильным.

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

  • Чрезмерная нагрузка на публичные пулы. Публичные пулы NTP ограничивают частоту обращений недобросовестных клиентов. Раз в час более чем достаточно; раз в минуту приведёт к блокировке камеры.

Полный справочник по ntptime см. в ntptime — простой NTP-клиент.