Nota
O acceso a esta páxina require autorización. Pode tentar iniciar sesión ou modificar os directorios.
O acceso a esta páxina require autorización. Pode tentar modificar os directorios.
Aplicable a:
IoT Edge 1.1
Importante
La fecha de finalización del soporte técnico de IoT Edge 1.1 fue el 13 de diciembre de 2022. Compruebe el ciclo de vida del producto de Microsoft para obtener información sobre cómo se admite este producto, servicio, tecnología o API. Para más información sobre cómo actualizar a la versión más reciente de IoT Edge, consulte Actualización de IoT Edge.
En este artículo, creamos tres módulos de IoT Edge que reciben mensajes de dispositivos IoT descendentes, procesan los datos a través de su modelo de aprendizaje automático, y luego reenvían la información a IoT Hub.
El centro de IoT Edge facilita la comunicación entre módulos. El uso del centro de IoT Edge como agente de mensajes mantiene los módulos independientes entre sí. Los módulos solo necesitan especificar las entradas en las que aceptan mensajes y las salidas en las que los escriben.
Queremos que el dispositivo IoT Edge realice cuatro cosas para nosotros:
- Recibir datos de los dispositivos descendentes.
- Prediga la vida útil restante (RUL) para el dispositivo que envió los datos.
- Envíe un mensaje con la RUL del dispositivo a IoT Hub. Esta función se podría modificar para enviar datos solo si la RUL cae por debajo de un nivel especificado.
- Guarde los datos del dispositivo aguas abajo en un archivo local en el dispositivo IoT Edge. Este archivo de datos se carga periódicamente en IoT Hub para refinar el entrenamiento del modelo de aprendizaje automático. El uso de la carga de archivos en lugar de la transmisión de mensajes constante es más rentable.
Para realizar estas tareas, usamos tres módulos personalizados:
Clasificador RUL: El módulo turboFanRulClassifier que hemos creado en Entrenamiento e implementación de un modelo de Azure Machine Learning es un módulo de aprendizaje automático estándar, que expone una entrada denominada "amlInput" y una salida denominada "amlOutput". "amlInput" espera que su entrada sea exactamente similar a la entrada que hemos enviado al servicio web basado en ACI. Del mismo modo, "amlOutput" devuelve los mismos datos que el servicio web.
Escritor avro: Este módulo recibe mensajes en la entrada "avroModuleInput" y conserva el mensaje en formato Avro en el disco para su posterior carga en IoT Hub.
Módulo de enrutador: El módulo de enrutador recibe mensajes de dispositivos de bajada y, a continuación, da formato a los mensajes y los envía al clasificador. A continuación, el módulo recibe los mensajes del clasificador y reenvía el mensaje al módulo de escritura de Avro. Por último, el módulo envía solo la predicción RUL a IoT Hub.
Entradas:
- deviceInput: recibe mensajes de dispositivos aguas abajo
- rulInput: recibe mensajes de "amlOutput"
Salidas:
- clasificar: envía mensajes a "amlInput"
- writeAvro: envía mensajes a "avroModuleInput"
- toIotHub: envía mensajes a $upstream, que pasa los mensajes a la instancia de IoT Hub conectada.
En el diagrama siguiente se muestran los módulos, las entradas, las salidas y las rutas de IoT Edge Hub para la solución completa:
Los pasos de este artículo suelen realizarse por un desarrollador en la nube.
En esta sección del tutorial, aprenderá a:
- Cree un módulo de IoT Edge a partir del código personalizado.
- Genere una imagen de Docker a partir del módulo personalizado.
- Vuelva a configurar el enrutamiento de IoT Hub para admitir los módulos personalizados.
- Compile, publique e implemente los módulos personalizados.
Prerrequisitos
Este artículo forma parte de una serie de un tutorial acerca del uso de Azure Machine Learning en IoT Edge. Cada artículo de la serie se basa en el trabajo del artículo anterior. Si ha llegado directamente a este artículo, visite el primer artículo de la serie.
Creación de una nueva solución de IoT Edge
Durante la ejecución del segundo de nuestros dos Cuadernos de Azure, creamos y publicamos una imagen de contenedor que contiene nuestro modelo RUL. Azure Machine Learning, como parte del proceso de creación de imágenes, empaqueta ese modelo para que la imagen se pueda implementar como un módulo de Azure IoT Edge.
En este paso, vamos a crear una solución de Azure IoT Edge mediante el módulo "Azure Machine Learning" y apuntaremos el módulo a la imagen que publicamos mediante Azure Notebooks.
Abra una sesión de escritorio remoto en la máquina virtual de desarrollo.
Abra la carpeta C:\source\IoTEdgeAndMlSample en Visual Studio Code.
Haga clic con el botón derecho en el panel del explorador (en el espacio en blanco) y seleccione Nueva solución de IoT Edge.
Acepte el nombre de solución predeterminado EdgeSolution.
Elija de Azure Machine Learning como plantilla de módulo.
Asigne al módulo el nombre turbofanRulClassifier.
Elija el área de trabajo de Machine Learning. Esta área de trabajo es el área de trabajo turboFanDemo que creó en Tutorial: Entrenamiento e implementación de un modelo de Azure Machine Learning
Seleccione la imagen que creó mientras ejecuta Azure Notebook.
Examine la solución y observe los archivos que se han creado:
deployment.template.json: Este archivo contiene la definición de cada uno de los módulos de la solución. Hay tres secciones a las que prestar atención en este archivo:
Credenciales del Registro: Define el conjunto de registros de contenedor personalizados que usa en la solución. En este momento, debe contener el registro del área de trabajo de Aprendizaje automático, que es donde se almacenó la imagen de Azure Machine Learning. Puede tener cualquier número de registros de contenedor, pero por motivos de simplicidad usaremos este registro para todos los 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 sección contiene el conjunto de módulos definidos por el usuario que van con esta solución. La definición del módulo turbofanRulClassifier apunta a la imagen en tu registro de contenedor. A medida que agregamos más módulos a la solución, se mostrarán en esta sección.
"modules": { "turbofanRulClassifier": { "version": "1.0", "type": "docker", "status": "running", "restartPolicy": "always", "settings": { "image": "turbofandemo2cd74296.azurecr.io/edgemlsample:1", "createOptions": {} } } }Rutas: trabajaremos con rutas un poco en este tutorial. Las rutas definen cómo se comunican los módulos entre sí. La ruta existente definida por la plantilla no coincide con el enrutamiento que necesitamos. Elimine la ruta
turbofanRulClassifierToIoTHub."$edgeHub": { "properties.desired": { "schemaVersion": "1.0", "routes": { "turbofanRulClassifierToIoTHub": "FROM /messages/modules/turbofanRulClassifier/outputs/* INTO $upstream" }, "storeAndForwardConfiguration": { "timeToLiveSecs": 7200 } } }
deployment.debug.template.json: este archivo es la versión de depuración de deployment.template.json. Normalmente, debemos mantener este archivo sincronizado con el contenido del archivo deployment.template.json, pero no es necesario hacerlo para este tutorial.
.env: este archivo es donde debe proporcionar el nombre de usuario y la contraseña para acceder al registro.
CONTAINER_REGISTRY_USERNAME_<your registry name>=<ACR username> CONTAINER_REGISTRY_PASSWORD_<your registry name>=<ACR password>Nota:
En este tutorial se usan credenciales de inicio de sesión de administrador de Azure Container Registry, que son prácticas para escenarios de desarrollo y pruebas. Cuando esté listo para escenarios de producción, recomendamos una opción de autenticación con privilegios mínimos, como los principales de servicio. Para más información, consulte Administración del acceso al registro de contenedor.
Haga clic con el botón derecho en el archivo deployment.template.json en el explorador de Visual Studio Code y seleccione Compilar solución de IoT Edge.
Tenga en cuenta que este comando crea una carpeta config con un archivo deployment.amd64.json. Este archivo es la plantilla de implementación concreta de la solución.
Agregar módulo de enrutador
A continuación, agregamos el módulo Enrutador a nuestra solución. El módulo Enrutador controla varias responsabilidades para nuestra solución:
- Recibir mensajes de dispositivos de bajada: a medida que llegan mensajes al dispositivo IoT Edge desde dispositivos de bajada, el módulo Enrutador recibe el mensaje y comienza a orquestar el enrutamiento del mensaje.
- Enviar mensajes al módulo Clasificador RUL: cuando se recibe un nuevo mensaje desde un dispositivo de bajada, el módulo Enrutador transforma el mensaje en el formato que espera el clasificador RUL. El enrutador envía el mensaje al clasificador RUL para una predicción RUL. Una vez que el clasificador ha realizado una predicción, devuelve el mensaje al módulo Enrutador.
- Enviar mensajes RUL a IoT Hub: cuando el enrutador recibe mensajes del clasificador, transforma el mensaje para que contenga solo la información esencial, el identificador de dispositivo y la RUL, y envía el mensaje abreviado al centro de IoT. Un refinamiento adicional, que no hemos hecho aquí, enviaría mensajes a IoT Hub solo cuando la predicción de RUL cae por debajo de un umbral (por ejemplo, cuando la RUL es inferior a 100 ciclos). El filtrado de esta manera reduciría el volumen de mensajes y reduciría el costo del centro de IoT.
- Enviar mensaje al módulo Avro Writer: para conservar todos los datos enviados por el dispositivo de bajada, el módulo Enrutador envía todo el mensaje recibido del clasificador al módulo Avro Writer, que conservará y cargará los datos mediante la carga de archivos de IoT Hub.
El módulo Enrutador es una parte importante de la solución que garantiza que los mensajes se procesen en el orden correcto.
Creación del módulo y copia de archivos
Haga clic con el botón derecho en la carpeta modules de Visual Studio Code y elija Agregar módulo IoT Edge.
Elija módulo de C# para la plantilla de módulo.
Asigne al módulo el nombre turbofanRouter.
Cuando se le solicite el repositorio de imágenes de Docker, use el registro del área de trabajo de Aprendizaje automático (puede encontrar el registro en el nodo registryCredentials del archivo deployment.template.json ). Este valor es la dirección completa del registro, como <registry.azurecr.io/turbofanrouter>.
Nota:
En este artículo, se usa Azure Container Registry creado por el área de trabajo de Azure Machine Learning. Esto es exclusivamente para comodidad. Podríamos haber creado un nuevo registro de contenedor y publicar nuestros módulos allí.
En la terminal mediante el símbolo del sistema, copie los archivos del módulo de ejemplo en la carpeta de la solución.
copy c:\source\IoTEdgeAndMlSample\EdgeModules\modules\turbofanRouter\*.cs c:\source\IoTEdgeAndMlSample\EdgeSolution\modules\turbofanRouter\Acepte la solicitud para sobrescribir el archivo program.cs.
Construir módulo del enrutador
En Visual Studio Code, seleccione TerminalConfigure Default Build Task (Configurar> tarea de compilación predeterminada).
Seleccione Crear tasks.json archivo a partir de una plantilla.
Seleccione .NET Core.
Reemplace el contenido de tasks.json por el código siguiente.
{ "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" } ] }Guarde y cierre tasks.json.
Ejecute la compilación con
Ctrl + Shift + Bo Terminal>Ejecutar tarea de compilación.
Configuración de rutas de módulo
Como se mencionó anteriormente, el entorno de ejecución de IoT Edge usa rutas configuradas en el archivo deployment.template.json para administrar la comunicación entre módulos acoplados flexiblemente. En esta sección, profundizaremos en cómo configurar las rutas para el módulo turbofanRouter. Trataremos primero las rutas de entrada y, a continuación, pasaremos a las salidas.
Entradas
En el método Init() de Program.cs registramos dos devoluciones de llamada para el módulo:
await ioTHubModuleClient.SetInputMessageHandlerAsync(EndpointNames.FromLeafDevice, LeafDeviceInputMessageHandler, ioTHubModuleClient); await ioTHubModuleClient.SetInputMessageHandlerAsync(EndpointNames.FromClassifier, ClassifierCallbackMessageHandler, ioTHubModuleClient);El primer callback escucha los mensajes enviados al receptor deviceInput. En el diagrama anterior, vemos que queremos enrutar mensajes desde cualquier dispositivo de bajada a esta entrada. En el archivo deployment.template.json, agregue una ruta que le indique al hub perimetral que enrute cualquier mensaje recibido por el dispositivo IoT Edge que no fue enviado por un módulo de IoT Edge a la entrada denominada "deviceInput" en el módulo turbofanRouter.
"leafMessagesToRouter": "FROM /messages/* WHERE NOT IS_DEFINED($connectionModuleId) INTO BrokeredEndpoint(\"/modules/turbofanRouter/inputs/deviceInput\")"A continuación, agregue una ruta para los mensajes del módulo rulClassifier al módulo turbofanRouter:
"classifierToRouter": "FROM /messages/modules/turbofanRulClassifier/outputs/amloutput INTO BrokeredEndpoint(\"/modules/turbofanRouter/inputs/rulInput\")"
Salidas
Agregue cuatro rutas adicionales al parámetro de ruta $edgeHub para controlar las salidas del módulo Enrutador.
Program.cs define el método SendMessageToClassifier(), que usa el cliente del módulo para enviar un mensaje al clasificador RUL mediante la ruta:
"routerToClassifier": "FROM /messages/modules/turbofanRouter/outputs/classOutput INTO BrokeredEndpoint(\"/modules/turbofanRulClassifier/inputs/amlInput\")"SendRulMessageToIotHub() usa el cliente del módulo para enviar solo los datos RUL del dispositivo a IoT Hub a través de la ruta:
"routerToIoTHub": "FROM /messages/modules/turboFanRouter/outputs/hubOutput INTO $upstream"SendMessageToAvroWriter() usa el cliente del módulo para enviar el mensaje con los datos RUL agregados al módulo avroFileWriter.
"routerToAvro": "FROM /messages/modules/turbofanRouter/outputs/avroOutput INTO BrokeredEndpoint(\"/modules/avroFileWriter/inputs/avroModuleInput\")"HandleBadMessage() envía mensajes fallidos hacia IoT Hub, donde se pueden enrutar para más adelante.
"deadLetter": "FROM /messages/modules/turboFanRouter/outputs/deadMessages INTO $upstream"
Con todas las rutas tomadas juntas, el nodo "$edgeHub" debe tener un aspecto similar al siguiente 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:
Al agregar el módulo turbofanRouter se creó la siguiente ruta adicional: turbofanRouterToIoTHub": "FROM /messages/modules/turbofanRouter/outputs/* INTO $upstream. Quite esta ruta, dejando solo las rutas enumeradas anteriormente en el archivo deployment.template.json.
Adición del módulo Avro Writer
El módulo Avro Writer tiene dos responsabilidades en nuestra solución para almacenar mensajes y cargar archivos.
Almacenar mensajes: cuando el módulo Avro Writer recibe un mensaje, escribe el mensaje en el sistema de archivos local en formato Avro. Usamos un montaje de enlace, que monta un directorio (en este caso /data/avrofiles) en una ruta del contenedor del módulo. Este montaje permite que el módulo escriba en una ruta de acceso local (/avrofiles) y que esos archivos sean accesibles directamente desde el dispositivo IoT Edge.
Carga de archivos: el módulo Avro Writer usa la característica de carga de archivos de Azure IoT Hub para cargar archivos en una cuenta de Almacenamiento de Azure. Una vez cargado correctamente un archivo, el módulo elimina el archivo del disco.
Creación de módulos y copia de archivos
En Visual Studio Code, seleccione Ver>paleta de comandos y busque y seleccione Python: Seleccionar intérprete.
Seleccione la versión 3.7 instalada de Python o posterior.
Haga clic con el botón derecho en la carpeta modules de Visual Studio Code y elija Agregar módulo IoT Edge.
Elija Módulo de Python.
Asigne al módulo el nombre
avroFileWriter.Cuando se le solicite el repositorio de imágenes de Docker, use el mismo registro que usó al agregar el módulo Enrutador.
Copie los archivos del módulo de ejemplo en la solución.
copy C:\source\IoTEdgeAndMlSample\EdgeModules\modules\avroFileWriter\*.py C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avroFileWriter\Acepte la sobrescritura de main.py.
Tenga en cuenta que filemanager.py y schema.py se han agregado a la solución y main.py se ha actualizado.
Nota:
Al abrir un archivo de Python, es posible que se le pida que instale pylint. No es necesario instalar el linter para completar este tutorial.
Montaje vinculado para archivos de datos
Como se mencionó anteriormente, el módulo de escritura se basa en la presencia de un montaje de vinculación para escribir archivos Avro en el sistema de archivos del dispositivo.
Agregar directorio al dispositivo
En Azure Portal, inicie la máquina virtual del dispositivo IoT Edge si no se está ejecutando. Conéctese a él mediante SSH. La conexión requiere el nombre DNS que puede copiar desde la página de información general de la máquina virtual en Azure Portal.
ssh -l <user>@<vm name>.<region>.cloudapp.azure.comDespués de iniciar sesión, cree el directorio que contendrá los mensajes guardados del dispositivo receptor.
sudo mkdir -p /data/avrofilesActualice los permisos de directorio para que el contenedor pueda escribirlo.
sudo chmod ugo+rw /data/avrofilesValide que el directorio ahora tiene permiso de escritura (w) para el usuario, el grupo y el propietario.
ls -la /data
Agregar directorio al módulo
Para agregar el directorio al contenedor del módulo, modificaremos los Dockerfiles asociados al módulo avroFileWriter. Hay tres dockerfiles asociados con el módulo: Dockerfile.amd64, Dockerfile.amd64.debug y Dockerfile.arm32v7. Estos archivos deben mantenerse sincronizados en caso de que deseemos depurar o implementar en un dispositivo arm32. Para este artículo, céntrese solo en Dockerfile.amd64.
En la máquina virtual de desarrollo, abra el archivo C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avoFileWriter\Dockerfile.amd64 .
Modifique el archivo para que tenga un aspecto similar al del ejemplo siguiente:
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" ]Los comandos
mkdirychownindican al proceso de compilación de Docker que cree un directorio de nivel superior denominado /avrofiles en la imagen y, a continuación, para que el moduleuser sea el propietario de ese directorio. Es importante que estos comandos se inserten después de agregar el usuario del módulo a la imagen con el comandouseraddy antes de que el contexto cambie al moduleuser (USER moduleuser).Si es necesario, realice los cambios correspondientes en Dockerfile.amd64.debug y Dockerfile.arm32v7.
Agrega la configuración de asociación a AvroFileWriter
El último paso para crear el enlace es actualizar los archivos deployment.template.json (y deployment.debug.template.json) con la información de enlace.
Abra deployment.template.json.
Modifique la definición del módulo para avroFileWriter agregando el parámetro
Bindsque apunta el directorio de contenedor /avrofiles al directorio local del dispositivo perimetral. La definición del módulo debe coincidir con este ejemplo:"avroFileWriter": { "version": "1.0", "type": "docker", "status": "running", "restartPolicy": "always", "settings": { "image": "${MODULES.avroFileWriter}", "createOptions": { "HostConfig": { "Binds": [ "/data/avrofiles:/avrofiles" ] } } } }
Montaje enlazado para acceder a config.yaml
Es necesario agregar una vinculación más para el módulo de escritura. Este vínculo permite al módulo acceder para leer la cadena de conexión desde el archivo /etc/iotedge/config.yaml en el dispositivo IoT Edge. Necesitamos la cadena de conexión para crear un ioTHubClient para que podamos llamar al método upload_blob_async para cargar archivos en el centro de IoT. Los pasos para agregar este enlace son similares a los de la sección anterior.
Actualizar permiso de directorio
Conéctese al dispositivo IoT Edge mediante SSH.
ssh -l <user>@IoTEdge-<extension>.<region>.cloudapp.azure.comAgregue permiso de lectura al archivo config.yaml.
sudo chmod +r /etc/iotedge/config.yamlValide que los permisos se establecen correctamente.
ls -la /etc/iotedge/Asegúrese de que los permisos de config.yaml son -r--r--r---.
Agregar directorio al módulo
En la máquina de desarrollo, abra el archivo Dockerfile.amd64 .
Agregue un conjunto adicional de comandos
mkdirychownal archivo para que tenga el siguiente aspecto: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"]Realice los cambios correspondientes en Dockerfile.amd64.debug y Dockerfile.arm32v7.
Actualización de la configuración del módulo
Abra el archivo deployment.template.json .
Modifique la definición del módulo para avroFileWriter agregando una segunda línea al parámetro
Bindsque señala el directorio de contenedor (/app/iotconfig) al directorio local del 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" ] } } } }Realice los cambios correspondientes en deployment.debug.template.json.
Instalación de dependencias
El módulo writer depende de dos bibliotecas de Python, fastavro y PyYAML. Es necesario instalar las dependencias en nuestra máquina de desarrollo e indicar al proceso de compilación de Docker que los instale en la imagen del módulo.
PyYAML
En la máquina de desarrollo, abra el archivo
C:\source\IoTEdgeAndMlSample\EdgeSolution\modules\avoFileWriter\requirements.txty agregue "pyyaml" en una nueva línea del archivo.azure-iothub-device-client~=1.4.3 pyyamlAbra el archivo Dockerfile.amd64 y agregue un
pip installcomando para actualizar 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" ]En la línea de comandos, instale la biblioteca pyyaml en la máquina de desarrollo.
pip install pyyaml
Fastavro
En requirements.txt, agregue fastavro después de pyyaml.
azure-iothub-device-client~=1.4.3 pyyaml fastavroInstale fastavro en la máquina de desarrollo.
pip install fastavro
Reconfiguración de IoT Hub
Al introducir el dispositivo IoT Edge y los módulos en el sistema, hemos cambiado nuestras expectativas sobre qué datos se enviarán al centro y para qué propósito. Es necesario volver a configurar el enrutamiento en el centro para adaptarnos a nuestra nueva realidad.
Nota:
Se vuelve a configurar el centro antes de implementar módulos porque parte de la configuración del centro, específicamente la carga de archivos, debe configurarse correctamente para que el módulo avroFileWriter se ejecute correctamente.
Configuración de la ruta de los mensajes RUL en IoT Hub
Con el enrutador y el clasificador en su lugar, esperamos recibir mensajes normales que contengan solo el identificador de dispositivo y la predicción de RUL para el dispositivo. Queremos enrutar los datos RUL a su propia ubicación de almacenamiento, donde podemos supervisar el estado de los dispositivos, compilar informes y desencadenar alertas según sea necesario. Al mismo tiempo, queremos que los datos del dispositivo que todavía se envían directamente a través de un dispositivo descendente que aún no está conectado a nuestro dispositivo IoT Edge continúen enrutándose a la ubicación de almacenamiento actual.
Creación de una ruta de mensajes RUL
En el portal de Azure, navegue a su IoT Hub.
En el menú del panel izquierdo, en Configuración del centro, seleccione Enrutamiento de mensajes.
En la pestaña Rutas , seleccione Agregar.
Asigne el nombre RulMessageRoute a la ruta.
Seleccione Agregar punto de conexión a la derecha del selector Punto de conexión y elija Almacenamiento.
En la página Agregar un punto de conexión de almacenamiento , asigne al punto de conexión el nombre ruldata.
Seleccione Elegir un contenedor.
En la página Cuentas de almacenamiento, busque la cuenta de almacenamiento que usa en este tutorial, que se denomina como iotedgeandml<sufijo único>.
Seleccione el contenedor ruldata y haga clic en Seleccionar.
De nuevo en la página Agregar un punto de conexión de almacenamiento , seleccione Crear para crear el punto de conexión de almacenamiento.
De nuevo en la página Agregar una ruta , para la consulta enrutamiento, reemplace por
truela siguiente consulta:IS_DEFINED($body.PredictedRul) AND NOT IS_DEFINED($body.OperationalSetting1)Expanda la sección Prueba y, a continuación, la sección Cuerpo del mensaje . Reemplace el cuerpo del mensaje por este ejemplo de nuestros mensajes esperados:
{ "ConnectionDeviceId": "aaLeafDevice_1", "CorrelationId": "b27e97bb-06c5-4553-a064-e9ad59c0fdd3", "PredictedRul": 132.62721409309165, "CycleTime": 64.0 }Seleccione Ruta de prueba. Si la prueba se realiza correctamente, verá "El mensaje coincide con la consulta".
Haga clic en Guardar.
Actualizar la ruta turbofanDeviceDataToStorage
No queremos enrutar los nuevos datos de predicción a nuestra ubicación de almacenamiento antigua, por lo que se actualiza la ruta para evitarlo.
En la página Enrutamiento de mensajes de IoT Hub, seleccione la pestaña Rutas .
Seleccione turbofanDeviceDataToStorage o cualquier nombre que haya asignado a la ruta de datos del dispositivo inicial.
Actualiza la consulta de enrutamiento a
IS_DEFINED($body.OperationalSetting1)Expanda la sección Prueba y, a continuación, la sección Cuerpo del mensaje . Reemplace el mensaje por este ejemplo de nuestros mensajes esperados:
{ "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 }Seleccione Ruta de prueba. Si la prueba se realiza correctamente, verá "El mensaje coincide con la consulta".
Seleccione Guardar.
Configuración de la carga de archivos
Configure la característica de carga de archivos de IoT Hub para permitir que el módulo de escritura de archivos cargue archivos en el almacenamiento.
En el menú del panel izquierdo de IoT Hub, en Configuración del centro, elija Carga de archivos.
Seleccione Contenedor de Azure Storage.
Seleccione la cuenta de almacenamiento en la lista.
Seleccione el contenedor que comienza con azureml-blobstore anexado con un guid y haga clic en Seleccionar.
Seleccione Guardar. El portal le notifica cuando se ha completado el guardado.
Nota:
No estamos activando la notificación de carga para este tutorial, pero consulte Recepción de una notificación de carga de archivos para obtener más información sobre cómo controlar la notificación de carga de archivos.
Compilación, publicación e implementación de módulos
Ahora que hemos realizado los cambios de configuración, estamos listos para compilar las imágenes y publicarlas en nuestro registro de contenedor de Azure. El proceso de compilación usa el archivo deployment.template.json para determinar qué módulos se deben compilar. La configuración de cada módulo, incluida la versión, se encuentra en el archivo module.json de la carpeta del módulo. El proceso de compilación ejecuta primero una compilación de Docker en los Dockerfiles que coinciden con la configuración actual que se encuentra en el archivo module.json para crear una imagen. A continuación, publica la imagen en el registro desde el archivo module.json con una etiqueta de versión que coincida con la del archivo module.json. Por último, genera un manifiesto de implementación específico de la configuración (por ejemplo, deployment.amd64.json), que se implementará en el dispositivo IoT Edge. El dispositivo IoT Edge lee la información del manifiesto de implementación y, en función de las instrucciones, descargará los módulos, configurará las rutas y establecerá las propiedades deseadas. Este método de implementación tiene dos efectos secundarios que debe tener en cuenta:
Retraso de implementación: dado que el entorno de ejecución de IoT Edge debe reconocer el cambio en sus propiedades deseadas antes de empezar a volver a configurarse, puede tardar algún tiempo después de implementar los módulos hasta que el tiempo de ejecución los recoge y empieza a actualizar el dispositivo IoT Edge.
Las versiones del módulo son importantes: si publica una nueva versión del contenedor de un módulo en el registro de contenedor con las mismas etiquetas de versión que el módulo anterior, el entorno de ejecución no descargará la nueva versión del módulo. Realiza una comparación de la etiqueta de versión de la imagen local y la imagen deseada del manifiesto de implementación. Si esas versiones coinciden, el entorno de ejecución no realiza ninguna acción. Por lo tanto, es importante incrementar la versión del módulo cada vez que quiera implementar nuevos cambios. Incremente la versión cambiando la propiedad version en la propiedad tag del archivo module.json para el módulo que va a cambiar. A continuación, compile y publique el 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" }
Construir y publicar
En la máquina virtual de desarrollo, inicie Docker si no se está ejecutando.
Desde Visual Studio Code, abre un nuevo terminal con línea de comandos y accede a tu registro de contenedores de Azure (ACR).
Puede encontrar los valores de nombre de usuario, contraseña y servidor de inicio de sesión necesarios en Azure Portal. El nombre del registro de contenedor tiene el formato "turbofandemo<identificador único>". En el menú del panel izquierdo, en Configuración, seleccione Claves de acceso para verlos .
docker login -u <ACR username> -p <ACR password> <ACR login server>
- En Visual Studio Code, haga clic con el botón derecho en deployment.template.json y elija Compilar e insertar solución de IoT Edge.
Visualización de módulos en el Registro
Una vez completada correctamente la compilación, podremos usar Azure Portal para revisar los módulos publicados.
Abra Azure Container Registry para este tutorial. El nombre del registro de contenedor tiene el formato "turbofandemo<identificador único>".
En el menú del panel izquierdo, en Servicios, seleccione Repositorios.
Tenga en cuenta que ambos módulos creados, avrofilewriter y turbofanrouter, aparecen como repositorios.
Seleccione turbofanrouter y observe que ha publicado una imagen etiquetada como 0.0.1-amd64.
Implementación de módulos en un dispositivo IoT Edge
Hemos creado y configurado los módulos en nuestra solución, ahora implementaremos los módulos en el dispositivo IoT Edge.
En Visual Studio Code, haga clic con el botón derecho en el archivo deployment.amd64.json de la carpeta config.
Elija Crear implementación para un único dispositivo.
Elija el dispositivo IoT Edge, aaTurboFanEdgeDevice.
Actualice el panel dispositivos de Azure IoT Hub en el explorador de Visual Studio Code. Debería ver que los tres módulos nuevos se implementan pero aún no se están ejecutando.
Vuelva a actualizar después de unos minutos y verá que se ejecutan los módulos.
Nota:
Los módulos pueden tardar varios minutos en iniciarse y establecerse en un estado de ejecución estable. Durante ese tiempo, es posible que vea que los módulos se inician y detienen mientras intentan establecer una conexión con el módulo del centro de IoT Edge.
Diagnóstico de errores
En esta sección, compartimos algunas técnicas para comprender lo que ha ido mal con un módulo o módulos. A menudo, se puede detectar un fallo en el estado de Visual Studio Code.
Identificación de módulos con errores
Visual Studio Code: Examine el panel Dispositivos de Azure IoT Hub. Si la mayoría de los módulos están en ejecución, pero uno está detenido, debe investigar más a fondo el módulo detenido. Si todos los módulos están en estado detenido durante un largo período de tiempo, también puede indicar un error.
Azure Portal: Al navegar a ioT Hub en el portal y, a continuación, buscar la página de detalles del dispositivo (en IoT Edge, profundizar en el dispositivo), es posible que encuentre que un módulo ha notificado un error o que nunca ha notificado nada al centro de IoT.
Diagnóstico desde el dispositivo
Al iniciar sesión en el dispositivo IoT Edge (la máquina virtual Linux en nuestro caso), puede obtener acceso a una buena cantidad de información sobre el estado de los módulos. El mecanismo principal que usamos son los comandos de Docker que nos permiten examinar los contenedores e imágenes del dispositivo.
Inicie sesión en el dispositivo IoT Edge:
ssh -l <user>@IoTEdge-<extension>.<region>.cloudapp.azure.comEnumerar todos los contenedores en ejecución. Esperamos ver un contenedor para cada módulo con un nombre que corresponda al módulo. Además, este comando muestra la imagen exacta del contenedor, incluida la versión, para que pueda coincidir con sus expectativas. También puede enumerar imágenes sustituyendo "image" por "container" en el comando .
sudo docker container lsObtenga los registros de un contenedor. Este comando muestra todo lo que se haya escrito en StdErr y StdOut dentro del contenedor. Este comando funciona para contenedores que se han iniciado y, a continuación, han muerto por algún motivo. También es útil para comprender lo que ha ocurrido con los contenedores edgeAgent o edgeHub.
sudo docker container logs <container id>Inspeccione un contenedor. Este comando proporciona una gran cantidad de información sobre la imagen. Los datos se pueden filtrar en función de lo que busque. Por ejemplo, si desea ver si las vinculaciones en el avroFileWriter son correctas, puede usar el comando:
sudo docker container inspect -f "{{ json .Mounts }}" avroFileWriter | python -m json.toolConéctese a un contenedor en ejecución. Este comando puede ser útil si desea examinar el contenedor mientras se ejecuta:
sudo docker exec -it avroFileWriter bash
Limpieza de recursos
Este tutorial forma parte de un conjunto en el que cada artículo se basa en el trabajo realizado en los anteriores. Espere para limpiar cualquier recurso hasta completar el tutorial final.
Pasos siguientes
En este artículo, hemos creado una solución de IoT Edge en Visual Studio Code con tres módulos: un clasificador, un enrutador y un escritor o cargador de archivos. Configuramos las rutas para permitir que los módulos se comuniquen entre sí en el dispositivo perimetral. Hemos modificado la configuración del dispositivo perimetral y hemos actualizado los Dockerfiles para instalar dependencias y agregar montajes de enlace a los contenedores de los módulos.
A continuación, hemos actualizado la configuración de IoT Hub para enrutar los mensajes en función del tipo y controlar las cargas de archivos. Con todo en su lugar, implementamos los módulos en el dispositivo IoT Edge y garantizamos que los módulos se estaban ejecutando correctamente.
Continúe con el siguiente artículo para empezar a enviar datos y ver la solución en acción.