Partilhar via


Tutorial: Criar e implementar módulos de IoT Edge personalizados

Aplica-se a:sim ícone IoT Edge 1.1

Importante

IoT Edge 1,1 data de fim do suporte 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 IoT Edge.

Neste artigo, criamos três módulos IoT Edge que recebem mensagens de dispositivos IoT a jusante, executamos os dados através do modelo de machine learning e, em seguida, reencaminhamos informações para Hub IoT.

IoT Edge hub facilita a comunicação do módulo para o módulo. A utilização do hub IoT Edge como mediador de mensagens mantém os módulos independentes uns dos outros. Os módulos só precisam de especificar as entradas nas quais aceitam mensagens e as saídas para as quais escrevem mensagens.

Queremos que o dispositivo IoT Edge consiga quatro coisas para nós:

  • Receber dados dos dispositivos a jusante.
  • Prever a vida útil restante (RUL) para o dispositivo que enviou os dados.
  • Envie uma mensagem com a RUL do dispositivo para Hub IoT. Esta função só pode ser modificada para enviar dados se a RUL ficar abaixo de um nível especificado.
  • Guarde os dados do dispositivo a jusante num ficheiro local no dispositivo IoT Edge. Este ficheiro de dados é carregado periodicamente para Hub IoT para refinar a preparação do modelo de machine learning. Utilizar o carregamento de ficheiros em vez da transmissão em fluxo de mensagens constante é mais rentável.

Para realizar estas tarefas, utilizamos três módulos personalizados:

  • Classificador RUL: O módulo turboFanRulClassifier que criámos em Preparar e implementar 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 a sua entrada se pareça exatamente com a entrada que enviámos para o serviço Web baseado na ACI. Da mesma forma, "amlOutput" devolve os mesmos dados que o serviço Web.

  • Escritor Avro: Este módulo recebe mensagens na entrada "avroModuleInput" e persiste a mensagem no formato Avro para o disco para carregamento posterior para Hub IoT.

  • Módulo router: O módulo router recebe mensagens de dispositivos a jusante e, em seguida, formata e envia as mensagens para o classificador. Em seguida, o módulo recebe as mensagens do classificador e reencaminha a mensagem para o módulo de escritor Avro. Por fim, o módulo envia apenas a predição de RUL para o Hub IoT.

    • Entradas:

      • deviceInput: recebe mensagens de dispositivos a jusante
      • rulInput: recebe mensagens do "amlOutput"
    • Saídas:

      • classificar: envia mensagens para "amlInput"
      • writeAvro: envia mensagens para "avroModuleInput"
      • toIotHub: envia mensagens para $upstream, que transmite as mensagens para o Hub IoT ligado

O diagrama seguinte mostra os módulos, entradas, saídas e as rotas do Hub IoT Edge para a solução completa:

IoT Edge diagrama de arquitetura de três módulos

Normalmente, os passos neste artigo são executados por um programador da cloud.

Nesta secção do tutorial, irá aprender a:

  • Crie um módulo IoT Edge a partir de código personalizado.
  • Gere uma imagem do Docker a partir do módulo personalizado.
  • Reconfigure Hub IoT encaminhamento para suportar os módulos personalizados.
  • Crie, publique e implemente os módulos personalizados.

Pré-requisitos

Este artigo faz parte de uma série para um tutorial sobre a utilização do Azure Machine Learning no IoT Edge. Cada artigo da série baseia-se no trabalho no artigo anterior. Se chegou diretamente a este artigo, visite o primeiro artigo da série.

Criar uma nova solução de IoT Edge

Durante a execução do segundo dos nossos dois Blocos de Notas do Azure, criámos e publicámos uma imagem de contentor que contém o nosso modelo RUL. O Azure Machine Learning, como parte do processo de criação de imagens, empacotou esse modelo para que a imagem seja implementável como um módulo IoT Edge do Azure.

Neste passo, vamos criar uma solução de IoT Edge do Azure com o módulo "Azure Machine Learning" e apontar o módulo para a imagem que publicámos com o Azure Notebooks.

  1. Abra uma sessão de ambiente de trabalho remoto na VM de desenvolvimento.

  2. Abra a pasta C:\source\IoTEdgeAndMlSample no Visual Studio Code.

  3. Clique com o botão direito do rato no painel do explorador (no espaço em branco) e selecione Nova Solução de IoT Edge.

    Criar nova solução de IoT Edge

  4. Aceite o nome da solução predefinido EdgeSolution.

  5. Selecione Azure Machine Learning como o modelo de módulo.

  6. Dê um nome ao módulo turbofanRulClassifier.

  7. Escolha a área de trabalho de machine learning. Esta área de trabalho é a área de trabalho turboFanDemo que criou no Tutorial: Preparar e implementar um modelo do Azure Machine Learning

  8. Selecione a imagem que criou durante a execução do Bloco de Notas do Azure.

  9. Observe a solução e repare nos ficheiros que foram criados:

    • deployment.template.json: Este ficheiro contém a definição de cada um dos módulos na solução. Existem três secções a ter em atenção neste ficheiro:

      • Credenciais do registo: Define o conjunto de registos de contentores personalizados que está a utilizar na sua solução. Neste momento, deve conter o registo da sua área de trabalho de machine learning, que é onde a sua imagem do Azure Machine Learning foi armazenada. Pode ter qualquer número de registos de contentores, mas, para simplificar, vamos utilizar este registo 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 secção contém o conjunto de módulos definidos pelo utilizador que acompanham esta solução. A definição do módulo turbofanRulClassifier aponta para a imagem no seu registo de contentor. À medida que adicionamos mais módulos à solução, estes serão apresentados nesta secçã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 comunicam entre si. A rota existente definida pelo modelo não corresponde ao encaminhamento de que precisamos. Elimine 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 ficheiro é a versão de depuração de deployment.template.json. Normalmente, devemos manter este ficheiro sincronizado com o conteúdo do ficheiro deployment.template.json, mas fazê-lo não é necessário para este tutorial.

    • .env: este ficheiro é onde deve fornecer o nome de utilizador e a palavra-passe para aceder ao seu registo.

      CONTAINER_REGISTRY_USERNAME_<your registry name>=<ACR username>
      CONTAINER_REGISTRY_PASSWORD_<your registry name>=<ACR password>
      

      Nota

      Este tutorial utiliza credenciais de início de sessão de administrador para Azure Container Registry, 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 com menos privilégios, como principais de serviço. Para obter mais informações, veja Gerir o acesso ao seu registo de contentor.

  10. Clique com o botão direito do rato no ficheiro deployment.template.json no explorador do Visual Studio Code e selecione Compilar IoT Edge Solução.

  11. Tenha em atenção que este comando cria uma pasta de configuração com um ficheiro deployment.amd64.json. Este ficheiro é o modelo de implementação concreto da solução.

Módulo Adicionar Router

Em seguida, adicionamos o módulo Router à nossa solução. O módulo Router processa várias responsabilidades para a nossa solução:

  • Receber mensagens de dispositivos a jusante: à medida que as mensagens chegam ao dispositivo IoT Edge a partir de dispositivos a jusante, o módulo Router recebe a mensagem e começa a orquestrar o encaminhamento da mensagem.
  • Enviar mensagens para o módulo Classificador de RUL: quando uma nova mensagem é recebida de um dispositivo a jusante, o módulo Router transforma a mensagem no formato esperado pelo Classificador de RUL. O Router envia a mensagem para o Classificador de RUL para uma predição de RUL. Assim que o classificador tiver feito uma predição, envia a mensagem de volta para o módulo Router.
  • Enviar mensagens RUL para Hub IoT: quando o Router recebe mensagens do classificador, transforma a mensagem para conter apenas as informações essenciais, o ID do dispositivo e a RUL, e envia a mensagem abreviada para o hub IoT. Um novo refinamento, que não fizemos aqui, enviaria mensagens para o Hub IoT apenas quando a predição de RUL ficar abaixo de um limiar (por exemplo, quando a RUL é inferior a 100 ciclos). A filtragem desta forma reduziria o volume de mensagens e reduziria o custo do hub IoT.
  • Envie uma mensagem para o módulo Avro Writer: para preservar todos os dados enviados pelo dispositivo a jusante, o módulo Router envia toda a mensagem recebida do classificador para o módulo Avro Writer, que irá manter e carregar os dados com Hub IoT carregamento de ficheiros.

O módulo Router é uma parte importante da solução que garante que as mensagens são processadas pela ordem correta.

Criar o módulo e copiar ficheiros

  1. Clique com o botão direito do rato na pasta módulos no Visual Studio Code e selecione Adicionar IoT Edge Módulo.

  2. Selecione o módulo C# para o modelo de módulo.

  3. Dê um nome ao módulo turbofanRouter.

  4. Quando lhe for pedido o Repositório de Imagens do Docker, utilize o registo da área de trabalho de machine learning (pode encontrar o registo no nó registryCredentials do ficheiro deployment.template.json ). Este valor é o endereço completamente qualificado para o registo, como <o registry.azurecr.io/turbofanrouter>.

    Nota

    Neste artigo, utilizamos o Azure Container Registry que foi criado pela área de trabalho do Azure Machine Learning. Isto é apenas por conveniência. Poderíamos ter criado um novo registo de contentor e publicado os nossos módulos lá.

  5. No Terminal com uma shell de linha de comandos, copie os ficheiros do módulo de exemplo para a solução.

    copy c:\source\IoTEdgeAndMlSample\EdgeModules\modules\turbofanRouter\*.cs c:\source\IoTEdgeAndMlSample\EdgeSolution\modules\turbofanRouter\
    
  6. Aceite o pedido para substituir o ficheiro program.cs.

Módulo de router de compilação

  1. No Visual Studio Code, selecione Configurar Terminal>Tarefa de Compilação Predefinida.

  2. Selecione Criar ficheiro tasks.json a partir do modelo.

  3. Selecione .NET Core.

  4. Substitua o conteúdo de tasks.json pelo seguinte código.

    {
      "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"
        }
      ]
    }
    
  5. Guarde e feche tasks.json.

  6. Execute a compilação com Ctrl + Shift + B ou aTarefa de Compilação executarterminal>.

Configurar rotas de módulos

Conforme mencionado acima, o IoT Edge runtime utiliza rotas configuradas no ficheiro deployment.template.json para gerir a comunicação entre módulos vagamente acoplados. Nesta secção, vamos analisar como configurar as rotas para o módulo turbofanRouter. Vamos abordar primeiro as rotas de entrada e, em seguida, avançar para as saídas.

Entradas

  1. No método Init() de Program.cs, registamos duas chamadas de retorno para o módulo:

    await ioTHubModuleClient.SetInputMessageHandlerAsync(EndpointNames.FromLeafDevice, LeafDeviceInputMessageHandler, ioTHubModuleClient);
    await ioTHubModuleClient.SetInputMessageHandlerAsync(EndpointNames.FromClassifier, ClassifierCallbackMessageHandler, ioTHubModuleClient);
    
  2. A primeira chamada de retorno escuta as mensagens enviadas para o sink deviceInput . No diagrama acima, vemos que queremos encaminhar mensagens de qualquer dispositivo a jusante para esta entrada. No ficheiro deployment.template.json, adicione uma rota que informa o hub edge para encaminhar qualquer mensagem recebida pelo dispositivo IoT Edge que não foi enviado por um módulo de IoT Edge para a entrada denominada "deviceInput" no módulo turbofanRouter:

    "leafMessagesToRouter": "FROM /messages/* WHERE NOT IS_DEFINED($connectionModuleId) INTO BrokeredEndpoint(\"/modules/turbofanRouter/inputs/deviceInput\")"
    
  3. 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 de rota $edgeHub, para processar saídas do módulo Router.

  1. Program.cs define o método SendMessageToClassifier(), que utiliza o cliente do módulo para enviar uma mensagem para o classificador RUL com a rota:

    "routerToClassifier": "FROM /messages/modules/turbofanRouter/outputs/classOutput INTO BrokeredEndpoint(\"/modules/turbofanRulClassifier/inputs/amlInput\")"
    
  2. SendRulMessageToIotHub() utiliza 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"
    
  3. SendMessageToAvroWriter() utiliza 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\")"
    
  4. HandleBadMessage() envia mensagens falhadas a montante a Hub IoT onde podem ser encaminhadas para mais tarde.

    "deadLetter": "FROM /messages/modules/turboFanRouter/outputs/deadMessages INTO $upstream"
    

Com todas as rotas efetuadas em conjunto, o nó "$edgeHub" deve ter um aspeto 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
    }
  }
}

Nota

Adicionar o módulo turbofanRouter criou a seguinte rota adicional: turbofanRouterToIoTHub": "FROM /messages/modules/turbofanRouter/outputs/* INTO $upstream. Remova esta rota, deixando apenas as rotas listadas acima no ficheiro deployment.template.json.

Módulo Adicionar Escritor Avro

O módulo Avro Writer tem duas responsabilidades na nossa solução: armazenar mensagens e carregar ficheiros.

  • Armazenar mensagens: quando o módulo Avro Writer recebe uma mensagem, escreve a mensagem no sistema de ficheiros local no formato Avro. Utilizamos uma montagem de enlace, que monta um diretório (neste caso /data/avrofiles) num caminho no contentor do módulo. Esta montagem permite ao módulo escrever num caminho local (/avrofiles) e ter esses ficheiros acessíveis diretamente a partir do dispositivo IoT Edge.

  • Carregar ficheiros: o módulo Avro Writer utiliza a funcionalidade de carregamento de ficheiros Hub IoT do Azure para carregar ficheiros para uma conta de armazenamento do Azure. Depois de um ficheiro ser carregado com êxito, o módulo elimina o ficheiro do disco

Criar módulo e copiar ficheiros

  1. No Visual Studio Code, selecione Ver>Paleta de Comandos e, em seguida, procure e selecione Python: Selecione Interpretador.

  2. Selecione a versão 3.7 ou posterior do Python instalada.

  3. Clique com o botão direito do rato na pasta módulos no Visual Studio Code e selecione Adicionar IoT Edge Módulo.

  4. Escolha Python Module (Módulo de Python).

  5. Atribua o nome ao módulo avroFileWriter.

  6. Quando lhe for pedido o Repositório de Imagens do Docker, utilize o mesmo registo que utilizou ao adicionar o módulo Router.

  7. Copie ficheiros do módulo de exemplo para a solução.

    copy C:\source\IoTEdgeAndMlSample\EdgeModules\modules\avroFileWriter\*.py C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avroFileWriter\
    
  8. Aceite a substituição de main.py.

  9. Repare que foram adicionados filemanager.py e schema.py à solução e main.py foi atualizado.

Nota

Quando abre um ficheiro Python, poderá ser-lhe pedido para instalar o pylint. Não precisa de instalar o linter para concluir este tutorial.

Enlace de montagem para ficheiros de dados

Conforme mencionado anteriormente, o módulo de escritor baseia-se na presença de uma montagem de enlace para escrever ficheiros Avro no sistema de ficheiros do dispositivo.

Adicionar diretório ao dispositivo

  1. Na portal do Azure, inicie a VM do dispositivo IoT Edge se não estiver em execução. Ligue-se ao mesmo através de SSH. A ligação requer o nome DNS que pode copiar a partir da página de descrição geral da VM no portal do Azure.

    ssh -l <user>@<vm name>.<region>.cloudapp.azure.com
    
  2. Depois de iniciar sessão, crie o diretório que irá conter as mensagens guardadas a jusante do dispositivo.

    sudo mkdir -p /data/avrofiles
    
  3. Atualize as permissões de diretório para torná-lo gravável pelo contentor.

    sudo chmod ugo+rw /data/avrofiles
    
  4. Valide se o diretório tem agora permissão de escrita (w) para utilizador, grupo e proprietário.

    ls -la /data
    

    Permissões de diretórios para avrofiles

Adicionar diretório ao módulo

Para adicionar o diretório ao contentor do módulo, vamos modificar os Dockerfiles associados ao módulo avroFileWriter. Existem três Dockerfiles associados ao módulo: Dockerfile.amd64, Dockerfile.amd64.debug e Dockerfile.arm32v7. Estes ficheiros devem ser mantidos sincronizados caso pretendamos depurar ou implementar num dispositivo arm32. Para este artigo, concentre-se apenas no Dockerfile.amd64.

  1. Na VM de desenvolvimento, abra o ficheiro C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avoFileWriter\Dockerfile.amd64 .

  2. Modifique o ficheiro para que tenha um aspeto semelhante ao 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 mkdir comandos e chown instruem o processo de compilação do Docker para criar um diretório de nível superior chamado /avrofiles na imagem e, em seguida, para tornar o módulo proprietário desse diretório. É importante que estes comandos sejam inseridos após o utilizador do módulo ser adicionado à imagem com o useradd comando e antes de o contexto mudar para o móduloutilizador (módulo USER).

  3. Se necessário, faça as alterações correspondentes a Dockerfile.amd64.debug e Dockerfile.arm32v7.

Adicionar configuração de enlace ao avroFileWriter

O passo final da criação do enlace é atualizar os ficheiros deployment.template.json (e deployment.debug.template.json) com as informações de enlace.

  1. Abra deployment.template.json.

  2. Modifique a definição do módulo para avroFileWriter ao adicionar o Binds parâmetro que aponta o diretório de contentor /avrofiles para o diretório local no dispositivo edge. A definição do 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"
            ]
          }
        }
      }
    }
    

Enlace de montagem para acesso a config.yaml

Temos de adicionar mais um enlace para o módulo de escritor. Este enlace dá ao módulo acesso para ler a cadeia de ligação a partir do ficheiro /etc/iotedge/config.yaml no dispositivo IoT Edge. Precisamos da cadeia de ligação para criar um IoTHubClient para que possamos chamar o método upload_blob_async para carregar ficheiros para o hub IoT. Os passos para adicionar este enlace são semelhantes aos da secção anterior.

Atualizar permissão de diretório

  1. Ligue-se ao seu dispositivo IoT Edge através de SSH.

    ssh -l <user>@IoTEdge-<extension>.<region>.cloudapp.azure.com
    
  2. Adicione permissão de leitura ao ficheiro config.yaml.

    sudo chmod +r /etc/iotedge/config.yaml
    
  3. Valide se as permissões estão definidas corretamente.

    ls -la /etc/iotedge/
    
  4. Certifique-se de que as permissões para config.yaml são -r-r--r--.

Adicionar diretório ao módulo

  1. No seu computador de desenvolvimento, abra o ficheiro Dockerfile.amd64 .

  2. Adicione um conjunto adicional de mkdir comandos e chown ao ficheiro para que tenha o seguinte aspeto:

    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"]
    
  3. Efetue as alterações correspondentes ao Dockerfile.amd64.debug e ao Dockerfile.arm32v7.

Atualizar a configuração do módulo

  1. Abra o ficheiro deployment.template.json .

  2. Modifique a definição do módulo para avroFileWriter ao adicionar uma segunda linha ao Binds parâmetro que aponta o diretório de contentor (/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"
            ]
          }
        }
      }
    }
    
  3. Efetue as alterações correspondentes a deployment.debug.template.json.

Instalar dependências

O módulo de escritor assume uma dependência em duas bibliotecas Python, fastavro e PyYAML. Precisamos de instalar as dependências no nosso computador de desenvolvimento e instruir o processo de compilação do Docker para instalá-las na imagem do nosso módulo.

PyYAML

  1. No seu computador de desenvolvimento, abra o C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avoFileWriter\requirements.txt ficheiro e adicione "pyyaml" numa nova linha no ficheiro.

    azure-iothub-device-client~=1.4.3
    pyyaml
    
  2. Abra o ficheiro Dockerfile.amd64 e adicione um pip install comando para atualizar as ferramentas de configuração.

    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" ]
    
  3. Numa linha de comandos, instale o pyyaml no seu computador de desenvolvimento.

    pip install pyyaml
    

Fastavro

  1. No requirements.txt, adicione fastavro após pyyaml.

    azure-iothub-device-client~=1.4.3
    pyyaml
    fastavro
    
  2. Instale o fastavro no seu computador de desenvolvimento.

    pip install fastavro
    

Reconfigurar Hub IoT

Ao introduzir o IoT Edge dispositivo e módulos no sistema, alterámos as nossas expectativas sobre que dados serão enviados para o hub e para que finalidade. Temos de reconfigurar o encaminhamento no hub para lidar com a nossa nova realidade.

Nota

Reconfiguramos o hub antes de implementar módulos porque algumas das definições do hub, especificamente o carregamento de ficheiros, têm de ser configuradas corretamente para que o módulo avroFileWriter seja executado corretamente

Configurar a rota para mensagens RUL no Hub IoT

Com o router e o classificador implementados, esperamos receber mensagens regulares que contêm apenas o ID do dispositivo e a predição de RUL para o dispositivo. Queremos encaminhar os dados da RUL para a sua própria localização de armazenamento, onde podemos monitorizar o estado dos dispositivos, criar relatórios e acionar alertas conforme necessário. Ao mesmo tempo, queremos que quaisquer dados do dispositivo que ainda estejam a ser enviados diretamente por um dispositivo a jusante que ainda não tenha sido ligado ao nosso dispositivo IoT Edge continuem a ser encaminhados para a localização de armazenamento atual.

Criar uma rota de mensagens RUL

  1. Na portal do Azure, navegue para a sua Hub IoT.

  2. No menu no painel esquerdo, em Definições do hub, selecione Encaminhamento de mensagens.

  3. No separador Rotas , selecione Adicionar.

  4. Atribua o nome RulMessageRoute à rota.

  5. Selecione Adicionar ponto final à direita do seletor de Ponto Final e selecione Armazenamento.

  6. Na página Adicionar um ponto final de armazenamento , atribua o nome ruldata ao ponto final.

  7. Selecione Escolher um contentor.

  8. Na página Contas de armazenamento, localize a conta de armazenamento que está a utilizar ao longo deste tutorial, que tem o nome de sufixo> exclusivo iotedgeandml<.

  9. Selecione o contentor ruldata e clique em Selecionar.

  10. Novamente na página Adicionar um ponto final de armazenamento , selecione Criar para criar o ponto final de armazenamento.

  11. Novamente na página Adicionar uma rota, na consulta Encaminhamento, substituatrue pela seguinte consulta:

    IS_DEFINED($body.PredictedRul) AND NOT IS_DEFINED($body.OperationalSetting1)
    
  12. Expanda a secção Teste e, em seguida, a secção Corpo da mensagem. Substitua o corpo da mensagem por este exemplo das nossas mensagens esperadas:

    {
      "ConnectionDeviceId": "aaLeafDevice_1",
      "CorrelationId": "b27e97bb-06c5-4553-a064-e9ad59c0fdd3",
      "PredictedRul": 132.62721409309165,
      "CycleTime": 64.0
    }
    
  13. Selecione Testar rota. Se o teste for bem-sucedido, verá "A mensagem correspondeu à consulta".

  14. Clique em Guardar.

Atualizar a rota turbofanDeviceDataToStorage

Não queremos encaminhar os novos dados de predição para a nossa localização de armazenamento antiga, por isso, atualize a rota para a impedir.

  1. Na página encaminhamento de mensagens Hub IoT, selecione o separador Rotas.

  2. Selecione turbofanDeviceDataToStorage ou qualquer nome que tenha dado à rota de dados inicial do dispositivo.

  3. Atualizar a consulta de encaminhamento para

    IS_DEFINED($body.OperationalSetting1)
    
  4. Expanda a secção Teste e, em seguida, a secção Corpo da mensagem. Substitua a mensagem por este exemplo das 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
    }
    
  5. Selecione Testar rota. Se o teste for bem-sucedido, verá "A mensagem correspondeu à consulta".

  6. Selecione Guardar.

Configurar o carregamento de ficheiros

Configure a funcionalidade Hub IoT carregamento de ficheiros para permitir que o módulo de escritor de ficheiros carregue ficheiros para o armazenamento.

  1. No menu do painel esquerdo do Hub IoT, em Definições do hub, selecione Carregamento de ficheiros.

  2. Selecione Contentor de Armazenamento do Azure.

  3. Selecione a sua conta de armazenamento na lista.

  4. Selecione o contentor que começa com azureml-blobstore anexado com um guid e clique em Selecionar.

  5. Selecione Guardar. O portal notifica-o quando a gravação estiver concluída.

Nota

Não estamos a ativar a notificação de carregamento para este tutorial, mas veja Receber uma notificação de carregamento de ficheiros para obter detalhes sobre como processar a notificação de carregamento de ficheiros.

Criar, publicar e implementar módulos

Agora que fizemos as alterações de configuração, estamos prontos para criar as imagens e publicá-las no nosso registo de contentor do Azure. O processo de compilação utiliza o ficheiro deployment.template.json para determinar que módulos têm de ser criados. As definições para cada módulo, incluindo a versão, encontram-se no ficheiro module.json na pasta do módulo. O processo de compilação executa primeiro uma compilação do Docker nos Dockerfiles que corresponde à configuração atual encontrada no ficheiro module.json para criar uma imagem. Em seguida, publica a imagem no registo a partir do ficheiro module.json com uma etiqueta de versão correspondente à do ficheiro module.json. Por fim, produz um manifesto de implementação específico da configuração (por exemplo, deployment.amd64.json), que iremos implementar no dispositivo IoT Edge. O dispositivo IoT Edge lê as informações do manifesto de implementação e, com base nas instruções, irá transferir os módulos, configurar as rotas e definir as propriedades pretendidas. Este método de implementação tem dois efeitos colaterais que deve ter em atenção:

  • Atraso na implementação: uma vez que o IoT Edge runtime tem de reconhecer a alteração às propriedades pretendidas antes de começar a reconfigurar, pode demorar algum tempo depois de implementar os módulos até que o runtime os selecione e comece a atualizar o dispositivo IoT Edge.

  • As versões do módulo são importantes: se publicar uma nova versão do contentor de um módulo no seu registo de contentor com as mesmas etiquetas de versão do módulo anterior, o runtime não transferirá a nova versão do módulo. Faz uma comparação da etiqueta de versão da imagem local e da imagem pretendida do manifesto de implementação. Se essas versões corresponderem, o runtime não efetua nenhuma ação. Por conseguinte, é importante incrementar a versão do módulo sempre que quiser implementar novas alterações. Incremente a versão ao alterar a propriedade da versão na propriedade tag no ficheiro module.json do módulo que está a alterar. 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

  1. Na VM de desenvolvimento, inicie o Docker se não estiver em execução.

  2. No Visual Studio Code, inicie um novo terminal com uma linha de comandos e inicie sessão no seu Azure Container Registry (ACR).

Pode encontrar os valores de nome de utilizador, palavra-passe e servidor de início de sessão necessários no portal do Azure. O nome do registo de contentor tem o formato "id> exclusivo do turbofandemo<". No menu do painel esquerdo, em Definições, selecione Teclas de acesso para as ver.

docker login -u <ACR username> -p <ACR password> <ACR login server>
  1. No Visual Studio Code, clique com o botão direito do rato em deployment.template.json e selecione Compilar e Emitir IoT Edge Solução.

Ver módulos no registo

Assim que a compilação for concluída com êxito, poderemos utilizar a portal do Azure para rever os nossos módulos publicados.

  1. Abra o Azure Container Registry deste tutorial. O nome do registo de contentor tem o formato "id> exclusivo do turbofandemo<".

  2. No menu do painel esquerdo, em Serviços, selecione Repositórios.

  3. Tenha em atenção que ambos os módulos que criou, avrofilewriter e turbofanrouter, são apresentados como repositórios.

  4. Selecione turbofanrouter e tenha em atenção que publicou uma imagem marcada como 0.0.1-amd64.

    Ver a primeira versão marcada do turbofanrouter

Implementar módulos no IoT Edge dispositivo

Criámos e configurámos os módulos na nossa solução, agora vamos implementar os módulos no dispositivo IoT Edge.

  1. No Visual Studio Code, clique com o botão direito do rato no ficheiro deployment.amd64.json na pasta config.

  2. Selecione Criar Implementação para Dispositivo Único.

  3. Selecione o seu dispositivo IoT Edge, aaTurboFanEdgeDevice.

  4. Atualize o painel Hub IoT do Azure dispositivos no explorador do Visual Studio Code. Deverá ver que os três novos módulos estão implementados, mas ainda não estão em execução.

  5. Atualize novamente após alguns minutos e verá os módulos em execução.

    Ver módulos em execução no Visual Studio Code

Nota

Pode demorar vários minutos para que os módulos comecem e se instalem num estado de execução constante. Durante esse período, poderá ver os módulos a serem iniciados e parados enquanto tentam estabelecer uma ligação com o módulo IoT Edge hub.

Diagnosticar falhas

Nesta secção, partilhamos algumas técnicas para compreender o que correu mal com um módulo ou módulos. Muitas vezes, é possível detetar uma falha a partir do estado no Visual Studio Code.

Identificar módulos com falhas

  • Visual Studio Code: Observe o painel Hub IoT do Azure dispositivos. Se a maioria dos módulos estiver num estado de execução, mas um estiver parado, terá de investigar mais aprofundadamente esse módulo parado. Se todos os módulos estiverem num estado parado durante um longo período de tempo, também poderá indicar uma falha.

  • portal do Azure: ao navegar para o seu hub IoT no portal e, em seguida, encontrar a página de detalhes do dispositivo (em IoT Edge, explorar o seu dispositivo), poderá descobrir que um módulo comunicou um erro ou nunca comunicou nada ao hub IoT.

Diagnosticar a partir do dispositivo

Ao iniciar sessão no dispositivo IoT Edge (a VM do Linux no nosso caso), pode obter acesso a uma boa quantidade de informações sobre o estado dos módulos. O mecanismo principal que utilizamos são os comandos do Docker que nos permitem examinar os contentores e imagens no dispositivo.

  1. Inicie sessão no seu dispositivo IoT Edge:

    ssh -l <user>@IoTEdge-<extension>.<region>.cloudapp.azure.com
    
  2. Listar todos os contentores em execução. Esperamos ver um contentor para cada módulo com um nome que corresponda ao módulo. Além disso, este comando lista a imagem exata do contentor, incluindo a versão, para que possa corresponder às suas expetativas. Também pode listar imagens substituindo "image" por "container" no comando .

    sudo docker container ls
    
  3. Obtenha os registos de um contentor. Este comando produz o que foi escrito em StdErr e StdOut no contentor. Este comando funciona para contentores que começaram e morreram por algum motivo. Também é útil para compreender o que tem acontecido com os contentores edgeAgent ou edgeHub.

    sudo docker container logs <container id>
    
  4. Inspecionar um contentor. Este comando fornece uma tonelada de informações sobre a imagem. Os dados podem ser filtrados consoante o que procura. Por exemplo, se quiser ver se os enlaces no avroFileWriter estão corretos, pode utilizar o comando :

    sudo docker container inspect -f "{{ json .Mounts }}" avroFileWriter | python -m json.tool
    
  5. Ligar a um contentor em execução. Este comando pode ser útil se quiser examinar o contentor enquanto está em execução:

    sudo docker exec -it avroFileWriter bash
    

Limpar os recursos

Este tutorial faz parte de um conjunto em que cada artigo baseia-se no trabalho realizado nos anteriores. Aguarde até concluir o tutorial final.

Passos seguintes

Neste artigo, criámos uma Solução IoT Edge no Visual Studio Code com três módulos: um classificador, um router e um escritor/carregador de ficheiros. Configuramos as rotas para permitir que os módulos comuniquem entre si no dispositivo edge. Modificámos a configuração do dispositivo edge e atualizámos os Dockerfiles para instalar dependências e adicionar montagens de enlace aos contentores dos módulos.

Em seguida, atualizámos a configuração do Hub IoT para encaminhar as nossas mensagens com base no tipo e para processar carregamentos de ficheiros. Com tudo em vigor, implementámos os módulos no dispositivo IoT Edge e garantimos que os módulos estavam a ser executados corretamente.

Avance para o artigo seguinte para começar a enviar dados e ver a sua solução em ação.