|
| 1 | +# Helios — Monitor Solar |
| 2 | + |
| 3 | +<picture> |
| 4 | + <source media="(prefers-color-scheme: dark)" srcset="assets/dashboard-dark.png"> |
| 5 | + <source media="(prefers-color-scheme: light)" srcset="assets/dashboard-light.png"> |
| 6 | + <img alt="Helios — vista Hoy con flujo de energía en vivo" src="assets/dashboard-light.png"> |
| 7 | +</picture> |
| 8 | + |
| 9 | +> Repo **privado**. Este README no es para vender el proyecto: es para que el |
| 10 | +> Nacho del futuro entienda en cinco minutos **por qué existe esto, de dónde |
| 11 | +> salió y por qué está hecho como está hecho**, sin tener que re-leerse todo |
| 12 | +> el código ni la memoria del asistente. |
| 13 | +
|
| 14 | +## Por qué existe (la motivación real) |
| 15 | + |
| 16 | +Tenemos placas solares con **dos inversores** (Solis 4,4 kWp + Fox 2,7 kWp) y |
| 17 | +una **batería de 5 kWh**. Las apps de los fabricantes (Solis Cloud y similares): |
| 18 | + |
| 19 | +- Viven en la nube del fabricante: si cae su servicio o cambian la API, te |
| 20 | + quedas sin tus datos — que encima son **tuyos** y no los puedes exportar bien. |
| 21 | +- Actualizan cada 5+ minutos y con retraso; nada de "ahora mismo". |
| 22 | +- No mezclan ambos inversores ni cruzan con el precio real de la luz |
| 23 | + (tarifa Octopus) para decirte cuánto **dinero** te estás ahorrando. |
| 24 | + |
| 25 | +Helios nace para tener **en casa, en local y para siempre** la telemetría de |
| 26 | +la instalación: qué produce cada inversor, qué consume la casa, cómo va la |
| 27 | +batería y cuánto vale en euros cada kWh autoconsumido. |
| 28 | + |
| 29 | +## Origen (cómo ha crecido esto) |
| 30 | + |
| 31 | +1. **Home Assistant (HAOS)** ya integraba los dos inversores, así que HAOS es |
| 32 | + la **fuente de verdad del dato en vivo** (sensores de potencia, batería, |
| 33 | + red). Helios no habla con los inversores: habla con HAOS. |
| 34 | +2. La primera versión fue un panel rápido para ver "producción vs consumo". |
| 35 | + Creció a multiusuario con roles, histórico, batería, precios y PWA. |
| 36 | +3. El histórico diario se importó desde HAOS y se sigue alimentando cada día: |
| 37 | + **798+ días de datos** en una SQLite que es **intocable** (vive en |
| 38 | + `/opt/helios/data/helios.db` del CT 226; antes de cualquier migración, |
| 39 | + backup — hay réplica Litestream con PITR al disco zfs_2tb de citadel-01). |
| 40 | +4. Además existe un **scraper de Solis Cloud** (LXC 202 + add-on HAOS) que |
| 41 | + complementa el dato cuando la integración local se queda corta. |
| 42 | + |
| 43 | +## Necesidades que cubre (requisitos de verdad) |
| 44 | + |
| 45 | +- **Multiusuario con roles** (admin/user), sesiones con cookie httpOnly, |
| 46 | + bcrypt, rate-limit de login, audit log de mutaciones y recovery de admin |
| 47 | + **solo desde localhost** (pensado para entrar por SSH al CT). |
| 48 | +- **i18n ES/EN/zh-CN** con idioma por usuario guardado en BD. |
| 49 | +- **Dato en vivo** vía WebSocket a HAOS (no REST lento): la vista "Hoy" y el |
| 50 | + flujo de energía se mueven en tiempo real. |
| 51 | +- **Histórico serio**: 798+ días con agregados diarios (producción, consumo, |
| 52 | + import/export red, carga/descarga de batería, por inversor), autoconsumo, |
| 53 | + ahorro en € con los precios de Octopus y CO₂ evitado. |
| 54 | +- **PWA** instalable, tema claro/oscuro/auto (el auto es por hora solar, no |
| 55 | + por el sistema), densidad y shell común con el resto de apps de la casa. |
| 56 | +- **Sin Docker**: servicio systemd en un LXC de Proxmox, con la BD fuera del |
| 57 | + código para que las actualizaciones no la toquen. |
| 58 | + |
| 59 | +## Por qué este stack (y no otro) |
| 60 | + |
| 61 | +| Decisión | Motivo | |
| 62 | +|---|---| |
| 63 | +| **Node 22 + Hono** (backend) | App de **negocio/vista**, no un colector 24/7: la lógica valiosa es la de agregados y saneado de datos, ya validada durante 798 días. Reescribirla en Go era riesgo puro sin ganancia (decisión cerrada 1-Ago-2026: Go = colectores/infra, Node = negocio; Helios queda descartada para Go). Hono porque es pequeño, rápido y sin magia. | |
| 64 | +| **better-sqlite3 (ESM plano)** | Una BD embebida transaccional es todo lo que necesita una app doméstica: cero servicios extra, backup trivial, y los 798 días caben en 90 MB. JS plano en vez de TS en el server: menos build, menos fricción; los contratos se garantizan con **schemas zod compartidos** (`shared/schemas.js`) entre server y front. | |
| 65 | +| **React 19 + Vite + Tailwind** | El mismo front de todas las apps de la casa (base común `webapp-stack`/`webapp-shell`): una sola forma de hacer shell, tema, ajustes y login. | |
| 66 | +| **HAOS como fuente del live** | HAOS ya mantiene las integraciones con Solis/Fox y sus reconexiones. Duplicar eso en Helios sería mantener dos drivers. Helios consume, no integra. | |
| 67 | +| **systemd + LXC, sin Docker** | Un binario de Node con `node_modules` y una unit hardenizada (`ProtectSystem`, `ReadWritePaths`) es más simple de razonar y de hacer rollback que un contenedor, y la BD vive en `/opt/helios/data` fuera del código. | |
| 68 | +| **Litestream → SFTP** | Réplica continua de la SQLite con point-in-time-recovery: la BD es lo único insustituible del sistema. | |
| 69 | + |
| 70 | +## Capturas (uso real, instalación en producción) |
| 71 | + |
| 72 | +| Vista Hoy (dark / light) | Histórico semanal | Batería | |
| 73 | +|---|---|---| |
| 74 | +|  |  |  | |
| 75 | + |
| 76 | +Las capturas son de la **instalación real** (server de desarrollo contra HAOS |
| 77 | +local y una copia de la BD con 798 días). No hay dataset demo aparte: los |
| 78 | +datos de verdad cuentan mejor para qué sirve cada vista. |
| 79 | + |
| 80 | +## Arquitectura en 30 segundos |
| 81 | + |
| 82 | +``` |
| 83 | +Inversores (Solis/Fox) ──integraciones──▶ HAOS ──WebSocket──▶ Helios server (Hono) |
| 84 | + ▲ │ better-sqlite3 |
| 85 | + scraper Solis Cloud ▼ |
| 86 | + (LXC 202 + add-on) SQLite (798+ días) |
| 87 | + │ Litestream |
| 88 | + ▼ |
| 89 | + SFTP zfs_2tb (citadel-01) |
| 90 | +``` |
| 91 | + |
| 92 | +- `server/` — API Hono + auth multiusuario + agregados + saneado de datos. |
| 93 | +- `app/` — React 19 (vistas: Hoy, Inversores, Batería, Histórico, Ajustes). |
| 94 | +- `shared/schemas.js` — contrato zod server↔front. |
| 95 | +- Detalle completo en `ARCHITECTURE.md` y `STACK.md`. |
| 96 | + |
| 97 | +## Operación (lo justo para no romper nada) |
| 98 | + |
| 99 | +- Producción: **CT 226** (citadel-01), servicio `helios.service`, puerto 80 |
| 100 | + (solo LAN). La BD **no se toca** sin backup previo. |
| 101 | +- Desarrollo local: `PORT=8199 AUTH_PASS=… node server/src/index.js` desde |
| 102 | + `server/` (la BD de `server/data/` es una copia de desarrollo). |
| 103 | +- Si la contraseña de admin se pierde: `curl -X POST |
| 104 | + http://127.0.0.1:<puerto>/api/auth/recover` **desde el propio host** (SSH) |
| 105 | + → devuelve una temporal. No funciona a través de proxy. |
| 106 | +- Actualizar = desplegar el build nuevo y reiniciar el servicio; la BD y el |
| 107 | + `.env` (`/opt/helios/`) sobreviven siempre. |
| 108 | + |
| 109 | +## Licencia |
| 110 | + |
| 111 | +Privada (repo sin publicar). Si algún día se publica, la casa usa AGPL-3.0 — |
| 112 | +pero esa decisión se toma entonces, no ahora. |
0 commit comments