IoT industrial

Eclipse Tahu: Implementações de Referência do Sparkplug em Java, Python e C

O Eclipse Tahu é a implementação de referência do Sparkplug. Este guia apresenta as suas bibliotecas em Java, Python e C, mostra como compilá-las e conecta um edge node Python baseado no Tahu a um broker MQTT.

Bibliotecas do Eclipse Tahu em Java, Python e C conectando um edge node Sparkplug a 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 Eclipse Tahu é a implementação de referência open source da especificação Sparkplug, com bibliotecas e exemplos em Java, Python e C. Neste guia você vai aprender o que cada parte do repositório Tahu faz, como compilá-lo, quais armadilhas costumam pegar quem o usa pela primeira vez e como conectar um edge node baseado no Tahu a um broker MQTT real e ver os seus births e dados chegando.

O que o Eclipse Tahu é e o que não é

O Sparkplug é mantido pela Eclipse Foundation, e o Tahu é o projeto que transforma a especificação em código funcional. Ele oferece três coisas:

  • A definição Protobuf dos payloads Sparkplug B, sparkplug_b.proto, além do código gerado a partir dela para cada linguagem.
  • Bibliotecas auxiliares que montam e interpretam payloads: criação de payloads BIRTH e DEATH, inclusão de métricas com os tipos de dados corretos, tratamento dos números de sequência.
  • Exemplos e ferramentas de compatibilidade que mostram um edge node e uma aplicação host mínimos e ajudam os fornecedores a verificar as suas implementações contra a especificação.

O que o Eclipse Tahu não é: ele não é um broker MQTT, não é um sistema SCADA e não é um produto de gateway. Todo exemplo do Tahu se conecta como um cliente MQTT comum a um broker fornecido por você. Essa separação é a essência do Sparkplug. O edge node e o host falam Sparkplug, e o broker MQTT no meio só precisa ser um servidor MQTT compatível.

O Tahu também é código de referência. Ele foi escrito para ser claro e correto, não para ser colocado sem alterações em um gateway de produção. Muitas equipes usam diretamente as definições Protobuf e os helpers de payload e escrevem o próprio tratamento de sessão em torno deles, que é exatamente o que faremos abaixo.

Um tour pelo repositório

O código-fonte fica no repositório do Eclipse Tahu no GitHub. Clone-o para explorar:

git clone https://github.com/eclipse-tahu/tahu.git
cd tahu
ls

A estrutura é organizada por linguagem. Os nomes das pastas mudaram entre versões, então trate esta tabela como um mapa e não como uma listagem exata, e consulte o README do branch que você clonar.

Área O que você encontra Uso típico
sparkplug_b (proto) A definição .proto dos payloads Sparkplug B Gerar bindings para qualquer linguagem
java Biblioteca core, builders e decodificadores de payload, exemplos de edge e host, testes de compatibilidade Gateways JVM e aplicações host
python core com os helpers sparkplug_b.py e o sparkplug_b_pb2.py gerado, além de exemplos Scripts, simuladores, ferramentas de teste
c Codificação de payload core construída sobre o nanopb, além de um cliente de exemplo Gateways embarcados e dispositivos com recursos limitados
javascript Helpers de codificação de payload para Node.js Ferramentas baseadas em Node e fluxos no estilo Node-RED

Java

A implementação em Java é a mais completa. Ela contém classes de modelo para payloads e métricas, codificadores e decodificadores e exemplos de nível mais alto de edge node e de host. Ela é compilada com Maven:

cd java
mvn clean install -DskipTests

Os artefatos resultantes podem ser usados a partir do seu próprio projeto Maven ou Gradle. Java é a escolha natural se você está escrevendo uma aplicação host ou integrando com um SCADA ou MES baseado em JVM.

Python

A pasta Python contém dois arquivos que você vai usar o tempo todo. O sparkplug_b_pb2.py é o módulo Protobuf gerado, e o sparkplug_b.py acrescenta helpers como getNodeBirthPayload, getDeviceBirthPayload, getDdataPayload, getNodeDeathPayload e addMetric, além de uma enumeração MetricDataType. A pasta de exemplos mostra um edge node simples que publica births, envia dados e responde a comandos.

C

A implementação em C codifica e decodifica payloads Sparkplug usando o nanopb, um pequeno runtime Protobuf projetado para microcontroladores. É o ponto de partida se você precisa de Sparkplug em um gateway Linux embarcado ou em um firmware com memória apertada. O cliente de exemplo combina o codificador com uma biblioteca MQTT; você o compila com o Makefile fornecido depois de instalar os headers de desenvolvimento dessa biblioteca.

Armadilhas comuns do Eclipse Tahu

A maioria dos problemas do primeiro dia com o Tahu são problemas de ambiente, e não de Sparkplug.

  1. O paho-mqtt 2.x quebra os exemplos Python mais antigos. Os exemplos Python do Tahu foram escritos para o paho-mqtt 1.x. Com o paho-mqtt 2.x, mqtt.Client() exige uma versão da API de callbacks como primeiro argumento. Fixe pip install "paho-mqtt<2" para os exemplos ou crie o client como mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, client_id=...) para manter as assinaturas antigas dos callbacks.
  2. Incompatibilidade do runtime Protobuf. Um sparkplug_b_pb2.py gerado por um protoc antigo pode falhar com um pacote protobuf novo, exibindo "Descriptors cannot be created directly". Gere-o de novo com protoc --python_out=. sparkplug_b.proto usando um compilador atual.
  3. Caminhos de importação. Os exemplos importam os helpers core inserindo um caminho relativo. Se você copiar um exemplo para outro lugar, copie também o sparkplug_b.py e o sparkplug_b_pb2.py para junto dele.
  4. Configurações de conexão fixas no código. Os exemplos apontam para localhost por padrão. Edite o host do broker, a porta, o group ID, o edge node ID e as credenciais no início do arquivo.
  5. Group IDs compartilhados em brokers públicos. Os topics Sparkplug sempre começam com spBv1.0, então em um broker público use um group ID aleatório para não colidir com os testes de outras pessoas.

Conectando um edge node Tahu a um broker MQTT

O script a seguir usa os helpers Python do Tahu com o paho-mqtt 2.x. Copie o sparkplug_b.py e o sparkplug_b_pb2.py da pasta Python core do Tahu para um diretório vazio, adicione este arquivo ao lado deles e instale as dependências com pip install "paho-mqtt>=2.0" protobuf.

import random
import time

import paho.mqtt.client as mqtt
from sparkplug_b import (
    MetricDataType,
    addMetric,
    getDdataPayload,
    getDeviceBirthPayload,
    getNodeBirthPayload,
    getNodeDeathPayload,
)

BROKER = "broker.connectmq.com"
PORT = 1883
GROUP = "tahu-demo-5mz8"       # group ID aleatório para o broker público
NODE = "tahu-edge-01"
DEVICE = "pump-01"
CLIENT_ID = f"tahu-edge-{random.randint(1000, 9999)}"

def t(msg_type, device=None):
    base = f"spBv1.0/{GROUP}/{msg_type}/{NODE}"
    return f"{base}/{device}" if device else base

def publish_births(client):
    nbirth = getNodeBirthPayload()
    addMetric(nbirth, "Node Control/Rebirth", None, MetricDataType.Boolean, False)
    client.publish(t("NBIRTH"), bytearray(nbirth.SerializeToString()), 0, False)

    dbirth = getDeviceBirthPayload()
    addMetric(dbirth, "Flow", None, MetricDataType.Float, 12.5)
    addMetric(dbirth, "Pressure", None, MetricDataType.Float, 3.1)
    addMetric(dbirth, "Running", None, MetricDataType.Boolean, True)
    client.publish(t("DBIRTH", DEVICE), bytearray(dbirth.SerializeToString()), 0, False)
    print("NBIRTH and DBIRTH published")

def on_connect(client, userdata, flags, reason_code, properties):
    print("connected:", reason_code)
    client.subscribe(t("NCMD"))
    publish_births(client)

def on_message(client, userdata, msg):
    print("command received on", msg.topic)
    publish_births(client)   # nesta demo, qualquer NCMD é tratado como pedido de rebirth

# O payload de death precisa ser criado antes do birth para que ambos tenham o mesmo bdSeq
death = getNodeDeathPayload()

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=CLIENT_ID)
client.on_connect = on_connect
client.on_message = on_message
client.will_set(t("NDEATH"), bytearray(death.SerializeToString()), 1, False)
client.connect(BROKER, PORT, 60)
client.loop_start()

try:
    while True:
        time.sleep(3)
        ddata = getDdataPayload()
        addMetric(ddata, "Flow", None, MetricDataType.Float, round(random.uniform(11, 14), 2))
        addMetric(ddata, "Pressure", None, MetricDataType.Float, round(random.uniform(2.8, 3.4), 2))
        client.publish(t("DDATA", DEVICE), bytearray(ddata.SerializeToString()), 0, False)
        print("DDATA published")
except KeyboardInterrupt:
    client.loop_stop()
    client.disconnect()

A ordem de getNodeDeathPayload() e getNodeBirthPayload() importa porque os helpers do Tahu gerenciam o contador bdSeq internamente, e o NDEATH registrado como will precisa carregar o mesmo valor do NBIRTH que vem em seguida. Se a sua cópia dos helpers se comportar de outra forma, inspecione a métrica bdSeq nos dois payloads e ajuste.

Execute o script e assine o group em outro terminal:

mosquitto_sub -h broker.connectmq.com -p 1883 -i tahu-watch-5mz8 -t "spBv1.0/tahu-demo-5mz8/#" -v

Você vai ver os topics chegando com payloads binários. Para ler as métricas, abra o tráfego em um portal do ConnectMQ: o topic explorer ao vivo decodifica payloads Sparkplug B, seja Protobuf ou JSON, em métricas nomeadas com tipos de dados e valores. Isso torna rápido confirmar que o Tahu produziu o que você esperava antes de envolver um host SCADA. O broker que você acabou de usar é o servidor MQTT público (gratuito); ele serve para testes e protótipos e pode ser lido por qualquer pessoa, então mantenha nomes e valores reais de tags fora dele.

Do código de referência a um edge node real

Depois que o exemplo funcionar, um edge node de produção precisa de mais do que o Tahu oferece de fábrica:

  • bdSeq persistente. Armazene o contador em disco para que ele seja incrementado entre reinícios do processo.
  • Report by exception. Publique apenas os valores alterados, com bandas mortas para sinais analógicos ruidosos.
  • Store and forward. Armazene os dados em buffer durante quedas do broker e reenvie-os com flags de histórico.
  • Aliases. Habilite os aliases de métricas do Sparkplug em links restritos.
  • Consciência do host primário. No Sparkplug 3.0, os edge nodes podem esperar a mensagem STATE do host primário antes de publicar os births.
  • TLS e credenciais. Passe para a porta 8883 com credenciais por cliente.

Se você quer um script totalmente autocontido, sem os helpers do Tahu, nosso simulador de edge node Sparkplug B monta os payloads diretamente a partir do módulo Protobuf gerado e trata números de sequência e rebirths de forma explícita. Para os detalhes internos do payload, veja tipos de dados do Sparkplug B. A própria especificação é publicada pelo grupo de trabalho Eclipse Sparkplug.

Em produção, por exemplo nas linhas de envase de uma planta em Campinas, conecte os nodes baseados no Tahu a um broker privado. No ConnectMQ, crie um broker no portal, copie os YOUR_USERNAME, YOUR_PASSWORD e YOUR_CLIENT_ID gerados, defina o client ID no script, adicione client.username_pw_set(...) e client.tls_set() e conecte-se à porta 8883. O ConnectMQ pode então republicar os dados Sparkplug B decodificados em topics ISA-95 como connectmq/factory1/production/line1/cnc1/telemetry, que consumidores sem Sparkplug, como historiadores, dashboards ou um gêmeo digital da linha, conseguem ler como dados simples. A arquitetura mais ampla é tratada no nosso guia de IoT industrial com MQTT.

Conecte o Eclipse Tahu ao ConnectMQ

O Tahu entrega payloads corretos; você ainda precisa de um broker confiável entre a borda e o host. O ConnectMQ é um broker MQTT gerenciado com MQTT 3.1.1 e 5.0, TLS na porta 8883, decodificação de Sparkplug B e republicação ISA-95. Crie um broker no plano gratuito Serverless em app.connectmq.com, sem cartão de crédito, e aponte o seu edge node Tahu para ele em poucos minutos.

Perguntas frequentes

O Eclipse Tahu é um broker?

Não. O Eclipse Tahu fornece bibliotecas e exemplos de Sparkplug. Edge nodes e hosts construídos com ele se conectam como clientes MQTT a qualquer broker MQTT compatível.

Qual linguagem do Tahu devo usar?

Use Java para aplicações host e gateways JVM, Python para scripts, simuladores e testes, e C para gateways embarcados com orçamento de memória apertado.

Por que os exemplos Python do Tahu falham com o paho-mqtt 2.x?

O paho-mqtt 2.x exige uma versão da API de callbacks ao criar o client. Fixe o paho-mqtt abaixo da 2.0 para os exemplos ou passe mqtt.CallbackAPIVersion.VERSION1 para manter as assinaturas de callback deles.

O Tahu está pronto para produção?

Ele é código de referência focado em correção. Muitas equipes usam as suas definições Protobuf e helpers de payload em produção, acrescentando o próprio gerenciamento de sessão, buffering e segurança.

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

Gateway de Borda IIoT: O Que Ele Faz e Como Escolher o Seu

Um gateway de borda IIoT conecta máquinas que falam Modbus, OPC UA ou protocolos proprietários ao MQTT e à nuvem. Conheça suas funções principais, as arquiteturas comuns e como escolher o modelo certo.

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.