# Alertas del hogar

Esta fase implementa reglas e historial dentro de la web. La decisión entre
aplicación nativa y PWA queda pendiente; no se envían notificaciones externas.

## Uso

1. Entrar como propietario y abrir un hogar.
2. En el dispositivo, pulsar **Configurar alertas**.
3. Elegir temperatura, humedad o falta de lecturas reales.
4. Indicar mínimo, máximo o ambos (temperatura/humedad), tiempo y estado.
5. Guardar cada tipo de regla por separado. Los valores se recuperan al elegir
   de nuevo ese tipo. No se crean reglas ni límites predeterminados para hogares.
6. Consultar **Alertas del hogar**, con eventos activos primero e historial
   hasta 100 eventos, incluyendo inicio, valor al activarse y motivo de cierre.

Solo el propietario configura. Otros miembros consultan; perfiles infantiles
solo ven eventos y reglas de dispositivos en sus habitaciones autorizadas.

## Semántica

- Una regla por dispositivo y tipo. Límites estrictos: igual al mínimo o máximo
  cuenta como normal. Se permite vigilar solo uno de los dos límites.
- Tiempo configurable de 1 a 1440 minutos. La web utiliza minutos enteros;
  la API recibe segundos enteros entre 60 y 86400.
- Temperatura y humedad requieren sucesivas lecturas reales fuera de rango.
  Una lectura normal reinicia el tiempo. Una interrupción mayor de 90 segundos
  o una muestra simulada reinicia el tiempo pendiente. Es coherente con el
  intervalo de 20 segundos del firmware actual.
- No se abre una alerta de rango solo porque pasó el tiempo sin nuevas muestras.
- Una alerta por episodio; nuevas lecturas anómalas no crean duplicados.
  Una lectura real normal la resuelve. Si faltan datos, una alerta de rango
  activa permanece activa: no se puede afirmar que la condición se normalizó.
- Falta de lecturas utiliza la última muestra de origen sensor, no el heartbeat.
  Empieza a contar desde que se guarda la regla si no hay una lectura más nueva.
  También funciona para dispositivos que nunca han enviado una lectura real.
- Guardar una regla cierra su evento activo como cambio de configuración,
  reinicia el tiempo y excluye muestras anteriores de la nueva evaluación de rango.
- Pausar una regla o dispositivo cierra sus eventos como configuración/pausa.
  El dispositivo pausado no genera alertas y, al reactivarlo, recibe un nuevo
  plazo de espera. El evaluador detecta pausas de dispositivo en su siguiente ciclo.
- Solo se evalúan lecturas reales; las pruebas simuladas no generan alertas de
  temperatura/humedad ni satisfacen la regla de recepción de datos reales.

## Implementación y operación

Migración `004_alerts.sql`: reglas, progreso persistente y eventos con copia
de los límites/tiempo vigentes al abrirse. Sin dependencias adicionales.
`backend/bin/evaluate-alerts.php` se ejecuta mediante `homecore-alerts.timer`
cada 10 segundos después de finalizar el ciclo anterior. La evaluación continúa
sin navegadores abiertos y se recupera tras reinicios.

El motor consume hasta 1000 muestras pendientes por regla y ciclo, en orden de ID.
Un bloqueo global evita evaluadores simultáneos; transacciones y bloqueo del
dispositivo serializan configuración/evaluación. El cursor y el evento se guardan
en la misma transacción. Un fallo revierte la regla y se reintenta en otro ciclo.
No requiere cambiar el firmware ni ampliar privilegios del proceso WebSocket.

La interfaz consulta cada 5 segundos mientras está visible. La demora habitual
tras cumplirse una regla es de hasta aproximadamente 15 segundos con servidor
sin carga. No sustituye una alarma de seguridad ni controla equipos físicos.

API autenticada, con CSRF en escritura:
- `GET /api/v1/devices/{id}/alert-rules`
- `POST /api/v1/devices/{id}/alert-rules`: `metric` (temperature/humidity/missing),
  `enabled` booleano, `minimum`/`maximum` números o null, `duration_seconds` entero.
- `GET /api/v1/homes/{id}/alerts`: eventos autorizados (activos primero), máximo 100.

Los eventos no tienen borrado automático en esta fase; la retención de telemetría
existente no elimina eventos. Si el evaluador queda parado más allá de la retención
de muestras (30 días), no puede reconstruir las lecturas ya eliminadas.

Instalación tras respaldo y migración con cuenta administrativa local:

```bash
sudo cp deployment/systemd/homecore-alerts.{service,timer} /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now homecore-alerts.timer
sudo systemctl start homecore-alerts.service
systemctl show homecore-alerts.service -p Result -p ExecMainStatus
```

Usa el mismo `EnvironmentFile` privado que PHP con permisos DML; el servicio
no necesita root. Para detener únicamente la evaluación, detener el timer y
el servicio. Mantener las tablas preserva el historial y los cursores.

Pruebas aisladas: `python3 backend/tests/alerts.py`. Con `HOMECORE_UI_TEST=1`,
Playwright verifica configuración, persistencia visual e historial a 390px.
Requiere las rutas de navegador y bibliotecas del entorno de pruebas documentado.
`websocket-server/tests/public-probe.mjs` verifica también una alerta temporal
a través del timer público y elimina únicamente sus propios datos.
