共用方式為


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

本指南會逐步解說撰寫可從IoT中樞擷取裝置遙測,並將其傳送至 Azure Digital Twins 實例的函式的程式。

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

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

本操作指南逐步解說撰寫可從 IoT 中樞匯入裝置遙測資料的函式。

先決條件

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

  • IoT 中樞。 如需指示,請參閱 此 IoT 中樞快速入門的<建立 IoT 中樞>一節
  • 接收您裝置遙測資料的 Azure Digital Twins 實例。 如需指示,請參閱 設定 Azure Digital Twins 實例和驗證

範例遙測案例

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

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

備註

此範例使用了裝置識別碼與相對應數位對應項識別碼之間的直接識別碼相符項,但可以提供從裝置到其對應項的更複雜的對應 (例如使用對應表)。

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

IoT 中樞裝置將溫度遙測傳送至 Azure 中函式的圖表,該函式會更新 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"
      }
    ]
  }

若要將此模型上傳至您的 Twins 實例,請執行下列 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;3",  "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}'

成功建立雙胞胎時,命令行介面的輸出應該像這樣:

{
  "$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 Hub 的控溫器裝置數據被傳送至 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中樞。

裝置模擬器項目的輸出螢幕快照。

驗證結果

如先前所示,在控制台視窗中執行裝置模擬器時,控溫器數字對應項的溫度值會變更。 在 Azure CLI 中,執行下列命令以查看溫度值。 有一個為執行個體主機名稱而設的預留位置(您也可以使用執行個體的友好名稱,但使用時效能會稍微降低)。

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

備註

如果您在 Bash 環境中使用非 Cloud Shell 的其他工具,您可能需要以不同方式跳脫查詢中的$字元,以便正確解析。 如需更多詳情,請參閱在不同命令列介面中使用特殊字元

您的輸出應該會顯示控溫器67 對應項的詳細數據,包括溫度值,如下所示:

{
  "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 的資料輸入和輸出: