commit 4e6884a4ad24ce40c8228ac22442f624dbe75381 Author: victor.fraile Date: Wed Mar 25 15:57:20 2026 +0000 Añadir climate-drainage-ngs/readme.md diff --git a/climate-drainage-ngs/readme.md b/climate-drainage-ngs/readme.md new file mode 100644 index 0000000..8136dbc --- /dev/null +++ b/climate-drainage-ngs/readme.md @@ -0,0 +1,137 @@ +# Vertical reusable: Climate Drainage NGS + +## Qué es + +`climate-drainage-ngs` es la vertical reusable de MESAVAULT para medición y control de drenaje en invernadero hidropónico NGS. + +No representa un nodo concreto ni un cliente concreto. Representa la solución reusable de ingeniería que permite: + +1. recibir uplinks del nodo en ChirpStack +2. decodificar correctamente el estado digital de `PA12` +3. persistir histórico y último valor en PostgreSQL +4. exponerlo en Grafana +5. cambiar remotamente perfiles del nodo: + - `TDC` + - `5VT` +6. gobernar esa lógica desde una UI web propia +7. dejar el diseño preparado para varios sensores, no para uno solo + +## Qué sí pertenece a esta vertical + +- arquitectura técnica reusable +- semántica de drenaje visible al usuario +- modelo de datos `mv_control.*` +- microservicio `drain-control` +- scheduler +- API +- UI de control +- queries base de Grafana +- criterios de operación +- archivos y rutas clave del sistema + +## Qué no pertenece a esta vertical + +No deben vivir aquí como elemento principal: + +- el hardware base del `LSN50 v2` +- el pinout genérico del nodo +- el datasheet del `XKC-Y25-V` +- el circuito físico de adaptación `LSN50 + XKC` + +Eso pertenece a: + +- `20-assets/models/dragino/lsn50-v2/` +- `25-kits/lsn50-v2-xkc-y25-v-drainage/` + +Tampoco vive aquí el despliegue singular de un cliente concreto. Eso irá en `40-clients/` cuando exista singularidad real. + +## Arquitectura consolidada + +La arquitectura correcta consolidada es: + +- OVH aloja el frontal público: + - Traefik + - Authentik + - Grafana del cliente + - routing `/control/*` + - salida por Tailscale hacia `platform-40` +- `platform-40` aloja la lógica real: + - `drain_control_api` + - `drain_control_scheduler` + - `drain01_norm` + - `drain01_pg` + - `mv_postgres_hot` + - `mv_mosquitto` + - `cs_chirpstack` +- el nodo `LSN50 + XKC` sigue siendo el extremo físico +- el dashboard del cliente vive en OVH, no en `platform-40` +- `platform-40` es backend, no frontal cliente + +## Principios de diseño que definen esta vertical + +### 1. Grafana no controla el nodo directamente +Grafana no debe enviar downlinks directamente a ChirpStack. +La lógica de control vive en un microservicio específico con API, scheduler y auditoría. + +### 2. No exponer servicios internos por IP pública +La UI no debe darse al cliente por `192.168.40.100:8088/ui`. +Debe publicarse por OVH, detrás de Traefik y Authentik, integrada en Grafana por iframe. + +### 3. No publicar alegremente en `0.0.0.0` +Con Tailscale presente, el criterio correcto es bindear explícitamente a `192.168.40.100`. + +### 4. La señal bruta no es semántica de negocio +`raw_drain_state` no debe mostrarse tal cual al usuario. +La vertical debe distinguir entre: +- señal bruta +- muestra válida +- drenaje interpretado +- estado de control +- semántica final visible al usuario + +## Componentes lógicos principales + +### Modelo de control +- `mv_control.drain_schedule` +- `mv_control.drain_downlink_audit` +- `mv_control.asset_device_map` + +### Backend +- `drain_control_api` +- `drain_control_scheduler` + +### UI +- `/ui` +- `/api/drain-window/current` +- `/api/drain-window/list` +- `/api/drain-window` +- `/api/drain-window/force-active` +- `/api/drain-window/force-auto` +- `/api/drain-window/audit` + +### Datos de proceso +- `mv_hot.drain_readings` +- `mv_hot.drain_latest` + +## Estado actual + +Esta vertical puede considerarse técnicamente válida porque ya quedó demostrado que: + +- la arquitectura de la vertical es válida +- el `LSN50 + XKC` funciona con el circuito definido +- el decoder correcto es `byte6 & 0x02` +- el downlink LoRaWAN funciona +- `set_tdc` y `set_5vt` funcionan por radio +- la micro-API y el scheduler funcionan +- la UI funciona +- PostgreSQL persiste correctamente +- ya no se confunden muestras de reposo con drenaje real + +## Referencias cruzadas + +- kit físico validado: `25-kits/lsn50-v2-xkc-y25-v-drainage/` +- activo base del nodo: `20-assets/models/dragino/lsn50-v2/` +- plataforma backend: `10-platforms/homelab/platform-40/` +- frontal/tenant: `10-platforms/ovh-cloud/` +- BookStack: `pendiente_de_crear` +- Vaultwarden: `pendiente_de_crear` \ No newline at end of file