Tutorial: Desarrollo de módulos de IoT Edge mediante Visual Studio Code

Se aplica a:IoT Edge 1.4 checkmark IoT Edge 1.4

Importante

IoT Edge 1.4 es la versión admitida. Si está usando una versión anterior, consulte Actualización de IoT Edge.

En este tutorial se explica cómo desarrollar e implementar código propio en un dispositivo IoT Edge. Los módulos Azure IoT Edge se pueden usar para implementar código que, a su vez, implementa una lógica de negocios directamente en los dispositivos IoT Edge. En el inicio rápido Implementación de código en un dispositivo Linux, creó un dispositivo IoT Edge e implementó un módulo desde Azure Marketplace.

En este artículo se incluyen los pasos para dos herramientas de desarrollo de IoT Edge.

  • Línea de comandos (CLI) de la herramienta de desarrollo de Azure IoT Edge. Para el desarrollo se prefiere esta herramienta.
  • Extensión de Herramientas de Azure IoT Edge para Visual Studio Code. La extensión está en modo de mantenimiento.

Use el botón del selector de la herramienta al principio de este artículo para seleccionar la versión de la herramienta.

En este tutorial, aprenderá a:

  • Configurar una máquina de desarrollo.
  • Uso de las herramientas de IoT Edge para crear un proyecto nuevo.
  • Compilar el proyecto como un contenedor Docker y almacenarlo en un registro de contenedor de Azure.
  • Implementar el código en un dispositivo IoT Edge.

El módulo IoT Edge que creó en este tutorial filtra lo datos sobre la temperatura generados por el dispositivo. Solo envía mensajes a los niveles superiores si la temperatura sobrepasa el umbral especificado. Este tipo de análisis perimetral resulta útil para reducir la cantidad de datos que se comunican a la nube y se almacenan en ella.

Requisitos previos

Una máquina de desarrollo:

  • Use su propio equipo o una máquina virtual.
  • La máquina de desarrollo deberá admitir la virtualización anidada para ejecutar un motor de contenedor.
  • La mayor parte de los sistemas operativos que pueden ejecutar un motor de contenedor se pueden usar para desarrollar módulos IoT Edge para dispositivos Linux. En este tutorial se usa un equipo Windows, pero se indican las diferencias conocidas con macOS o Linux.
  • Instalación de Visual Studio Code
  • Instale la CLI de Azure.

Un dispositivo de Azure IoT Edge:

Recursos en la nube:

  • Una instancia de IoT Hub de nivel estándar o gratis en Azure.

Si no tiene una suscripción a Azure, cree una cuenta gratuita de Azure antes de empezar.

Sugerencia

Para obtener instrucciones sobre la depuración interactiva en Visual Studio Code o Visual Studio 2022:

En este tutorial se enseñan los pasos del desarrollo en Visual Studio Code.

Conceptos clave

En este tutorial se realiza un recorrido por el desarrollo de un módulo IoT Edge. Un módulo loT Edge es un contenedor con código ejecutable. En un dispositivo IoT Edge se pueden implementar uno o varios módulos. Los módulos realizan tareas concretas, como la ingesta de datos de sensores, la limpieza y el análisis de datos, o el envío a un centro de IoT. Para más información, consulte Información sobre los módulos Azure IoT Edge.

Cuando se desarrollan módulos IoT Edge, es importante conocer la diferencia entre la máquina de desarrollo y el dispositivo IoT Edge de destino en el que se implemente el módulo. El contenedor que cree para contener el código del módulo debe coincidir con el sistema operativo del dispositivo de destino. Por ejemplo, el escenario más común es que alguien desarrolle un módulo en un equipo Windows que pretende tener como destino un dispositivo Linux en el que se ejecuta IoT Edge. En ese caso, el sistema operativo del contenedor sería Linux. A medida que avance en este tutorial, tenga en cuenta la diferencia entre el sistema operativo de la máquina de desarrollo y el sistema operativo del contenedor.

Sugerencia

Si usa IoT Edge para Linux en Windows, el dispositivo de destino del escenario es la máquina virtual de Linux, no el host de Windows.

Este tutorial va dirigido a dispositivos de destino que ejecutan IoT Edge con contenedores de Linux. Puede usar el sistema operativo que prefiera, siempre que dicha máquina ejecute contenedores Linux. Se recomienda usar Visual Studio Code para desarrollar con contenedores de Linux, así que es lo que se usa en este tutorial. También se puede usar Visual Studio, aunque hay diferencias en lo relativo a la compatibilidad entre ambas herramientas.

En la tabla siguiente se enumeran los escenarios de desarrollo compatibles con los contenedores de Linux en Visual Studio Code y Visual Studio.

Visual Studio Code Visual Studio 2019/2022
Arquitectura de dispositivos Linux Linux AMD64
Linux ARM32v7
Linux ARM64
Linux AMD64
Linux ARM32
Linux ARM64
Servicios de Azure Comprobación de
Azure Stream Analytics
Azure Machine Learning
Idiomas C
C#
Java
Node.js
Python
C
C#
Más información Azure IoT Edge para Visual Studio Code Azure IoT Edge Tools para Visual Studio 2019
Azure IoT Edge Tools para Visual Studio 2022

Instalación de un motor de contenedor

Los módulos IoT Edge se empaquetan como contenedores, por lo que necesita un sistema de administración de contenedores compatible con Docker en la máquina de desarrollo para compilarlos y administrarlos. Se recomienda Docker Desktop para el desarrollo debido a su popularidad y la compatibilidad de las características. Docker Desktop en Windows permite cambiar entre contenedores Linux y Windows para poder desarrollar módulos para los distintos tipos de dispositivos IoT Edge.

Use la documentación de Docker para realizar la instalación en la máquina de desarrollo:

Herramientas de configuración

Instalar la herramienta de desarrollo de Azure IoT Edge basada en Python para crear la solución de IoT Edge. Hay dos opciones:

Importante

La extensión de Herramientas de Azure IoT Edge para Visual Studio Code está en modo de mantenimiento. La herramienta de desarrollo preferida es la línea de comandos (CLI) Azure IoT Edge Dev Tool.

Use las extensiones de IoT para Visual Studio Code para desarrollar módulos IoT Edge. Estas extensiones ofrecen plantillas de proyecto, automatizan la creación del manifiesto de implementación y permiten supervisar y administrar dispositivos IoT Edge. En esta sección, se instalan Visual Studio Code y la extensión de IoT y luego se configurar una cuenta de Azure para administrar recursos de IoT Hub desde dentro de Visual Studio Code.

  1. Instalar la extensión de Azure IoT Edge.

  2. Instalar la extensión de Azure IoT Hub.

  3. Después de instalar extensiones, abra la paleta de comandos seleccionando Ver>Paleta de comandos.

  4. En la paleta de comandos, busque y seleccione Azure IoT Hub: Select IoT Hub (Azure IoT Hub: seleccione IoT Hub). Siga las instrucciones para seleccionar su suscripción de Azure y el centro de IoT.

  5. Abra la sección del explorador de Visual Studio Code, para lo que puede seleccionar el icono pertinente en la barra de actividad de la izquierda, o bien seleccionar Ver>Explorador.

  6. En la parte inferior de dicha sección, expanda el menú Azure IoT Hub / Devices (Azure IoT Hub/Dispositivos). Debería ver los dispositivos y los dispositivos IoT Edge asociados con el centro de IoT que seleccionó en la paleta de comandos.

Instalación de herramientas específicas del lenguaje

Instale las herramientas específicas del lenguaje en el que vaya a trabajar:

Creación de un Registro de contenedor

En este tutorial, puede usar las extensiones de Azure IoT Edge y Azure IoT Hub a fin de generar un módulo y crear una imagen de contenedor a partir de los archivos. Después, insertará esta imagen en un Registro donde se almacenan y administran las imágenes. Por último, implementará la imagen en el Registro para que se ejecute en el dispositivo IoT Edge.

Importante

La extensión de Visual Studio Code de Azure IoT Edge está en modo de mantenimiento.

Puede usar cualquier registro compatible con Docker para almacenar las imágenes de contenedor. Dos de los servicios de registro de Docker más conocidos son Azure Container Registry y Docker Hub. En este tutorial, utilizaremos Azure Container Registry.

Si no dispone de un registro de contenedores, siga estos pasos para crear uno nuevo en Azure:

  1. En Azure Portal, seleccione Crear un recurso>Contenedores>Container Registry.

  2. Especifique los siguientes valores obligatorios para crear el registro de contenedor:

    Campo Value
    Suscripción Seleccione una suscripción en la lista desplegable.
    Resource group Utilice el mismo grupo de recursos para todos los recursos de prueba que se crean en los inicios rápidos y tutoriales de IoT Edge. Por ejemplo, IoTEdgeResources.
    Nombre de registro Especifique un nombre único.
    Location Elija una ubicación cercana a usted.
    SKU Seleccione Básica.
  3. Seleccione Revisar y crear y, a continuación, Crear.

  4. Seleccione el nuevo registro de contenedor en la sección Recursos de la página principal de Azure Portal para abrirlo.

  5. En el panel izquierdo del registro de contenedor, seleccione Claves de acceso en el menú ubicado en Configuración.

    Screenshot of the Access Keys menu location.

  6. Habilite Usuario administrador con el botón de alternancia para ver el Nombre de usuario y la Contraseña para el registro de contenedor.

  7. Copie los valores de Servidor de inicio de sesión, Nombre de usuario y Contraseña, y guárdelos en cualquier lugar que le resulte práctico. Dichos valores se usan en todo el tutorial para proporcionar acceso al registro de contenedor.

Creación de un nuevo proyecto de módulo

La extensión de Azure IoT Edge ofrece plantillas de proyecto para todos los lenguajes del módulo IoT Edge admitidos que haya en Visual Studio Code. Estas plantillas tienen todos los archivos y el código que se necesita para implementar un módulo de trabajo y probar IoT Edge o le proporcionan a un punto de partida para personalizar la plantilla con su propia lógica de negocios.

Creación de una plantilla de proyecto

La herramienta de desarrollo de IoT Edge simplifica el desarrollo de Azure IoT Edge con comandos controlados por variables de entorno. Le permite comenzar con el desarrollo de IoT Edge con el contenedor de desarrollo de IoT Edge y el andamiaje de soluciones de IoT Edge que tiene un módulo predeterminado y todos los archivos de configuración necesarios.

  1. Cree un directorio para la solución con la ruta de acceso que prefiera. Cambie al directorio iotedgesolution.

    mkdir c:\dev\iotedgesolution
    cd c:\dev\iotedgesolution
    
  2. Use el comando iotedgedev solution init para crear una solución y configurar Azure IoT Hub en el lenguaje de desarrollo que prefiera.

    iotedgedev solution init --template csharp
    

El script iotedgedev solution init le pide que complete varios pasos, entre los que se incluyen:

  • Autentíquese en Azure
  • Elegir una suscripción de Azure
  • Elegir o crear un grupo de recursos
  • Elegir o crear una instancia de Azure IoT Hub
  • Elegir o crear un dispositivo de Azure IoT Edge

Utilice Visual Studio Code y la extensión de Azure IoT Edge. Primero debe crear una solución y, a continuación, generar el primer módulo de esa solución. Cada solución puede contener varios módulos.

  1. Seleccione Ver>Paleta de comandos.
  2. En la paleta de comandos, escriba y ejecute el comando Azure IoT Edge: New IoT Edge solution (Nueva solución de IoT Edge).
  3. Vaya a la carpeta en la que desea crear la solución y después haga clic en Seleccionar carpeta.
  4. Escriba un nombre para la solución.
  5. Seleccione una plantilla de módulo para que su lenguaje de desarrollo preferido sea el primer módulo de la solución.
  6. Escriba un nombre para el módulo. Elija un nombre que sea único dentro del registro de contenedor.
  7. Proporcione el nombre del repositorio de imágenes del módulo. Visual Studio Code rellena automáticamente el nombre del módulo como localhost:5000/<nombre del módulo>. Reemplácelo por su propia información de registro. Utilice localhost si usa un registro de Docker local para realizar pruebas. Si va a usar Azure Container Registry, utilice el servidor de inicio de sesión de la configuración del registro. El servidor de inicio de sesión se parece al <nombre del registro>.azurecr.io. Reemplace solo la sección localhost:5000 de la cadena para que el resultado final se parezca a <nombre del registro>.azurecr.io/ <nombre del módulo> .

Visual Studio Code toma la información que le ha proporcionado, crea una solución IoT Edge y la carga en una nueva ventana.

Después de la creación de la solución, estos archivos principales estarán en la solución:

  • Una carpeta .vscode, que contiene el archivo de configuración launch.json.

  • Una carpeta modules que contiene subcarpetas para cada módulo. Dentro de la subcarpeta de cada módulo, hay un archivo module.json que controla cómo se compilan e implementan los módulos.

  • Un archivo .env enumera las variables de entorno. La variable de entorno para el registro de contenedor es localhost:5000 de forma predeterminada.

  • Dos archivos de implementación de módulos denominados deployment.template.json y deployment.debug.template.json enumeran los módulos que se van a implementar en el dispositivo. De forma predeterminada, la lista incluye los módulos del sistema de IoT Edge (edgeAgent y edgeHub) y módulos de ejemplo como:

    Nota

    Los módulos exactos instalados pueden depender del idioma que prefiera.

Establecimiento de la versión del entorno de ejecución de IoT Edge

La versión más reciente del módulo del sistema de IoT Edge estable es la 1.4. Establezca los módulos del sistema en la versión 1.4.

  1. En Visual Studio Code, abra el archivo de manifiesto deployment.template.json. El manifiesto de implementación es un documento JSON que describe los módulos que se van a configurar en los dispositivos IoT Edge de destino.

  2. Cambie la versión en tiempo de ejecución de las imágenes edgeAgent y edgeHub del módulo en tiempo de ejecución del sistema. Por ejemplo, si quiere usar la versión 1.4 del entorno de ejecución de IoT Edge, cambie las líneas siguientes en el archivo de manifiesto de implementación:

    "systemModules": {
        "edgeAgent": {
    
            "image": "mcr.microsoft.com/azureiotedge-agent:1.4",
    
        "edgeHub": {
    
            "image": "mcr.microsoft.com/azureiotedge-hub:1.4",
    

Especificación de la credenciales del registro para el agente de IoT Edge

El archivo del entorno almacena las credenciales del registro de contenedor y las comparte con el runtime de IoT Edge. El entorno de ejecución necesita estas credenciales para extraer las imágenes de contenedor e insertarlas en el dispositivo IoT Edge.

La extensión de IoT Edge intenta extraer de Azure las credenciales del registro del contenedor y rellenar con ellas el archivo de entorno.

Nota

Solo se crea el archivo de entorno si proporciona un repositorio de imágenes para el módulo. Si aceptó los valores predeterminados de localhost para probar y depurar localmente, no es necesario declarar las variables de entorno.

Compruebe si las credenciales existen. Si no lo están, agréguelas ahora:

  1. Si Azure Container Registry es su registro, establezca un nombre de usuario y una contraseña de Azure Container Registry. Obtenga estos valores en el menú Configuración>Claves de acceso del registro de contenedor de Azure Portal.

  2. Abra el archivo .env en la solución del módulo.

  3. Agregue los valores de nombre de usuario y contraseña que ha copiado del registro de contenedor de Azure. Por ejemplo:

    CONTAINER_REGISTRY_SERVER="myacr.azurecr.io"
    CONTAINER_REGISTRY_USERNAME="myacr"
    CONTAINER_REGISTRY_PASSWORD="<registry_password>"
    
  4. Guarde los cambios en el archivo .env.

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, se recomienda una opción de autenticación con privilegios mínimos, como las entidades de servicio o los tokens de ámbito de repositorio. Para más información, consulte Administración del acceso al registro de contenedor.

Arquitectura de destino

Debe seleccionar qué arquitectura tiene como destino con cada solución, ya que ello afecta a la forma en que se crea y ejecuta el contenedor. La opción predeterminada es Linux AMD64. Para este tutorial, usaremos una máquina virtual de Ubuntu como dispositivo IoT Edge y mantendremos el valor predeterminado de amd64.

Si necesita cambiar la arquitectura de destino de la solución, siga estos pasos.

  1. Abra la paleta de comandos y busque Azure IoT Edge: Set Default Target Platform for Edge Solution (Establecer la plataforma de destino predeterminada para la solución perimetral), o bien seleccione el icono de acceso directo en la barra lateral en la parte inferior de la ventana.

  2. En la paleta de comandos, seleccione la arquitectura de destino en la lista de opciones.

La arquitectura de destino se establece al crear la imagen de contenedor en un paso posterior.

Actualización del módulo con código personalizado

Cada plantilla incluye un código de ejemplo, que toma los datos del sensor simulado del módulo SimulatedTemperatureSensor y los enruta al centro de IoT. El módulo de ejemplo recibe los mensajes y, después, los pasa. La funcionalidad de canalización muestra un concepto importante de IoT Edge, cómo se comunican los módulos entre sí.

Cada módulo puede tener varias colas de entrada y salida declaran en su código. El centro de IoT Edge que se ejecuta en el dispositivo enruta los mensajes de la salida de un módulo en la entrada de uno o varios módulos. El código específico para declarar las entradas y salidas varía de un lenguaje a otro, pero el concepto es el mismo en todos los módulos. Para más información acerca del enrutamiento entre módulos, consulte Declaración de rutas.

El código de C# de ejemplo que acompaña a la plantilla del proyecto usa la clase ModuleClient del SDK de IoT Hub para .NET.

  1. En el explorador de Visual Studio Code, abra módulos>filtermodule>ModuleBackgroundService.cs.

  2. En la parte superior del espacio de nombres filtermodule, agregue tres instrucciones using para los tipos que se usarán más adelante en:

    using System.Collections.Generic;     // For KeyValuePair<>
    using Microsoft.Azure.Devices.Shared; // For TwinCollection
    using Newtonsoft.Json;                // For JsonConvert
    
  3. Agregue la variable temperatureThreshold a la clase ModuleBackgroundService. Esta variable establece el valor que debe superar la temperatura medida para que los datos se envíen al centro de IoT.

    static int temperatureThreshold { get; set; } = 25;
    
  4. Agregue las clases MessageBody, Machine y Ambient. Estas clases definen el esquema esperado para el cuerpo de los mensajes entrantes.

    class MessageBody
    {
        public Machine machine {get;set;}
        public Ambient ambient {get; set;}
        public string timeCreated {get; set;}
    }
    class Machine
    {
        public double temperature {get; set;}
        public double pressure {get; set;}
    }
    class Ambient
    {
        public double temperature {get; set;}
        public int humidity {get; set;}
    }
    
  5. Busque la función ExecuteAsync. Esta función crea y configura un objeto ModuleClient, que permite al módulo conectarse al entorno de ejecución de Azure IoT Edge local para enviar y recibir mensajes. Después de crear ModuleClient, el código lee el valor temperatureThreshold en las propiedades deseadas del módulo gemelo. El código registra una devolución de llamada para recibir mensajes desde un centro de IoT Edge mediante el punto de conexión llamado input1.

    Reemplace la llamada al método ProcessMessageAsync por uno nuevo que actualice el nombre del punto de conexión y el método al que se llama cuando llega la entrada. Además, agregue un método SetDesiredPropertyUpdateCallbackAsync para las actualizaciones de las propiedades deseadas. Para realizar este cambio, reemplace la última línea del método ExecuteAsync con el siguiente código:

    // Register a callback for messages that are received by the module.
    // await _moduleClient.SetInputMessageHandlerAsync("input1", PipeMessage, cancellationToken);
    
    // Read the TemperatureThreshold value from the module twin's desired properties
    var moduleTwin = await _moduleClient.GetTwinAsync();
    await OnDesiredPropertiesUpdate(moduleTwin.Properties.Desired, _moduleClient);
    
    // Attach a callback for updates to the module twin's desired properties.
    await _moduleClient.SetDesiredPropertyUpdateCallbackAsync(OnDesiredPropertiesUpdate, null);
    
    // Register a callback for messages that are received by the module. Messages received on the inputFromSensor endpoint are sent to the FilterMessages method.
    await _moduleClient.SetInputMessageHandlerAsync("inputFromSensor", FilterMessages, _moduleClient);
    
  6. Agregue el método onDesiredPropertiesUpdate a la clase ModuleBackgroundService. Este método recibe las actualizaciones sobre las propiedades que se quieren del módulo gemelo y actualiza la variable temperatureThreshold para que coincida. Todos los módulos tienen su propio módulo gemelo, que le permite configurar el código que se ejecuta dentro de un módulo directamente desde la nube.

    static Task OnDesiredPropertiesUpdate(TwinCollection desiredProperties, object userContext)
    {
        try
        {
            Console.WriteLine("Desired property change:");
            Console.WriteLine(JsonConvert.SerializeObject(desiredProperties));
    
            if (desiredProperties["TemperatureThreshold"]!=null)
                temperatureThreshold = desiredProperties["TemperatureThreshold"];
    
        }
        catch (AggregateException ex)
        {
            foreach (Exception exception in ex.InnerExceptions)
            {
                Console.WriteLine();
                Console.WriteLine("Error when receiving desired property: {0}", exception);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine();
            Console.WriteLine("Error when receiving desired property: {0}", ex.Message);
        }
        return Task.CompletedTask;
    }
    
  7. Agregue el método FilterMessages. Se llama a este método cada vez que el módulo recibe un mensaje del centro de IoT Edge. Filtra los mensajes que informan de temperaturas por debajo del umbral de temperatura que se establecen mediante el módulo gemelo. También agrega la propiedad MessageType al mensaje con el valor establecido en Alerta.

    async Task<MessageResponse> FilterMessages(Message message, object userContext)
    {
        var counterValue = Interlocked.Increment(ref _counter);
        try
        {
            ModuleClient moduleClient = (ModuleClient)userContext;
            var messageBytes = message.GetBytes();
            var messageString = Encoding.UTF8.GetString(messageBytes);
            Console.WriteLine($"Received message {counterValue}: [{messageString}]");
    
            // Get the message body.
            var messageBody = JsonConvert.DeserializeObject<MessageBody>(messageString);
    
            if (messageBody != null && messageBody.machine.temperature > temperatureThreshold)
            {
                Console.WriteLine($"Machine temperature {messageBody.machine.temperature} " +
                    $"exceeds threshold {temperatureThreshold}");
                using (var filteredMessage = new Message(messageBytes))
                {
                    foreach (KeyValuePair<string, string> prop in message.Properties)
                    {
                        filteredMessage.Properties.Add(prop.Key, prop.Value);
                    }
    
                    filteredMessage.Properties.Add("MessageType", "Alert");
                    await moduleClient.SendEventAsync("output1", filteredMessage);
                }
            }
    
            // Indicate that the message treatment is completed.
            return MessageResponse.Completed;
        }
        catch (AggregateException ex)
        {
            foreach (Exception exception in ex.InnerExceptions)
            {
                Console.WriteLine();
                Console.WriteLine("Error in sample: {0}", exception);
            }
            // Indicate that the message treatment is not completed.
            var moduleClient = (ModuleClient)userContext;
            return MessageResponse.Abandoned;
        }
        catch (Exception ex)
        {
            Console.WriteLine();
            Console.WriteLine("Error in sample: {0}", ex.Message);
            // Indicate that the message treatment is not completed.
            ModuleClient moduleClient = (ModuleClient)userContext;
            return MessageResponse.Abandoned;
        }
    }
    
  8. Guarde el archivo ModuleBackgroundService.cs.

  9. En el explorador de Visual Studio Code, abra el archivo deployment.template.json en el área de trabajo de la solución de IoT Edge.

  10. Puesto que hemos cambiado el nombre del punto de conexión en el que el módulo escucha, también es necesario actualizar las rutas en el manifiesto de implementación para que edgeHub envíe mensajes al nuevo punto de conexión.

    Busque la sección routes en el módulo gemelo $edgeHub. Actualice la ruta sensorTofiltermodule para reemplazar input1 por inputFromSensor:

    "sensorTofiltermodule": "FROM /messages/modules/tempSensor/outputs/temperatureOutput INTO BrokeredEndpoint(\"/modules/filtermodule/inputs/inputFromSensor\")"
    
  11. Agregue el módulo gemelo de filtermodule al manifiesto de implementación. Inserte el siguiente contenido JSON en la parte inferior de la sección modulesContent, después del módulo gemelo $edgeHub:

       "filtermodule": {
           "properties.desired":{
               "TemperatureThreshold":25
           }
       }
    
  12. Guarde el archivo deployment.template.json.

Compilación e inserción de la solución

Actualizó el código del módulo y la plantilla de implementación para ayudar a conocer algunos conceptos clave de la implementación. Ya está listo para que compilar la imagen de contenedor del módulo e insertarla en el registro de contenedor.

En Visual Studio Code, abra el archivo de manifiesto de implementación deployment.template.json. El manifiesto de implementación describe los módulos que se van a configurar en los dispositivos IoT Edge de destino. Antes de la implementación, debe actualizar las credenciales de Azure Container Registry y las imágenes del módulo con los valores de createOptions adecuados. Para más información sobre los valores de createOption, consulte Configuración de las opciones de creación de contenedores para módulos de IoT Edge.

Si usa un Azure Container Registry para almacenar la imagen del módulo, agregue sus credenciales a la sección modulesContent>edgeAgent>configuración>registryCredentials en deployment.template.json. Reemplace myacr por su propio nombre del registro y proporcione la contraseña y la dirección del servidor de inicio de sesión. Por ejemplo:

"registryCredentials": {
    "myacr": {
        "username": "myacr",
        "password": "<your_acr_password>",
        "address": "myacr.azurecr.io"
    }
}

Agregue o reemplace el siguiente contenido con cadenas para el valor createOptions en cada sistema (edgeHub y edgeAgent) y módulo personalizado (filtermodule y tempSensor) que aparece enumerado. Cambie los valores si es necesario.

"createOptions": "{\"HostConfig\":{\"PortBindings\":{\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}],\"443/tcp\":[{\"HostPort\":\"443\"}]}}}"

Por ejemplo, la configuración filtermodule debería ser similar a:

"filtermodule": {
"version": "1.0",
"type": "docker",
"status": "running",
"restartPolicy": "always",
"settings": {
   "image": "myacr.azurecr.io/filtermodule:0.0.1-amd64",
   "createOptions": "{\"HostConfig\":{\"PortBindings\":{\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}],\"443/tcp\":[{\"HostPort\":\"443\"}]}}}"
}

Imagen de Docker del módulo de compilación

Abra el terminal integrado de Visual Studio Code seleccionando Terminal>Nuevo terminal.

Use el comando dotnet publish para compilar la imagen de contenedor para la arquitectura Linux y amd64. Cambie el directorio al directorio filtermodule del proyecto y ejecute el comando dotnet publish.

dotnet publish --os linux --arch x64 /t:PublishContainer

Actualmente, la plantilla de herramientas iotedgedev tiene como destino .NET 7.0. Si desea tener como destino una versión diferente de .NET, edite el archivo filtermodule.csproj y cambie los valores de TargetFramework y PackageReference. Por ejemplo, para tener como destino .NET 8.0, el archivo filtermodule.csproj debería tener este aspecto:

<Project Sdk="Microsoft.NET.Sdk.Worker">
    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <Nullable>enable</Nullable>
        <ImplicitUsings>enable</ImplicitUsings>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Microsoft.Azure.Devices.Client" Version="1.42.0" />
        <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
    </ItemGroup>
</Project>

Etiquete la imagen de Docker con la arquitectura, la versión y la información del registro de contenedor. Reemplace myacr por su propio nombre de registro.

docker tag filtermodule myacr.azurecr.io/filtermodule:0.0.1-amd64

Imagen de Docker del módulo de inserción

Especifique las credenciales del registro de contenedor a Docker para que pueda insertar la imagen de contenedor para que se almacene en el registro.

  1. Inicie sesión en Docker con las credenciales de Azure Container Registry (ACR).

    docker login -u <ACR username> -p <ACR password> <ACR login server>
    

    Podría recibir una advertencia de seguridad en la que se recomiende el uso de --password-stdin. Aunque ese es un procedimiento recomendado para escenarios de producción, está fuera del ámbito de este tutorial. Para más información, consulte la referencia de docker login.

  2. Inicie sesión en Azure Container Registry. Es necesario Instalar la CLI de Azure para usar el comando az. Este comando solicita el nombre de usuario y la contraseña que se encuentran en el registro de contenedor en Configuración>Claves de acceso.

    az acr login -n <ACR registry name>
    

    Sugerencia

    Si cierra la sesión en cualquier momento de este tutorial, repita los pasos de inicio de sesión de Docker y Azure Container Registry para continuar.

  3. Inserte la imagen del módulo en el registro local o en un registro de contenedor.

    docker push <ImageName>
    

    Por ejemplo:

    # Push the Docker image to the local registry
    
    docker push localhost:5000/filtermodule:0.0.1-amd64
    
    # Or push the Docker image to an Azure Container Registry. Replace myacr with your Azure Container Registry name.
    
    az acr login --name myacr
    docker push myacr.azurecr.io/filtermodule:0.0.1-amd64
    

Actualizar la plantilla de implementación

Actualice la plantilla de implementación deployment.template.json con la ubicación de la imagen del registro de contenedor. Por ejemplo, si usa myacr.azurecr.io de Azure Container Registry y la imagen es filtermodule:0.0.1-amd64, actualice la configuración de filtermodule a:

"filtermodule": {
    "version": "1.0",
    "type": "docker",
    "status": "running",
    "restartPolicy": "always",
    "settings": {
        "image": "myacr.azurecr.io/filtermodule:0.0.1-amd64",
        "createOptions": "{\"HostConfig\":{\"PortBindings\":{\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}],\"443/tcp\":[{\"HostPort\":\"443\"}]}}}"
    }
}

En el explorador de Visual Studio Code, haga clic con el botón derecho en el archivo deployment.template.json y seleccione Build and Push IoT Edge solution (Compilar e insertar solución IoT Edge).

El comando de compilación e inserción inicia tres operaciones. En primer lugar, se crea una nueva carpeta en la solución denominada config que contiene los archivos del manifiesto de la implementación completa, con la información de la plantilla de implementación y otros archivos de la solución. En segundo lugar, ejecuta docker build para generar la imagen de contenedor basándose en el Dockerfile adecuado para la arquitectura de destino. A continuación, ejecuta docker push para insertar el repositorio de imágenes en el registro de contenedor.

Este proceso puede tardar varios minutos la primera vez, pero es más rápido la próxima vez que ejecute los comandos.

Opcional: actualizar el módulo y la imagen

Si realiza cambios en el código del módulo, debe volver a generar e insertar la imagen del módulo en el registro de contenedor. Siga los pasos de esta sección para actualizar la compilación y la imagen de contenedor. Puede omitir esta sección si no ha realizado ningún cambio en el código del módulo.

Abra el archivo deployment.amd64.json en la carpeta de configuración recién creada. El nombre de archivo refleja la arquitectura de destino, así que es diferente si ha elegido una otra arquitectura.

Tenga en cuenta que los dos parámetros que tenían marcadores de posición ahora contienen los valores adecuados. La sección registryCredentials tiene el nombre de usuario y la contraseña del registro que se extrajeron del archivo .env. filtermodule tiene el repositorio de imágenes completo con el nombre, la versión y la etiqueta de arquitectura del archivo module.json.

  1. Abra el archivo module.json de la carpeta filtermodule.

  2. Cambie el número de versión de la imagen del módulo. Por ejemplo, incremente el número de versión de la revisión a "version": "0.0.2" como si hubiera hecho una pequeña corrección en el código del módulo.

    Sugerencia

    Las versiones de los módulos permiten el control de versiones y le permiten probar los cambios en un pequeño conjunto de dispositivos antes de implementar actualizaciones en la producción. Si no incrementa la versión del módulo antes de la compilación e inserción, entonces sobrescribirá el repositorio en el registro de contenedor.

  3. Guarde los cambios en el archivo module.json.

Compile e inserte la imagen actualizada con una etiqueta de versión 0.0.2. Por ejemplo, para compilar e insertar la imagen del registro local o un registro de contenedor de Azure, use los siguientes comandos:


# Build the container image for Linux and amd64 architecture.

dotnet publish --os linux --arch x64

# For local registry:
# Tag the image with version 0.0.2, x64 architecture, and the local registry.

docker tag filtermodule localhost:5000/filtermodule:0.0.2-amd64

# For Azure Container Registry:
# Tag the image with version 0.0.2, x64 architecture, and your container registry information. Replace **myacr** with your own registry name.

docker tag filtermodule myacr.azurecr.io/filtermodule:0.0.2-amd64

Vuelva a hacer clic con el botón derecho en el archivo deployment.template.json y seleccione Build and Push IoT Edge solution (Compilar e insertar solución IoT Edge) de nuevo.

Vuelva a abrir el archivo deployment.amd64.json de nuevo. Observe que el sistema de compilación no crea un nuevo archivo al ejecutar de nuevo el comando de compilación e inserción. Más bien, el mismo archivo se actualiza para reflejar los cambios. La imagen de filtermodule ahora apunta a la versión 0.0.2 del contenedor.

Para comprobar mejor lo que hizo el comando de compilación e inserción, vaya a Azure Portal y navegue al registro de contenedor.

En el registro de contenedor, seleccione Repositorios y después filtermodule. Compruebe que ambas versiones de la imagen se insertan en el registro.

Screenshot of where to view both image versions in your container registry.

Solución de problemas

Si encuentra errores al compilar e insertar la imagen del módulo, a menudo tiene que ver con la configuración de Docker en la máquina de desarrollo. Utilice las siguientes comprobaciones para revisar la configuración:

  • ¿Ha ejecutado el comando docker login mediante las credenciales que copió del registro de contenedor? Estas credenciales son diferentes a las que se utilizan para iniciar sesión en Azure.
  • ¿Es el repositorio de contenedor correcto? ¿Tiene el nombre correcto del registro de contenedor y el nombre correcto del módulo? Abra el archivo module.json de la carpeta filtermodule para comprobar. El valor del repositorio debería ser similar a <nombre del registro>.azurecr.io/filtermodule.
  • Si utilizó un nombre diferente a filtermodule para el módulo, ¿es coherente ese nombre en toda la solución?
  • ¿La máquina funciona con el mismo tipo de contenedores que está creando? Este tutorial es para dispositivos IoT Edge de Linux, por lo que Visual Studio Code debería indicar amd64 o arm32v7 en la barra lateral y Docker Desktop debe ejecutar contenedores Linux.

Implementación de módulos en el dispositivo

Ha verificado que hay imágenes de contenedor creadas y almacenadas en el registro de contenedor, por lo que es el momento de implementarlas en un dispositivo. Asegúrese de que el dispositivo IoT Edge está en funcionamiento.

Use el comando IoT Edge Azure CLI set-modules para implementar los módulos en Azure IoT Hub. Por ejemplo, para implementar los módulos definidos en el archivo deployment.template.json en el centro de IoT my-iot-hub para el dispositivo de IoT Edge my-device, use el siguiente comando. Sustituya los valores de cadena de conexión de loT Hub hub-name, device-id y login por los suyos propios.

az iot edge set-modules --hub-name my-iot-hub --device-id my-device --content ./deployment.template.json --login "HostName=my-iot-hub.azure-devices.net;SharedAccessKeyName=iothubowner;SharedAccessKey=<SharedAccessKey>"

Sugerencia

Puede encontrar la cadena de conexión de IoT Hub, incluida la clave de acceso compartido, en Azure Portal. Vaya a IoT Hub >Configuración de seguridad>Directivas de acceso compartido>iothubowner.

  1. En el explorador de Visual Studio Code, en la sección Azure IoT Hub, expanda Dispositivos para ver la lista de dispositivos IoT.

  2. Haga clic con el dispositivo IoT Edge que desea implementar y seleccione Create Deployment for IoT Edge device (Crear una implementación para un dispositivo individual).

  3. En el Explorador de archivos, vaya a la carpeta config y seleccione el archivo deployment.amd64.json.

    No utilice el archivo deployment.template.json, que no contiene todas las credenciales del registro de contenedor o los valores de imagen del módulo. Si tiene como destino un dispositivo LINUX ARM32, el nombre del manifiesto de implementación es deployment.arm32v7.json.

  4. En el dispositivo, expanda Módulos para ver una lista de módulos implementados y en ejecución. Seleccione el botón actualizar. Debería ver los nuevos módulos tempSensor y filtermodule que se ejecutan en el dispositivo.

    Los módulos podrían tardar unos minutos en iniciarse. El entorno de ejecución de Azure IoT Edge necesita recibir su nuevo manifiesto de implementación, extraer las imágenes de los módulos del entorno de ejecución del contenedor y, después, iniciar cada nuevo módulo.

Visualización de los mensajes desde el dispositivo

El código de módulo de ejemplo recibe mensajes mediante la cola de entrada y los pasa por la cola de salida. El manifiesto de implementación declaraba las rutas que pasaban a filtermodule los mensajes de tempSensor, y luego enviaban los mensajes de filtermodule a la instancia de IoT Hub. Las extensiones de Azure IoT Edge y Azure IoT Hub permiten ver los mensajes que llegan a IoT Hub desde dispositivos individuales.

  1. En el explorador de Visual Studio Code, haga clic con el botón derecho en el dispositivo IoT Edge que desea supervisar y seleccione Start Monitoring Built-in Event Endpoint (Iniciar supervisión del punto de conexión del evento integrado).

  2. En la ventana de salida podrá ver si llegan mensajes al centro de IoT.

    Screenshot showing where to view incoming device to cloud messages.

Visualización de los cambios en el dispositivo

Si desea ver lo que está ocurriendo en su propio dispositivo, utilice los comandos de esta sección para inspeccionar el entorno de ejecución de Azure IoT Edge y los módulos que se ejecutan en el dispositivo.

Los comandos de esta sección son para el dispositivo IoT Edge, no en la máquina de desarrollo. Si usa una máquina virtual para el dispositivo IoT Edge, conéctese a ella ahora. En Azure, vaya a la página de información general de la máquina virtual y seleccione Conectar para acceder a la conexión de Secure Shell.

  • Vea todos los módulos implementados en el dispositivo y compruebe su estado:

    iotedge list
    

    Debería ver cuatro módulos: los dos módulos personalizados del entorno de ejecución de IoT Edge, tempSensor e filtermodule. Debería ver las cuatro enumeradas como en ejecución.

  • Inspeccione los registros para un módulo específico:

    iotedge logs <module name>
    

    Los módulos IoT Edge distinguen mayúsculas de minúsculas.

    Los registros de tempSensor y filtermodule deben mostrar los mensajes que están procesando. El módulo edgeAgent es responsable de iniciar los otros módulos, por lo que sus registros tienen información sobre cómo implementar el manifiesto de implementación. Si encuentra que un módulo no está en la lista o no está en ejecución, es probable que los registros de edgeAgent tengan los errores. El módulo edgeHub es responsable de las comunicaciones entre los módulos e IoT Hub. Si los módulos están en funcionamiento, pero los mensajes no llegan al centro de IoT, los registros de edgeHub probablemente tendrán los errores.

Limpieza de recursos

Si prevé seguir con el siguiente artículo recomendado, puede mantener los recursos y las configuraciones que ya ha creado y volverlos a utilizar. También puede seguir usando el mismo dispositivo de IoT Edge como dispositivo de prueba.

En caso contrario, para evitar gastos, puede eliminar las configuraciones locales y los recursos de Azure que creó en este artículo.

Eliminación de recursos de Azure

La eliminación de los recursos de Azure y de los grupos de recursos es un proceso irreversible. Asegúrese de no eliminar por accidente el grupo de recursos o los recursos equivocados. Si ha creado el centro de IoT en un grupo de recursos ya existente que tiene recursos que desea conservar, elimine solo el recurso del centro de IoT en sí en lugar de eliminar todo el grupo de recursos.

Para eliminar los recursos:

  1. Inicie sesión en Azure Portal y después seleccione Grupos de recursos.

  2. Seleccione el nombre del grupo de recursos que contiene los recursos de prueba de IoT Edge.

  3. Revise la lista de los recursos contenidos en el grupo de recursos. Si desea eliminar todos ellos, puede seleccionar Eliminar grupo de recursos. Si desea eliminar solo algunos de ellos, puede hacer clic en cada recurso para eliminarlos individualmente.

Pasos siguientes

En este tutorial, configuró Visual Studio Code en la máquina de desarrollo e implementó el primer módulo de IoT Edge que contiene código para filtrar los datos sin procesar generados por el dispositivo IoT Edge.

Puede continuar con los siguientes tutoriales para obtener información sobre cómo Azure IoT Edge puede ayudarle a implementar servicios en la nube de Azure para procesar y analizar datos en el perímetro.