Tutorial: Konfigurieren Ihrer Geräte über einen Back-End-Dienst

Im Rahmen des Gerätelebenszyklus müssen Sie möglicherweise Ihre IoT-Geräte über Ihren Back-End-Dienst konfigurieren. Wenn Sie eine gewünschte Konfiguration an Ihre Geräte senden, kann es sein, dass Sie auch Status- und Konformitätsaktualisierungen von diesen Geräten erhalten möchten. Beispielsweise können Sie einen Zieltemperaturbereich für den Betrieb eines Geräts festlegen oder Informationen zur Firmwareversion von Ihren Geräten erfassen.

Zum Synchronisieren von Zustandsinformationen zwischen einem Gerät und einem IoT Hub verwenden Sie Gerätezwillinge. Ein Gerätezwilling ist ein JSON-Dokument, das einem bestimmten Gerät zugeordnet ist und von IoT Hub in der Cloud gespeichert wird, wo es abgefragt werden kann. Ein Gerätezwilling enthält gewünschte Eigenschaften, gemeldete Eigenschaften und Tags.

  • Eine gewünschte Eigenschaft wird von einer Back-End-Anwendung festgelegt und von einem Gerät gelesen.
  • Eine gemeldete Eigenschaft wird von einem Gerät festgelegt und von einer Back-End-Anwendung gelesen.
  • Ein Tag wird von einer Back-End-Anwendung festgelegt und niemals an ein Gerät gesendet. Sie verwenden Tags, um Ihre Geräte zu organisieren.

In diesem Tutorial wird veranschaulicht, wie Sie gewünschte und gemeldete Eigenschaften zum Synchronisieren von Statusinformationen verwenden.

Diagram of device twins on the device and in the cloud.

In diesem Tutorial führen Sie die folgenden Aufgaben aus:

  • Erstellen eines IoT Hub und Hinzufügen eines Testgeräts zur Identitätsregistrierung
  • Verwenden von gewünschten Eigenschaften zum Senden von Statusinformationen an Ihr simuliertes Gerät
  • Verwenden von gemeldeten Eigenschaften zum Empfangen von Statusinformationen von Ihrem simulierten Gerät

Wenn Sie kein Azure-Abonnement besitzen, können Sie ein kostenloses Konto erstellen, bevor Sie beginnen.

Voraussetzungen

  • In diesem Tutorial wird die Azure CLI zum Erstellen von Cloudressourcen verwendet. Wenn Sie bereits über einen IoT-Hub verfügen, für den ein Gerät registriert ist, können Sie diese Schritte überspringen. Es gibt zwei Möglichkeiten zum Ausführen von CLI-Befehlen:

  • Die beiden in diesem Tutorial ausgeführten Beispielanwendungen sind in Node.js geschrieben. Sie benötigen mindestens Node.js v10.x.x auf Ihrem Entwicklungscomputer.

    • Sie können Node.js für mehrere Plattformen von nodejs.org herunterladen.

    • Mit dem folgenden Befehl können Sie die aktuelle Node.js-Version auf Ihrem Entwicklungscomputer überprüfen:

      node --version
      
  • Klonen Sie das Node.js-Beispielprojekt aus den Azure IoT-Beispielen für Node.js, oder laden Sie es herunter.

  • Stellen Sie sicher, dass der Port 8883 in Ihrer Firewall geöffnet ist. Für das Beispielgerät in diesem Tutorial wird das MQTT-Protokoll verwendet, das über Port 8883 kommuniziert. In einigen Netzwerkumgebungen von Unternehmen oder Bildungseinrichtungen ist dieser Port unter Umständen blockiert. Weitere Informationen und Problemumgehungen finden Sie unter Herstellen einer Verbindung mit IoT Hub (MQTT).

Einrichten von Azure-Ressourcen

Damit Sie dieses Tutorial durcharbeiten können, muss Ihr Azure-Abonnement einen IoT Hub mit einem Gerät enthalten, das der Geräteidentitätsregistrierung hinzugefügt wurde. Mit dem Eintrag in der Geräteidentitätsregistrierung kann für das simulierte Gerät, das Sie in diesem Tutorial ausführen, eine Verbindung mit Ihrem Hub hergestellt werden.

Falls Sie in Ihrem Abonnement noch keinen IoT Hub eingerichtet haben, können Sie hierfür das folgende CLI-Skript verwenden. In diesem Skript wird der Name tutorial-iot-hub mit einer angehängten zufälligen Zahl als IoT-Hub-Name verwendet. Sie können diesen Namen bei der Ausführung durch Ihren eigenen global eindeutigen Namen ersetzen. Mit dem Skript werden die Ressourcengruppe und der Hub in der Region Central US (USA, Mitte) erstellt. Sie können dies auch in eine Region ändern, die in Ihrer Nähe liegt. Das Skript ruft Ihre IoT Hub-Dienstverbindungszeichenfolge ab, die Sie im Back-End-Beispiel verwenden, um eine Verbindung mit Ihrem IoT Hub herzustellen:

let "randomIdentifier=$RANDOM*$RANDOM"  
hubname="tutorial-iot-hub-$randomIdentifier"
location=centralus

# Install the IoT extension if it's not already installed:
az extension add --name azure-iot

# Create a resource group:
az group create --name tutorial-iot-hub-rg --location $location

# Create your free-tier IoT hub. You can only have one free IoT hub per subscription.
# Change the sku to S1 to create a standard-tier hub if necessary.
az iot hub create --name $hubname --location $location --resource-group tutorial-iot-hub-rg --partition-count 2 --sku F1

# Make a note of the service connection string, you need it later:
az iot hub connection-string show --hub-name $hubname --policy-name service -o table

In diesem Tutorial wird ein simuliertes Gerät mit dem Namen MyTwinDevice verwendet. Mit dem folgenden Skript wird dieses Gerät Ihrer Identitätsregistrierung hinzugefügt und die Verbindungszeichenfolge abgerufen:

# Create the device in the identity registry:
az iot hub device-identity create --device-id MyTwinDevice --hub-name $hubname --resource-group tutorial-iot-hub-rg

# Retrieve the device connection string, you need this later:
az iot hub device-identity connection-string show --device-id MyTwinDevice --hub-name $hubname --resource-group tutorial-iot-hub-rg -o table

Senden von Zustandsinformationen an ein Gerät

Sie nutzen die gewünschten Eigenschaften, um Statusinformationen von einer Back-End-Anwendung an ein Gerät zu senden. In diesem Abschnitt wird Folgendes veranschaulicht:

  • Konfigurieren Sie ein Gerät, um gewünschte Eigenschaften zu empfangen und zu verarbeiten.
  • Senden Sie gewünschte Eigenschaften von einer Back-End-Anwendung an ein Gerät.

Beispiel für gewünschte Eigenschaften

Sie können die gewünschten Eigenschaften so strukturieren, wie dies für Ihre Anwendung am besten geeignet ist. In diesem Beispiel wird eine Eigenschaft der obersten Ebene mit dem Namen fanOn verwendet, und die übrigen Eigenschaften werden zu separaten Komponenten gruppiert. Im folgenden JSON-Codeausschnitt ist die Struktur der gewünschten Eigenschaften in diesem Tutorial dargestellt. Der JSON-Code befindet sich in der gewünschten JSON-Datei.

{
  "fanOn": "true",
  "components": {
    "system": {
      "id": "17",
      "units": "farenheit",
      "firmwareVersion": "9.75"
    },
    "wifi" : { 
      "channel" : "6",
      "ssid": "my_network"
    },
    "climate" : {
      "minTemperature": "68",
      "maxTemperature": "76"
    }
  }
}

Empfangen gewünschter Eigenschaften in einer Geräteanwendung

Navigieren Sie zum Anzeigen des Beispielcodes für das simulierte Gerät, über den die gewünschten Eigenschaften empfangen werden, im heruntergeladenen Node.js-Beispielprojekt zum Ordner iot-hub/Tutorials/DeviceTwins. Öffnen Sie anschließend die Datei „SimulatedDevice.js“ in einem Text-Editor.

In den folgenden Abschnitten wird der Code beschrieben, der auf dem simulierten Gerät ausgeführt wird und auf Änderungen gewünschter Eigenschaften reagiert, die von der Back-End-Anwendung gesendet werden.

Abrufen des Gerätezwillingsobjekts

Als Sie Ihr Gerät beim IoT-Hub registriert haben, haben Sie eine Geräteverbindungszeichenfolge als Ausgabe erhalten. Eine Geräteverbindungszeichenfolge wird vom Gerät verwendet, um sich mit seiner registrierten Identität in der Cloud zu authentifizieren. Mit dem folgenden Code wird eine Verbindung mit Ihrem IoT Hub über eine Geräteverbindungszeichenfolge hergestellt:

// Get the device connection string from a command line argument
var connectionString = process.argv[2];

Mit dem folgenden Code wird ein Zwilling aus dem Clientobjekt abgerufen:

// Get the device twin
client.getTwin(function(err, twin) {
  if (err) {
    console.error(chalk.red('Could not get device twin'));
  } else {
    console.log(chalk.green('Device twin created'));

Erstellen von Handlern

Sie können Handler für Aktualisierungen von gewünschten Eigenschaften erstellen, die auf unterschiedlichen Ebenen der JSON-Hierarchie auf Aktualisierungen antworten. Dieser Handler erkennt beispielsweise alle Änderungen gewünschter Eigenschaften, die über eine Back-End-Anwendung an das Gerät gesendet werden. Die Variable delta enthält die gewünschten Eigenschaften, die vom Back-End der Lösung gesendet werden:

// Handle all desired property updates
twin.on('properties.desired', function(delta) {
    console.log(chalk.yellow('\nNew desired properties received in patch:'));

Der folgende Handler reagiert nur auf Änderungen, die an der gewünschten Eigenschaft fanOn vorgenommen werden:

// Handle changes to the fanOn desired property
twin.on('properties.desired.fanOn', function(fanOn) {
    console.log(chalk.green('\nSetting fan state to ' + fanOn));

    // Update the reported property after processing the desired property
    reportedPropertiesPatch.fanOn = fanOn ? fanOn : '{unknown}';
});

Handler für mehrere Eigenschaften

In den Beispielen gewünschter Eigenschaften für den JSON-Code für dieses Tutorial enthält der Knoten climate unter components die beiden Eigenschaften minTemperature und maxTemperature.

Im lokalen Zwillingsobjekt (twin) eines Geräts wird ein vollständiger Satz mit gewünschten und gemeldeten Eigenschaften gespeichert. Mit den vom Back-End gesendeten delta-Daten wird unter Umständen nur eine Teilmenge der gewünschten Eigenschaften aktualisiert. Im folgenden Codeausschnitt wird – wenn das simulierte Gerät nur eine Aktualisierung für eines der beiden Elemente minTemperature und maxTemperature erhält – der Wert im lokalen Zwilling für den anderen Wert verwendet, um das Gerät zu konfigurieren:

// Handle desired properties updates to the climate component
twin.on('properties.desired.components.climate', function(delta) {
    if (delta.minTemperature || delta.maxTemperature) {
      console.log(chalk.green('\nUpdating desired tempertures in climate component:'));
      console.log('Configuring minimum temperature: ' + twin.properties.desired.components.climate.minTemperature);
      console.log('Configuring maximum temperture: ' + twin.properties.desired.components.climate.maxTemperature);

      // Update the reported properties and send them to the hub
      reportedPropertiesPatch.minTemperature = twin.properties.desired.components.climate.minTemperature;
      reportedPropertiesPatch.maxTemperature = twin.properties.desired.components.climate.maxTemperature;
      sendReportedProperties();
    }
});

Verarbeiten von Einfüge-, Aktualisierungs- und Löschvorgängen

Mit den vom Back-End gesendeten gewünschten Eigenschaften wird nicht angegeben, welcher Vorgang für eine bestimmte gewünschte Eigenschaft durchgeführt wird. In Ihrem Code muss der Vorgang aus dem aktuellen Satz mit den lokal gespeicherten gewünschten Eigenschaften und den vom Hub gesendeten Änderungen abgeleitet werden.

Der folgende Codeausschnitt zeigt, wie das simulierte Gerät Einfüge-, Aktualisierungs- und Löschvorgänge in der Liste mit den Komponenten in den gewünschten Eigenschaften verarbeitet. Sie sehen, wie Sie NULL-Werte verwenden, um anzugeben, dass eine Komponente gelöscht werden sollte:

// Keep track of all the components the device knows about
var componentList = {};

// Use this componentList list and compare it to the delta to infer
// if anything was added, deleted, or updated.
twin.on('properties.desired.components', function(delta) {
  if (delta === null) {
    componentList = {};
  }
  else {
    Object.keys(delta).forEach(function(key) {

      if (delta[key] === null && componentList[key]) {
        // The delta contains a null value, and the
        // device has a record of this component.
        // Must be a delete operation.
        console.log(chalk.green('\nDeleting component ' + key));
        delete componentList[key];

      } else if (delta[key]) {
        if (componentList[key]) {
          // The delta contains a component, and the
          // device has a record of it.
          // Must be an update operation.
          console.log(chalk.green('\nUpdating component ' + key + ':'));
          console.log(JSON.stringify(delta[key]));
          // Store the complete object instead of just the delta
          componentList[key] = twin.properties.desired.components[key];

        } else {
          // The delta contains a component, and the
          // device has no record of it.
          // Must be an add operation.
          console.log(chalk.green('\nAdding component ' + key + ':'));
          console.log(JSON.stringify(delta[key]));
          // Store the complete object instead of just the delta
          componentList[key] = twin.properties.desired.components[key];
        }
      }
    });
  }
});

Senden von gewünschten Eigenschaften von einer Back-End-Anwendung

Sie haben gesehen, wie ein Gerät Handler für den Empfang von Aktualisierungen für gewünschte Eigenschaften implementiert. In diesem Abschnitt wird veranschaulicht, wie Sie Änderungen gewünschter Eigenschaften von einer Back-End-Anwendung an ein Gerät senden.

Navigieren Sie zum Anzeigen des Beispielcodes für das simulierte Gerät, über den die gewünschten Eigenschaften empfangen werden, im heruntergeladenen Node.js-Beispielprojekt zum Ordner iot-hub/Tutorials/DeviceTwins. Öffnen Sie anschließend die Datei „ServiceClient.js“ in einem Text-Editor.

Im folgenden Codeausschnitt wird gezeigt, wie Sie eine Verbindung mit der Geräteidentitätsregistrierung herstellen und auf den Zwilling für ein bestimmtes Gerät zugreifen:

// Create a device identity registry object
var registry = Registry.fromConnectionString(connectionString);

// Get the device twin and send desired property update patches at intervals.
// Print the reported properties after some of the desired property updates.
registry.getTwin(deviceId, async (err, twin) => {
  if (err) {
    console.error(err.message);
  } else {
    console.log('Got device twin');

Im folgenden Codeausschnitt sind verschiedene Patches für gewünschte Eigenschaften dargestellt, die von der Back-End-Anwendung an das Gerät gesendet werden:

// Turn the fan on
var twinPatchFanOn = {
  properties: {
    desired: {
      patchId: "Switch fan on",
      fanOn: "false",
    }
  }
};

// Set the maximum temperature for the climate component
var twinPatchSetMaxTemperature = {
  properties: {
    desired: {
      patchId: "Set maximum temperature",
      components: {
        climate: {
          maxTemperature: "92"
        }
      }
    }
  }
};

// Add a new component
var twinPatchAddWifiComponent = {
  properties: {
    desired: {
      patchId: "Add WiFi component",
      components: {
        wifi: { 
          channel: "6",
          ssid: "my_network"
        }
      }
    }
  }
};

// Update the WiFi component
var twinPatchUpdateWifiComponent = {
  properties: {
    desired: {
      patchId: "Update WiFi component",
      components: {
        wifi: { 
          channel: "13",
          ssid: "my_other_network"
        }
      }
    }
  }
};

// Delete the WiFi component
var twinPatchDeleteWifiComponent = {
  properties: {
    desired: {
      patchId: "Delete WiFi component",
      components: {
        wifi: null
      }
    }
  }
};

Im folgenden Codeausschnitt ist zu sehen, wie die Back-End-Anwendung die Aktualisierung einer gewünschten Eigenschaft an ein Gerät sendet:

// Send a desired property update patch
async function sendDesiredProperties(twin, patch) {
  twin.update(patch, (err, twin) => {
    if (err) {
      console.error(err.message);
    } else {
      console.log(chalk.green(`\nSent ${twin.properties.desired.patchId} patch:`));
      console.log(JSON.stringify(patch, null, 2));
    }
  });
}

Empfangen von Zustandsinformationen von einem Gerät

Ihre Back-End-Anwendung empfängt Statusinformationen von einem Gerät als gemeldete Eigenschaften. Ein Gerät legt die gemeldeten Eigenschaften fest und sendet sie an Ihren Hub. Eine Back-End-Anwendung kann die aktuellen Werte der gemeldeten Eigenschaften vom Gerätezwilling lesen, der in Ihrem Hub gespeichert ist.

Senden von gemeldeten Eigenschaften von einem Gerät

Sie können Aktualisierungen für Werte von gemeldeten Eigenschaften als Patch senden. Der folgende Codeausschnitt enthält eine Vorlage für den Patch, der vom simulierten Gerät gesendet wird. Das simulierte Gerät aktualisiert die Felder im Patch, bevor dieser an den Hub gesendet wird:

// Create a patch to send to the hub
var reportedPropertiesPatch = {
  firmwareVersion:'1.2.1',
  lastPatchReceivedId: '',
  fanOn:'',
  minTemperature:'',
  maxTemperature:''
};

Für das simulierte Gerät wird die folgende Funktion verwendet, um den Patch mit den gemeldeten Eigenschaften an den Hub zu senden:

// Send the reported properties patch to the hub
function sendReportedProperties() {
  twin.properties.reported.update(reportedPropertiesPatch, function(err) {
    if (err) throw err;
    console.log(chalk.blue('\nTwin state reported'));
    console.log(JSON.stringify(reportedPropertiesPatch, null, 2));
  });
}

Verarbeiten von gemeldeten Eigenschaften

Eine Back-End-Anwendung greift über den Gerätezwilling auf die aktuellen Werte der gemeldeten Eigenschaften für ein Gerät zu. Im folgenden Codeausschnitt ist dargestellt, wie die Back-End-Anwendung die Werte der gemeldeten Eigenschaften für das simulierte Gerät liest:

// Display the reported properties from the device
function printReportedProperties(twin) {
  console.log("Last received patch: " + twin.properties.reported.lastPatchReceivedId);
  console.log("Firmware version: " + twin.properties.reported.firmwareVersion);
  console.log("Fan status: " + twin.properties.reported.fanOn);
  console.log("Min temperature set: " + twin.properties.reported.minTemperature);
  console.log("Max temperature set: " + twin.properties.reported.maxTemperature);
}

Ausführen der Anwendungen

In diesem Abschnitt führen Sie die beiden Beispielanwendungen aus, um zu verfolgen, wie eine Back-End-Anwendung Aktualisierungen für gewünschte Eigenschaften an eine Anwendung zur Simulation eines Geräts sendet.

Zum Ausführen der Anwendung zur Simulation eines Geräts und der Back-End-Anwendung benötigen Sie die Verbindungszeichenfolgen für das Gerät und den Dienst. Sie haben sich die Verbindungszeichenfolgen notiert, als Sie am Anfang dieses Tutorials die Ressourcen erstellt haben.

Öffnen Sie zum Ausführen der Anwendung zur Simulation eines Geräts ein Shell- oder Befehlseingabefenster, und navigieren Sie im heruntergeladenen Node.js-Projekt zum Ordner iot-hub/Tutorials/DeviceTwins. Führen Sie anschließend die folgenden Befehle aus:

npm install
node SimulatedDevice.js "{your device connection string}"

Öffnen Sie ein weiteres Shell- oder Befehlseingabefenster, um die Back-End-Anwendung auszuführen. Navigieren Sie anschließend im heruntergeladenen Node.js-Projekt zum Ordner iot-hub/Tutorials/DeviceTwins. Führen Sie anschließend die folgenden Befehle aus:

npm install
node ServiceClient.js "{your service connection string}"

Beobachten gewünschter Eigenschaftenupdates

Im folgenden Screenshot ist die Ausgabe der Anwendung zur Simulation eines Geräts dargestellt, und die Verarbeitung einer Aktualisierung der gewünschten Eigenschaft maxTemperature ist hervorgehoben. Sie sehen, wie der Handler der obersten Ebene und die Komponente „climate“ ausgeführt werden:

Screenshot that shows how both the top-level handler and the climate component handlers run.

Im folgenden Screenshot ist die Ausgabe der Back-End-Anwendung dargestellt, und das Senden einer Aktualisierung der gewünschten Eigenschaft maxTemperature ist hervorgehoben:

Screenshot that shows the output from the back-end application and highlights how it sends an update.

Beobachten gemeldeter Eigenschaftenupdates

Im folgenden Screenshot ist die Ausgabe der Anwendung zur Simulation eines Geräts dargestellt, und es ist hervorgehoben, wie eine Aktualisierung für gemeldete Eigenschaften an Ihren Hub gesendet werden:

Screenshot that shows the simulated device updating its twin state.

Im folgenden Screenshot ist die Ausgabe der Back-End-Anwendung zu sehen, und es ist hervorgehoben, wie eine Aktualisierung für gemeldete Eigenschaften von einem Gerät empfangen und verarbeitet wird:

Screenshot that shows the back-end application receiving the device reported properties.

Bereinigen von Ressourcen

Wenn Sie das nächste Tutorial ausführen möchten, können Sie die Ressourcengruppe und die IoT Hub-Instanz beibehalten und später erneut verwenden.

Falls Sie die IoT Hub-Instanz nicht mehr benötigen, löschen Sie die Ressourcengruppe über das Portal. Wählen Sie hierzu die Ressourcengruppe tutorial-iot-hub-rg aus, die Ihre IoT Hub-Instanz enthält, und wählen Sie Löschen aus.

Verwenden Sie alternativ hierzu die CLI:

# Delete your resource group and its contents
az group delete --name tutorial-iot-hub-rg

Nächste Schritte

In diesem Tutorial wurde beschrieben, wie Sie Statusinformationen zwischen Ihren Geräten und Ihrem IoT Hub synchronisieren. Im nächsten Tutorial wird beschrieben, wie Sie Gerätezwillinge zum Implementieren eines Prozesses zur Geräteaktualisierung verwenden.