Partager via


Tutoriel : Créer et déployer des modules IoT Edge personnalisés

S’applique à :yes icon IoT Edge 1.1

Important

IoT Edge 1.1 date de fin de support était le 13 décembre 2022. Consultez la page Politique de support Microsoft pour plus d’informations sur la prise en charge de ce produit, de ce service, de cette technologie ou de cette API. Pour plus d’informations sur la mise à jour vers la dernière version d’IoT Edge, consultez Mettre à jour IoT Edge.

Dans cet article, nous créons trois modules IoT Edge qui reçoivent des messages provenant d’appareils IoT en aval, exécutons les données via votre modèle d'apprentissage automatique, puis transférons des informations à IoT Hub.

Le hub IoT Edge facilite la communication entre les modules. L’utilisation du hub IoT Edge en tant que répartiteur de messages conserve les modules indépendants les uns des autres. Il suffit aux modules de spécifier les entrées sur lesquelles ils acceptent des messages et les sorties vers lesquelles ils écrivent des messages.

Nous voulons que l’appareil IoT Edge effectue quatre tâches pour nous :

  • Recevoir des données des dispositifs en aval.
  • Prédire la durée de vie utile restante (RUL) pour l’appareil qui a envoyé les données.
  • Envoyez un message avec la RUL de l’appareil à IoT Hub. Cette fonction peut être modifiée pour envoyer des données uniquement si la RUL tombe en dessous d’un niveau spécifié.
  • Enregistrez les données de l’appareil en aval dans un fichier local sur l’appareil IoT Edge. Ce fichier de données est régulièrement chargé sur IoT Hub pour affiner l’apprentissage du modèle Machine Learning. L’utilisation du chargement de fichiers au lieu de la diffusion en continu de messages constants est plus rentable.

Pour accomplir ces tâches, nous utilisons trois modules personnalisés :

  • Classifieur RUL : Le module TurboFanRulClassifier que nous avons développé dans Entraîner et déployer un modèle Azure Machine Learning est un module de machine learning standard, qui expose une entrée appelée "amlInput" et une sortie appelée "amlOutput". L’élément « amlInput » s’attend à ce que son entrée ressemble exactement à l’entrée que nous avons envoyée au service web basé sur ACI. De même, « amlOutput » retourne les mêmes données que le service web.

  • enregistreur Avro : Ce module reçoit des messages sur l’entrée « avroModuleInput » et conserve le message au format Avro sur le disque pour le chargement ultérieur sur IoT Hub.

  • Module routeur : Le module routeur reçoit les messages des appareils en aval, puis met en forme et envoie les messages au classifieur. Le module reçoit ensuite les messages du classifieur et transfère le message vers le module enregistreur Avro. Enfin, le module envoie uniquement la prédiction RUL au hub IoT.

    • Saisies :

      • deviceInput: reçoit les messages des appareils en aval
      • rulInput : reçoit des messages du « amlOutput »
    • Sorties :

      • classifier : envoie des messages à « amlInput »
      • writeAvro : envoie des messages à « avroModuleInput »
      • toIotHub : envoie des messages à $upstream, qui transmet les messages au hub IoT connecté

Le diagramme suivant montre les modules, les entrées, les sorties et les itinéraires IoT Edge Hub pour la solution complète :

diagramme d’architecture de trois modules IoT Edge

Les étapes décrites dans cet article sont généralement effectuées par un développeur cloud.

Dans cette section du tutoriel, vous allez apprendre à :

  • Créez un module IoT Edge à partir d’un code personnalisé.
  • Générez une image Docker à partir de votre module personnalisé.
  • Reconfigurez le routage IoT Hub pour prendre en charge vos modules personnalisés.
  • Générez, publiez et déployez vos modules personnalisés.

Conditions préalables

Cet article fait partie d’une série de tutoriels sur l’utilisation d’Azure Machine Learning sur IoT Edge. Chaque article de la série s’appuie sur le travail de l’article précédent. Si vous êtes arrivé directement à cet article, visitez le premier article de la série.

Créer une solution IoT Edge

Lors de l’exécution du deuxième de nos deux notebooks Azure, nous avons créé et publié une image conteneur contenant notre modèle RUL. Azure Machine Learning, dans le cadre du processus de création d’images, empaqueté ce modèle afin que l’image soit déployable en tant que module Azure IoT Edge.

Dans cette étape, nous allons créer une solution Azure IoT Edge à l’aide du module « Azure Machine Learning » et pointer le module vers l’image que nous avons publiée à l’aide d’Azure Notebooks.

  1. Ouvrez une session de bureau à distance sur votre machine virtuelle de développement.

  2. Ouvrez le dossier C :\source\IoTEdgeAndMlSample dans Visual Studio Code.

  3. Cliquez avec le bouton droit sur le panneau de l’explorateur (dans l’espace vide) et sélectionnez nouvelle solution IoT Edge.

    Créer une solution IoT Edge

  4. Acceptez le nom de solution par défaut EdgeSolution.

  5. Choisissez Azure Machine Learning comme modèle de module.

  6. Nommez le module turbofanRulClassifier.

  7. Choisissez votre espace de travail Machine Learning. Cet espace de travail est l’espace de travail turboFanDemo que vous avez créé dans Tutoriel : Entraîner et déployer un modèle Azure Machine Learning

  8. Sélectionnez l’image que vous avez créée lors de l’exécution d’Azure Notebook.

  9. Examinez la solution et notez les fichiers qui ont été créés :

    • deployment.template.json: Ce fichier contient la définition de chacun des modules de la solution. Il existe trois sections à prendre en compte dans ce fichier :

      • Informations d’identification du Registre : définit l’ensemble de registres de conteneurs personnalisés que vous utilisez dans votre solution. À l’heure actuelle, il devrait contenir le registre dans votre espace de travail de Machine Learning, où votre image Azure Machine Learning a été stockée. Vous pouvez avoir n’importe quel nombre de registres de conteneurs, mais par souci de simplicité, nous allons utiliser ce registre pour tous les modules.

        "registryCredentials": {
          "<your registry>": {
            "username": "$CONTAINER_REGISTRY_USERNAME_<your registry>",
            "password": "$CONTAINER_REGISTRY_PASSWORD_<your registry>",
            "address": "<your registry>.azurecr.io"
          }
        }
        
      • Modules : Cette section contient l’ensemble de modules définis par l’utilisateur qui vont avec cette solution. La définition du module turbofanRulClassifier pointe vers l’image spécifiée dans votre registre de conteneurs. À mesure que nous ajoutons d’autres modules à la solution, ils apparaîtront dans cette section.

        "modules": {
           "turbofanRulClassifier": {
             "version": "1.0",
             "type": "docker",
             "status": "running",
             "restartPolicy": "always",
             "settings": {
               "image": "turbofandemo2cd74296.azurecr.io/edgemlsample:1",
               "createOptions": {}
             }
           }
        }
        
      • Routes : nous allons travailler beaucoup avec des itinéraires dans ce tutoriel. Les itinéraires définissent la façon dont les modules communiquent entre eux. L’itinéraire existant défini par le modèle ne correspond pas au routage dont nous avons besoin. Supprimez l’itinéraire turbofanRulClassifierToIoTHub.

        "$edgeHub": {
           "properties.desired": {
             "schemaVersion": "1.0",
             "routes": {
               "turbofanRulClassifierToIoTHub": "FROM /messages/modules/turbofanRulClassifier/outputs/* INTO $upstream"
             },
             "storeAndForwardConfiguration": {
               "timeToLiveSecs": 7200
             }
           }
        }
        
    • deployment.debug.template.json: ce fichier est la version de débogage de deployment.template.json. En règle générale, nous devons conserver ce fichier synchronisé avec le contenu du fichier deployment.template.json, mais cela n’est pas nécessaire pour ce didacticiel.

    • .env : ce fichier est l’emplacement où vous devez fournir le nom d’utilisateur et le mot de passe pour accéder à votre registre.

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

      Remarque

      Ce tutoriel utilise les informations d’identification de l’administrateur pour Azure Container Registry, qui sont pratiques pour les scénarios de développement et de test. Lorsque vous êtes prêt pour les scénarios de production, nous vous recommandons d’utiliser une option d’authentification avec le moins de privilèges possible, comme les principaux de service. Pour plus d’informations, consultez Gérer l’accès au registre de conteneurs.

  10. Cliquez avec le bouton droit sur le fichier deployment.template.json dans l’Explorateur Visual Studio Code, puis sélectionnez générer la solution IoT Edge.

  11. Notez que cette commande crée un dossier de configuration avec un fichier deployment.amd64.json. Ce fichier est le modèle de déploiement concret de la solution.

Ajouter un module Routeur

Ensuite, nous ajoutons le module Routeur à notre solution. Le module Routeur gère plusieurs responsabilités pour notre solution :

  • recevoir des messages provenant d’appareils en aval : à mesure que les messages arrivent à l’appareil IoT Edge à partir d’appareils en aval, le module Routeur reçoit le message et commence à orchestrer le routage du message.
  • envoyer des messages au module classifieur RUL : lorsqu’un nouveau message est reçu d’un appareil en aval, le module Routeur transforme le message au format attendu par le classifieur RUL. Le routeur envoie le message au classifieur RUL pour une prédiction RUL. Une fois que le classifieur a effectué une prédiction, il renvoie le message au module Router.
  • Envoyer des messages RUL à IoT Hub : lorsque le routeur reçoit des messages du classifieur, il transforme le message en contenant uniquement les informations essentielles, l’ID d’appareil et la RUL, et envoie le message abrégé au hub IoT. Un affinement supplémentaire, que nous n’avons pas fait ici, envoie des messages au Hub IoT uniquement lorsque la prédiction de RUL tombe en dessous d’un seuil (par exemple, lorsque la RUL est inférieure à 100 cycles). Le filtrage de cette façon réduit le volume de messages et réduit le coût du hub IoT.
  • Envoyer un message au module Enregistreur Avro : pour conserver toutes les données envoyées par l’appareil en aval, le module Routeur envoie l’intégralité du message reçu du classifieur au module Enregistreur Avro, qui conservera et chargera les données à l’aide du chargement de fichiers IoT Hub.

Le module Routeur est un élément important de la solution qui garantit que les messages sont traités dans l’ordre correct.

Créer le module et copier des fichiers

  1. Cliquez avec le bouton droit sur le dossier modules dans Visual Studio Code, puis choisissez Ajouter un module IoT Edge.

  2. Choisissez module C# pour le modèle de module.

  3. Nommez le module turbofanRouter.

  4. Lorsqu'on vous demande d'entrer votre référentiel d’images Docker, utilisez le registre provenant de l’espace de travail de machine learning (vous pouvez trouver le registre dans le nœud RegistryCredentials de votre fichier deployment.template.json). Cette valeur est l'adresse complète du registre, comme <votre registre>.azurecr.io/turbofanrouter.

    Remarque

    Dans cet article, nous utilisons Azure Container Registry qui a été créé par l’espace de travail Azure Machine Learning. C’est purement pratique. Nous aurions pu créer un registre de conteneurs et y publier nos modules.

  5. Dans le terminal à l’aide d’un interpréteur de commandes, copiez les fichiers de l’exemple de module dans la solution.

    copy c:\source\IoTEdgeAndMlSample\EdgeModules\modules\turbofanRouter\*.cs c:\source\IoTEdgeAndMlSample\EdgeSolution\modules\turbofanRouter\
    
  6. Acceptez l’invite pour remplacer le fichier program.cs.

Construire module de routeur

  1. Dans Visual Studio Code, sélectionnez Terminal>Configurer la tâche de génération par défaut.

  2. Sélectionnez Créer un fichier tasks.json à partir du modèle.

  3. Sélectionnez .NET Core .

  4. Remplacez le contenu de tasks.json par le code suivant.

    {
      "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. Enregistrez et fermez tasks.json.

  6. Exécutez la compilation avec Ctrl + Shift + B ou Terminal>Exécuter la tâche de build.

Configurer des itinéraires de module

Comme mentionné ci-dessus, le runtime IoT Edge utilise des itinéraires configurés dans le fichier deployment.template.json pour gérer la communication entre les modules faiblement couplés. Dans cette section, nous allons explorer comment configurer les itinéraires du module turbofanRouter. Nous allons d’abord couvrir les itinéraires d’entrée, puis passer aux sorties.

Entrées

  1. Dans la méthode Init() de Program.cs nous inscrivons deux rappels pour le module :

    await ioTHubModuleClient.SetInputMessageHandlerAsync(EndpointNames.FromLeafDevice, LeafDeviceInputMessageHandler, ioTHubModuleClient);
    await ioTHubModuleClient.SetInputMessageHandlerAsync(EndpointNames.FromClassifier, ClassifierCallbackMessageHandler, ioTHubModuleClient);
    
  2. Le premier rappel écoute les messages envoyés au récepteur deviceInput. Dans le diagramme ci-dessus, nous voyons que nous voulons acheminer les messages de n’importe quel appareil en aval vers cette entrée. Dans le fichier deployment.template.json, ajoutez un itinéraire qui indique au hub edge d’acheminer tout message reçu par l’appareil IoT Edge qui n’a pas été envoyé par un module IoT Edge dans l’entrée appelée « deviceInput » sur le module turbofanRouter :

    "leafMessagesToRouter": "FROM /messages/* WHERE NOT IS_DEFINED($connectionModuleId) INTO BrokeredEndpoint(\"/modules/turbofanRouter/inputs/deviceInput\")"
    
  3. Ajoutez ensuite un itinéraire pour les messages du module rulClassifier dans le module turbofanRouter :

    "classifierToRouter": "FROM /messages/modules/turbofanRulClassifier/outputs/amloutput INTO BrokeredEndpoint(\"/modules/turbofanRouter/inputs/rulInput\")"
    

Sorties

Ajoutez quatre itinéraires supplémentaires au paramètre de routage $edgeHub pour gérer les sorties du module Routeur.

  1. Program.cs définit la méthode SendMessageToClassifier(), qui utilise le client de module pour envoyer un message au classifieur RUL à l’aide de l’itinéraire :

    "routerToClassifier": "FROM /messages/modules/turbofanRouter/outputs/classOutput INTO BrokeredEndpoint(\"/modules/turbofanRulClassifier/inputs/amlInput\")"
    
  2. SendRulMessageToIotHub() utilise le client de module pour envoyer uniquement les données RUL de l’appareil à IoT Hub via l’itinéraire :

    "routerToIoTHub": "FROM /messages/modules/turboFanRouter/outputs/hubOutput INTO $upstream"
    
  3. SendMessageToAvroWriter() utilise le client de module pour envoyer le message avec les données RUL ajoutées au module avroFileWriter.

    "routerToAvro": "FROM /messages/modules/turbofanRouter/outputs/avroOutput INTO BrokeredEndpoint(\"/modules/avroFileWriter/inputs/avroModuleInput\")"
    
  4. HandleBadMessage() envoie des messages ayant échoué en amont du hub IoT où ils peuvent être routés ultérieurement.

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

Avec tous les itinéraires pris ensemble votre nœud « $edgeHub » doit ressembler au code JSON suivant :

"$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
    }
  }
}

Remarque

L’ajout du module turbofanRouter a créé l’itinéraire supplémentaire suivant : turbofanRouterToIoTHub": "FROM /messages/modules/turbofanRouter/outputs/* INTO $upstream. Supprimez cet itinéraire, en laissant uniquement les itinéraires répertoriés ci-dessus dans votre fichier deployment.template.json.

Ajouter un module enregistreur Avro

Le module Avro Writer a deux responsabilités dans notre solution, pour stocker les messages et charger des fichiers.

  • Stocker les messages: lorsque le module Enregistreur Avro reçoit un message, il écrit le message dans le système de fichiers local au format Avro. Nous utilisons un montage de liaison, qui monte un répertoire (dans ce cas /data/avrofiles) vers un chemin dans le conteneur du module. Ce montage permet au module d’écrire dans un chemin d’accès local (/avrofiles) et d’avoir ces fichiers accessibles directement à partir de l’appareil IoT Edge.

  • Charger des fichiers: le module Avro Writer utilise la fonctionnalité de chargement de fichiers Azure IoT Hub pour charger des fichiers dans un compte de stockage Azure. Une fois qu’un fichier a été chargé, le module supprime le fichier du disque

Créer un module et copier des fichiers

  1. Dans Visual Studio Code, sélectionnez Afficher>palette de commandes, puis recherchez et sélectionnez Python : Sélectionner un interpréteur.

  2. Sélectionnez votre python installé version 3.7 ou ultérieure.

  3. Cliquez avec le bouton droit sur le dossier modules dans Visual Studio Code, puis choisissez Ajouter un module IoT Edge.

  4. Choisissez Module Python.

  5. Nommez le module avroFileWriter.

  6. Lorsque vous êtes invité à spécifier votre référentiel d’images Docker, utilisez le même registre de conteneurs que lors de l’ajout du module Routeur.

  7. Copiez des fichiers à partir de l’exemple de module dans la solution.

    copy C:\source\IoTEdgeAndMlSample\EdgeModules\modules\avroFileWriter\*.py C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avroFileWriter\
    
  8. Acceptez le remplacement de main.py.

  9. Notez que filemanager.py et schema.py ont été ajoutés à la solution et main.py a été mis à jour.

Remarque

Lorsque vous ouvrez un fichier Python, vous pouvez être invité à installer pylint. Vous n’avez pas besoin d’installer le linter pour suivre ce tutoriel.

Montage par lien pour les fichiers de données

Comme mentionné précédemment, le module Writer s’appuie sur la présence d’un montage par lien pour écrire des fichiers Avro dans le système de fichiers de l’appareil.

Ajouter un répertoire à l’appareil

  1. Dans le portail Azure, démarrez votre machine virtuelle d’appareil IoT Edge si elle n’est pas en cours d’exécution. Connectez-vous à celui-ci à l’aide de SSH. La connexion nécessite le nom DNS que vous pouvez copier à partir de la page vue d’ensemble de la machine virtuelle dans le portail Azure.

    ssh -l <user>@<vm name>.<region>.cloudapp.azure.com
    
  2. Après vous être connecté, créez le répertoire qui contiendra les messages d’appareil en aval enregistrés.

    sudo mkdir -p /data/avrofiles
    
  3. Mettez à jour les autorisations de répertoire pour le rendre accessible en écriture par le conteneur.

    sudo chmod ugo+rw /data/avrofiles
    
  4. Vérifiez que le répertoire dispose désormais de l’autorisation d’écriture (w) pour l’utilisateur, le groupe et le propriétaire.

    ls -la /data
    

    autorisations d’annuaire pour les avrofiles

Ajouter un répertoire au module

Pour ajouter le répertoire au conteneur du module, nous allons modifier les fichiers Dockerfile associés au module avroFileWriter. Il existe trois fichiers Dockerfile associés au module : Dockerfile.amd64, Dockerfile.amd64.debug et Dockerfile.arm32v7. Ces fichiers doivent être conservés synchronisés au cas où nous souhaitons déboguer ou déployer sur un appareil arm32. Pour cet article, concentrez-vous uniquement sur Dockerfile.amd64.

  1. Sur votre machine virtuelle de développement, ouvrez le fichier C :\source\IoTEdgeAndMlSample\EdgeSolution\modules\avoFileWriter\Dockerfile.amd64.

  2. Modifiez le fichier de sorte qu’il ressemble à l’exemple suivant :

    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" ]
    

    Les commandes mkdir et chown indiquent au processus de génération Docker de créer un répertoire de niveau supérieur appelé /avrofiles dans l’image, puis de rendre le moduleuser le propriétaire de ce répertoire. Il est important que ces commandes soient insérées une fois que l’utilisateur du module est ajouté à l’image avec la commande useradd et avant que le contexte bascule vers l’utilisateur du module (USER moduleuser).

  3. Si nécessaire, apportez les modifications correspondantes à Dockerfile.amd64.debug et Dockerfile.arm32v7.

Ajouter une configuration de liaison à l'avroFileWriter

La dernière étape de création de la liaison consiste à mettre à jour les fichiers deployment.template.json (et deployment.debug.template.json) avec les informations de liaison.

  1. Ouvrez deployment.template.json.

  2. Modifiez la définition du module pour avroFileWriter en ajoutant le paramètre Binds qui pointe le répertoire conteneur /avrofiles vers le répertoire local sur l’appareil de périphérie. Votre définition de module doit correspondre à cet exemple :

    "avroFileWriter": {
      "version": "1.0",
      "type": "docker",
      "status": "running",
      "restartPolicy": "always",
      "settings": {
        "image": "${MODULES.avroFileWriter}",
        "createOptions": {
          "HostConfig": {
            "Binds": [
              "/data/avrofiles:/avrofiles"
            ]
          }
        }
      }
    }
    

Montage de liaison pour accéder à config.yaml

Nous devons ajouter une liaison supplémentaire pour le module rédacteur. Cette liaison permet au module de lire la chaîne de connexion à partir du fichier /etc/iotedge/config.yaml sur l’appareil IoT Edge. Nous avons besoin de la chaîne de connexion pour créer un IoTHubClient afin de pouvoir appeler la méthode upload_blob_async pour charger des fichiers vers le hub IoT. Les étapes d’ajout de cette liaison sont similaires à celles de la section précédente.

Mettre à jour l’autorisation d’annuaire

  1. Connectez-vous à votre appareil IoT Edge à l’aide de SSH.

    ssh -l <user>@IoTEdge-<extension>.<region>.cloudapp.azure.com
    
  2. Ajoutez l’autorisation de lecture au fichier config.yaml.

    sudo chmod +r /etc/iotedge/config.yaml
    
  3. Vérifiez que les autorisations sont correctement définies.

    ls -la /etc/iotedge/
    
  4. Vérifiez que les autorisations pour config.yaml sont -r--r--r--.

Ajouter un répertoire au module

  1. Sur votre ordinateur de développement, ouvrez le fichier Dockerfile.amd64.

  2. Ajoutez un ensemble supplémentaire de commandes mkdir et chown au fichier pour qu’il ressemble à ceci :

    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. Apportez les modifications correspondantes à Dockerfile.amd64.debug et Dockerfile.arm32v7.

Mettre à jour la configuration du module

  1. Ouvrez le fichier deployment.template.json.

  2. Modifiez la définition du module pour avroFileWriter en ajoutant une deuxième ligne au paramètre Binds qui pointe le répertoire du conteneur (/app/iotconfig) vers le répertoire local sur l’appareil (/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. Apportez les modifications correspondantes à deployment.debug.template.json.

Installer des dépendances

Le module writer dépend de deux bibliothèques Python, fastavro et PyYAML. Nous devons installer les dépendances sur notre ordinateur de développement et indiquer au processus de génération Docker de les installer dans l’image de notre module.

PyYAML

  1. Sur votre ordinateur de développement, ouvrez le fichier C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avoFileWriter\requirements.txt et ajoutez « pyyaml » sur une nouvelle ligne du fichier.

    azure-iothub-device-client~=1.4.3
    pyyaml
    
  2. Ouvrez le fichier Dockerfile.amd64 et ajoutez une commande pip install pour mettre à niveau 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" ]
    
  3. À l’invite de commandes, installez pyyaml sur votre ordinateur de développement.

    pip install pyyaml
    

Fastavro

  1. Dans requirements.txt, ajoutez fastavro après pyyaml.

    azure-iothub-device-client~=1.4.3
    pyyaml
    fastavro
    
  2. Installez fastavro sur votre ordinateur de développement.

    pip install fastavro
    

Reconfigurer IoT Hub

En introduisant l’appareil et les modules IoT Edge sur le système, nous avons modifié nos attentes concernant les données qui seront envoyées au hub et à quel objectif. Nous devons reconfigurer le routage dans le hub pour gérer notre nouvelle réalité.

Remarque

Nous reconfigurons le hub avant de déployer des modules, car certains paramètres du hub, en particulier le chargement de fichiers, doivent être correctement configurés pour que le module avroFileWriter s’exécute correctement

Configurer l’itinéraire pour les messages RUL dans IoT Hub

Avec le routeur et le classifieur en place, nous nous attendons à recevoir des messages réguliers contenant uniquement l’ID d’appareil et la prédiction RUL pour l’appareil. Nous voulons acheminer les données RUL vers son propre emplacement de stockage, où nous pouvons surveiller l’état des appareils, générer des rapports et déclencher des alertes en fonction des besoins. En même temps, nous voulons que toutes les données d’appareil qui sont toujours envoyées directement par un appareil en aval qui n’a pas encore été attaché à notre appareil IoT Edge continuent à être acheminées vers l’emplacement de stockage actuel.

Créer un itinéraire de message RUL

  1. Dans le portail Azure, accédez à votre hub IoT.

  2. Dans le menu du volet gauche, sous paramètres hub, sélectionnez routage des messages.

  3. Sous l’onglet Routes, sélectionnez Ajouter.

  4. Nommez l’itinéraire RulMessageRoute.

  5. Sélectionnez Ajouter un point de terminaison à droite du point de terminaison dans le sélecteur et choisissez Stockage.

  6. Sur la page Ajouter un point de terminaison de stockage, nommez le point de terminaison ruldata.

  7. Sélectionnez Choisir un conteneur.

  8. Sur la page des comptes de stockage , recherchez le compte de stockage que vous utilisez tout au long de ce didacticiel, nommé iotedgeandml<suffixe unique>.

  9. Sélectionnez le conteneur ruldata et cliquez sur Sélectionner.

  10. De retour à la page Ajouter un point de terminaison de stockage, sélectionnez Créer pour créer le point de terminaison de stockage.

  11. Revenu sur la page Ajouter un itinéraire, pour la requête de routage associée à, remplacez true par la requête suivante :

    IS_DEFINED($body.PredictedRul) AND NOT IS_DEFINED($body.OperationalSetting1)
    
  12. Développez la section Test, puis la section corps du message. Remplacez le corps du message par cet exemple de nos messages attendus :

    {
      "ConnectionDeviceId": "aaLeafDevice_1",
      "CorrelationId": "b27e97bb-06c5-4553-a064-e9ad59c0fdd3",
      "PredictedRul": 132.62721409309165,
      "CycleTime": 64.0
    }
    
  13. Sélectionnez l'itinéraire de test . Si le test réussit, vous voyez « Le message correspond à la requête ».

  14. Cliquez sur Enregistrer.

Mettre à jour la route turbofanDeviceDataToStorage

Nous ne voulons pas acheminer les nouvelles données de prédiction vers notre ancien emplacement de stockage. Mettez donc à jour l’itinéraire pour l’empêcher.

  1. Dans la page Routage des messages de l'IoT Hub, sélectionnez l'onglet Itinéraires .

  2. Sélectionnez turbofanDeviceDataToStorage, ou quel que soit le nom que vous avez donné à votre chemin de données de l'appareil initial.

  3. Mettre à jour la requête de routage vers

    IS_DEFINED($body.OperationalSetting1)
    
  4. Développez la section Test, puis la section corps du message. Remplacez le message par cet exemple de nos messages attendus :

    {
      "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. Sélectionnez l'itinéraire de test . Si le test réussit, vous voyez « Le message correspond à la requête ».

  6. Cliquez sur Enregistrer.

Configurer le chargement de fichiers

Configurez la fonctionnalité de chargement de fichiers IoT Hub pour permettre au module enregistreur de fichiers de charger des fichiers dans le stockage.

  1. Dans le menu du volet gauche de votre Hub IoT, sous paramètres du hub, choisissez chargement de fichiers.

  2. Sélectionnez le conteneur de stockage Azure .

  3. Sélectionnez votre compte de stockage dans la liste.

  4. Sélectionnez le conteneur qui commence par azureml-blobstore ajouté avec un guid, puis cliquez sur Sélectionner.

  5. Cliquez sur Enregistrer. Le portail vous avertit lorsque l’enregistrement est terminé.

Remarque

Nous n’activons pas la notification de chargement pour ce didacticiel, mais consultez Recevoir une notification de chargement de fichier pour plus d’informations sur la façon de gérer la notification de chargement de fichier.

Générer, publier et déployer des modules

Maintenant que nous avons apporté les modifications de configuration, nous sommes prêts à créer les images et à les publier dans notre registre de conteneurs Azure. Le processus de génération utilise le fichier deployment.template.json pour déterminer quels modules doivent être générés. Les paramètres de chaque module, y compris la version, se trouvent dans le fichier module.json dans le dossier du module. Le processus de génération exécute d’abord une build Docker sur les fichiers Dockerfile correspondant à la configuration actuelle trouvée dans le fichier module.json pour créer une image. Il publie ensuite l’image dans le Registre à partir du fichier module.json avec une balise de version correspondant à celle du fichier module.json. Enfin, il produit un manifeste de déploiement spécifique à la configuration (par exemple, deployment.amd64.json), que nous allons déployer sur l’appareil IoT Edge. L’appareil IoT Edge lit les informations du manifeste de déploiement et, en fonction des instructions, télécharge les modules, configure les itinéraires et définit les propriétés souhaitées. Cette méthode de déploiement a deux effets secondaires que vous devez connaître :

  • décalage de déploiement : étant donné que le runtime IoT Edge doit reconnaître la modification de ses propriétés souhaitées avant de commencer à reconfigurer, il peut prendre un certain temps après le déploiement de vos modules jusqu’à ce que le runtime les récupère et commence à mettre à jour l’appareil IoT Edge.

  • les versions du module importent : si vous publiez une nouvelle version du conteneur d’un module dans votre registre de conteneurs à l’aide des mêmes balises de version que le module précédent, le runtime ne télécharge pas la nouvelle version du module. Il effectue une comparaison de la balise de version de l’image locale et de l’image souhaitée à partir du manifeste de déploiement. Si ces versions correspondent, le runtime n’effectue aucune action. Par conséquent, il est important d’incrémenter la version de votre module chaque fois que vous souhaitez déployer de nouvelles modifications. Incrémentez la version en modifiant la propriété version dans la propriété tag du fichier module.json pour le module que vous modifiez. Générez et publiez ensuite le module.

    {
      "$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"
    }
    

Construire et publier

  1. Sur votre machine virtuelle de développement, démarrez Docker s’il n’est pas en cours d’exécution.

  2. Dans Visual Studio Code, démarrez un nouveau terminal avec une invite de commandes et connectez-vous à votre registre de conteneurs Azure (ACR).

Vous trouverez les valeurs de nom d’utilisateur, de mot de passe et de serveur de connexion requises dans le portail Azure. Le nom du registre de conteneurs a le format « turbofandemo<id unique>». Dans le menu du volet gauche, sous Paramètres, sélectionnez touches d’accès pour les afficher.

docker login -u <ACR username> -p <ACR password> <ACR login server>
  1. Dans Visual Studio Code, cliquez avec le bouton droit sur deployment.template.json, puis choisissez Construire et envoyer (push) la solution IoT Edge.

Afficher les modules dans le Registre

Une fois la build terminée, nous serons en mesure d’utiliser le portail Azure pour passer en revue nos modules publiés.

  1. Ouvrez Azure Container Registry pour ce didacticiel. Le nom du registre de conteneurs a le format « turbofandemo<id unique>».

  2. Dans le menu du volet gauche, sous Services, sélectionnez Dépôts.

  3. Notez que les deux modules que vous avez créés, avrofilewriter et turbofanrouter, apparaissent en tant que référentiels.

  4. Sélectionnez turbofanrouter et notez que vous avez publié une image marquée comme 0.0.1-amd64.

    Voir la première version balisée de turbofanrouter

Déployer des modules sur un appareil IoT Edge

Nous avons créé et configuré les modules dans notre solution. Nous allons maintenant déployer les modules sur l’appareil IoT Edge.

  1. Dans Visual Studio Code, cliquez avec le bouton droit sur le fichier deployment.amd64.json dans le dossier de configuration.

  2. Choisissez Créer un déploiement pour un seul appareil.

  3. Choisissez votre appareil IoT Edge, aaTurboFanEdgeDevice.

  4. Actualisez le panneau appareils Azure IoT Hub dans l’Explorateur Visual Studio Code. Vous devez voir que les trois nouveaux modules sont déployés, mais pas encore en cours d’exécution.

  5. Actualisez à nouveau après quelques minutes et vous verrez les modules en cours d’exécution.

    Afficher les modules en cours d’exécution dans Visual Studio Code

Remarque

Plusieurs minutes peuvent être nécessaires pour que les modules démarrent et s’installent dans un état d’exécution stable. Pendant ce temps, vous pouvez voir que les modules démarrent et s’arrêtent lorsqu’ils tentent d’établir une connexion avec le module Hub IoT Edge.

Diagnostic des échecs

Dans cette section, nous partageons quelques techniques pour comprendre ce qui a mal fonctionné avec un module ou des modules. Souvent, un échec peut d’abord être repéré à partir de l’état dans Visual Studio Code.

Identifier les modules ayant échoué

  • Visual Studio Code : Regardez le panneau des appareils Azure IoT Hub. Si la plupart des modules sont dans un état en cours d’exécution, mais qu’ils sont arrêtés, vous devez examiner ce module arrêté plus loin. Si tous les modules sont dans un état arrêté pendant une longue période, il peut également indiquer l’échec.

  • portail Azure : En accédant à votre hub IoT dans le portail, puis en recherchant la page de détails de l’appareil (sous IoT Edge, explorer votre appareil), vous pouvez constater qu’un module a signalé une erreur ou n’a jamais signalé quoi que ce soit au hub IoT.

Diagnostic depuis l’appareil

En vous connectant à l’appareil IoT Edge (la machine virtuelle Linux dans notre cas), vous pouvez accéder à une bonne quantité d’informations sur l’état de vos modules. Le mécanisme principal que nous utilisons est les commandes Docker qui nous permettent d’examiner les conteneurs et les images sur l’appareil.

  1. Connectez-vous à votre appareil IoT Edge :

    ssh -l <user>@IoTEdge-<extension>.<region>.cloudapp.azure.com
    
  2. Répertorier tous les conteneurs en cours d’exécution. Nous nous attendons à voir un conteneur pour chaque module portant un nom qui correspond au module. En outre, cette commande répertorie l’image exacte du conteneur, y compris la version, afin que vous puissiez correspondre à vos attentes. Vous pouvez également répertorier des images en remplaçant « image » pour « conteneur » dans la commande.

    sudo docker container ls
    
  3. Obtenez les journaux d’activité d’un conteneur. Cette commande affiche, dans le conteneur, tout ce qui a été écrit dans StdErr et StdOut. Cette commande fonctionne pour les conteneurs qui ont démarré et sont morts pour une raison quelconque. Il est également utile de comprendre ce qui se passe avec les conteneurs edgeAgent ou edgeHub.

    sudo docker container logs <container id>
    
  4. Inspectez un conteneur. Cette commande fournit une tonne d’informations sur l’image. Les données peuvent être filtrées en fonction de ce que vous recherchez. Par exemple, si vous souhaitez voir si les liaisons sur avroFileWriter sont correctes, vous pouvez utiliser la commande :

    sudo docker container inspect -f "{{ json .Mounts }}" avroFileWriter | python -m json.tool
    
  5. Connectez-vous à un conteneur en cours d’exécution. Cette commande peut être utile si vous souhaitez examiner le conteneur pendant son exécution :

    sudo docker exec -it avroFileWriter bash
    

Nettoyer les ressources

Ce tutoriel fait partie d’un ensemble où chaque article s’appuie sur le travail effectué dans les précédents. Veuillez patienter pour nettoyer les ressources jusqu’à ce que vous mettez fin au didacticiel final.

Étapes suivantes

Dans cet article, nous avons créé une solution IoT Edge dans Visual Studio Code avec trois modules : un classifieur, un routeur et un enregistreur/chargeur de fichiers. Nous avons configuré les itinéraires pour permettre aux modules de communiquer entre eux sur l’appareil de périphérie. Nous avons modifié la configuration de l’appareil périphérique et mis à jour les Dockerfiles pour installer les dépendances et ajouter des liaisons de montage aux conteneurs des modules.

Ensuite, nous avons mis à jour la configuration du hub IoT pour acheminer nos messages en fonction du type et pour gérer les chargements de fichiers. Avec tout ce qui est en place, nous avons déployé les modules sur l’appareil IoT Edge et nous avons vérifié que les modules s’exécutaient correctement.

Passez à l’article suivant pour commencer à envoyer des données et voir votre solution en action.