Jumeau numérique

Tutoriel Eclipse Ditto MQTT : des jumeaux numériques open source sur un broker MQTT managé

Un tutoriel Eclipse Ditto MQTT pratique : lancer Ditto avec Docker, créer un thing, ajouter une connexion MQTT 5 vers un broker, mapper le JSON des appareils en features et republier sur MQTT les événements de modification du jumeau.

Configuration Eclipse Ditto MQTT montrant des appareils publiant vers un broker, Ditto maintenant les jumeaux des things et des événements renvoyés vers les tableaux de bord
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

Eclipse Ditto avec MQTT est l'une des façons les plus pratiques de construire des jumeaux numériques open source : les appareils publient sur un broker, Ditto conserve un jumeau JSON de chaque appareil, et les applications lisent l'état des jumeaux via une API ou reçoivent des événements de modification. Dans ce tutoriel, vous allez lancer Ditto en local, créer un thing, connecter Ditto à un broker MQTT, mapper le JSON brut des appareils en features de jumeau et republier les événements du jumeau sur MQTT.

Pour situer la place d'un service de jumeau, consultez le guide de la technologie du jumeau numérique.

Ce que fait Eclipse Ditto

Eclipse Ditto est un framework open source de l'Eclipse Foundation dédié à la gestion de jumeaux numériques. Il ne communique pas directement avec les capteurs. Il maintient plutôt un document de jumeau par appareil, appelé thing, et vous offre :

  • Une API REST et WebSocket pour lire et modifier les jumeaux.
  • Des politiques (policies) qui contrôlent qui peut lire ou écrire quelle partie d'un jumeau.
  • Un service de connectivité qui se connecte à des brokers externes, dont MQTT 3.1.1 et MQTT 5.
  • Un mapping de payload pour transformer des messages d'appareils arbitraires en mises à jour du jumeau.
  • Des événements de modification et une recherche sur l'ensemble des things.

Un thing possède des attributes (métadonnées plutôt statiques comme l'emplacement ou le numéro de série) et des features (parties fonctionnelles, chacune avec des properties pour les valeurs rapportées et, éventuellement, des desiredProperties pour les valeurs cibles). Cela correspond parfaitement au pattern rapporté/désiré décrit dans la synchronisation d'état du jumeau numérique.

Architecture d'une configuration Eclipse Ditto MQTT

devices --publish--> MQTT broker <--subscribe/publish-- Ditto connectivity
                         |                                   |
                         |                             Ditto things (twins)
                         |                                   |
dashboards <--subscribe--+                 REST / WebSocket API for apps

Ditto se connecte au broker comme un client MQTT ordinaire. Le broker peut donc être n'importe quel broker conforme aux standards : un Mosquitto local, le serveur MQTT public gratuit pour les expérimentations, ou un broker MQTT managé comme ConnectMQ en production.

Étape 1 : lancer Eclipse Ditto avec Docker

Le dépôt Ditto fournit une configuration Docker Compose. Clonez-le et démarrez la stack :

git clone https://github.com/eclipse-ditto/ditto.git
cd ditto/deployment/docker
docker compose up -d

Une fois les conteneurs opérationnels, l'API est disponible via nginx sur http://localhost:8080. Les identifiants de développement par défaut sont ditto / ditto pour l'API et devops / foobar pour les endpoints d'administration comme les connexions. Modifiez-les avant d'exposer Ditto où que ce soit. La documentation d'Eclipse Ditto décrit en détail les options de déploiement.

Étape 2 : créer un thing

Créez un jumeau pour une pompe. Lorsque vous créez un thing sans politique explicite, Ditto crée une politique par défaut accordant un accès complet au sujet authentifié, qui est nginx:ditto dans la configuration nginx.

curl -u ditto:ditto -X PUT -H "Content-Type: application/json" \
  http://localhost:8080/api/2/things/acme:pump-01 \
  -d '{
    "attributes": { "site": "plant1", "line": "water", "model": "CP-200" },
    "features": {
      "flow": { "properties": { "value": 0, "unit": "l/min" } },
      "pressure": { "properties": { "value": 0, "unit": "bar" } },
      "motor": { "properties": { "running": false } }
    }
  }'

Relisez-le avec curl -u ditto:ditto http://localhost:8080/api/2/things/acme:pump-01.

Étape 3 : ajouter une connexion MQTT

Indiquez maintenant à Ditto de se connecter au broker. L'exemple ci-dessous utilise MQTT 5 sur le serveur MQTT public gratuit avec un préfixe de topic unique. Remplacez e3b9 par votre propre chaîne aléatoire.

{
  "name": "connectmq-demo",
  "connectionType": "mqtt-5",
  "connectionStatus": "open",
  "uri": "tcp://broker.connectmq.com:1883",
  "specificConfig": {
    "clientId": "ditto-e3b9",
    "separatePublisherClient": "false"
  },
  "sources": [
    {
      "addresses": ["connectmq/demo/e3b9/devices/+/telemetry"],
      "authorizationContext": ["nginx:ditto"],
      "qos": 1,
      "payloadMapping": ["telemetry"]
    }
  ],
  "targets": [
    {
      "address": "connectmq/demo/e3b9/twins/{{ thing:name }}/events",
      "topics": ["_/_/things/twin/events"],
      "authorizationContext": ["nginx:ditto"],
      "qos": 0
    }
  ],
  "mappingDefinitions": {
    "telemetry": {
      "mappingEngine": "JavaScript",
      "options": {
        "incomingScript": "function mapToDittoProtocolMsg(headers, textPayload, bytePayload, contentType) { var name = headers['mqtt.topic'].split('/')[4]; var d = JSON.parse(textPayload); var value = { flow: { properties: { value: d.flow, unit: 'l/min' } }, pressure: { properties: { value: d.pressure, unit: 'bar' } }, motor: { properties: { running: d.running } } }; return Ditto.buildDittoProtocolMsg('acme', name, 'things', 'twin', 'commands', 'merge', '/features', headers, value); }"
      }
    }
  }
}

Enregistrez-la sous connection.json et créez-la via l'API des connexions avec l'utilisateur devops :

curl -u devops:foobar -X POST -H "Content-Type: application/json" \
  http://localhost:8080/api/2/connections -d @connection.json

Points clés de cette configuration :

  • separatePublisherClient à false fait utiliser à Ditto un seul client MQTT dans les deux sens. Par défaut, Ditto peut ouvrir un second client avec un client ID dérivé, ce qui échoue sur les brokers qui lient les client IDs aux identifiants délivrés, comme le fait ConnectMQ pour les brokers de production.
  • La source s'abonne à la télémétrie de tous les appareils avec un wildcard à un niveau.
  • Le mapping JavaScript extrait le nom de l'appareil du topic et convertit le JSON brut en commande Ditto merge sur /features, si bien que les appareils n'ont jamais besoin de connaître le protocole Ditto.
  • La cible publie chaque événement de modification du jumeau sur un topic d'événements propre à chaque thing.

En production, changez l'URI en ssl://YOUR_BROKER_HOST:8883, définissez clientId sur YOUR_CLIENT_ID et ajoutez les identifiants issus du portail ConnectMQ, par exemple ssl://YOUR_USERNAME:YOUR_PASSWORD@YOUR_BROKER_HOST:8883.

Étape 4 : publier la télémétrie de l'appareil

Simulez la pompe avec mosquitto_pub. Le cinquième niveau du topic est le nom du thing que le script de mapping extrait :

mosquitto_pub -h broker.connectmq.com -p 1883 -i pump-01-e3b9 -q 1 \
  -t "connectmq/demo/e3b9/devices/pump-01/telemetry" \
  -m '{"flow": 418.5, "pressure": 3.7, "running": true}'

Vérifiez le jumeau :

curl -u ditto:ditto http://localhost:8080/api/2/things/acme:pump-01/features

Vous devriez voir les nouvelles valeurs de débit, de pression et de marche.

Étape 5 : consommer les événements du jumeau via MQTT

N'importe quelle application peut désormais suivre les modifications du jumeau sans appeler l'API Ditto. Abonnez-vous au topic d'événements :

mosquitto_sub -h broker.connectmq.com -p 1883 -i events-viewer-e3b9 \
  -t "connectmq/demo/e3b9/twins/+/events" -v

Publiez un autre message de télémétrie et un événement au format du protocole Ditto apparaît, contenant le topic acme/pump-01/things/twin/events/merged, le chemin et la valeur modifiée. Les tableaux de bord et visualiseurs 3D peuvent s'abonner à ces événements, ou se connecter à l'API WebSocket de Ditto s'ils ont besoin d'un accès contrôlé par politique pour chaque jumeau.

Points à considérer en production pour Eclipse Ditto et MQTT

Passer de cette configuration locale à la production implique quelques décisions faciles à négliger :

  • Identifiants et politiques. Remplacez les utilisateurs nginx par défaut par votre fournisseur d'identité, et créez des politiques explicites par thing ou par groupe de things au lieu de vous reposer sur la politique par défaut. Le contexte d'autorisation de la connexion doit être un sujet dédié ne disposant que des droits nécessaires.
  • Contrats de topics. Documentez la structure de topics attendue par le script de mapping. Si le firmware d'un appareil modifie la profondeur du topic, l'extraction par index du script casse silencieusement : validez les entrées et journalisez les messages rejetés.
  • Débit. Ditto persiste chaque modification de jumeau. Lui envoyer chaque échantillon à haute fréquence est du gaspillage ; laissez les appareils publier sur changement ou à un rythme modéré, et envoyez les données à pleine fréquence à un abonné de séries temporelles distinct.
  • État désiré. Si des applications définissent des desiredProperties, ajoutez une cible qui publie ces modifications vers un topic de commande de l'appareil, et faites remonter les retours des appareils par le même chemin de télémétrie.
  • Supervision. Surveillez conjointement l'état de la connexion et l'activité des topics du broker, pour savoir si un jumeau périmé est dû à l'appareil, au broker ou au mapping.

Dépannage des connexions Eclipse Ditto MQTT

Symptôme Cause probable Correction
L'état de la connexion reste en échec Mauvais schéma d'URI ou mauvais port Utiliser tcp:// avec 1883 ou ssl:// avec 8883
La connexion tombe juste après s'être établie Client ID dupliqué ou non autorisé Définir un clientId unique, désactiver le client de publication séparé
Messages reçus mais jumeau non mis à jour Contexte d'autorisation absent de la politique du thing Faire correspondre authorizationContext à un sujet de la politique
Erreurs de mapping dans les logs Le script lève une exception sur un payload inattendu Se prémunir contre les champs manquants et le JSON invalide
Aucun événement sur le topic cible Filtre topics de la cible manquant Inclure _/_/things/twin/events

Récupérez les diagnostics de connexion avec GET /api/2/connections/{connectionId}/status et /logs après avoir activé la journalisation via l'endpoint des commandes de connexion.

Quand utiliser Ditto plutôt que des topics retained

Ditto ajoute un service de jumeau avec API, politiques, recherche et historique des modifications. Si vous avez seulement besoin que les visualiseurs chargent l'état actuel, des topics MQTT retained peuvent suffire, sans infrastructure supplémentaire ; consultez jumeau numérique et MQTT retained. Choisissez Ditto lorsque vous avez besoin de requêtes sur de nombreux jumeaux, d'un contrôle d'accès fin par jumeau, de propriétés désirées ou d'une API REST pour les applications métier. Pour savoir où chacun s'insère dans une stack complète, lisez l'architecture du jumeau numérique.

Faire tourner Eclipse Ditto sur ConnectMQ

Ditto gère les jumeaux ; ConnectMQ gère la messagerie. En tant que broker MQTT cloud compatible MQTT 3.1.1 et 5.0, avec TLS sur le port 8883 et un explorateur de topics en temps réel pour observer côte à côte la télémétrie et les événements Ditto, il vous évite d'exploiter votre propre broker. Inscrivez-vous sur app.connectmq.com, créez un broker avec l'offre Serverless gratuite sans carte bancaire, et renseignez ses identifiants dans votre connexion Ditto.

Questions fréquentes

Eclipse Ditto inclut-il un broker MQTT ?

Non. Ditto se connecte à un broker MQTT externe en tant que client via son service de connectivité : vous choisissez et exploitez le broker séparément, ou vous utilisez un broker MQTT managé.

Ditto peut-il utiliser MQTT 5 ?

Oui. Définissez connectionType sur mqtt-5 pour MQTT 5 ou sur mqtt pour MQTT 3.1.1.

Les appareils doivent-ils envoyer des messages au format du protocole Ditto ?

Non. Avec un mapping de payload comme l'exemple JavaScript ci-dessus, les appareils peuvent publier du JSON brut que Ditto convertit en commandes de jumeau.

Comment envoyer des valeurs désirées de Ditto vers les appareils ?

Mettez à jour les desiredProperties d'une feature et ajoutez une cible qui publie ces modifications, ou envoyez des messages live, vers un topic de commande auquel l'appareil est abonné.

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.