分享方式:


教學課程:使用自訂配置原則搭配裝置佈建服務 (DPS)

自訂配置原則可讓您進一步掌控將裝置指派給 IoT 中樞的方式。 透過自訂配置原則,您可在 Azure IoT 中樞裝置佈建服務 (DPS) 所提供的原則不符合案例的需求時,定義您自己的配置原則。 自定義配置原則會在裝載於 Azure FunctionsWebhook 中實作,並在一或多個個別註冊和/或註冊群組上設定。 當裝置使用設定的註冊項目向 DPS 註冊時,DPS 會呼叫 Webhook,以找出裝置應該註冊到哪一個 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 訂閱,請在開始之前,先建立 Azure 免費帳戶

必要條件

下列必要條件適用於 Windows 開發環境。 針對 Linux 或 macOS,請參閱 SDK 文件中準備您的開發環境中的適當章節。

建立布建服務和兩個IoT中樞

在本節中,您會使用 Azure Cloud Shell 建立佈建服務和兩個 IoT 中樞,分別代表 Contoso 烤箱部門Contoso 熱泵部門

  1. 首先,在您的工作區中設定環境變數,以簡化本教學課程中的命令。

    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 狀態 ] 頁面並搜尋 「裝置布建服務」,以檢視可用位置的清單。 在命令中,可指定一個字或多字格式的位置;例如:uswest、West US、WEST US 等等。此值不區分大小寫。

  2. 使用 az group create 命令來建立 Azure 資源群組。 Azure 資源群組是在其中部署與管理 Azure 資源的邏輯容器。

    下列範例會建立資源群組。 建議您針對本教學課程中建立的所有資源使用單一群組。 透過此方法,您在完成作業後將可更容易清除資源。

    az group create --name $RESOURCE_GROUP --location $LOCATION
    
  3. 使用 az iot dps create 命令來建立裝置布建服務 (DPS) 的實例。 布建服務會新增至 contoso-us-resource-group

    az iot dps create --name $DPS --resource-group $RESOURCE_GROUP --location $LOCATION
    

    此命令可能需要幾分鐘的時間才能完成。

  4. 使用 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
    

    此命令可能需要幾分鐘的時間才能完成。

  5. 使用 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
    

    此命令可能需要幾分鐘的時間才能完成。

  6. 執行下列兩個命令,以取得您所建立中樞的連接字串。

    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
    
  7. 執行下列命令,將中樞連結至 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 中樞。 也會根據裝置是烤箱或熱泵,設定裝置對應項的初始狀態。

  1. 登入 Azure 入口網站

  2. 在搜尋方塊中,搜尋並選取 [函式應用程式]。

  3. 選取 [建立] 或 [建立函數應用程式]。

  4. 在 [函數應用程式] 建立頁面的 [基本] 索引標籤底下,為您的新函數應用程式輸入下列設定,然後選取 [檢閱 + 建立]

    參數
    訂用帳戶 請確定您已選取您為此教學課程建立資源的訂用帳戶。
    資源群組 選取您在上一節中建立的資源群組。 上一節中提供的預設值是 contoso-us-resource-group
    函數應用程式名稱 提供函式應用程式的名稱。
    您要部署程式碼或容器映像嗎? 代碼
    執行階段堆疊 .NET
    版本 選取任何 進程內模型 版本。
    區域 選取接近您的區域。

    注意

    預設會啟用 Application Insights。 本教學課程並不需要 Application Insights,但其可能會協助您了解並調查您使用自訂配置時遇到的任何問題。 如果您想要的話,可以選取 [監視] 索引標籤,然後針對 [啟用 Application Insights] 選取 [否] 來停用 Application Insights。

    顯示 Azure 入口網站 中 [建立函式應用程式] 表單的螢幕快照。

  5. 在 [ 檢閱 + 建立] 索引標籤上,選取 [建立 ] 以建立函式應用程式。

  6. 部署可能需要幾分鐘的時間。 完成時,選取 [移至資源]

  7. 在函式應用程式 [概觀 ] 頁面的左窗格中,選取 [ 建立函式]。

    顯示選取選項以在 Azure 入口網站 中建立函式的螢幕快照。

  8. 在 [ 建立函式 ] 頁面上,選取 [HTTP 觸發程式 ] 範本,然後選取 [ 下一步]。

  9. 在 [範本詳細數據] 索引標籤上,選取 [匿名] 作為 [授權層級],然後選取 [建立]。

    顯示將授權層級設定為匿名的螢幕快照。

    提示

    如果您將授權層級保留為 式,則必須使用函式 API 金鑰來設定 DPS 註冊。 如需詳細資訊,請參閱 Azure Functions HTTP 觸發程式

  10. HttpTrigger1 函式開啟時,請選取左側窗格上的 [程式碼 + 測試]。 這可讓您編輯函式的程式碼。 run.csx 程式碼檔案應會開啟以進行編輯。

  11. 參考必要的 NuGet 套件。 若要建立初始裝置對應項,自訂配置函式會使用兩個 NuGet 套件 (必須載入裝載環境) 中定義的類別。 使用 Azure Functions 時,NuGet 套件會使用 function.proj 檔案來加以參考。 在此步驟中,您會儲存並上傳必要組件的 function.proj 檔案。 如需詳細資訊,請參閱搭配 Azure Functions 使用 NuGet 套件

    1. 將下列幾行複製到您慣用的編輯器中,並將檔案儲存為您電腦上的 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>
      
    2. 選取程式代碼編輯器上方的 [上傳] 按鈕,以上傳您的 function.proj 檔案。 上傳之後,使用下拉式方塊選取程式碼編輯器中的檔案,以確認內容。

    3. 在程式碼編輯器中選取 function.proj 檔案,並確認其內容。 如果 function.proj 檔案是空的,請將上述程式碼行複製到檔案中並儲存。 (有時上傳會建立檔案而不上傳內容。

  12. 請確定已在程式碼編輯器中選取 [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 憑證證明與信任鏈結。

  1. 登入 Azure 入口網站,並瀏覽至您的裝置佈建服務執行個體。

  2. 從導覽功能表的 [設定] 區段選取 [管理註冊]

  3. 選取 [新增註冊群組]

  4. 在 [新增註冊群組] 頁面的 [註冊 + 佈建] 索引標籤上,提供下列資訊以設定註冊群組詳細資料:

    欄位 描述
    證明 選取 [對稱金鑰] 作為 [證明機制]
    對稱金鑰設定 核取 [自動產生對稱金鑰] 方塊。
    群組名稱 輸入 contoso-custom-allocated-devices 作為群組名稱。
    佈建狀態 核取 [啟用此註冊] 方塊。
  5. 選取 [下一步:IoT 中樞]

  6. 在 [新增註冊群組] 頁面的 [IoT 中樞] 索引標籤上,提供下列資訊以判斷註冊群組可將裝置佈建到哪些 IoT 中樞:

    欄位 描述
    目標 IoT 中樞 選取一或多個連結的 IoT 中樞,或是新增 IoT 中樞的連結。
    配置原則 選取 [自訂 (使用 Azure 函式)]。 選取 [選取 Azure 函式],然後依照提示選取您為此教學課程建立的函式。
  7. 選取 [檢閱 + 建立]。

  8. 在 [檢閱 + 建立] 索引標籤上,確認所有值,然後選取 [建立]

儲存註冊之後,請重新開啟它,並記下 [主要金鑰]。 您必須先儲存註冊,才能產生金鑰。 此金鑰用於在下一節中產生模擬裝置的唯一裝置金鑰。

衍生唯一的裝置金鑰

裝置不會直接使用註冊群組的主要對稱金鑰。 相反地,您會使用主要金鑰來為每個裝置衍生裝置金鑰。 在本節中,您要建立兩個裝置金鑰。 仿真的烤箱裝置使用一個密鑰。 另一個金鑰用於模擬熱泵裝置。

若要衍生裝置密鑰,您可以使用您稍早注意到的註冊群組 主要密鑰 ,計算 每個裝置的裝置註冊標識碼 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 範例,請參閱教學課程:針對地理延遲來佈建 (英文) 中的 VM 設定。

  1. 下載 CMake 建置系統

    在開始安裝 CMake之前,請務必將 Visual Studio 必要條件 (Visual Studio 和「使用 C++ 的桌面開發」工作負載) 安裝在您的機器上。 在符合先決條件,並且驗證過下載項目之後,請安裝 CMake 建置系統。

  2. 尋找最新版本 SDK 的標籤名稱。

  3. 開啟命令提示字元或 Git Bash 殼層。 執行下列命令以複製最新版的 Azure IoT 裝置 SDK for C (英文) GitHub 存放庫。 使用您在上一個步驟中找到的標籤作為 -b 參數的值,例如:lts_01_2023

    git clone -b <release-tag> https://github.com/Azure/azure-iot-sdk-c.git
    cd azure-iot-sdk-c
    git submodule update --init
    

    預期此作業需要幾分鐘的時間才能完成。

  4. 在 git 存放庫的根目錄中建立 cmake 子目錄,並瀏覽至該資料夾。 從 azure-iot-sdk-c 目錄執行下列命令:

    mkdir cmake
    cd cmake
    
  5. 請執行下列命令,以建置您開發用戶端平台特有的 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中樞的烤箱裝置。

  1. 在 Azure 入口網站中,為您的裝置佈建服務選取 [概觀] 索引標籤,並記下 [識別碼範圍] 值。

    從入口網站刀鋒視窗擷取裝置布建服務端點資訊

  2. 在 Visual Studio 中,開啟先前藉由執行 CMake 而產生的 azure_iot_sdks.sln 解決方案檔案。 方案檔應位於下列位置: azure-iot-sdk-c\cmake\azure_iot_sdks.sln

  3. 在 Visual Studio 的 [方案總管] 視窗中,瀏覽至 Provision_Samples 資料夾。 展開名為 prov_dev_client_sample 的範例專案。 展開 [來源檔案],然後開啟 prov_dev_client_sample.c

  4. 找出 id_scope 常數,並將其值取代為您先前複製的 [識別碼範圍] 值。

    static const char* id_scope = "0ne00002193";
    
  5. 在相同的檔案中找出 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;
    
  6. main() 函式中,尋找 Prov_Device_Register_Device() 的呼叫。 在呼叫之前,請新增下列幾行程式碼,以使用 Prov_Device_Set_Provisioning_Payload() 在佈建期間傳遞自訂 JSON 承載。 這可用來提供自訂配置函式的詳細資訊。 這也可以用來傳遞裝置類型,而不是檢查註冊識別碼。 如需使用 DPS 傳送和接收自訂資料承載的詳細資訊,請參閱如何在裝置與 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));
    }
    
  7. 以滑鼠右鍵按一下 [prov_dev_client_sample] 專案,然後選取 [設為起始專案]

模擬 Contoso 烤箱裝置

  1. 若要模擬 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=");
    

    儲存檔案。

  2. 在 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 熱泵裝置

  1. 若要模擬熱泵裝置,請使用您稍早產生的熱泵註冊識別碼和衍生裝置金鑰再次更新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=");
    

    儲存檔案。

  2. 在 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 確定」,且 'iotHubHostName' 設定為有效的 IoT 中樞主機名稱 結果狀態:已指派 SDK 傳回 PROV_DEVICE_RESULT_OK 與中樞資訊
Webhook 傳回「200 確定」,且回應中包含 '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 將會忽略錯誤,並在指定的時間內提交另一個取得狀態訊息
Webhook 傳回任何其他狀態碼 結果狀態:失敗

錯誤碼:CustomAllocationFailed (400207)
SDK 傳回 PROV_DEVICE_RESULT_DEV_AUTH_ERROR

清除資源

如果您打算繼續使用在此教學課程中建立的資源,可以將其保留。 如果不打算繼續使用這些資源,請使用下列步驟刪除此教學課程中建立的所有資源,以避免產生非必要費用。

以下步驟假設您依照指示在名為 contoso-us-resource-group 的相同資源群組中建立了此教學課程中的所有資源。

重要

刪除資源群組是無法回復的動作。 資源群組和其中包含的所有資源都將永久刪除。 請確定您不會誤刪錯誤的資源群組或資源。 如果您在現有的資源群組內建立了 IoT 中樞,而該群組中包含您想要保留的資源,則您只需刪除 IoT 中樞本身即可,而不要刪除資源群組。

依名稱刪除資源群組:

  1. 登入 Azure 入口網站,然後選取 [資源群組]

  2. 在 [依名稱篩選] 文字方塊中,輸入您的資源所屬的資源群組名稱 contoso-us-resource-group

  3. 在結果清單中的資源群組右側,選取 [...],然後按一下 [刪除資源群組]

  4. 系統將會要求您確認是否刪除資源。 再次輸入您的資源群組名稱以進行確認,然後選取 [刪除]。 片刻過後,系統便會刪除該資源群組及其所有內含的資源。

下一步

若要深入了解自訂配置原則,請參閱