Node-RED

Node-RED Sparkplug B: publicando e consumindo dados de borda

Transforme o Node-RED em um edge node Sparkplug B com o node-red-contrib-mqtt-sparkplug-plus: defina métricas, publique NBIRTH, DBIRTH e DDATA, trate comandos DCMD e depois decodifique os payloads Protobuf em topics MQTT simples.

Edge node Node-RED Sparkplug B publicando mensagens de birth e de dados de uma máquina CNC em um broker MQTT
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

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 NBIRTH quando se conecta e registra um NDEATH como seu Last Will MQTT. Os dispositivos atrás dele publicam DBIRTH e DDEATH.
  • Report by exception: depois do birth, as mensagens DDATA contêm apenas as métricas que mudaram.
  • Comandos: as aplicações enviam mensagens NCMD e DCMD, 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, porta 1883, 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 com spBv1.0, então você não pode usar aqui o prefixo habitual connectmq/demo/.... Em vez disso, torne o group ID único, substituindo a7f3k2 por 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:

  1. Adicione um nó mqtt sparkplug in usando uma configuração de broker separada, com seu próprio client ID único.
  2. Assine spBv1.0/demo-a7f3k2/+/line1/#.
  3. 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

  1. 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.
  2. 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.
  3. 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.
  4. Ignorar números de sequência. O campo seq vai de 0 a 255 e reinicia. Uma lacuna significa que uma mensagem foi perdida e que um pedido de rebirth é adequado.
  5. Níveis de topic. Os IDs de group, edge e device são níveis únicos de topic e não podem conter /, + ou #.
  6. 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.

Artigos relacionados

Node-RED Dashboard 2.0 com MQTT: gauges, gráficos e controles

Um tutorial prático do Node-RED Dashboard 2.0: assine telemetria MQTT ao vivo, exiba-a em gauges e em um gráfico de linha e controle um dispositivo com um switch que publica comandos e reflete o estado real.

9 min de leitura

Cliente OPC UA no Node-RED para MQTT com topics ISA-95

Use o node-red-contrib-opcua para assinar variáveis OPC UA em um CLP ou servidor de simulação, mapear node IDs para topics MQTT no estilo ISA-95 e publicar os valores com qualidade e timestamps.

10 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.