9.16. Tempo e NTP

Uma câmara recém-ligada não sabe que horas são. O relógio interno começa num momento arbitrário (1970-01-01 na maioria das placas) e conta a partir daí até que algo o corrija. O NTP – o Network Time Protocol – é a forma como a câmara consulta a rede para obter a hora real do mundo e acerta o seu próprio relógio com a resposta.

9.16.1. Por que razão a câmara precisa de saber a hora

Para muitos scripts, o relógio da câmara não importa – um ciclo de captura de fotogramas não se importa com o dia que é. Para algumas coisas comuns, importa bastante:

  • Marcas de tempo em registos ou dados enviados. Entradas que mostram todas 1970-01-01 são difíceis de interpretar depois.

  • Tarefas agendadas. «Executar às 03:00» exige que a câmara saiba o que são as 03:00.

9.16.2. O que o NTP faz

O NTP é um pequeno serviço público: uma rede de servidores que respondem a «que horas são?» através de uma única troca UDP. A câmara envia um pedido curto a um servidor NTP conhecido; o servidor responde com um timestamp preciso (com uma precisão de alguns milissegundos para qualquer servidor público comum); a câmara usa isso para acertar o seu próprio relógio. O servidor predefinido que a câmara utiliza é pool.ntp.org, um conjunto com balanceamento de carga global concebido exactamente para este tipo de cliente.

9.16.3. A API Python: ntptime

O MicroPython encapsula o protocolo numa única chamada. O padrão comum é estabelecer primeiro a ligação e depois pedir a hora ao 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())

Depois de ntptime.settime() retornar, o relógio de tempo real integrado e time.localtime() reflectem a hora UTC actual. Dois parâmetros ajustam as predefinições:

  • ntptime.host é o nome do servidor a consultar. Substitua-o (ntptime.host = "time.google.com") antes de chamar settime() para apontar para um servidor diferente.

  • ntptime.timeout é o número de segundos a aguardar por uma resposta antes de desistir; a predefinição é curta.

9.16.4. Quando chamá-lo

  • Depois de a ligação de rede estar activa. O NTP usa UDP, que assenta numa configuração IP estabelecida. Aguarde que isconnected() retorne True primeiro.

  • Periodicamente em câmaras de longa duração. O relógio interno deriva ao longo de horas e dias. Um settime() diário ou semanal mantém-no preciso.

9.16.5. Fusos horários

O NTP devolve UTC. O MicroPython não inclui uma base de dados de fusos horários, pelo que converter UTC para hora local é responsabilidade do script. Uma diferença fixa para o fuso da instalação é a abordagem habitual:

import time

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

O horário de verão, os segundos bissextos e as alterações históricas de fuso não são tratados por esta abordagem. Para a maioria das instalações de câmaras, uma diferença fixa é suficiente; se um script necessitar genuinamente de hora civil com horário de verão, faça a conversão no lado do servidor.

9.16.6. O que pode correr mal

  • Sem rede ainda. ntptime.settime() lança OSError se não conseguir alcançar o servidor. A ligação pode ainda não estar activa, a resolução de nomes falhou, o servidor está inacessível, ou não chegou nenhuma resposta dentro de ntptime.timeout. Tente novamente quando a ligação estiver estável.

  • Portais cativo. Uma rede Wi-Fi que intercepta DNS pode responder ao nome do servidor NTP com o IP do portal, e os pedidos NTP para esse endereço devolvem resultados absurdos. A câmara pensará que a rede está activa, mas a definição da hora falhará ou estará completamente errada. Passe para uma rede limpa ou use um IP fixo.

  • Sobrecarregar conjuntos públicos. Os conjuntos NTP públicos limitam a taxa de clientes abusivos. Uma vez por hora é suficiente; uma vez por minuto levará a que a câmara seja banida.

Para a referência completa de ntptime, consulte ntptime — cliente NTP simples.