Tutorial: Criar e implantar módulos do IoT Edge personalizados
Aplica-se a: IoT Edge 1.1
Importante
IoT Edge 1.1 a 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 Atualizar o IoT Edge.
Neste artigo, criamos três módulos IoT Edge que recebem mensagens de dispositivos IoT downstream, executam os dados por meio de seu modelo de aprendizado de máquina e encaminham insights para o Hub IoT.
O hub do IoT Edge facilita a comunicação de módulo para módulo. Usar o hub do IoT Edge como um agente de mensagem mantém os módulos independentes uns dos outros. Os módulos precisam apenas especificar as entradas nas quais eles aceitam mensagens e as saídas nas quais eles gravam mensagens.
Queremos que o dispositivo IoT Edge realize quatro coisas para nós:
- Receber dados dos dispositivos de downstream.
- Prever a RUL (vida útil restante) do dispositivo que enviou os dados.
- Enviar uma mensagem com o RUL do dispositivo para o Hub IoT. Essa função poderia ser modificada para enviar dados somente se o RUL chegasse a um valor inferior a um nível especificado.
- Salve os dados do dispositivo de downstream em um arquivo local no dispositivo IoT Edge. Esse arquivo de dados é carregado periodicamente para o Hub IoT para refinar o treinamento do modelo de machine learning. Usar o upload de arquivos em vez do streaming de mensagens constantes é mais econômico.
Para realizar essas tarefas, usamos três módulos personalizados:
Classificador de RUL: o módulo turboFanRulClassifier criado em Treinar e implantar um modelo do Azure Machine Learning é um módulo de machine learning padrão, que expõe uma entrada chamada “amlInput” e uma saída chamada “amlOutput”. O "amlInput" espera que sua entrada tenha a aparência exata da entrada que enviamos para o serviço Web baseado em ACI. Da mesma forma, "amlOutput" retorna os mesmos dados que o serviço Web.
Gravador Avro: este módulo recebe mensagens na entrada “avroModuleInput” e persiste a mensagem no formato Avro em disco para upload posterior para o Hub IoT.
Módulo do Roteador: o módulo do roteador recebe mensagens de dispositivos de downstream, formata e envia as mensagens para o classificador. O módulo recebe as mensagens do classificador e encaminha a mensagem para o módulo do gravador Avro. Finalmente, o módulo envia apenas a previsão da RUL para o Hub IoT.
Entradas:
- deviceInput: recebe mensagens de dispositivos de downstream
- rulInput: recebe mensagens do "amlOutput"
Saídas:
- classify: envia mensagens para "amlInput"
- writeAvro: envia mensagens para "avroModuleInput"
- toIotHub: envia mensagens para $upstream, que as passa para o Hub IoT conectado
O seguinte diagrama mostra os módulos, as entradas, as saídas e as rotas do hub do IoT Edge para a solução completa:
As etapas deste artigo normalmente são realizadas por um desenvolvedor de nuvem.
Nesta seção do tutorial, você aprenderá a:
- Criar um módulo do IoT Edge com base em um código personalizado.
- Gerar uma imagem do Docker com base no módulo personalizado.
- Reconfigurar o roteamento do hub IoT para dar suporte aos módulos personalizados.
- Criar, publicar e implantar seus módulos personalizados.
Pré-requisitos
Este artigo faz parte de uma série para um tutorial sobre como usar o Azure Machine Learning no IoT Edge. Cada artigo da série se baseia no trabalho do artigo anterior. Se você chegou a este artigo diretamente, acesse o primeiro artigo da série.
Criar uma solução do IoT Edge
Durante a execução do segundo dos nossos dois Azure Notebooks, criamos e publicamos uma imagem de contêiner que contém nosso modelo de RUL. O Azure Machine Learning, como parte do processo de criação da imagem, empacotou esse modelo para tornar a imagem implantável como um módulo do Azure IoT Edge.
Nesta etapa, criaremos uma solução do Azure IoT Edge usando o módulo do "Azure Machine Learning" e apontaremos o módulo para a imagem que publicamos usando o Azure Notebooks.
Abra uma sessão da Área de Trabalho Remota na 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 do IoT Edge.
Aceite o nome da solução padrão EdgeSolution.
Escolha o Azure Machine Learning como o modelo de módulo.
Dê ao módulo o nome turbofanRulClassifier.
Escolha o Workspace do Machine Learning. Esse é o workspace do turboFanDemo que você criou em Tutorial: Treinar e implantar um modelo do Azure Machine Learning
Selecione a imagem criada ao executar o Azure Notebook.
Examine a solução e observe os arquivos que foram criados:
deployment.template.json: esse arquivo contém a definição de cada um dos módulos na solução. Há três seções às quais você deve prestar atenção neste arquivo:
Credenciais de Registro: define o conjunto de registros de contêiner personalizados que você está usando em sua solução. Agora, ele deve conter o Registro do Workspace do Machine Learning, que é o local em que sua imagem do Azure Machine Learning foi armazenada. É possível 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 registro de contêiner. Conforme adicionamos mais módulos à solução, eles serão exibidos nesta seção.
"modules": { "turbofanRulClassifier": { "version": "1.0", "type": "docker", "status": "running", "restartPolicy": "always", "settings": { "image": "turbofandemo2cd74296.azurecr.io/edgemlsample:1", "createOptions": {} } } }
Rotas: trabalharemos um pouco com rotas neste tutorial. As rotas definem como os módulos se comunicam uns com os outros. A rota existente definida pelo modelo não corresponde ao roteamento de que precisamos. Exclua a rota
turbofanRulClassifierToIoTHub
."$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 de deployment.template.json. Normalmente, devemos manter esse arquivo sincronizado com o conteúdo do arquivo deployment.template.json, mas isso não é necessário neste tutorial.
.env: é neste arquivo que você deve fornecer o nome de usuário e a senha para acessar seu Registro.
CONTAINER_REGISTRY_USERNAME_<your registry name>=<ACR username> CONTAINER_REGISTRY_PASSWORD_<your registry name>=<ACR password>
Observação
Este tutorial usa as credenciais de logon do administrador do Registro de Contêiner do Azure, que são convenientes para cenários de desenvolvimento e teste. Se você está 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, confira Gerenciar o acesso ao registro de contêiner.
Clique com o botão direito do mouse no arquivo deployment.template.json no explorador do Visual Studio Code 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 Roteador
Em seguida, adicionaremos o módulo Roteador à nossa solução. O módulo Roteador lida com várias responsabilidades para a nossa solução:
- Receber mensagens de dispositivos de downstream: à medida que as mensagens chegam ao dispositivo IoT Edge de dispositivos de downstream, o módulo do Roteador recebe a mensagem e começa a orquestrar o roteamento da mensagem.
- Enviar mensagens para o módulo Classificador de RUL: quando uma nova mensagem é recebida de um dispositivo downstream, o módulo Roteador transforma a mensagem no formato que o classificador de RUL espera. O Roteador envia a mensagem para o Classificador de RUL para uma previsão de RUL. Depois que o classificador fizer uma previsão, ele enviará a mensagem de volta para o módulo Roteador.
- Enviar mensagens de RUL para o Hub IoT: quando o Roteador recebe mensagens do classificador, ele transforma a mensagem para conter somente as informações essenciais, a ID e a RUL do dispositivo e envia a mensagem abreviada para o hub IoT. Um ajuste adicional, que não fizemos aqui, enviaria mensagens para o Hub IoT somente quando a previsão de RUL ficasse abaixo de um limite (por exemplo, quando a RUL for menor que 100 ciclos). Filtrar dessa maneira reduziria o volume de mensagens e o custo do hub IoT.
- Enviar mensagem para o módulo Gravador Avro: para preservar todos os dados enviados pelo dispositivo downstream, o módulo Roteador envia toda a mensagem recebida do classificador para o módulo Gravador Avro, que persistirá e fará upload dos dados usando o upload de arquivos do Hub IoT.
O módulo Roteador é uma parte importante da solução, que garante que as mensagens sejam processadas na ordem correta.
Criar o módulo e copiar os arquivos
Clique com o botão direito do mouse na pasta de módulos no Visual Studio Code e escolha Adicionar módulo do IoT Edge.
Escolha Módulo C# como o modelo de módulo.
Dê ao módulo o nome turbofanRouter.
Quando solicitado para seu Repositório de Imagens do Docker, use o Registro do Workspace do Machine Learning (é possível localizar o Registro no nó registryCredentials do seu arquivo deployment.template.json). Esse valor é o endereço totalmente qualificado para o Registro, como <seu Registro>.azurecr.io/turbofanrouter.
Observação
Neste artigo, usamos o Registro de Contêiner do Azure criado pelo Workspace do Azure Machine Learning. Isso destina-se meramente para sua conveniência. Poderíamos ter criado um 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.
Criar módulo do roteador
No Visual Studio Code, selecione Terminal>Configurar Tarefa de Build Padrão.
Selecione Criar arquivo tasks.json com base em modelo.
Selecione .NET Core.
Substitua o conteúdo do arquivo 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 o tasks.json.
Execute o build com
Ctrl + Shift + B
ou Terminal>Executar tarefa de build.
Configurar rotas de módulo
Conforme mencionado acima, o runtime do IoT Edge usa rotas configuradas no arquivo deployment.template.json para gerenciar a comunicação entre módulos fracamente acoplados. Nesta seção, analisaremos detalhadamente como configurar as rotas para o módulo turbofanRouter. Abordaremos as rotas de entrada primeiro e, em seguida, passaremos para 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 de downstream para esta entrada. No arquivo deployment.template.json, adicione uma rota que informa o hub de borda para rotear qualquer mensagem recebida pelo dispositivo IoT Edge que não foi enviada por um módulo do IoT Edge na 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\")"
outputs
Adicione mais quatro rotas ao parâmetro de rota $edgeHub para lidar com saídas do módulo Roteador.
Program.cs define o método SendMessageToClassifier(), que usa o cliente de módulo para enviar uma mensagem ao classificador de RUL usando a rota:
"routerToClassifier": "FROM /messages/modules/turbofanRouter/outputs/classOutput INTO BrokeredEndpoint(\"/modules/turbofanRulClassifier/inputs/amlInput\")"
SendRulMessageToIotHub() usa o cliente de módulo para enviar apenas os dados de RUL do dispositivo para o Hub IoT por meio da rota:
"routerToIoTHub": "FROM /messages/modules/turboFanRouter/outputs/hubOutput INTO $upstream"
SendMessageToAvroWriter() usa o cliente de módulo para enviar a mensagem com os dados de 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 no Hub IoT em que elas podem ser roteadas futuramente.
"deadLetter": "FROM /messages/modules/turboFanRouter/outputs/deadMessages INTO $upstream"
Com todas as rotas usadas juntas, o nó "$edgeHub" deve ser semelhante ao 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
}
}
}
Observação
Adicionar o módulo turbofanRouter criava 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 Gravador Avro
O módulo Gravador Avro tem duas responsabilidades em nossa solução, armazenar mensagens e fazer upload de arquivos.
Armazenar mensagens: quando o módulo Gravador Avro recebe uma mensagem, ele grava a mensagem no sistema de arquivos local em formato Avro. Usamos uma montagem associada, que monta um diretório (nesse caso /data/avrofiles) em um caminho no contêiner do módulo. Essa montagem permite que o módulo seja gravado em um caminho local (/avrofiles) e que você faça esses arquivos serem acessíveis diretamente do dispositivo IoT Edge.
Fazer upload de arquivos: o módulo Gravador Avro usa o recurso de upload de arquivos do Hub IoT do Azure para fazer upload de arquivos em uma conta de armazenamento do Azure. Depois 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 Exibição>Paleta de Comandos e pesquise e escolha Python: selecionar interpretador.
Selecione seu Python versão 3.7 ou posterior instalado.
Clique com o botão direito do mouse na pasta de módulos no Visual Studio Code e escolha Adicionar módulo do IoT Edge.
Escolha Módulo de Python.
Nomeie o módulo
avroFileWriter
.Quando solicitado para seu Repositório de Imagens do Docker, use o mesmo Registro que você usou ao adicionar o módulo Roteador.
Copie arquivos de exemplo de módulo 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 que main.py foi atualizado.
Observação
Quando você abre um arquivo Python, talvez precise instalar pylint. Não é necessário instalar o linter para concluir este tutorial.
Montagem associada para arquivos de dados
Como já mencionado, o módulo de gravador depende da presença de uma montagem associada para gravar arquivos do Avro no sistema de arquivos do dispositivo.
Adicionar diretório ao dispositivo
No portal do Azure, inicie a VM do dispositivo do IoT Edge se ela não estiver em execução. Conecte-se a ela 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 conterá as mensagens de dispositivo de downstream salvas.
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
Valide se o diretório agora tem a permissão w (gravação) para o usuário, o grupo e o proprietário.
ls -la /data
Adicionar o 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. Neste artigo, concentre-se apenas em Dockerfile.amd64.
Em sua VM de desenvolvimento, abra o arquivo C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avoFileWriter\Dockerfile.amd64.
Modifique o arquivo para que ele tenha a aparência do seguinte exemplo:
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 comandos
mkdir
echown
instruem o processo de build do Docker a criar um diretório de nível superior chamado /avrofiles na imagem e, em seguida, a tornar o moduleuser o proprietário desse diretório. É importante que esses comandos sejam inseridos depois que o usuário do módulo for adicionado à imagem com o comandouseradd
e antes que o contexto alterne para o moduleuser (moduleuser USER).Se necessário, faça as alterações correspondentes em Dockerfile.amd64.debug e Dockerfile.arm32v7.
Adicionar configuração de associaçã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 associação.
Abra deployment.template.json.
Modifique a definição de módulo do avroFileWriter adicionando o parâmetro
Binds
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" ] } } } }
Montagem associada para acesso a config.yaml
É necessário adicionar mais uma associação para o módulo de gravador. Essa associação fornece ao módulo acesso para ler a cadeia de conexão do arquivo /etc/iotedge/config.yaml no dispositivo IoT Edge. É necessário que a cadeia de conexão crie um IoTHubClient para podermos chamar o método upload_blob_async para fazer upload de arquivos para o hub IoT. As etapas para adicionar essa associaçã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 foram 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
Em seu computador de desenvolvimento, abra o arquivo Dockerfile.amd64.
Adicione um conjunto adicional de comandos
mkdir
echown
ao arquivo para que ele tenha a seguinte aparência: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 de módulo de avroFileWriter adicionando uma segunda linha ao parâmetro
Binds
que aponta o diretório de contêiner (/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 de gravador usa uma dependência em duas bibliotecas Python, fastavro e PyYAML. É necessário instalar as dependências no computador de desenvolvimento e instruir o processo de build do Docker para instalá-las na imagem do módulo.
PyYAML
No computador de desenvolvimento, abra o arquivo
C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avoFileWriter\requirements.txt
e adicione "pyyaml" a uma nova linha no arquivo.azure-iothub-device-client~=1.4.3 pyyaml
Abra o arquivo Dockerfile.amd64 e adicione um comando
pip install
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 o pyyaml em seu computador 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 em seu computador de desenvolvimento.
pip install fastavro
Reconfigurar Hub IoT
Introduzindo o dispositivo e os módulos do IoT Edge no sistema, mudamos nossas expectativas sobre quais dados serão enviados ao hub e para qual finalidade. É necessário reconfigurar o roteamento no hub para lidar com nossa nova realidade.
Observação
Reconfiguramos o hub antes de implantar módulos, porque algumas configurações do hub, principalmente o upload de arquivo, precisam ser corretamente definidas para o módulo avroFileWriter ser executado devidamente
Configurar rota para mensagens RUL no Hub IoT
Com o roteador e o classificador em vigor, esperamos receber mensagens granulares que contêm apenas a identificação do dispositivo e a previsão de RUL dele. Gostaríamos de rotear os dados de RUL para sua própria localização de armazenamento no qual podemos monitorar o status dos dispositivos, criar relatórios e disparar alertas, conforme necessário. Ao mesmo tempo, queremos que todos os dados do dispositivo que ainda estejam sendo enviados diretamente por um dispositivo de downstream que ainda não tenha sido anexado ao nosso dispositivo IoT Edge continuem a ser roteados para o local de armazenamento atual.
Criar uma rota de mensagem RUL
No portal do Azure, navegue até o Hub IoT.
No menu do painel esquerdo, em Configurações do hub, selecione Roteamento de mensagem.
Na guia Rotas, selecione Adicionar.
Dê a rota o nome RulMessageRoute.
Selecione Adicionar ponto de extremidade ao lado do seletor Ponto de extremidade e escolha Armazenamento.
Na página Adicionar um ponto de extremidade de armazenamento, dê ao ponto de extremidade o nome ruldata.
Selecione Escolher um contêiner.
Na página Contas de armazenamento, localize a conta de armazenamento que você está usando em todo este tutorial, que tem um nome semelhante ao 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 Consulta de 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 Testar rota. Se o teste for bem-sucedido, você verá "A mensagem correspondeu à consulta".
Clique em Save (Salvar).
Atualize a rota turbofanDeviceDataToStorage
Não convém rotear os novos dados de previsão para nossa antiga localização de armazenamento; portanto, atualize a rota para impedir isso.
Na página Roteamento de mensagens do Hub IoT, selecione a guia Rotas.
Selecione turbofanDeviceDataToStorage ou qualquer nome que você tenha dado à sua rota inicial de dados do dispositivo.
Atualizar 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 Testar rota. Se o teste for bem-sucedido, você verá "A mensagem correspondeu à consulta".
Clique em Salvar.
Configurar o upload de arquivo
Configure o recurso de upload de arquivo do Hub IoT para permitir que o módulo de gravador de arquivos faça upload dos arquivos no armazenamento.
No menu do painel esquerdo do Hub IoT, em Configurações do hub, escolha Upload 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 acrescentado a um GUID e clique em Selecionar.
Clique em Salvar. O portal notificará você quando o salvamento for concluído.
Observação
Não ativaremos a notificação de upload para este tutorial, mas confira Receber uma notificação de upload de arquivo para obter detalhes sobre como manipular 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 no Registro de Contêiner do Azure. O processo de build usa o arquivo deployment.template.json para determinar quais módulos precisam ser criados. As configurações de cada módulo, incluindo a versão, são encontradas no arquivo module.json na pasta do módulo. O processo de build executa um build do Docker primeiro no Dockerfiles que corresponde à configuração atual encontrada no arquivo module.json para criar uma imagem. Em seguida, ele publica a imagem no Registro do arquivo module.json com uma tag de versão que corresponde ao arquivo module.json. Por fim, ele produz um manifesto de implantação específico de configuração (por exemplo, deployment.amd64.json), que implantaremos no dispositivo IoT Edge. O dispositivo IoT Edge lê as informações no manifesto de implantação e, com base nas instruções, baixará os módulos, configurará as rotas e definirá propriedades desejadas. Esse método de implantação tem dois efeitos colaterais aos quais você deve estar atento:
Atraso na implantação: como o runtime do IoT Edge deve reconhecer a alteração em suas propriedades desejadas antes do começo da reconfiguração, pode levar algum tempo após você implantar seus módulos até que o runtime os selecione e inicie a atualização do dispositivo IoT Edge.
As versões do módulo importam: se você publicar uma nova versão do contêiner de um módulo no registro de contêiner usando as mesmas marcas de versão que o módulo anterior, o runtime não baixará a nova versão do módulo. Ele faz uma comparação da tag de versão da imagem local e da imagem desejada do manifesto de implantação. Se essas versões coincidirem, o runtime não executará nenhuma ação. Portanto, será importante incrementar a versão do seu módulo sempre que você desejar implantar novas alterações. Incremente a versão alterando a propriedade version na propriedade tag no arquivo module.json para o 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
Em sua 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 ACR (Registro de Contêiner do Azure).
Você pode encontrar os valores de nome de usuário, senha e servidor de logon necessários no portal do Azure. O nome do registro de contêiner tem o formato "turbofandemo< unique ID>". No menu do painel esquerdo, em Configurações, selecione Chaves de acesso para exibi-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 Criar e Efetuar Push da Solução IoT Edge.
Exibir módulos no Registro
Quando o build for concluído com sucesso, poderemos usar o portal do Azure para examinar nossos módulos publicados.
Abra o Registro de Contêiner do Azure para este tutorial. O nome do registro de contêiner tem o formato "turbofandemo< unique ID>".
No menu do painel esquerdo, em Serviços, selecione Repositórios.
Observe que os dois módulos criados, avrofilewriter e turbofanrouter, são exibidos como repositórios.
Selecione turbofanrouter e observe que você publicou uma imagem marcada como 0.0.1-amd64.
Implantar módulos no dispositivo IoT Edge
Criamos e configuramos os módulos em nossa solução. Agora, nós os implantaremos no dispositivo IoT Edge.
No Visual Studio Code, clique com o botão direito do mouse no arquivo deployment.amd64.json na pasta de configuração.
Escolha Criar implantação para dispositivo único.
Escolha seu dispositivo IoT Edge, aaTurboFanEdgeDevice.
Atualize o painel de dispositivos do Hub IoT do Azure no explorador do Visual Studio Code. Você deverá ver que os três novos módulos são implantados, mas ainda não estão em execução.
Atualize novamente após alguns minutos e você verá os módulos em execução.
Observação
Pode levar vários minutos para os módulos iniciarem e se estabilizarem em um estado de execução. Durante esse tempo, você pode ver os módulos iniciarem e pararem conforme eles tentam estabelecer uma conexão com o módulo de hub do IoT Edge.
Diagnosticar falhas
Nesta seção, compartilhamos algumas técnicas para entender o que deu errado com um módulo ou módulos. Geralmente, uma falha pode ser identificada primeiro no status no Visual Studio Code.
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 deles for interrompido, será necessário investigar esse módulo interrompido mais a fundo. Se todos os módulos estiverem em um estado interrompido por um longo período de tempo, isso poderá indicar uma falha também.
Portal do Azure: navegando até seu hub IoT no portal e, em seguida, localizando a página de detalhes do dispositivo (em IoT Edge, analisar seu dispositivo) você pode constatar que um módulo relatou um erro ou que nunca reportou nada para o hub IoT.
Diagnosticar com base no dispositivo
Ao fazer logon no dispositivo do IoT Edge (em nosso caso, a VM do Linux), é possível obter acesso a uma boa dose de informações sobre o status dos seus módulos. O principal mecanismo que usamos são os comandos do Docker que nos permitem examinar os contêineres e as imagens no dispositivo.
Faça logon no dispositivo do 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 corresponde ao módulo. Além disso, esse comando lista a imagem exata do contêiner, incluindo a versão, para que você possa atender às suas expectativas. Também é possível listar imagens substituindo "image" por "container" no comando.
sudo docker container ls
Obtenha os logs de um contêiner. Este comando gera tudo o que foi escrito para StdErr e StdOut no contêiner. Esse comando funciona para contêineres que iniciaram e pararam por algum motivo. Também é útil para entender o que estava acontecendo com os contêineres edgeAgent e edgeHub.
sudo docker container logs <container id>
Inspecione um contêiner. Esse comando oferece milhares de informações sobre a imagem. Os dados podem ser filtrados dependendo do que você está procurando. Como exemplo, se desejar ver se as associações no avroFileWriter estão corretas, é possível 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 poderá ser útil se você desejar examinar o contêiner enquanto ele estiver em execução:
sudo docker exec -it avroFileWriter bash
Limpar recursos
Este tutorial faz parte de um conjunto em que cada artigo se baseia no trabalho feito nos anteriores. Aguarde para limpar todos os recursos até concluir o tutorial final.
Próximas etapas
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 associadas aos contêineres de módulos.
Em seguida, atualizamos a configuração do Hub IoT para rotear nossas mensagens com base no tipo e para lidar com uploads de arquivo. Com tudo em vigor, implantamos os módulos no dispositivo IoT Edge e verificamos se os módulos estavam sendo executados corretamente.
Passe para o próximo artigo para começar a enviar dados e ver sua solução em ação.