Tutorial: Implementación de Azure Functions como módulos en Azure IoT Edge

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.

Azure Functions se puede usar para implementar código que, a su vez, implementa una lógica de negocios directamente en los dispositivos de Azure IoT Edge. En este tutorial, se detallan los pasos para crear e implementar una instancia de Azure Functions que filtra los datos de un sensor en el dispositivo IoT Edge simulado. Utilizará el dispositivo IoT Edge simulado que creó en los inicios rápidos. En este tutorial, aprenderá a:

  • Usar Visual Studio Code para crear una instancia de Azure Functions.
  • Use Visual Studio Code y Docker para crear una imagen de Docker y publicarla en un contenedor de registro.
  • Implementar el módulo desde el registro de contenedor en el dispositivo IoT Edge.
  • Ver los datos filtrados.

Diagram of function architecture, showing how to stage and deploy a function module.

La instancia de Azure Functions que crea en este tutorial filtra los datos de temperatura que genera su dispositivo. La función solo envía mensajes a Azure IoT Hub si la temperatura sobrepasa un umbral especificado.

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

Requisitos previos

Antes de comenzar este tutorial, complete el tutorial sobre la configuración del entorno de desarrollo de contenedores de Linux: Desarrollo de módulos de Azure IoT Edge mediante Visual Studio Code. Después de completar este tutorial, se deben cumplir los siguientes requisitos previos:

Para desarrollar un módulo de IoT Edge con Azure Functions, instale los requisitos previos adicionales en la máquina de desarrollo:

Creación de un proyecto de aplicación de una función

Azure IoT Edge para Visual Studio Code que ha instalado en los requisitos previos proporciona funcionalidades de administración, así como algunas plantillas de código. En esta sección, se usa Visual Studio Code para crear una solución de IoT Edge que contiene una instancia de Azure Functions.

Creación de un nuevo proyecto

Siga estos pasos para crear una plantilla de solución de función de C# que se pueda personalizar.

  1. Abra Visual Studio Code en el equipo de desarrollo.

  2. Abra la paleta de comandos de Visual Studio Code; para ello, seleccione Ver>Paleta de comandos.

  3. En la paleta de comandos, agregue y ejecute el comando Azure IoT Edge: nueva solución IoT Edge. Para crear la solución, siga estas indicaciones de la paleta de comandos:

    • Seleccione una carpeta: elija la ubicación en la máquina de desarrollo en la que Visual Studio Code creará los archivos de la solución.
    • Escriba un nombre para la solución: agregue un nombre descriptivo para la solución, como SoluciónDeFunción o acepte el valor predeterminado.
    • Seleccione una plantilla de módulo: elija Azure Functions - C#.
    • Proporcione un nombre de módulo: asigne al módulo el nombre CSharpFunction.
    • Proporcione un repositorio de imágenes de Docker para el módulo. Un repositorio de imágenes incluye el nombre del registro de contenedor y el nombre de la imagen de contenedor. La imagen de contenedor se rellena previamente a partir del último paso. Reemplace localhost:5000 por el valor de Servidor de inicio de sesión del registro de contenedor de Azure. Puede recuperar el Servidor de inicio de sesión de la página Información general del registro de contenedor en Azure Portal. La cadena final se parece a <nombre del Registro>.azurecr.io/csharpfunction.

    Screenshot showing where to add your Docker image repository name in Visual Studio Code.

Adición de las credenciales del Registro

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

La extensión de IoT Edge en Visual Studio Code intenta extraer de Azure las credenciales del registro del contenedor y rellenar con ellas el archivo de entorno. Compruebe si las credenciales ya están en el archivo. Si no lo están, agréguelas ahora:

  1. En el explorador de Visual Studio Code, abra el archivo .env.
  2. Actualice los campos con los valores de nombre de usuario y contraseña que ha copiado del Registro de contenedor de Azure. Para encontrarlos de nuevo, vaya a su registro de contenedor en Azure y busque la página Configuración>Claves de acceso.
  3. Guarde este archivo.

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. Para más información, consulte Administración del acceso al registro de contenedor.

Establecimiento de la arquitectura de destino en AMD64

La ejecución de módulos de Azure Functions en IoT Edge solo se admite en contenedores basados en Linux AMD64. La arquitectura de destino predeterminada para Visual Studio Code es Linux AMD64, pero aquí la estableceremos explícitamente en Linux AMD64.

  1. Abra la paleta de comandos y busque Azure IoT Edge: establecer la plataforma de destino predeterminada para la solución perimetral.

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

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

Vamos a agregar código adicional para que el módulo CSharpFunction procese los mensajes en el perímetro antes de reenviarlos a IoT Hub.

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

  2. Reemplace el contenido del archivo CSharpFunction.cs por el código siguiente. Este código recibe datos de telemetría sobre la temperatura ambiente y la de la máquina y solo reenvía el mensaje a IoT Hub si la temperatura de la máquina está por encima de un umbral definido.

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.Azure.Devices.Client;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Azure.WebJobs.Extensions.EdgeHub;
    using Microsoft.Azure.WebJobs.Host;
    using Microsoft.Extensions.Logging;
    using Newtonsoft.Json;
    
    namespace Functions.Samples
    {
        public static class CSharpFunction
        {
            [FunctionName("CSharpFunction")]
            public static async Task FilterMessageAndSendMessage(
                [EdgeHubTrigger("input1")] Message messageReceived,
                [EdgeHub(OutputName = "output1")] IAsyncCollector<Message> output,
                ILogger logger)
            {
                const int temperatureThreshold = 20;
                byte[] messageBytes = messageReceived.GetBytes();
                var messageString = System.Text.Encoding.UTF8.GetString(messageBytes);
    
                if (!string.IsNullOrEmpty(messageString))
                {
                    logger.LogInformation("Info: Received one non-empty message");
                    // Get the body of the message and deserialize it.
                    var messageBody = JsonConvert.DeserializeObject<MessageBody>(messageString);
    
                    if (messageBody != null && messageBody.machine.temperature > temperatureThreshold)
                    {
                        // Send the message to the output as the temperature value is greater than the threshold.
                        using (var filteredMessage = new Message(messageBytes))
                        {
                             // Copy the properties of the original message into the new Message object.
                             foreach (KeyValuePair<string, string> prop in messageReceived.Properties)
                             {filteredMessage.Properties.Add(prop.Key, prop.Value);}
                             // Add a new property to the message to indicate it is an alert.
                             filteredMessage.Properties.Add("MessageType", "Alert");
                             // Send the message.
                             await output.AddAsync(filteredMessage);
                             logger.LogInformation("Info: Received and transferred a message with temperature above the threshold");
                        }
                    }
                }
            }
        }
        //Define the expected schema for the body of incoming messages.
        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;}
        }
    }
    
  3. Guarde el archivo.

Compilación e inserción de una solución IoT Edge

En la sección anterior se ha creado una solución de IoT Edge y se ha modificado CSharpFunction para filtrar los mensajes que notifiquen una temperatura de la máquina inferior al umbral aceptable. Ahora, tiene que compilar la solución como una imagen de contenedor e insertarla en el registro de contenedor.

  1. Abra el terminal integrado de Visual Studio Code, para lo que debe seleccionar Ver>Terminal.

  2. Escriba el comando siguiente en el terminal para iniciar sesión en Docker. Inicie sesión con el nombre de usuario, la contraseña y el servidor de inicio de sesión de Azure Container Registry. Puede recuperar estos valores en la sección Claves de acceso del Registro en Azure Portal.

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

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

  3. 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 llamada 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.

Visualización de una imagen de contenedor

Visual Studio Code genera un mensaje de éxito cuando la imagen de contenedor se inserta en el registro de contenedor. Si quiere confirmar por su cuenta que la operación es correcta, puede ver la imagen en el registro.

  1. En Azure Portal, vaya al registro de contenedor de Azure.
  2. Seleccione Servicios>Repositorios.
  3. Verá que el repositorio csharpfunction se muestra en la lista. Seleccione este repositorio para ver más detalles.
  4. En la sección Etiquetas, verá la etiqueta 0.0.1-amd64. Esta etiqueta refleja la versión y la plataforma de la imagen que ha creado. Estos valores se establecen en el archivo module.json, en la carpeta CSharpFunction.

Implementación y ejecución de la solución

Azure Portal se puede usar para implementar un módulo de Functions en un dispositivo IoT Edge, como hizo en el artículo de inicio rápido. También puede implementar y supervisar los módulos desde dentro de Visual Studio Code. En las secciones siguientes, se usa la instancia de Azure IoT Edge e IoT Hub para Visual Studio Code que se indicó en los requisitos previos. Si no lo ha hecho aún, instale las extensiones ahora.

  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 botón derecho en el nombre del dispositivo IoT Edge y seleccione Create Deployment for Single Device (Crear una implementación para un dispositivo individual).

  3. Vaya a la carpeta de la solución que contiene CSharpFunction. Abra la carpeta config, seleccione el archivo deployment.amd64.json y, después, haga clic en Select Edge Deployment Manifest (Seleccionar manifiesto de implementación de Edge).

  4. En el dispositivo, expanda Módulos para ver una lista de módulos implementados y en ejecución. Haga clic en el botón Actualizar. Debería ver el nuevo CSharpFunction en ejecución junto con el módulo SimulatedTemperatureSensor, así como $edgeAgent y $edgeHub.

    Los nuevos módulos pueden tardar unos instantes en mostrarse. El dispositivo IoT Edge debe recuperar su nueva información de implementación de IoT Hub, iniciar los nuevos contenedores y, a continuación, notificar el estado a IoT Hub.

    Screenshot showing how to view deployed modules in Visual Studio Code.

Visualización de los datos generados

Para ver todos los mensajes que llegan a su centro de IoT desde todos sus dispositivos, puede ejecutarAzure IoT Hub: iniciar supervisión del punto de conexión del evento integrado en la paleta de comandos. Para detener la supervisión de mensajes, ejecute el comando Azure IoT Hub: Stop Monitoring Built-in Event Endpoint (Detener supervisión del punto de conexión del evento integrado) en la paleta de comandos.

También puede filtrar la vista para ver todos los mensajes que llegan al centro de IoT desde un dispositivo específico. Haga clic con el botón derecho en el dispositivo en la sección Azure IoT Hub>Dispositivos del explorador de Visual Studio Code y seleccione Iniciar supervisión del punto de conexión de eventos integrado.

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, ha creado un módulo de Azure Functions que contiene código para filtrar los datos sin procesar que genera un dispositivo IoT Edge.

Puede continuar con los siguientes tutoriales para aprender otras formas en las que Azure IoT Edge puede ayudarle a convertir los datos en información empresarial en el perímetro.