# Sistema de Monitoreo de Parámetros Fisicoquímicos para Fotobiorreactor **Plataforma de hardware:** Raspberry Pi 4 Model B **Estado del proyecto:** Desarrollo activo — Integración de hardware en curso (Fase 9) **Pila tecnológica:** C, Node.js, Express, Vanilla JavaScript, Nginx **Protocolo de comunicación físico:** I²C (Inter-Integrated Circuit), 100 kHz — 400 kHz --- ## 1. Resumen Ejecutivo Este repositorio documenta la arquitectura de software y las especificaciones de diseño de hardware de un sistema de adquisición de datos (DAQ) en tiempo real orientado a fotobiorreactores de escala de laboratorio. El proyecto se inició como un sistema de medición de temperatura de precisión basado en el módulo **EZO-RTD™** de Atlas Scientific y una sonda de platino PT1000; sin embargo, ha evolucionado en una plataforma integral de monitoreo que gestiona de forma simultánea cuatro parámetros fisicoquímicos críticos para el control de cultivos fotosintéticos. Los cuatro parámetros monitoreados y los módulos OEM asociados son los siguientes: | Parámetro | Módulo EZO | Dirección I²C | Unidad de medida | |---|---|---|---| | Temperatura | EZO-RTD™ (ISCCB-2) | `0x66` | °C | | Potencial de Hidrógeno | EZO-pH™ | `0x63` | pH | | Oxígeno Disuelto | EZO-DO™ | `0x61` | mg/L | | Conductividad Eléctrica | EZO-EC™ | `0x64` | µS/cm | La arquitectura del sistema implementa una topología de red distribuida localmente, separando de forma explícita las responsabilidades en cuatro capas: presentación (frontend), enrutamiento (Nginx), lógica de negocio y API (Node.js/Express) y adquisición de datos en hardware (demonios en C). Este diseño por capas garantiza la extensibilidad del sistema y permite la sustitución o incorporación de nuevos módulos sensores sin alterar la lógica de presentación. --- ## 2. Pila Tecnológica ### 2.1. Capa de Presentación (Frontend) - **Lenguaje:** Vanilla JavaScript ES6+, HTML5, CSS3 puro - **Biblioteca de visualización:** Chart.js (entregada vía CDN) - **Biblioteca de exportación tabular:** SheetJS (`xlsx.full.min.js`, vía CDN) - **Ciclo de actualización de lecturas en vivo:** 1000 ms (intervalo de *polling*) - **Ciclo de actualización de tendencias históricas:** 10 000 ms - **Idioma de la interfaz:** Español neutro ### 2.2. Capa de Enrutamiento y Proxy - **Servidor:** Nginx - **Puerto de entrada:** `8888` - **Función:** Entrega de archivos estáticos del frontend y proxy inverso transparente hacia el puerto `3000` para el prefijo `/api/` ### 2.3. Capa de Lógica de Negocio y API - **Entorno de ejecución:** Node.js (≥ v18) - **Framework HTTP:** Express v5 - **Puerto de escucha:** `3000` - **Dependencias de producción:** `express ^5.2.1`, `cors ^2.8.6` ### 2.4. Capa de Adquisición de Datos (Hardware) - **Lenguaje:** C (estándar C99) - **Interfaz de hardware:** Bus I²C del sistema operativo Linux mediante `/dev/i2c-1` - **Encabezados del sistema utilizados:** ``, `` - **Sistema de construcción:** GNU Make --- ## 3. Estructura del Directorio Fuente ```text / ├── api/ │ └── server.js # Servidor Express: endpoints REST y parser léxico EZO │ ├── config/ │ ├── alarms.json # Umbrales operativos configurables por variable │ └── sensors.json # Metadatos declarativos de los módulos EZO (dirección I²C, habilitación) │ ├── data/ │ ├── EZORTD.json # Vector de estado actual: temperatura (escrito por el demonio C) │ ├── EZOPH.json # Vector de estado actual: pH │ ├── EZODO.json # Vector de estado actual: oxígeno disuelto │ └── EZOEC.json # Vector de estado actual: conductividad eléctrica │ ├── frontend/ │ ├── index.html # Punto de entrada del dashboard de monitoreo │ ├── dashboard.css # Hoja de estilos responsiva del sistema │ ├── dashboard.js # Lógica principal: polling, evaluación de alarmas, gráficas │ ├── ezo-service.js # Consola EZO y panel de calibración por sensor │ ├── export-service.js # Serialización de datos históricos a formato CSV │ └── export-excel.js # Generación de reportes multipagina en formato XLSX │ ├── logs/ │ ├── temperature.csv # Historial persistente de temperatura (escrito por el demonio) │ ├── ph.csv # Historial persistente de pH │ ├── do.csv # Historial persistente de oxígeno disuelto │ └── ec.csv # Historial persistente de conductividad eléctrica │ ├── sensors/ │ ├── EZORTD/ │ │ ├── ezortd.h # API pública: constante de dirección I²C y firma de getTemperature() │ │ ├── ezortd.c # Implementación del protocolo I²C para el EZO-RTD │ │ ├── main.c # Ejecutable de lectura única (one-shot), salida JSON a stdout │ │ ├── ezortd_daemon.c # Demonio de lectura continua: escribe JSON y appends CSV │ │ └── Makefile # Sistema de construcción del módulo RTD │ │ │ ├── EZOPH/ │ │ ├── ezoph.h # API pública del módulo pH │ │ ├── ezoph.c # Implementación del protocolo I²C para el EZO-pH │ │ ├── main.c # Ejecutable de lectura única │ │ └── Makefile │ │ │ ├── EZODO/ │ │ ├── ezodo.h # API pública del módulo DO │ │ ├── ezodo.c # Implementación del protocolo I²C para el EZO-DO │ │ ├── main.c # Ejecutable de lectura única │ │ └── Makefile │ │ │ └── EZOEC/ │ ├── ezoec.h # API pública del módulo EC │ ├── ezoec.c # Implementación del protocolo I²C para el EZO-EC │ ├── main.c # Ejecutable de lectura única │ └── Makefile │ ├── package.json # Manifiesto de dependencias Node.js ├── package-lock.json # Árbol de dependencias resuelto y bloqueado ├── README.md # Este documento ├── ARCHITECTURE.md # Especificación técnica de la arquitectura del sistema └── PROJECT_STATUS.md # Estado de hitos, riesgos y fases pendientes ``` --- ## 4. Instrucciones de Despliegue ### 4.1. Requisitos Previos - Node.js v18 o superior instalado en el sistema anfitrión - Nginx instalado (`sudo apt install nginx` en sistemas Debian/Ubuntu) - Acceso al directorio raíz del repositorio ### 4.2. Inicialización del Servidor de Backend (Node.js) Desde el directorio raíz del repositorio, instalar las dependencias de producción y levantar el servidor: ```bash npm install node api/server.js ``` El servidor quedará escuchando en `http://localhost:3000`. Verificar el inicio exitoso con el mensaje: ``` [MOCK SERVER] Backend Node.js corriendo en http://localhost:3000 ``` Para desarrollo local, abrir directamente: ```text http://localhost:3000/frontend/index.html ``` Express sirve las carpetas necesarias para el dashboard. Nginx sigue siendo la opcion recomendada para el despliegue final en Raspberry Pi. Para ejecución persistente en segundo plano se recomienda el gestor de procesos `pm2`: ```bash npm install -g pm2 pm2 start api/server.js --name fotobiorreactor-api pm2 save ``` ### 4.3. Configuración del Proxy Inverso Nginx Crear o editar el bloque de servidor activo de Nginx. En sistemas Debian-based, el archivo de configuración canónico es `/etc/nginx/sites-available/fotobiorreactor`: ```nginx server { listen 8888; server_name localhost; # Raíz del contenido estático: directorio raíz del repositorio root /ruta/absoluta/al/repositorio; index frontend/index.html; # Entrega de archivos estáticos del frontend location / { try_files $uri $uri/ =404; } # Proxy inverso transparente hacia el backend Node.js location /api/ { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } ``` Habilitar el sitio y recargar el servicio: ```bash sudo ln -s /etc/nginx/sites-available/fotobiorreactor /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx ``` ### 4.4. Acceso al Cliente Abrir un navegador web y dirigirse a: ``` http://localhost:8888/frontend/index.html ``` El dashboard inicia automáticamente el ciclo de polling de los archivos JSON ubicados en `data/`. La API se usa por separado para la consola de comandos simulada, las exportaciones simuladas y las operaciones administrativas. La consola EZO detecta automaticamente el transporte disponible. En Raspberry Pi puede enviar comandos reales por I2C mediante `sensors/EZOCommand/EZO_COMMAND`; en otros equipos permanece en modo demo. Consulte `docs/EZO_COMMANDS.md`. ### 4.5. Construcción de los Demonios en C (Hardware Real) Para compilar los controladores de hardware en la Raspberry Pi, ejecutar el siguiente procedimiento por módulo sensor (se ilustra con el módulo RTD): ```bash cd sensors/EZORTD make ``` Esto generará el ejecutable `EZORTD`. Antes de compilar el demonio continuo (`ezortd_daemon.c`), actualizar las rutas absolutas codificadas en el código fuente para que correspondan al directorio de despliegue real en la Raspberry Pi. **Nota:** El bus I²C debe estar habilitado en la Raspberry Pi mediante `sudo raspi-config` → *Interface Options* → *I2C* → *Enable*. Se recomienda agregar el usuario de ejecución al grupo `i2c` para evitar la ejecución con privilegios de superusuario: ```bash sudo usermod -aG i2c $USER ```