feat(eventos): menu Eventos, modo presenca e 3 dias de historico

- "Eventos" vira item do menu principal: lista por dia (Hoje, Ontem...),
  presenca e movimento em destaque, botao "Ver foto" com miniatura
- modo presenca: o PIR liga a camera do celular e acorda o Carinha; sem
  ninguem por N minutos (5 por padrao) a camera desliga, ele dorme e fica
  em silencio (sons e fala desligados enquanto dorme)
- historico guarda so os ultimos 3 dias (ajustavel de 1 a 30), com faxina
  automatica de eventos e fotos antigos
- testes da retencao e do modo presenca

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
julio
2026-10-06 03:51:49 -03:00
co-authored by Claude Opus 5.5
parent 6029c79645
commit 499a4ae479
13 changed files with 449 additions and 315 deletions
+27
View File
@@ -66,6 +66,33 @@ class HistoricoTest(unittest.TestCase):
self.assertFalse(self.h.evento(ids[0])['foto'])
self.assertEqual(len(list((Path(self.tmp.name) / 'fotos').glob('*.jpg'))), MAX_FOTOS)
def test_guarda_so_os_ultimos_dias(self):
agora = 10 * 86400
velho = self.h.registrar('pir', agora=agora - 4 * 86400)
self.h.guardar_foto(velho, JPEG)
novo = self.h.registrar('pir', agora=agora - 86400)
self.assertEqual(self.h.limpar_antigos(agora), 1) # 3 dias por padrão
self.assertIsNone(self.h.evento(velho))
self.assertIsNotNone(self.h.evento(novo))
self.assertFalse((Path(self.tmp.name) / 'fotos' / f'evento-{velho}.jpg').exists())
with self.assertRaises(ValueError):
self.h.validar({'dias': 0})
def test_modo_presenca(self):
chamadas = []
self.h.ao_presenca = lambda: chamadas.append('chegou')
self.h.ao_ausencia = lambda: chamadas.append('saiu')
self.h.pir['disponivel'] = True
self.h.marcar_presenca(1000)
self.assertFalse(self.h.checar_ausencia(1000 + 4 * 60)) # 4 min: ainda presente
self.assertTrue(self.h.checar_ausencia(1000 + 5 * 60 + 1)) # 5 min: ausente
self.assertFalse(self.h.checar_ausencia(1000 + 10 * 60)) # não repete
self.h.marcar_presenca(2000) # voltou alguém
self.assertEqual(chamadas, ['saiu', 'chegou'])
self.h.config['presenca'] = False
self.h.marcar_presenca(3000)
self.assertFalse(self.h.checar_ausencia(9999))
def test_apagar_e_limpar(self):
a = self.h.registrar('pir', agora=1); self.h.guardar_foto(a, JPEG)
b = self.h.registrar('som', agora=1)