Gêmeo digital

DTDL Explicado: a Digital Twin Definition Language e Como Mapeá-la para MQTT

Uma introdução prática à DTDL, a Digital Twin Definition Language: como funcionam interfaces, telemetria, propriedades, comandos, componentes e relacionamentos, e como mapeá-los para topics MQTT em um broker.

Diagrama de modelo DTDL mostrando uma interface com telemetria, propriedades e comandos mapeados para topics MQTT de um gêmeo digital
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

DTDL, a Digital Twin Definition Language, é uma forma baseada em JSON de descrever do que um gêmeo digital é feito: a telemetria que ele emite, as propriedades que mantém, os comandos que aceita e como se relaciona com outros gêmeos. Neste artigo você vai aprender como os modelos DTDL são estruturados, ler um exemplo completo e ver como mapear esse modelo para topics MQTT, para que dispositivos e aplicações de gêmeo compartilhem um contrato único e claro.

Para a visão geral de onde os modelos se encaixam, veja nosso guia completo sobre gêmeo digital.

O Que É DTDL e Por Que Ela Existe

Quando dez equipes constroem gêmeos de forma independente, cada uma inventa sua própria maneira de dizer "esta bomba tem uma vazão em litros por minuto e um comando de partida". A DTDL padroniza essa descrição. Ela é uma linguagem aberta publicada pela Microsoft, baseada em JSON-LD e usada pelo Azure Digital Twins e pelo IoT Plug and Play, mas nada na linguagem em si prende você a uma nuvem. Um arquivo DTDL é apenas um documento que descreve um tipo de ativo; você pode usá-lo para gerar código, validar payloads, construir interfaces ou documentar contratos de topics.

A linguagem passou por várias versões; a DTDL v3 é a atual, e a v2 ainda aparece bastante em projetos existentes. A especificação oficial está no repositório da DTDL no GitHub.

Os Blocos de Construção de um Modelo DTDL

Tudo em DTDL é definido dentro de uma Interface. Uma interface tem um identificador e uma lista de conteúdos, cada um sendo de um destes tipos de elemento:

Elemento O que descreve Exemplo
Telemetry Um fluxo de medições, não armazenado como estado Temperatura a cada segundo
Property Um valor de estado, opcionalmente gravável Versão de firmware, setpoint
Command Uma operação que o gêmeo pode ser solicitado a executar Partir, parar, zerar contador
Component Reuso de outra interface dentro desta Uma bomba contendo uma interface de motor
Relationship Um vínculo com outro gêmeo Bomba isPartOf estação

Cada modelo e elemento tem um DTMI (Digital Twin Model Identifier), como dtmi:com:example:Pump;1. O número final é a versão. Quando você altera um modelo de forma incompatível, incrementa a versão em vez de editá-lo no lugar.

Telemetria vs Propriedade

Esta é a distinção que as equipes mais erram. Telemetria é um fluxo de eventos: cada amostra importa e não há um "valor atual" armazenado pela plataforma do gêmeo. Propriedades são estado: o gêmeo sempre tem um valor atual, e uma propriedade gravável pode ser definida a partir da nuvem (um valor desejado), com o dispositivo reportando de volta seu valor real.

Regra prática: se um novo visualizador precisa ver o dado imediatamente ao carregar, é uma propriedade; se ele só importa como série ao longo do tempo, é telemetria.

Um Exemplo Completo de DTDL

Aqui está uma interface DTDL v3 para uma bomba centrífuga:

{
  "@context": "dtmi:dtdl:context;3",
  "@id": "dtmi:com:example:Pump;1",
  "@type": "Interface",
  "displayName": "Centrifugal Pump",
  "contents": [
    {
      "@type": ["Telemetry", "VolumeFlowRate"],
      "name": "flow",
      "schema": "double",
      "unit": "litrePerSecond"
    },
    {
      "@type": ["Telemetry", "Pressure"],
      "name": "dischargePressure",
      "schema": "double",
      "unit": "bar"
    },
    {
      "@type": "Property",
      "name": "running",
      "schema": "boolean"
    },
    {
      "@type": "Property",
      "name": "speedSetpoint",
      "schema": "double",
      "writable": true
    },
    {
      "@type": "Property",
      "name": "firmwareVersion",
      "schema": "string"
    },
    {
      "@type": "Command",
      "name": "resetRunHours"
    },
    {
      "@type": "Relationship",
      "name": "isPartOf",
      "target": "dtmi:com:example:PumpingStation;1"
    }
  ]
}

Tipos semânticos como VolumeFlowRate e unidades como litrePerSecond vêm da extensão de tipos quantitativos da DTDL. Eles permitem que as ferramentas exibam as unidades corretamente sem adivinhar. Consulte a especificação para ver a lista exata de tipos semânticos e unidades válidos na versão que você usa.

Mapeando DTDL para Topics MQTT

A DTDL descreve o que um gêmeo contém; ela não diz como os dados trafegam. O MQTT é um transporte natural, e um mapeamento limpo transforma seu modelo DTDL em um contrato de topics. Uma convenção prática:

Elemento DTDL Topic MQTT Retido QoS
Telemetry flow <asset>/telemetry (JSON com todos os campos de telemetria) Não 0
Property (somente leitura) <asset>/properties/reported Sim 1
Valor desejado de propriedade gravável <asset>/properties/desired Sim 1
Command resetRunHours <asset>/commands/resetRunHours Não 1
Resposta do comando <asset>/commands/resetRunHours/response Não 1
Relationship Armazenado no modelo ou no registro, não trafega n/a n/a

Sendo <asset> um caminho ISA-95 como acme/site1/water/station3/pump2 (pense na estação elevatória de uma companhia de saneamento), um visualizador pode assinar acme/site1/water/# e saber, a partir do modelo, como interpretar cada mensagem.

Por que combinar a telemetria em uma mensagem por ativo? Publicar um topic por campo de telemetria multiplica o número de mensagens sem acrescentar informação, e a maioria dos consumidores quer todos os campos com o mesmo timestamp. As propriedades se beneficiam de retained messages para que os visualizadores do gêmeo recebam o estado atual instantaneamente; o tutorial de gêmeo digital com retained MQTT mostra isso na prática.

Validando Payloads Contra um Modelo DTDL

Depois de ter um modelo, use-o. Uma pequena verificação em Python pode rejeitar telemetria que não corresponde à interface antes que ela polua seu histórico:

import json
import paho.mqtt.client as mqtt

with open("pump.json", encoding="utf-8") as f:
    model = json.load(f)

TYPE_MAP = {"double": (int, float), "boolean": bool, "string": str, "integer": int}
telemetry = {
    c["name"]: c["schema"]
    for c in model["contents"]
    if "Telemetry" in (c["@type"] if isinstance(c["@type"], list) else [c["@type"]])
}

def on_connect(client, userdata, flags, reason_code, properties):
    client.subscribe("connectmq/demo/d41f/+/+/+/+/telemetry")

def on_message(client, userdata, msg):
    data = json.loads(msg.payload)
    for name, schema in telemetry.items():
        if name not in data:
            print(f"{msg.topic}: missing {name}")
        elif not isinstance(data[name], TYPE_MAP[schema]):
            print(f"{msg.topic}: {name} should be {schema}")

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="dtdl-validator-d41f")
client.on_connect = on_connect
client.on_message = on_message
client.connect("broker.connectmq.com", 1883)
client.loop_forever()

Teste publicando uma mensagem de exemplo no servidor MQTT público (gratuito), que serve para testes e protótipos, não para dados de produção:

mosquitto_pub -h broker.connectmq.com -p 1883 -i dtdl-pub-d41f \
  -t "connectmq/demo/d41f/acme/site1/station3/pump2/telemetry" \
  -m '{"flow": 12.4, "dischargePressure": "4.1"}'

O validador aponta dischargePressure como string em vez de double, o tipo de bug que, de outra forma, só aparece semanas depois como um gráfico quebrado.

Checklist de Modelagem DTDL

  1. Uma interface por tipo de ativo, não por instância de ativo.
  2. Telemetria para fluxos, propriedades para estado, comandos para ações.
  3. Use componentes para partes reutilizáveis, como motores ou sensores.
  4. Inclua unidades por meio de tipos semânticos sempre que possível.
  5. Versione os DTMIs e nunca quebre uma versão publicada.
  6. Documente o mapeamento MQTT ao lado do modelo, no mesmo repositório.
  7. Valide os payloads na ingestão, não apenas na interface.

DTDL Comparada com Outros Modelos de Gêmeo

A DTDL não é a única opção. A Asset Administration Shell, do universo da Indústria 4.0, foca em submodelos padronizados para ativos industriais e é comum na manufatura europeia; veja Asset Administration Shell explicada. O Eclipse Ditto usa seus próprios "things" em JSON com attributes e features. Muitas equipes também usam um JSON Schema simples por tipo de ativo. O que mais importa é ter um modelo explícito e um mapeamento documentado para o transporte, papel que a DTDL cumpre bem. Para ver como a camada de modelo se posiciona ao lado de mensageria, estado e visualização, veja arquitetura de gêmeo digital.

Rodando Seu Gêmeo Baseado em DTDL no ConnectMQ

A DTDL define o contrato; você ainda precisa de um transporte confiável. O ConnectMQ é um broker MQTT gerenciado com suporte a MQTT 3.1.1 e 5.0, retained messages para propriedades, TLS na porta 8883 para dispositivos e WSS na 8084 para gêmeos no navegador. Validação de modelos, geração de código e grafos de gêmeos rodam nas suas próprias ferramentas, conectadas ao ConnectMQ como clientes MQTT comuns. Crie um broker no plano Serverless gratuito em app.connectmq.com, sem cartão de crédito, e publique sua primeira telemetria no formato DTDL em minutos.

Perguntas frequentes

A DTDL serve apenas para o Azure?

Não. A DTDL é uma linguagem aberta baseada em JSON-LD. O Azure Digital Twins a usa nativamente, mas você pode usar modelos DTDL com qualquer transporte, incluindo MQTT em qualquer broker.

Qual é a diferença entre uma propriedade e uma telemetria em DTDL?

Uma propriedade é estado com um valor atual, opcionalmente gravável; a telemetria é um fluxo de medições em que cada amostra importa, mas nenhum valor atual é armazenado.

Como representar comandos DTDL sobre MQTT?

Publique o comando em um topic de comando não retido com QoS 1 e um correlation ID, e faça o dispositivo publicar o resultado em um topic de resposta. As propriedades response topic e correlation data do MQTT 5 suportam isso diretamente.

Qual versão de DTDL devo usar?

Use a DTDL v3 em novos projetos, a menos que alguma ferramenta da qual você depende só suporte a v2.

Artigos relacionados

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.