Digitaler Zwilling

Eclipse Ditto MQTT Tutorial: Open-Source-Zwillinge auf einem verwalteten MQTT-Broker

Ein praxisnahes Eclipse Ditto MQTT Tutorial: Ditto mit Docker starten, ein Thing anlegen, eine MQTT-5-Verbindung zu einem Broker einrichten, Geräte-JSON in Features abbilden und Änderungsereignisse des Zwillings zurück auf MQTT publizieren.

Eclipse-Ditto-MQTT-Setup, bei dem Geräte an einen Broker publizieren, Ditto Thing-Zwillinge pflegt und Ereignisse zurück an Dashboards fließen
Probieren Sie es auf Ihrem eigenen MQTT-Broker ausHolen Sie sich im Free-Tarif einen privaten, verwalteten MQTT-Broker und starten Sie mit fertigen Codebeispielen.
Kostenlos testen Codebeispiele Keine Kreditkarte erforderlich

Eclipse Ditto mit MQTT ist einer der praktikabelsten Wege zu Open-Source-Zwillingen: Geräte publizieren an einen Broker, Ditto führt für jedes Gerät einen JSON-Zwilling, und Anwendungen lesen den Zwillingszustand über eine API oder erhalten Änderungsereignisse. In diesem Tutorial betreiben Sie Ditto lokal, legen ein Thing an, verbinden Ditto mit einem MQTT-Broker, bilden einfaches Geräte-JSON auf Zwillings-Features ab und publizieren Zwillingsereignisse zurück auf MQTT.

Wo ein Zwillingsdienst einzuordnen ist, erklärt der Leitfaden zur Digital-Twin-Technologie.

Was Eclipse Ditto macht

Eclipse Ditto ist ein Open-Source-Framework der Eclipse Foundation zur Verwaltung digitaler Zwillinge. Es spricht nicht direkt mit Sensoren. Stattdessen pflegt es pro Gerät ein Zwillingsdokument, ein sogenanntes Thing, und bietet Ihnen:

  • Eine REST- und WebSocket-API zum Lesen und Ändern von Zwillingen.
  • Policies, die steuern, wer welchen Teil eines Zwillings lesen oder schreiben darf.
  • Einen Connectivity-Service, der sich mit externen Brokern verbindet, darunter MQTT 3.1.1 und MQTT 5.
  • Payload-Mapping, um beliebige Gerätenachrichten in Zwillings-Updates umzuwandeln.
  • Änderungsereignisse und Suche über alle Things.

Ein Thing hat Attribute (überwiegend statische Metadaten wie Standort oder Seriennummer) und Features (funktionale Teile, jeweils mit properties für gemeldete Werte und optional desiredProperties für Zielwerte). Das passt genau zum Muster aus gemeldetem und gewünschtem Zustand, das in Zustandssynchronisation digitaler Zwillinge beschrieben ist.

Architektur eines Eclipse-Ditto-MQTT-Setups

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

Ditto verbindet sich als gewöhnlicher MQTT-Client mit dem Broker. Der Broker kann also jeder standardkonforme sein: ein lokaler Mosquitto, der öffentliche MQTT-Broker für Tests und Experimente oder ein verwalteter MQTT-Broker wie ConnectMQ in der Produktion.

Schritt 1: Eclipse Ditto mit Docker starten

Das Ditto-Repository enthält ein Docker-Compose-Setup. Klonen Sie es und starten Sie den Stack:

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

Sobald die Container gesund sind, ist die API über nginx unter http://localhost:8080 erreichbar. Die Standard-Zugangsdaten für die Entwicklung lauten ditto / ditto für die API und devops / foobar für administrative Endpunkte wie Connections. Ändern Sie diese, bevor Sie Ditto irgendwo zugänglich machen. Die Eclipse-Ditto-Dokumentation beschreibt die Deployment-Optionen ausführlich.

Schritt 2: Ein Thing anlegen

Legen Sie einen Zwilling für eine Pumpe an. Wenn Sie ein Thing ohne explizite Policy anlegen, erstellt Ditto eine Standard-Policy, die dem authentifizierten Subjekt vollen Zugriff gewährt; beim nginx-Setup ist das nginx:ditto.

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

Lesen Sie es mit curl -u ditto:ditto http://localhost:8080/api/2/things/acme:pump-01 wieder aus.

Schritt 3: Eine MQTT-Verbindung hinzufügen

Weisen Sie Ditto nun an, sich mit dem Broker zu verbinden. Das folgende Beispiel nutzt MQTT 5 gegen den öffentlichen MQTT-Broker mit einem eindeutigen Topic-Präfix; senden Sie dort nur Testdaten, keine Produktionsdaten. Ersetzen Sie e3b9 durch Ihre eigene zufällige Zeichenfolge.

{
  "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); }"
      }
    }
  }
}

Speichern Sie die Konfiguration als connection.json und legen Sie die Verbindung mit dem devops-Benutzer über die Connections-API an:

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

Die wichtigsten Punkte dieser Konfiguration:

  • separatePublisherClient auf false sorgt dafür, dass Ditto einen einzigen MQTT-Client für beide Richtungen verwendet. Standardmäßig öffnet Ditto unter Umständen einen zweiten Client mit abgeleiteter Client ID, was auf Brokern scheitert, die Client IDs an ausgegebene Zugangsdaten binden, wie ConnectMQ es bei Produktions-Brokern tut.
  • Die Source abonniert mit einer einstufigen Wildcard die Telemetrie aller Geräte.
  • Das JavaScript-Mapping extrahiert den Gerätenamen aus dem Topic und wandelt einfaches JSON in einen Ditto-merge-Befehl auf /features um, sodass Geräte das Ditto Protocol nie kennen müssen.
  • Das Target publiziert jedes Änderungsereignis eines Zwillings auf ein Events-Topic pro Thing.

Für die Produktion ändern Sie die URI auf ssl://YOUR_BROKER_HOST:8883, setzen clientId auf YOUR_CLIENT_ID und ergänzen die Zugangsdaten aus dem ConnectMQ-Portal, zum Beispiel ssl://YOUR_USERNAME:YOUR_PASSWORD@YOUR_BROKER_HOST:8883.

Schritt 4: Gerätetelemetrie publizieren

Simulieren Sie die Pumpe mit mosquitto_pub. Die fünfte Topic-Ebene ist der Thing-Name, den das Mapping-Skript extrahiert:

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

Prüfen Sie den Zwilling:

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

Sie sollten die neuen Werte für Durchfluss, Druck und Betriebszustand sehen.

Schritt 5: Zwillingsereignisse über MQTT konsumieren

Jede Anwendung kann Zwillingsänderungen jetzt verfolgen, ohne die Ditto-API aufzurufen. Abonnieren Sie das Events-Topic:

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

Publizieren Sie eine weitere Telemetrienachricht, und es erscheint ein Ditto-Protocol-Ereignis mit dem Topic acme/pump-01/things/twin/events/merged, dem Pfad und dem geänderten Wert. Dashboards und 3D-Viewer können diese Ereignisse abonnieren oder sich mit der WebSocket-API von Ditto verbinden, wenn sie einen per Policy abgesicherten Zugriff pro Zwilling benötigen.

Hinweise für den Produktivbetrieb von Eclipse Ditto mit MQTT

Der Schritt von diesem lokalen Setup in die Produktion erfordert einige Entscheidungen, die leicht übersehen werden:

  • Zugangsdaten und Policies. Ersetzen Sie die Standard-nginx-Benutzer durch Ihren Identity Provider und legen Sie explizite Policies pro Thing oder pro Gruppe von Things an, statt sich auf die Standard-Policy zu verlassen. Der Authorization Context der Verbindung sollte ein eigenes Subjekt mit nur den nötigen Berechtigungen sein.
  • Topic-Verträge. Dokumentieren Sie das Topic-Layout, das das Mapping-Skript erwartet. Ändert die Geräte-Firmware die Topic-Tiefe, bricht die indexbasierte Extraktion des Skripts stillschweigend; validieren Sie daher Eingaben und protokollieren Sie abgelehnte Nachrichten. In der Fabrik richten Sie das Layout am besten am Unified Namespace (UNS) aus: Die ISA-95-Hierarchie (Enterprise → Site → Area → Line → Cell) wird zur Topic-Struktur auf dem MQTT-Broker, etwa acme/werk-stuttgart/wasseraufbereitung/linie-1/pumpe-01/telemetry, und Ditto liest daraus Thing-ID und Attribute wie site und line ab. Mehr zum UNS-Konzept unter Sparkplug B und Unified Namespace.
  • Durchsatz. Ditto persistiert jede Änderung eines Zwillings. Jeden hochfrequenten Messwert hineinzuschieben ist Verschwendung; lassen Sie Geräte bei Änderung oder mit moderater Rate publizieren und senden Sie die Daten in voller Auflösung an einen separaten Zeitreihen-Subscriber.
  • Gewünschter Zustand. Wenn Anwendungen desiredProperties setzen, ergänzen Sie ein Target, das diese Änderungen auf ein Befehls-Topic des Geräts publiziert, und lassen Sie Geräte über denselben Telemetriepfad zurückmelden.
  • Monitoring. Beobachten Sie den Verbindungsstatus und die Topic-Aktivität des Brokers gemeinsam, damit Sie erkennen, ob ein veralteter Zwilling am Gerät, am Broker oder am Mapping liegt.

Fehlersuche bei Eclipse-Ditto-MQTT-Verbindungen

Symptom Wahrscheinliche Ursache Lösung
Verbindungsstatus bleibt auf failed Falsches URI-Schema oder falscher Port tcp:// mit 1883 oder ssl:// mit 8883 verwenden
Verbindung bricht direkt nach dem Aufbau ab Doppelte oder nicht autorisierte Client ID Eindeutige clientId setzen, separaten Publisher-Client deaktivieren
Nachrichten kommen an, Zwilling wird aber nicht aktualisiert Authorization Context nicht in der Thing-Policy authorizationContext auf ein Subjekt in der Policy abstimmen
Mapping-Fehler in den Logs Skript wirft bei unerwartetem Payload eine Exception Fehlende Felder und ungültiges JSON abfangen
Keine Ereignisse auf dem Target-Topic Filter topics im Target fehlt _/_/things/twin/events aufnehmen

Rufen Sie Verbindungsdiagnosen mit GET /api/2/connections/{connectionId}/status und /logs ab, nachdem Sie das Logging über den Endpunkt für Connection-Befehle aktiviert haben.

Wann Ditto und wann Retained Topics?

Ditto ergänzt einen Zwillingsdienst mit APIs, Policies, Suche und Änderungshistorie. Wenn Viewer nur den aktuellen Zustand laden müssen, reichen unter Umständen Retained MQTT-Topics ohne zusätzliche Infrastruktur; siehe Digitaler Zwilling mit Retained MQTT. Wählen Sie Ditto, wenn Sie Abfragen über viele Zwillinge, feingranulare Zugriffskontrolle pro Zwilling, Desired Properties oder eine REST-API für Geschäftsanwendungen brauchen. Wo welche Lösung in einem vollständigen Stack hingehört, lesen Sie unter Architektur digitaler Zwillinge.

Eclipse Ditto auf ConnectMQ betreiben

Ditto kümmert sich um die Zwillinge, ConnectMQ um das Messaging. Als Cloud-MQTT-Broker mit MQTT 3.1.1 und 5.0, TLS auf Port 8883 und einem Live-Topic-Explorer, in dem Sie Telemetrie und Ditto-Ereignisse nebeneinander verfolgen, nimmt ConnectMQ Ihnen den Betrieb eines eigenen Brokers ab. Registrieren Sie sich unter app.connectmq.com, erstellen Sie einen Broker im kostenlosen Serverless-Plan ohne Kreditkarte und tragen Sie die Zugangsdaten in Ihre Ditto-Verbindung ein.

Häufig gestellte Fragen

Enthält Eclipse Ditto einen MQTT-Broker?

Nein. Ditto verbindet sich über seinen Connectivity-Service als Client mit einem externen MQTT-Broker; den Broker wählen und betreiben Sie also separat oder nutzen einen verwalteten MQTT-Broker.

Kann Ditto MQTT 5 verwenden?

Ja. Setzen Sie connectionType auf mqtt-5 für MQTT 5 oder auf mqtt für MQTT 3.1.1.

Müssen Geräte Ditto-Protocol-Nachrichten senden?

Nein. Mit einem Payload-Mapping wie dem obigen JavaScript-Beispiel können Geräte einfaches JSON publizieren, und Ditto wandelt es in Zwillingsbefehle um.

Wie sende ich gewünschte Werte von Ditto an Geräte?

Aktualisieren Sie desiredProperties eines Features und ergänzen Sie ein Target, das diese Änderungen publiziert, oder senden Sie Live-Nachrichten an ein Befehls-Topic, das das Gerät abonniert.

Verwandte Artikel

Alle Artikel →

Ihr privater MQTT-Broker ist nur wenige Klicks entfernt

Konto anlegen, Broker-Zugangsdaten erhalten und das erste Gerät verbinden — ohne Server, die installiert, gepatcht oder skaliert werden müssen.