MQTT a secas no impone nada a propósito: cualquier topic, cualquier payload. Esa flexibilidad es un problema en las fábricas, donde un sistema SCADA de un fabricante tiene que entender los datos de gateways de PLC construidos por otro. Sparkplug B cubre ese hueco. Es una especificación abierta, mantenida por el Sparkplug Working Group de la Eclipse Foundation, que define cómo usar MQTT en el IoT industrial: una estructura de topics fija, un formato de payload binario y reglas para saber si cada dispositivo está online. La versión 3.0 de la especificación también se publica como estándar internacional ISO/IEC 20237.
Si eres nuevo en el protocolo subyacente, empieza por qué es MQTT.
Los componentes de un sistema Sparkplug
- Servidor MQTT: cualquier broker compatible con MQTT 3.1.1 o 5.
- Edge Node: un gateway o dispositivo que se conecta a MQTT, por ejemplo un gateway de PLC. Publica sus propios datos y los de los dispositivos que tiene detrás.
- Device: un sensor, PLC o máquina conectado a un Edge Node. Los devices no se conectan ellos mismos a MQTT; el Edge Node habla en su nombre.
- Host Application: un consumidor como un SCADA, un MES o un historian que se suscribe a los datos y envía comandos. Uno de ellos puede designarse como Primary Host Application.
El espacio de nombres de topics de Sparkplug
Todos los topics de Sparkplug B siguen la misma estructura:
spBv1.0/<group_id>/<message_type>/<edge_node_id>[/<device_id>]
# Examples
spBv1.0/Plant1/NBIRTH/Gateway-07
spBv1.0/Plant1/DDATA/Gateway-07/Press-3
spBv1.0/Plant1/DCMD/Gateway-07/Press-3spBv1.0: el espacio de nombres y la versión de la definición del payload.group_id: una agrupación lógica de Edge Nodes, como una planta o una línea de producción.message_type: uno de los tipos de mensaje que se describen más abajo.edge_node_idy eldevice_idopcional: identifican al publicador.
Como la estructura es fija, los consumidores pueden suscribirse con comodines como spBv1.0/Plant1/+/# o spBv1.0/+/DDATA/#. Pégalos en el probador de topics para comprobar con qué coinciden, o lee topics y comodines en MQTT para conocer las reglas.
Tipos de mensaje
| Tipo | Publicado por | Propósito |
|---|---|---|
NBIRTH | Edge Node | Anuncia que el nodo está online; enumera todas sus métricas con nombre, tipo y valor actual |
NDEATH | Edge Node (mediante Last Will) | Anuncia que el nodo está offline |
DBIRTH | Edge Node | Anuncia que un device está online, con su lista completa de métricas |
DDEATH | Edge Node | Anuncia que un device está offline |
NDATA / DDATA | Edge Node | Valores modificados de métricas del nodo o del device (report by exception) |
NCMD / DCMD | Host Application | Comandos a un nodo o device, p. ej. escribir una consigna o solicitar un rebirth |
STATE | Host Application | Anuncia si una Host Application está online |
Sparkplug se basa en el report by exception: después de que el mensaje BIRTH establece todas las métricas, los mensajes DATA solo llevan los valores que han cambiado. Un consumidor que se une tarde, o que pierde el hilo, puede pedir un BIRTH nuevo enviando un NCMD que ponga a true la métrica Node Control/Rebirth.
Estado de la sesión: NDEATH, bdSeq y seq
La gran baza de Sparkplug es que el host siempre sabe si los datos están al día. Se apoya en el Last Will and Testament de MQTT:
- Cuando el Edge Node se conecta, registra un mensaje
NDEATHcomo su will. El will lleva una métricabdSeq(secuencia de birth/death). - Justo después de conectarse, publica
NBIRTHcon el mismobdSeq, seguido de unDBIRTHpor cada device. - Si el nodo se cae, el broker publica el will NDEATH. El host compara su
bdSeqcon el del último NBIRTH y marca como obsoletas todas las métricas de ese nodo y de sus devices.
bdSeq se incrementa con cada nueva sesión MQTT (y vuelve a empezar tras 255), de modo que un NDEATH tardío de una conexión antigua no se confunde con la muerte de la actual.
Por otro lado, cada mensaje que publica un Edge Node lleva un número seq de 0 a 255. NBIRTH empieza en 0 y cada mensaje siguiente lo incrementa, volviendo a 0 después de 255. Si un host detecta un hueco, sabe que se ha perdido un mensaje y puede solicitar un rebirth.
La Primary Host Application y STATE
Los datos solo sirven si alguien los registra. Una Primary Host Application publica un mensaje STATE retenido (y registra un STATE offline como su will). Los Edge Nodes configurados con un primary host esperan a que esté online antes de publicar sus births; si se cae, se desconectan y pueden guardar datos localmente o conmutar a otro servidor MQTT hasta que vuelva. En Sparkplug 3.0 el topic es spBv1.0/STATE/<host_id> con un pequeño payload JSON:
{ "online": true, "timestamp": 1760140800000 }Las instalaciones antiguas 2.x usaban el topic STATE/<host_id> con una simple cadena ONLINE/OFFLINE.
Payloads Protobuf
Los payloads de Sparkplug B se codifican con Google Protocol Buffers. Un payload tiene un timestamp, un seq y una lista de métricas. Cada métrica tiene un nombre, un tipo de dato, un valor, un timestamp opcional y un alias numérico opcional. Los alias se declaran en el BIRTH; después, los mensajes DATA pueden enviar el alias en lugar del nombre completo, lo que mantiene los mensajes compactos.
timestamp: 1760140800123
seq: 17
metrics {
alias: 4 # "Press-3/Hydraulic/Pressure" in DBIRTH
timestamp: 1760140800120
datatype: Float
float_value: 182.4
}La codificación binaria hace que los payloads sean pequeños, algo importante en enlaces limitados; puedes estimar el tamaño de los paquetes con la calculadora de tamaño de paquetes MQTT. La desventaja es que un cliente genérico muestra bytes en bruto. Aun así, puedes usar uno para confirmar que los births y deaths llegan a los topics correctos:
Observa un espacio de nombres Sparkplug en el cliente online
Ajustes de MQTT que usa Sparkplug
- QoS 0 para los mensajes NBIRTH/DBIRTH, DATA y CMD; QoS 1 para el will NDEATH y STATE.
- Retain false para todo excepto STATE, que es retenido.
- Sesiones limpias para los Edge Nodes (Clean Session true en 3.1.1, o Clean Start true con un session expiry de 0 en MQTT 5). Sparkplug gestiona el estado por sí mismo mediante births y rebirths, así que no depende de las sesiones persistentes.
Primeros pasos con Eclipse Tahu
Eclipse Tahu es la implementación de referencia de Sparkplug, con la definición Protobuf y librerías cliente para Java, C, Python y JavaScript. Se encarga de la codificación, los alias y los números de secuencia para que te centres en tus métricas. El Sparkplug Working Group también publica un Technology Compatibility Kit (TCK) para comprobar si las implementaciones cumplen la especificación.
Consideraciones de seguridad
Como los comandos de Sparkplug pueden escribir consignas en máquinas reales, trata el acceso a los topics NCMD y DCMD como algo crítico para la seguridad. Usa TLS, credenciales únicas por Edge Node y ACL que solo permitan a cada nodo publicar bajo su propio edge_node_id. Nuestras buenas prácticas de seguridad MQTT cubren los detalles.
Preguntas frecuentes
¿Qué diferencia hay entre MQTT y Sparkplug B?
MQTT es un protocolo de transporte que mueve bytes por topics sin definir qué significan los topics ni los payloads. Sparkplug B es una especificación sobre MQTT que define un espacio de nombres de topics fijo, un formato de payload Protobuf y la gestión del estado de sesión, para que dispositivos industriales y sistemas SCADA de distintos fabricantes puedan interoperar.
¿Sparkplug B necesita un broker MQTT especial?
No. Sparkplug B funciona con cualquier broker compatible con MQTT 3.1.1 o MQTT 5 que soporte QoS, mensajes retenidos y Last Will. Algunos brokers ofrecen funciones opcionales específicas para Sparkplug, pero no son necesarias para el funcionamiento básico.
¿Por qué los mensajes Sparkplug B son ilegibles en mi cliente MQTT?
Los payloads de Sparkplug B son Google Protocol Buffers binarios, no JSON ni texto. Un cliente MQTT genérico los muestra como bytes en bruto. Necesitas una herramienta compatible con Sparkplug o una librería como Eclipse Tahu para decodificarlos en métricas.