Skip to content

EDD-001 — Sistema de Control Ambiental End-to-End ​

Metadata ​

CampoValor
AutorAlejandro Maturana
EstadoACCEPTED
Fecha2026-06-06
Versión1.0.0
ADRs relacionadosADR-001, ADR-002, ADR-003, ADR-004, ADR-005, ADR-008, ADR-012
RFC relacionados—

1. Problema / Contexto ​

El cultivo de hongos adaptógenos requiere control preciso de 4 variables ambientales simultáneas: temperatura, humedad relativa, CO₂ y ventilación. Las soluciones existentes en el mercado son o demasiado costosas (sistemas de HVAC industrial), o demasiado limitadas (controladores de temperatura simples sin inteligencia).

Mush2 nace como una plataforma IoT accesible que permite a productores ocasionales y laboratorios micológicos automatizar el microclima de sus cámaras de cultivo mediante recetas configurables, telemetría en tiempo real y alertas proactivas.

El desafío de diseño es construir un sistema distribuido (firmware embebido + backend cloud + frontend web) que sea confiable en condiciones de red inestable, seguro para operar sin supervisión constante, y extensible a múltiples cámaras.


2. Objetivos ​

  • Medir temperatura, humedad, CO₂ y VOC con ciclos de lectura ≤ 10 segundos
  • Controlar 4 actuadores (ventilación, calefacción, humidificación, iluminación) con latencia de comando ≤ 5 segundos extremo a extremo
  • Operar en modo degradado (actuadores según última receta + histéresis local) si el backend no es alcanzable
  • Soportar recetas de cultivo con múltiples fases (incubación, primordia, fructificación, cosecha)
  • Proveer dashboard en tiempo real accesible desde cualquier navegador moderno
  • Garantizar seguridad del sistema sin intervención del operador (watchdog, fail-safe overheat, safe mode)

3. No-objetivos (Out of Scope — v1) ​

  • Control de CO₂ activo (inyección de CO₂) — solo ventilación pasiva
  • Sincronización entre múltiples cámaras con lógica compartida (cubierta en Fase 8)
  • Aplicación móvil nativa (cubierta en Fase 17)
  • Predicción ML de ciclos de cultivo (cubierta en Fase 15)
  • Certificación regulatoria o exportación (cubierta en Fase 18)

4. Alternativas consideradas ​

4.1 Protocolo de comunicación Firmware → Backend ​

OpciónProsContrasDecisión
HTTP Polling (elegida)Simple, firewall-friendly, sin broker externo, funciona en ESP32 sin librerías complejasMayor latencia que push, overhead por polling frecuente✅ Elegida — ADR-008
MQTT bidireccionalLatencia mínima, push de comandosRequiere broker siempre disponible; si broker cae, firmware queda sin comandos❌ Descartado para telemetría
WebSocketBidireccional, eficienteComplejo en firmware, requiere reconexión robusta❌ Descartado
HTTP/2 + Server PushEficienteNo soportado en Arduino Core ESP32 de forma nativa❌ Descartado

Nota: MQTT sí se usa en el backend para propagar eventos al frontend vía SSE. El firmware usa HTTP exclusivamente.

4.2 Hardware del microcontrolador ​

OpciónProsContrasDecisión
ESP32-S3 (elegido)Dual-core, FreeRTOS, NVS nativo, particiones OTA duales, crypto hardwareMás costoso que ESP8266✅ Elegido — ADR-001
ESP8266Barato, amplio soporteSingle-core, sin OTA dual, sin NVS robusto, RTOS limitado❌ Usado en v1, reemplazado en v2
Arduino Nano IoTFamiliarWiFi limitado, sin FreeRTOS completo❌ Descartado
Raspberry Pi ZeroPotente, LinuxConsumo alto, boot lento, no adecuado para RTOS❌ Descartado

4.3 Base de datos ​

OpciónProsContrasDecisión
PostgreSQL (elegida)Relacional, transaccional, JSONB, TimescaleDB compatibleRequiere servidor✅ Elegida — ADR-005
InfluxDBOptimizada para time-seriesNo relacional, dificulta CRUD de recetas/usuarios❌ Descartado
SQLiteSin servidorNo escala a múltiples conexiones simultáneas❌ Descartado
MongoDBFlexibleSin transacciones ACID en versiones anteriores❌ Descartado

5. Solución propuesta ​

Arquitectura de 3 capas ​

┌─────────────────────────────────────────────────────────┐
│                        INTERNET                          │
│                                                          │
│  ┌─────────────────┐    ┌──────────────────────────────┐ │
│  │   Firmware       │    │         Backend               │ │
│  │   ESP32-S3       │    │   Node.js + Express 5         │ │
│  │                  │    │                               │ │
│  │  AHT21  ENS160  │    │  API REST (JWT)               │ │
│  │  SSR 4ch         │    │  Motor de reglas             │ │
│  │  FreeRTOS 6t     │    │  MQTT bridge                 │ │
│  │                  │    │  WebSocket/SSE               │─┼──► DB PostgreSQL
│  └────────┬─────────┘    └──────────────┬───────────────┘ │
│           │ HTTP Polling                │                  │
│           │ (telemetría + comandos)     │ MQTT             │
│           │                        ┌───▼───────┐          │
│           │                        │  Broker   │          │
│           │                        │  MQTT     │          │
│           │                        └───────────┘          │
│           │ HTTP GET                    │ SSE              │
│           └──────► ThingSpeak     ┌────▼──────────┐       │
│                                   │   Frontend    │       │
│                                   │  React + Vite │       │
│                                   └───────────────┘       │
└─────────────────────────────────────────────────────────┘

Flujo de telemetría ​

Sensor AHT21/ENS160 (cada 8s)
  └──► HTTP POST /api/v1/telemetry → Backend → PostgreSQL
  └──► HTTP GET → ThingSpeak (respaldo visual)
       └──► SSE → Frontend (tiempo real)

Flujo de control ​

Usuario → Frontend → REST PATCH /actuators/:channel
  └──► Backend → MQTT publish → Broker
       └──► Backend suscribe ACK → SSE → Frontend
Firmware (polling cada 500ms) → GET /poll → recibe comando
  └──► SSR actuador → POST /ack → Backend

Motor de reglas ​

Backend ControlEngine (cada 60s)
  ├── Lee setpoints de receta activa
  ├── Compara con última telemetría
  ├── Evalúa reglas de histéresis
  └── Publica comando MQTT si necesario

Firmware (local, sin red)
  ├── Histéresis local T/H/CO₂
  ├── Temporizadores minOn/maxOn
  └── Modo DEGRADED si pierde HTTP

6. Impacto en componentes ​

ComponenteImpactoCambios requeridos
FirmwareAlto6 tareas FreeRTOS, HTTP polling, state machine 8 estados, OTA v3
BackendAltoMotor de reglas, WebSocket/SSE, MQTT bridge, RBAC, PostgreSQL
FrontendMedioReact 18, SSE, Chart.js, dashboard en tiempo real
Base de datosAlto18+ entidades relacionadas, backup diario
InfraestructuraBajoPostgreSQL local (dev), broker MQTT público temporal

7. Plan de implementación ​

Ver docs/roadmap/roadmap.md — Fases 0–7 completadas.

La implementación sigue el principio "contratos primero, slices verticales después":

  • Fase 0: Contratos y arquitectura
  • Fases 1–3: Cadena de telemetría + control + sensores
  • Fases 4–5: Automatización + hardening
  • Fases 6–7: Multiusuario + producción

8. Métricas de éxito ​

MétricaObjetivoEstado
Ciclo de telemetría≤ 10s✅ 8s
Latencia de comando E2E≤ 5s✅ ~1s (polling 500ms)
API respuesta (p95)≤ 200ms✅
Operación sin red✅ modo DEGRADED✅ histéresis local
Uptime firmware> 99% con watchdog✅ TWDT + SWDT
Cobertura tests backend> 60%🟡 En progreso

9. Riesgos y mitigaciones ​

RiesgoProb.ImpactoMitigación
Red inestable → firmware sin comandosAltaMedioModo DEGRADED + histéresis local
Sensor falla → actuadores descontroladosMediaAltoFail-safe overheat (ADR-010), SAFE mode
Backend caído → frontend sin datosBajaMedioThingSpeak como respaldo visual
OTA falla → dispositivo inoperableBajaCríticoRollback nativo del bootloader (ADR-014)
Credenciales expuestasBajaCríticoNVS, .env, config.h nunca commiteado

10. Referencias ​

Mush2 — Sistema IoT de control ambiental