Ir al contenido

← Todas las funcionalidades

Riego agrícola automatizadoRaspberry Pi (Docker)MySQLDatalogging

Un histórico de alarmas en MySQL escrito por Node-RED

Una alarma que nadie puede revisar después es como si nunca hubiera existido. Este ejemplo construye un histórico de alarmas en MySQL sobre una Raspberry Pi: una tabla alarms que guarda cada evento (dispositivo, entrada, mensaje, marca de tiempo) y una tabla alarms_describe que define qué entrada digital corresponde a qué mensaje y si está habilitada. Node-RED inserta los eventos con una consulta parametrizada y un frontend Laravel lee el histórico. Es la pista de auditoría de un despliegue real de riego automatizado.

Definiciones y eventos son tablas distintas

alarms_describe guarda una fila por cada entrada digital supervisada — su mensaje y un flag de habilitación — mientras que alarms solo almacena lo que realmente ha ocurrido. Desactivar una alarma ruidosa es un único UPDATE, sin redesplegar el flujo y sin reescribir el histórico. Una clave única sobre (devices_id, input) mantiene limpias las definiciones en el esquema multidispositivo heredado del login de Laravel.

Inserts parametrizados desde un nodo function

El nodo function de Node-RED pone en msg.topic un INSERT con placeholders con nombre y pasa los valores en msg.payload, dejando que node-red-node-mysql haga el escapado — sin concatenar cadenas y sin superficie de inyección. El mismo mensaje continúa después hacia el formateador de Telegram, de modo que la escritura en base de datos y la notificación al móvil salen del mismo punto de detección y siempre coinciden.

Las consultas que el frontend ejecuta de verdad

El fichero incluye las dos consultas que hay detrás de las pantallas de Laravel: la lista con los últimos 50 eventos y una agregación a 30 días que une los eventos con sus definiciones para un gráfico de barras por alarma. Como el esquema se monta como script de docker-entrypoint-initdb.d en el contenedor de MySQL, una Raspberry Pi recién instalada arranca con las tablas, las definiciones iniciales y las credenciales ya en su sitio.

Un fragmento de la implementación

Tal cual del ejemplo desplegado en el Raspberry Pi (Docker) — cópialo libremente:

-- ============================================================================
-- COMPLETE EXAMPLE — Alarm history in MySQL
--
-- Hardware:  Raspberry Pi (Docker) with MySQL 8 + Node-RED + Laravel frontend
-- Based on:  automated agricultural irrigation project
--
-- Requirements:
--   - MySQL container from the stack (see docker-compose-irrigation.yml).
--   - node-red-node-mysql palette in Node-RED for the inserts.
--   - The password goes in the stack's MYSQL_PASSWORD environment variable.
--
-- Model:
--   alarms_describe  defines each possible alarm: which digital input it is
--                    tied to, the message to display and whether it is enabled.
--   alarms           event history: each trigger inserts a row with the
--                    device, the input, the message and the timestamp.
--   The Laravel frontend queries both tables for the listing and the counters.
-- ============================================================================

CREATE DATABASE IF NOT EXISTS irrigation
  CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE irrigation;

-- ----------------------------------------------------------------------------
-- Alarm definitions: one row per monitored digital input
-- ----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS alarms_describe (
  id          BIGINT AUTO_INCREMENT PRIMARY KEY,
  devices_id  CHAR(36)     NOT NULL,            -- device UUID (Raspberry Pi)
  input       VARCHAR(10)  NOT NULL,            -- digital input: I0, I1...

El ejemplo completo es un programa entero — cabecera de conexionado, setup y bucle principal — listo para adaptar a tu aplicación.

Preguntas frecuentes

¿Por qué la marca de tiempo se guarda como VARCHAR en lugar de DATETIME?

El sistema desplegado escribe cadenas ISO-8601 generadas en Node-RED, que ordenan lexicográficamente y se parsean sin esfuerzo en PHP y JavaScript. Con una columna DATETIME ganas funciones de fecha nativas; el ejemplo mantiene el campo tal como está desplegado por compatibilidad.

¿Cómo detecta Node-RED que una entrada de alarma está activa?

La pestaña de E/S sondea las entradas digitales y las compara con las definiciones habilitadas de alarms_describe. En un flanco de subida emite un único mensaje con la entrada y el texto, que alimenta tanto el INSERT en MySQL como la notificación de Telegram.

¿Pueden varios dispositivos compartir la misma base de datos?

Sí, cada fila lleva un UUID devices_id, y el frontend Laravel filtra por el dispositivo asociado a cada login de empresa. Un solo contenedor MySQL en una Raspberry Pi puede centralizar las alarmas de varios controladores de campo.

Funcionalidades relacionadas