Share via


將 IoT 中樞遙測內嵌至 Azure Digital Twins

本指南會逐步解說撰寫函數的流程,該函數可以內嵌 IoT 中樞的裝置遙測,並將其傳送至 Azure Digital Twins 執行個體。

Azure Digital Twins 是由來自 IoT 裝置和其他來源的資料所驅動的。 在 Azure Digital Twins 中使用裝置資料的常見來源是 IoT 中樞

將資料內嵌到 Azure Digital Twins 的流程將會設定外部計算資源,例如使用 Azure Functions 建立的函數。 函數會接收資料,並使用 DigitalTwins API 來設定屬性,或據以在數位對應項上引發遙測事件。

本操作說明文件會逐步解說撰寫可從 IoT 中樞內嵌裝置遙測函數的流程。

必要條件

繼續進行此範例之前,您必須將下列資源設定為先決條件:

範例遙測情節

本操作說明描述如何使用 Azure 中的函數,將訊息從 IoT 中樞傳送至 Azure Digital Twins。 您可以使用許多可能的設定和比對策略來傳送訊息,但本文的範例包含下列部分:

  • IoT 中樞中的控溫器裝置,具有已知的裝置識別碼
  • 代表裝置的數位對應項,具有相符的識別碼

注意

此範例會使用裝置識別碼與所對應數位對應項識別碼之間的直接識別碼比對,但也可提供更為複雜的裝置與對應項對應 (如使用對應表)。

每當控溫器裝置傳送溫度遙測事件時,函數會處理遙測,且數位對應項的 Temperature 屬性將會更新。 下圖概述此情節:

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.

新增模型與對應項

在本節中,您將在 Azure Digital Twins 中設定數位對應項,以代表控溫器裝置,並使用來自 IoT 中樞的資訊進行更新。

若要建立控溫器型別的對應項,您必須先將控溫器模型上傳至執行個體,該模型描述控溫器的屬性,並在稍後用來建立對應項。

此模型看似如下:

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

若要將此模型上傳至對應項執行個體,請執行下列 Azure CLI 命令,將上述模型上傳為內置 JSON。 您可以在瀏覽器的 Azure Cloud Shell (使用 Bash 環境),或在您的機器上 (如果您有在本地安裝 CLI 時) 執行命令。 執行個體主機名稱有一個預留位置 (您也可以使用執行個體的自訂名稱,但效能會稍微降低)。

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

注意

如果您在 Bash 環境中使用 Cloud Shell 以外的任何項目,您可能需要逸出內嵌 JSON 中的特定字元,使系統正確剖析。 如需詳細資訊,請參閱在不同殼層中使用特殊字元

接著,您必須使用此模型建立一個對應項。 使用下列命令建立名為 thermostat67 的控溫器對應項,並將初始溫度值設定為 0.0。 系統將會有執行個體主機名稱的預留位置 (您也可以使用執行個體的自訂名稱,但效能會稍微減少)。

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

成功建立對應項時,命令的 CLI 輸出看起來應該會像這樣:

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

建立 Azure 函數

在本節中,您將建立 Azure 函數來存取 Azure Digital Twins,並根據接收的 IoT 裝置遙測事件來更新對應項。 請追隨下列步驟來建立和發佈函數。

  1. 首先,建立事件方格觸發程式類型的新 Azure Functions 專案。

    您可以使用 Visual Studio (如需相關指示,請參閱使用 Visual Studio 來開發 Azure Functions)、Visual Studio Code (如需相關指示,請參閱使用 Visual Studio Code 在 Azure 中建立 C# 函數) 或 Azure CLI (如需相關指示,請參閱從命令列在 Azure 中建立 C# 函數) 來執行此動作。

  2. 將下列套件新增至您的專案 (您可以使用 Visual Studio NuGet 套件管理員,或命令列工具中的 dotnet add package 命令)。

  3. 在名為 IoTHubtoTwins.cs 的專案內建立函數。 將下列程式碼貼到函數檔案中:

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

    儲存您的函數程式碼。

  4. 使用 IoTHubtoTwins.cs 函數,將專案發佈至 Azure 中的函數應用程式。

    對於如何使用 Visual Studio 來發佈函數,如需相關指示,請參閱使用 Visual Studio 來開發 Azure Functions。 如需如何使用 Visual Studio Code 來發佈函式的相關指示,請參閱使用 Visual Studio Code 以在 Azure 中建立 C# 函式。 對於如何使用 Azure CLI 來發佈函數,如需相關指示,請參閱從命令列在 Azure 中建立 C# 函數

函數發佈流程完成後,您可以使用此 Azure CLI 命令來驗證發佈是否成功。 系統將會有資源群組和函數應用程式名稱的預留位置。 此命令會列印 IoTHubToTwins 函數的相關資訊。

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

設定函式應用程式

若要存取 Azure Digital Twins,函數應用程式需要具有 Azure Digital Twins 執行個體存取權的系統指派的受控識別。 您會在本節中設定存取權,方法是指派存取角色給函數,並設定應用程式設定,以便存取您的 Azure Digital Twins 執行個體。

Azure Cloud Shell本機 Azure CLI 中執行下列命令。

注意

此區段必須由有權限管理使用者對 Azure 資源存取權的 Azure 使用者來完成,包括授與和委派權限。 符合此需求的常見角色包括:擁有者帳戶管理員,或使用者存取管理員參與者的組合。 如需 Azure Digital Twins 角色權限需求的詳細資訊,請參閱設定執行個體和驗證

指派存取角色

Azure 函數需要傳遞給角色的持有人權杖。 若要確定已傳遞持有人權杖,請為函數應用程式授與 Azure Digital Twins 執行個體的 Azure Digital Twins 資料擁有者角色,這會授與函數應用程式在執行個體上執行資料平面活動的權限。

  1. 使用下列命令來為函式建立 系統受控識別 (如果函式已經有,此命令將會列印其詳細資料)。 記下輸出中的 principalId 欄位。 您將使用此識別碼來參考函數,以便可以在下一個步驟中授與其權限。

    az functionapp identity assign --resource-group <your-resource-group> --name <your-function-app-name>	
    
  2. 使用下列命令中的 principalId 值,將函數提供給您 Azure Digital Twins 執行個體的 Azure Digital Twins 資料擁有者角色。

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

設定應用程式設定

接下來,為函數設定環境變數,讓您的 Azure Digital Twins 執行個體的 URL 存取函數。

提示

Azure Digital Twins 執行個體的 URL 是藉由將 https:// 新增至執行個體主機名稱的開頭加以建立。 若要查看主機名稱,以及執行個體的所有屬性,請執行 az dt show --dt-name <your-Azure-Digital-Twins-instance>

下列命令會設定執行個體 URL 的環境變數,每當函數需要存取執行個體時,就會使用該環境變數。

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

將函數連線至 IoT 中樞

在本節中,您會將函數設定為 IoT 中樞裝置資料的事件目的地。 以這種方式設定您的函數,可確保 IoT 中樞控溫器裝置的資料會傳送至 Azure 函數進行處理。

使用下列 CLI 命令來建立事件訂用帳戶,IoT 中樞會使用該帳戶將事件資料傳送至 IoTHubtoTwins 函數。 系統將會有預留位置可供您輸入事件訂用帳戶的名稱,以及其他預留位置可供您輸入訂用帳戶識別碼、資源群組、IoT 中樞名稱和函數應用程式的名稱。

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

關於已建立的事件訂用帳戶,輸出會顯示其相關資訊。 您可以藉由驗證結果中的 provisioningState 值來確認作業是否順利完成:

"provisioningState": "Succeeded",

使用模擬 IoT 資料進行測試

您可以使用連線到端對端解決方案中的裝置模擬器來測試新的輸入函數。 DeviceSimulator 專案包含可傳送樣本溫度資料的模擬控溫器裝置。 若要設定裝置模擬器,請追隨下列步驟:

  1. 瀏覽至 Azure Digital Twins 端對端樣本專案存放庫。 選取標題下方的 [瀏覽程式碼] 按鈕,以取得機器上的樣本專案。 這將會帶您前往樣本的 GitHub 存放庫,您可以選取 [程式碼] 按鈕,以及 [下載 ZIP] 按鈕,以 .zip 形式下載樣本。

    這會將 .ZIP 資料夾以 digital-twins-samples-main.zip 的形式下載至您的機器。 將資料夾解壓縮並擷取檔案。 您將使用 DeviceSimulator 專案資料夾。

  2. 向 IoT 中樞註冊模擬裝置

  3. 設定並執行模擬

完成這些步驟之後,您應該會看到執行中的專案主控台視窗,並將模擬的裝置遙測資料傳送至 IoT 中樞。

Screenshot of the output from the device simulator project.

驗證結果

執行上述裝置模擬器時,控溫器數位對應項的溫度值將會變更。 在 Azure CLI 中,執行下列命令以查看溫度值。 系統將會有執行個體主機名稱的預留位置 (您也可以使用執行個體的自訂名稱,但效能會稍微減少)。

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

注意

如果您在 Bash 環境中使用 Cloud Shell 以外的任何項目,您可能需要以不同的方式逸出查詢中的 $ 字元,使其正確剖析。 如需詳細資訊,請參閱在不同殼層中使用特殊字元

您的輸出應該會顯示 thermostat67 對應項的詳細資料,包括溫度值,如下所示:

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

若要查看 Temperature 值的變更,請重複執行上述查詢命令。

下一步

閱讀使用 Azure Digital Twins 的資料輸入和輸出: