O suporte do Node-RED a Sparkplug B permite que um fluxo low-code se comporte como um edge node industrial de verdade: ele anuncia suas métricas com certificados de birth, publica dados Protobuf compactos, informa sua morte quando se desconecta e aceita comandos. Neste tutorial você vai montar um edge node Sparkplug B para uma máquina CNC simulada, consumir e decodificar os dados em um segundo fluxo e conferir o resultado em um broker que entende Sparkplug. No caminho, você vai descobrir quais detalhes da especificação mais confundem as pessoas.
Sparkplug B em resumo
Sparkplug B é uma especificação da Eclipse Foundation que fica sobre o MQTT. O MQTT puro não diz nada sobre estrutura de topics ou formato de payload; o Sparkplug define os dois, além do estado da sessão, para que equipamentos de fabricantes diferentes interoperem com aplicações SCADA e MES sem esforço adicional.
As ideias principais:
- Namespace de topics:
spBv1.0/<group_id>/<message_type>/<edge_node_id>/[<device_id>]. - Payload: Google Protocol Buffers com uma lista de métricas, cada uma com nome, tipo de dado, valor e timestamp.
- Consciência de sessão: um edge node publica
NBIRTHquando se conecta e registra umNDEATHcomo seu Last Will MQTT. Os dispositivos atrás dele publicamDBIRTHeDDEATH. - Report by exception: depois do birth, as mensagens
DDATAcontêm apenas as métricas que mudaram. - Comandos: as aplicações enviam mensagens
NCMDeDCMD, incluindo um pedido de "Rebirth".
| Mensagem | Direção | Significado |
|---|---|---|
| NBIRTH / DBIRTH | Borda para o broker | Lista completa de métricas com tipos e valores atuais |
| NDATA / DDATA | Borda para o broker | Somente métricas alteradas |
| NDEATH / DDEATH | Borda para o broker (NDEATH via Last Will) | Nó ou dispositivo offline |
| NCMD / DCMD | Aplicação para a borda | Escrever uma métrica ou pedir um rebirth |
| STATE | Aplicação host primária | Se a aplicação host está online |
Para a gramática completa dos topics, veja o guia do namespace de topics Sparkplug e, para entender como births e deaths mantêm o estado consistente, leia certificados de birth e death do Sparkplug.
Instale os nós Sparkplug
A implementação de Sparkplug mais completa para o Node-RED é o node-red-contrib-mqtt-sparkplug-plus. Instale-o pelo gerenciador de paleta ou pela linha de comando:
cd ~/.node-red
npm install node-red-contrib-mqtt-sparkplug-plus
# reinicie o Node-RED depois
Ele adiciona três nós e um nó de configuração:
- mqtt sparkplug device: representa um dispositivo atrás do edge node. Ele cuida de DBIRTH, DDATA, DDEATH e DCMD por você.
- mqtt sparkplug in: assina topics Sparkplug e decodifica o payload Protobuf em um objeto JavaScript.
- mqtt sparkplug out: publica mensagens Sparkplug brutas quando você precisa de controle total.
- Sparkplug broker config: a conexão MQTT mais o Group ID e o Edge Node ID do Sparkplug. Ele publica o NBIRTH e registra o NDEATH automaticamente.
Monte um edge node Sparkplug B no Node-RED
Passo 1: configurar o broker e a identidade
Adicione um nó mqtt sparkplug device e crie uma nova configuração de broker:
- Server:
broker.connectmq.com, porta1883, com um client ID único. Esse é o servidor MQTT público gratuito, então tudo o que você publicar pode ser lido por outras pessoas; use apenas dados simulados. - Group ID:
demo-a7f3k2. Os topics Sparkplug precisam começar comspBv1.0, então você não pode usar aqui o prefixo habitualconnectmq/demo/.... Em vez disso, torne o group ID único, substituindoa7f3k2por uma string aleatória sua. - Edge Node ID:
line1.
Depois defina o nome do dispositivo no nó device como cnc1. O dispositivo vai publicar em spBv1.0/demo-a7f3k2/DDATA/line1/cnc1.
Passo 2: definir as métricas
No nó device, adicione métricas com nomes e tipos de dados Sparkplug:
| Nome da métrica | Tipo de dado | Significado |
|---|---|---|
spindle/speed |
Int32 | Rotação do spindle em rpm |
spindle/load |
Float | Carga do spindle em porcentagem |
coolant/temperature |
Float | Temperatura do fluido de corte em °C |
running |
Boolean | Máquina em operação |
partCount |
Int64 | Contador acumulado de peças |
Declarar os tipos é importante: o DBIRTH diz a todos os consumidores o que esperar, e uma aplicação host vai rejeitar ou interpretar errado dados que mudem de tipo depois. Por padrão, o nó espera até que todas as métricas tenham recebido um valor antes de publicar o DBIRTH, o que evita um certificado de birth cheio de valores vazios.
Passo 3: alimentar com dados
Um nó inject que se repete a cada 2 segundos alimenta um nó function que simula a máquina. O nó device espera msg.payload.metrics como um array de pares de nome e valor:
// Nó function "simulate cnc1" -> mqtt sparkplug device
let parts = context.get("parts") || 0;
const running = Math.random() > 0.1;
if (running) {
parts += 1;
}
context.set("parts", parts);
msg.payload = {
metrics: [
{ name: "spindle/speed", value: running ? Math.round(11800 + Math.random() * 400) : 0 },
{ name: "spindle/load", value: running ? Math.round(450 + Math.random() * 200) / 10 : 0 },
{ name: "coolant/temperature", value: Math.round((21 + Math.random() * 3) * 10) / 10 },
{ name: "running", value: running },
{ name: "partCount", value: parts }
]
};
return msg;
Faça o deploy. A configuração do broker publica o NBIRTH de line1, o dispositivo publica o DBIRTH de cnc1 e, a partir daí, apenas as métricas alteradas saem em mensagens DDATA.
Passo 4: tratar comandos
Quando uma aplicação envia um DCMD para spBv1.0/demo-a7f3k2/DCMD/line1/cnc1, o nó device o emite na sua saída como uma mensagem com as métricas solicitadas. Ligue a saída a um nó function que valide o pedido e aja sobre ele, por exemplo zerando o contador de peças:
// Nó function "handle DCMD" (ligado à saída do nó device)
const metrics = (msg.payload && msg.payload.metrics) || [];
for (const m of metrics) {
if (m.name === "partCount" && Number(m.value) === 0) {
flow.set("cnc1_reset_requested", true);
node.warn("Part counter reset requested");
} else {
node.warn("Ignored command for metric " + m.name);
}
}
return null;
Para que o simulador respeite o reset, leia cnc1_reset_requested do contexto de fluxo no simulador e volte parts para zero. Os pedidos de rebirth são tratados pelo próprio nó, que republica os certificados de birth.
Consuma e decodifique Sparkplug B no Node-RED
Os payloads Sparkplug são binários. Um nó mqtt in comum em spBv1.0/# entregaria um Buffer cheio de bytes Protobuf. O nó mqtt sparkplug in os decodifica:
- Adicione um nó mqtt sparkplug in usando uma configuração de broker separada, com seu próprio client ID único.
- Assine
spBv1.0/demo-a7f3k2/+/line1/#. - Ligue-o a um nó debug configurado para mostrar a mensagem completa.
Você vai ver objetos com um timestamp, um número seq e um array metrics. Para tornar os dados úteis a consumidores que não usam Sparkplug, achate-os em um topic MQTT simples por métrica:
// Nó function "sparkplug to plain topics"
// msg.topic: spBv1.0/<group>/<type>/<edge>/<device>
const t = msg.topic.split("/");
const type = t[2];
if (type !== "DDATA" && type !== "DBIRTH") {
return null;
}
const group = t[1];
const edge = t[3];
const device = t[4];
const out = [];
for (const m of msg.payload.metrics || []) {
// O Sparkplug permite "/" nos nomes de métricas; mantém cada métrica em um único nível de topic
const metric = String(m.name).replace(/\//g, "_");
let value = m.value;
if (value !== null && typeof value === "object" && typeof value.toNumber === "function") {
value = value.toNumber(); // inteiros de 64 bits podem chegar como objetos Long
}
out.push({
topic: `connectmq/demo/a7f3k2/${group}/${edge}/${device}/${metric}`,
payload: { value: value, ts: Number(m.timestamp) || Date.now() },
retain: true
});
}
return [out];
Ligue-o a um nó mqtt out com os campos de topic e retain vazios. Agora um dashboard, um script ou uma planilha pode assinar connectmq/demo/a7f3k2/demo-a7f3k2/line1/cnc1/spindle_speed sem saber nada de Protobuf. É a mesma ideia da arquitetura Sparkplug com UNS descrita em Sparkplug B e o Unified Namespace.
Confira os dados em um broker que entende Sparkplug
Os nós debug provam que o Node-RED consegue decodificar as próprias mensagens, mas vale conferir com uma ferramenta independente. A ConnectMQ decodifica payloads Sparkplug B, tanto Protobuf quanto JSON, para que você veja no portal as métricas de cada mensagem DBIRTH e DDATA em vez de bytes brutos. Ela também consegue republicar dados Sparkplug em topics ISA-95, por exemplo spBv1.0/factory1/DDATA/line1/cnc1 vira connectmq/factory1/production/line1/cnc1/telemetry, o que entrega a etapa de achatamento acima sem que você precise manter o nó function.
Para experimentar, crie um broker gratuito no portal da ConnectMQ e altere a configuração de broker Sparkplug no Node-RED para o host desse broker, porta 8883 com TLS, e o nome de usuário, a senha e o client ID gerados. Depois abra o explorador de topics ao vivo e veja os births e os dados chegarem decodificados.
Armadilhas comuns do Sparkplug
- Reutilizar client IDs. Dois edge nodes com o mesmo client ID MQTT ficam derrubando um ao outro, e cada reconexão gera um novo NDEATH e um novo NBIRTH. Todo edge node precisa de um client ID único.
- Mudar tipos de métricas. Uma métrica declarada como Int32 não pode passar a carregar um float depois. Corrija a definição e dispare um rebirth.
- Births ausentes nos consumidores. Um consumidor que inicia depois do birth só vê DDATA com as métricas alteradas. Ele deve enviar um NCMD de Rebirth, ou ler o estado retained em outro lugar, antes de confiar na própria visão.
- Ignorar números de sequência. O campo
seqvai de 0 a 255 e reinicia. Uma lacuna significa que uma mensagem foi perdida e que um pedido de rebirth é adequado. - Níveis de topic. Os IDs de group, edge e device são níveis únicos de topic e não podem conter
/,+ou#. - Expectativas de QoS. As mensagens de dados normalmente usam QoS 0, enquanto NDEATH e STATE usam QoS 1. Garanta que o plano do seu broker suporte QoS 1.
Do piloto à produção
Uma arquitetura Sparkplug concentra no broker todos os edge nodes, aplicações host e historiadores, então o broker vira infraestrutura crítica. Use conexões autenticadas via TLS, client IDs únicos vinculados a credenciais e um broker que continue acessível tanto da planta quanto da nuvem. Um broker MQTT na nuvem atende a implantações com vários sites, e um broker MQTT gerenciado elimina o trabalho operacional de rodá-lo por conta própria. Para alimentar o Sparkplug a partir de controladores existentes, combine este fluxo com o Node-RED com OPC UA como fonte de dados. Os mesmos dados de máquina, uma vez padronizados, também servem de base para um gêmeo digital de uma usina ou de uma planta de manufatura. Se você está começando com os nós MQTT, comece pelo tutorial Node-RED MQTT.
Rode seus edge nodes Sparkplug na ConnectMQ
Cadastre-se em app.connectmq.com no plano Serverless gratuito, sem cartão de crédito. Crie um broker, aponte para ele a configuração Sparkplug do Node-RED com as credenciais geradas e inspecione no portal, em poucos minutos, births, dados e deaths decodificados.
Perguntas frequentes
Qual pacote do Node-RED suporta Sparkplug B?
O node-red-contrib-mqtt-sparkplug-plus é a opção mais completa. Ele cuida por você de births, deaths, números de sequência, pedidos de rebirth e da codificação e decodificação Protobuf.
Posso ler mensagens Sparkplug B com um nó mqtt in comum?
Você vai receber os bytes Protobuf brutos como um Buffer. Use o nó mqtt sparkplug in, ou um decodificador Protobuf em um nó function, para transformá-los em métricas legíveis.
O Node-RED envia o NDEATH automaticamente?
Sim. A configuração de broker Sparkplug registra o NDEATH como Last Will MQTT ao se conectar, então o broker o publica se o edge node se desconectar de forma inesperada.
Por que só algumas métricas aparecem nas minhas mensagens DDATA?
O Sparkplug reporta por exceção: o DDATA traz apenas as métricas que mudaram. A lista completa e os valores atuais estão no DBIRTH, então os consumidores precisam guardar o birth para interpretar os dados seguintes.



