IoT industrial

Como Projetar Topics MQTT Baseados na ISA-95

Como codificar a hierarquia de equipamentos ISA-95 em topics MQTT: ordem dos níveis, projeto da folha, planejamento de curingas, escolhas de payload e armadilhas comuns, além de como republicar dados Sparkplug B na mesma árvore.

Diagrama de topics MQTT ISA-95 mapeando os níveis de empresa, site, área, linha e máquina em um caminho de topic
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

Topics MQTT ISA-95 colocam a hierarquia de equipamentos da planta diretamente no caminho do topic, de modo que acme/dallas/packaging/line-02/filler/telemetry diz a cada assinante exatamente de onde vem um valor. Neste guia você vai aprender a codificar cada nível ISA-95, a projetar a folha do topic, a planejar as assinaturas com curinga antes de precisar delas e quais armadilhas geram mais retrabalho quando um namespace já está em produção.

Por que codificar a ISA-95 nos topics MQTT

Topics MQTT são strings livres separadas por barras, e o broker MQTT não atribui a elas nenhum significado além de casar assinaturas. Essa liberdade é perigosa na escala de uma planta, seja uma fábrica em Joinville, uma mineradora ou uma usina. Se cada integrador inventar uma estrutura, os consumidores acabam com uma tabela de consulta por fonte.

A hierarquia de equipamentos ISA-95 resolve isso ao oferecer uma estrutura que já existe na documentação da planta, no MES e no sistema de manutenção. Codificá-la nos topics traz três propriedades de graça:

  • Descoberta. Qualquer pessoa que conheça a planta encontra um valor navegando pela árvore.
  • Contexto. O topic carrega o endereço do ativo, então os payloads não precisam repeti-lo.
  • Assinatura seletiva. Os curingas correspondem naturalmente a escopos organizacionais: um site, uma área, todas as envasadoras.

Se você precisa revisar os próprios níveis, leia primeiro sobre a hierarquia de equipamentos ISA-95.

O padrão básico

O padrão canônico posiciona os níveis do mais amplo ao mais restrito, seguidos por um namespace que diz que tipo de dado a mensagem contém:

<enterprise>/<site>/<area>/<work center>/<work unit>/<namespace>[/<detail>]

acme/dallas/packaging/line-02/filler/telemetry
acme/dallas/packaging/line-02/filler/state
acme/dallas/packaging/line-02/filler/alarms
acme/dallas/packaging/line-02/filler/events/batch-complete
acme/dallas/packaging/line-02/filler/cmd/stop

Regras para cada nível

Nível Regra Exemplo
Empresa Um nome curto e estável; omita apenas se o broker atender uma única empresa acme
Site Código de localização que sobreviva a reorganizações dallas, izmir
Área Área de função ou de produto packaging, utilities
Centro de trabalho Linha, célula, célula de processo, unidade ou zona de armazenagem line-02, cell-03
Unidade de trabalho Máquina ou unidade, de preferência pela tag do ativo filler, cnc-01
Namespace Vocabulário fixo telemetry, state, alarms, events, cmd

Mantenha a profundidade fixa nos topics de equipamento. Quando todas as unidades de trabalho ficam no nível cinco, +/+/+/+/+/state retorna o estado de todas as máquinas da empresa, e a posição de cada nível no caminho fica garantida.

Projetando a folha

O namespace e o que vem depois dele é onde acontece a maioria dos debates de projeto. Há duas opções principais para a telemetria.

Um objeto por equipamento. Todos os valores atuais de uma máquina vão em um único documento JSON em .../filler/telemetry. Isso é compacto, mantém valores relacionados consistentes no tempo e exige apenas uma retained message por máquina.

{ "ts": "2026-10-16T08:15:02Z", "speed_bpm": 118.4, "temp_c": 41.2, "good_count": 18342, "v": 1 }

Um topic por métrica. Cada valor tem seu próprio topic, como .../filler/telemetry/speed_bpm, com um payload escalar ou um JSON pequeno. Isso combina naturalmente com ferramentas baseadas em tags, como sistemas SCADA, e os consumidores podem assinar exatamente os sinais de que precisam.

As duas são válidas. Escolha por namespace e documente. Um híbrido comum é um objeto para a telemetria e valores retidos por topic para state e alguns KPIs-chave.

Planeje suas assinaturas com curinga

Antes de finalizar a estrutura, anote as assinaturas de que seus consumidores vão precisar e confira se cada uma é um único filtro com curinga:

Consumidor Precisa de Assinatura
Dashboard do site Tudo de um site acme/dallas/#
Supervisor de envase Todos os estados de uma área acme/dallas/packaging/+/+/state
Analytics da frota Todas as envasadoras, em qualquer lugar acme/+/+/+/filler/telemetry
Serviço de alarmes Todos os alarmes acme/+/+/+/+/alarms
Historiador Toda a telemetria acme/+/+/+/+/telemetry

Se um escopo necessário exigir várias assinaturas ou filtragem no cliente, a estrutura está jogando contra você. Normalmente isso significa que falta um nível, que a ordem é inconsistente ou que o vocabulário das folhas está solto demais.

Publicando topics ISA-95 a partir do código

Gerar os topics em um só lugar evita que erros de digitação criem ramos indevidos. Este helper em Python monta e valida o caminho e depois publica o estado e a telemetria como mensagens retidas. Instale o cliente com pip install "paho-mqtt>=2.0". Ele usa o servidor MQTT público com um prefixo de demonstração; em um broker privado, defina PREFIX com o nome da sua empresa.

import json
import re
import threading
from dataclasses import dataclass
from datetime import datetime, timezone

import paho.mqtt.client as mqtt

PREFIX = "connectmq/demo/r8t5"      # no seu próprio broker: "acme"
SAFE = re.compile(r"^[a-z0-9]+(-[a-z0-9]+)*$")
NAMESPACES = {"telemetry", "state", "alarms", "events", "cmd"}

@dataclass(frozen=True)
class Asset:
    site: str
    area: str
    work_center: str
    work_unit: str

    def topic(self, namespace: str) -> str:
        for level in (self.site, self.area, self.work_center, self.work_unit):
            if not SAFE.match(level):
                raise ValueError(f"invalid level: {level!r}")
        if namespace not in NAMESPACES:
            raise ValueError(f"unknown namespace: {namespace!r}")
        return f"{PREFIX}/{self.site}/{self.area}/{self.work_center}/{self.work_unit}/{namespace}"

filler = Asset("dallas", "packaging", "line-02", "filler")

connected = threading.Event()

def on_connect(client, userdata, flags, reason_code, properties):
    print("connected:", reason_code)
    connected.set()

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="isa95-pub-r8t5")
client.on_connect = on_connect
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_start()
connected.wait(timeout=10)

client.publish(filler.topic("state"), "running", qos=1, retain=True).wait_for_publish()
telemetry = {"ts": datetime.now(timezone.utc).isoformat(), "speed_bpm": 118.4, "temp_c": 41.2, "v": 1}
client.publish(filler.topic("telemetry"), json.dumps(telemetry), qos=1, retain=True).wait_for_publish()
print("published to", filler.topic("telemetry"))

client.loop_stop()
client.disconnect()

Verifique com um curinga que corresponda à tabela acima:

mosquitto_sub -h broker.connectmq.com -p 1883 -i isa95-sub-r8t5 -t "connectmq/demo/r8t5/+/packaging/+/+/state" -v

O servidor MQTT público (gratuito) serve para testes, pode ser lido por qualquer pessoa e permite 8 níveis de topic, por isso o prefixo de demonstração substitui aqui o nível da empresa. Reserve nomes e valores reais de ativos, e qualquer dado de produção, para um broker privado.

Trazendo o Sparkplug B para a árvore ISA-95

Topics Sparkplug B seguem um formato fixo, spBv1.0/<group>/<type>/<edge node>/<device>, com payloads Protobuf. Eles não seguem a ISA-95, e consumidores que não entendem Sparkplug não conseguem lê-los. Em vez de abandonar o Sparkplug na borda, republique seus dados na sua árvore ISA-95.

O ConnectMQ faz isso automaticamente: decodifica payloads Sparkplug B, em Protobuf ou JSON, e os republica em topics ISA-95. Por exemplo, spBv1.0/factory1/DDATA/line1/cnc1 é republicado como connectmq/factory1/production/line1/cnc1/telemetry. Escolha IDs de grupo e de edge node do Sparkplug que carreguem nomes significativos da planta, para que os caminhos ISA-95 resultantes sejam legíveis. Os prós e contras das duas abordagens são discutidos em MQTT, Sparkplug B e o Unified Namespace.

Armadilhas a evitar

  1. Barra inicial. /acme/dallas cria um primeiro nível vazio e divide as assinaturas.
  2. Maiúsculas e minúsculas misturadas. Topics diferenciam maiúsculas de minúsculas; Line-02 e line-02 são ramos diferentes.
  3. Nomes de protocolo ou fabricante no caminho. acme/dallas/opcua/... acopla os consumidores à tecnologia de integração atual.
  4. Profundidade variável. Pular um nível para uma máquina quebra os curingas posicionais. Use um centro de trabalho de preenchimento.
  5. Timestamps ou IDs nos topics. Topics como .../telemetry/20261016 criam ramos ilimitados e acúmulo de retained messages.
  6. Reter eventos. Retenha estado, não fluxos de eventos; um novo assinante não deveria receber um "batch complete" antigo.
  7. Comandos sem requisição e resposta. Use response topics e correlation data do MQTT 5 em cmd, para que quem envia saiba se o comando teve sucesso.
  8. Caminhos longos em links limitados. Topics longos adicionam bytes a cada mensagem. Os topic aliases do MQTT 5 reduzem essa sobrecarga sem mudar o projeto.

Documente o padrão antes da implantação

Um padrão de topics que existe só na cabeça de um engenheiro será quebrado pelo segundo integrador. Antes que o primeiro gateway entre em operação, escreva um padrão de uma página que cubra:

  • A ordem dos níveis e os caracteres permitidos em cada nível.
  • A lista de namespaces e o que cada um pode conter, com um payload de exemplo.
  • Quais topics são retidos e quais não são.
  • O formato de timestamp, o fuso horário e a convenção de unidades.
  • Quem aprova novos sites, áreas e centros de trabalho, e como as solicitações são feitas.

Entregue essa página a cada integrador de sistemas e fornecedor de gateway, junto com o helper de topics acima ou seu equivalente na linguagem deles. Quando o padrão e o código concordam, a maioria dos erros é pega antes de chegar ao broker.

A segurança merece uma nota própria: emita uma credencial por gateway e aplicação, para que cada publicador seja identificável e revogável, e use TLS na porta 8883 em todo lugar fora do laboratório. Nossas boas práticas de segurança MQTT cobrem o restante.

Uma árvore ISA-95 consistente também é a base de dados de um gêmeo digital da planta. Para árvores completas prontas para copiar, veja a estrutura de topics UNS. Para a arquitetura ao redor delas, o guia de MQTT para IoT industrial é o ponto de partida.

Rode topics MQTT ISA-95 no ConnectMQ

O ConnectMQ é um broker MQTT gerenciado que entende estruturas de topics industriais: detecta topics ISA-95 e de Unified Namespace, mostra os dispositivos por nível ISA-95 no portal e republica Sparkplug B na sua árvore. Crie um broker no plano gratuito Serverless em app.connectmq.com, sem cartão de crédito, e publique hoje mesmo seu primeiro ramo ISA-95.

Perguntas frequentes

O nome da empresa deve ser o primeiro nível do topic?

Sim, se o broker puder algum dia atender mais de uma empresa ou unidade de negócio. Em um broker de uma única empresa você pode omiti-lo, mas adicioná-lo depois significa renomear todos os topics.

Como lidar com máquinas que não pertencem a uma linha?

Dê a elas um centro de trabalho de preenchimento, como standalone ou shared, para que fiquem na mesma profundidade que todo o resto.

Posso usar espaços ou letras maiúsculas em topics MQTT ISA-95?

O MQTT permite, mas isso causa bugs sutis. Use apenas letras minúsculas, dígitos e hifens.

Topics ISA-95 funcionam com MQTT 3.1.1?

Sim. O projeto de topics independe da versão. O MQTT 5 acrescenta extras úteis, como topic aliases e response topics para comandos.

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.