Erfassen von IoT Hub Telemetriedaten in Azure Digital Twins

Dieser Leitfaden führt durch den Prozess des Schreibens einer Funktion, die Die Gerätetelemetrie von IoT Hub aufnehmen und an eine Instanz von Azure Digital Twins senden kann.

Azure Digital Twins wird mit Daten von IoT-Geräten und anderen Quellen gesteuert. Eine gängige Quelle für Gerätedaten zur Verwendung in Azure Digital Twins ist IoT Hub.

Der Prozess der Erfassung von Daten in Azure Digital Twins besteht darin, eine externe Computeressource einzurichten, z. B. eine Funktion, die mithilfe von Azure Functions erstellt wird. Die Funktion empfängt die Daten und verwendet APIs von Azure Digital Twins, um entsprechend für digitale Zwillinge Eigenschaften festzulegen oder Telemetrieereignisse auszulösen.

Dieses Vorgehensweisendokument durchläuft den Prozess zum Schreiben einer Funktion, die Gerätetelemetrie über IoT Hub aufnehmen kann.

Voraussetzungen

Bevor Sie mit diesem Beispiel fortfahren können, müssen Sie die folgenden Ressourcen als Voraussetzungen einrichten:

Beispieltelemetrieszenario

In dieser Schrittanleitung wird erläutert, wie Sie Nachrichten von IoT Hub mithilfe einer Funktion in Azure an Azure Digital Twins senden. Es gibt viele mögliche Konfigurationen und Abgleichstrategien, die Sie zum Senden von Nachrichten nutzen können, aber das Beispiel für diesen Artikel enthält die folgenden Teile:

  • Ein Thermostatgerät in IoT Hub mit einer bekannten Geräte-ID
  • Ein digitaler Zwilling als Darstellung des Geräts mit einer übereinstimmenden ID

Hinweis

In diesem Beispiel wird eine einfache ID-Übereinstimmung zwischen der Geräte-ID und der ID eines zugehörigen digitalen Zwillings verwendet. Es können jedoch auch anspruchsvollere Zuordnungen vom Gerät zu dessen Zwilling bereitgestellt werden, z. B. eine Zuordnungstabelle.

Jedes Mal, wenn ein Temperaturtelemetrieereignis vom Thermometergerät gesendet wird, verarbeitet eine Funktion die Telemetrie und die Temperature Eigenschaft des digitalen Zwillings aktualisieren. Dieses Szenario ist nachstehend in einem Diagramm dargestellt:

Diagram of IoT Hub device sending Temperature telemetry to a function in Azure, which updates a Temperature property on a twin in Azure Digital Twins.

Hinzufügen eines Modells und eines Zwillings

In diesem Abschnitt richten Sie einen digitalen Zwilling in Azure Digital Twins ein, der das Thermostat darstellt und mit Informationen aus IoT Hub aktualisiert wird.

Wenn Sie den Zwilling des Thermostattyps erstellen möchten, müssen Sie zunächst das Thermostatmodell in Ihre Instanz hochladen, das die Eigenschaften eines Thermostats beschreibt und später zum Erstellen des Zwillings verwendet wird.

Das Modell sieht so aus:

{
    "@id": "dtmi:contosocom:DigitalTwins:Thermostat;1",
    "@type": "Interface",
    "@context": "dtmi:dtdl:context;3",
    "contents": [
      {
        "@type": "Property",
        "name": "Temperature",
        "schema": "double"
      }
    ]
  }

Führen Sie den folgenden Azure CLI-Befehl aus, der das obige Modell als Inline-JSON hochlädt, um dieses Modell in Ihre Twins-Instanz hochzuladen. Sie können den Befehl in Azure Cloud Shell in Ihrem Browser (verwenden Sie die Bash-Umgebung) oder auf Ihrem Computer ausführen, wenn die CLI lokal installiert ist. Es gibt einen Platzhalter für den Hostnamen der Instanz (Sie können auch den Anzeigenamen der Instanz mit einer leichten Verringerung der Leistung verwenden).

az dt model create --dt-name <instance-hostname-or-name> --models '{  "@id": "dtmi:contosocom:DigitalTwins:Thermostat;1",  "@type": "Interface",  "@context": "dtmi:dtdl:context;2",  "contents": [    {      "@type": "Property",      "name": "Temperature",      "schema": "double"    }  ]}' 

Hinweis

Wenn Sie etwas anderes als die Cloud Shell in der Bash-Umgebung verwenden, müssen Sie möglicherweise bestimmte Zeichen im JSON-Inlinecode mit Escapezeichen versehen, damit sie ordnungsgemäß analysiert werden. Weitere Informationen finden Sie unter Verwenden von Sonderzeichen in verschiedenen Shells.

Anschließend müssen Sie einen einzigen Zwilling mit diesem Modell erstellen. Verwenden Sie den folgenden Befehl zum Erstellen eines Thermostatzwillings mit dem Namen thermostat67 und zum Festlegen von „0,0“ als anfänglichen Temperaturwert. Es gibt einen Platzhalter für den Hostnamen der Instanz (Sie können auch den Anzeigenamen der Instanz mit einer leichten Verringerung der Leistung verwenden).

az dt twin create  --dt-name <instance-hostname-or-name> --dtmi "dtmi:contosocom:DigitalTwins:Thermostat;1" --twin-id thermostat67 --properties '{"Temperature": 0.0}'

Wenn der Zwilling erfolgreich erstellt wurde, sollte die CLI-Ausgabe des Befehls in etwa wie folgt aussehen:

{
  "$dtId": "thermostat67",
  "$etag": "W/\"0000000-9735-4f41-98d5-90d68e673e15\"",
  "$metadata": {
    "$model": "dtmi:contosocom:DigitalTwins:Thermostat;1",
    "Temperature": {
      "lastUpdateTime": "2021-09-09T20:32:46.6692326Z"
    }
  },
  "Temperature": 0.0
}

Erstellen der Azure-Funktion

In diesem Abschnitt erstellen Sie eine Azure-Funktion, um auf Azure Digital Twins zuzugreifen und Zwillinge basierend auf den empfangenen IoT-Gerätetelemetrieereignissen zu aktualisieren. Führen Sie die folgenden Schritte aus, um die Funktion zu erstellen und zu veröffentlichen.

  1. Erstellen Sie zunächst ein neues Azure Functions-Projekt des Typs „Event Grid-Trigger“.

    Dazu können Sie Folgendes verwenden: Visual Studio (Anweisungen finden Sie unter Entwickeln von Azure Functions mithilfe von Visual Studio), Visual Studio Code (Anweisungen finden Sie unter Erstellen einer C#-Funktion in Azure mit Visual Studio Code) oder die Azure CLI (Anweisungen finden Sie unter Erstellen einer C#-Funktion über die Befehlszeile in Azure).

  2. Fügen Sie Ihrem Projekt die folgenden Pakete hinzu (Sie können dazu den Visual Studio NuGet-Paket-Manager oder den Befehl dotnet add package in einem Befehlszeilentool verwenden).

  3. Erstellen Sie eine Funktion im Projekt namens IoTHubtoTwins.cs. Fügen Sie den folgenden Code in die Funktionsdatei ein:

    using System;
    using Azure;
    using System.Net.Http;
    using Azure.Core.Pipeline;
    using Azure.DigitalTwins.Core;
    using Azure.Identity;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Azure.WebJobs.Extensions.EventGrid;
    using Microsoft.Extensions.Logging;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    using Azure.Messaging.EventGrid;
    
    namespace IotHubtoTwins
    {
        public class IoTHubtoTwins
        {
            private static readonly string adtInstanceUrl = Environment.GetEnvironmentVariable("ADT_SERVICE_URL");
            private static readonly HttpClient httpClient = new HttpClient();
    
            [FunctionName("IoTHubtoTwins")]
            // While async void should generally be used with caution, it's not uncommon for Azure function apps, since the function app isn't awaiting the task.
    #pragma warning disable AZF0001 // Suppress async void error
            public async void Run([EventGridTrigger] EventGridEvent eventGridEvent, ILogger log)
    #pragma warning restore AZF0001 // Suppress async void error
            {
                if (adtInstanceUrl == null) log.LogError("Application setting \"ADT_SERVICE_URL\" not set");
    
                try
                {
                    // Authenticate with Digital Twins
                    var cred = new DefaultAzureCredential();
                    var client = new DigitalTwinsClient(new Uri(adtInstanceUrl), cred);
                    log.LogInformation($"ADT service client connection created.");
                
                    if (eventGridEvent != null && eventGridEvent.Data != null)
                    {
                        log.LogInformation(eventGridEvent.Data.ToString());
    
                        // <Find_device_ID_and_temperature>
                        JObject deviceMessage = (JObject)JsonConvert.DeserializeObject(eventGridEvent.Data.ToString());
                        string deviceId = (string)deviceMessage["systemProperties"]["iothub-connection-device-id"];
                        var temperature = deviceMessage["body"]["Temperature"];
                        // </Find_device_ID_and_temperature>
    
                        log.LogInformation($"Device:{deviceId} Temperature is:{temperature}");
    
                        // <Update_twin_with_device_temperature>
                        var updateTwinData = new JsonPatchDocument();
                        updateTwinData.AppendReplace("/Temperature", temperature.Value<double>());
                        await client.UpdateDigitalTwinAsync(deviceId, updateTwinData);
                        // </Update_twin_with_device_temperature>
                    }
                }
                catch (Exception ex)
                {
                    log.LogError($"Error in ingest function: {ex.Message}");
                }
            }
        }
    }
    

    Speichern Sie Ihren Funktionscode.

  4. Veröffentlichen Sie das Projekt mit der Funktion IoTHubtoTwins.cs in einer Funktions-App in Azure.

    Anweisungen zum Veröffentlichen der Funktion mithilfe von Visual Studio finden Sie unter Entwickeln von Azure Functions mithilfe von Visual Studio. Anweisungen zum Veröffentlichen der Funktion mithilfe von Visual Studio Code finden Sie unter Erstellen einer C#-Funktion in Azure mit Visual Studio Code. Anweisungen zum Veröffentlichen der Funktion mithilfe der Azure CLI finden Sie unter Erstellen einer C#-Funktion über die Befehlszeile in Azure.

Sobald der Prozess der Veröffentlichung der Funktion abgeschlossen ist, können Sie mithilfe dieses Azure CLI-Befehls überprüfen, ob die Veröffentlichung erfolgreich war. Es sind Platzhalter für Ihre Ressourcengruppe und den Namen Ihrer Funktionsanwendung vorhanden. Der Befehl gibt Informationen über die Funktion IoTHubToTwins aus.

az functionapp function show --resource-group <your-resource-group> --name <your-function-app> --function-name IoTHubToTwins

Konfigurieren der Funktions-App

Damit Ihre Funktions-App auf Azure Digital Twins zugreifen kann, muss sie über eine systemseitig zugewiesene verwaltete Identität mit Zugriffsberechtigungen für Ihre Azure Digital Twins-Instanz verfügen. Sie richten die im vorliegenden Abschnitt ein, indem Sie der Funktion eine Zugriffsrolle zuweisen und die Anwendungseinstellungen so konfigurieren, dass sie auf Ihre Azure Digital Twins-Instanz zugreifen kann.

Führen Sie die folgenden Befehle in Azure Cloud Shell oder einer lokalen Installation der Azure CLI aus.

Hinweis

Dieser Abschnitt muss von einem Azure-Benutzer durchgeführt werden, der über die nötigen Berechtigungen zum Verwalten des Benutzerzugriffs auf Azure-Ressourcen (einschließlich des Gewährens und Delegieren von Berechtigungen) verfügt. Allgemeine Rollen, die diese Anforderung erfüllen, heißen Besitzer oder Kontoadministrator. Ebenso können die beiden Rollen Benutzerzugriffsadministrator und Mitwirkender kombiniert werden. Weitere Informationen zu den erforderlichen Berechtigungen für Azure Digital Twins-Rollen finden Sie unter Einrichten einer Azure Digital Twins-Instanz und der Authentifizierung (Portal).

Zuweisen einer Zugriffsrolle

Die Azure-Funktion erfordert die Übergabe eines Bearertokens. Um sicherzustellen, dass das Bearertoken übergeben wird, erteilen Sie der Funktions-App die Rolle Azure Digital Twins-Datenbesitzer für Ihre Azure Digital Twins-Instanz, die der Funktions-App die Berechtigung zum Ausführen von Datenebenenaktivitäten für die Instanz erteilt.

  1. Verwenden Sie den folgenden Befehl, um eine systemseitig verwaltete Identität für Ihre Funktion zu erstellen (wenn die Funktion bereits über eine verfügt, gibt dieser Befehl deren Details aus). Notieren Sie sich das principalId Feld in der Ausgabe. Sie verwenden diese ID, um auf die Funktion zu verweisen, damit Sie ihr im nächsten Schritt Berechtigungen erteilen können.

    az functionapp identity assign --resource-group <your-resource-group> --name <your-function-app-name>	
    
  2. Verwenden Sie den Wert principalId im folgenden Befehl, um der Funktion die Rolle Azure Digital Twins-Datenbesitzer für Ihre Azure Digital Twins-Instanz zuzuweisen.

    az dt role-assignment create --dt-name <your-Azure-Digital-Twins-instance> --assignee "<principal-ID>" --role "Azure Digital Twins Data Owner"
    

Konfigurieren von Anwendungseinstellungen

Machen Sie als Nächstes die URL Ihrer Azure Digital Twins-Instanz für Ihre Funktion zugänglich, indem Sie eine Umgebungsvariable dafür festlegen.

Tipp

Die URL der Azure Digital Twins-Instanz wird durch das Hinzufügen von https:// am Anfang des Hostnamens der Instanz erstellt. Um den Hostnamen mit allen Eigenschaften der Instanz anzuzeigen, führen Sie Folgendes aus: az dt show --dt-name <your-Azure-Digital-Twins-instance>.

Der folgende Befehl legt eine Umgebungsvariable für die URL Ihrer Instanz fest, die Ihre Funktion immer dann verwendet, wenn sie auf die Instanz zugreifen muss.

az functionapp config appsettings set --resource-group <your-resource-group> --name <your-function-app-name> --settings "ADT_SERVICE_URL=https://<your-Azure-Digital-Twins-instance-host-name>"

Verbinden der Funktion mit IoT Hub

In diesem Abschnitt richten Sie Ihre Funktion als Ereignisziel für die IoT Hub-Gerätedaten ein. Wenn Sie Ihre Funktion so einrichten, wird sichergestellt, dass die Daten aus dem Thermostatgerät in IoT Hub zur Verarbeitung an die Azure-Funktion gesendet werden.

Erstellen Sie mit dem folgenden CLI-Befehl ein Ereignisabonnement, das der IoT Hub verwendet, um Ereignisdaten an die Funktion IoTHubtoTwins zu senden. Es ist ein Platzhalter vorhanden, in den Sie einen Namen für das Ereignisabonnement eingeben können. Außerdem gibt es Platzhalter, in die Sie Ihre Abonnement-ID, die Ressourcengruppe, den Namen des IoT-Hubs und den Namen Ihrer Funktions-App eingeben können.

az eventgrid event-subscription create --name <name-for-hub-event-subscription> --event-delivery-schema eventgridschema --source-resource-id /subscriptions/<your-subscription-ID>/resourceGroups/<your-resource-group>/providers/Microsoft.Devices/IotHubs/<your-IoT-hub> --included-event-types Microsoft.Devices.DeviceTelemetry --endpoint-type azurefunction --endpoint /subscriptions/<your-subscription-ID>/resourceGroups/<your-resource-group>/providers/Microsoft.Web/sites/<your-function-app>/functions/IoTHubtoTwins

Die Ausgabe enthält Informationen über das erstellte Ereignisabonnement. Sie können bestätigen, dass der Vorgang erfolgreich abgeschlossen wurde, indem Sie den Wert provisioningState im Ergebnis überprüfen:

"provisioningState": "Succeeded",

Testen mit simulierten IoT-Daten

Sie können Ihre neue Eingangsfunktion testen, indem Sie den Gerätesimulator aus Verbinden einer End-to-End-Lösung verwenden. Das Projekt DeviceSimulator enthält einen simulierten Thermostat, der Beispieltemperaturdaten sendet. Um den Gerätesimulator einzurichten, gehen Sie folgendermaßen vor:

  1. Navigieren Sie zum Repository für das Azure Digital Twins-End-to-End-Projekt. Laden Sie das Beispielprojekt auf Ihren Computer herunter, indem Sie unter dem Titel auf die Schaltfläche Code durchsuchen klicken. Dadurch gelangen Sie zum GitHub-Repository für die Beispiele, die Sie als ZIP-Datei herunterladen können. Wählen Sie hierzu die Schaltfläche Code und anschließend ZIP herunterladen aus.

    Dadurch wird ein ZIP-Ordner (digital-twins-samples-main.zip) auf Ihren Computer heruntergeladen. Entpacken Sie den Ordner, und extrahieren Sie die Dateien. Sie verwenden den Projektordner DeviceSimulator.

  2. Registrieren des simulierten Geräts bei IoT Hub

  3. Konfigurieren und Ausführen der Simulation

Nach Abschluss dieser Schritte sollten Sie über ein Projektkonsolenfenster verfügen, in dem simulierte Gerätetelemetriedaten an Ihren IoT-Hub gesendet werden.

Screenshot of the output from the device simulator project.

Überprüfen der Ergebnisse

Während der Ausführung des vorstehenden Gerätesimulators ändert sich der Temperaturwert des digitalen Zwillings Ihres Thermostats. Führen Sie in der Azure CLI den folgenden Befehl zum Anzeigen des Temperaturwerts aus. Es gibt einen Platzhalter für den Hostnamen der Instanz (Sie können auch den Anzeigenamen der Instanz mit einer leichten Verringerung der Leistung verwenden).

az dt twin query --query-command "SELECT * FROM digitaltwins WHERE \$dtId = 'thermostat67'" --dt-name <instance-hostname-or-name>

Hinweis

Wenn Sie nicht die Cloud Shell in der Bash-Umgebung verwenden, müssen Sie möglicherweise das $-Zeichen in der Abfrage mit anderen Escapezeichen versehen, damit es ordnungsgemäß analysiert wird. Weitere Informationen finden Sie unter Verwenden von Sonderzeichen in verschiedenen Shells.

Ihre Ausgabe sollte die Details des thermostat67-Zwillings, einschließlich eines Temperaturwerts, wie folgt anzeigen:

{
  "result": [
    {
      "$dtId": "thermostat67",
      "$etag": "W/\"dbf2fea8-d3f7-42d0-8037-83730dc2afc5\"",
      "$metadata": {
        "$model": "dtmi:contosocom:DigitalTwins:Thermostat;1",
        "Temperature": {
          "lastUpdateTime": "2021-06-03T17:05:52.0062638Z"
        }
      },
      "Temperature": 70.20518558807913
    }
  ]
}

Um zu sehen, wie sich der Wert Temperature ändert, führen Sie den obigen Abfragebefehl wiederholt aus.

Nächste Schritte

Informieren Sie sich über eingehende und ausgehende Daten mit Azure Digital Twins: