Automatická správa zařízení ve službě Azure Digital Twins pomocí služby Device Provisioning Service (DPS)

V tomto článku se dozvíte, jak integrovat službu Azure Digital Twins se službou Device Provisioning Service (DPS).

Řešení popsané v tomto článku vám umožní automatizovat proces zřizování a vyřazení zařízení IoT Hubu ve službě Azure Digital Twins pomocí služby Device Provisioning.

Další informace ofázích

Požadavky

Než budete moct nastavit zřizování, budete muset nastavit následující prostředky:

Tato ukázka také používá simulátor zařízení, který zahrnuje zřizování pomocí služby Device Provisioning. Simulátor zařízení se nachází tady: Azure Digital Twins a Ukázka integrace služby IoT Hub. Získejte ukázkový projekt na svém počítači tak, že přejdete do úložiště GitHubu pro ukázku, které si můžete stáhnout jako soubor .zip výběrem tlačítka Kód a Stáhnout ZIP.

Snímek obrazovky s úložištěm digital-twins-iothub-integration na GitHubu a zvýrazněným postupem, jak ho stáhnout jako zip

Rozbalte staženou složku.

Na svém počítači budete potřebovat Node.js nainstalovat. Simulátor zařízení je založený na Node.js verze 10.0.x nebo novější.

Architektura řešení

Toto řešení zahrnuje kroky pro zřízení a vyřazení zařízení ve službě Azure Digital Twins pomocí služby Device Provisioning.

Pokud chcete přidělit zařízení v řešení, data proudí mezi termostatem a DPS. Data pak proudí z DPS do IoT Hubu a do Azure Digital Twins prostřednictvím funkce Azure.

Pokud chcete zařízení vyřadit, data z ručního odstranění zařízení se převedou do služby Azure Digital Twins prostřednictvím služby IoT Hub, Event Hubs a funkce Azure.

Následující obrázek znázorňuje tuto architekturu.

Diagram zařízení a několika služeb Azure v kompletním scénáři znázorňující tok dat

Tento článek je rozdělený do dvou částí, z nichž každá se zaměřuje na část této úplné architektury:

Automatické zřízení zařízení pomocí služby Device Provisioning

V této části připojíte službu Device Provisioning ke službě Azure Digital Twins k automatickému zřizování zařízení pomocí níže uvedené cesty. Tento diagram je výňatek z celé architektury, která je znázorněna dříve.

Diagram toku zřizování – výňatek diagramu architektury řešení, který sleduje data z termostatu do Služby Azure Digital Twins

Tady je popis toku procesu:

  1. Zařízení kontaktuje koncový bod DPS a předává identifikační informace, aby prokázalo svou identitu.
  2. DPS ověří identitu zařízení tím, že ověří ID registrace a klíč v seznamu registrací a zavolá funkci Azure, která provede přidělení.
  3. Funkce Azure pro zařízení vytvoří nové dvojče ve službě Azure Digital Twins. Dvojče bude mít stejný název jako ID registrace zařízení.
  4. DPS zaregistruje zařízení v Centru IoT a naplní zvolený stav dvojčete zařízení.
  5. IoT Hub vrací informace o ID zařízení a informace o připojení centra IoT k zařízení. Zařízení se teď může připojit k centru IoT.

Následující části projdou postupem nastavení tohoto toku zařízení automatického zřizování.

Vytvoření služby Device Provisioning

Když je nové zařízení zřízeno pomocí služby Device Provisioning, můžete v Azure Digital Twins vytvořit nové dvojče se stejným názvem jako ID registrace.

Vytvořte instanci služby Device Provisioning, která se použije ke zřízení zařízení IoT. Buď můžete použít následující pokyny Azure CLI, nebo pomocí webu Azure Portal nastavit službu IoT Hub Device Provisioning pomocí webu Azure Portal.

Následující příkaz Azure CLI vytvoří službu Device Provisioning. Budete muset zadat název služby Device Provisioning, skupinu prostředků a oblast. Pokud chcete zjistit, které oblasti podporují službu Device Provisioning, navštivte produkty Azure dostupné v jednotlivých oblastech. Příkaz můžete spustit v Cloud Shellu nebo místně, pokud máte na počítači nainstalované Rozhraní příkazového řádku Azure.

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

Přidání funkce pro použití se službou Device Provisioning

V projektu aplikace funkcí, který jste vytvořili v části Požadavky, vytvoříte novou funkci, která se použije se službou Device Provisioning. Tuto funkci bude služba Device Provisioning používat ve vlastních zásadách přidělování ke zřízení nového zařízení.

Přejděte na projekt aplikace funkcí na svém počítači a postupujte podle následujících kroků.

  1. Nejprve v projektu aplikace funkcí vytvořte novou funkci typu HTTP-trigger .

  2. Přidejte do projektu nový balíček NuGet: Microsoft.Azure.Devices.Provisioning.Service. Pokud balíčky použité v kódu ještě nejsou součástí projektu, budete možná muset do projektu přidat další balíčky.

  3. Do nově vytvořeného souboru kódu funkce vložte následující kód, pojmenujte funkci DpsAdtAllocationFunc.cs a soubor uložte.

    // 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. Publikujte projekt pomocí funkce DpsAdtAllocationFunc.cs do aplikace funkcí v Azure.

    Pokyny k publikování funkce pomocí sady Visual Studio najdete v tématu Vývoj azure Functions pomocí sady Visual Studio. Pokyny k publikování funkce pomocí editoru Visual Studio Code najdete v tématu Vytvoření funkce jazyka C# v Azure pomocí editoru Visual Studio Code. Pokyny k publikování funkce pomocí Azure CLI najdete v tématu Vytvoření funkce jazyka C# v Azure z příkazového řádku.

Důležité

Při prvním vytvoření aplikace funkcí v části Požadavky jste už možná přiřadili přístupovou roli pro tuto funkci a nakonfigurovali nastavení aplikace pro přístup k vaší instanci Azure Digital Twins. Tyto kroky je potřeba udělat jednou pro celou aplikaci funkcí, proto před pokračováním ověřte, že se dokončily ve vaší aplikaci. Pokyny najdete v části Konfigurace publikované aplikace v článku o ověřovacím kódu pro psaní aplikace.

Vytvoření registrace zařízení Provisioning

Dále budete muset vytvořit registraci ve službě Device Provisioning pomocí vlastní funkce přidělování. Pokud chcete vytvořit registraci, postupujte podle pokynů v části Vytvoření registrace článku o vlastních zásadách přidělování v dokumentaci ke službě Device Provisioning.

Při procházení tohoto toku nezapomeňte vybrat následující možnosti pro propojení registrace s funkcí, kterou jste vytvořili.

  • Vyberte, jak chcete přiřadit zařízení k rozbočovačům: Vlastní (použijte funkci Azure Functions).
  • Vyberte centra IoT, ke kterým může být tato skupina přiřazena: Zvolte název centra IoT nebo vyberte tlačítko Propojit nové centrum IoT a v možnostech zvolte centrum IoT.

Potom zvolte tlačítko Vybrat novou funkci a propojte aplikaci funkcí se skupinou registrací. Pak vyplňte následující hodnoty:

  • Předplatné: Vaše předplatné Azure je automaticky vyplněné. Ujistěte se, že je to správné předplatné.
  • Aplikace funkcí: Zvolte název aplikace funkcí.
  • Funkce: Zvolte DpsAdtAllocationFunc.

Uložte si podrobnosti.

Snímek obrazovky s oknem podrobností o skupině celní registrace na webu Azure Portal

Po vytvoření registrace ji vyberte a zobrazte její nastavení. Zkopírujte primární klíč pro registraci, který se použije později v tomto článku ke konfiguraci simulátoru zařízení.

Nastavení simulátoru zařízení

Tato ukázka používá simulátor zařízení, který zahrnuje zřizování pomocí služby Device Provisioning. Simulátor zařízení se nachází v ukázce integrace služby Azure Digital Twins a IoT Hubu, kterou jste stáhli v části Požadavky.

Nahrání modelu

Simulátor zařízení je zařízení typu termostat, které používá model s tímto ID: dtmi:contosocom:DigitalTwins:Thermostat;1. Před vytvořením dvojčete tohoto typu pro zařízení budete muset tento model nahrát do služby Azure Digital Twins.

Model vypadá takto:

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

Pokud chcete tento model nahrát do instance dvojčat, spusťte následující příkaz Azure CLI, který nahraje výše uvedený model jako vložený JSON. Příkaz můžete spustit v Azure Cloud Shellu v prohlížeči (použít prostředí Bash) nebo na počítači, pokud máte rozhraní příkazového řádku nainstalované místně. Pro název hostitele instance existuje jeden zástupný symbol (můžete také použít popisný název instance s mírným snížením výkonu).

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

Poznámka:

Pokud v prostředí Bash používáte cokoli jiného než Cloud Shell, budete možná muset utéct určitými znaky ve vloženém kódu JSON, aby se správně parsoval. Další informace naleznete v tématu Použití speciálních znaků v různých prostředích.

Další informace o modelech najdete v tématu Správa modelů.

Konfigurace a spuštění simulátoru

V příkazovém okně na místním počítači přejděte do stažené ukázkové integrace Azure Digital Twins a IoT Hubu, kterou jste rozbalili dříve, a pak do adresáře simulátoru zařízení. Potom pomocí následujícího příkazu nainstalujte závislosti projektu:

npm install

Dále v adresáři simulátoru zařízení zkopírujte soubor .env.template do nového souboru s názvem .env a shromážděte následující hodnoty, které vyplní nastavení:

  • PROVISIONING_IDSCOPE: Pokud chcete získat tuto hodnotu, přejděte na webu Azure Portal do služby zřizování zařízení, v možnostech nabídky vyberte Přehled a vyhledejte obor ID pole.

    Snímek obrazovky se zobrazením webu Azure Portal se stránkou přehledu zřizování zařízení se zvýrazněnou hodnotou Oboru ID

  • PROVISIONING_REGISTRATION_ID: Můžete zvolit ID registrace pro vaše zařízení.

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

  • PROVISIONING_SYMMETRIC_KEY: Tato proměnná prostředí je primárním klíčem pro registraci, kterou jste nastavili dříve. Pokud chcete tuto hodnotu získat znovu, přejděte na webu Azure Portal ke službě zřizování zařízení, vyberte Spravovat registrace a pak vyberte skupinu registrací, kterou jste vytvořili dříve, a zkopírujte primární klíč.

    Snímek obrazovky se zobrazením webu Azure Portal služby zřizování zařízení se stránkou pro správu registrací se zvýrazněnou hodnotou primárního klíče SAS

Teď pomocí výše uvedených hodnot aktualizujte nastavení souboru .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>"

Soubor uložte a zavřete.

Spuštění simulátoru zařízení

V adresáři simulátoru zařízení v příkazovém okně spusťte simulátor zařízení pomocí následujícího příkazu:

node .\adt_custom_register.js

Měli byste vidět, že zařízení je zaregistrované a připojené ke službě IoT Hub, a pak začít posílat zprávy. Snímek obrazovky s oknem Příkaz zobrazující registraci zařízení a odesílání zpráv

Ověřit

Tok, který jste nastavili v tomto článku, způsobí, že se zařízení automaticky zaregistruje ve službě Azure Digital Twins. Pomocí následujícího příkazu Azure Digital Twins CLI vyhledejte dvojče zařízení v instanci Azure Digital Twins, kterou jste vytvořili. Pro název hostitele instance je zástupný symbol (můžete také použít popisný název instance s mírným snížením výkonu) a zástupný symbol pro ID registrace zařízení.

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

Měli byste vidět dvojče zařízení, které se nachází v instanci Azure Digital Twins. Snímek obrazovky s oknem Příkaz zobrazující nově vytvořené dvojče

Automatické obnovení zařízení s využitím událostí životního cyklu služby IoT Hub

V této části připojíte události životního cyklu služby IoT Hub ke službě Azure Digital Twins, abyste mohli zařízení automaticky zregresovat pomocí níže uvedené cesty. Tento diagram je výňatek z celé architektury, která je znázorněna dříve.

Diagram toku vyřazení zařízení – výňatek z diagramu architektury řešení, který sleduje data z odstranění zařízení do služby Azure Digital Twins

Tady je popis toku procesu:

  1. Externí nebo ruční proces aktivuje odstranění zařízení ve službě IoT Hub.
  2. IoT Hub odstraní zařízení a vygeneruje událost životního cyklu zařízení, která se bude směrovat do centra událostí.
  3. Funkce Azure odstraní dvojče zařízení ve službě Azure Digital Twins.

Následující části projdou postupem nastavení tohoto toku zařízení pro autoretire.

Vytvoření centra událostí

Dále vytvoříte centrum událostí Azure pro příjem událostí životního cyklu služby IoT Hub.

Postupujte podle kroků popsaných v rychlém startu k vytvoření centra událostí. Pojmenujte životní cyklus centra událostí. Tento název centra událostí použijete při nastavování trasy ioT Hubu a funkce Azure v dalších částech.

Následující snímek obrazovky znázorňuje vytvoření centra událostí. Snímek obrazovky s oknem webu Azure Portal znázorňující, jak vytvořit centrum událostí s názvem lifecycleevents

Vytvoření zásad SAS pro centrum událostí

Dále budete muset vytvořit zásadu sdíleného přístupového podpisu (SAS) pro konfiguraci centra událostí s vaší aplikací funkcí. Vytvoření zásady SAS:

  1. Přejděte do centra událostí, které jste vytvořili na webu Azure Portal, a v možnostech nabídky vlevo vyberte Zásady sdíleného přístupu.
  2. Vyberte Přidat. V okně Přidat zásadu SAS, které se otevře, zadejte název zásady podle vašeho výběru a zaškrtněte políčko Naslouchat.
  3. Vyberte Vytvořit.

Snímek obrazovky webu Azure Portal znázorňující, jak přidat zásadu SAS centra událostí

Konfigurace centra událostí pomocí aplikace funkcí

Dále nakonfigurujte aplikaci funkcí Azure, kterou jste nastavili v části Požadavky, aby fungovala s novým centrem událostí. Funkci nakonfigurujete tak, že v aplikaci funkcí nastavíte proměnnou prostředí s připojovací řetězec centra událostí.

  1. Otevřete zásadu, kterou jste vytvořili, a zkopírujte hodnotu připojovacího řetězce primárního klíče .

    Snímek obrazovky webu Azure Portal znázorňující, jak zkopírovat připojovací řetězec primární klíč

  2. Do nastavení aplikace funkcí přidejte připojovací řetězec jako proměnnou pomocí následujícího příkazu Azure CLI. Příkaz můžete spustit v Cloud Shellu nebo místně, pokud máte na počítači nainstalované Rozhraní příkazového řádku Azure.

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

Přidání funkce pro vyřazení z časového cyklu služby IoT Hub

V projektu aplikace funkcí, který jste vytvořili v části Požadavky, vytvoříte novou funkci pro vyřazení existujícího zařízení pomocí událostí životního cyklu služby IoT Hub.

Další informace oudálostch Další informace o používání služby Event Hubs se službou Azure Functions najdete v tématu Trigger služby Azure Event Hubs pro Azure Functions.

Přejděte na projekt aplikace funkcí na svém počítači a postupujte podle následujících kroků.

  1. Nejprve v projektu aplikace funkcí vytvořte novou funkci typu Trigger centra událostí.

  2. Přidejte do projektu nový balíček NuGet: Microsoft.Azure.Devices.Provisioning.Service. Pokud balíčky použité v kódu ještě nejsou součástí projektu, budete možná muset do projektu přidat další balíčky.

  3. Do nově vytvořeného souboru kódu funkce vložte následující kód, pojmenujte funkci DeleteDeviceInTwinFunc.cs a soubor uložte.

    // 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. Publikujte projekt pomocí funkce DeleteDeviceInTwinFunc.cs do aplikace funkcí v Azure.

    Pokyny k publikování funkce pomocí sady Visual Studio najdete v tématu Vývoj azure Functions pomocí sady Visual Studio. Pokyny k publikování funkce pomocí editoru Visual Studio Code najdete v tématu Vytvoření funkce jazyka C# v Azure pomocí editoru Visual Studio Code. Pokyny k publikování funkce pomocí Azure CLI najdete v tématu Vytvoření funkce jazyka C# v Azure z příkazového řádku.

Důležité

Při prvním vytvoření aplikace funkcí v části Požadavky jste už možná přiřadili přístupovou roli pro tuto funkci a nakonfigurovali nastavení aplikace pro přístup k vaší instanci Azure Digital Twins. Tyto kroky je potřeba udělat jednou pro celou aplikaci funkcí, proto před pokračováním ověřte, že se dokončily ve vaší aplikaci. Pokyny najdete v části Konfigurace publikované aplikace v článku o ověřovacím kódu pro psaní aplikace.

Vytvoření trasy ioT Hubu pro události životního cyklu

Teď nastavíte trasu ioT Hubu pro směrování událostí životního cyklu zařízení. V tomto případě budete konkrétně naslouchat událostem odstranění zařízení identifikovaným uživatelem if (opType == "deleteDeviceIdentity"). Tato událost aktivuje odstranění položky digitálního dvojčete a dokončí proces vyřazení zařízení a jeho digitálního dvojčete.

Nejprve budete muset ve službě IoT Hub vytvořit koncový bod centra událostí. Pak do tohoto koncového bodu centra událostí přidáte trasu ve službě IoT Hub, která bude odesílat události životního cyklu. Pomocí následujícího postupu vytvořte koncový bod centra událostí:

  1. Na webu Azure Portal přejděte do centra IoT, které jste vytvořili v části Požadavky, a v možnostech nabídky vlevo vyberte Směrování zpráv.

  2. Vyberte kartu Vlastní koncové body.

  3. Vyberte + Přidat a zvolte Event Hubs a přidejte koncový bod typu Event Hubs.

    Snímek obrazovky webu Azure Portal znázorňující, jak přidat vlastní koncový bod služby Event Hubs

  4. V okně Přidejte koncový bod centra událostí, který se otevře, zvolte následující hodnoty:

    • Název koncového bodu: Zvolte název koncového bodu.
    • Obor názvů centra událostí: V rozevíracím seznamu vyberte obor názvů centra událostí.
    • Instance centra událostí: Zvolte název centra událostí, který jste vytvořili v předchozím kroku.
  5. Vyberte Vytvořit. Pokud chcete přidat trasu v dalším kroku, nechte toto okno otevřené.

    Snímek obrazovky webu Azure Portal znázorňující, jak přidat koncový bod centra událostí

Dále přidáte trasu, která se připojí ke koncovému bodu, který jste vytvořili v předchozím kroku, pomocí směrovacího dotazu, který odesílá události odstranění. Pokud chcete vytvořit trasu, postupujte takto:

  1. Přejděte na kartu Trasy a vyberte Přidat a přidejte trasu.

    Snímek obrazovky webu Azure Portal znázorňující, jak přidat trasu pro odesílání událostí

  2. Na stránce Přidat trasu, která se otevře, zvolte následující hodnoty:

    • Název: Zvolte název trasy.
    • Koncový bod: V rozevíracím seznamu zvolte koncový bod služby Event Hubs, který jste vytvořili dříve.
    • Zdroj dat: Zvolte události životního cyklu zařízení.
    • Dotaz směrování: Zadejte opType='deleteDeviceIdentity'. Tento dotaz omezuje události životního cyklu zařízení tak, aby odesílaly pouze události odstranění.
  3. Zvolte Uložit.

    Snímek obrazovky webu Azure Portal znázorňující, jak přidat trasu pro odesílání událostí životního cyklu

Jakmile tento tok projdete, všechno je nastavené tak, aby zařízení vyřadila z provozu.

Ověřit

Pokud chcete aktivovat proces vyřazení, musíte ručně odstranit zařízení ze služby IoT Hub.

Zařízení můžete ručně odstranit ze služby IoT Hub pomocí příkazu Azure CLI nebo na webu Azure Portal. Pomocí následujícího postupu odstraňte zařízení na webu Azure Portal:

  1. Přejděte do centra IoT a v možnostech nabídky vlevo zvolte zařízení IoT.
  2. Zobrazí se zařízení s ID registrace zařízení, které jste zvolili v první polovině tohoto článku. Můžete také zvolit jakékoli jiné zařízení, které chcete odstranit, pokud má dvojče ve službě Azure Digital Twins, abyste mohli ověřit, že se dvojče po odstranění zařízení automaticky odstraní.
  3. Vyberte zařízení a zvolte Odstranit.

Snímek obrazovky webu Azure Portal znázorňující, jak odstranit dvojče zařízení ze zařízení IoT

Může trvat několik minut, než se změny projeví ve službě Azure Digital Twins.

Pomocí následujícího příkazu Azure Digital Twins CLI ověřte, že se dvojče zařízení v instanci Azure Digital Twins odstranilo. Pro název hostitele instance je zástupný symbol (můžete také použít popisný název instance s mírným snížením výkonu) a zástupný symbol pro ID registrace zařízení.

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

Měli byste vidět, že dvojče zařízení se už v instanci Služby Azure Digital Twins nenašlo.

Snímek obrazovky s oknem Příkazového řádku, ve kterém je vidět, že dvojče už nejde najít

Vyčištění prostředků

Pokud už prostředky vytvořené v tomto článku nepotřebujete, odstraňte je následujícím postupem.

Pomocí Azure Cloud Shellu nebo místního Azure CLI můžete pomocí příkazu az group delete odstranit všechny prostředky Azure ve skupině prostředků. Tento příkaz odebere skupinu prostředků; instance Azure Digital Twins; IoT Hub a registrace zařízení centra; téma Event Gridu a přidružená předplatná; obor názvů služby Event Hubs i aplikace Azure Functions, včetně přidružených prostředků, jako je úložiště.

Důležité

Odstranění skupiny prostředků je nevratné. Skupina prostředků i všechny prostředky v ní obsažené se trvale odstraní. Ujistěte se, že nechtěně neodstraníte nesprávnou skupinu prostředků nebo prostředky.

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

Pak odstraňte ukázkovou složku projektu, kterou jste stáhli z místního počítače.

Další kroky

Digitální dvojčata vytvořená pro zařízení jsou uložená jako plochá hierarchie ve službě Azure Digital Twins, ale dají se rozšířit o informace o modelu a víceúrovňovou hierarchii pro organizaci. Další informace o tomto konceptu najdete tady:

Další informace o používání požadavků HTTP se službou Azure Functions najdete tady:

Můžete napsat vlastní logiku, která tyto informace automaticky poskytne pomocí dat modelu a grafu, která jsou už uložená ve službě Azure Digital Twins. Další informace o správě, upgradu a načítání informací z grafu dvojčat najdete v následujících návodech: