Un panel de energía local puede arrancar con tres piezas: un broker MQTT, un flujo de n8n y una base de datos de series temporales. El flujo recibe una lectura de potencia, la convierte en un registro y la envía a InfluxDB; desde allí se consulta y representa la serie.
La plantilla de n8n para monitorización IoT ya combina un MQTT Trigger, un nodo de código y una petición HTTP a InfluxDB. Su ejemplo usa un ESP32 con sensor DHT22, pero la propia plantilla plantea adaptar el flujo a otros dispositivos MQTT. En este tutorial usaremos lecturas de voltaje, corriente y potencia, como las que admite el monitor energético de referencia.
El recorrido será MQTT → n8n → InfluxDB. El proyecto de monitorización energética de referencia sirve los datos del panel mediante API; aquí el foco está en recibir las lecturas y enviarlas a InfluxDB.
flowchart LR A["Publicador de prueba"] --> B["Mosquitto local"] B --> C["MQTT Trigger de n8n"] C --> D["Validar y convertir"] D --> E["HTTP Request"] E --> F["InfluxDB"] F --> G["Panel de consultas"]
Arranque local con Docker
Este Compose levanta n8n, Mosquitto e InfluxDB en una red común. Mosquitto escucha en el puerto local 1883, el broker usado también por el ejemplo de monitorización energética disponible en GitHub. La configuración de acceso anónimo es adecuada solo para esta demostración local: el repositorio advierte que un despliegue de producción debe exigir autenticación, ACL por tema y TLS.
services:
mosquitto:
image: eclipse-mosquitto:2
ports:
- "1883:1883"
command: ["mosquitto", "-c", "/mosquitto-no-auth.conf"]
volumes:
- ./mosquitto.conf:/mosquitto-no-auth.conf:ro
n8n:
image: n8nio/n8n:latest
ports:
- "5678:5678"
volumes:
- n8n_data:/home/node/.n8n
influxdb:
image: influxdb:2
ports:
- "8086:8086"
volumes:
- influxdb_data:/var/lib/influxdb2
volumes:
n8n_data:
influxdb_data:
Guarda el archivo como compose.yaml. Mosquitto necesita una configuración explícita para este arranque:
listener 1883
allow_anonymous true
Levanta los servicios con docker compose up -d. Para conectar n8n con InfluxDB, necesitarás la dirección y el puerto de la base de datos, el bucket, el identificador de organización y un token; el ejemplo de n8n cita esos datos para su petición HTTP. El puerto de InfluxDB en este Compose es el 8086.
Publica una lectura MQTT de prueba
El tema seguirá el patrón devices/{device_uid}/measurements, documentado por el monitor energético de GitHub. El identificador del dispositivo va en el tema; el JSON contiene las medidas y la marca de tiempo. Para simular un dispositivo basta con publicar una lectura manual desde Python usando Paho MQTT.
python -m pip install paho-mqtt
import json
from datetime import datetime, timezone
import paho.mqtt.client as mqtt
broker = "localhost"
topic = "devices/DEV-002/measurements"
reading = {
"voltage": 230.4,
"current": 2.8,
"power": 645.1,
"timestamp": datetime.now(timezone.utc).isoformat()
}
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
client.connect(broker, 1883, 60)
client.publish(topic, json.dumps(reading), qos=0)
client.disconnect()
print("Lectura publicada:", reading)
El tema y los campos de la lectura coinciden con el esquema de telemetría del repositorio de IoT Energy Monitor. Publica el mensaje después de activar el flujo; si lo envías antes, el trigger todavía no estará escuchando.
Configura el MQTT Trigger de n8n
Crea un workflow nuevo y añade un nodo MQTT Trigger. En las credenciales, apunta al host mosquitto y al puerto 1883: dentro de Docker, n8n debe usar el nombre del servicio, no localhost. Suscríbelo a devices/+/measurements, que recoge las lecturas de cualquier dispositivo con esa estructura.
La documentación de n8n describe MQTT como un protocolo ligero de publicación y suscripción y remite la autenticación de este nodo a sus credenciales MQTT. Para este Compose local, el broker se ha dejado sin autenticación; no reutilices esa configuración fuera de una máquina de pruebas.
Añade un nodo Code después del trigger. Como los nombres de las propiedades de salida pueden depender de cómo llegue el mensaje al nodo, primero publica una lectura y revisa el elemento de entrada en la ejecución de n8n. El código siguiente admite el JSON ya interpretado o una cadena en message o payload; rechaza campos ausentes y valores negativos antes de escribir.
const input = $input.first().json;
let reading = input;
if (typeof input.message === 'string') {
reading = JSON.parse(input.message);
} else if (typeof input.payload === 'string') {
reading = JSON.parse(input.payload);
} else if (input.message && typeof input.message === 'object') {
reading = input.message;
}
const required = ['voltage', 'current', 'power', 'timestamp'];
for (const key of required) {
if (!(key in reading)) {
throw new Error(`Falta el campo ${key}`);
}
}
for (const key of ['voltage', 'current', 'power']) {
if (typeof reading[key] !== 'number' || reading[key] < 0) {
throw new Error(`Medida inválida: ${key}`);
}
}
const timestamp = Date.parse(reading.timestamp);
if (!Number.isFinite(timestamp)) {
throw new Error('La marca de tiempo no es válida');
}
return [{
json: {
voltage: reading.voltage,
current: reading.current,
power: reading.power,
timestampSeconds: Math.floor(timestamp / 1000)
}
}];
Envía los datos a InfluxDB
Conecta un nodo HTTP Request al Code. La plantilla de n8n usa ese nodo para enviar los datos a InfluxDB y especifica que hacen falta la URL y el puerto de la base de datos, el bucket, el identificador de organización y un token. Configura esos valores según la instancia local y el formato de escritura que admita.
El Code siguiente prepara una cadena de datos para el cuerpo de la petición. Ajusta el nodo HTTP Request a la configuración de escritura de tu instancia y pasa esa cadena como cuerpo.
const { voltage, current, power, timestampSeconds } = $input.first().json;
const line = `energy,device=DEV-002 voltage=${voltage},current=${current},power=${power} ${timestampSeconds}`;
return [{ json: { line } }];
El ejemplo fija el dispositivo como DEV-002, que identifica al medidor MQTT en el proyecto de referencia. Para distinguir varios equipos, usa un identificador controlado por el tema y valida ese valor antes de incorporarlo como etiqueta; no insertes texto recibido sin comprobarlo.
Comprueba la serie y consulta el panel
Activa el workflow y vuelve a ejecutar el publicador. Comprueba en InfluxDB que las lecturas se hayan almacenado; después consulta los datos y represéntalos en el panel según la configuración de tu instancia.
La plantilla de n8n para sensores remotos también envía desde el flujo a InfluxDB mediante HTTP y señala que sus datos pueden mostrarse en tiempo real. Aquí el almacenamiento mantiene voltaje, corriente y potencia por separado; las lecturas instantáneas no bastan por sí solas para afirmar el consumo acumulado en kWh. El monitor energético de referencia calcula esa energía integrando muestras consecutivas y omite intervalos demasiado separados, en vez de asumir que una única lectura se mantuvo constante.
Fallos habituales
Si el trigger no recibe nada, revisa primero el host del broker: en el contenedor de n8n es mosquitto, mientras que el publicador ejecutado en el equipo usa localhost. Comprueba también el tema exacto y que el workflow esté activo.
Si el flujo llega al HTTP Request pero InfluxDB lo rechaza, verifica organización, bucket, token y que el cuerpo tenga el formato que espera tu instancia. Una marca de tiempo inválida o una lectura con medidas negativas debe fallar en el nodo Code, antes de intentar almacenarla.
El broker de este ejemplo queda configurado para una prueba local. Si pasa a formar parte de un despliegue real, sustituye el acceso anónimo por autenticación, permisos por tema y TLS; esas medidas también figuran entre las recomendaciones de seguridad del proyecto de monitorización energética.