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-клиент.