Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Aplica-se a:
IoT Edge 1.1
Importante
O IoT Edge 1.1 data de término do suporte foi 13 de dezembro de 2022. Confira o Ciclo de Vida do Produto da Microsoft para obter informações sobre o suporte deste produto, serviço, tecnologia ou API. Para obter mais informações sobre como atualizar para a versão mais recente do IoT Edge, consulte Update IoT Edge.
Este artigo mostra como usar o Visual Studio para desenvolver código C e implantá-lo em um dispositivo Windows que executa o Azure IoT Edge.
Observação
O IoT Edge 1.1 LTS é o último canal de lançamento que dá suporte a contêineres do Windows. A partir da versão 1.2, não há suporte para contêineres do Windows. Considere usar ou mover para o IoT Edge para Linux no Windows, a fim de executá-lo em dispositivos Windows.
Você pode usar módulos do Azure IoT Edge para implantar código que implementa sua lógica de negócios diretamente em seus dispositivos do IoT Edge. Este tutorial explica como criar e implantar um módulo do IoT Edge que filtra os dados do sensor.
Neste tutorial, você aprenderá como:
- Use o Visual Studio para criar um módulo do IoT Edge baseado no SDK do C.
- Use o Visual Studio e o Docker para criar uma imagem do Docker e publicá-la no registro.
- Implante o módulo em seu dispositivo IoT Edge.
- Exibir dados gerados.
O módulo do IoT Edge criado neste tutorial filtra os dados de temperatura gerados pelo dispositivo. O módulo envia mensagens upstream somente se a temperatura exceder um limite especificado. Este tipo de análise no edge é útil para reduzir a quantidade de dados que são comunicados e armazenados na nuvem.
Caso você não tenha uma assinatura do Azure, crie uma conta gratuita do Azure antes de começar.
Pré-requisitos
Este tutorial demonstra como desenvolver um módulo em C usando o Visual Studio 2019 e, em seguida, implantá-lo em um dispositivo Windows. Se você estiver desenvolvendo módulos usando contêineres do Linux, vá para Desenvolver módulos do IoT Edge C usando contêineres do Linux .
Para entender suas opções de desenvolvimento e implantação de módulos C usando contêineres do Windows, consulte a seguinte tabela:
| C | Visual Studio Code | Visual Studio 2017 e 2019 |
|---|---|---|
| Windows AMD64 |
|
Antes de começar este tutorial, configure seu ambiente de desenvolvimento seguindo as instruções no tutorial Desenvolver módulos IoT Edge usando contêineres do Windows. Depois de concluí-lo, seu ambiente conterá os seguintes pré-requisitos:
- Um hub IoT gratuito ou de camada padrão no Azure.
- Um dispositivo Windows que está rodando o Azure IoT Edge.
- Um registro de contêiner, como registro de contêiner do Azure.
- Visual Studio 2019, configurado com a extensão do Azure IoT Edge Tools.
- Docker Desktop, configurado para executar contêineres do Windows.
Instale o SDK do Azure IoT C para Windows x64 através do vcpkg executando os seguintes comandos:
git clone https://github.com/Microsoft/vcpkg
cd vcpkg
.\bootstrap-vcpkg.bat
.\vcpkg install azure-iot-sdk-c:x64-windows
.\vcpkg --triplet x64-windows integrate install
Dica
Se você estiver usando o Visual Studio 2017 (versão 15.7 ou posterior), baixe e instale as Ferramentas do Azure IoT Edge para Visual Studio 2017 do Visual Studio Marketplace.
Criar um projeto de módulo
Nesta seção, você criará um projeto de módulo do IoT Edge baseado no SDK do C usando o Visual Studio e a extensão ferramentas do Azure IoT Edge. Depois de criar um modelo de projeto, você adicionará um novo código para que o módulo filtre mensagens com base em suas propriedades relatadas.
Criar um novo projeto
Crie um modelo de solução C que você possa personalizar com seu próprio código.
Abra o Visual Studio 2019 e selecione Criar Novo Projeto.
No painel Criar um novo projeto, pesquise por IoT Edge e, na lista de resultados, selecione o projeto Azure IoT Edge (Windows amd64).
Selecione Próximo.
O painel Configurar seu novo projeto é aberto.
No painel Configurar seu novo projeto , renomeie o projeto e a solução para algo mais descritivo, como CTutorialApp.
Selecione Criar para criar o projeto.
O painel Adicionar Módulo é aberto.
Na página Configurar seu novo projeto, siga as etapas abaixo:
um. No painel esquerdo, selecione o modelo do Módulo C .
b. Na caixa Nome do Módulo , insira CModule.
c. Na caixa de URL do repositório , substitua localhost:5000 pelo valor do servidor de logon do registro de contêiner do Azure, no seguinte formato:<registry name>.azurecr.io/cmoduleObservação
Um repositório de imagens inclui o nome do registro de contêiner e o nome da imagem de contêiner. Sua imagem de contêiner é pré-populada a partir do valor do nome do módulo do projeto. Você pode recuperar o servidor de logon na página de visão geral do registro de contêiner no portal do Azure.
Selecione Adicionar para criar o projeto.
Adicionar suas credenciais de registro
O manifesto de implantação compartilha as credenciais do registro de contêiner com o runtime do IoT Edge. O runtime precisa dessas credenciais para fazer o download de suas imagens privadas no dispositivo IoT Edge. Use as credenciais da seção Access keys do registro de contêiner do Azure.
No Gerenciador de Soluções do Visual Studio, abra o arquivo deployment.template.json.
Procure a propriedade registryCredentials nas propriedades desejadas do $edgeAgent. O endereço do Registro da propriedade deve ser preenchido automaticamente com as informações fornecidas quando você criou o projeto. Os campos nome de usuário e senha devem conter nomes de variáveis. Por exemplo:
"registryCredentials": { "<registry name>": { "username": "$CONTAINER_REGISTRY_USERNAME_<registry name>", "password": "$CONTAINER_REGISTRY_PASSWORD_<registry name>", "address": "<registry name>.azurecr.io" } }Abra o arquivo ENV (ambiente) na solução do módulo. Por padrão, o arquivo está oculto no Gerenciador de Soluções, portanto, talvez seja necessário selecionar o botão Mostrar Todos os Arquivos para exibi-lo. O arquivo ENV deve conter as mesmas variáveis de nome de usuário e senha que você viu no arquivo deployment.template.json.
Adicione os valores de nome de usuário e senha do registro de contêiner do Azure.
Salve suas alterações no arquivo ENV.
Atualizar o módulo com código personalizado
O código do módulo padrão recebe mensagens em uma fila de entrada e as passa por uma fila de saída. Vamos adicionar um pouco mais de código para que o módulo processe as mensagens na borda antes de encaminhá-las para o hub IoT. Atualize o módulo para que ele analise os dados de temperatura em cada mensagem e envie a mensagem para o hub IoT somente se a temperatura exceder um determinado limite.
Os dados do sensor nesse cenário são fornecidos no formato JSON. Para filtrar as mensagens no formato JSON, importe uma biblioteca JSON para C. Este tutorial utiliza Parson.
um. Baixe o repositório do GitHub Parson.
b. Copie os arquivos parson.c e parson.h para o projeto CModule.
c. No Visual Studio, abra o arquivo CMakeLists.txt da pasta do projeto CModule.
d. Na parte superior do arquivo, importe os arquivos Parson como uma biblioteca chamada my_parson.add_library(my_parson parson.c parson.h )e. Adicione
my_parsonà lista de bibliotecas na seção "target_link_libraries" do arquivo CMakeLists.txt .
f. Salve o arquivo CMakeLists.txt.
g. Selecione CModule>main.c. Na parte inferior da lista de instruções de inclusão, adicione uma nova instrução para incluirparson.hpara o suporte JSON:#include "parson.h"No arquivo main.c , adicione uma variável global chamada
temperatureThresholdao lado damessagesReceivedByInput1Queuevariável. Essa variável define o valor que a temperatura medida deve exceder para que os dados sejam enviados para o hub IoT.static double temperatureThreshold = 25;Localize a
CreateMessageInstancefunção em main.c. Substitua a instrução if-else interna pelo código a seguir, que adiciona algumas linhas de funcionalidade:if ((messageInstance->messageHandle = IoTHubMessage_Clone(message)) == NULL) { free(messageInstance); messageInstance = NULL; } else { messageInstance->messageTrackingId = messagesReceivedByInput1Queue; MAP_HANDLE propMap = IoTHubMessage_Properties(messageInstance->messageHandle); if (Map_AddOrUpdate(propMap, "MessageType", "Alert") != MAP_OK) { printf("ERROR: Map_AddOrUpdate Failed!\r\n"); } }As novas linhas de código na instrução else adicionam uma nova propriedade à mensagem, que rotula a mensagem como um alerta. Esse código rotula todas as mensagens como alertas, pois adicionaremos a funcionalidade que envia mensagens ao hub IoT somente se elas relatarem altas temperaturas.
Localize a
InputQueue1Callbackfunção e substitua toda a função pelo código a seguir. Essa função implementa o filtro de mensagens real. Quando uma mensagem é recebida, ela verifica se a temperatura relatada excede o limite. Se a temperatura exceder o limite, a função encaminha a mensagem por meio de sua fila de saída. Se ele não exceder o limite, a função ignorará a mensagem.static unsigned char *bytearray_to_str(const unsigned char *buffer, size_t len) { unsigned char *ret = (unsigned char *)malloc(len + 1); memcpy(ret, buffer, len); ret[len] = '\0'; return ret; } static IOTHUBMESSAGE_DISPOSITION_RESULT InputQueue1Callback(IOTHUB_MESSAGE_HANDLE message, void* userContextCallback) { IOTHUBMESSAGE_DISPOSITION_RESULT result; IOTHUB_CLIENT_RESULT clientResult; IOTHUB_MODULE_CLIENT_LL_HANDLE iotHubModuleClientHandle = (IOTHUB_MODULE_CLIENT_LL_HANDLE)userContextCallback; unsigned const char* messageBody; size_t contentSize; if (IoTHubMessage_GetByteArray(message, &messageBody, &contentSize) == IOTHUB_MESSAGE_OK) { messageBody = bytearray_to_str(messageBody, contentSize); } else { messageBody = "<null>"; } printf("Received Message [%zu]\r\n Data: [%s]\r\n", messagesReceivedByInput1Queue, messageBody); // Check whether the message reports temperatures that exceed the threshold JSON_Value *root_value = json_parse_string(messageBody); JSON_Object *root_object = json_value_get_object(root_value); double temperature; // If temperature exceeds the threshold, send to output1 if (json_object_dotget_value(root_object, "machine.temperature") != NULL && (temperature = json_object_dotget_number(root_object, "machine.temperature")) > temperatureThreshold) { printf("Machine temperature %f exceeds threshold %f\r\n", temperature, temperatureThreshold); // This message should be sent to next stop in the pipeline, namely "output1". What happens at "outpu1" is determined // by the configuration of the Edge routing table setup. MESSAGE_INSTANCE *messageInstance = CreateMessageInstance(message); if (NULL == messageInstance) { result = IOTHUBMESSAGE_ABANDONED; } else { printf("Sending message (%zu) to the next stage in pipeline\n", messagesReceivedByInput1Queue); clientResult = IoTHubModuleClient_LL_SendEventToOutputAsync(iotHubModuleClientHandle, messageInstance->messageHandle, "output1", SendConfirmationCallback, (void *)messageInstance); if (clientResult != IOTHUB_CLIENT_OK) { IoTHubMessage_Destroy(messageInstance->messageHandle); free(messageInstance); printf("IoTHubModuleClient_LL_SendEventToOutputAsync failed on sending msg#=%zu, err=%d\n", messagesReceivedByInput1Queue, clientResult); result = IOTHUBMESSAGE_ABANDONED; } else { result = IOTHUBMESSAGE_ACCEPTED; } } } // If message does not exceed the threshold, do not forward else { printf("Not sending message (%zu) to the next stage in pipeline.\r\n", messagesReceivedByInput1Queue); result = IOTHUBMESSAGE_ACCEPTED; } messagesReceivedByInput1Queue++; return result; }Adicione uma função
moduleTwinCallback. Este método recebe atualizações sobre as propriedades desejadas do módulo gêmeo e atualiza a variável temperatureThreshold para corresponder. Todos os módulos têm seu próprio módulo gêmeo, o que permite configurar o código em execução dentro do módulo diretamente da nuvem.static void moduleTwinCallback(DEVICE_TWIN_UPDATE_STATE update_state, const unsigned char* payLoad, size_t size, void* userContextCallback) { printf("\r\nTwin callback called with (state=%s, size=%zu):\r\n%s\r\n", MU_ENUM_TO_STRING(DEVICE_TWIN_UPDATE_STATE, update_state), size, payLoad); JSON_Value *root_value = json_parse_string(payLoad); JSON_Object *root_object = json_value_get_object(root_value); if (json_object_dotget_value(root_object, "desired.TemperatureThreshold") != NULL) { temperatureThreshold = json_object_dotget_number(root_object, "desired.TemperatureThreshold"); } if (json_object_get_value(root_object, "TemperatureThreshold") != NULL) { temperatureThreshold = json_object_get_number(root_object, "TemperatureThreshold"); } }Procure pela função
SetupCallbacksForModule. Substitua a função pelo código a seguir, que adiciona uma instrução else-if para verificar se o módulo gêmeo foi atualizado.static int SetupCallbacksForModule(IOTHUB_MODULE_CLIENT_LL_HANDLE iotHubModuleClientHandle) { int ret; if (IoTHubModuleClient_LL_SetInputMessageCallback(iotHubModuleClientHandle, "input1", InputQueue1Callback, (void*)iotHubModuleClientHandle) != IOTHUB_CLIENT_OK) { printf("ERROR: IoTHubModuleClient_LL_SetInputMessageCallback(\"input1\")..........FAILED!\r\n"); ret = MU_FAILURE; } else if (IoTHubModuleClient_LL_SetModuleTwinCallback(iotHubModuleClientHandle, moduleTwinCallback, (void*)iotHubModuleClientHandle) != IOTHUB_CLIENT_OK) { printf("ERROR: IoTHubModuleClient_LL_SetModuleTwinCallback(default)..........FAILED!\r\n"); ret = MU_FAILURE; } else { ret = 0; } return ret; }Salve o arquivo main.c.
Abra o arquivo deployment.template.json.
Adicione o módulo gêmeo CModule ao manifesto de implantação. Insira o seguinte conteúdo JSON na parte inferior da seção
moduleContent, após o módulo gêmeo do$edgeHub:"CModule": { "properties.desired":{ "TemperatureThreshold":25 } }
Salve o arquivo deployment.template.json.
Compilar e subir seu módulo
Na seção anterior, você criou uma solução do IoT Edge e adicionou código ao CModule para filtrar mensagens em que a temperatura do computador relatada está abaixo do limite aceitável. Agora você precisa construir a solução como uma imagem de contêiner e enviá-la para o registro de imagens de contêiner.
Entrar no Docker
Forneça suas credenciais de registro de contêiner ao Docker em seu computador de desenvolvimento para que ele possa enviar por push sua imagem de contêiner para ser armazenada no registro.
Abra o PowerShell ou uma janela do Prompt de Comando.
Entre no Docker com as credenciais do Registro de Contêiner do Azure que você salvou depois de criar o registro.
docker login -u <ACR username> -p <ACR password> <ACR login server>Você pode receber um aviso de segurança que recomenda o uso de
--password-stdin. Embora recomendemos isso como uma prática recomendada para cenários de produção, ele está fora do escopo deste tutorial. Para obter mais informações, consulte a referência de login do docker .
Compilar e enviar por push
Seu computador de desenvolvimento agora tem acesso ao registro de contêiner, e seus dispositivos do IoT Edge também terão. É hora de transformar o código do projeto em uma imagem de contêiner.
No Gerenciador de Soluções do Visual Studio, clique com o botão direito do mouse no nome do projeto que você deseja criar. O nome padrão é AzureIotEdgeApp1. Para este tutorial, escolhemos o nome CTutorialApp e, como você está criando um módulo do Windows, a extensão deve ser Windows.Amd64.
Selecione Construir e fazer o push dos módulos do IoT Edge.
O comando build e push inicia três operações:
- Primeiro, cria uma nova pasta na solução chamada configuração , que contém o manifesto de implantação completo. Ele é compilado a partir de informações no modelo de implantação e em outros arquivos de solução.
- Em segundo lugar, ele executa
docker buildpara criar a imagem de contêiner, com base no Dockerfile apropriado para sua arquitetura de destino. - Por fim, executa-se o
docker pushpara fazer o push do repositório de imagens para o registro de containers.
Esse processo pode levar vários minutos na primeira vez, mas será mais rápido na próxima vez que você executar os comandos.
Implantar módulos no dispositivo
Use o Visual Studio Cloud Explorer e a extensão ferramentas do Azure IoT Edge para implantar o projeto de módulo em seu dispositivo IoT Edge. Você já preparou um manifesto de implantação para o seu cenário, o arquivo deployment.windows-amd64.json na pasta de configuração. Agora, tudo o que você precisa fazer é selecionar um dispositivo para receber a implantação.
Verifique se seu dispositivo IoT Edge está em funcionamento.
No Visual Studio Cloud Explorer, expanda os recursos para exibir sua lista de dispositivos IoT.
Clique com o botão direito do mouse no nome do dispositivo IoT Edge que você deseja receber a implantação.
Selecione Criar Implementação.
No Explorador de Arquivos do Visual Studio, selecione o arquivo deployment.windows-amd64.json na pasta de configuração da solução.
Atualize o Cloud Explorer para exibir os módulos implantados listados em seu dispositivo.
Exibir os dados gerados
Depois de aplicar o manifesto de implantação ao dispositivo IoT Edge, o runtime do IoT Edge no dispositivo coletará as novas informações de implantação e começará a ser executado nele. Todos os módulos em execução no dispositivo, mas não incluídos no manifesto de implantação, são interrompidos. Todos os módulos ausentes do dispositivo são iniciados.
Você pode usar a extensão ferramentas do IoT Edge para exibir as mensagens à medida que elas chegam ao hub IoT.
No Visual Studio Cloud Explorer, selecione o nome do dispositivo IoT Edge.
Na lista Ações, selecione "Iniciar o monitoramento do ponto de extremidade de evento embutido".
Exiba as mensagens que estão chegando ao hub IoT. Pode demorar um pouco para que as mensagens cheguem, pois o dispositivo do IoT Edge precisa receber sua nova implantação e iniciar todos os módulos. As alterações no código CModule devem aguardar até que a temperatura do computador atinja 25 graus antes que as mensagens possam ser enviadas. O código também adiciona o tipo de mensagem de Alerta a qualquer mensagem que atinja esse limite de temperatura.
Editar o módulo gêmeo
Você usou o módulo gêmeo CModule para definir o limite de temperatura em 25 graus. Você pode usar o módulo gêmeo para alterar a funcionalidade sem precisar atualizar o código do módulo.
No Visual Studio, abra o arquivo deployment.windows-amd64.json.
Não abra o arquivo deployment.template. Se você não vir o manifesto de implantação no arquivo de configuração no Gerenciador de Soluções, selecione o ícone Mostrar todos os arquivos na barra de ferramentas do Gerenciador de Soluções.
Busque o gêmeo CModule e modifique o valor do parâmetro temperatureThreshold para uma nova temperatura de 5 a 10 graus mais alta do que a temperatura relatada mais recente.
Salve o arquivo deployment.windows-amd64.json.
Siga as instruções de implantação novamente para aplicar o manifesto de implantação atualizado ao seu dispositivo.
Monitore as mensagens de entrada do dispositivo para a nuvem. As mensagens devem parar até que o novo limite de temperatura seja atingido.
Limpar os recursos
Se você planeja continuar para o próximo artigo recomendado, poderá manter e reutilizar os recursos e as configurações que criou neste tutorial. Você também pode continuar usando o mesmo dispositivo IoT Edge como um dispositivo de teste.
Caso contrário, para evitar incorrer em encargos, você pode excluir as configurações locais e os recursos do Azure que você usou aqui.
Excluir recursos do Azure
A exclusão de recursos do Azure e dos grupos de recursos é irreversível. Certifique-se de não excluir acidentalmente o grupo de recursos ou os recursos errados. Se você criou o hub IoT em um grupo de recursos existente que contém recursos que deseja manter, exclua apenas o recurso do hub IoT, não o grupo de recursos.
Para excluir os recursos:
Entre no portal do Azure e selecione Grupos de recursos.
Selecione o nome do grupo de recursos que contém os recursos de teste do IoT Edge.
Examine a lista de recursos contidos em seu grupo de recursos. Se você deseja excluir todos eles, selecione Excluir grupo de recursos. Se você quiser excluir apenas alguns deles, clique em cada recurso para excluí-los individualmente.
Próximas etapas
Neste tutorial, você criou um módulo do IoT Edge com código para filtrar dados brutos gerados pelo dispositivo IoT Edge.
Para saber como o Azure IoT Edge pode ajudá-lo a implantar serviços de nuvem do Azure para processar e analisar dados na borda, continue para os próximos tutoriais.