Sparkplug B
Sparkplug B é MQTT — não substitui o MQTT do CMS, é uma especificação que roda sobre ele (MQTT 3.1.1) e preenche o que o MQTT deixa em aberto:
MQTT puro (MQTT_TOPIC_SUBSCRIBER) | Sparkplug B (SPARKPLUG_SUBSCRIBER) | |
|---|---|---|
| Tópico | você digita (fabrica/linha1/forno/temp) | namespace fixo spBv1.0/{grupo}/{tipo}/{edge}/{device} |
| Payload | o que a origem mandar (JSON, texto, número) | protobuf, com tipo e timestamp por métrica |
| Descobrir tags | alguém documenta e você cadastra | vêm no BIRTH, quando o dispositivo conecta |
| Dispositivo caiu | silêncio, indistinguível de “nada mudou” | DEATH publicado pelo broker, na hora |
| Perdeu mensagem | invisível | buraco no número de sequência (seq) |
| Escrever de volta | publicar num tópico combinado | NCMD/DCMD padronizados |
Use Sparkplug quando o outro lado fala Sparkplug — Ignition, HiveMQ Edge, Kepware, Cirrus Link, Opto 22. Um sensor que publica JSON num tópico continua sendo caso de MQTT puro.
Conexão
Nenhuma conexão nova: use a mesma Conexão Externa MQTT do broker (host, porta, credenciais). Há só um campo a mais, opcional:
Primary Host ID — preenchido, o CMS se anuncia como Host Application do namespace: publica
spBv1.0/STATE/{hostId} como ONLINE ao conectar e registra OFFLINE como Last Will. Vários gateways
usam esse sinal para ativar store-and-forward quando o host sai do ar.
Só preencha o Primary Host ID se nenhum outro host (um Ignition, por exemplo) já exercer esse papel com o mesmo ID no seu namespace. Em branco, o CMS é apenas mais um assinante e não interfere.
Coleta — SPARKPLUG_SUBSCRIBER
A Coleta aponta um recorte do namespace, não um tópico:
| Campo | Papel |
|---|---|
| Group ID | agrupa os edge nodes de uma planta/área |
| Edge Node ID | o gateway |
| Device ID | opcional — em branco, coleta de todos os devices do nó |
| Incluir métricas do edge node | traz também NBIRTH/NDATA (CPU, uptime do gateway) |
| Solicitar Rebirth | ao conectar, pede que o nó reanuncie suas métricas |
Cada NDATA/DDATA vira uma mensagem com as métricas que mudaram (report by exception, como a
própria spec):
{ "grupo": "Fabrica01", "edgeNode": "GW_L1", "device": "Forno_A", "tipo": "DDATA", "seq": 42,
"timestamp": "2026-08-21T19:00:00.000Z", "recebidoEm": "2026-08-21T19:00:03.120Z",
"metricas": { "Temperatura": 812.5, "Status": "RUN" } }timestamp é o carimbo da origem (quando o dispositivo mediu), não o da chegada — é uma das
razões de existir do Sparkplug, e o que permite ordenar corretamente dados que atrasaram na rede.
Descobrir tags
O botão Descobrir tags na tela da Coleta mostra o catálogo de métricas de cada device: nome, tipo de dado e o último valor anunciado. O catálogo fica salvo, então a tela abre com ele mesmo se o dispositivo estiver offline; o botão publica um Rebirth e atualiza.
Rebirth e ordem
Depois do BIRTH, as métricas trafegam só com o alias numérico — quem não tem o catálogo não sabe
o que é alias 7. Por isso o CMS pede Rebirth quando conecta, quando recebe dado de um nó sem BIRTH
conhecido e quando o seq salta (sinal de mensagem perdida). Os pedidos são limitados a um a cada
30s por nó.
A queda de um edge node (NDEATH) ou de um device (DDEATH) marca a coleta como desconectada e
dispara o alerta Dispositivo Sparkplug Offline — distinto de Conexão MQTT Perdida, que é a
queda do broker.
Float no Sparkplug é 32 bits: um valor 33,3 volta como 33.29999923706055. Para precisão decimal
exata use métricas Double no gateway.
Entrega — SPARKPLUG_CMD
Escreve métricas no dispositivo publicando DCMD (Device ID preenchido) ou NCMD (em branco). O
mapeamento é o mesmo das Tags de Escrita OPC UA: cada linha liga um alias esperado no payload a
uma métrica do dispositivo, com o tipo de dado usado na codificação.
| Campo da linha | Papel |
|---|---|
| Alias | chave no payload da mensagem |
| Métrica | nome no dispositivo (destino do comando) |
| Tipo | Boolean, Int32, Int64, Float, Double, String ou DateTime |
| Valor padrão | usado quando a mensagem não traz o alias |
| Obrigatório | sem valor (e sem padrão), a entrega falha e nada é publicado |
Os aliases são resolvidos contra o payload já transformado — se houver um Transformador na definição ou no encaminhamento, é a saída dele que vale. (As Tags de Escrita OPC UA/Modbus fazem o contrário: leem o payload original.)
O retorno gravado é {"topico": "spBv1.0/.../DCMD/...", "metricas": N}.
Testar sem gateway real
O repositório traz um simulador de edge node que publica um ciclo de vida completo e responde a comandos:
docker compose -f docker-compose.test.yml up -d mosquitto # broker local (opcional)
node tools/sparkplug-simulador/edge-node.mjs --broker mqtt://localhost:18830
node tools/sparkplug-simulador/edge-node.mjs --morrer 30 # publica NDEATH após 30s