Initial commit: Hybrid polling, interactive log modal and 3-second hard reset

This commit is contained in:
cheveguerra
2026-07-24 15:31:56 +00:00
commit 7808501bf4
16 changed files with 34739 additions and 0 deletions
+70
View File
@@ -0,0 +1,70 @@
# Plan de Implementación y Walkthrough Propuesto: Integración de Eventos en Tiempo Real
Este documento detalla el plan de diseño técnico y la arquitectura de los cambios que se implementarán en el proyecto TotalConnect (`index.py`) para integrar el monitoreo por eventos en tiempo real.
---
## 🎯 Objetivos de la Implementación
1. **Monitoreo Automático en Segundo Plano:** El servidor Python consultará a Honeywell mediante `GetEvents` cada 4560 segundos sin requerir la intervención del usuario.
2. **Actualización Ultra-Rápida (Delta Update):** En lugar de consultar las 285 sucursales (1-2 minutos), el sistema identificará únicamente las sucursales que registraron eventos nuevos y actualizará el reporte en **1 a 3 segundos**.
3. **Cero Retraso al Abrir la Página (`GET /`):** La carga inicial seguirá leyendo `last_state.json` de inmediato (< 5 milisegundos).
4. **Control Manual y Circuit Breaker (Botonera & Kill-Switch):**
* Botón en la cabecera del dashboard para **Pausar / Reanudar Polling**.
* Pausa automática inteligente si Honeywell responde errores de autenticación (401) o límite de peticiones (429).
5. **DOM Patching Silencioso en la Interfaz (JS):** Actualización instantánea en el navegador únicamente de los nodos/tarjetas que cambiaron de estado, evitando parpadeos o animaciones molestas.
6. **Manejo Resiliente Multicuenta y Revocados:** Las cuentas fuera de línea se mantendrán clasificadas con prioridad 3 al final del listado con fondo gris.
---
## 🏗️ Cambios Arquitectónicos por Componente
### 1. Backend (`index.py`)
#### A. Hilo Demonio de Polling en Segundo Plano (`BackgroundPollerThread`)
* Se agregará un `threading.Thread(daemon=True)` que se ejecuta automáticamente al arrancar el servidor.
* Mantiene variables globales en memoria:
* `polling_enabled` (`True` / `False`): Estado global del motor de consulta.
* `last_event_ids`: Diccionario `{ "Ccontrol2020": 850123, "Ccontrol2019": 412099 }` con el último ID de evento procesado por cuenta.
* `consecutive_errors`: Contador de fallos consecutivos por cuenta.
#### B. Flujo del Poller (`poll_events_cycle()`):
1. **Verificación de Pausa:** Si `polling_enabled` es `False`, el hilo espera 15 segundos y re-evalúa.
2. **Petición Delta `GetEvents`:**
Para cada cuenta activa en `credentials.json`, envía una llamada ligera `GetEvents` pasando `LastEventIdReceived`.
3. **Evaluación de Resultados:**
* **Sin cambios:** Honeywell responde `[]`. No se hace nada más.
* **Con cambios:** Extrae los `LocationID` afectados. Ejecuta `fullStatus` únicamente para esos IDs.
4. **Actualización de Estado:** Consolida la información en `last_state.json` y vuelve a generar `status.html`.
5. **Manejo de Errores (Circuit Breaker):** Si una cuenta recibe 2 errores `401` o `429` seguidos, el servidor pausa el polling automático para esa cuenta y notifica a la UI.
#### C. Endpoints HTTP Nuevos en `DashboardHandler`
* `GET /polling-status`: Devuelve el estado actual (`enabled`, `last_run`, `active_errors`).
* `POST /toggle-polling`: Permite a la interfaz web activar o pausar manualmente el polling.
---
### 2. Frontend (`status.html` / Template en `index.py`)
#### A. Botón de Control de Polling en Cabecera
Junto al botón "Actualizar" y al selector de cuentas, se agregará un nuevo botón dinámico:
```html
<button id="toggle-polling-btn" class="btn-polling-active" onclick="togglePolling()">
<span class="polling-indicator"></span> Polling: Activo
</button>
```
#### B. Polling Local JS y DOM Patching
Un script JS en el cliente ejecutará una consulta ultrarrápida a `GET /polling-status` cada 15 segundos:
* Si la respuesta indica un cambio en el timestamp del último estado, realiza un `fetch('/')` silencioso.
* Compara los estados de las sucursales y actualiza el HTML **únicamente de las tarjetas que cambiaron**, manteniendo la posición y el foco del usuario.
* **Auto-Check por Visibilidad (`visibilitychange`):** Al volver a la pestaña tras estar inactivo, el navegador refresca los datos al instante.
---
## 📝 Plan de Verificación
1. **Prueba de Polling en Segundo Plano:** Iniciar el servidor, alterar el estado de una sucursal de prueba y verificar en consola que la consulta toma < 2 segundos.
2. **Prueba de Kill-Switch:** Presionar el botón "Pausar Polling" en la interfaz y verificar que cesan las llamadas HTTP a Honeywell.
3. **Prueba de Circuit Breaker:** Simular una credencial inválida y verificar que el servidor desactiva automáticamente el polling tras 2 intentos fallidos.
4. **Prueba de Rendimiento:** Confirmar que la carga inicial `GET /` sigue respondiendo en < 5ms.