Mata in IoT Hub-telemetri i Azure Digital Twins

Den här guiden går igenom processen med att skriva en funktion som kan mata in enhetstelemetri från IoT Hub och skicka den till en instans av Azure Digital Twins.

Azure Digital Twins drivs med data från IoT-enheter och andra källor. En vanlig källa för enhetsdata som ska användas i Azure Digital Twins är IoT Hub.

Processen för att mata in data i Azure Digital Twins är att konfigurera en extern beräkningsresurs, till exempel en funktion som görs med hjälp av Azure Functions. Funktionen tar emot data och använder DigitalTwins-API:erna för att ange egenskaper eller utlösa telemetrihändelser på digitala tvillingar i enlighet med detta.

Det här instruktionsdokumentet går igenom processen för att skriva en funktion som kan mata in enhetstelemetri från IoT Hub.

Förutsättningar

Innan du fortsätter med det här exemplet måste du konfigurera följande resurser som förutsättningar:

Exempel på telemetriscenario

Den här instruktioner beskriver hur du skickar meddelanden från IoT Hub till Azure Digital Twins med hjälp av en funktion i Azure. Det finns många möjliga konfigurationer och matchande strategier som du kan använda för att skicka meddelanden, men exemplet för den här artikeln innehåller följande delar:

  • En termostatenhet i IoT Hub med ett känt enhets-ID
  • En digital tvilling som representerar enheten med ett matchande ID

Kommentar

I det här exemplet används en enkel ID-matchning mellan enhets-ID:t och motsvarande ID för en digital tvilling, men det går att tillhandahålla mer avancerade mappningar från enheten till tvillingen (till exempel med en mappningstabell).

När en temperaturtelemetrihändelse skickas av termostatenheten, bearbetar en funktion telemetrin Temperature och egenskapen för den digitala tvillingen bör uppdateras. Det här scenariot beskrivs i ett diagram nedan:

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.

Lägg till en modell och tvilling

I det här avsnittet konfigurerar du en digital tvilling i Azure Digital Twins som representerar termostatenheten och uppdateras med information från IoT Hub.

För att skapa en tvilling av termostattyp måste du först ladda upp termostatmodellen till din instans, som beskriver egenskaperna för en termostat och kommer att användas senare för att skapa tvillingen.

Modellen ser ut så här:

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

Om du vill ladda upp den här modellen till din twins-instans kör du följande Azure CLI-kommando, som laddar upp modellen ovan som infogad JSON. Du kan köra kommandot i Azure Cloud Shell i webbläsaren (använd Bash-miljön) eller på datorn om du har CLI installerat lokalt. Det finns en platshållare för instansens värdnamn (du kan också använda instansens eget namn med en liten minskning av prestanda).

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

Kommentar

Om du använder något annat än Cloud Shell i Bash-miljön kan du behöva undvika vissa tecken i infogad JSON så att den parsas korrekt. Mer information finns i Använda specialtecken i olika gränssnitt.

Sedan måste du skapa en tvilling med den här modellen. Använd följande kommando för att skapa en termostattvilling med namnet thermostat67 och ange 0,0 som ett initialt temperaturvärde. Det finns en platshållare för instansens värdnamn (du kan också använda instansens eget namn med en liten minskning av prestanda).

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

När tvillingen har skapats bör CLI-utdata från kommandot se ut ungefär så här:

{
  "$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
}

Skapa Azure-funktionen

I det här avsnittet skapar du en Azure-funktion för att komma åt Azure Digital Twins och uppdatera tvillingar baserat på telemetrihändelser för IoT-enheter som den tar emot. Följ stegen nedan för att skapa och publicera funktionen.

  1. Börja med att skapa ett nytt Azure Functions-projekt av typen Event Grid-utlösare.

    Du kan göra detta med Visual Studio (anvisningar finns i Utveckla Azure Functions med Visual Studio), Visual Studio Code (anvisningar finns i Skapa en C#-funktion i Azure med Visual Studio Code) eller Azure CLI (instruktioner finns i Skapa en C#-funktion i Azure från kommandoraden).

  2. Lägg till följande paket i projektet (du kan använda Visual Studio NuGet-pakethanteraren eller kommandot dotnet add package i ett kommandoradsverktyg).

  3. Skapa en funktion i projektet med namnet IoTHubtoTwins.cs. Klistra in följande kod i funktionsfilen:

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

    Spara funktionskoden.

  4. Publicera projektet med funktionen IoTHubtoTwins.cs till en funktionsapp i Azure.

    Anvisningar om hur du publicerar funktionen med Visual Studio finns i Utveckla Azure Functions med Visual Studio. Anvisningar om hur du publicerar funktionen med Visual Studio Code finns i Skapa en C#-funktion i Azure med Hjälp av Visual Studio Code. Anvisningar om hur du publicerar funktionen med hjälp av Azure CLI finns i Skapa en C#-funktion i Azure från kommandoraden.

När publiceringsprocessen har slutförts kan du använda det här Azure CLI-kommandot för att kontrollera att publiceringen lyckades. Det finns platshållare för resursgruppen och namnet på funktionsappen. Kommandot skriver ut information om funktionen IoTHubToTwins .

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

Konfigurera funktionsappen

För att få åtkomst till Azure Digital Twins behöver din funktionsapp en systemtilldelad hanterad identitet med behörighet att komma åt din Azure Digital Twins-instans. Du konfigurerar det i det här avsnittet genom att tilldela en åtkomstroll för funktionen och konfigurera programinställningarna så att den kan komma åt din Azure Digital Twins-instans.

Kör följande kommandon i Azure Cloud Shell eller ett lokalt Azure CLI.

Kommentar

Det här avsnittet måste slutföras av en Azure-användare som har behörighet att hantera användaråtkomst till Azure-resurser, inklusive beviljande och delegering av behörigheter. Vanliga roller som uppfyller detta krav är ägare, kontoadministratör eller kombinationen av administratör och deltagare för användaråtkomst. Mer information om behörighetskrav för Azure Digital Twins-roller finns i Konfigurera en instans och autentisering.

Tilldela en åtkomstroll

Azure-funktionen kräver att en ägartoken skickas till den. För att se till att ägartoken skickas beviljar du funktionsappen rollen Azure Digital Twins-dataägare för din Azure Digital Twins-instans, vilket ger funktionsappen behörighet att utföra dataplansaktiviteter på instansen.

  1. Använd följande kommando för att skapa en systemhanterad identitet för din funktion (om funktionen redan har en kommer det här kommandot att skriva ut sin information). Anteckna fältet principalId i utdata. Du använder det här ID:t för att referera till funktionen så att du kan ge den behörighet i nästa steg.

    az functionapp identity assign --resource-group <your-resource-group> --name <your-function-app-name>	
    
  2. principalId Använd värdet i följande kommando för att ge funktionen rollen Azure Digital Twins-dataägare för din Azure Digital Twins-instans.

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

Konfigurera programinställningar

Gör sedan URL:en för din Azure Digital Twins-instans tillgänglig för din funktion genom att ange en miljövariabel för den.

Dricks

Azure Digital Twins-instansens URL skapas genom att https:// läggs till i början av instansens värdnamn. Om du vill se värdnamnet, tillsammans med alla egenskaper för din instans, kör du az dt show --dt-name <your-Azure-Digital-Twins-instance>.

Följande kommando anger en miljövariabel för instansens URL som funktionen ska använda när den behöver komma åt instansen.

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>"

Anslut funktionen till IoT Hub

I det här avsnittet konfigurerar du funktionen som ett händelsemål för IoT Hub-enhetsdata. Om du konfigurerar funktionen på det här sättet ser du till att data från termostatenheten i IoT Hub skickas till Azure-funktionen för bearbetning.

Använd följande CLI-kommando för att skapa en händelseprenumeration som IoT Hub använder för att skicka händelsedata till funktionen IoTHubtoTwins . Det finns en platshållare där du kan ange ett namn för händelseprenumerationen och det finns även platshållare där du kan ange ditt prenumerations-ID, resursgrupp, IoT Hub-namn och namnet på din funktionsapp.

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

Utdata visar information om händelseprenumerationen som har skapats. Du kan bekräfta att åtgärden har slutförts genom att provisioningState verifiera värdet i resultatet:

"provisioningState": "Succeeded",

Testa med simulerade IoT-data

Du kan testa din nya ingressfunktion med hjälp av enhetssimulatorn från Anslut en lösning från slutpunkt till slutpunkt. DeviceSimulator-projektet innehåller en simulerad termostatenhet som skickar exempeltemperaturdata. Följ dessa steg för att konfigurera enhetssimulatorn:

  1. Gå till azure Digital Twins-exempellagringsplatsen från slutpunkt till slutpunkt. Hämta exempelprojektet på datorn genom att välja knappen Bläddra kod under rubriken. Detta tar dig till GitHub-lagringsplatsen för exemplen, som du kan ladda ned som en .zip genom att välja knappen Kod följt av Ladda ned ZIP.

    Då laddas en .zip-mapp ned till datorn som digital-twins-samples-main.zip. Packa upp mappen och extrahera filerna. Du kommer att använda projektmappen DeviceSimulator .

  2. Registrera den simulerade enheten med IoT Hub

  3. Konfigurera och köra simuleringen

När du har slutfört de här stegen bör du ha ett projektkonsolfönster som körs och skickar simulerade enhetstelemetridata till din IoT-hubb.

Screenshot of the output from the device simulator project.

Verifiera resultat

När du kör enhetssimulatorn ovan ändras temperaturvärdet för din digitala termostattvilling. I Azure CLI kör du följande kommando för att se temperaturvärdet. Det finns en platshållare för instansens värdnamn (du kan också använda instansens eget namn med en liten minskning av prestanda).

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

Kommentar

Om du använder något annat än Cloud Shell i Bash-miljön kan du behöva undvika $ tecknet i frågan på ett annat sätt så att det parsas korrekt. Mer information finns i Använda specialtecken i olika gränssnitt.

Dina utdata bör visa information om termostat67-tvillingen, inklusive ett temperaturvärde, så här:

{
  "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
    }
  ]
}

Om du vill se värdeändringen Temperature kör du frågekommandot ovan upprepade gånger.

Nästa steg

Läs mer om ingress och utgående data med Azure Digital Twins: