Node-RED

Nodos switch y change de Node-RED para enrutar mensajes MQTT

Usa el nodo switch de Node-RED para dividir el tráfico MQTT por topic y valor, y después da forma a cada rama con el nodo change antes de republicar. Incluye un flujo importable y un plan de pruebas en un broker gratuito.

Nodo switch de Node-RED dividiendo mensajes MQTT en tres salidas que alimentan nodos change y un nodo mqtt out
Pruébalo en tu propio broker MQTTConsigue un broker MQTT privado y gestionado con el plan Free y empieza con ejemplos de código listos para usar.
Pruébalo gratis Ejemplos de código Sin tarjeta

El nodo switch de Node-RED es la forma más sencilla de enviar cada mensaje MQTT por el camino correcto: las temperaturas a una rama, la humedad a otra y los valores fuera de rango a una alerta. En este tutorial combinarás el nodo switch con el nodo change para enrutar mensajes por topic y por valor, remodelar payloads sin escribir JavaScript y republicar alertas limpias en un broker. Terminarás con un flujo importable que puedes probar en dos minutos.

Por qué enrutar mensajes MQTT dentro de Node-RED

Un único nodo mqtt in suscrito a un comodín como sensors/# recibe todo lo que hay por debajo de ese nivel. Es cómodo, porque una suscripción sustituye a decenas, pero implica que cada nodo posterior ve todos los mensajes. Sin enrutamiento acabas escribiendo un gran nodo function lleno de sentencias if que nadie quiere mantener.

El nodo switch lo resuelve de forma declarativa. Evalúa una propiedad del mensaje frente a una lista de reglas y envía el mensaje por el puerto que coincide. Después, el nodo change edita el mensaje en cada rama: asigna un nuevo topic, mueve un campo, elimina ruido o calcula un valor con una expresión JSONata. Juntos cubren la mayoría de las tareas de enrutamiento, y la lógica queda visible en el editor, donde un compañero puede leerla de un vistazo.

Si eres nuevo en el propio editor, empieza por el tutorial de Node-RED MQTT y vuelve aquí cuando tengas funcionando una conexión con el broker.

Cómo funciona el nodo switch de Node-RED

Abre un nodo switch y verás tres ajustes importantes.

  1. Property. El valor que se comprueba. Por defecto es msg.payload, pero puede ser msg.topic, un campo anidado como msg.payload.value, una variable de contexto flow o global, o una expresión JSONata.
  2. Rules. Cada regla crea un puerto de salida. Las reglas se evalúan en orden.
  3. Modo de comprobación. "Checking all rules" envía el mensaje por todos los puertos que coinciden. "Stopping after first match" lo envía solo por la primera coincidencia. Para enrutar casi siempre querrás la segunda opción, para que un valor nunca acabe por accidente en dos ramas.

Los tipos de regla que más usarás se enumeran a continuación.

Regla Qué comprueba Uso típico en MQTT
==, != Igualdad exacta Estado de un dispositivo, como ON u OFF
<, <=, >, >= Comparación numérica Alertas por umbral
is between Rango inclusivo Banda de funcionamiento normal
contains Subcadena El topic contiene /alarm/
matches regex Expresión regular El topic termina en /temperature
is true / is false Booleano Indicadores de puerta abierta
is null / is not null Valores ausentes Descartar lecturas incompletas
is of type string, number, object, buffer... Rechazar payloads mal formados
has key El objeto tiene una propiedad Campos opcionales
JSONata exp Cualquier expresión que devuelva true Condiciones con varios campos
otherwise No coincidió nada más Cajón de sastre y registro

Añade siempre una regla otherwise al final. No cuesta nada y es el primer sitio donde mirarás cuando un mensaje parezca desaparecer.

Cómo funciona el nodo change

El nodo change aplica una lista de operaciones al mensaje, en orden:

  • Set: asigna a una propiedad una cadena, un número, un booleano, JSON, otra propiedad del mensaje, un valor de contexto, una marca de tiempo o una expresión JSONata.
  • Change: modifica parte de una cadena, con texto literal o una expresión regular, algo muy útil para reescribir topics.
  • Delete: elimina una propiedad, por ejemplo un campo de depuración que un dispositivo incluye en cada mensaje.
  • Move: mueve una propiedad a una nueva ubicación, como subir msg.payload.value a msg.payload.

JSONata es lo que hace potente al nodo change. Dentro de una expresión, payload y topic se refieren a msg.payload y msg.topic, así que $round(payload.value * 9 / 5 + 32, 1) convierte Celsius a Fahrenheit y $split(topic, "/")[4] extrae el quinto nivel del topic. Obtienes valores calculados sin un nodo function y sin salir del editor visual.

El flujo de ejemplo: enruta por topic y después por valor

El flujo que vas a importar hace lo siguiente:

  1. Se suscribe a connectmq/demo/a7f3k2/sensors/# en el servidor MQTT público gratuito con el tipo de payload configurado como JSON analizado.
  2. Un primer nodo switch de Node-RED enruta por msg.topic: temperatura, humedad o cualquier otra cosa.
  3. Un segundo nodo switch divide las temperaturas en tres bandas según msg.payload.value.
  4. Las bandas baja y alta pasan por un nodo change que construye el topic y el payload de la alerta, y después un nodo mqtt out la publica.
  5. Las lecturas normales, la humedad y los topics desconocidos van a nodos debug.

Sustituye a7f3k2 por tu propia cadena aleatoria en todas partes antes de desplegar. Cualquiera puede leer el broker público, así que un prefijo único mantiene separado tu tráfico de prueba, y nunca deberías enviar allí datos sensibles. El client ID también debe ser único y no vacío.

[
  {"id":"cmq_broker","type":"mqtt-broker","name":"ConnectMQ public","broker":"broker.connectmq.com","port":"1883","clientid":"nr-switch-a7f3k2","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true},
  {"id":"in_all","type":"mqtt in","name":"all sensors","topic":"connectmq/demo/a7f3k2/sensors/#","qos":"1","datatype":"json","broker":"cmq_broker","nl":false,"rap":true,"rh":0,"inputs":0,"x":140,"y":160,"wires":[["sw_topic"]]},
  {"id":"sw_topic","type":"switch","name":"by measurement","property":"topic","propertyType":"msg","rules":[{"t":"regex","v":"/temperature$","vt":"str","case":false},{"t":"regex","v":"/humidity$","vt":"str","case":false},{"t":"else"}],"checkall":"false","repair":false,"outputs":3,"x":350,"y":160,"wires":[["sw_temp"],["dbg_hum"],["dbg_other"]]},
  {"id":"sw_temp","type":"switch","name":"temperature band","property":"payload.value","propertyType":"msg","rules":[{"t":"lt","v":"5","vt":"num"},{"t":"btwn","v":"5","vt":"num","v2":"30","v2t":"num"},{"t":"gt","v":"30","vt":"num"},{"t":"else"}],"checkall":"false","repair":false,"outputs":4,"x":560,"y":100,"wires":[["chg_alert"],["dbg_ok"],["chg_alert"],["dbg_other"]]},
  {"id":"chg_alert","type":"change","name":"build alert","rules":[{"t":"delete","p":"payload.debug","pt":"msg"},{"t":"set","p":"payload","pt":"msg","to":"{\"room\": $split(topic, \"/\")[4], \"value\": payload.value, \"level\": payload.value > 30 ? \"high\" : \"low\", \"fahrenheit\": $round(payload.value * 9 / 5 + 32, 1)}","tot":"jsonata"},{"t":"set","p":"topic","pt":"msg","to":"\"connectmq/demo/a7f3k2/alerts/\" & payload.room","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":790,"y":60,"wires":[["out_alert","dbg_alert"]]},
  {"id":"out_alert","type":"mqtt out","name":"publish alert","topic":"","qos":"1","retain":"false","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"cmq_broker","x":1000,"y":40,"wires":[]},
  {"id":"dbg_alert","type":"debug","name":"alert","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":990,"y":90,"wires":[]},
  {"id":"dbg_ok","type":"debug","name":"normal temperature","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":800,"y":120,"wires":[]},
  {"id":"dbg_hum","type":"debug","name":"humidity","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":560,"y":200,"wires":[]},
  {"id":"dbg_other","type":"debug","name":"unrouted","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":800,"y":240,"wires":[]}
]

Impórtalo con Menu → Import, pega el JSON y haz clic en Deploy. En pocos segundos, el nodo mqtt in debería mostrar debajo el estado "connected" en verde.

Fíjate en dos detalles del nodo change. Primero se reconstruye el payload, y después la regla del topic lee payload.room del nuevo payload. El orden de las reglas importa: cada regla ve el mensaje tal como lo dejó la anterior. Fíjate también en que el nodo mqtt out tiene el campo topic vacío, así que publica en el msg.topic que haya fijado el nodo change. Si rellenas el campo topic en el nodo, sobrescribe msg.topic y tu enrutamiento dinámico deja de funcionar sin avisar.

Prueba el enrutamiento desde la línea de comandos

Publica algunos mensajes de prueba con los clientes de Mosquitto. Cada comando usa su propio client ID.

# Temperatura normal -> salida de depuración "normal temperature"
mosquitto_pub -h broker.connectmq.com -p 1883 -i pub-a7f3k2-1 \
  -t connectmq/demo/a7f3k2/sensors/room1/temperature -m '{"value": 22.5}'

# Temperatura alta -> alerta publicada en connectmq/demo/a7f3k2/alerts/room1
mosquitto_pub -h broker.connectmq.com -p 1883 -i pub-a7f3k2-2 \
  -t connectmq/demo/a7f3k2/sensors/room1/temperature -m '{"value": 34.2, "debug": "fw-1.2"}'

# Humedad -> salida de depuración "humidity"
mosquitto_pub -h broker.connectmq.com -p 1883 -i pub-a7f3k2-3 \
  -t connectmq/demo/a7f3k2/sensors/room1/humidity -m '{"value": 48}'

# Medida desconocida -> salida de depuración "unrouted"
mosquitto_pub -h broker.connectmq.com -p 1883 -i pub-a7f3k2-4 \
  -t connectmq/demo/a7f3k2/sensors/room1/co2 -m '{"value": 640}'

En una segunda terminal, vigila el topic de alertas para confirmar que el nodo change construyó el mensaje que esperabas:

mosquitto_sub -h broker.connectmq.com -p 1883 -i sub-a7f3k2 -v \
  -t 'connectmq/demo/a7f3k2/alerts/#'

Deberías ver {"room":"room1","value":34.2,"level":"high","fahrenheit":93.6}, sin el campo debug. Si no tienes claro qué efecto tiene cada ajuste de QoS sobre la entrega en esta prueba, la guía de niveles de QoS de MQTT explica por qué el flujo usa QoS 1 para las alertas.

Patrones de enrutamiento que vale la pena reutilizar

Cuando el flujo básico funcione, estos patrones cubren la mayoría de los proyectos reales:

  • Enrutar por tipo de dispositivo con un nivel del topic. En lugar de una regex, configura la propiedad del switch con la expresión JSONata $split(topic, "/")[3] y compárala con reglas ==. Es más fácil de leer que una regex cuando los topics siguen una jerarquía estricta.
  • Validar antes de enrutar. Coloca un nodo switch justo después de mqtt in con una regla "is of type: object". Los payloads mal formados van al puerto otherwise, donde puedes registrarlos en lugar de dejar que hagan fallar un nodo function más adelante.
  • Eliminar cambios de estado duplicados. Combina el nodo switch con un nodo filter (modo report-by-exception) para que un sensor de puerta que publica open cada segundo solo active tu rama cuando cambie el valor.
  • Normalizar unidades pronto. Usa un nodo change justo después de enrutar para convertir unidades y renombrar campos, de modo que todo lo posterior vea un único esquema.
  • Enriquecer con contexto. Un nodo change puede asignar msg.payload.limit desde flow.limits[room], y el siguiente nodo switch puede comparar con msg.payload.limit en lugar de con un número fijo. Así los umbrales viven en un único sitio.

Cuando las condiciones superan unas pocas reglas o necesitan bucles y estado, un nodo function es la mejor herramienta. La guía del nodo function de Node-RED cubre ese paso, y el tutorial del nodo JSON explica cómo interactúan los payloads de cadena y de objeto con estas reglas de enrutamiento.

Solución de problemas de los nodos switch y change

Síntoma Causa probable Solución
No sale nada del nodo switch El payload es una cadena, no un objeto Configura la salida de mqtt in como "a parsed JSON object" o añade un nodo JSON
La regla numérica nunca coincide El valor llega como "34.2" (cadena) Conviértelo con un nodo change: $number(payload.value)
El mensaje aparece en dos ramas Está seleccionado "Checking all rules" Cambia a "stopping after first match"
Las alertas van al topic equivocado El campo topic está relleno en mqtt out Déjalo vacío para que se use msg.topic
Error de JSONata en la barra de depuración La expresión hace referencia a msg.payload Dentro de JSONata, usa payload, no msg.payload
La regex coincide con demasiado Falta el ancla Termina los patrones con $, por ejemplo /temperature$

Un hábito útil: da a cada nodo switch y change un nombre descriptivo. La barra lateral de depuración muestra el nombre del nodo, y "temperature band" es mucho más fácil de rastrear que "switch".

Lleva el flujo a un broker privado

El broker público es ideal para aprender, pero los flujos de enrutamiento en producción deben ejecutarse contra tu propio broker, con credenciales y TLS. Crea un broker en el portal de ConnectMQ y edita el nodo de configuración mqtt-broker:

  • Server: el host que muestra el portal, puerto 8883, con Use TLS activado.
  • Pestaña Security: YOUR_USERNAME y YOUR_PASSWORD.
  • Client ID: YOUR_CLIENT_ID, porque ConnectMQ vincula los client IDs a las credenciales que emite.

Todos los nodos mqtt in y mqtt out comparten ese nodo de configuración, así que la lógica de enrutamiento no cambia. Después puedes eliminar el prefijo connectmq/demo/a7f3k2 y usar una jerarquía adecuada como site/area/line/device/measurement. Ejecutarlo en un broker MQTT gestionado también significa que no tienes que parchear y supervisar un proceso de broker junto a Node-RED.

Ejecuta tus flujos de Node-RED en ConnectMQ

Tus nodos switch y change merecen un broker que siga en pie mientras iteras. Regístrate en app.connectmq.com, elige el plan Serverless gratuito (sin tarjeta de crédito), crea un broker y pega el usuario, la contraseña y el client ID generados en tu nodo de configuración de Node-RED. El explorador de topics en directo del portal muestra cómo llegan tus topics de alerta en tiempo real, lo que acelera mucho la comprobación de la lógica de enrutamiento.

Preguntas frecuentes

¿Cuál es la diferencia entre el nodo switch y el nodo change en Node-RED?

El nodo switch decide adónde va un mensaje comprobando una propiedad frente a unas reglas y eligiendo un puerto de salida. El nodo change modifica el propio mensaje asignando, cambiando, eliminando o moviendo propiedades.

¿Puede el nodo switch de Node-RED enrutar según msg.topic?

Sí. Configura la propiedad como msg.topic y usa reglas "matches regex", "contains" o ==. Es la forma estándar de dividir el tráfico de una única suscripción MQTT con comodín.

¿Por qué mi regla numérica del switch no coincide con los valores MQTT?

Los payloads MQTT llegan como texto salvo que el nodo mqtt in los analice. Asegúrate de que el nodo emite un objeto JSON analizado y convierte los campos de tipo cadena con $number() en un nodo change antes de comparar.

¿Debería usar un nodo function en lugar de los nodos switch y change?

Usa los nodos switch y change para el enrutamiento y las transformaciones sencillas, porque son más fáciles de leer y revisar. Pasa a un nodo function cuando necesites bucles, estado complejo o lógica que requeriría más de unas pocas reglas.

Artículos relacionados

Cliente OPC UA en Node-RED hacia MQTT con topics ISA-95

Usa node-red-contrib-opcua para suscribirte a variables OPC UA de un PLC o de un servidor de simulación, asignar los node IDs a topics MQTT de estilo ISA-95 y publicar los valores con calidad y marcas de tiempo.

10 min de lectura

Node-RED Dashboard 2.0 con MQTT: indicadores, gráficos y controles

Un tutorial práctico de Node-RED Dashboard 2.0: suscríbete a telemetría MQTT en directo, muéstrala en indicadores y en un gráfico de líneas, y controla un dispositivo con un interruptor que publica comandos y refleja el estado real.

9 min de lectura

Todos los artículos →

Tu broker MQTT privado, a unos pocos clics

Crea una cuenta, obtén las credenciales de tu broker y conecta tu primer dispositivo, sin servidores que instalar, parchear ni escalar.