IoT Plug & Play-Konventionen

Für IoT Plug & Play-Geräte muss beim Austauschen von Nachrichten mit einem IoT-Hub eine Reihe von Konventionen eingehalten werden. Für IoT Plug & Play-Geräte wird für die Kommunikation mit IoT Hub das MQTT-Protokoll verwendet. IoT Hub unterstützt auch das AMQP-Protokoll, das in einigen IoT-Geräte-SDKs verfügbar ist.

Ein Gerät kann Module enthalten oder in einem IoT Edge-Modul implementiert werden, das von der IoT Edge-Runtime gehostet wird.

Die Telemetriedaten, Eigenschaften und Befehle, die ein Gerät in IoT Plug & Play implementiert, werden mit einem DTDL-Modell Digital Twins Definition Language beschrieben. In diesem Artikel werden zwei Modelltypen erläutert:

  • Ohne Komponenten: Ein Modell ohne Komponenten. Bei diesem Modell werden Telemetriedaten, Eigenschaften und Befehle im Inhaltsabschnitt der Hauptschnittstelle als Elemente der obersten Ebene deklariert. Im Azure IoT-Explorer-Tool wird dieses Modell als einzelne Standardkomponente angezeigt.
  • Mit mehreren Komponenten: Ein Modell, das aus mindestens zwei Schnittstellen besteht. Eine Hauptschnittstelle, die als Standardkomponente mit Telemetriedaten, Eigenschaften und Befehlen angezeigt wird. Mindestens eine Schnittstelle, die als Komponente mit weiteren Telemetriedaten, Eigenschaften und Befehlen deklariert wurde.

Weitere Informationen finden Sie unter Leitfaden: Modellierung mit IoT Plug & Play.

Identifizieren des Modells

Zur Ankündigung des Modells, das vom IoT Plug & Play-Gerät oder -Modul implementiert wird, wird die Modell-ID in das MQTT-Verbindungspaket eingebunden, indem dem Feld USERNAME der Eintrag model-id hinzugefügt wird.

Um das von einem Gerät oder einem Modul implementierte Modell zu identifizieren, kann ein Dienst die Modell-ID vom folgenden Ort abrufen:

  • Vom modelId-Feld des Gerätezwillings
  • Vom $metadata.$model-Feld des digitalen Zwillings
  • Aus einer Änderungsbenachrichtigung bei einem digitalen Zwilling

Telemetrie

  • Telemetriedaten, die von einem Gerät ohne Komponenten gesendet werden, erfordern keine zusätzlichen Metadaten. Vom System wird die dt-dataschema-Eigenschaft hinzugefügt.
  • Telemetriedaten, die von einem Gerät mit Komponenten gesendet werden, müssen den Komponentennamen an die Telemetrie-Nachricht anhängen.
  • Wenn Sie MQTT verwenden und die $.sub-Eigenschaft mit dem Komponentennamen zum Telemetriethema hinzufügen, fügt das System die dt-subject-Eigenschaft hinzu.
  • Wenn Sie AMQP verwenden, fügen Sie die dt-subject-Eigenschaft mit dem Komponentennamen als Nachrichtenanmerkung hinzu.

Hinweis

Telemetrie aus Komponenten erfordert eine Nachricht pro Komponente.

Weitere Telemetriebeispiele finden Sie unter Nutzdaten > Telemetrie.

Schreibgeschützte Eigenschaften

Ein Gerät legt eine schreibgeschützte Eigenschaft fest, die es dann an die Back-End-Anwendung meldet.

Beispiel für eine schreibgeschützte Eigenschaft eines Geräts ohne Komponenten

Ein Gerät oder Modul kann eine gültige JSON-Nachricht senden, die den DTDL-Regeln entspricht.

DTDL, das eine Eigenschaft für eine Schnittstelle definiert:

{
  "@context": "dtmi:dtdl:context;2",
  "@id": "dtmi:example: Thermostat;1",
  "@type": "Interface",
  "contents": [
    {
      "@type": "Property",
      "name": "temperature",
      "schema": "double"
    }
  ]
}

Beispiel für Nutzdaten der gemeldeten Eigenschaft:

"reported" :
{
  "temperature" : 21.3
}

Beispiel für eine schreibgeschützte Eigenschaft eines Geräts mit mehreren Komponenten

Das Gerät oder Modul muss zusätzlich den Marker {"__t": "c"} aufweisen, um anzugeben, dass das Element auf eine Komponente verweist.

DTDL zum Verweisen auf eine Komponente:

{
  "@context": "dtmi:dtdl:context;2",
  "@id": "dtmi:com:example:TemperatureController;1",
  "@type": "Interface",
  "displayName": "Temperature Controller",
  "contents": [
    {
      "@type" : "Component",
      "schema": "dtmi:com:example:Thermostat;1",
      "name": "thermostat1"
    }
  ]
}

DTDL zum Definieren der Komponente:

{
  "@context": "dtmi:dtdl:context;2",
  "@id": "dtmi:com:example:Thermostat;1",
  "@type": "Interface",
  "contents": [
    {
      "@type": "Property",
      "name": "temperature",
      "schema": "double"
    }
  ]
}

Beispiel für Nutzdaten der gemeldeten Eigenschaft:

"reported": {
  "thermostat1": {
    "__t": "c",
    "temperature": 21.3
  }
}

Weitere Beispiele für schreibgeschützte Eigenschaften finden Sie unter Nutzdaten > Eigenschaften.

Schreibbare Eigenschaften

Eine Back-End-Anwendung legt eine schreibbare Eigenschaft fest, die IoT Hub dann an das Gerät sendet.

Das Gerät oder Modul muss bestätigen, dass es die Eigenschaft erhalten hat, indem es eine gemeldete Eigenschaft sendet. Die gemeldete Eigenschaft muss Folgendes enthalten:

  • value: den tatsächlichen Wert der Eigenschaft (in der Regel der empfangene Wert, aber das Gerät kann bei Bedarf einen anderen Wert melden).
  • ac: einen Bestätigungscode, der einen HTTP-Statuscode enthält
  • av: eine Bestätigungsversion, die auf die $version der gewünschten Eigenschaft verweist. Sie finden diesen Wert in den JSON-Nutzdaten der gewünschten Eigenschaft.
  • ad: eine optionale Beschreibung der Bestätigung

Bestätigungsantworten

Wenn ein Gerät schreibbare Eigenschaften meldet, sollte es die Bestätigungsnachricht mit vier Feldern in der vorherigen Liste erstellen, um den tatsächlichen Gerätestatus anzugeben, wie in der folgenden Tabelle beschrieben wird:

Status(ac) Version(av) Wert(value) Beschreibung(av)
200 Gewünschte Version Gewünschter Wert Gewünschter Eigenschaftswert akzeptiert
202 Gewünschte Version Vom Gerät akzeptierter Wert Gewünschter Eigenschaftswert akzeptiert, wird aktualisiert (sollte mit 200 abgeschlossen werden)
203 0 Vom Gerät festgelegter Wert Vom Gerät festlegte Eigenschaft, entspricht keiner gewünschten Eigenschaft
400 Gewünschte Version Tatsächlicher vom Gerät verwendeter Wert Gewünschter Eigenschaftswert nicht akzeptiert
500 Gewünschte Version Tatsächlicher vom Gerät verwendeter Wert Ausnahme beim Anwenden der Eigenschaft

Nachdem ein Gerät gestartet wurde, sollte es den Gerätezwilling anfordern und eine Überprüfung auf Updates für schreibbare Eigenschaften durchführen. Wenn sich die Versionsnummer einer schreibbaren Eigenschaft erhöht hat, während sich das Gerät im Offlinezustand befunden hat, sollte vom Gerät eine Antwort vom Typ „Gemeldete Eigenschaft“ gesendet werden, um den Empfang des Updates zu bestätigen.

Wenn ein Gerät zum ersten Mal gestartet wird, kann es einen Anfangswert für eine gemeldete Eigenschaft senden, falls es vom IoT-Hub keine anfängliche gewünschte Eigenschaft empfängt. In diesem Fall kann das Gerät den Standardwert mit av an 0 und mit ac an 203 senden. Zum Beispiel:

"reported": {
  "targetTemperature": {
    "value": 20.0,
    "ac": 203,
    "av": 0,
    "ad": "initialize"
  }
}

Ein Gerät kann die gemeldete Eigenschaft verwenden, um weitere Informationen für den Hub bereitzustellen. Beispielsweise kann das Gerät mit einer Reihe von Meldungen vom Typ „Wird ausgeführt“ antworten, z. B.:

"reported": {
  "targetTemperature": {
    "value": 35.0,
    "ac": 202,
    "av": 3,
    "ad": "In-progress - reporting current temperature"
  }
}

Wenn das Gerät die Zieltemperatur erreicht, sendet es die folgende Meldung:

"reported": {
  "targetTemperature": {
    "value": 20.0,
    "ac": 200,
    "av": 4,
    "ad": "Reached target temperature"
  }
}

Ein Gerät kann einen Fehler melden, z. B.:

"reported": {
  "targetTemperature": {
    "value": 120.0,
    "ac": 500,
    "av": 3,
    "ad": "Target temperature out of range. Valid range is 10 to 99."
  }
}

Objekttyp

Wenn eine schreibbare Eigenschaft als Objekt definiert wird, muss der Dienst ein vollständiges Objekt an das Gerät senden. Das Gerät sollte das Update bestätigen, indem es ausreichende Informationen zurück an den Dienst sendet, damit er nachvollziehen kann, wie das Gerät bei dem Update reagiert hat. Diese Antwort könnte Folgendes enthalten:

  • Das gesamte Objekt.
  • Nur die Felder, die das Gerät aktualisiert hat.
  • Eine Teilmenge der Felder.

Bei großen Objekten sollten Sie erwägen, die Größe des Objekts, das Sie in die Bestätigung einbeziehen, zu minimieren.

Das folgende Beispiel zeigt eine schreibbare Eigenschaft, die als Object mit vier Feldern definiert wurde:

DTDL:

{
  "@type": "Property",
  "name": "samplingRange",
  "schema": {
    "@type": "Object",
    "fields": [
      {
        "name": "startTime",
        "schema": "dateTime"
      },
      {
        "name": "lastTime",
        "schema": "dateTime"
      },
      {
        "name": "count",
        "schema": "integer"
      },
      {
        "name": "errorCount",
        "schema": "integer"
      }
    ]
  },
  "displayName": "Sampling range"
  "writable": true
}

Senden Sie zum Aktualisieren dieser schreibbaren Eigenschaft ein vollständiges Objekt aus dem Dienst, das wie im folgenden Beispiel aussieht:

{
  "samplingRange": {
    "startTime": "2021-08-17T12:53:00.000Z",
    "lastTime": "2021-08-17T14:54:00.000Z",
    "count": 100,
    "errorCount": 5
  }
}

Das Gerät antwortet mit einer Bestätigung, die wie im folgenden Beispiel aussieht:

{
  "samplingRange": {
    "ac": 200,
    "av": 5,
    "ad": "Weighing status updated",
    "value": {
      "startTime": "2021-08-17T12:53:00.000Z",
      "lastTime": "2021-08-17T14:54:00.000Z",
      "count": 100,
      "errorCount": 5
    }
  }
}

Beispiel für eine schreibbare Eigenschaft eines Geräts ohne Komponenten

Wenn ein Gerät mehrere gewünschte Eigenschaften in einem einzelnen Nutzdatenelement empfängt, kann es die gemeldeten Eigenschaftsantworten über mehrere Nutzdatenelemente hinweg senden oder die Antworten in einem einzelnen Nutzdatenelement kombinieren.

Ein Gerät oder Modul kann eine gültige JSON-Nachricht senden, die den DTDL-Regeln entspricht.

DTDL:

{
  "@context": "dtmi:dtdl:context;2",
  "@id": "dtmi:example: Thermostat;1",
  "@type": "Interface",
  "contents": [
    {
      "@type": "Property",
      "name": "targetTemperature",
      "schema": "double",
      "writable": true
    },
    {
      "@type": "Property",
      "name": "targetHumidity",
      "schema": "double",
      "writable": true
    }
  ]
}

Beispiel für Nutzdaten einer gewünschten Eigenschaft:

"desired" :
{
  "targetTemperature" : 21.3,
  "targetHumidity" : 80,
  "$version" : 3
}

Beispiel für erstes Nutzdatenelement der gemeldeten Eigenschaft:

"reported": {
  "targetTemperature": {
    "value": 21.3,
    "ac": 200,
    "av": 3,
    "ad": "complete"
  }
}

Beispiel für zweites Nutzdatenelement der gemeldeten Eigenschaft:

"reported": {
  "targetHumidity": {
    "value": 80,
    "ac": 200,
    "av": 3,
    "ad": "complete"
  }
}

Hinweis

Sie könnten diese beiden gemeldeten Eigenschaftennutzdaten in einem einzelnen Nutzdatenelement kombinieren.

Beispiel für eine schreibbare Eigenschaft eines Geräts mit mehreren Komponenten

Das Gerät oder Modul muss zusätzlich den Marker {"__t": "c"} aufweisen, um anzugeben, dass das Element auf eine Komponente verweist.

Der Marker wird nur für Updates von Eigenschaften gesendet, die in einer Komponente definiert sind. Updates von Eigenschaften, die in der Standardkomponente definiert wurden, enthalten den Marker nicht. Lesen Sie dazu Beispiel für eine schreibbare Eigenschaft eines Geräts ohne Komponenten.

Wenn ein Gerät mehrere gemeldete Eigenschaften in einem einzelnen Nutzdatenelement empfängt, kann es die gemeldeten Eigenschaftenantworten über mehrere Nutzdatenelemente hinweg senden oder die Antworten in einem einzelnen Nutzdatenelement kombinieren.

Das Gerät oder Modul muss bestätigen, dass es die Eigenschaften erhalten hat, indem es gemeldete Eigenschaften sendet:

DTDL zum Verweisen auf eine Komponente:

{
  "@context": "dtmi:dtdl:context;2",
  "@id": "dtmi:com:example:TemperatureController;1",
  "@type": "Interface",
  "displayName": "Temperature Controller",
  "contents": [
    {
      "@type" : "Component",
      "schema": "dtmi:com:example:Thermostat;1",
      "name": "thermostat1"
    }
  ]
}

DTDL zum Definieren der Komponente:

{
  "@context": "dtmi:dtdl:context;2",
  "@id": "dtmi:com:example:Thermostat;1",
  "@type": "Interface",
  "contents": [
    {
      "@type": "Property",
      "name": "targetTemperature",
      "schema": "double",
      "writable": true
    }
  ]
}

Beispiel für Nutzdaten einer gewünschten Eigenschaft:

"desired": {
  "thermostat1": {
    "__t": "c",
    "targetTemperature": 21.3,
    "targetHumidity": 80,
    "$version" : 3
  }
}

Beispiel für erstes Nutzdatenelement der gemeldeten Eigenschaft:

"reported": {
  "thermostat1": {
    "__t": "c",
    "targetTemperature": {
      "value": 23,
      "ac": 200,
      "av": 3,
      "ad": "complete"
    }
  }
}

Beispiel für zweites Nutzdatenelement der gemeldeten Eigenschaft:

"reported": {
  "thermostat1": {
    "__t": "c",
    "targetHumidity": {
      "value": 80,
      "ac": 200,
      "av": 3,
      "ad": "complete"
    }
  }
}

Hinweis

Sie könnten diese beiden gemeldeten Eigenschaftennutzdaten in einem einzelnen Nutzdatenelement kombinieren.

Weitere Beispiele für schreibbare Eigenschaften finden Sie unter Nutzdaten > Eigenschaften.

Befehle

Bei Schnittstellen ohne Komponenten wird der Befehlsname ohne Präfix verwendet.

Bei einem Gerät oder Modul werden bei Schnittstellen mit mehreren Komponenten Befehlsnamen im folgenden Format verwendet: componentName*commandName.

Weitere Befehlsbeispiele finden Sie unter Nutzdaten > Befehle.

Tipp

IoT Central verfügt über eigene Konventionen für die Implementierung von Befehlen mit langer Ausführungsdauer und Offlinebefehlen.

Nächste Schritte

Nachdem Sie etwas über IoT Plug & Play-Konventionen erfahren haben, finden Sie jetzt hier einige weitere Ressourcen: