Los flujos Node-RED S7 son una forma práctica de sacar datos de PLC Siemens S7-1200, S7-1500 y de los más antiguos S7-300/400 y llevarlos a MQTT sin apenas modificar el programa del PLC. En este tutorial prepararás el PLC en TIA Portal, leerás variables de bloques de datos con node-red-contrib-s7 y las publicarás como JSON en un broker MQTT cada vez que cambien. También añadirás una ruta de escritura protegida para las consignas y aprenderás las reglas de direccionamiento que provocan la mayoría de los fallos en el primer intento.
Cómo se comunica Node-RED con un PLC S7
node-red-contrib-s7 utiliza el protocolo de comunicación S7 (ISO-on-TCP, puerto 102), el mismo que usan las herramientas de ingeniería y los HMI de Siemens. Node-RED actúa como cliente: se conecta a la CPU, lee una lista de direcciones con un tiempo de ciclo fijo y, opcionalmente, escribe valores de vuelta. No hace falta hardware adicional ni licencia en el PLC, pero la CPU debe permitir este tipo de acceso, que las CPU modernas bloquean por defecto.
Una vez que los valores están en Node-RED, MQTT se encarga de la distribución. En lugar de que cada panel, historiador y herramienta de analítica se conecte al PLC, un único gateway lo lee y un broker entrega valores con nombre a todos los suscriptores. Si quieres una comparativa más amplia de enfoques, la guía de Siemens S7 y MQTT cubre también los clientes MQTT nativos del PLC y los gateways comerciales.
Paso 1: prepara el PLC en TIA Portal
Para las CPU S7-1200 y S7-1500, haz dos cambios y cárgalos en el PLC:
- Permite PUT/GET. Abre las propiedades de la CPU, ve a Protection & Security → Connection mechanisms y activa "Permit access with PUT/GET communication from remote partner".
- Desactiva el acceso optimizado al bloque en cada bloque de datos que Node-RED deba leer. Haz clic derecho en el bloque de datos, abre Properties → Attributes y desmarca "Optimized block access". Compila el bloque; ahora muestra offsets fijos para cada variable.
El segundo paso es el que da sentido a direcciones absolutas como DB10,REAL0. Con el acceso optimizado, el PLC reorganiza internamente las variables y el protocolo S7 no puede direccionarlas por offset.
El acceso PUT/GET es un compromiso de seguridad: cualquier cliente que alcance el puerto 102 puede leer y escribir esas áreas. Mantén el PLC en una red OT aislada, deja que solo el gateway llegue a él y utiliza preferiblemente un bloque de datos dedicado que contenga únicamente los valores que quieres exponer.
Las CPU S7-300 y S7-400 no necesitan estos ajustes. Usa para ellas rack 0 y slot 2, en lugar del slot 1 de las familias más recientes.
Paso 2: diseña un bloque de datos para el gateway
Crea un bloque de datos no optimizado, por ejemplo DB10 "GatewayData", y copia en él desde tu programa los valores que quieras publicar. Un bloque dedicado mantiene estable la interfaz aunque cambie el programa principal.
| Variable | Tipo | Offset | Dirección en node-red-contrib-s7 |
|---|---|---|---|
| temperature | Real | 0.0 | DB10,REAL0 |
| speed | Int | 4.0 | DB10,INT4 |
| running | Bool | 6.0 | DB10,X6.0 |
| partCount | DInt | 8.0 | DB10,DINT8 |
| setpoint | Real | 12.0 | DB10,REAL12 |
Las demás áreas usan la misma sintaxis: M0.0 y MW10 para marcas, I0.0 e IW64 para entradas, Q0.1 para salidas y DB10,S20.16 para una cadena en el offset 20 con una longitud máxima de 16. Toma siempre los offsets del bloque de datos compilado en TIA Portal, nunca contándolos a mano.
Paso 3: instala y configura node-red-contrib-s7
Instala el paquete:
cd ~/.node-red
npm install node-red-contrib-s7
# restart Node-RED afterwards
Añade un nodo s7 in y crea una nueva configuración de endpoint:
- Transporte: Ethernet (ISO-on-TCP)
- Dirección: la IP del PLC, por ejemplo
192.168.0.10, puerto102 - Modo: Rack/Slot, rack
0, slot1(S7-1200/1500) - Tiempo de ciclo:
1000ms - Timeout:
2000ms
En la pestaña Variables, añade cada fila de la tabla anterior con un nombre y una dirección. Después configura el propio nodo s7 in:
- Modo: "All variables", que emite un único mensaje cuyo payload es un objeto con todas las variables.
- Activa "Emit only when value changes" para que los ciclos sin cambios no generen mensajes.
Despliega y añade un nodo debug. Deberías ver payloads como {"temperature":61.4,"speed":1480,"running":true,"partCount":20391,"setpoint":60}. El estado del nodo muestra "online" cuando la conexión está sana.
Paso 4: da forma a los datos y publícalos en MQTT
El objeto en bruto está casi listo para MQTT, pero conviene añadir una marca de tiempo, redondear los decimales y construir un topic que refleje la posición de la máquina en la planta. Un nodo function se encarga de ello:
// Function node "s7 to mqtt"
const v = msg.payload;
if (typeof v !== "object" || v === null) {
return null;
}
const round = (x, d) => Math.round(x * Math.pow(10, d)) / Math.pow(10, d);
msg.topic = "connectmq/demo/a7f3k2/plant1/line3/press2/telemetry";
msg.payload = {
temperature: round(Number(v.temperature), 1),
speed: Number(v.speed),
running: v.running === true,
partCount: Number(v.partCount),
setpoint: round(Number(v.setpoint), 1),
ts: Date.now()
};
return msg;
Conéctalo a un nodo mqtt out con el campo de topic vacío. Para pruebas, usa broker.connectmq.com en el puerto 1883 con un client ID único; es el servidor MQTT público gratuito. Sustituye a7f3k2 por tu propia cadena aleatoria y nunca envíes allí datos reales de producción, porque cualquiera puede suscribirse.
Compruébalo desde una terminal:
mosquitto_sub -h broker.connectmq.com -p 1883 -i sub-s7-a7f3k2 -v \
-t 'connectmq/demo/a7f3k2/plant1/#'
Si prefieres un topic por variable, algo que encaja con los diseños de Unified Namespace, selecciona en su lugar el modo "All variables, one per message". Cada mensaje lleva entonces el nombre de la variable en msg.topic y el nodo function puede añadirlo a la ruta de la máquina.
Publica también el estado del propio gateway. Añade un nodo status limitado al nodo s7 in y publica su texto en .../press2/gateway/status con retain activado. Así los suscriptores pueden distinguir entre "la máquina se ha parado" y "el gateway ha perdido el PLC".
Paso 5: escribe consignas desde MQTT, con salvaguardas
El nodo s7 out escribe una única variable definida en la configuración del endpoint. Una ruta de comandos segura tiene este aspecto:
- Un nodo
mqtt inse suscribe a un único topic dedicado,connectmq/demo/a7f3k2/plant1/line3/press2/setpoint/set. En un sistema real debe ser un broker privado y autenticado. - Un nodo function valida el valor.
- Un nodo s7 out configurado para la variable
setpointlo escribe. - El siguiente ciclo de lectura publica la nueva consigna en la telemetría, lo que sirve de confirmación.
// Function node "validate setpoint" -> s7 out (variable: setpoint)
const MIN = 40.0;
const MAX = 80.0;
const value = Number(msg.payload);
if (!Number.isFinite(value) || value < MIN || value > MAX) {
node.warn(`Rejected setpoint ${msg.payload}; allowed ${MIN}-${MAX}`);
return null;
}
msg.payload = Math.round(value * 10) / 10;
node.status({ fill: "blue", shape: "dot", text: "wrote " + msg.payload });
return msg;
Deja la seguridad en manos del PLC. El programa del PLC debe seguir limitando la consigna e ignorarla en los modos en los que no se permiten cambios remotos. Un gateway que escribe directamente en la lógica de control sin esas comprobaciones en el PLC es un accidente esperando a ocurrir.
Solución de problemas en conexiones Node-RED S7
| Síntoma | Causa probable | Solución |
|---|---|---|
| Timeout de conexión | IP incorrecta, firewall, puerto 102 bloqueado | Haz ping al PLC y prueba el puerto 102 desde el gateway |
| Conecta, pero las lecturas fallan | PUT/GET no permitido | Actívalo en las propiedades de la CPU y carga |
| "Address out of range" o valores erróneos | El acceso optimizado al bloque sigue activo | Desmarca el atributo, recompila y usa los nuevos offsets |
| Los valores parecen desordenados | Los offsets cambiaron tras editar el DB | Vuelve a leer los offsets en TIA Portal y actualiza las variables |
| Funciona en S7-1200, no en S7-300 | Slot incorrecto | Usa rack 0, slot 2 para S7-300/400 |
| Sube la carga de la CPU del PLC | Tiempo de ciclo demasiado corto, muchas lecturas dispersas | Agrupa los valores en un DB y aumenta el tiempo de ciclo |
Una comprobación rápida del puerto desde la máquina del gateway ahorra muchas conjeturas:
# Linux: succeeds if port 102 is reachable
nc -zv 192.168.0.10 102
Lista de verificación para producción
- Usa un bloque de datos dedicado y no optimizado como interfaz del gateway.
- Restringe el acceso de red al puerto 102 únicamente al gateway.
- Publica al cambiar, con un heartbeat periódico, no en cada ciclo.
- Publica el estado del gateway como topic de estado retenido.
- Valida cada escritura en Node-RED y de nuevo en el PLC.
- Usa un broker MQTT privado con TLS y credenciales por gateway.
- Pon tus flujos bajo control de versiones para que se revisen los cambios de direcciones.
Adónde van los datos después
Con los valores del S7 en MQTT, todo lo demás se convierte en suscriptor: paneles, cálculos de OEE, historiadores y analítica en la nube, e incluso un gemelo digital 3D de la línea. El mismo enfoque sirve para otros controladores, como muestran la guía de Node-RED con Modbus y el tutorial de Node-RED con OPC UA para dispositivos Modbus y servidores OPC UA. Para una visión más amplia de cómo sacar los datos de los controladores de la planta, lee la guía del PLC a la nube.
El gateway solo se conecta hacia fuera con el broker, lo que mantiene la red OT cerrada al tráfico entrante. Un broker MQTT gestionado como ConnectMQ ofrece a ese gateway un endpoint TLS en el puerto 8883, credenciales generadas en el portal y bloqueo de IP tras intentos de inicio de sesión fallidos repetidos. ConnectMQ también reconoce topics de estilo ISA-95 como plant1/line3/press2/telemetry y lista los dispositivos por esos niveles, de modo que ves de un vistazo qué máquinas están enviando datos. Si todavía estás decidiendo la arquitectura, empieza por qué hace un broker MQTT y consulta el tutorial de Node-RED y MQTT para lo básico de los nodos MQTT.
Conecta tu gateway S7 a ConnectMQ
Regístrate en app.connectmq.com con el plan gratuito Serverless, sin tarjeta de crédito. Crea un broker, pega el usuario, la contraseña y el client ID generados en el nodo de configuración MQTT de Node-RED, activa TLS en el puerto 8883 y elimina el prefijo de demostración. Los valores de tu PLC se publicarán entonces de forma privada y podrás ver cómo llegan en el explorador de topics en vivo.
Preguntas frecuentes
¿Qué PLC Siemens funcionan con node-red-contrib-s7?
Admite S7-1200 y S7-1500, así como las CPU más antiguas S7-300 y S7-400, a través de Ethernet. Las familias más recientes necesitan el acceso PUT/GET activado y bloques de datos no optimizados.
¿Por qué Node-RED no puede leer el bloque de datos de mi S7-1500?
Lo más probable es que el bloque de datos use acceso optimizado, que no tiene offsets fijos. Desactívalo en los atributos del bloque, recompila, carga y usa los nuevos offsets en Node-RED.
¿Qué rack y slot debo usar para un PLC S7?
Usa rack 0 y slot 1 para las CPU S7-1200 y S7-1500, y rack 0 y slot 2 para la mayoría de las CPU S7-300 y S7-400.
¿Es seguro escribir valores del PLC desde MQTT?
Solo con salvaguardas: un topic de comandos dedicado en un broker autenticado, validación en Node-RED y comprobaciones de rango en el propio programa del PLC.



