IoT industrial

Primary Host Application do Sparkplug e Mensagens STATE

A Primary Host Application é o consumidor Sparkplug do qual os edge nodes dependem. Este guia explica as mensagens STATE no Sparkplug 3.0, como os edge nodes reagem quando o host fica offline e como testar o fluxo com Python e mosquitto.

Primary Host Application do Sparkplug publicando uma mensagem STATE online que os edge nodes observam antes de enviar os births
Rode isso no seu próprio broker MQTTTenha um broker MQTT privado e gerenciado no plano Free e comece com exemplos de código prontos.
Teste grátis Exemplos de código Sem cartão de crédito

Uma Primary Host Application do Sparkplug é o principal consumidor dos dados da planta, normalmente um SCADA ou um MES, que os edge nodes observam antes de publicar qualquer coisa. Neste guia você vai aprender como o host se anuncia com mensagens STATE, como se espera que os edge nodes reajam quando ele fica offline e como testar esse comportamento de ponta a ponta com um pequeno host em Python e algumas ferramentas de linha de comando.

O que uma aplicação host faz

O Sparkplug define dois tipos de participantes além do broker. Os edge nodes publicam dados. As aplicações host os consomem, acompanham o estado de cada node e device e enviam comandos como solicitações de rebirth ou escritas de setpoint. Uma planta pode ter muitas aplicações host: SCADA, um historian, um serviço de analytics, uma ponte para o Unified Namespace.

Uma aplicação host tem várias responsabilidades:

  • Assinar spBv1.0/# (ou os groups que gerencia) e manter um modelo ao vivo de nodes, devices e métricas.
  • Usar os certificados de birth para aprender nomes de métricas, aliases e tipos de dados.
  • Marcar dados como desatualizados quando chega um NDEATH ou DDEATH, usando o bdSeq para descartar deaths de sessões antigas.
  • Observar os números de sequência e solicitar um rebirth quando surgir uma lacuna.
  • Publicar o seu próprio STATE para que os edge nodes saibam se ele está ouvindo.

O que torna um host primário

Um host pode ser designado como Primary Host Application de um conjunto de edge nodes. Isso é configurado no edge node, não no broker: o node recebe o host ID do qual depende. A ideia é simples. Se o sistema em que os operadores confiam não está conectado, os dados publicados naquele momento seriam perdidos para ele, então o edge node deve parar de publicar dados ao vivo, armazená-los localmente se suportar store and forward, e esperar.

Sem um host primário configurado, um edge node publica assim que se conecta ao broker, independentemente de quem esteja ouvindo. Isso serve para monitoramento e dashboards, mas é mais frágil para SCADA, onde lacunas no histórico importam.

Mensagens STATE no Sparkplug 3.0

O host se anuncia em um topic dedicado, fora da estrutura de groups:

spBv1.0/STATE/{host_id}
Propriedade Birth (online) Death (offline)
Como é enviada Publicada pelo host depois de conectar Registrada como will MQTT na conexão
Payload {"online": true, "timestamp": T} {"online": false, "timestamp": T}
QoS 1 1
Retained Sim Sim
Timestamp O mesmo T para esta sessão O mesmo T para esta sessão

Manter a mensagem como retained significa que um edge node que se conecta a qualquer momento descobre na hora se o host está online. O timestamp compartilhado permite que os nodes ignorem uma mensagem antiga: se um node viu online com timestamp T2, uma mensagem offline com um timestamp mais antigo T1 é resquício de uma sessão anterior e não deve provocar uma desconexão.

Sistemas 2.2 mais antigos usam STATE/{host_id} com as strings simples ONLINE e OFFLINE. As diferenças estão resumidas na nossa comparação do Sparkplug 3.0.

Como os edge nodes reagem

Um edge node configurado com um host primário segue um padrão previsível:

  1. Conecta-se ao broker com o seu NDEATH registrado como will.
  2. Assina spBv1.0/STATE/{primary_host_id} e os seus próprios topics NCMD e DCMD.
  3. Aguarda uma mensagem STATE com "online": true.
  4. Publica NBIRTH e DBIRTH e, depois, os dados normalmente.
  5. Se o STATE mudar para "online": false com um timestamp pelo menos tão recente quanto o último visto, publica o NDEATH, desconecta e armazena os dados em buffer, se houver suporte.
  6. Reconecta (possivelmente a outro broker em uma configuração com vários servidores) e espera de novo o host ficar online.
  7. Quando o host volta, publica births novos e, em seguida, os dados históricos armazenados, marcados com is_historical.

O passo 7 é o motivo pelo qual o STATE importa: os births dão ao host um modelo limpo, e as flags de histórico permitem preencher as lacunas sem sobrescrever valores ao vivo. A mecânica de birth e death é tratada em certificados de birth e death do Sparkplug.

Teste o fluxo com um host mínimo em Python

Este script faz o papel de host primário: registra o seu will offline, publica o seu estado online e escuta um group. Ele usa paho-mqtt 2.x e não precisa de Protobuf, porque os payloads STATE são 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()

Execute-o, anote o host ID que ele imprime e, em um segundo terminal, faça o papel do edge node que observa esse host:

mosquitto_sub -h broker.connectmq.com -p 1883 -i node-watch-91aa -q 1 -v \
  -t "spBv1.0/STATE/demo-host-xxxxxx"

Você vai receber imediatamente a mensagem online retained. Agora mate o processo Python sem usar Ctrl+C (feche o terminal ou finalize a tarefa). Depois que a janela de keepalive passar, o broker publica o will e o observador imprime "online": false com o mesmo timestamp. Reinicie o host e você verá uma nova mensagem online com um timestamp mais recente. Esse é exatamente o sinal que um edge node usa para decidir quando publicar os births.

Quando terminar, apague o estado retained para que o servidor MQTT público, que é compartilhado e serve apenas para testes, não o mantenha:

mosquitto_pub -h broker.connectmq.com -p 1883 -i cleanup-91aa -r -n -t "spBv1.0/STATE/demo-host-xxxxxx"

Acompanhando o estado do host em um topic explorer

Durante o comissionamento você quer ver o estado do host e os births dos nodes em uma única tela. O ConnectMQ mostra as mensagens STATE retained no topic explorer do portal ao lado dos births e dados Sparkplug decodificados, e expõe o estado de conexão dos clientes em $SYS/broker/connection/{clientId}/state. Assinar esse topic para o client ID do seu host é uma verificação cruzada rápida: se o estado de conexão diz desconectado, mas o STATE ainda diz online, o will ainda não foi disparado porque a janela de keepalive não expirou.

Problemas comuns

Sintoma Causa provável Solução
Os edge nodes nunca publicam births Host ID diferente entre a configuração do node e o topic STATE Copie o host ID exato, respeitando maiúsculas e minúsculas
Os nodes se desconectam logo depois que o host reinicia Will offline antigo processado depois do novo online Os nodes precisam comparar timestamps; verifique o suporte à 3.0
STATE ausente para novos nodes STATE publicado sem retain Publique o online e o will com retain true
Grande atraso até os nodes perceberem a perda do host Keepalive alto no host Use um keepalive curto, como 15 a 30 segundos
Nodes e host se ignoram Um dos lados usa o topic STATE/ da 2.2 Alinhe as versões ou habilite o modo de compatibilidade

Projetando para a disponibilidade do host

Como os edge nodes param de publicar quando o host primário está offline, o host e a sua conexão com o broker se tornam críticos. Rode o host em infraestrutura confiável, use um keepalive curto para que as falhas sejam percebidas rapidamente e garanta que o próprio broker não seja o elo fraco. Um broker MQTT gerenciado ou um broker MQTT na nuvem elimina o trabalho de aplicar patches e monitorar o broker. Se um node perde a conexão, o processo de rebirth do Sparkplug é a forma como o host volta a ter uma visão consistente. Para o panorama completo de IIoT, veja IoT Industrial com MQTT.

Comece com o ConnectMQ

Crie um broker Serverless gratuito em app.connectmq.com, sem cartão de crédito. Rode o script do host com as credenciais geradas via TLS na porta 8883, conecte um edge node configurado com esse host ID e acompanhe STATE, births e dados no portal do ConnectMQ.

Perguntas frequentes

Pode haver mais de uma Primary Host Application?

Cada edge node é configurado com um único host ID primário. Groups diferentes de nodes podem depender de hosts diferentes, e qualquer número de aplicações host não primárias pode consumir dados ao mesmo tempo.

A mensagem STATE é retained?

Sim. Tanto a mensagem online quanto o will offline são publicados como retained com QoS 1, então qualquer edge node que se conecte depois descobre imediatamente o estado atual do host.

O broker precisa de suporte especial a Sparkplug para o STATE?

Não. O STATE se apoia em recursos padrão do MQTT: retained messages, QoS 1 e last will. Qualquer broker compatível pode transportá-lo.

O que acontece com os dados enquanto o host primário está offline?

Os edge nodes param de publicar dados ao vivo. Nodes que suportam store and forward armazenam os dados em buffer e os enviam depois como métricas históricas, após novos births.

Artigos relacionados

Cliente MQTT no CODESYS: Publicando Variáveis do CLP em um Broker

Configure a biblioteca IIoT MQTT Client do CODESYS para publicar variáveis do CLP em JSON, verifique-as no servidor MQTT público broker.connectmq.com e depois migre para um broker privado com credenciais e TLS.

8 min de leitura

Todos os artigos →

Seu broker MQTT privado está a poucos cliques de distância

Crie uma conta, receba as credenciais do seu broker e conecte seu primeiro dispositivo — sem servidores para instalar, atualizar ou escalar.