Automatyczne zarządzanie urządzeniami w usłudze Azure Digital Twins przy użyciu usługi Device Provisioning Service (DPS)

Z tego artykułu dowiesz się, jak zintegrować usługę Azure Digital Twins z usługą Device Provisioning Service (DPS).

Rozwiązanie opisane w tym artykule pozwoli zautomatyzować proces aprowizacji i wycofywania urządzeń usługi IoT Hub w usłudze Azure Digital Twins przy użyciu usługi Device Provisioning Service.

Aby uzyskać więcej informacji na temat etapów aprowizacji i wycofywania oraz lepiej zrozumieć zestaw ogólnych etapów zarządzania urządzeniami, które są wspólne dla wszystkich projektów IoT przedsiębiorstwa, zobacz sekcję Cykl życia urządzenia w dokumentacji zarządzania urządzeniami w usłudze IoT Hub.

Wymagania wstępne

Przed skonfigurowaniem aprowizacji należy skonfigurować następujące zasoby:

  • Wystąpienie usługi Azure Digital Twins. Postępuj zgodnie z instrukcjami w temacie Konfigurowanie wystąpienia i uwierzytelniania , aby utworzyć wystąpienie usługi Azure Digital Twins. Zbierz nazwę hosta wystąpienia w witrynie Azure Portal (instrukcje).
  • Centrum IoT. Aby uzyskać instrukcje, zobacz sekcję "Tworzenie centrum IoT Hub" w przewodniku Szybki start usługi IoT Hub.
  • Funkcja platformy Azure, która aktualizuje informacje o cyfrowej reprezentacji bliźniaczej na podstawie danych usługi IoT Hub. Postępuj zgodnie z instrukcjami w temacie Pozyskiwanie danych centrum IoT Hub, aby utworzyć tę funkcję platformy Azure. Zbierz nazwę funkcji, aby użyć jej w tym artykule.

W tym przykładzie użyto również symulatora urządzenia, który obejmuje aprowizowanie przy użyciu usługi Device Provisioning Service. Symulator urządzenia znajduje się tutaj: Azure Digital Twins i IoT Hub Integration Sample. Pobierz przykładowy projekt na maszynie, przechodząc do repozytorium GitHub dla przykładu, który można pobrać jako plik zip, wybierając przycisk Kod i Pobierz plik ZIP.

Screenshot of the digital-twins-iothub-integration repo on GitHub, highlighting the steps to download it as a zip.

Rozpakuj pobrany folder.

Na maszynie będzie potrzebny plik Node.js . Symulator urządzenia jest oparty na środowisku Node.js w wersji 10.0.x lub nowszej.

Architektura rozwiązania

To rozwiązanie obejmuje kroki aprowizacji i wycofywania urządzenia w usłudze Azure Digital Twins przy użyciu usługi Device Provisioning Service.

Aby przydzielić urządzenia w rozwiązaniu, dane przepływa między urządzeniem termostatu a usługą DPS. Następnie dane przepływają z usługi DPS do usługi IoT Hub i do usługi Azure Digital Twins za pośrednictwem funkcji platformy Azure.

Aby wycofać urządzenie, dane z ręcznego usuwania urządzenia są przekazywane do usługi Azure Digital Twins za pośrednictwem usługi IoT Hub, usługi Event Hubs i funkcji platformy Azure.

Na poniższej ilustracji przedstawiono tę architekturę.

Diagram of device and several Azure services in an end-to-end scenario showing the data flow.

Ten artykuł jest podzielony na dwie sekcje, z których każda koncentruje się na części tej pełnej architektury:

Automatyczne aprowizowanie urządzenia przy użyciu usługi Device Provisioning Service

W tej sekcji dołączysz usługę Device Provisioning Service do usługi Azure Digital Twins w celu automatycznego aprowizowania urządzeń za pomocą poniższej ścieżki. Ten diagram jest fragmentem przedstawionej wcześniej pełnej architektury.

Diagram of Provision flow—an excerpt of the solution architecture diagram following data from a thermostat into Azure Digital Twins.

Oto opis przepływu procesu:

  1. Urządzenie kontaktuje się z punktem końcowym usługi DPS, przekazując informacje identyfikujące w celu potwierdzenia tożsamości.
  2. Usługa DPS weryfikuje tożsamość urządzenia, weryfikując identyfikator rejestracji i klucz na liście rejestracji, a następnie wywołuje funkcję platformy Azure w celu wykonania alokacji.
  3. Funkcja platformy Azure tworzy nową reprezentację bliźniacze w usłudze Azure Digital Twins dla urządzenia. Bliźniaczyna reprezentacja będzie mieć taką samą nazwę jak identyfikator rejestracji urządzenia.
  4. Usługa DPS rejestruje urządzenie w centrum IoT i wypełnia wybrany stan bliźniaczej reprezentacji urządzenia.
  5. Centrum IoT zwraca informacje o identyfikatorze urządzenia i informacje o połączeniu centrum IoT z urządzeniem. Urządzenie może teraz łączyć się z centrum IoT Hub.

W poniższych sekcjach opisano kroki konfigurowania tego przepływu urządzenia automatycznego aprowizacji.

Tworzenie usługi Device Provisioning Service

Po aprowizacji nowego urządzenia przy użyciu usługi Device Provisioning Service można utworzyć nową reprezentację bliźniacze dla tego urządzenia w usłudze Azure Digital Twins o takiej samej nazwie jak identyfikator rejestracji.

Utwórz wystąpienie usługi Device Provisioning Service, które będzie używane do aprowizowania urządzeń IoT. Możesz użyć poniższych instrukcji interfejsu wiersza polecenia platformy Azure lub użyć witryny Azure Portal, wykonując czynności opisane w temacie Konfigurowanie usługi IoT Hub Device Provisioning przy użyciu witryny Azure Portal.

Następujące polecenie interfejsu wiersza polecenia platformy Azure utworzy usługę Device Provisioning Service. Musisz określić nazwę usługi Device Provisioning Service, grupę zasobów i region. Aby zobaczyć, które regiony obsługują usługę Device Provisioning, odwiedź stronę Dostępność produktów platformy Azure według regionów. Polecenie można uruchomić w usłudze Cloud Shell lub lokalnie, jeśli na maszynie jest zainstalowany interfejs wiersza polecenia platformy Azure.

az iot dps create --name <Device-Provisioning-Service-name> --resource-group <resource-group-name> --location <region>

Dodawanie funkcji do użycia z usługą Device Provisioning Service

Wewnątrz projektu aplikacji funkcji utworzonego w sekcji Wymagania wstępne utworzysz nową funkcję do użycia z usługą Device Provisioning Service. Ta funkcja będzie używana przez usługę Device Provisioning Service w niestandardowych zasadach alokacji w celu aprowizacji nowego urządzenia.

Przejdź do projektu aplikacji funkcji na maszynie i wykonaj poniższe kroki.

  1. Najpierw utwórz nową funkcję typu HTTP-trigger w projekcie aplikacji funkcji.

  2. Dodaj nowy pakiet NuGet do projektu: Microsoft.Azure.Devices.Provisioning.Service. Może być konieczne dodanie kolejnych pakietów do projektu, jeśli pakiety używane w kodzie nie są już częścią projektu.

  3. W nowo utworzonym pliku kodu funkcji wklej następujący kod, nadaj funkcji nazwę DpsAdtAllocationFunc.cs i zapisz plik.

    // Copyright (c) Microsoft. All rights reserved.
    // Licensed under the MIT license. See LICENSE file in the project root for full license information.
    
    using System;
    using System.IO;
    using System.Net;
    using System.Net.Http;
    using System.Threading.Tasks;
    using Azure;
    using Azure.Core.Pipeline;
    using Azure.DigitalTwins.Core;
    using Azure.Identity;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Http;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Azure.WebJobs.Extensions.Http;
    using Microsoft.Azure.Devices.Shared;
    using Microsoft.Azure.Devices.Provisioning.Service;
    using Microsoft.Extensions.Logging;
    using Newtonsoft.Json;
    
    namespace Samples.AdtIothub
    {
        public static class DpsAdtAllocationFunc
        {
            private static string adtInstanceUrl = Environment.GetEnvironmentVariable("ADT_SERVICE_URL");
            private static readonly HttpClient singletonHttpClientInstance = new HttpClient();
    
            [FunctionName("DpsAdtAllocationFunc")]
            public static async Task<IActionResult> Run(
                [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log)
            {
                // Get request body
                string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
                log.LogDebug($"Request.Body: {requestBody}");
                dynamic data = JsonConvert.DeserializeObject(requestBody);
    
                // Get registration ID of the device
                string regId = data?.deviceRuntimeContext?.registrationId;
    
                bool fail = false;
                string message = "Uncaught error";
                var response = new ResponseObj();
    
                // Must have unique registration ID on DPS request
                if (regId == null)
                {
                    message = "Registration ID not provided for the device.";
                    log.LogInformation("Registration ID: NULL");
                    fail = true;
                }
                else
                {
                    string[] hubs = data?.linkedHubs.ToObject<string[]>();
    
                    // Must have hubs selected on the enrollment
                    if (hubs == null
                        || hubs.Length < 1)
                    {
                        message = "No hub group defined for the enrollment.";
                        log.LogInformation("linkedHubs: NULL");
                        fail = true;
                    }
                    else
                    {
                        // Find or create twin based on the provided registration ID and model ID
                        dynamic payloadContext = data?.deviceRuntimeContext?.payload;
                        string dtmi = payloadContext.modelId;
                        log.LogDebug($"payload.modelId: {dtmi}");
                        string dtId = await FindOrCreateTwinAsync(dtmi, regId, log);
    
                        // Get first linked hub (TODO: select one of the linked hubs based on policy)
                        response.iotHubHostName = hubs[0];
    
                        // Specify the initial tags for the device.
                        var tags = new TwinCollection();
                        tags["dtmi"] = dtmi;
                        tags["dtId"] = dtId;
    
                        // Specify the initial desired properties for the device.
                        var properties = new TwinCollection();
    
                        // Add the initial twin state to the response.
                        var twinState = new TwinState(tags, properties);
                        response.initialTwin = twinState;
                    }
                }
    
                log.LogDebug("Response: " + ((response.iotHubHostName != null)? JsonConvert.SerializeObject(response) : message));
    
                return fail
                    ? new BadRequestObjectResult(message)
                    : (ActionResult)new OkObjectResult(response);
            }
    
            public static async Task<string> FindOrCreateTwinAsync(string dtmi, string regId, ILogger log)
            {
                // Create Digital Twins client
                var cred = new DefaultAzureCredential();
                var client = new DigitalTwinsClient(new Uri(adtInstanceUrl), cred);
    
                // Find existing DigitalTwin with registration ID
                try
                {
                    // Get DigitalTwin with Id 'regId'
                    BasicDigitalTwin existingDt = await client.GetDigitalTwinAsync<BasicDigitalTwin>(regId).ConfigureAwait(false);
    
                    // Check to make sure it is of the correct model type
                    if (StringComparer.OrdinalIgnoreCase.Equals(dtmi, existingDt.Metadata.ModelId))
                    {
                        log.LogInformation($"DigitalTwin {existingDt.Id} already exists");
                        return existingDt.Id;
                    }
    
                    // Found DigitalTwin but it is not of the correct model type
                    log.LogInformation($"Found DigitalTwin {existingDt.Id} but it is not of model {dtmi}");
                }
                catch(RequestFailedException ex) when (ex.Status == (int)HttpStatusCode.NotFound)
                {
                    log.LogDebug($"Did not find DigitalTwin {regId}");
                }
    
                // Either the DigitalTwin was not found, or we found it but it is of a different model type
                // Create or replace it with what it needs to be, meaning if it was not found a brand new DigitalTwin will be created
                // and if it was of a different model, it will replace that existing DigitalTwin
                // If it was intended to only create the DigitalTwin if there is no matching DigitalTwin with the same Id,
                // ETag.All could have been used as the ifNonMatch parameter to the CreateOrReplaceDigitalTwinAsync method call.
                // Read more in the CreateOrReplaceDigitalTwinAsync documentation here:
                // https://docs.microsoft.com/en-us/dotnet/api/azure.digitaltwins.core.digitaltwinsclient.createorreplacedigitaltwinasync?view=azure-dotnet
                BasicDigitalTwin dt = await client.CreateOrReplaceDigitalTwinAsync(
                    regId, 
                    new BasicDigitalTwin
                    {
                        Metadata = { ModelId = dtmi },
                        Contents = 
                        {
                            { "Temperature", 0.0 }
                        }
                    }
                ).ConfigureAwait(false);
    
                log.LogInformation($"Digital Twin {dt.Id} created.");
                return dt.Id;
            }
        }
    
        /// <summary>
        /// Expected function result format
        /// </summary>
        public class ResponseObj
        {
            public string iotHubHostName { get; set; }
            public TwinState initialTwin { get; set; }
        }
    }
    
  4. Opublikuj projekt za pomocą funkcji DpsAdtAllocationFunc.cs w aplikacji funkcji na platformie Azure.

    Aby uzyskać instrukcje dotyczące publikowania funkcji przy użyciu programu Visual Studio, zobacz Tworzenie usługi Azure Functions przy użyciu programu Visual Studio. Aby uzyskać instrukcje dotyczące publikowania funkcji przy użyciu programu Visual Studio Code, zobacz Tworzenie funkcji języka C# na platformie Azure przy użyciu programu Visual Studio Code. Aby uzyskać instrukcje dotyczące publikowania funkcji przy użyciu interfejsu wiersza polecenia platformy Azure, zobacz Tworzenie funkcji języka C# na platformie Azure z poziomu wiersza polecenia.

Ważne

Podczas tworzenia aplikacji funkcji po raz pierwszy w sekcji Wymagania wstępne być może przypisano już rolę dostępu dla funkcji i skonfigurowano dla niej ustawienia aplikacji w celu uzyskania dostępu do wystąpienia usługi Azure Digital Twins. Należy je wykonać raz dla całej aplikacji funkcji, więc przed kontynuowaniem sprawdź, czy zostały one ukończone w aplikacji. Instrukcje można znaleźć w sekcji Konfigurowanie opublikowanej aplikacji w artykule Pisanie kodu uwierzytelniania aplikacji.

Tworzenie rejestracji aprowizacji urządzeń

Następnie należy utworzyć rejestrację w usłudze Device Provisioning Przy użyciu niestandardowej funkcji alokacji. Aby utworzyć rejestrację, postępuj zgodnie z instrukcjami w sekcji Tworzenie rejestracji w artykule niestandardowe zasady alokacji w dokumentacji usługi Device Provisioning Service.

Podczas przechodzenia przez ten przepływ upewnij się, że wybrano następujące opcje, aby połączyć rejestrację z utworzoną funkcją.

  • Wybierz sposób przypisywania urządzeń do centrów: niestandardowe (użyj funkcji platformy Azure).
  • Wybierz centra IoT, do których można przypisać tę grupę: wybierz nazwę centrum IoT Lub wybierz przycisk Połącz nowe centrum IoT Hub i wybierz swoje centrum IoT Hub z opcji.

Następnie wybierz przycisk Wybierz nową funkcję, aby połączyć aplikację funkcji z grupą rejestracji. Następnie wypełnij następujące wartości:

  • Subskrypcja: Twoja subskrypcja platformy Azure jest wypełniana automatycznie. Upewnij się, że jest to właściwa subskrypcja.
  • Aplikacja funkcji: wybierz nazwę aplikacji funkcji.
  • Funkcja: wybierz pozycję DpsAdtAllocationFunc.

Zapisz szczegóły.

Screenshot of the Customs enrollment group details window in the Azure portal.

Po utworzeniu rejestracji wybierz ją, aby wyświetlić jej ustawienia. Skopiuj klucz podstawowy rejestracji, który będzie używany w dalszej części tego artykułu w celu skonfigurowania symulatora urządzenia.

Konfigurowanie symulatora urządzenia

W tym przykładzie użyto symulatora urządzenia, który obejmuje aprowizowanie przy użyciu usługi Device Provisioning Service. Symulator urządzenia znajduje się w przykładzie integracji usługi Azure Digital Twins i usługi IoT Hub pobranym w sekcji Wymagania wstępne.

Przekazywanie modelu

Symulator urządzenia to urządzenie typu termostatu, które używa modelu o tym identyfikatorze: dtmi:contosocom:DigitalTwins:Thermostat;1. Przed utworzeniem bliźniaczej reprezentacji tego typu dla urządzenia należy przekazać ten model do usługi Azure Digital Twins.

Model wygląda następująco:

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

Aby przekazać ten model do wystąpienia reprezentacji bliźniaczych, uruchom następujące polecenie interfejsu wiersza polecenia platformy Azure, które przekazuje powyższy model jako wbudowany kod JSON. Możesz uruchomić polecenie w usłudze Azure Cloud Shell w przeglądarce (użyj środowiska powłoki Bash) lub na komputerze, jeśli interfejs wiersza polecenia jest zainstalowany lokalnie. Istnieje jeden symbol zastępczy nazwy hosta wystąpienia (można również użyć przyjaznej nazwy wystąpienia z niewielkim spadkiem wydajności).

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

Uwaga

Jeśli używasz niczego innego niż usługa Cloud Shell w środowisku powłoki Bash, może być konieczne ucieczka niektórych znaków w wbudowanym formacie JSON, aby była poprawnie analizowana. Aby uzyskać więcej informacji, zobacz Używanie znaków specjalnych w różnych powłokach.

Aby uzyskać więcej informacji na temat modeli, zobacz Zarządzanie modelami.

Konfigurowanie i uruchamianie symulatora

W oknie poleceń na komputerze lokalnym przejdź do pobranego przykładu usługi Azure Digital Twins i integracji usługi IoT Hub, która została rozpakowana wcześniej, a następnie do katalogu symulatora urządzeń. Następnie zainstaluj zależności dla projektu przy użyciu następującego polecenia:

npm install

Następnie w katalogu symulatora urządzenia skopiuj plik .env.template do nowego pliku o nazwie env i zbierz następujące wartości, aby wypełnić ustawienia:

  • PROVISIONING_IDSCOPE: Aby uzyskać tę wartość, przejdź do usługi aprowizacji urządzeń w witrynie Azure Portal, a następnie wybierz pozycję Przegląd w opcjach menu i wyszukaj zakres identyfikatora pola.

    Screenshot of the Azure portal view of the device provisioning overview page highlighting the ID Scope value.

  • PROVISIONING_REGISTRATION_ID: możesz wybrać identyfikator rejestracji urządzenia.

  • ADT_MODEL_ID: dtmi:contosocom:DigitalTwins:Thermostat;1

  • PROVISIONING_SYMMETRIC_KEY: ta zmienna środowiskowa jest kluczem podstawowym dla rejestracji skonfigurowanej wcześniej. Aby ponownie uzyskać tę wartość, przejdź do usługi aprowizacji urządzeń w witrynie Azure Portal, wybierz pozycję Zarządzaj rejestracjami, a następnie wybierz utworzoną wcześniej grupę rejestracji i skopiuj klucz podstawowy.

    Screenshot of the Azure portal view of the device provisioning service manage enrollments page highlighting the SAS primary key value.

Teraz użyj powyższych wartości, aby zaktualizować ustawienia pliku env .

PROVISIONING_HOST = "global.azure-devices-provisioning.net"
PROVISIONING_IDSCOPE = "<Device-Provisioning-Service-Scope-ID>"
PROVISIONING_REGISTRATION_ID = "<Device-Registration-ID>"
ADT_MODEL_ID = "dtmi:contosocom:DigitalTwins:Thermostat;1"
PROVISIONING_SYMMETRIC_KEY = "<Device-Provisioning-Service-enrollment-primary-SAS-key>"

Zapisz i zamknij plik.

Uruchamianie symulatora urządzenia

Nadal w katalogu device-simulator w oknie polecenia uruchom symulator urządzenia przy użyciu następującego polecenia:

node .\adt_custom_register.js

Powinno zostać wyświetlone urządzenie zarejestrowane i połączone z usługą IoT Hub, a następnie rozpoczęcie wysyłania komunikatów. Screenshot of the Command window showing device registration and sending messages.

Sprawdź poprawność

Przepływ skonfigurowany w tym artykule spowoduje automatyczne zarejestrowanie urządzenia w usłudze Azure Digital Twins. Użyj następującego polecenia interfejsu wiersza polecenia usługi Azure Digital Twins, aby znaleźć bliźniaczkę urządzenia w utworzonym wystąpieniu usługi Azure Digital Twins. Istnieje symbol zastępczy nazwy hosta wystąpienia (można również użyć przyjaznej nazwy wystąpienia z niewielkim spadkiem wydajności) i symbolem zastępczym identyfikatora rejestracji urządzenia.

az dt twin show --dt-name <instance-hostname-or-name> --twin-id "<device-registration-ID>"

Powinna zostać wyświetlona reprezentacja bliźniaczego urządzenia znalezionego w wystąpieniu usługi Azure Digital Twins. Screenshot of the Command window showing newly created twin.

Autoretire urządzenia przy użyciu zdarzeń cyklu życia usługi IoT Hub

W tej sekcji dołączysz zdarzenia cyklu życia usługi IoT Hub do usługi Azure Digital Twins w celu autoretire urządzeń za pomocą poniższej ścieżki. Ten diagram jest fragmentem przedstawionej wcześniej pełnej architektury.

Diagram of the Retire device flow—an excerpt of the solution architecture diagram, following data from a device deletion into Azure Digital Twins.

Oto opis przepływu procesu:

  1. Proces zewnętrzny lub ręczny wyzwala usunięcie urządzenia w usłudze IoT Hub.
  2. Usługa IoT Hub usuwa urządzenie i generuje zdarzenie cyklu życia urządzenia, które zostanie przekierowane do centrum zdarzeń.
  3. Funkcja platformy Azure usuwa bliźniacze reprezentacje urządzenia w usłudze Azure Digital Twins.

W poniższych sekcjach opisano kroki konfigurowania tego przepływu urządzenia autoretire.

Tworzenie centrum zdarzeń

Następnie utworzysz centrum zdarzeń platformy Azure w celu odbierania zdarzeń cyklu życia usługi IoT Hub.

Wykonaj kroki opisane w przewodniku Szybki start Tworzenie centrum zdarzeń. Nadaj nazwę cyklowi życia centrum zdarzeń. Ta nazwa centrum zdarzeń będzie używana podczas konfigurowania trasy usługi IoT Hub i funkcji platformy Azure w następnych sekcjach.

Poniższy zrzut ekranu przedstawia tworzenie centrum zdarzeń. Screenshot of the Azure portal window showing how to create an event hub with the name lifecycleevents.

Tworzenie zasad sygnatury dostępu współdzielonego dla centrum zdarzeń

Następnie należy utworzyć zasady sygnatury dostępu współdzielonego (SAS), aby skonfigurować centrum zdarzeń za pomocą aplikacji funkcji. Aby utworzyć zasady sygnatury dostępu współdzielonego:

  1. Przejdź do centrum zdarzeń utworzonego w witrynie Azure Portal i wybierz pozycję Zasady dostępu współdzielonego w opcjach menu po lewej stronie.
  2. Wybierz pozycję Dodaj. W oknie Dodawanie zasad sygnatury dostępu współdzielonego, które zostanie otwarte, wprowadź wybraną nazwę zasad i zaznacz pole wyboru Nasłuchiwanie.
  3. Wybierz pozycję Utwórz.

Screenshot of the Azure portal showing how to add an event hub SAS policy.

Konfigurowanie centrum zdarzeń za pomocą aplikacji funkcji

Następnie skonfiguruj aplikację funkcji platformy Azure skonfigurowaną w sekcji Wymagania wstępne, aby pracować z nowym centrum zdarzeń. Skonfigurujesz funkcję, ustawiając zmienną środowiskową wewnątrz aplikacji funkcji przy użyciu parametry połączenia centrum zdarzeń.

  1. Otwórz utworzone zasady i skopiuj wartość ciągu podstawowego Połączenie ion.

    Screenshot of the Azure portal showing how to copy the connection string-primary key.

  2. Dodaj parametry połączenia jako zmienną w ustawieniach aplikacji funkcji za pomocą następującego polecenia interfejsu wiersza polecenia platformy Azure. Polecenie można uruchomić w usłudze Cloud Shell lub lokalnie, jeśli na maszynie jest zainstalowany interfejs wiersza polecenia platformy Azure.

    az functionapp config appsettings set --settings "EVENTHUB_CONNECTIONSTRING=<Event-Hubs-SAS-connection-string-Listen>" --resource-group <resource-group> --name <your-function-app-name>
    

Dodawanie funkcji do wycofania zdarzeń cyklu życia usługi IoT Hub

Wewnątrz projektu aplikacji funkcji utworzonego w sekcji Wymagania wstępne utworzysz nową funkcję w celu wycofania istniejącego urządzenia przy użyciu zdarzeń cyklu życia usługi IoT Hub.

Aby uzyskać więcej informacji na temat zdarzeń cyklu życia, zobacz Zdarzenia nie telemetryczne usługi IoT Hub. Aby uzyskać więcej informacji na temat korzystania z usługi Event Hubs z usługą Azure Functions, zobacz Wyzwalacz usługi Azure Event Hubs dla usługi Azure Functions.

Przejdź do projektu aplikacji funkcji na maszynie i wykonaj poniższe kroki.

  1. Najpierw utwórz nową funkcję typu Wyzwalacz centrum zdarzeń w projekcie aplikacji funkcji.

  2. Dodaj nowy pakiet NuGet do projektu: Microsoft.Azure.Devices.Provisioning.Service. Może być konieczne dodanie kolejnych pakietów do projektu, jeśli pakiety używane w kodzie nie są już częścią projektu.

  3. W nowo utworzonym pliku kodu funkcji wklej następujący kod, nadaj funkcji nazwę DeleteDeviceInTwinFunc.cs i zapisz plik.

    // Copyright (c) Microsoft. All rights reserved.
    // Licensed under the MIT license. See LICENSE file in the project root for full license information.
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Threading.Tasks;
    using Azure;
    using Azure.Core.Pipeline;
    using Azure.DigitalTwins.Core;
    using Azure.Identity;
    using Microsoft.Azure.EventHubs;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Extensions.Logging;
    
    namespace Samples.AdtIothub
    {
        public static class DeleteDeviceInTwinFunc
        {
            private static string adtAppId = "https://digitaltwins.azure.net";
            private static readonly string adtInstanceUrl = Environment.GetEnvironmentVariable("ADT_SERVICE_URL", EnvironmentVariableTarget.Process);
            private static readonly HttpClient singletonHttpClientInstance = new HttpClient();
    
            [FunctionName("DeleteDeviceInTwinFunc")]
            public static async Task Run(
                [EventHubTrigger("lifecycleevents", Connection = "EVENTHUB_CONNECTIONSTRING")] EventData[] events, ILogger log)
            {
                var exceptions = new List<Exception>(events.Length);
    
                // Create Digital Twin client
                var cred = new ManagedIdentityCredential(adtAppId);
                var client = new DigitalTwinsClient(
                    new Uri(adtInstanceUrl),
                    cred,
                    new DigitalTwinsClientOptions
                    {
                        Transport = new HttpClientTransport(singletonHttpClientInstance)
                    });
    
                foreach (EventData eventData in events)
                {
                    try
                    {
                        //log.LogDebug($"EventData: {System.Text.Json.JsonSerializer.Serialize(eventData)}");
    
                        string opType = eventData.Properties["opType"] as string;
                        if (opType == "deleteDeviceIdentity")
                        {
                            string deviceId = eventData.Properties["deviceId"] as string;
    
                            try
                            {
                                // Find twin based on the original Registration ID
                                BasicDigitalTwin digitalTwin = await client.GetDigitalTwinAsync<BasicDigitalTwin>(deviceId);
    
                                // In order to delete the twin, all relationships must first be removed
                                await DeleteAllRelationshipsAsync(client, digitalTwin.Id, log);
    
                                // Delete the twin
                                await client.DeleteDigitalTwinAsync(digitalTwin.Id, digitalTwin.ETag);
                                log.LogInformation($"Twin {digitalTwin.Id} deleted in DT");
                            }
                            catch (RequestFailedException e) when (e.Status == (int)HttpStatusCode.NotFound)
                            {
                                log.LogWarning($"Twin {deviceId} not found in DT");
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        // We need to keep processing the rest of the batch - capture this exception and continue.
                        exceptions.Add(e);
                    }
                }
    
                if (exceptions.Count > 1)
                    throw new AggregateException(exceptions);
    
                if (exceptions.Count == 1)
                    throw exceptions.Single();
            }
    
            /// <summary>
            /// Deletes all outgoing and incoming relationships from a specified digital twin
            /// </summary>
            public static async Task DeleteAllRelationshipsAsync(DigitalTwinsClient client, string dtId, ILogger log)
            {
                AsyncPageable<BasicRelationship> relationships = client.GetRelationshipsAsync<BasicRelationship>(dtId);
                await foreach (BasicRelationship relationship in relationships)
                {
                    await client.DeleteRelationshipAsync(dtId, relationship.Id, relationship.ETag);
                    log.LogInformation($"Twin {dtId} relationship {relationship.Id} deleted in DT");
                }
    
                AsyncPageable<IncomingRelationship> incomingRelationships = client.GetIncomingRelationshipsAsync(dtId);
                await foreach (IncomingRelationship incomingRelationship in incomingRelationships)
                {
                    await client.DeleteRelationshipAsync(incomingRelationship.SourceId, incomingRelationship.RelationshipId);
                    log.LogInformation($"Twin {dtId} incoming relationship {incomingRelationship.RelationshipId} from {incomingRelationship.SourceId} deleted in DT");
                }
            }
        }
    }
    
  4. Opublikuj projekt za pomocą funkcji DeleteDeviceInTwinFunc.cs w aplikacji funkcji na platformie Azure.

    Aby uzyskać instrukcje dotyczące publikowania funkcji przy użyciu programu Visual Studio, zobacz Tworzenie usługi Azure Functions przy użyciu programu Visual Studio. Aby uzyskać instrukcje dotyczące publikowania funkcji przy użyciu programu Visual Studio Code, zobacz Tworzenie funkcji języka C# na platformie Azure przy użyciu programu Visual Studio Code. Aby uzyskać instrukcje dotyczące publikowania funkcji przy użyciu interfejsu wiersza polecenia platformy Azure, zobacz Tworzenie funkcji języka C# na platformie Azure z poziomu wiersza polecenia.

Ważne

Podczas tworzenia aplikacji funkcji po raz pierwszy w sekcji Wymagania wstępne być może przypisano już rolę dostępu dla funkcji i skonfigurowano dla niej ustawienia aplikacji w celu uzyskania dostępu do wystąpienia usługi Azure Digital Twins. Należy je wykonać raz dla całej aplikacji funkcji, więc przed kontynuowaniem sprawdź, czy zostały one ukończone w aplikacji. Instrukcje można znaleźć w sekcji Konfigurowanie opublikowanej aplikacji w artykule Pisanie kodu uwierzytelniania aplikacji.

Tworzenie trasy usługi IoT Hub dla zdarzeń cyklu życia

Teraz skonfigurujesz trasę usługi IoT Hub w celu kierowania zdarzeń cyklu życia urządzenia. W takim przypadku będziesz nasłuchiwać zdarzeń usuwania urządzenia zidentyfikowanych przez if (opType == "deleteDeviceIdentity")usługę . To zdarzenie spowoduje wyzwolenie usunięcia elementu cyfrowej reprezentacji bliźniaczej, ukończenie procesu wycofania urządzenia i jego cyfrowej reprezentacji bliźniaczej.

Najpierw należy utworzyć punkt końcowy centrum zdarzeń w centrum IoT Hub. Następnie dodasz trasę w centrum IoT, aby wysyłać zdarzenia cyklu życia do tego punktu końcowego centrum zdarzeń. Wykonaj następujące kroki, aby utworzyć punkt końcowy centrum zdarzeń:

  1. W witrynie Azure Portal przejdź do centrum IoT Hub utworzonego w sekcji Wymagania wstępne i wybierz pozycję Routing komunikatów w opcjach menu po lewej stronie.

  2. Wybierz kartę Niestandardowe punkty końcowe .

  3. Wybierz pozycję + Dodaj i wybierz pozycję Centra zdarzeń , aby dodać punkt końcowy typu usługi Event Hubs.

    Screenshot of the Azure portal showing how to add an Event Hubs custom endpoint.

  4. W oknie Dodawanie otwieranego punktu końcowego centrum zdarzeń wybierz następujące wartości:

    • Nazwa punktu końcowego: wybierz nazwę punktu końcowego.
    • Przestrzeń nazw centrum zdarzeń: wybierz przestrzeń nazw centrum zdarzeń z listy rozwijanej.
    • Wystąpienie centrum zdarzeń: wybierz nazwę centrum zdarzeń utworzoną w poprzednim kroku.
  5. Wybierz pozycję Utwórz. Pozostaw to okno otwarte, aby dodać trasę w następnym kroku.

    Screenshot of the Azure portal showing how to add an event hub endpoint.

Następnie dodasz trasę łączącą się z punktem końcowym utworzonym w powyższym kroku z zapytaniem routingu wysyłającym zdarzenia usuwania. Wykonaj następujące kroki, aby utworzyć trasę:

  1. Przejdź do karty Trasy i wybierz pozycję Dodaj , aby dodać trasę.

    Screenshot of the Azure portal showing how to add a route to send events.

  2. Na stronie Dodawanie trasy, która zostanie otwarta, wybierz następujące wartości:

    • Nazwa: wybierz nazwę trasy.
    • Punkt końcowy: wybierz utworzony wcześniej punkt końcowy usługi Event Hubs z listy rozwijanej.
    • Źródło danych: wybierz pozycję Zdarzenia cyklu życia urządzenia.
    • Zapytanie dotyczące routingu: wprowadź .opType='deleteDeviceIdentity' To zapytanie ogranicza zdarzenia cyklu życia urządzenia tylko do wysyłania zdarzeń usuwania.
  3. Wybierz pozycję Zapisz.

    Screenshot of the Azure portal showing how to add a route to send lifecycle events.

Po przejściu przez ten przepływ wszystko jest gotowe do wycofania urządzeń.

Sprawdź poprawność

Aby wyzwolić proces wycofywania, należy ręcznie usunąć urządzenie z usługi IoT Hub.

Urządzenie można usunąć ręcznie z usługi IoT Hub za pomocą polecenia interfejsu wiersza polecenia platformy Azure lub w witrynie Azure Portal. Wykonaj poniższe kroki, aby usunąć urządzenie w witrynie Azure Portal:

  1. Przejdź do centrum IoT i wybierz pozycję Urządzenia IoT w opcjach menu po lewej stronie.
  2. Zobaczysz urządzenie z identyfikatorem rejestracji urządzenia wybranym w pierwszej połowie tego artykułu. Możesz również wybrać dowolne inne urządzenie do usunięcia, o ile ma bliźniacze reprezentację w usłudze Azure Digital Twins, aby sprawdzić, czy bliźniaka zostanie automatycznie usunięta po usunięciu urządzenia.
  3. Wybierz urządzenie i wybierz pozycję Usuń.

Screenshot of the Azure portal showing how to delete device twin from the IoT devices.

Może upłynąć kilka minut, aby zobaczyć zmiany odzwierciedlone w usłudze Azure Digital Twins.

Użyj następującego polecenia interfejsu wiersza polecenia usługi Azure Digital Twins, aby sprawdzić, czy bliźniacze reprezentacje urządzenia w wystąpieniu usługi Azure Digital Twins zostały usunięte. Istnieje symbol zastępczy nazwy hosta wystąpienia (można również użyć przyjaznej nazwy wystąpienia z niewielkim spadkiem wydajności) i symbolem zastępczym identyfikatora rejestracji urządzenia.

az dt twin show --dt-name <instance-hostname-or-name> --twin-id "<device-registration-ID>"

W wystąpieniu usługi Azure Digital Twins nie można już odnaleźć bliźniaczej reprezentacji urządzenia.

Screenshot of the Command window showing that the twin can't be found anymore.

Czyszczenie zasobów

Jeśli nie potrzebujesz już zasobów utworzonych w tym artykule, wykonaj następujące kroki, aby je usunąć.

Za pomocą usługi Azure Cloud Shell lub lokalnego interfejsu wiersza polecenia platformy Azure można usunąć wszystkie zasoby platformy Azure w grupie zasobów za pomocą polecenia az group delete . To polecenie usuwa grupę zasobów; wystąpienie usługi Azure Digital Twins; centrum IoT i rejestracja urządzenia centrum; temat usługi Event Grid i skojarzone subskrypcje; Przestrzeń nazw usługi Event Hubs i aplikacje usługi Azure Functions, w tym skojarzone zasoby, takie jak magazyn.

Ważne

Usunięcie grupy zasobów jest nieodwracalne. Grupa zasobów oraz wszystkie zawarte w niej zasoby zostaną trwale usunięte. Uważaj, aby nie usunąć przypadkowo niewłaściwych zasobów lub grupy zasobów.

az group delete --name <your-resource-group>

Następnie usuń folder przykładowy projektu pobrany z komputera lokalnego.

Następne kroki

Cyfrowe reprezentacje bliźniacze utworzone dla urządzeń są przechowywane jako płaska hierarchia w usłudze Azure Digital Twins, ale można je wzbogacić o informacje o modelu i hierarchię wielowymiarową dla organizacji. Aby dowiedzieć się więcej na temat tej koncepcji, przeczytaj:

Aby uzyskać więcej informacji na temat korzystania z żądań HTTP w usłudze Azure Functions, zobacz:

Możesz napisać logikę niestandardową, aby automatycznie podać te informacje przy użyciu modelu i danych grafu przechowywanych już w usłudze Azure Digital Twins. Aby dowiedzieć się więcej na temat zarządzania, uaktualniania i pobierania informacji z grafu bliźniaczych reprezentacji, zobacz następujące przewodniki z instrukcjami: