Una primary host application de Sparkplug es el consumidor principal de los datos de planta, normalmente un SCADA o un MES, al que los edge nodes vigilan antes de publicar nada. En esta guía aprenderás cómo el host se anuncia mediante mensajes STATE, cómo se espera que reaccionen los edge nodes cuando se desconecta y cómo probar ese comportamiento de extremo a extremo con un pequeño host en Python y un par de herramientas de línea de comandos.
Qué hace una aplicación host
Además del broker, Sparkplug define dos tipos de participantes. Los edge nodes publican datos. Las aplicaciones host los consumen, siguen el estado de cada nodo y dispositivo y envían comandos como solicitudes de rebirth o escrituras de consignas. Una planta puede tener muchas aplicaciones host: SCADA, un historian, un servicio de analítica, un puente hacia un Unified Namespace.
Una aplicación host tiene varias responsabilidades:
- Suscribirse a
spBv1.0/#(o a los grupos que gestiona) y mantener un modelo en vivo de nodos, dispositivos y métricas. - Usar los certificados de birth para conocer nombres de métricas, alias y tipos de datos.
- Marcar los datos como obsoletos cuando llega un NDEATH o DDEATH, usando bdSeq para descartar deaths de sesiones antiguas.
- Vigilar los números de secuencia y solicitar un rebirth cuando aparece un salto.
- Publicar su propio STATE para que los edge nodes sepan si está escuchando.
Qué hace que un host sea primario
Un host puede designarse como primary host application para un conjunto de edge nodes. Esto se configura en el edge node, no en el broker: al nodo se le indica el host ID del que depende. La idea es sencilla. Si el sistema en el que confían los operadores no está conectado, los datos publicados en ese momento se perderían para él, así que el edge node debe dejar de publicar datos en vivo, almacenarlos localmente si admite store and forward, y esperar.
Sin un host primario configurado, un edge node publica en cuanto se conecta al broker, con independencia de quién esté escuchando. Eso está bien para monitorización y dashboards, pero es más débil para SCADA, donde los huecos en el histórico importan.
Mensajes STATE en Sparkplug 3.0
El host se anuncia en un topic dedicado fuera de la estructura de grupos:
spBv1.0/STATE/{host_id}
| Propiedad | Birth (online) | Death (offline) |
|---|---|---|
| Cómo se envía | Lo publica el host tras conectarse | Se registra como will MQTT al conectarse |
| Payload | {"online": true, "timestamp": T} |
{"online": false, "timestamp": T} |
| QoS | 1 | 1 |
| Retained | Sí | Sí |
| Marca de tiempo | Misma T para esta sesión | Misma T para esta sesión |
Que el mensaje sea retained significa que un edge node que se conecte en cualquier momento sabe de inmediato si el host está online. La marca de tiempo compartida permite a los nodos ignorar un mensaje antiguo: si un nodo ha visto online con la marca T2, un mensaje offline con una marca anterior T1 es un resto de una sesión previa y no debe provocar una desconexión.
Los sistemas antiguos 2.2 usan STATE/{host_id} con cadenas simples ONLINE y OFFLINE. Las diferencias se resumen en nuestra comparativa de Sparkplug 3.0.
Cómo reaccionan los edge nodes
Un edge node configurado con un host primario sigue un patrón predecible:
- Se conecta al broker con su NDEATH registrado como will.
- Se suscribe a
spBv1.0/STATE/{primary_host_id}y a sus propios topics NCMD y DCMD. - Espera un mensaje STATE con
"online": true. - Publica NBIRTH y DBIRTH y, a continuación, los datos de la forma habitual.
- Si STATE cambia a
"online": falsecon una marca de tiempo al menos tan reciente como la última vista, publica el NDEATH, se desconecta y almacena los datos en búfer si lo admite. - Se reconecta (posiblemente a otro broker en una configuración multiservidor) y vuelve a esperar a que el host esté online.
- Cuando el host vuelve, publica births nuevos y después los datos históricos almacenados, marcados con
is_historical.
El paso 7 es la razón por la que STATE importa: los births dan al host un modelo limpio, y los indicadores de histórico le permiten rellenar huecos sin sobrescribir los valores en vivo. La mecánica de birth y death se explica en certificados birth y death de Sparkplug.
Prueba el flujo con un host mínimo en Python
Este script hace de host primario: registra su will offline, publica su estado online y escucha un grupo. Usa paho-mqtt 2.x y no necesita Protobuf porque los payloads STATE son JSON.
import json
import time
import uuid
import paho.mqtt.client as mqtt
BROKER = "broker.connectmq.com"
PORT = 1883
HOST_ID = "demo-host-" + uuid.uuid4().hex[:6]
GROUP = "demo-" + HOST_ID[-6:]
STATE_TOPIC = f"spBv1.0/STATE/{HOST_ID}"
SESSION_TS = int(time.time() * 1000)
def state(online):
return json.dumps({"online": online, "timestamp": SESSION_TS})
def on_connect(client, userdata, flags, reason_code, properties):
if reason_code.is_failure:
print("connect failed:", reason_code)
return
client.subscribe(f"spBv1.0/{GROUP}/#", qos=1)
client.subscribe(STATE_TOPIC, qos=1)
client.publish(STATE_TOPIC, state(True), qos=1, retain=True)
print(f"host {HOST_ID} online, watching group {GROUP}")
def on_message(client, userdata, msg):
if msg.topic == STATE_TOPIC:
print("STATE:", msg.payload.decode())
else:
print(f"{msg.topic} ({len(msg.payload)} bytes)")
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
client_id=f"host-{uuid.uuid4().hex[:8]}",
clean_session=True)
client.on_connect = on_connect
client.on_message = on_message
client.will_set(STATE_TOPIC, state(False), qos=1, retain=True)
client.connect(BROKER, PORT, keepalive=15)
try:
client.loop_forever()
except KeyboardInterrupt:
client.publish(STATE_TOPIC, state(False), qos=1, retain=True).wait_for_publish()
client.disconnect()
Ejecútalo, anota el host ID que muestra y, en una segunda terminal, haz de edge node vigilando ese host:
mosquitto_sub -h broker.connectmq.com -p 1883 -i node-watch-91aa -q 1 -v \
-t "spBv1.0/STATE/demo-host-xxxxxx"
Recibirás inmediatamente el mensaje online retained. Ahora mata el proceso de Python sin Ctrl+C (cierra la terminal o finaliza la tarea). Pasado el intervalo de keepalive, el broker publica el will y el observador muestra "online": false con la misma marca de tiempo. Reinicia el host y verás un nuevo mensaje online con una marca de tiempo más reciente. Esa es exactamente la señal que usa un edge node para decidir cuándo publicar sus births.
Cuando termines, borra el estado retained para que el servidor MQTT público gratuito, que es compartido y solo sirve para pruebas, no lo conserve:
mosquitto_pub -h broker.connectmq.com -p 1883 -i cleanup-91aa -r -n -t "spBv1.0/STATE/demo-host-xxxxxx"
Vigilar el estado del host en un explorador de topics
Durante la puesta en marcha quieres ver el estado del host y los births de los nodos en una misma pantalla. ConnectMQ muestra los mensajes STATE retained en el explorador de topics de su portal junto a los births y datos Sparkplug decodificados, y expone el estado de conexión de los clientes en $SYS/broker/connection/{clientId}/state. Suscribirse a ese topic con el client ID de tu host es una comprobación cruzada rápida: si el estado de conexión indica desconectado pero STATE sigue diciendo online, el will aún no se ha disparado porque no ha expirado el intervalo de keepalive.
Problemas habituales
| Síntoma | Causa probable | Solución |
|---|---|---|
| Los edge nodes nunca publican births | El host ID no coincide entre la configuración del nodo y el topic STATE | Copia el host ID exacto, distingue mayúsculas |
| Los nodos se desconectan justo después de reiniciar el host | Se procesa un will offline antiguo después del nuevo online | Los nodos deben comparar marcas de tiempo; comprueba el soporte de 3.0 |
| Falta STATE para los nodos nuevos | STATE publicado sin retain | Publica el online y el will con retain a true |
| Gran retraso hasta que los nodos detectan la caída del host | Keepalive elevado en el host | Usa un keepalive corto, por ejemplo de 15 a 30 segundos |
| Nodos y host se ignoran mutuamente | Una de las partes usa el topic STATE/ de la 2.2 |
Alinea versiones o activa el modo de compatibilidad |
Diseñar pensando en la disponibilidad del host
Como los edge nodes dejan de publicar cuando el host primario está offline, el host y su conexión al broker se vuelven críticos. Ejecuta el host en una infraestructura fiable, usa un keepalive corto para detectar los fallos rápidamente y asegúrate de que el propio broker no sea el eslabón débil. Un broker MQTT gestionado o un broker MQTT en la nube te quita la carga de parchear y monitorizar el broker. Si un nodo pierde la conexión, el proceso de rebirth de Sparkplug es la forma en que el host recupera una visión coherente. Para el panorama completo del IIoT, consulta IoT industrial con MQTT.
Empieza con ConnectMQ
Crea un broker Serverless gratuito en app.connectmq.com, sin tarjeta de crédito. Ejecuta el script del host con tus credenciales generadas mediante TLS en el puerto 8883, conecta un edge node configurado con ese host ID y observa STATE, births y datos en el portal de ConnectMQ.
Preguntas frecuentes
¿Puede haber más de una primary host application?
Cada edge node se configura con un único host ID primario. Distintos grupos de nodos pueden depender de hosts diferentes, y cualquier número de aplicaciones host no primarias puede consumir datos al mismo tiempo.
¿El mensaje STATE es retained?
Sí. Tanto el mensaje online como el will offline se publican como retained con QoS 1, de modo que cualquier edge node que se conecte más tarde conoce de inmediato el estado actual del host.
¿El broker necesita soporte especial de Sparkplug para STATE?
No. STATE se basa en funciones estándar de MQTT: retained messages, QoS 1 y el last will. Cualquier broker que cumpla el estándar puede transportarlo.
¿Qué ocurre con los datos mientras el host primario está offline?
Los edge nodes dejan de publicar datos en vivo. Los nodos que admiten store and forward los almacenan en búfer y los envían más tarde como métricas históricas tras los nuevos births.



