Monitr Managed — logotipoMonitr Managed

Integração PLC→MQTT: padrões de tópicos e payloads para escalabilidade

Rodrigo5 min de leitura

A ponte entre PLC/RTU e MQTT define o quanto sua telemetria vai escalar com previsibilidade. Sem padrões claros de tópicos e payloads, o projeto degrada em caos: nomes diferentes para a mesma variável, unidades inconsistentes e painéis difíceis de manter. Este guia resume convenções práticas para você padronizar a publicação PLC→MQTT (direta ou via gateway) desde o primeiro dia.

1) Identidade, contexto e multi-site

Padronize a identidade no nível do cliente MQTT e no caminho do tópico:

  • ClientID do gateway: gw-<org>-<site>-<area>-<host> (ex.: gw-acme-plantaA-l1-opc).
  • Ambientes: prefira prefixar (ex.: prod/, hml/) para separar dev/homolog/produção.
  • Organização e local: normalize com org/<org>/<site>/... para suportar multi-tenant.

2) Convenção de tópicos (árvore estável)

Crie uma árvore que reflita o domínio e permita filtros/ACLs simples. Um modelo comum:

prod/org/<org>/<site>/<area>/<equip>/<dominio>/<variavel>

Domínios recomendados:

  • process — variáveis de processo (nível, pressão, estado de bomba).
  • electrical — grandezas elétricas (corrente, potência).
  • alarms — árvore de estado de alarmes (retido) e eventos (não retidos).
  • meta — metadados de equipamento (firmware, modelo, hora do boot).
  • gatewaystatus do gateway (LWT, health do buffer).

Exemplos:

prod/org/acme/plantaA/linha1/bomba03/process/state
prod/org/acme/plantaA/linha1/tanque01/process/level_m
prod/org/acme/plantaA/linha1/bomba03/alarms/state/overcurrent
prod/org/acme/plantaA/linha1/bomba03/alarms/events/overcurrent
prod/org/acme/plantaA/gateway/status

Boas práticas:

  • Use snake_case para variáveis e evite acentos.
  • Separe estado (retido) de evento (não retido) em subárvores claras.
  • Evite codificar unidades no tópico (use _m, _bar apenas para legibilidade opcional).

3) Contrato de payload (JSON enxuto e versionado)

Padronize um formato mínimo e estável, versionado e com carimbo temporal.

{
  "v": 1,
  "ts": 1730252400123,   // epoch ms
  "value": 3.42,
  "unit": "m",
  "q": "ok"              // qualidade: ok, bad, suspect
}

Para boolean e strings:

{"v":1,"ts":1730252401000,"value":true}
{"v":1,"ts":1730252402000,"value":"on"}

Metadados (nome “bonito”, limites, descrição) ficam fora da telemetria, em um catálogo de tags (meta service, planilha ou coleção em DB). Isso mantém o payload leve.

3.1 Versão e depreciação

  • Incrementar v ao mudar semântica/campos.
  • Manter consumidores antigos por um ciclo (ex.: 90 dias), publicando v1 e v2 em paralelo se necessário.
  • Documentar mudanças em um CHANGELOG de payloads.

4) QoS, retained e LWT

  • QoS: 1 é o padrão para estados e medidas; 0 apenas para streams efêmeros; 2 só quando idempotência é crítica.
  • Retained: apenas para estado (ex.: .../process/state, .../gateway/status).
  • LWT: publicar “offline” no tópico .../gateway/status (retido, QoS 1) se o cliente cair.
// Conexão do gateway
ClientID: gw-acme-plantaA-l1-opc
LWT topic: prod/org/acme/plantaA/gateway/status
LWT payload: {"v":1,"ts":1730252410000,"value":"offline"}
LWT QoS: 1, retained: true

// Após conectar:
Publish: prod/org/acme/plantaA/gateway/status
Payload: {"v":1,"ts":1730252410500,"value":"online"}
QoS: 1, retained: true

5) Catálogo de tags (a fonte da verdade)

Cadastre cada variável publicável com, no mínimo:

  • tag_id (único), nome lógico, unidade, tipo (numérico, boolean, string), faixa (min/max), frequência e tópico.
  • origem (PLC DB/endereçamento), conversão (escala/offset), histerese/debounce.
  • proprietário (time), versão de payload aplicável e status (ativo/obsoleto).

O gateway usa o catálogo para validar e “lintar” mensagens antes de publicar.

6) Deduplicação, idempotência e buffer offline

  • Store & forward: persista mensagens no edge quando off-line e reenvie na ordem.
  • Idempotência: inclua ts (epoch ms) e, opcionalmente, seq incremental por origem.
  • Deduplicação: no consumidor, descarte mensagens com ts ≤ último processado para aquela tag.
{"v":1,"ts":1730252423456,"seq":8712,"value":2.81,"unit":"bar","q":"ok"}

7) Tratamento e normalização no gateway

Mesmo quando o PLC envia dados, o gateway é o melhor lugar para normalizar:

  • Conversões: 4–20 mA → engenharia, inteiros Modbus → escala correta.
  • Filtros: média móvel, histerese, debouncing de digitais.
  • Agregações: média/mín/máx por janela (ex.: 1 s → 10 s) para reduzir tráfego.
  • Compressão (opcional): compactar lotes no link edge→nuvem quando suportado.

8) Segurança e ACL por tópico

  • TLS no broker; usuários por função (gateway, dashboard, integrador).
  • ACL: gateway publica apenas prod/org/acme/plantaA/#; dashboard apenas assina.
  • Evite expor broker à internet sem camada de proxy/VPN e controle de origem.

9) Testes de contrato (CI/CD da telemetria)

Valide payloads e tópicos continuamente para evitar regressões.

  • JSON Schema por versão de payload (ex.: v1.schema.json).
  • Lint de tópicos: regex que impede caminhos fora do padrão.
  • Testes de cenários: queda de rede, reenvio, mensagens fora de ordem, pacotes duplicados.
// Regex exemplo (simplificado) para process/state boolean
^prod\/org\/[^\/]+\/[^\/]+\/[^\/]+\/[^\/]+\/process\/state$

10) Estados vs eventos (e retidos)

  • Estado (retido): refletir condição atual (on/off, healthy/faulted).
  • Evento (não retido): mudanças pontuais, com carimbo ts único.
// Estado (retido)
prod/org/acme/plantaA/linha1/bomba03/process/state
{"v":1,"ts":1730252430000,"value":"on"}

// Evento (não retido)
prod/org/acme/plantaA/linha1/bomba03/alarms/events/overcurrent
{"v":1,"ts":1730252432000,"value":true}

11) Observabilidade do próprio pipeline

  • Métricas do gateway: fila do buffer, uso de disco, taxa de publicação, LWT “online”.
  • Métricas do broker: conexões ativas, inflight, taxa msg/s, erros de ACL.
  • Dead letter: tópico/coleção para mensagens rejeitadas pelo validador (com motivo).

12) Erros comuns (e como evitar)

  1. Nomeação ad-hoc de tópicos → impossível filtrar/ACL. Solucione: convenção escrita + lint.
  2. Payload verborrágico com metadados repetidos → custo/latência. Solucione: catálogo externo.
  3. QoS 2 em tudo → overhead sem ganho. Solucione: QoS 1 como padrão.
  4. Retained em eventos → painéis “congelados”. Solucione: separar estado vs evento.
  5. Sem buffer offline → buracos no histórico. Solucione: store & forward com persistência.
  6. Falta de versão no payload → quebras silenciosas. Solucione: campo v e CHANGELOG.

13) Checklist de produção

  1. Defina árvore de tópicos e publique uma RDI (Referência de Dados & Integração).
  2. Implemente payload v1 com ts, value, unit, q; cadastre o catálogo.
  3. Configure QoS 1, retained em estados e LWT por gateway.
  4. Habilite store & forward, seq e deduplicação no consumidor.
  5. Ative TLS e ACL por função; separe ambientes (hml vs prod).
  6. Automatize testes de contrato (JSON Schema, regex de tópicos) no CI.
  7. Monitore métricas do broker/gateway e crie um dead letter para mensagens inválidas.
  8. Documente o processo de depreciação e janela de coexistência entre versões.

Conclusão: escalar PLC→MQTT com qualidade depende menos de ferramentas e mais de governança: árvore de tópicos consistente, contrato de payload versionado, catálogo de tags e disciplina operacional (QoS/retained/LWT, buffer offline, testes de contrato). Com esses pilares, sua telemetria cresce com segurança, previsibilidade e baixo custo de manutenção.

Integração PLC→MQTT: padrões de tópicos e payloads para escalabilidade — Monitr