Node-RED

Assinatura MQTT Dinâmica no Node-RED: Mude Topics em Tempo de Execução

Entenda como funciona o modo de assinatura dinâmica do node mqtt in, como assinar e cancelar assinaturas com msg.action, como restaurar as assinaturas depois de um restart e como controlar tudo a partir de um dashboard ou de uma lista de dispositivos.

Fluxo do Node-RED enviando ações de subscribe e unsubscribe para um node mqtt in em uma configuração de assinatura MQTT dinâmica
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 modo de assinatura MQTT dinâmica do Node-RED permite que um fluxo decida quais topics escutar enquanto está rodando, em vez de fixar um único topic no node mqtt in. Neste tutorial você vai configurar um assinante dinâmico, adicionar e remover topics com msg.action, listar as assinaturas ativas, restaurá-las depois de um restart e controlar tudo a partir de uma lista simples de dispositivos.

Quando você precisa de assinaturas dinâmicas

Um node mqtt in comum assina um filtro de topic fixo no momento do deploy. Isso atende à maioria dos fluxos, principalmente quando um wildcard como site/+/telemetry já cobre todos os dispositivos. As assinaturas dinâmicas compensam a ligação extra quando:

  • Um operador de uma planta em Campinas escolhe em um dashboard qual máquina acompanhar, e você quer que apenas os dados daquela máquina trafeguem.
  • A lista de dispositivos fica em um banco de dados ou em um topic de configuração e muda sem redeploy.
  • Um wildcard traria muito mais tráfego do que o necessário, por exemplo # em um site movimentado.
  • Você quer seguir temporariamente um topic de debug durante uma investigação e depois descartá-lo.
  • Você está perto do limite de assinaturas de um broker e precisa ser seletivo.

O último ponto importa em infraestrutura compartilhada. O servidor MQTT público (gratuito) em broker.connectmq.com, por exemplo, permite 10 assinaturas por cliente, então assinar sob demanda é uma forma prática de ficar dentro do limite. Lembre-se de que ele serve apenas para testes e protótipos, não para dados de produção.

Configure o node mqtt in no modo dinâmico

As assinaturas dinâmicas chegaram no Node-RED 2.2 e fazem parte de todas as versões atuais. Para habilitá-las:

  1. Arraste um node mqtt in para o canvas e abra-o.
  2. Selecione ou crie um node de configuração de broker. Para testes, use o servidor broker.connectmq.com, a porta 1883 e um client ID exclusivo e não vazio, como nr-dyn-91c4.
  3. Mude Action de "Subscribe to single topic" para Dynamic subscription.
  4. Defina Output como "auto-detect" ou "a parsed JSON object", como de costume.
  5. Faça o deploy.

O node agora tem uma porta de entrada, e o status mostra "connected", mas ele ainda não assina nada. Daqui em diante, tudo é controlado pelas mensagens que você envia para essa entrada.

Você também vai notar a opção Connect automatically no node de configuração do broker. Deixe-a marcada, a menos que também queira controlar a própria conexão com as ações connect e disconnect, abordadas mais adiante.

Ações de assinatura MQTT dinâmica no Node-RED

O node reage a msg.action e msg.topic:

msg.action msg.topic Resultado
subscribe "a/b/c" Assina um topic com o QoS padrão do node
subscribe ["a/+", "b/#"] Assina vários filtros de topic
subscribe { "topic": "a/b", "qos": 1 } Assina com opções explícitas
unsubscribe "a/b/c" ou um array Remove essas assinaturas
unsubscribe true Remove todas as assinaturas deste node
getSubscriptions não é necessário Envia a lista atual em msg.payload
connect / disconnect não é necessário Abre ou fecha a conexão com o broker

A forma de objeto também aceita opções de assinatura do MQTT 5, como nl (no local), rap (retain as published) e rh (retain handling), quando o node do broker usa a versão 5 do protocolo.

As mensagens recebidas nos topics adicionados dinamicamente saem pela mesma saída de uma assinatura normal, com msg.topic definido como o topic real, então o restante do fluxo não muda.

Um exemplo funcional no servidor MQTT público

Inicie um publicador que simula três máquinas. Substitua 91c4 pela sua própria sequência aleatória para que seus topics sejam exclusivos:

for i in $(seq 1 300); do
  for m in cnc1 cnc2 press1; do
    mosquitto_pub -h broker.connectmq.com -p 1883 -i demo-dyn-pub-91c4 \
      -t "connectmq/demo/91c4/line1/$m/telemetry" \
      -m "{\"machine\":\"$m\",\"load\":$((RANDOM % 100))}"
  done
  sleep 3
done

Agora importe o fluxo abaixo. Ele tem nodes inject que assinam cnc1, adicionam press1, listam as assinaturas e cancelam todas.

[
  {"id":"tabd","type":"tab","label":"Dynamic subscribe"},
  {"id":"brkd","type":"mqtt-broker","name":"ConnectMQ public","broker":"broker.connectmq.com","port":"1883","clientid":"nr-dyn-91c4","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true},
  {"id":"i1","type":"inject","z":"tabd","name":"watch cnc1","props":[{"p":"action","v":"subscribe","vt":"str"},{"p":"topic","v":"connectmq/demo/91c4/line1/cnc1/telemetry","vt":"str"}],"repeat":"","once":false,"x":130,"y":60,"wires":[["dyn"]]},
  {"id":"i2","type":"inject","z":"tabd","name":"add press1 (QoS 1)","props":[{"p":"action","v":"subscribe","vt":"str"},{"p":"topic","v":"{\"topic\":\"connectmq/demo/91c4/line1/press1/telemetry\",\"qos\":1}","vt":"json"}],"repeat":"","once":false,"x":150,"y":110,"wires":[["dyn"]]},
  {"id":"i3","type":"inject","z":"tabd","name":"list","props":[{"p":"action","v":"getSubscriptions","vt":"str"}],"repeat":"","once":false,"x":110,"y":160,"wires":[["dyn"]]},
  {"id":"i4","type":"inject","z":"tabd","name":"unsubscribe all","props":[{"p":"action","v":"unsubscribe","vt":"str"},{"p":"topic","v":"true","vt":"bool"}],"repeat":"","once":false,"x":140,"y":210,"wires":[["dyn"]]},
  {"id":"dyn","type":"mqtt in","z":"tabd","name":"dynamic","topic":"","qos":"0","datatype":"auto-detect","broker":"brkd","inputs":1,"x":380,"y":130,"wires":[["dbgd"]]},
  {"id":"dbgd","type":"debug","z":"tabd","name":"received","active":true,"complete":"true","x":560,"y":130,"wires":[]}
]

Clique em "watch cnc1" e apenas os dados de cnc1 aparecem na barra lateral de debug. Clique em "add press1" e as duas máquinas aparecem. "list" mostra as assinaturas ativas, e "unsubscribe all" interrompe o fluxo de dados sem redeploy.

Restaure as assinaturas depois de um restart

Esta é a parte que a maioria esquece: as assinaturas dinâmicas vivem na memória. Quando você reimplanta o node, reinicia o Node-RED ou a conexão com o broker cai e reconecta com uma sessão limpa, o node pode voltar sem nenhuma assinatura. Planeje isso desde o início.

Um padrão confiável é guardar a lista desejada em um contexto persistente e reaplicá-la na inicialização:

// Function node "apply subscriptions"
// Entrada: msg.payload = array de IDs de máquinas, ex.: ["cnc1", "press1"]
const prefix = "connectmq/demo/91c4/line1/";
const wanted = Array.isArray(msg.payload) ? msg.payload : [];

global.set("watchedMachines", wanted, "file");   // requer um context store em arquivo

// Duas mensagens, em ordem, por uma única saída
return [[
    { action: "unsubscribe", topic: true },
    { action: "subscribe", topic: wanted.map(m => ({ topic: prefix + m + "/telemetry", qos: 1 })) }
]];

Os colchetes duplos enviam as duas mensagens em sequência pela única saída, então o unsubscribe sempre chega antes do novo subscribe. Depois, adicione um node inject configurado para disparar uma vez após alguns segundos, com o payload definido como a propriedade global #:(file)::watchedMachines (a sintaxe que o Node-RED usa para ler de um context store nomeado), e ligue-o à mesma função. A configuração do armazenamento em arquivo está explicada no nosso guia sobre contexto no Node-RED.

Limpar tudo antes de reassinar mantém o estado do node previsível: o que você guardou é exatamente o que você recebe.

Controlando assinaturas por um dashboard ou topic de configuração

Como a entrada é apenas uma mensagem, qualquer coisa pode controlá-la:

  • Dropdown no dashboard. Um dropdown do Dashboard 2.0 envia a máquina selecionada; um node Change monta msg.action = "subscribe" e o topic. Envie antes um unsubscribe para a seleção anterior.
  • Topic de configuração. Publique uma lista JSON retida de máquinas em um topic como connectmq/demo/91c4/config/watchlist. Um node mqtt in comum a lê e alimenta a função acima, de modo que alterar a mensagem retida reconfigura todas as instâncias do Node-RED que estiverem escutando.
  • Endpoint HTTP. Um node http in pode receber uma lista de outro sistema e aplicá-la da mesma forma.

O topic de configuração retido é especialmente elegante: o broker entrega a lista mais recente ao Node-RED assim que ele assina, o que também resolve o problema do restart sem armazenamento em arquivo. Se precisar limpar essa lista depois, veja nossa nota sobre como apagar retained messages.

Conexões dinâmicas com o broker

O mesmo mecanismo controla as conexões. Enviar msg.action = "disconnect" fecha a conexão com o broker e connect a reabre. Com connect, você também pode passar msg.broker contendo propriedades como broker, port, clientid, username e password para sobrescrever o node de configuração em tempo de execução. Isso é útil para alternar entre um broker de testes e o de produção, mas mantenha as credenciais fora dos fluxos: leia-as de variáveis de ambiente em um function node em vez de digitá-las em nodes inject.

Checklist de armadilhas

  1. Sem fio de entrada, sem assinaturas. Um node dinâmico não assina nada até receber uma mensagem.
  2. Client IDs duplicados. Duas instâncias do Node-RED com o mesmo client ID vão derrubar uma à outra do broker; cada instância precisa do próprio ID.
  3. Filtros sobrepostos. Assinar ao mesmo tempo line1/# e line1/cnc1/telemetry pode entregar a mesma mensagem duas vezes. Mantenha os filtros disjuntos.
  4. Limites. Respeite os limites de assinaturas e de profundidade de topic do broker; o servidor MQTT público limita os topics a 8 níveis.
  5. Estado perdido. Guarde a lista desejada e reaplique-a na inicialização, como mostrado acima.
  6. Saída errada para o topic errado. Todos os topics dinâmicos compartilham uma única saída, então roteie com um node Switch em msg.topic se eles precisarem de tratamentos diferentes.

Se algo simplesmente não conecta, percorra o guia Node-RED MQTT não conecta antes de depurar a lógica de assinatura. Todos os detalhes das propriedades de entrada do node estão na documentação oficial dos nodes MQTT do Node-RED e no painel de ajuda integrado do node.

Use assinaturas dinâmicas com o ConnectMQ

Em um broker privado você tem espaço para crescer: o ConnectMQ é um broker MQTT gerenciado com suporte a MQTT 3.1.1 e 5.0, então as opções de assinatura do MQTT 5 na forma de objeto funcionam como esperado. O portal inclui um explorador de topics ao vivo, que facilita confirmar quais topics os dispositivos realmente publicam antes de montar uma lista de acompanhamento. Crie um broker no plano Serverless (Free) em app.connectmq.com, sem cartão de crédito, cole as credenciais no seu node de broker com TLS na porta 8883 e seu fluxo dinâmico roda sem alterações. Para entender as opções de hospedagem, leia sobre como rodar um broker MQTT na nuvem ou comece pelo tutorial de MQTT no Node-RED se esses nodes forem novidade para você.

Perguntas frequentes

Qual versão do Node-RED suporta assinaturas MQTT dinâmicas?

O Node-RED 2.2 e posteriores. Se o seu node mqtt in não tiver a opção "Dynamic subscription", atualize o Node-RED.

As assinaturas dinâmicas sobrevivem a um redeploy?

Não. Elas ficam na memória, então guarde a lista desejada em um contexto persistente ou em um topic de configuração retido e reaplique-a quando o fluxo iniciar.

Posso definir o QoS por topic com assinaturas dinâmicas?

Sim. Envie um objeto como { "topic": "a/b", "qos": 1 }, ou um array desses objetos, em msg.topic, com msg.action definido como subscribe.

Como vejo o que o node está assinando?

Envie uma mensagem com msg.action definido como getSubscriptions. O node entrega a lista atual de assinaturas em msg.payload.

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.