Tutorial: Criar e implantar módulos personalizados do IoT Edge
Aplica-se a: IoT Edge 1.1
Importante
A data de fim do suporte do IoT Edge 1.1 foi 13 de dezembro de 2022. Consulte o Ciclo de Vida de Produtos da Microsoft para obter informações sobre como é suportado este produto, serviço, tecnologia ou API. Para obter mais informações sobre como atualizar para a versão mais recente do IoT Edge, consulte Atualizar o IoT Edge.
Neste artigo, criamos três módulos do IoT Edge que recebem mensagens de dispositivos IoT downstream, executam os dados por meio de seu modelo de aprendizado de máquina e, em seguida, encaminham insights para o Hub IoT.
O hub IoT Edge facilita a comunicação entre módulos. O uso do hub IoT Edge como um agente de mensagens mantém os módulos independentes uns dos outros. Os módulos só precisam especificar as entradas nas quais aceitam mensagens e as saídas para as quais escrevem mensagens.
Queremos que o dispositivo IoT Edge realize quatro coisas para nós:
- Receba dados dos dispositivos a jusante.
- Preveja a vida útil restante (RUL) para o dispositivo que enviou os dados.
- Envie uma mensagem com o RUL do dispositivo para o Hub IoT. Esta função pode ser modificada para enviar dados somente se o RUL cair abaixo de um nível especificado.
- Salve os dados do dispositivo downstream em um arquivo local no dispositivo IoT Edge. Esse arquivo de dados é carregado periodicamente no Hub IoT para refinar o treinamento do modelo de aprendizado de máquina. Usar o upload de arquivos em vez do streaming constante de mensagens é mais econômico.
Para realizar essas tarefas, usamos três módulos personalizados:
Classificador RUL: O módulo turboFanRulClassifier que criamos em Train and deploy an Azure Machine Learning model é um módulo de aprendizado de máquina padrão, que expõe uma entrada chamada "amlInput" e uma saída chamada "amlOutput". O "amlInput" espera que sua entrada se pareça exatamente com a entrada que enviamos para o serviço Web baseado em ACI. Da mesma forma, "amlOutput" retorna os mesmos dados que o serviço Web.
Avro writer: Este módulo recebe mensagens na entrada "avroModuleInput" e persiste a mensagem no formato Avro para o disco para posterior upload para o IoT Hub.
Módulo do roteador: O módulo do roteador recebe mensagens de dispositivos downstream e, em seguida, formata e envia as mensagens para o classificador. Em seguida, o módulo recebe as mensagens do classificador e encaminha a mensagem para o módulo gravador Avro. Finalmente, o módulo envia apenas a previsão RUL para o Hub IoT.
Entradas:
- deviceInput: recebe mensagens de dispositivos a jusante
- rulInput: recebe mensagens do "amlOutput"
Realizações:
- classificar: envia mensagens para "amlInput"
- writeAvro: envia mensagens para "avroModuleInput"
- toIotHub: envia mensagens para $upstream, que passa as mensagens para o Hub IoT conectado
O diagrama a seguir mostra os módulos, entradas, saídas e as rotas do Hub IoT Edge para a solução completa:
As etapas neste artigo geralmente são executadas por um desenvolvedor de nuvem.
Nesta seção do tutorial, você aprenderá a:
- Crie um módulo IoT Edge a partir de código personalizado.
- Gere uma imagem do Docker a partir do seu módulo personalizado.
- Reconfigure o roteamento do Hub IoT para dar suporte aos seus módulos personalizados.
- Crie, publique e implante seus módulos personalizados.
Pré-requisitos
Este artigo faz parte de uma série de tutoriais sobre como usar o Azure Machine Learning no IoT Edge. Cada artigo da série baseia-se no trabalho do artigo anterior. Se você chegou a este artigo diretamente, visite o primeiro artigo da série.
Criar uma nova solução IoT Edge
Durante a execução do segundo de nossos dois Blocos de Anotações do Azure, criamos e publicamos uma imagem de contêiner contendo nosso modelo RUL. O Azure Machine Learning, como parte do processo de criação da imagem, empacotou esse modelo para que a imagem possa ser implantada como um módulo do Azure IoT Edge.
Nesta etapa, vamos criar uma solução do Azure IoT Edge usando o módulo "Azure Machine Learning" e apontar o módulo para a imagem que publicamos usando o Azure Notebooks.
Abra uma sessão de área de trabalho remota para sua VM de desenvolvimento.
Abra a pasta C:\source\IoTEdgeAndMlSample no Visual Studio Code.
Clique com o botão direito do mouse no painel do explorador (no espaço em branco) e selecione Nova Solução IoT Edge.
Aceite o nome da solução padrão EdgeSolution.
Escolha Azure Machine Learning como o modelo de módulo.
Nomeie o módulo turbofanRulClassifier.
Escolha seu espaço de trabalho de aprendizado de máquina. Este espaço de trabalho é o espaço de trabalho turboFanDemo que você criou em Tutorial: Treinar e implantar um modelo do Azure Machine Learning
Selecione a imagem que você criou ao executar o Bloco de Anotações do Azure.
Olhe para a solução e observe os arquivos que foram criados:
deployment.template.json: Este arquivo contém a definição de cada um dos módulos na solução. Há três seções para prestar atenção neste arquivo:
Credenciais do Registro: define o conjunto de registros de contêiner personalizados que você está usando em sua solução. No momento, ele deve conter o registro do seu espaço de trabalho de aprendizado de máquina, que é onde sua imagem do Azure Machine Learning foi armazenada. Você pode ter qualquer número de registros de contêiner, mas para simplificar, usaremos este registro para todos os módulos.
"registryCredentials": { "<your registry>": { "username": "$CONTAINER_REGISTRY_USERNAME_<your registry>", "password": "$CONTAINER_REGISTRY_PASSWORD_<your registry>", "address": "<your registry>.azurecr.io" } }
Módulos: Esta seção contém o conjunto de módulos definidos pelo usuário que acompanham esta solução. A definição do módulo turbofanRulClassifier aponta para a imagem no seu registro de contêiner. À medida que adicionamos mais módulos à solução, eles aparecerão nesta seção.
"modules": { "turbofanRulClassifier": { "version": "1.0", "type": "docker", "status": "running", "restartPolicy": "always", "settings": { "image": "turbofandemo2cd74296.azurecr.io/edgemlsample:1", "createOptions": {} } } }
Rotas: vamos trabalhar bastante com rotas neste tutorial. As rotas definem como os módulos se comunicam entre si. A rota existente definida pelo modelo não corresponde ao roteamento de que precisamos. Exclua a
turbofanRulClassifierToIoTHub
rota."$edgeHub": { "properties.desired": { "schemaVersion": "1.0", "routes": { "turbofanRulClassifierToIoTHub": "FROM /messages/modules/turbofanRulClassifier/outputs/* INTO $upstream" }, "storeAndForwardConfiguration": { "timeToLiveSecs": 7200 } } }
deployment.debug.template.json: Este arquivo é a versão de depuração do deployment.template.json. Normalmente, devemos manter esse arquivo sincronizado com o conteúdo do arquivo deployment.template.json, mas isso não é necessário para este tutorial.
.env: este arquivo é onde você deve fornecer o nome de usuário e senha para acessar seu registro.
CONTAINER_REGISTRY_USERNAME_<your registry name>=<ACR username> CONTAINER_REGISTRY_PASSWORD_<your registry name>=<ACR password>
Nota
Este tutorial usa credenciais de logon de administrador para o Registro de Contêiner do Azure, que são convenientes para cenários de desenvolvimento e teste. Quando estiver pronto para cenários de produção, recomendamos uma opção de autenticação de privilégios mínimos, como entidades de serviço. Para obter mais informações, consulte Gerenciar o acesso ao registro de contêiner.
Clique com o botão direito do mouse no arquivo deployment.template.json no explorador de código do Visual Studio e selecione Criar solução IoT Edge.
Observe que esse comando cria uma pasta de configuração com um arquivo deployment.amd64.json. Este arquivo é o modelo de implantação concreto para a solução.
Adicionar módulo de roteador
Em seguida, adicionamos o módulo Router à nossa solução. O módulo Router assume várias responsabilidades pela nossa solução:
- Receber mensagens de dispositivos downstream: à medida que as mensagens chegam ao dispositivo IoT Edge a partir de dispositivos downstream, o módulo Router recebe a mensagem e começa a orquestrar o encaminhamento da mensagem.
- Enviar mensagens para o módulo Classificador RUL: quando uma nova mensagem é recebida de um dispositivo a jusante, o módulo Router transforma a mensagem para o formato esperado pelo Classificador RUL. O roteador envia a mensagem para o classificador RUL para uma previsão RUL. Uma vez que o classificador tenha feito uma previsão, ele envia a mensagem de volta para o módulo do roteador.
- Enviar mensagens RUL para o Hub IoT: quando o Roteador recebe mensagens do classificador, ele transforma a mensagem para conter apenas as informações essenciais, ID do dispositivo e RUL, e envia a mensagem abreviada para o hub IoT. Um aperfeiçoamento adicional, que não fizemos aqui, enviaria mensagens para o Hub IoT apenas quando a previsão do RUL cair abaixo de um limite (por exemplo, quando o RUL tiver menos de 100 ciclos). A filtragem dessa forma reduziria o volume de mensagens e reduziria o custo do hub IoT.
- Enviar mensagem para o módulo Avro Writer: para preservar todos os dados enviados pelo dispositivo downstream, o módulo Router envia toda a mensagem recebida do classificador para o módulo Avro Writer, que persistirá e carregará os dados usando o upload de arquivos do Hub IoT.
O módulo Router é uma peça importante da solução que garante que as mensagens são processadas na ordem correta.
Criar o módulo e copiar arquivos
Clique com o botão direito do mouse na pasta modules no Visual Studio Code e escolha Add IoT Edge Module.
Escolha o módulo C# para o modelo de módulo.
Nomeie o módulo turbofanRouter.
Quando solicitado para o repositório de imagens do Docker, use o registro do espaço de trabalho de aprendizado de máquina (você pode encontrar o registro no nó registryCredentials do arquivo deployment.template.json ). Esse valor é o endereço totalmente qualificado para o registro, como seu registro.azurecr.io/turbofanrouter>.<
Nota
Neste artigo, usamos o Registro de Contêiner do Azure que foi criado pelo espaço de trabalho do Azure Machine Learning. Isto é puramente por conveniência. Poderíamos ter criado um novo registro de contêiner e publicado nossos módulos lá.
No Terminal usando um shell de prompt de comando, copie os arquivos do módulo de exemplo para a solução.
copy c:\source\IoTEdgeAndMlSample\EdgeModules\modules\turbofanRouter\*.cs c:\source\IoTEdgeAndMlSample\EdgeSolution\modules\turbofanRouter\
Aceite o prompt para substituir o arquivo program.cs.
Construir módulo de roteador
No Visual Studio Code, selecione Terminal>Configure Default Build Task.
Selecione Criar tasks.json arquivo do modelo.
Selecione .NET Core.
Substitua o conteúdo do tasks.json pelo código a seguir.
{ "version": "2.0.0", "tasks": [ { "label": "build", "command": "dotnet", "type": "shell", "group": { "kind": "build", "isDefault": true }, "args": [ "build", "${workspaceFolder}/modules/turbofanRouter" ], "presentation": { "reveal": "always" }, "problemMatcher": "$msCompile" } ] }
Salve e feche tasks.json.
Executar compilação com
Ctrl + Shift + B
ou Tarefa de compilação de execução de terminal>.
Configurar rotas de módulo
Como mencionado acima, o tempo de execução do IoT Edge usa rotas configuradas no arquivo deployment.template.json para gerenciar a comunicação entre módulos com acoplamento flexível. Nesta seção, detalhamos como configurar as rotas para o módulo turbofanRouter. Vamos cobrir as rotas de entrada primeiro e, em seguida, passar sobre as saídas.
Entradas
No método Init() de Program.cs registramos dois retornos de chamada para o módulo:
await ioTHubModuleClient.SetInputMessageHandlerAsync(EndpointNames.FromLeafDevice, LeafDeviceInputMessageHandler, ioTHubModuleClient); await ioTHubModuleClient.SetInputMessageHandlerAsync(EndpointNames.FromClassifier, ClassifierCallbackMessageHandler, ioTHubModuleClient);
O primeiro retorno de chamada escuta as mensagens enviadas para o coletor deviceInput . No diagrama acima, vemos que queremos rotear mensagens de qualquer dispositivo downstream para essa entrada. No arquivo deployment.template.json, adicione uma rota que diga ao hub de borda para rotear qualquer mensagem recebida pelo dispositivo IoT Edge que não tenha sido enviada por um módulo IoT Edge para a entrada chamada "deviceInput" no módulo turbofanRouter:
"leafMessagesToRouter": "FROM /messages/* WHERE NOT IS_DEFINED($connectionModuleId) INTO BrokeredEndpoint(\"/modules/turbofanRouter/inputs/deviceInput\")"
Em seguida, adicione uma rota para mensagens do módulo rulClassifier no módulo turbofanRouter:
"classifierToRouter": "FROM /messages/modules/turbofanRulClassifier/outputs/amloutput INTO BrokeredEndpoint(\"/modules/turbofanRouter/inputs/rulInput\")"
Saídas
Adicione quatro rotas adicionais ao parâmetro $edgeHub route, para lidar com saídas do módulo Router.
Program.cs define o método SendMessageToClassifier(), que usa o cliente do módulo para enviar uma mensagem para o classificador RUL usando a rota:
"routerToClassifier": "FROM /messages/modules/turbofanRouter/outputs/classOutput INTO BrokeredEndpoint(\"/modules/turbofanRulClassifier/inputs/amlInput\")"
SendRulMessageToIotHub() usa o cliente do módulo para enviar apenas os dados RUL do dispositivo para o Hub IoT através da rota:
"routerToIoTHub": "FROM /messages/modules/turboFanRouter/outputs/hubOutput INTO $upstream"
SendMessageToAvroWriter() usa o cliente do módulo para enviar a mensagem com os dados RUL adicionados ao módulo avroFileWriter.
"routerToAvro": "FROM /messages/modules/turbofanRouter/outputs/avroOutput INTO BrokeredEndpoint(\"/modules/avroFileWriter/inputs/avroModuleInput\")"
HandleBadMessage() envia mensagens com falha upstream do Hub IoT onde podem ser roteadas para mais tarde.
"deadLetter": "FROM /messages/modules/turboFanRouter/outputs/deadMessages INTO $upstream"
Com todas as rotas juntas, seu nó "$edgeHub" deve se parecer com o seguinte JSON:
"$edgeHub": {
"properties.desired": {
"schemaVersion": "1.0",
"routes": {
"leafMessagesToRouter": "FROM /messages/* WHERE NOT IS_DEFINED($connectionModuleId) INTO BrokeredEndpoint(\"/modules/turbofanRouter/inputs/deviceInput\")",
"classifierToRouter": "FROM /messages/modules/turbofanRulClassifier/outputs/amlOutput INTO BrokeredEndpoint(\"/modules/turbofanRouter/inputs/rulInput\")",
"routerToClassifier": "FROM /messages/modules/turbofanRouter/outputs/classOutput INTO BrokeredEndpoint(\"/modules/turbofanRulClassifier/inputs/amlInput\")",
"routerToIoTHub": "FROM /messages/modules/turboFanRouter/outputs/hubOutput INTO $upstream",
"routerToAvro": "FROM /messages/modules/turbofanRouter/outputs/avroOutput INTO BrokeredEndpoint(\"/modules/avroFileWriter/inputs/avroModuleInput\")",
"deadLetter": "FROM /messages/modules/turboFanRouter/outputs/deadMessages INTO $upstream"
},
"storeAndForwardConfiguration": {
"timeToLiveSecs": 7200
}
}
}
Nota
Adicionar o módulo turbofanRouter criou a seguinte rota adicional: turbofanRouterToIoTHub": "FROM /messages/modules/turbofanRouter/outputs/* INTO $upstream
. Remova essa rota, deixando apenas as rotas listadas acima em seu arquivo deployment.template.json.
Adicionar módulo Avro Writer
O módulo Avro Writer tem duas responsabilidades em nossa solução, armazenar mensagens e fazer upload de arquivos.
Armazenar mensagens: quando o módulo Avro Writer recebe uma mensagem, ele grava a mensagem no sistema de arquivos local no formato Avro. Usamos um bind mount, que monta um diretório (neste caso /data/avrofiles) em um caminho no contêiner do módulo. Essa montagem permite que o módulo grave em um caminho local (/avrofiles) e tenha esses arquivos acessíveis diretamente do dispositivo IoT Edge.
Carregar arquivos: o módulo Avro Writer usa o recurso de carregamento de arquivos do Hub IoT do Azure para carregar arquivos em uma conta de armazenamento do Azure. Uma vez que um arquivo é carregado com êxito, o módulo exclui o arquivo do disco
Criar módulo e copiar arquivos
No Visual Studio Code, selecione View>Command Palette e, em seguida, procure e selecione Python: Select Interpreter.
Selecione a versão 3.7 ou posterior do Python instalado.
Clique com o botão direito do mouse na pasta modules no Visual Studio Code e escolha Add IoT Edge Module.
Escolha Python Module (Módulo de Python).
Nomeie o módulo
avroFileWriter
.Quando solicitado para o repositório de imagens do Docker, use o mesmo registro que você usou ao adicionar o módulo do roteador.
Copie arquivos do módulo de exemplo para a solução.
copy C:\source\IoTEdgeAndMlSample\EdgeModules\modules\avroFileWriter\*.py C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avroFileWriter\
Aceite a substituição de main.py.
Observe que filemanager.py e schema.py foram adicionados à solução e main.py foi atualizado.
Nota
Quando você abre um arquivo Python você pode ser solicitado a instalar pylint. Não é necessário instalar o linter para concluir este tutorial.
Montagem de ligação para arquivos de dados
Como mencionado anteriormente, o módulo de gravador depende da presença de uma montagem de ligação para gravar arquivos Avro no sistema de arquivos do dispositivo.
Adicionar diretório ao dispositivo
No portal do Azure, inicie a VM do dispositivo IoT Edge se ela não estiver em execução. Conecte-se a ele usando SSH. A conexão requer o nome DNS que você pode copiar da página de visão geral da VM no portal do Azure.
ssh -l <user>@<vm name>.<region>.cloudapp.azure.com
Depois de fazer login, crie o diretório que armazenará as mensagens salvas do dispositivo downstream.
sudo mkdir -p /data/avrofiles
Atualize as permissões de diretório para torná-lo gravável pelo contêiner.
sudo chmod ugo+rw /data/avrofiles
Validar o diretório agora tem permissão de gravação (w) para usuário, grupo e proprietário.
ls -la /data
Adicionar diretório ao módulo
Para adicionar o diretório ao contêiner do módulo, modificaremos os Dockerfiles associados ao módulo avroFileWriter. Há três Dockerfiles associados ao módulo: Dockerfile.amd64, Dockerfile.amd64.debug e Dockerfile.arm32v7. Esses arquivos devem ser mantidos em sincronia caso desejemos depurar ou implantar em um dispositivo arm32. Para este artigo, concentre-se apenas em Dockerfile.amd64.
Na VM de desenvolvimento, abra o arquivo C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avoFileWriter\Dockerfile.amd64 .
Modifique o arquivo para que seja parecido com o exemplo a seguir:
FROM ubuntu:xenial WORKDIR /app RUN apt-get update && apt-get install -y --no-install-recommends libcurl4-openssl-dev python3-pip libboost-python1.58-dev libpython3-dev && rm -rf /var/lib/apt/lists/* RUN pip3 install --upgrade pip COPY requirements.txt ./ RUN pip install -r requirements.txt COPY . . RUN useradd -ms /bin/bash moduleuser RUN mkdir /avrofiles && chown moduleuser /avrofiles USER moduleuser CMD [ "python3", "-u", "./main.py" ]
Os
mkdir
comandos echown
instruem o processo de compilação do Docker a criar um diretório de nível superior chamado /avrofiles na imagem e, em seguida, tornar o moduleuser o proprietário desse diretório. É importante que esses comandos sejam inseridos depois que o usuário do módulo é adicionado à imagem com ouseradd
comando e antes que o contexto mude para o moduleuser (USER moduleuser).Se necessário, faça as alterações correspondentes em Dockerfile.amd64.debug e Dockerfile.arm32v7.
Adicionar configuração de ligação ao avroFileWriter
A etapa final da criação da associação é atualizar os arquivos deployment.template.json (e deployment.debug.template.json) com as informações de ligação.
Abra deployment.template.json.
Modifique a definição de módulo para avroFileWriter adicionando o
Binds
parâmetro que aponta o diretório de contêiner /avrofiles para o diretório local no dispositivo de borda. Sua definição de módulo deve corresponder a este exemplo:"avroFileWriter": { "version": "1.0", "type": "docker", "status": "running", "restartPolicy": "always", "settings": { "image": "${MODULES.avroFileWriter}", "createOptions": { "HostConfig": { "Binds": [ "/data/avrofiles:/avrofiles" ] } } } }
Bind mount para acesso a config.yaml
Precisamos adicionar mais um link para o módulo writer. Essa associação dá ao módulo acesso para ler a cadeia de conexão do arquivo /etc/iotedge/config.yaml no dispositivo IoT Edge. Precisamos da cadeia de conexão para criar um IoTHubClient para que possamos chamar o método upload_blob_async para carregar arquivos para o hub IoT. As etapas para adicionar essa ligação são semelhantes às da seção anterior.
Atualizar permissão de diretório
Conecte-se ao seu dispositivo IoT Edge usando SSH.
ssh -l <user>@IoTEdge-<extension>.<region>.cloudapp.azure.com
Adicione permissão de leitura ao arquivo config.yaml.
sudo chmod +r /etc/iotedge/config.yaml
Valide se as permissões estão definidas corretamente.
ls -la /etc/iotedge/
Verifique se as permissões para config.yaml são -r--r--r--.
Adicionar diretório ao módulo
Na máquina de desenvolvimento, abra o arquivo Dockerfile.amd64 .
Adicione um conjunto adicional de
mkdir
comandos echown
ao arquivo para que seja parecido com:FROM ubuntu:xenial WORKDIR /app RUN apt-get update && apt-get install -y --no-install-recommends libcurl4-openssl-dev python3-pip libboost-python1.58-dev libpython3-dev && rm -rf /var/lib/apt/lists/\* RUN pip3 install --upgrade pip COPY requirements.txt ./ RUN pip install -r requirements.txt COPY . . RUN useradd -ms /bin/bash moduleuser RUN mkdir /avrofiles && chown moduleuser /avrofiles RUN mkdir -p /app/iotconfig && chown moduleuser /app/iotconfig USER moduleuser CMD "python3", "-u", "./main.py"]
Faça as alterações correspondentes em Dockerfile.amd64.debug e Dockerfile.arm32v7.
Atualizar a configuração do módulo
Abra o arquivo deployment.template.json .
Modifique a definição do módulo para avroFileWriter adicionando uma segunda linha ao
Binds
parâmetro que aponta o diretório container (/app/iotconfig) para o diretório local no dispositivo (/etc/iotedge)."avroFileWriter": { "version": "1.0", "type": "docker", "status": "running", "restartPolicy": "always", "settings": { "image": "${MODULES.avroFileWriter}", "createOptions": { "HostConfig": { "Binds": [ "/data/avrofiles:/avrofiles", "/etc/iotedge:/app/iotconfig" ] } } } }
Faça as alterações correspondentes em deployment.debug.template.json.
Instalar dependências
O módulo writer depende de duas bibliotecas Python, fastavro e PyYAML. Precisamos instalar as dependências em nossa máquina de desenvolvimento e instruir o processo de compilação do Docker para instalá-las na imagem do nosso módulo.
PyYAML
Em sua máquina de desenvolvimento, abra o
C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avoFileWriter\requirements.txt
arquivo e adicione "pyyaml" em uma nova linha no arquivo.azure-iothub-device-client~=1.4.3 pyyaml
Abra o arquivo Dockerfile.amd64 e adicione um
pip install
comando para atualizar setuptools.FROM ubuntu:xenial WORKDIR /app RUN apt-get update && \ apt-get install -y --no-install-recommends libcurl4-openssl-dev python3-pip libboost-python1.58-dev libpython3-dev && \ rm -rf /var/lib/apt/lists/\* RUN pip3 install --upgrade pip RUN pip install -U pip setuptools COPY requirements.txt ./ RUN pip install -r requirements.txt COPY . . RUN useradd -ms /bin/bash moduleuser RUN mkdir /avrofiles && chown moduleuser /avrofiles RUN mkdir -p /app/iotconfig && chown moduleuser /app/iotconfig USER moduleuser CMD [ "python3", "-u", "./main.py" ]
Em um prompt de comando, instale pyyaml em sua máquina de desenvolvimento.
pip install pyyaml
Fastavro
Em requirements.txt, adicione fastavro após pyyaml.
azure-iothub-device-client~=1.4.3 pyyaml fastavro
Instale o fastavro na sua máquina de desenvolvimento.
pip install fastavro
Reconfigurar o Hub IoT
Ao introduzir o dispositivo e os módulos IoT Edge no sistema, mudamos nossas expectativas sobre quais dados serão enviados para o hub e para qual finalidade. Precisamos reconfigurar o roteamento no hub para lidar com a nossa nova realidade.
Nota
Reconfiguramos o hub antes de implantar módulos porque algumas das configurações do hub, especificamente o upload de arquivos, precisam ser configuradas corretamente para que o módulo avroFileWriter seja executado corretamente
Configurar rota para mensagens RUL no Hub IoT
Com o roteador e o classificador no lugar, esperamos receber mensagens regulares contendo apenas o ID do dispositivo e a previsão RUL para o dispositivo. Queremos encaminhar os dados RUL para o seu próprio local de armazenamento, onde podemos monitorizar o estado dos dispositivos, criar relatórios e alertas de incêndio conforme necessário. Ao mesmo tempo, queremos que todos os dados do dispositivo que ainda estejam sendo enviados diretamente por um dispositivo downstream que ainda não tenha sido conectado ao nosso dispositivo IoT Edge continuem a ser encaminhados para o local de armazenamento atual.
Criar uma rota de mensagem RUL
No portal do Azure, navegue para o Hub IoT.
No menu no painel esquerdo, em Configurações do Hub, selecione Roteamento de mensagens.
Na guia Rotas, selecione Adicionar.
Nomeie a rota RulMessageRoute.
Selecione Adicionar ponto de extremidade à direita do seletor de ponto de extremidade e escolha Armazenamento.
Na página Adicionar um ponto de extremidade de armazenamento, nomeie o ponto de extremidade como ruldata.
Selecione Escolher um contêiner.
Na página Contas de armazenamento, localize a conta de armazenamento que você está usando ao longo deste tutorial, que é nomeada como sufixo> exclusivo iotedgeandml<.
Selecione o contêiner ruldata e clique em Selecionar.
De volta à página Adicionar um ponto de extremidade de armazenamento, selecione Criar para criar o ponto de extremidade de armazenamento.
De volta à página Adicionar uma rota , para a consulta Roteamento, substitua
true
pela seguinte consulta:IS_DEFINED($body.PredictedRul) AND NOT IS_DEFINED($body.OperationalSetting1)
Expanda a seção Teste e, em seguida, a seção Corpo da mensagem. Substitua o corpo da mensagem por este exemplo de nossas mensagens esperadas:
{ "ConnectionDeviceId": "aaLeafDevice_1", "CorrelationId": "b27e97bb-06c5-4553-a064-e9ad59c0fdd3", "PredictedRul": 132.62721409309165, "CycleTime": 64.0 }
Selecione Rota de teste. Se o teste for bem-sucedido, você verá "A mensagem correspondeu à consulta".
Clique em Guardar.
Atualizar rota turbofanDeviceDataToStorage
Não queremos encaminhar os novos dados de previsão para o nosso antigo local de armazenamento, portanto, atualize a rota para evitá-lo.
Na página Roteamento de mensagens do Hub IoT, selecione a guia Rotas.
Selecione turbofanDeviceDataToStorage, ou qualquer nome que você deu à rota inicial de dados do dispositivo.
Atualize a consulta de roteamento para
IS_DEFINED($body.OperationalSetting1)
Expanda a seção Teste e, em seguida, a seção Corpo da mensagem. Substitua a mensagem por este exemplo de nossas mensagens esperadas:
{ "Sensor13": 2387.96, "OperationalSetting1": -0.0008, "Sensor6": 21.61, "Sensor11": 47.2, "Sensor9": 9061.45, "Sensor4": 1397.86, "Sensor14": 8140.39, "Sensor18": 2388.0, "Sensor12": 522.87, "Sensor2": 642.42, "Sensor17": 391.0, "OperationalSetting3": 100.0, "Sensor1": 518.67, "OperationalSetting2": 0.0002, "Sensor20": 39.03, "DeviceId": 19.0, "Sensor5": 14.62, "PredictedRul": 212.00132402791962, "Sensor8": 2388.01, "Sensor16": 0.03, "CycleTime": 42.0, "Sensor21": 23.3188, "Sensor15": 8.3773, "Sensor3": 1580.09, "Sensor10": 1.3, "Sensor7": 554.57, "Sensor19": 100.0 }
Selecione Rota de teste. Se o teste for bem-sucedido, você verá "A mensagem correspondeu à consulta".
Selecione Guardar.
Configurar o carregamento de ficheiros
Configure o recurso de carregamento de arquivos do Hub IoT para permitir que o módulo de gravador de arquivos carregue arquivos para o armazenamento.
No menu do painel esquerdo do Hub IoT, em Configurações do Hub, escolha Carregamento de arquivo.
Selecione Contêiner de Armazenamento do Azure.
Selecione sua conta de armazenamento na lista.
Selecione o contêiner que começa com azureml-blobstore anexado com um guid e clique em Selecionar.
Selecione Guardar. O portal notifica-o quando a gravação estiver concluída.
Nota
Não estamos ativando a notificação de upload para este tutorial, mas consulte Receber uma notificação de upload de arquivo para obter detalhes sobre como lidar com a notificação de upload de arquivo.
Criar, publicar e implantar módulos
Agora que fizemos as alterações de configuração, estamos prontos para criar as imagens e publicá-las em nosso registro de contêiner do Azure. O processo de compilação usa o arquivo deployment.template.json para determinar quais módulos precisam ser construídos. As configurações para cada módulo, incluindo a versão, são encontradas no arquivo module.json na pasta do módulo. O processo de compilação primeiro executa uma compilação do Docker nos Dockerfiles correspondentes à configuração atual encontrada no arquivo module.json para criar uma imagem. Em seguida, ele publica a imagem no registro a partir do arquivo module.json com uma tag de versão correspondente à do arquivo module.json. Finalmente, ele produz um manifesto de implantação específico da configuração (por exemplo, deployment.amd64.json), que implantaremos no dispositivo IoT Edge. O dispositivo IoT Edge lê as informações do manifesto de implantação e, com base nas instruções, baixará os módulos, configurará as rotas e definirá as propriedades desejadas. Esse método de implantação tem dois efeitos colaterais que você deve estar ciente:
Atraso de implantação: como o tempo de execução do IoT Edge deve reconhecer a alteração em suas propriedades desejadas antes de começar a reconfigurar, pode levar algum tempo depois de implantar seus módulos até que o tempo de execução os pegue e comece a atualizar o dispositivo IoT Edge.
As versões do módulo são importantes: se você publicar uma nova versão do contêiner de um módulo no registro do contêiner usando as mesmas tags de versão do módulo anterior, o tempo de execução não baixará a nova versão do módulo. Ele faz uma comparação da tag de versão da imagem local e a imagem desejada do manifesto de implantação. Se essas versões corresponderem, o tempo de execução não executará nenhuma ação. Portanto, é importante incrementar a versão do seu módulo cada vez que você deseja implantar novas alterações. Incremente a versão alterando a propriedade version sob a propriedade tag no arquivo module.json do módulo que você está alterando. Em seguida, crie e publique o módulo.
{ "$schema-version": "0.0.1", "description": "", "image": { "repository": "<your registry>.azurecr.io/avrofilewriter", "tag": { "version": "0.0.1", "platforms": { "amd64": "./Dockerfile.amd64", "amd64.debug": "./Dockerfile.amd64.debug", "arm32v7": "./Dockerfile.arm32v7" } }, "buildOptions": [] }, "language": "python" }
Criar e publicar
Na VM de desenvolvimento, inicie o Docker se ele não estiver em execução.
No Visual Studio Code, inicie um novo terminal com um prompt de comando e faça logon no seu registro de contêiner do Azure (ACR).
Você pode encontrar o nome de usuário, a senha e os valores de servidor de logon necessários no portal do Azure. O nome do registro do contêiner tem o formato "turbofandemo<unique id>". No menu do painel esquerdo, em Configurações, selecione Teclas de acesso para visualizá-las.
docker login -u <ACR username> -p <ACR password> <ACR login server>
- No Visual Studio Code, clique com o botão direito do mouse em deployment.template.json e escolha Build and Push IoT Edge Solution.
Ver módulos no registo
Quando a compilação for concluída com êxito, poderemos usar o portal do Azure para revisar nossos módulos publicados.
Abra o Registro de Contêiner do Azure para este tutorial. O nome do registro do contêiner tem o formato "turbofandemo<unique id>".
No menu do painel esquerdo, em Serviços, selecione Repositórios.
Observe que ambos os módulos que você criou, avrofilewriter e turbofanrouter, aparecem como repositórios.
Selecione turbofanrouter e note que você publicou uma imagem marcada como 0.0.1-amd64.
Implantar módulos no dispositivo IoT Edge
Construímos e configuramos os módulos em nossa solução, agora vamos implantar os módulos no dispositivo IoT Edge.
No Visual Studio Code, clique com o botão direito do mouse no arquivo deployment.amd64.json na pasta config.
Escolha Create Deployment for Single Device (Criar implantação para um único dispositivo).
Escolha seu dispositivo IoT Edge, aaTurboFanEdgeDevice.
Atualize o painel de dispositivos do Hub IoT do Azure no explorador de códigos do Visual Studio. Você deve ver que os três novos módulos estão implantados, mas ainda não estão em execução.
Atualize novamente depois de alguns minutos e você verá os módulos em execução.
Nota
Pode levar vários minutos para que os módulos iniciem e se instalem em um estado de funcionamento estável. Durante esse tempo, você pode ver os módulos iniciarem e pararem enquanto tentam estabelecer uma conexão com o módulo do hub IoT Edge.
Diagnóstico de falhas
Nesta seção, compartilhamos algumas técnicas para entender o que deu errado com um módulo ou módulos. Muitas vezes, uma falha pode ser detetada primeiro a partir do status no código do Visual Studio.
Identificar módulos com falha
Visual Studio Code: examine o painel de dispositivos do Hub IoT do Azure. Se a maioria dos módulos estiver em um estado de execução, mas um estiver parado, você precisará investigar mais a fundo esse módulo interrompido. Se todos os módulos estiverem em um estado parado por um longo período de tempo, isso também pode indicar falha.
Portal do Azure: Ao navegar até seu hub IoT no portal e, em seguida, encontrar a página de detalhes do dispositivo (em IoT Edge, detalhar seu dispositivo), você pode descobrir que um módulo relatou um erro ou nunca relatou nada ao hub IoT.
Diagnóstico a partir do dispositivo
Ao fazer login no dispositivo IoT Edge (a VM Linux no nosso caso), você pode obter acesso a uma boa quantidade de informações sobre o status de seus módulos. O principal mecanismo que usamos são os comandos do Docker que nos permitem examinar os contêineres e imagens no dispositivo.
Faça login no seu dispositivo IoT Edge:
ssh -l <user>@IoTEdge-<extension>.<region>.cloudapp.azure.com
Liste todos os contêineres em execução. Esperamos ver um contêiner para cada módulo com um nome que corresponda ao módulo. Além disso, este comando lista a imagem exata para o contêiner, incluindo a versão, para que você possa corresponder à sua expectativa. Você também pode listar imagens substituindo "image" por "container" no comando.
sudo docker container ls
Obtenha os logs para um contêiner. Este comando produz tudo o que foi gravado em StdErr e StdOut no contêiner. Este comando funciona para contentores que começaram e depois morreram por algum motivo. Também é útil para entender o que tem acontecido com os contêineres edgeAgent ou edgeHub.
sudo docker container logs <container id>
Inspecione um recipiente. Este comando fornece uma tonelada de informações sobre a imagem. Os dados podem ser filtrados dependendo do que você está procurando. Como exemplo, se você quiser ver se as ligações no avroFileWriter estão corretas, você pode usar o comando:
sudo docker container inspect -f "{{ json .Mounts }}" avroFileWriter | python -m json.tool
Conecte-se a um contêiner em execução. Este comando pode ser útil se você quiser examinar o contêiner enquanto ele está em execução:
sudo docker exec -it avroFileWriter bash
Clean up resources (Limpar recursos)
Este tutorial faz parte de um conjunto onde cada artigo se baseia no trabalho realizado nos anteriores. Aguarde para limpar todos os recursos até concluir o tutorial final.
Próximos passos
Neste artigo, criamos uma solução IoT Edge no Visual Studio Code com três módulos: um classificador, um roteador e um gravador/carregador de arquivos. Configuramos as rotas para permitir que os módulos se comuniquem entre si no dispositivo de borda. Modificamos a configuração do dispositivo de borda e atualizamos os Dockerfiles para instalar dependências e adicionar montagens de ligação aos contêineres dos módulos.
Em seguida, atualizamos a configuração do Hub IoT para rotear nossas mensagens com base no tipo e para lidar com carregamentos de arquivos. Com tudo no lugar, implantamos os módulos no dispositivo IoT Edge e garantimos que os módulos estivessem funcionando corretamente.
Continue para o próximo artigo para começar a enviar dados e ver sua solução em ação.