Jumeau numérique

DTDL expliqué : le Digital Twin Definition Language et sa correspondance avec MQTT

Une introduction pratique à DTDL, le Digital Twin Definition Language : fonctionnement des interfaces, de la télémétrie, des propriétés, des commandes, des composants et des relations, et correspondance avec les topics MQTT d'un broker.

Schéma d'un modèle DTDL montrant une interface avec télémétrie, propriétés et commandes mappées sur des topics MQTT pour un jumeau numérique
Essayez-le sur votre propre broker MQTTObtenez un broker MQTT privé et managé avec l’offre Free et partez d’exemples de code prêts à l’emploi.
Essayer gratuitement Exemples de code Aucune carte bancaire requise

DTDL, le Digital Twin Definition Language, est une façon fondée sur JSON de décrire ce qui compose un jumeau numérique : la télémétrie qu'il émet, les propriétés qu'il détient, les commandes qu'il accepte et ses relations avec d'autres jumeaux. Dans cet article, vous découvrirez comment sont structurés les modèles DTDL, lirez un exemple complet et verrez comment mapper ce modèle sur des topics MQTT pour que les appareils et les applications de jumeau partagent un contrat unique et clair.

Pour situer les modèles dans l'ensemble, consultez notre guide de la technologie du jumeau numérique.

Ce qu'est DTDL et pourquoi il existe

Quand dix équipes construisent des jumeaux chacune de leur côté, chacune invente sa propre manière de dire « cette pompe a un débit en litres par minute et une commande de démarrage ». DTDL normalise cette description. C'est un langage ouvert publié par Microsoft, fondé sur JSON-LD et utilisé par Azure Digital Twins et IoT Plug and Play, mais rien dans le langage lui-même ne vous lie à un cloud. Un fichier DTDL n'est qu'un document décrivant un type d'actif ; vous pouvez vous en servir pour générer du code, valider des payloads, construire des interfaces ou documenter des contrats de topics.

Le langage a connu plusieurs versions ; DTDL v3 est la version actuelle, la v2 restant très présente dans les projets existants. La spécification officielle se trouve dans le dépôt GitHub de DTDL.

Les briques d'un modèle DTDL

Tout, dans DTDL, est défini à l'intérieur d'une Interface. Une interface possède un identifiant et une liste de contenus, chacun relevant de l'un de ces types d'éléments :

Élément Ce qu'il décrit Exemple
Telemetry Un flux de mesures, non stocké comme état Température chaque seconde
Property Une valeur d'état, éventuellement modifiable Version du firmware, consigne
Command Une opération que l'on peut demander au jumeau d'effectuer Démarrer, arrêter, remettre un compteur à zéro
Component La réutilisation d'une autre interface au sein de celle-ci Une pompe contenant une interface moteur
Relationship Un lien vers un autre jumeau Pompe isPartOf station

Chaque modèle et chaque élément possède un DTMI (Digital Twin Model Identifier), par exemple dtmi:com:example:Pump;1. Le nombre final est la version. Lorsque vous modifiez un modèle de façon incompatible, vous incrémentez la version au lieu de le modifier sur place.

Télémétrie ou propriété

C'est la distinction que les équipes confondent le plus souvent. La télémétrie est un flux d'événements : chaque échantillon compte, et la plateforme de jumeau ne stocke aucune « valeur actuelle ». Les propriétés sont de l'état : le jumeau a toujours une valeur actuelle, et une propriété modifiable peut être définie côté cloud (valeur désirée), l'appareil renvoyant ensuite sa valeur réelle.

Règle empirique : si un nouveau visualiseur doit la voir dès le chargement, c'est une propriété ; si elle n'a d'intérêt que sous forme de série dans le temps, c'est de la télémétrie.

Un exemple DTDL complet

Voici une interface DTDL v3 pour une pompe centrifuge :

{
  "@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"
    }
  ]
}

Les types sémantiques comme VolumeFlowRate et les unités comme litrePerSecond proviennent de l'extension DTDL des types quantitatifs. Ils permettent aux outils d'afficher correctement les unités sans deviner. Consultez la spécification pour la liste exacte des types sémantiques et des unités valides dans la version que vous ciblez.

Mapper DTDL sur des topics MQTT

DTDL décrit ce que contient un jumeau ; il ne dit pas comment les données circulent. MQTT est un transport naturel, et un mapping propre transforme votre modèle DTDL en contrat de topics. Une convention pratique :

Élément DTDL Topic MQTT Retained QoS
Telemetry flow <asset>/telemetry (JSON avec tous les champs de télémétrie) Non 0
Property (lecture seule) <asset>/properties/reported Oui 1
Valeur désirée d'une propriété modifiable <asset>/properties/desired Oui 1
Command resetRunHours <asset>/commands/resetRunHours Non 1
Réponse à la commande <asset>/commands/resetRunHours/response Non 1
Relationship Stockée dans le modèle ou le registre, pas sur le réseau n/a n/a

Avec <asset> correspondant à un chemin ISA-95 comme acme/site1/water/station3/pump2, un visualiseur peut s'abonner à acme/site1/water/# et savoir, grâce au modèle, comment interpréter chaque message.

Pourquoi regrouper la télémétrie en un seul message par actif ? Publier un topic par champ de télémétrie multiplie le nombre de messages sans apporter d'information, et la plupart des consommateurs veulent tous les champs au même horodatage. Les propriétés tirent parti des retained messages pour que les visualiseurs de jumeau obtiennent instantanément l'état actuel ; le tutoriel jumeau numérique et MQTT retained le montre en pratique.

Valider les payloads par rapport à un modèle DTDL

Une fois le modèle défini, utilisez-le. Un petit contrôle en Python peut rejeter la télémétrie non conforme à l'interface avant qu'elle ne pollue votre historique :

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()

Testez-le en publiant un message d'exemple sur le serveur MQTT public gratuit, réservé aux tests :

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"}'

Le validateur signale que dischargePressure est une chaîne au lieu d'un double, le genre de bug qui, autrement, n'apparaît que des semaines plus tard sous la forme d'un graphique cassé.

Checklist de modélisation DTDL

  1. Une interface par type d'actif, pas par instance d'actif.
  2. La télémétrie pour les flux, les propriétés pour l'état, les commandes pour les actions.
  3. Des composants pour les parties réutilisables comme les moteurs ou les capteurs.
  4. Des unités via les types sémantiques chaque fois que possible.
  5. Des DTMI versionnés, sans jamais casser une version publiée.
  6. Le mapping MQTT documenté à côté du modèle, dans le même dépôt.
  7. Une validation des payloads à l'ingestion, pas seulement dans l'interface.

DTDL comparé aux autres modèles de jumeau

DTDL n'est pas la seule option. L'Asset Administration Shell, issu de l'univers Industrie 4.0, se concentre sur des sous-modèles normalisés pour les actifs industriels et est répandu dans l'industrie européenne ; consultez l'Asset Administration Shell expliqué. Eclipse Ditto utilise ses propres « things » JSON avec attributs et features. Beaucoup d'équipes utilisent aussi un simple JSON Schema par type d'actif. Le plus important est d'avoir un modèle explicite unique et un mapping documenté vers le transport, rôle que DTDL remplit bien. Pour voir comment la couche modèle s'articule avec la messagerie, l'état et la visualisation, consultez l'architecture du jumeau numérique.

Faire tourner votre jumeau fondé sur DTDL avec ConnectMQ

DTDL définit le contrat ; il vous faut encore un transport fiable. ConnectMQ est un broker MQTT managé compatible MQTT 3.1.1 et 5.0, avec retained messages pour les propriétés, TLS sur le port 8883 pour les appareils et WSS sur le 8084 pour les jumeaux dans le navigateur. La validation des modèles, la génération de code et les graphes de jumeaux s'exécutent dans vos propres outils, connectés à ConnectMQ comme des clients MQTT ordinaires. Créez un broker avec l'offre Serverless gratuite sur app.connectmq.com, sans carte bancaire, et publiez votre première télémétrie conforme à DTDL en quelques minutes.

Questions fréquentes

DTDL est-il réservé à Azure ?

Non. DTDL est un langage ouvert fondé sur JSON-LD. Azure Digital Twins l'utilise nativement, mais vous pouvez employer des modèles DTDL avec n'importe quel transport, y compris MQTT sur n'importe quel broker.

Quelle est la différence entre une propriété et la télémétrie en DTDL ?

Une propriété est un état doté d'une valeur actuelle, éventuellement modifiable ; la télémétrie est un flux de mesures où chaque échantillon compte, mais où aucune valeur actuelle n'est stockée.

Comment représenter les commandes DTDL sur MQTT ?

Publiez la commande sur un topic de commande non retained en QoS 1 avec un identifiant de corrélation, et faites publier le résultat par l'appareil sur un topic de réponse. Les propriétés response topic et correlation data de MQTT 5 prennent cela en charge directement.

Quelle version de DTDL utiliser ?

Utilisez DTDL v3 pour les nouveaux projets, sauf si un outil dont vous dépendez ne prend en charge que la v2.

Articles liés

Tous les articles →

Votre broker MQTT privé, à quelques clics

Créez un compte, récupérez les identifiants de votre broker et connectez votre premier appareil — aucun serveur à installer, mettre à jour ou dimensionner.