Tutorial: Usar políticas de alocação personalizadas com o Serviço de Provisionamento de Dispositivo (DPS)

As políticas de alocação personalizadas oferecem mais controle sobre como os dispositivos são atribuídos aos seus hubs IoT. Com políticas de alocação personalizadas, você pode definir suas próprias políticas de alocação quando as políticas fornecidas pelo DPS (Serviço de Provisionamento de Dispositivo) do Hub IoT do Azure não atenderem aos requisitos do seu cenário. Uma política de alocação personalizada é implementada em um webhook hospedado no Azure Functions e configurada em um ou mais registros individuais e/ou grupos de registro. Quando um dispositivo se registra no DPS usando uma entrada de registro configurada, o DPS chama o webhook para descobrir em qual hub IoT o dispositivo deve ser registrado e, opcionalmente, seu estado inicial. Para saber mais, consulte Compreender as políticas de alocação personalizadas.

Este tutorial demonstra uma política de alocação personalizada usando uma Função do Azure escrita em C#. Os dispositivos são atribuídos a um dos dois hubs IoT que representam uma Divisão de Torradeiras da Contoso e uma Divisão de Bombas de Calor da Contoso. Os dispositivos que solicitam provisionamento devem ter uma ID de registro com um dos seguintes sufixos para serem aceitos para provisionamento:

  • -contoso-tstrsd-007 para a Divisão de Torradeiras da Contoso
  • -contoso-hpsd-088 para a Divisão de Bombas de Calor da Contoso

Os dispositivos são simulados usando um exemplo de provisionamento incluído no SDK do Azure IoT C.

Neste tutorial, você fará o seguinte:

  • Use a CLI do Azure para criar uma instância DPS e para criar e vincular dois hubs IoT da divisão Contoso (Divisão Contoso Toasters e Divisão Contoso Heat Pumps) a ela.
  • Crie uma Função do Azure que implemente a política de alocação personalizada.
  • Criar um novo grupo de inscrição usa a Função do Azure para a política de alocação personalizada.
  • Crie chaves simétricas de dispositivo para dois dispositivos simulados.
  • Configure o ambiente de desenvolvimento para o Azure IoT C SDK.
  • Simule os dispositivos e verifique se eles são provisionados de acordo com o código de exemplo na política de alocação personalizada.

Se não tiver uma subscrição do Azure, crie uma conta gratuita do Azure antes de começar.

Pré-requisitos

Os pré-requisitos a seguir são para um ambiente de desenvolvimento do Windows. Para Linux ou macOS, consulte a seção apropriada em Prepare your development environment na documentação do SDK.

Criar o serviço de provisionamento e dois hubs IoT

Nesta seção, você usa o Azure Cloud Shell para criar um serviço de provisionamento e dois hubs IoT que representam a Divisão de Torradeiras da Contoso e a divisão de Bombas de Calor da Contoso.

  1. Primeiro, defina variáveis de ambiente em seu espaço de trabalho para simplificar os comandos neste tutorial.

    Os nomes DPS e Hub IoT devem ser globalmente exclusivos. Substitua o espaço reservado SUFFIX pelo seu próprio valor.

    Além disso, o código da Função do Azure que você cria posteriormente neste tutorial procura hubs IoT que tenham um ou -toasters--heatpumps- em seus nomes. Se você alterar os valores sugeridos, certifique-se de usar nomes que contenham as substrings necessárias.

    #!/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"
    

    Gorjeta

    Os comandos usados neste tutorial criam recursos no local Oeste dos EUA por padrão. Recomendamos que você crie seus recursos na região mais próxima de você que oferece suporte ao Serviço de Provisionamento de Dispositivo. Você pode exibir uma lista de locais disponíveis acessando a página Status do Azure e procurando por "Serviço de Provisionamento de Dispositivo". Nos comandos, os locais podem ser especificados em formato de uma palavra ou de várias palavras; por exemplo: westus, West US, WEST US, etc. O valor não diferencia maiúsculas de minúsculas.

  2. Use o comando az group create para criar um grupo de recursos do Azure. Um grupo de recursos do Azure é um contentor lógico no qual os recursos do Azure são implementados e geridos.

    O exemplo a seguir cria um grupo de recursos. Recomendamos que você use um único grupo para todos os recursos criados neste tutorial. Essa abordagem facilitará a limpeza depois que você terminar.

    az group create --name $RESOURCE_GROUP --location $LOCATION
    
  3. Use o comando az iot dps create para criar uma instância do Device Provisioning Service (DPS). O serviço de provisionamento é adicionado ao contoso-us-resource-group.

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

    Esse comando pode levar alguns minutos para ser concluído.

  4. Use o comando az iot hub create para criar o hub IoT da Divisão de Torradeiras da Contoso. O hub IoT é adicionado ao contoso-us-resource-group.

    az iot hub create --name $TOASTER_HUB --resource-group $RESOURCE_GROUP --location $LOCATION --sku S1
    

    Esse comando pode levar alguns minutos para ser concluído.

  5. Use o comando az iot hub create para criar o hub IoT da Divisão de Bombas de Calor da Contoso. Esse hub IoT também é adicionado ao contoso-us-resource-group.

    az iot hub create --name $HEATPUMP_HUB --resource-group $RESOURCE_GROUP --location $LOCATION --sku S1
    

    Esse comando pode levar alguns minutos para ser concluído.

  6. Execute os dois comandos a seguir para obter as cadeias de conexão para os hubs que você criou.

    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. Execute os comandos a seguir para vincular os hubs ao recurso DPS. Substitua os espaços reservados pelas cadeias de conexão de hub da etapa anterior.

    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>
    

Criar a função de alocação personalizada

Nesta seção, você cria uma função do Azure que implementa sua política de alocação personalizada. Essa função decide em qual hub IoT divisional um dispositivo deve ser registrado com base em se sua ID de registro contém a cadeia de caracteres -contoso-tstrsd-007 ou -contoso-hpsd-088. Ele também define o estado inicial do dispositivo gêmeo com base em se o dispositivo é uma torradeira ou uma bomba de calor.

  1. Inicie sessão no portal do Azure.

  2. Na caixa de pesquisa, procure e selecione Aplicativo de função.

  3. Selecione Criar ou Criar aplicativo de função.

  4. Na página Criar aplicativo de função, na guia Noções básicas, insira as seguintes configurações para seu novo aplicativo de função e selecione Revisar + criar:

    Parâmetro Value
    Subscrição Certifique-se de que a subscrição onde criou os recursos para este tutorial está selecionada.
    Grupo de Recursos Selecione o grupo de recursos que você criou na seção anterior. O padrão fornecido na seção anterior é contoso-us-resource-group.
    Nome da Aplicação de Funções Forneça um nome para seu aplicativo de função.
    Deseja implantar código ou imagem de contêiner? Código
    Pilha de Runtime .NET
    Versão Selecione qualquer versão do modelo em processo.
    Região Selecione uma região perto de si.

    Nota

    Por padrão, o Application Insights está habilitado. O Application Insights não é necessário para este tutorial, mas pode ajudá-lo a entender e investigar quaisquer problemas encontrados com a alocação personalizada. Se preferir, você pode desabilitar o Application Insights selecionando a guia Monitoramento e, em seguida, selecionando Não para Habilitar Application Insights.

    Captura de ecrã que mostra o formulário Criar Aplicação de Função no portal do Azure.

  5. Na guia Revisão + criação, selecione Criar para criar o aplicativo de função.

  6. A implantação pode levar vários minutos. Quando terminar, selecione Ir para recurso.

  7. No painel esquerdo da página Visão geral do aplicativo de função, selecione Criar função.

    Captura de tela que mostra a seleção da opção para criar função no portal do Azure.

  8. Na página Criar função, selecione o modelo Gatilho HTTP e, em seguida, selecione Avançar.

  9. Na guia Detalhes do modelo, selecione Anônimo como o nível de Autorização e, em seguida, selecione Criar.

    Captura de ecrã que mostra a definição do nível de autorização como anónimo.

    Gorjeta

    Se você mantiver o nível de autorização como Função, precisará configurar seus registros DPS com a chave API da função. Para obter mais informações, consulte Gatilho HTTP do Azure Functions.

  10. Quando a função HttpTrigger1 abrir, selecione Código + Teste no painel esquerdo. Isso permite que você edite o código para a função. O arquivo de código run.csx deve ser aberto para edição.

  11. Referência necessária de pacotes NuGet. Para criar o gêmeo de dispositivo inicial, a função de alocação personalizada usa classes definidas em dois pacotes NuGet que devem ser carregados no ambiente de hospedagem. Com o Azure Functions, os pacotes NuGet são referenciados usando um arquivo function.proj . Nesta etapa, você salva e carrega um arquivo function.proj para os assemblies necessários. Para obter mais informações, consulte Usando pacotes NuGet com o Azure Functions.

    1. Copie as seguintes linhas para o seu editor favorito e salve o arquivo no seu computador como 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. Selecione o botão Upload localizado acima do editor de código para carregar seu arquivo function.proj . Após o upload, selecione o arquivo no editor de códigos usando a caixa suspensa para verificar o conteúdo.

    3. Selecione o arquivo function.proj no editor de códigos e verifique seu conteúdo. Se o arquivo function.proj estiver vazio, copie as linhas acima no arquivo e salve-o. (Às vezes, o upload cria o arquivo sem carregar o conteúdo.)

  12. Certifique-se de que run.csx para HttpTrigger1 está selecionado no editor de código. Substitua o código para a função HttpTrigger1 com o seguinte código e selecione Salvar:

    #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;}
    }
    

Criar a inscrição

Nesta seção, você cria um novo grupo de registro que usa a política de alocação personalizada. Para simplificar, este tutorial usa o atestado de chave simétrica com o registro. Para obter uma solução mais segura, considere usar o atestado de certificado X.509 com uma cadeia de confiança.

  1. Entre no portal do Azure e navegue até sua instância do Serviço de Provisionamento de Dispositivo.

  2. Selecione Gerenciar inscrições na seção Configurações do menu de navegação.

  3. Selecione Adicionar grupo de inscrição.

  4. Na guia Registro + provisionamento da página Adicionar grupo de registro, forneça as seguintes informações para configurar os detalhes do grupo de registro:

    Campo Descrição
    Atestado Selecione Chave simétrica como o mecanismo de atestado.
    Configurações de chave simétrica Marque a caixa Gerar chaves simétricas automaticamente .
    Nome do grupo Insira contoso-custom-allocated-devices como o nome do grupo.
    Status de provisionamento Marque a caixa Habilitar este registro .
  5. Selecione Next: Hubs IoT.

  6. Na guia Hubs IoT da página Adicionar grupo de registro, forneça as seguintes informações para determinar para quais hubs IoT o grupo de registro pode provisionar dispositivos:

    Campo Descrição
    Hubs IoT de destino Selecione um ou mais hubs IoT vinculados ou adicione um novo link a um hub IoT.
    Política de afetação Selecione Personalizado (usar a Função do Azure). Selecione Selecionar função do Azure e siga as instruções para selecionar a função que você criou para este tutorial.
  7. Selecione Rever + criar.

  8. No separador Rever + criar, verifique todos os seus valores e, em seguida, selecione Criar.

Depois de salvar o registro, abra-o novamente e anote a chave primária. Você deve salvar o registro primeiro para ter as chaves geradas. Essa chave é usada para gerar chaves de dispositivo exclusivas para dispositivos simulados na próxima seção.

Derivar chaves de dispositivo exclusivas

Os dispositivos não usam diretamente a chave simétrica principal do grupo de inscrição. Em vez disso, você usa a chave primária para derivar uma chave de dispositivo para cada dispositivo. Nesta seção, você cria duas chaves de dispositivo exclusivas. Uma chave é usada para um dispositivo de torradeira simulado. A outra chave é usada para um dispositivo de bomba de calor simulado.

Para derivar a chave do dispositivo, use a chave primária do grupo de registro que você anotou anteriormente para calcular o HMAC-SHA256 do ID de registro do dispositivo para cada dispositivo e converter o resultado no formato Base 64. Para obter mais informações sobre como criar chaves de dispositivo derivadas com grupos de registro, consulte a seção Inscrições de grupo do Atestado de chave simétrica.

Para o exemplo neste tutorial, use as duas IDs de registro de dispositivo a seguir e calcule uma chave de dispositivo para ambos os dispositivos. Ambos os IDs de registro têm um sufixo válido para trabalhar com o código de exemplo para a política de alocação personalizada:

  • breakroom499-contoso-tstrsd-007
  • mainbuilding167-contoso-hpsd-088

A extensão IoT para a CLI do Azure fornece o iot dps enrollment-group compute-device-key comando para gerar chaves de dispositivo derivadas. Este comando pode ser usado em sistemas baseados em Windows ou Linux, a partir do PowerShell ou de um shell Bash.

Substitua o valor do --key argumento pela Chave Primária do seu grupo de inscrição.

az iot dps enrollment-group compute-device-key --key <ENROLLMENT_GROUP_KEY> --registration-id breakroom499-contoso-tstrsd-007
az iot dps compute-device-key --key <ENROLLMENT_GROUP_KEY> --registration-id mainbuilding167-contoso-hpsd-088

Nota

Você também pode fornecer o ID do grupo de registro em vez da chave simétrica para o iot dps enrollment-group compute-device-key comando. Por exemplo:

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

Os dispositivos simulados usam as chaves de dispositivo derivadas com cada ID de registro para executar o atestado de chave simétrica.

Preparar um ambiente de programação para o SDK C do Azure IoT

Nesta seção, você prepara o ambiente de desenvolvimento usado para criar o SDK do Azure IoT C. O SDK inclui o código de exemplo para o dispositivo simulado. Esse dispositivo simulado irá tentar fazer o aprovisionamento durante a respetiva sequência de arranque.

Esta seção é orientada para uma estação de trabalho baseada no Windows. Para obter um exemplo do Linux, consulte a configuração das VMs em Tutorial: Provisão para latência geográfica.

  1. Faça o download do sistema de compilação CMake.

    É importante que os pré-requisitos do Visual Studio (Visual Studio e a carga de trabalho 'Desenvolvimento de área de trabalho com C++') estejam instalados em sua máquina antes de iniciar a CMake instalação. Depois de os pré-requisitos estarem assegurados e a transferência verificada, instale o sistema de compilação CMake.

  2. Encontre o nome da tag para a versão mais recente do SDK.

  3. Abra uma linha de comandos ou a shell do Git Bash. Execute os comandos a seguir para clonar a versão mais recente do SDK do Dispositivo IoT do Azure para o repositório C GitHub. Use a tag que você encontrou na etapa anterior como o valor para o -b parâmetro, por exemplo: 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
    

    Esta operação deve demorar vários minutos a ser concluída.

  4. Crie um subdiretório cmake no diretório de raiz do repositório git e navegue para essa pasta. Execute os seguintes comandos a partir do azure-iot-sdk-c diretório:

    mkdir cmake
    cd cmake
    
  5. Execute o seguinte comando para compilar uma versão do SDK específica da plataforma de cliente de desenvolvimento. Será gerada uma solução do Visual Studio para o dispositivo simulado no diretório cmake.

    cmake -Dhsm_type_symm_key:BOOL=ON -Duse_prov_client:BOOL=ON  ..
    

    Se cmake não encontrar seu compilador C++, você poderá ver erros de compilação ao executar o comando. Se isso acontecer, tente executar o comando no prompt de comando do Visual Studio.

    Quando a compilação for bem-sucedida, as últimas linhas de saída serão semelhantes à seguinte saída:

    $ 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
    

Simule os dispositivos

Nesta seção, você atualiza um exemplo de provisionamento chamado prov_dev_client_sample localizado no SDK do Azure IoT C configurado anteriormente.

Este código de exemplo simula uma sequência de inicialização de dispositivo que envia a solicitação de provisionamento para sua instância do Serviço de Provisionamento de Dispositivo. A sequência de inicialização faz com que o dispositivo torradeiro seja reconhecido e atribuído ao hub IoT usando a política de alocação personalizada.

  1. No portal do Azure, selecione a guia Visão geral do seu Serviço de Provisionamento de Dispositivo e anote o valor do Escopo da ID.

    Extrair informações de ponto final do Serviço Aprovisionamento de Dispositivos do painel do portal

  2. No Visual Studio, abra o arquivo de solução azure_iot_sdks.sln que foi gerado executando o CMake anteriormente. O arquivo de solução deve estar no seguinte local: azure-iot-sdk-c\cmake\azure_iot_sdks.sln.

  3. Na janela Gerenciador de Soluções do Visual Studio, navegue até a pasta Provision_Samples. Expanda o projeto de exemplo chamado prov_dev_client_sample. Expanda Arquivos de origem e abra prov_dev_client_sample.c.

  4. Localize a constante id_scope e substitua o valor pelo seu Âmbito do ID que copiou anteriormente.

    static const char* id_scope = "0ne00002193";
    
  5. Localize a definição da função main() no mesmo ficheiro. Certifique-se de que a variável hsm_type está definida como SECURE_DEVICE_TYPE_SYMMETRIC_KEY, conforme mostrado abaixo:

    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. Na função, encontre a main() chamada para Prov_Device_Register_Device(). Pouco antes dessa chamada, adicione as seguintes linhas de código que usam Prov_Device_Set_Provisioning_Payload() para passar uma carga JSON personalizada durante o provisionamento. Isso pode ser usado para fornecer mais informações para suas funções de alocação personalizadas. Isso também pode ser usado para passar o tipo de dispositivo em vez de examinar o ID de registro. Para obter mais informações sobre como enviar e receber cargas úteis de dados personalizadas com DPS, consulte Como transferir cargas úteis entre dispositivos e 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. Clique com o botão direito do mouse no projeto prov_dev_client_sample e selecione Definir como projeto de inicialização.

Simular o dispositivo de torradeira da Contoso

  1. Para simular o dispositivo de torradeira, encontre a chamada para prov_dev_set_symmetric_key_info() em prov_dev_client_sample.c que é comentado.

    // Set the symmetric key if using they auth type
    //prov_dev_set_symmetric_key_info("<symm_registration_id>", "<symmetric_Key>");
    

    Descomente a chamada de função e substitua os valores de espaço reservado (incluindo os colchetes angulares) pelo ID de registro da torradeira e pela chave de dispositivo derivada gerada anteriormente. O valor-chave JC8F96eayuQwwz+PkE7IzjH2lIAjCUnAa61tDigBnSs= mostrado abaixo é dado apenas como exemplo.

    // Set the symmetric key if using they auth type
    prov_dev_set_symmetric_key_info("breakroom499-contoso-tstrsd-007", "JC8F96eayuQwwz+PkE7IzjH2lIAjCUnAa61tDigBnSs=");
    

    Guarde o ficheiro.

  2. No menu do Visual Studio, selecione Debug (Depurar) >Start without debugging (Iniciar sem depuração) para executar a solução. No prompt para reconstruir o projeto, selecione Sim, para reconstruir o projeto antes de executar.

    A saída a seguir é um exemplo do dispositivo de torradeira simulado inicializando e conectando-se com êxito à instância do serviço de provisionamento a ser atribuída ao hub IoT das torradeiras pela política de alocação personalizada:

    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:
    

    A saída a seguir é um exemplo de saída de log do código da função de alocação personalizada em execução para o dispositivo torradeiro. Observe que um hub foi selecionado com êxito para um dispositivo de torradeira. Observe também a payload propriedade que contém o conteúdo JSON personalizado que você adicionou ao código. Isso está disponível para seu código usar no deviceRuntimeContext.

    Esse registro está disponível clicando em Logs sob o código da função no portal:

    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)
    

Simular o dispositivo de bomba de calor da Contoso

  1. Para simular o dispositivo da bomba de calor, atualize a chamada para prov_dev_set_symmetric_key_info() prov_dev_client_sample.c novamente com o ID de registo da bomba de calor e a chave do dispositivo derivada gerada anteriormente. O valor da chave 6uejA9PfkQgmYylj8Zerp3kcbeVrGZ172YLa7VSnJzg= mostrado abaixo também é dado apenas como exemplo.

    // Set the symmetric key if using they auth type
    prov_dev_set_symmetric_key_info("mainbuilding167-contoso-hpsd-088", "6uejA9PfkQgmYylj8Zerp3kcbeVrGZ172YLa7VSnJzg=");
    

    Guarde o ficheiro.

  2. No menu do Visual Studio, selecione Debug (Depurar) >Start without debugging (Iniciar sem depuração) para executar a solução. No prompt para reconstruir o projeto, selecione Sim para reconstruir o projeto antes de executá-lo.

    A saída a seguir é um exemplo do dispositivo de bomba de calor simulado inicializando e conectando-se com êxito à instância de serviço de provisionamento a ser atribuída ao hub IoT de bombas de calor da Contoso pela política de alocação personalizada:

    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:
    

Solucionar problemas de políticas de alocação personalizadas

A tabela a seguir mostra os cenários esperados e os códigos de erro de resultados que você pode receber. Use esta tabela para ajudar a solucionar problemas de falhas de política de alocação personalizada com seu Azure Functions.

Cenário Resultado do registro do Serviço de Provisionamento Resultados do SDK de provisionamento
O webhook retorna 200 OK com 'iotHubHostName' definido como um nome de host de hub IoT válido Status do resultado: Atribuído SDK retorna PROV_DEVICE_RESULT_OK junto com informações de hub
O webhook retorna 200 OK com 'iotHubHostName' presente na resposta, mas definido como uma string vazia ou null Status do resultado: Falha

Código de erro: CustomAllocationIotHubNotSpecified (400208)
SDK retorna PROV_DEVICE_RESULT_HUB_NOT_SPECIFIED
O webhook retorna 401 não autorizado Status do resultado: Falha

Código de erro: CustomAllocationUnauthorizedAccess (400209)
SDK retorna PROV_DEVICE_RESULT_UNAUTHORIZED
Foi criado um Registo Individual para desativar o dispositivo Status do resultado: Desativado SDK retorna PROV_DEVICE_RESULT_DISABLED
O webhook retorna o código >de erro = 429 A orquestração do DPS tentará várias vezes. Atualmente, a política de repetição é:

  - Contagem de tentativas: 10
  - Intervalo inicial: 1 s
  - Incremento: 9 s
O SDK ignorará o erro e enviará outra mensagem de status get no tempo especificado
O webhook retorna qualquer outro código de status Status do resultado: Falha

Código de erro: CustomAllocationFailed (400207)
SDK retorna PROV_DEVICE_RESULT_DEV_AUTH_ERROR

Clean up resources (Limpar recursos)

Se você planeja continuar trabalhando com os recursos criados neste tutorial, você pode deixá-los. Se você não planeja continuar usando os recursos, use as etapas a seguir para excluir todos os recursos criados neste tutorial para evitar cobranças desnecessárias.

As etapas aqui pressupõem que você criou todos os recursos neste tutorial conforme instruído no mesmo grupo de recursos chamado contoso-us-resource-group.

Importante

A eliminação de um grupo de recursos é irreversível. O grupo de recursos e todos os recursos nele contidos são eliminados permanentemente. Confirme que não elimina acidentalmente o grupo de recursos ou recursos errados. Se tiver criado o Hub IoT no interior de um grupo de recursos existente que contenha recursos que pretende manter, elimine apenas o recurso do Hub IoT, em vez de eliminar o grupo de recursos.

Para excluir o grupo de recursos pelo nome:

  1. Inicie sessão no Portal do Azure e selecione Grupos de recursos.

  2. Na caixa de texto Filtrar por nome..., digite o nome do grupo de recursos que contém seus recursos, contoso-us-resource-group.

  3. À direita do seu grupo de recursos na lista de resultados, selecione ... e, em seguida , Excluir grupo de recursos.

  4. Ser-lhe-á pedido que confirme a eliminação do grupo de recursos. Digite o nome do grupo de recursos novamente para confirmar e selecione Excluir. Após alguns instantes, o grupo de recursos e todos os recursos contidos no mesmo são eliminados.

Próximos passos

Para saber mais sobre políticas de alocação personalizadas, consulte