· Eduardo Vieira · Técnico · 11 min de lectura
MQTT Sparkplug B: Hablando la Lingua Franca del IIoT
Para sistemas industriales donde las aplicaciones participantes necesitan un espacio de nombres y un modelo de ciclo de vida compartidos, conozca cómo Sparkplug B puede aportar una capa de interoperabilidad respaldada por evidencia en 2026.

MQTT deja deliberadamente abierto el significado de la aplicación. Un broker puede enrutar un PUBLISH con un tópico, bytes y opciones de entrega, pero no determinar si 24.5 es temperatura, si el nodo de borde sigue activo o si un suscriptor recibió los metadatos para interpretarlo. Esa flexibilidad sirve para integraciones pequeñas; en una planta puede convertir a cada consumidor en un analizador y una máquina de estados a medida. MQTT «no es suficiente» se limita a ese problema de interoperabilidad compartida, no a todos los usos de MQTT simple.
Sparkplug es una especificación de aplicación sobre MQTT para ese problema. Este artículo emplea Sparkplug 3.0.0 y el esquema fijado de Eclipse Tahu indicado más adelante. No afirma que todos los clientes MQTT, brokers, gateways o productos SCADA implementen Sparkplug, ni que MQTT 5.0 proporcione por sí mismo su estado. MQTT es transporte; Sparkplug define un espacio de nombres, convenciones de payload y reglas de ciclo de vida que las aplicaciones participantes acuerdan seguir [C-A-S-001] [C-A-S-002].
Lo que MQTT 5.0 aporta y lo que no define
MQTT 5.0 estandariza un protocolo entre cliente y broker. Incluye, entre otras capacidades, expiración de sesión, expiración de mensajes, códigos de razón, alias de tópico, metadatos de solicitud/respuesta, suscripciones compartidas y propiedades de PUBLISH como Payload Format Indicator, Content Type y User Property. Son capacidades de transporte. Por ejemplo, Content Type puede indicar que los bytes son JSON, pero MQTT no prescribe un modelo de planta, nombres de métricas, unidades, semántica de calidad, un certificado de nacimiento ni una regla para declarar un dispositivo desconectado [C-A-S-003].
Sparkplug 3.0.0 no reemplaza MQTT 5.0. Una instalación Sparkplug puede usar un broker compatible con MQTT 5.0, pero su semántica debe seguir siendo interoperable con la especificación y los clientes desplegados. No confunda un topic alias de MQTT —un entero local a la conexión que acorta un tópico repetido— con un metric alias de Sparkplug, que identifica una métrica después de su definición de nacimiento. Resuelven problemas distintos y se reinician bajo condiciones distintas.
La diferencia es importante al diagnosticar. Un broker puede aceptar un PUBLISH MQTT sintácticamente válido mientras una aplicación rechaza el tópico Sparkplug, no puede decodificar el payload, no observó el mensaje de nacimiento correspondiente o detecta una transición de ciclo de vida inválida. Por ello, «el mensaje llegó» no demuestra que el modelo de datos industrial esté sano.
El espacio de nombres es un contrato, no una convención de carpetas
Los tópicos Sparkplug usan el espacio de nombres spBv1.0. Un nacimiento típico de nodo de borde es:
spBv1.0/PlantA/NBIRTH/Edge01Los segmentos identifican el espacio de nombres, el Group ID, el tipo de mensaje y el Edge Node ID. Los mensajes de dispositivo añaden un Device ID:
spBv1.0/PlantA/DBIRTH/Edge01/Pump07PlantA, Edge01 y Pump07 son ejemplos, no nombres reservados. Un Group ID delimita una población lógica; un Edge Node representa la aplicación de borde conectada por MQTT; un Device es una entidad representada a través de ese nodo. Los nombres son identificadores dentro de un contrato distribuido: defina su propiedad, reglas de caracteres, proceso de cambio y política de colisiones antes del despliegue. Renombrar un ID no es un cambio cosmético de tablero; los consumidores pueden considerarlo una entidad diferente y esperar una nueva secuencia de nacimiento.
Sparkplug también usa un tópico de estado, habitualmente con la forma spBv1.0/STATE/<host-id>, para coordinar una aplicación primaria. El host ID identifica a esa aplicación primaria, no al broker ni a cada suscriptor. Los mensajes de estado ayudan al nodo de borde a decidir cuándo publicar su información de nacimiento después de que la aplicación primaria esté disponible. No vuelven altamente disponible al broker, no autentican al host ni prueban que toda la planta esté operativa. Esas son responsabilidades del despliegue [C-A-S-002].
Los mensajes de nacimiento establecen el vocabulario
El ciclo de vida es un acuerdo sobre lo que un receptor puede asumir. Un nodo de borde publica NBIRTH para anunciarse y sus métricas; si representa dispositivos, publica DBIRTH para cada uno. El payload de nacimiento define nombres o alias, tipos, valores y metadatos. El receptor debe crear o actualizar su interpretación antes de tratar los datos posteriores como una descripción completa.
Después del nacimiento, NDATA actualiza métricas del nodo de borde y DDATA las de dispositivos. Son actualizaciones, no sustitutos del nacimiento. Un mensaje compacto puede usar un alias en vez del nombre. Eso ahorra bytes solamente después de que ambas partes comparten el mapa derivado del nacimiento. La implementación debe descartarlo o reconstruirlo cuando cambie el contexto; no debe suponer que el alias 12 conserva el significado tras un reinicio o nuevo nacimiento.
El archivo fijado sparkplug_b.proto de Tahu vuelve concreto ese vocabulario de payload. Define un Payload con timestamp=1, metrics=2 y seq=3; un Metric incluye name=1, datatype=4 y double_value=13; y el valor del tipo de dato Double es 10 [C-A-P-001]. Esos números de campo son hechos del esquema en ese commit fijado, no una invitación a ensamblar mensajes Protobuf de producción a mano. Use una implementación generada y fijada a una versión, y valídela contra la versión desplegada.
Muerte, renacimiento y los dos números de secuencia
Sparkplug separa los mensajes de ciclo de vida porque un flujo de datos silencioso es ambiguo. NDEATH describe la pérdida de un nodo de borde y DDEATH la pérdida de un dispositivo representado. En una desconexión no controlada del nodo de borde, la ruta NDEATH depende del comportamiento MQTT Last Will configurado por el cliente de borde. Un apagado controlado todavía requiere una transición de ciclo de vida intencional. El broker no infiere salud de proceso por la ausencia de telemetría ni inventa por sí solo un certificado de muerte Sparkplug.
bdSeq y seq responden preguntas diferentes. bdSeq está vinculado al ciclo de nacimiento/muerte: el receptor lo usa para distinguir un ciclo de nacimiento o muerte nuevo de un mensaje de ciclo de vida anterior. seq ordena los payloads Sparkplug dentro de la ventana de secuencia pertinente y tiene un rango limitado; por eso, los consumidores deben implementar el comportamiento de reinicio y vuelta de contador especificado, en vez de tratarlo como un identificador de eventos global y permanentemente creciente. Ninguno sustituye una traza de auditoría de la aplicación ni la marca temporal de un historiador.
Un rebirth es, por tanto, una acción de recuperación del protocolo, no un botón genérico de reintento. Si un nodo de borde se reconecta, descubre que el estado de la aplicación primaria exige un modelo nuevo, cambia la definición de una métrica o entra en otro contexto de ciclo de vida, debe emitir la secuencia de nacimiento requerida antes de que los consumidores confíen en datos posteriores. Los consumidores deben exponer como condiciones diagnosticables los nacimientos faltantes, cambios inesperados de bdSeq, huecos de secuencia y datos recibidos antes de un nacimiento conocido. No deben asociar silenciosamente datos nuevos con metadatos obsoletos porque el tópico parezca familiar.
QoS, estado retenido y sesiones requieren un diseño explícito
El QoS de MQTT afecta la entrega entre cliente y broker; no proporciona procesamiento de negocio exactamente una vez de extremo a extremo. QoS 1 puede volver a entregar, por lo que el tratamiento posterior debe ser idempotente cuando importen los duplicados. QoS 2 añade un intercambio más costoso, pero tampoco coordina una escritura en PLC, una transacción y una acción del operador. Sparkplug no elimina esos límites distribuidos.
Sparkplug 3.0 exige retain=false para NBIRTH, DBIRTH, NDEATH y DDEATH [C-A-S-002]. Por tanto, un suscriptor tardío no recibe estado retenido de ciclo de vida ni de alias de nacimiento; debe observar una nueva secuencia de nacimiento conforme o solicitar rebirth según la arquitectura del despliegue. Si la aplicación también publica estado actual retenido, manténgalo en tópicos de aplicación fuera del espacio de ciclo de vida Sparkplug y defina expiración, limpieza y controles de frescura porque ese estado puede quedar obsoleto.
Las sesiones MQTT persistentes y la expiración de sesión de MQTT 5 pueden preservar suscripciones y estado en vuelo entre reconexiones. No preservan el mapa de alias Sparkplug correcto ni autorizan a confiar en datos de ciclo de vida antiguos. Alinee expiración de sesión, clean start, Last Will, mensajes retenidos y rebirth como un único modelo de fallos. Documente las suposiciones y ensaye por separado el reinicio del broker, del nodo de borde y de la aplicación primaria.
Arquitectura del broker y límites de autorización
Los despliegues Sparkplug sitúan un broker entre nodos de borde, aplicaciones primarias, historiadores y consumidores. El broker enruta tráfico MQTT; no valida un modelo de ingeniería porque un tópico empiece por spBv1.0. Aplique TLS, autentique cada cliente y use autorización por tópico que conceda únicamente derechos necesarios para el Group, Edge Node, Device y rol asignados. Proteja la administración del broker por separado del acceso a telemetría.
TLS protege un salto de red configurado, no la corrección de la configuración de borde ni la seguridad de los comandos. Los certificados requieren emisión, rotación, revocación, validación del nombre de host y disciplina de reloj. Las reglas de autorización necesitan revisión cuando cambia un Group ID o host ID. Los datos del payload pueden seguir siendo sensibles después del cifrado de transporte, así que aplique de forma deliberada políticas de retención, registro y acceso posterior. Este artículo no contiene credenciales reales ni afirma éxito con brokers o dispositivos; el recibo siguiente es local y determinista.
Para alta disponibilidad, defina qué ocurre si se particiona el broker, la aplicación primaria o un nodo de borde. Un clúster puede mejorar la disponibilidad, pero no evita por sí solo duplicados, visiones divididas, estado retenido obsoleto ni decisiones inseguras. Pruebe la conmutación por error con el broker, biblioteca cliente, sesión e implementación Sparkplug exactos. Trate las rutas de control como un caso de seguridad independiente con autorización, interbloqueos, procedimientos de operador y confirmación; no como consecuencia de publicar un mensaje Sparkplug.
Un recibo pequeño y reproducible del espacio de nombres
El siguiente recibo solo demuestra la longitud en bytes y SHA-256 del tópico de ejemplo. No se conecta a un broker, no codifica un payload Protobuf de Sparkplug, no autentica un cliente ni prueba interoperabilidad de dispositivos. Es deliberadamente pequeño para que una persona revisora pueda reproducirlo sin dependencias ni sistemas en vivo.
Recibo: V-A-S-001 Entorno: Python 3.14.6; ejecutado el 2026-07-22 Contexto fijado: Sparkplug 3.0.0 y commit de Tahu 5736e404889d4b95910613040a99ba79589ffb13
python3 - <<'PY'
import hashlib
b=b'spBv1.0/PlantA/NBIRTH/Edge01'
print(f'topic bytes={len(b)} sha256={hashlib.sha256(b).hexdigest()}')
PYSalida esperada y observada, en dos ejecuciones locales idénticas:
topic bytes=28 sha256=5090047c0afa216ef698e938fa1c822038b6de991420c1eb81b9bcf54d85c8ddEl SHA-256 de la salida repetida es 6c67fcb2d6738d2b2ded68f2a895514c5ce0551b4446fd1d603bd3a6d4637a02. El recibo es únicamente una comprobación local de bytes del tópico [V-A-S-001].
Un orden operativo para el diagnóstico
Ante datos ausentes o mal interpretados, empiece por evidencia, no por cambiar QoS al azar:
- Confirme identidad, TLS, autenticación y autorización en registros sin exponer credenciales.
- Verifique Group, Edge Node, Device y tipo contra el espacio de nombres previsto.
- Determine si el receptor vio estado y NBIRTH o DBIRTH antes de interpretar NDATA o DDATA.
- Compare
bdSeq,seq, tiempos, alias y tipos con el nacimiento; registre duplicados, huecos y rebirth. - Pruebe retención y expiración de sesión con un suscriptor nuevo; no borre datos de producción como primer paso.
- Entre productos, capture una muestra anonimizada, versiones, nivel MQTT, supuestos del broker y cronología de ciclo de vida.
Cuándo MQTT simple es una mejor elección
Sparkplug no es obligatorio para toda carga MQTT. MQTT simple suele ser preferible cuando productor y consumidor comparten un contrato estrecho, el payload es específico o no se necesita descubrimiento ni estado estandarizado. En esos casos, documente tópico, esquema, autenticación, versionado y fallos.
Sparkplug requiere implementaciones compatibles, gobierno del espacio de nombres, consumidores conscientes del ciclo de vida y pruebas de integración. No valida calibración, no garantiza un clúster ni vuelve segura una acción de control. Elíjalo porque sus convenciones encajan en el límite de integración, no por interoperabilidad universal.
El próximo artículo, Diseño de payloads MQTT: JSON, Sparkplug y evolución, trata envolventes de aplicación, unidades, calidad, marcas temporales, canonicalización y fixtures de payload medidos. Esos son temas de diseño de payload; este artículo conserva deliberadamente la responsabilidad sobre el espacio de nombres y la semántica de ciclo de vida.
Referencias
- [C-A-S-001] Eclipse Sparkplug, Especificación Sparkplug 3.0 e información de ratificación, acceso el 2026-07-22.
- [C-A-S-002] Eclipse Sparkplug, Sparkplug Specification 3.0.0 (PDF), acceso el 2026-07-22.
- [C-A-S-003] OASIS, MQTT Version 5.0, publicado el 2019-03-07; acceso el 2026-07-22.
- [C-A-P-001] Eclipse Tahu,
sparkplug_b.protoen el commit5736e404889d4b95910613040a99ba79589ffb13, acceso el 2026-07-22. - [V-A-S-001] Recibo local determinista anterior; Python 3.14.6; ejecutado dos veces el 2026-07-22. No es evidencia de broker ni de dispositivo en vivo.
Last verified: 2026-07-22. La selección de fuentes usó la solicitud Tavily acb84e15-ec4a-40f7-9486-000e54a1b296; los intentos de Context7 para Eclipse Paho MQTT Python y Eclipse Tahu devolvieron Monthly quota exceeded. Create a free API key at https://context7.com/dashboard for more requests. En su lugar se usan las fuentes oficiales de OASIS, Eclipse Sparkplug y Tahu fijado.



