自訂配置原則可讓您進一步掌控將裝置指派給 IoT 中樞的方式。 透過自訂配置原則,您可在 Azure IoT 中樞裝置佈建服務 (DPS) 所提供的原則不符合案例的需求時,定義您自己的配置原則。 自訂配置原則會在託管於 Azure Functions 的 Webhook 中實作,並在一個或多個個別註冊和/或註冊群組上進行設定。 當裝置使用設定的註冊項目向 DPS 註冊時,DPS 會呼叫 Webhook,以找出裝置應該註冊到哪一個 IoT 中樞及其初始狀態 (選擇性)。 若要深入瞭解,請參閱 瞭解 Azure IoT 中樞裝置佈建服務的自訂配置原則。
本教學課程將示範如何使用以 C# 撰寫的 Azure 函式設定自訂配置原則。 裝置會指派給兩個 IoT 中樞的其中一個,這兩個中樞分別代表「Contoso 烤箱部門」和「Contoso 熱泵部門」。 要求佈建的裝置必須具有包含下列其中一個尾碼的註冊識別碼,才能進行佈建:
- Contoso 烤箱部門的是 -contoso-tstrsd-007
- Contoso 熱泵部門的是 -contoso-hpsd-088
會使用 Azure IoT C SDK 中包含的佈建範例來模擬裝置。
在這個教學中,你要執行以下動作:
- 使用 Azure CLI 建立 DPS 執行個體,然後建立兩個 Contoso 部門 IoT 中樞 (Contoso 烤箱部門和 Contoso 熱泵部門) 來與該執行個體連結。
- 建立實作自訂配置原則的 Azure 函式。
- 使用 Azure 函式為自訂配置原則建立新的註冊群組。
- 為兩個模擬裝置建立裝置對稱金鑰。
- 設定適用於 Azure IoT C SDK 的開發環境。
- 模擬裝置,並確認其根據自訂配置原則中的範例程式碼進行佈建。
如果您沒有 Azure 帳戶,請在開始之前建立 免費帳戶 。
先決條件
下列必要條件適用於 Windows 開發環境。 針對 Linux 或 macOS,請參閱 SDK 文件中準備您的開發環境中的適當章節。
Visual Studio 2022 並啟用使用 C++ 的桌面開發工作負載。 也會支援 Visual Studio 2015 和 Visual Studio 2017。
已安裝 Git。 如需詳細資訊,請參閱 Git 下載。
已安裝 Azure CLI。 如需詳細資訊,請參閱如何安裝 Azure CLI。 或者,您也可以在 Azure Cloud Shell 的 Bash 環境中執行本教學課程中的命令。
建立佈建服務和兩個 IoT 中樞
在本節中,您會使用 Azure Cloud Shell 建立佈建服務和兩個 IoT 中樞,分別代表 Contoso 烤箱部門和 Contoso 熱泵部門。
首先,在您的工作區中設定環境變數,以簡化本教學課程中的命令。
DPS 和 IoT 中樞名稱必須是全域唯一的。 將
SUFFIX預留位置取代為您自己的值。此外,您稍後將在本教學課程中建立的 Azure 函式程式碼會尋找其名稱中包含
-toasters-或-heatpumps-的 IoT 中樞。 如果您變更建議的值,請務必使用包含必要子字串的名稱。#!/bin/bash export RESOURCE_GROUP="contoso-us-resource-group" export LOCATION="westus" export DPS="contoso-provisioning-service-SUFFIX" export TOASTER_HUB="contoso-toasters-hub-SUFFIX" export HEATPUMP_HUB="contoso-heatpumps-hub-SUFFIX"# PowerShell $env:RESOURCE_GROUP = "contoso-us-resource-group" $env:LOCATION = "westus" $env:DPS = "contoso-provisioning-service-SUFFIX" $env:TOASTER_HUB = "contoso-toasters-hub-SUFFIX" $env:HEATPUMP_HUB = "contoso-heatpumps-hub-SUFFIX"秘訣
本教學課程中使用的命令預設會在美國西部位置中建立資源。 建議您在離您最近且支援裝置佈建服務的區域中建立資源。 你可以透過 Azure 狀態 頁面搜尋「Device Provisioning Service」來查看可用地點清單。 在指令中,位置可以以單字或多字格式指定;例如:westus、West US、WEST US 等。這個數值並不區分大小寫。
使用 az group create 命令來建立 Azure 資源群組。 Azure 資源群組是在其中部署與管理 Azure 資源的邏輯容器。
下列範例會建立資源群組。 建議您針對本教學課程中建立的所有資源使用單一群組。 透過此方法,您在完成作業後將可更容易清除資源。
az group create --name $RESOURCE_GROUP --location $LOCATION使用 az iot dps create 命令來建立裝置佈建服務 (DPS) 的執行個體。 該佈建服務會新增至 contoso-us-resource-group。
az iot dps create --name $DPS --resource-group $RESOURCE_GROUP --location $LOCATION此命令可能需要幾分鐘才能完成。
使用 az iot hub create 命令來建立 Contoso Toasters Division IoT 中樞。 該 IoT 中樞會新增至 contoso-us-resource-group。
az iot hub create --name $TOASTER_HUB --resource-group $RESOURCE_GROUP --location $LOCATION --sku S1此命令可能需要幾分鐘才能完成。
使用 az iot hub create 命令來建立 Contoso Heat Pumps Division IoT 中樞。 此 IoT 中樞也會新增至 contoso-us-resource-group。
az iot hub create --name $HEATPUMP_HUB --resource-group $RESOURCE_GROUP --location $LOCATION --sku S1此命令可能需要幾分鐘才能完成。
執行下列兩個命令,以取得您所建立中樞的連接字串。
az iot hub connection-string show --hub-name $TOASTER_HUB --key primary --query connectionString -o tsv az iot hub connection-string show --hub-name $HEATPUMP_HUB --key primary --query connectionString -o tsv執行下列命令,將中樞連結至 DPS 資源。 將預留位置取代為上一個步驟中的中樞連接字串。
az iot dps linked-hub create --dps-name $DPS --resource-group $RESOURCE_GROUP --location $LOCATION --connection-string <toaster_hub_connection_string> az iot dps linked-hub create --dps-name $DPS --resource-group $RESOURCE_GROUP --location $LOCATION --connection-string <heatpump_hub_connection_string>
建立自訂配置函式
在本節中,您會建立可實作自訂配置原則的 Azure 函式。 此函式會根據裝置的註冊識別碼是否包含 -contoso-tstrsd-007 或 -contoso-hpsd-088 字串,決定裝置應該註冊的部門 IoT 中樞。 也會根據裝置是烤箱或熱泵,設定裝置對應項的初始狀態。
登入 Azure 入口網站。
在搜尋方塊中,搜尋並選取 [函式應用程式]。
選取 [建立] 或 [建立函式應用程式]。
在 「建立功能應用程式 」頁面,在 「基礎 」標籤下,輸入以下設定,並選擇 「檢視+創建」:
參數 值 訂用帳戶 請確定您已選取您為此教學課程建立資源的訂用帳戶。 資源群組 選取您在上一節中建立的資源群組。 上一節中提供的預設值是 contoso-us-resource-group。 函式應用程式名稱 為您的函式應用程式提供名稱。 執行階段堆疊 .NET 版本 選取任何內含式模型版本。 區域 選取接近您的區域。 附註
預設會啟用 Application Insights。 應用程式洞察不是本教學的必要內容,但它可能幫助你理解並調查自訂分配時遇到的問題。 如果您想要的話,可以選取 [監視] 索引標籤,然後針對 [啟用 Application Insights] 選取 [否] 來停用 Application Insights。
在 [檢閱 + 建立] 索引標籤上,選取 [建立] 以建立函式應用程式。
部署可能需要數分鐘的時間。 完成時,選取 [移至資源]。
在函式應用程式 [概觀] 頁面的左窗格上,選取 [建立函式]。
在 [建立函式] 頁面上,選取 [HTTP 觸發程序] 範本,然後選取 [下一步]。
在 [範本詳細資料] 索引標籤上,選取 [匿名] 作為 [授權層級],然後選取 [建立]。
秘訣
如果你保留授權層級為 Function,那你需要用 function API 金鑰來設定你的 DPS 註冊。 如需詳細資訊,請參閱 Azure Functions HTTP 觸發程序。
當 HttpTrigger1 函式開啟時,請選取左側窗格上的 [程式碼 + 測試]。 這個選擇讓你可以編輯該函式的程式碼。 run.csx 程式碼檔案應會開啟以進行編輯。
參考必要的 NuGet 套件。 若要建立初始裝置對應項,自訂配置函式會使用兩個 NuGet 套件 (必須載入裝載環境) 中定義的類別。 使用 Azure Functions 時,NuGet 套件會使用 function.proj 檔案來加以參考。 在此步驟中,您會儲存並上傳必要組件的 function.proj 檔案。 欲了解更多資訊,請參閱使用 NuGet 套件。
將下列幾行複製到您慣用的編輯器中,並將檔案儲存為您電腦上的 function.proj。
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netstandard2.0</TargetFramework> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.Azure.Devices.Provisioning.Service" Version="1.18.1" /> <PackageReference Include="Microsoft.Azure.Devices.Shared" Version="1.30.1" /> </ItemGroup> </Project>選取程式代碼編輯器上方的 [上傳] 按鈕,以上傳您的 function.proj 檔案。 上傳之後,使用下拉式方塊選取程式碼編輯器中的檔案,以確認內容。
在程式碼編輯器中選取 function.proj 檔案,並確認其內容。 如果 function.proj 檔案是空的,請將之前的行複製到檔案中並儲存。 (有時上傳會建立檔案而不上傳內容。)
請確定已在程式碼編輯器中選取 [HttpTrigger1] 的 [run.csx]。 將 HttpTrigger1 函式的程式碼取代為下列程式碼,然後選取 [儲存]:
#r "Newtonsoft.Json" using System.Net; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Primitives; using Newtonsoft.Json; using Microsoft.Azure.Devices.Shared; // For TwinCollection using Microsoft.Azure.Devices.Provisioning.Service; // For TwinState public static async Task<IActionResult> Run(HttpRequest req, ILogger log) { log.LogInformation("C# HTTP trigger function processed a request."); // Get request body string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); dynamic data = JsonConvert.DeserializeObject(requestBody); log.LogInformation("Request.Body:..."); log.LogInformation(requestBody); // Get registration ID of the device string regId = data?.deviceRuntimeContext?.registrationId; string message = "Uncaught error"; bool fail = false; ResponseObj obj = new ResponseObj(); 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) { message = "No hub group defined for the enrollment."; log.LogInformation("linkedHubs : NULL"); fail = true; } else { // This is a Contoso Toaster Model 007 if (regId.Contains("-contoso-tstrsd-007")) { //Find the "-toasters-" IoT hub configured on the enrollment foreach(string hubString in hubs) { if (hubString.Contains("-toasters-")) obj.iotHubHostName = hubString; } if (obj.iotHubHostName == null) { message = "No toasters hub found for the enrollment."; log.LogInformation(message); fail = true; } else { // Specify the initial tags for the device. TwinCollection tags = new TwinCollection(); tags["deviceType"] = "toaster"; // Specify the initial desired properties for the device. TwinCollection properties = new TwinCollection(); properties["state"] = "ready"; properties["darknessSetting"] = "medium"; // Add the initial twin state to the response. TwinState twinState = new TwinState(tags, properties); obj.initialTwin = twinState; } } // This is a Contoso Heat pump Model 008 else if (regId.Contains("-contoso-hpsd-088")) { //Find the "-heatpumps-" IoT hub configured on the enrollment foreach(string hubString in hubs) { if (hubString.Contains("-heatpumps-")) obj.iotHubHostName = hubString; } if (obj.iotHubHostName == null) { message = "No heat pumps hub found for the enrollment."; log.LogInformation(message); fail = true; } else { // Specify the initial tags for the device. TwinCollection tags = new TwinCollection(); tags["deviceType"] = "heatpump"; // Specify the initial desired properties for the device. TwinCollection properties = new TwinCollection(); properties["state"] = "on"; properties["temperatureSetting"] = "65"; // Add the initial twin state to the response. TwinState twinState = new TwinState(tags, properties); obj.initialTwin = twinState; } } // Unrecognized device. else { fail = true; message = "Unrecognized device registration."; log.LogInformation("Unknown device registration"); } } } log.LogInformation("\nResponse"); log.LogInformation((obj.iotHubHostName != null) ? JsonConvert.SerializeObject(obj) : message); return (fail) ? new BadRequestObjectResult(message) : (ActionResult)new OkObjectResult(obj); } public class ResponseObj { public string iotHubHostName {get; set;} public TwinState initialTwin {get; set;} }
建立註冊
在本節中,您將建立一個使用自訂配置原則的新註冊群組。 為簡單起見,本教學課程會使用 對稱金鑰證明 與註冊。 如需更安全的解決方案,請考慮使用 X.509 憑證證明與信任鏈結。
登入 Azure 入口網站,並瀏覽至您的裝置佈建服務執行個體。
從導覽功能表的 [設定] 區段中選取 [管理註冊]。
選取 [新增註冊群組]。
在 [新增註冊群組] 頁面的 [註冊 + 佈建] 索引標籤上,提供下列資訊以設定註冊群組詳細資料:
欄位 描述 證明 選取 [對稱金鑰] 作為 [證明機制]。 對稱金鑰設定 核取 [自動產生對稱金鑰] 方塊。 群組名稱 輸入 contoso-custom-allocated-devices 作為群組名稱。 佈建狀態 核取 [啟用此註冊] 方塊。 選取 [下一步:IoT 中樞]。
在 [新增註冊群組] 頁面的 [IoT 中樞] 索引標籤上,提供下列資訊以判斷註冊群組可將裝置佈建到哪些 IoT 中樞:
欄位 描述 目標 IoT 中樞 選取一或多個連結的 IoT 中樞,或是新增 IoT 中樞的連結。 配置原則 選取 [自訂 (使用 Azure 函式)]。 選取 [選取 Azure 函式],然後依照提示選取您為此教學課程建立的函式。 選取 [檢閱 + 建立]。
在 [檢閱 + 建立] 索引標籤上,驗證您的所有值,然後選取 [建立]。
儲存註冊之後,請重新開啟它,並記下 [主要金鑰]。 您必須先儲存註冊,才能產生金鑰。 此金鑰會用於為下一節中的模擬裝置產生唯一的裝置金鑰。
秘訣
當您在 Azure 入口網站中建立註冊群組並選取自訂配置原則時,Azure 入口網站會自動代表您擷取和內嵌函式金鑰。 如果您以程式設計方式建立註冊,則需要在建立步驟中提供該金鑰。
衍生唯一的裝置金鑰
裝置不會直接使用註冊群組的主要對稱金鑰。 相反地,您會使用主要金鑰來為每個裝置衍生裝置金鑰。 在本節中,您要建立兩個裝置金鑰。 一個金鑰會用於模擬的烤箱裝置。 另一個金鑰會用於模擬的熱泵裝置。
要推導裝置金鑰,您可以使用您先前提到的註冊群組 主金鑰 ,計算每個裝置註冊 ID 的 HMAC-SHA256 雜湊值,並將結果轉換為 Base 64 格式。 欲了解更多關於建立帶有註冊群組的衍生裝置金鑰的資訊,請參閱對稱金鑰證明中「使用對稱金鑰的群組註冊」章節。
針對本教學課程的範例,請使用下列兩個裝置註冊識別碼,並計算這兩個裝置的裝置金鑰。 這兩種註冊識別碼都具有有效的尾碼,可用於自訂配置原則的範例程式碼:
- breakroom499-contoso-tstrsd-007
- mainbuilding167-contoso-hpsd-088
Azure CLI 的 IoT 延伸模組可提供 iot dps enrollment-group compute-device-key 命令來產生衍生的裝置金鑰。 此命令可再 Window 或 Linux 系統、PowerShell 或 Bash 殼層上使用。
將 --key 引數的值取代為註冊群組的主要金鑰。
az iot dps enrollment-group compute-device-key --key <ENROLLMENT_GROUP_KEY> --registration-id breakroom499-contoso-tstrsd-007
az iot dps enrollment-group compute-device-key --key <ENROLLMENT_GROUP_KEY> --registration-id mainbuilding167-contoso-hpsd-088
附註
您也可以提供註冊群組識別碼,而不是 iot dps enrollment-group compute-device-key 命令的對稱密鑰。 例如:
az iot dps enrollment-group compute-device-key -g contoso-us-resource-group --dps-name contoso-provisioning-service-1098 --enrollment-id contoso-custom-allocated-devices --registration-id breakroom499-contoso-tstrsd-007
模擬的裝置會使用每個註冊識別碼的衍生裝置金鑰來執行對稱金鑰證明。
準備 Azure IoT C SDK 開發環境
在本節中,您要準備用來建置 Azure IoT C SDK 的開發環境。 SDK 包含模擬裝置的範例程式碼。 此模擬裝置在開機過程中嘗試配置。
此節以 Windows 工作站為基礎來說明。 關於 Linux 範例,請參閱教學中「 建立區域 Linux 虛擬機 」部分 :為地理延遲配置。
下載 CMake 建置系統。
在開始安裝
CMake之前,請務必將 Visual Studio 必要條件 (Visual Studio 和「使用 C++ 的桌面開發」工作負載) 安裝在您的機器上。 在符合先決條件,並且驗證過下載項目之後,請安裝 CMake 建置系統。尋找最新版本 SDK 的標籤名稱。
開啟命令提示字元或 Git Bash 殼層。 執行下列命令以複製最新版的 Azure IoT 裝置 SDK for C (英文) GitHub 存放庫。 使用您在上一個步驟中找到的標籤作為
-b參數的值,例如:lts_03_2025。git clone -b <release-tag> https://github.com/Azure/azure-iot-sdk-c.git cd azure-iot-sdk-c git submodule update --init預期此作業需要幾分鐘的時間才能完成。
在 git 存放庫的根目錄中建立
cmake子目錄,並瀏覽至該資料夾。 從azure-iot-sdk-c目錄執行下列命令:mkdir cmake cd cmake請執行下列命令,以建置您開發用戶端平台特有的 SDK 版本。
cmake目錄中會產生模擬裝置的 Visual Studio 解決方案。cmake -Dhsm_type_symm_key:BOOL=ON -Duse_prov_client:BOOL=ON ..如果
cmake找不到 C++ 編譯器,您在執行命令時,可能會看到建置錯誤。 如果發生這種情況,請嘗試在 Visual Studio 命令提示字元中執行命令。建置成功後,最後幾行輸出會類似於下列輸出:
$ cmake -Dhsm_type_symm_key:BOOL=ON -Duse_prov_client:BOOL=ON .. -- Building for: Visual Studio 15 2017 -- Selecting Windows SDK version 10.0.16299.0 to target Windows 10.0.17134. -- The C compiler identification is MSVC 19.12.25835.0 -- The CXX compiler identification is MSVC 19.12.25835.0 ... -- Configuring done -- Generating done -- Build files have been written to: E:/IoT Testing/azure-iot-sdk-c/cmake
模擬裝置
在本節中,您將在先前設定的 Azure IoT C SDK 中更新名為 prov_dev_client_sample 的佈建範例。
此範例程式碼會模擬將佈建要求傳送至裝置佈建服務執行個體的裝置開機順序。 此開機順序會使烤箱裝置接受辨識,並使用自訂配置原則指派給 IoT 中樞。
在 Azure 入口網站中,選取您裝置佈建服務的 [概觀] 索引標籤,並記下 [識別碼範圍] 值。
在 Visual Studio 中,開啟先前藉由執行 CMake 而產生的 azure_iot_sdks.sln 解決方案檔案。 該方案檔案應位於下列位置:
azure-iot-sdk-c\cmake\azure_iot_sdks.sln。在 Visual Studio 的 [方案總管] 視窗中,瀏覽至 Provision_Samples 資料夾。 展開名為 prov_dev_client_sample 的範例專案。 展開 [來源檔案],然後開啟 prov_dev_client_sample.c。
找出
id_scope常數,並將其值取代為您先前複製的 [識別碼範圍] 值。static const char* id_scope = "0ne00002193";在相同的檔案中找出
main()函式的定義。 確定hsm_type變數已設定為SECURE_DEVICE_TYPE_SYMMETRIC_KEY,如下列範例所示:SECURE_DEVICE_TYPE hsm_type; //hsm_type = SECURE_DEVICE_TYPE_TPM; //hsm_type = SECURE_DEVICE_TYPE_X509; hsm_type = SECURE_DEVICE_TYPE_SYMMETRIC_KEY;在
main()函式中,尋找Prov_Device_Register_Device()的呼叫。 在呼叫之前,請新增下列幾行程式碼,以使用Prov_Device_Set_Provisioning_Payload()在佈建期間傳遞自訂 JSON 承載。 這些自訂有效載荷可用來向你的自定義分配函數提供更多資訊。 此有效載荷也可用來傳遞裝置類型,而不是檢查註冊 ID。 欲了解更多關於使用 DPS 傳送與接收自訂資料有效載荷的資訊,請參閱 在自訂分配中使用裝置有效載荷。// An example custom payload const char* custom_json_payload = "{\"MyDeviceFirmwareVersion\":\"12.0.2.5\",\"MyDeviceProvisioningVersion\":\"1.0.0.0\"}"; prov_device_result = Prov_Device_Set_Provisioning_Payload(prov_device_handle, custom_json_payload); if (prov_device_result != PROV_DEVICE_RESULT_OK) { (void)printf("\r\nFailure setting provisioning payload: %s\r\n", MU_ENUM_TO_STRING(PROV_DEVICE_RESULT, prov_device_result)); }以滑鼠右鍵按一下 prov_dev_client_sample 專案,然後選取 [設為起始專案]。
模擬 Contoso 烤箱裝置
若要模擬 toaster 裝置,請在 prov_dev_client_sample.c 中尋找已註解化的
prov_dev_set_symmetric_key_info()呼叫。// Set the symmetric key if using they auth type //prov_dev_set_symmetric_key_info("<symm_registration_id>", "<symmetric_Key>");取消註解函式呼叫,並將預留位置值 (包括角括號) 取代為您先前產生的 toaster 註冊識別碼和衍生裝置金鑰。 以下程式碼中顯示的鍵值 JC8F96eayuQwwz+PkE7IzjH2lIAjCUnAa61tDigBnSs= 僅作為範例。
// Set the symmetric key if using they auth type prov_dev_set_symmetric_key_info("breakroom499-contoso-tstrsd-007", "JC8F96eayuQwwz+PkE7IzjH2lIAjCUnAa61tDigBnSs=");儲存檔案。
在 Visual Studio 功能表中,選取 [偵錯]>[啟動但不偵錯] 以執行解決方案。 出現重新建置專案的提示時,選取 [是],以在執行前重新建置專案。
以下顯示輸出範例,說明模擬的烤箱裝置在成功開機後連線至佈建服務執行個體,並依自訂配置原則指派給烤箱 IoT 中樞的情形:
Provisioning API Version: 1.8.0 Registering Device Provisioning Status: PROV_DEVICE_REG_STATUS_CONNECTED Provisioning Status: PROV_DEVICE_REG_STATUS_ASSIGNING Provisioning Status: PROV_DEVICE_REG_STATUS_ASSIGNING Registration Information received from service: contoso-toasters-hub-1098.azure-devices.net, deviceId: breakroom499-contoso-tstrsd-007 Press enter key to exit:下列輸出是對 toaster 裝置執行自訂配置函式程式碼後產生的範例記錄輸出。 請注意,已成功選取 toaster 裝置的中樞。 另請注意
payload屬性,其中包含您新增至程式碼的自訂 JSON 內容。 這些內容可供你的程式碼在deviceRuntimeContext中使用。按一下入口網站中函式程式碼底下的 [記錄],即可取得此記錄:
2022-08-03T20:34:41.178 [Information] Executing 'Functions.HttpTrigger1' (Reason='This function was programmatically called via the host APIs.', Id=12950752-6d75-4f41-844b-c253a6653d4f) 2022-08-03T20:34:41.340 [Information] C# HTTP trigger function processed a request. 2022-08-03T20:34:41.341 [Information] Request.Body:... 2022-08-03T20:34:41.341 [Information] {"enrollmentGroup":{"enrollmentGroupId":"contoso-custom-allocated-devices","attestation":{"type":"symmetricKey"},"capabilities":{"iotEdge":false},"etag":"\"0000f176-0000-0700-0000-62eaad1e0000\"","provisioningStatus":"enabled","reprovisionPolicy":{"updateHubAssignment":true,"migrateDeviceData":true},"createdDateTimeUtc":"2022-08-03T17:15:10.8464255Z","lastUpdatedDateTimeUtc":"2022-08-03T17:15:10.8464255Z","allocationPolicy":"custom","iotHubs":["contoso-toasters-hub-1098.azure-devices.net","contoso-heatpumps-hub-1098.azure-devices.net"],"customAllocationDefinition":{"webhookUrl":"https://contoso-function-app-1098.azurewebsites.net/api/HttpTrigger1?****","apiVersion":"2021-10-01"}},"deviceRuntimeContext":{"registrationId":"breakroom499-contoso-tstrsd-007","currentIotHubHostName":"contoso-toasters-hub-1098.azure-devices.net","currentDeviceId":"breakroom499-contoso-tstrsd-007","symmetricKey":{},"payload":{"MyDeviceFirmwareVersion":"12.0.2.5","MyDeviceProvisioningVersion":"1.0.0.0"}},"linkedHubs":["contoso-toasters-hub-1098.azure-devices.net","contoso-heatpumps-hub-1098.azure-devices.net"]} 2022-08-03T20:34:41.382 [Information] Response 2022-08-03T20:34:41.398 [Information] {"iotHubHostName":"contoso-toasters-hub-1098.azure-devices.net","initialTwin":{"properties":{"desired":{"state":"ready","darknessSetting":"medium"}},"tags":{"deviceType":"toaster"}}} 2022-08-03T20:34:41.399 [Information] Executed 'Functions.HttpTrigger1' (Succeeded, Id=12950752-6d75-4f41-844b-c253a6653d4f, Duration=227ms)
模擬 Contoso 熱泵裝置
若要模擬熱泵裝置,請使用您稍早產生的熱泵註冊識別碼和衍生裝置金鑰再次更新prov_dev_client_sample.c 中的
prov_dev_set_symmetric_key_info()呼叫。 以下程式碼中顯示的鍵值 6uejA9PfkQgmYylj8Zerp3kcbeVrGZ172YLa7VSnJzg= 也僅作為範例。// Set the symmetric key if using they auth type prov_dev_set_symmetric_key_info("mainbuilding167-contoso-hpsd-088", "6uejA9PfkQgmYylj8Zerp3kcbeVrGZ172YLa7VSnJzg=");儲存檔案。
在 Visual Studio 功能表中,選取 [偵錯]>[啟動但不偵錯] 以執行解決方案。 出現重新建置專案的提示時,選取 [是],以在執行前重新建置專案。
以下顯示輸出範例,說明模擬的熱泵裝置在成功開機後連線至佈建服務執行個體,並依自訂配置原則指派給 Contoso 熱泵 IoT 中樞的情形:
Provisioning API Version: 1.8.0 Registering Device Provisioning Status: PROV_DEVICE_REG_STATUS_CONNECTED Provisioning Status: PROV_DEVICE_REG_STATUS_ASSIGNING Provisioning Status: PROV_DEVICE_REG_STATUS_ASSIGNING Registration Information received from service: contoso-heatpumps-hub-1098.azure-devices.net, deviceId: mainbuilding167-contoso-hpsd-088 Press enter key to exit:
針對自訂配置原則進行疑難排解
下表顯示預期的案例和您可能會收到的結果錯誤碼。 您可以利用此表格對 Azure Functions 的自訂配置原則失敗進行疑難排解。
| 狀況 | 佈建服務的註冊結果 | 佈建 SDK 結果 |
|---|---|---|
| webhook 回傳 200 OK,將 'iotHubHostName' 設為有效的物聯網 hub 主機名稱 | 結果狀態:已指派 | SDK 傳回 PROV_DEVICE_RESULT_OK 與中樞資訊 |
| webhook 回傳 200 OK,『iotHubHostName』出現在回應中,但其值是空字串或為 null。 | 結果狀態:失敗 錯誤碼:CustomAllocationIotHubNotSpecified (400208) |
SDK 傳回 PROV_DEVICE_RESULT_HUB_NOT_SPECIFIED |
| Webhook 傳回「401 未授權」 | 結果狀態:失敗 錯誤碼:CustomAllocationUnauthorizedAccess (400209) |
SDK 傳回 PROV_DEVICE_RESULT_UNAUTHORIZED |
| 建立了個別註冊以停用裝置 | 結果狀態:已停用 | SDK 傳回 PROV_DEVICE_RESULT_DISABLED |
| Webhook 傳回錯誤碼 >= 429 | DPS 的協調流程會重試多次。 目前的重試原則為: - 重試計數:10 - 初始間隔:1 秒 - 遞增:9 秒 |
SDK 忽略錯誤,並在指定時間內再次提交 get status 訊息 |
| Webhook 傳回任何其他狀態碼 | 結果狀態:失敗 錯誤碼:CustomAllocationFailed (400207) |
SDK 傳回 PROV_DEVICE_RESULT_DEV_AUTH_ERROR |
清除資源
如果您打算繼續使用在此教學課程中建立的資源,可以將其保留。 如果不打算繼續使用這些資源,請使用下列步驟刪除此教學課程中建立的所有資源,以避免產生非必要費用。
以下步驟假設您依照指示在名為 contoso-us-resource-group 的相同資源群組中建立了此教學課程中的所有資源。
重要事項
刪除資源群組是無法回復的動作。 資源群組和其中包含的所有資源都將永久刪除。 請確定您不會誤刪錯誤的資源群組或資源。 如果您在包含您想要保留之資源的現有資源群組內建立IoT中樞,則只會刪除IoT中樞資源本身,而不是刪除資源群組。
依名稱刪除資源群組:
登入 Azure 入口網站,然後選取 [資源群組]。
在 [依名稱篩選] 文字方塊中,輸入您的資源所屬的資源群組名稱 contoso-us-resource-group。
在結果清單中的資源群組右側,選取 [...],然後按一下 [刪除資源群組]。
系統將會要求您確認是否刪除資源群組。 再次輸入您的資源群組名稱以進行確認,然後選取 [刪除]。 片刻過後,系統便會刪除該資源群組及其所有內含的資源。
後續步驟
若要深入了解自訂配置原則,請參閱