Tutorial: Desarrollo de un módulo IoT Edge con Java mediante contenedores Linux
Se aplica a: IoT Edge 1.4
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 este tutorial, se detallan los pasos para crear e implementar un módulo de IoT Edge que filtra los datos de sensor. Utilizará el dispositivo IoT Edge simulado que creó en los artículos del inicio rápido Implementación de Azure IoT Edge en un dispositivo simulado. En este tutorial, aprenderá a:
- Use Visual Studio Code para crear un módulo de Java de IoT Edge basado en el paquete de plantillas de Maven de Azure IoT Edge y el SDK de dispositivo de Java de Azure IoT.
- Utilizar Visual Studio Code y Docker para crear una imagen de Docker y publicarla en el Registro.
- Implementar el módulo en el dispositivo IoT Edge.
- Ver datos generados.
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.
Si no tiene una suscripción a Azure, cree una cuenta gratuita de Azure antes de empezar.
Requisitos previos
En este tutorial se muestra cómo desarrollar un módulo en Java mediante Visual Studio Code y cómo implementarlo en un dispositivo IoT Edge. IoT Edge no admite módulos de Java compilados como contenedores de Windows.
Utilice la tabla siguiente si desea conocer las opciones para desarrollar e implementar módulos de Java:
Java | Visual Studio Code | Visual Studio 2017/2019 |
---|---|---|
Linux AMD64 | ![]() |
|
Linux ARM32 | ![]() |
|
Linux ARM64 | ![]() |
Antes de comenzar este tutorial, debe haber realizado el anterior para configurar el entorno de desarrollo de contenedores de Linux: Desarrollo de módulos IoT Edge para dispositivos Linux. Al completar cualquiera de estos tutoriales, se deben cumplir los siguientes requisitos previos:
- Una instancia de IoT Hub de nivel estándar o gratis en Azure.
- Un dispositivo que ejecute Azure IoT Edge con contenedores de Linux. Puede usar los inicios rápidos para configurar un dispositivo Linux o un dispositivo Windows.
- Un registro de contenedor, como Azure Container Registry.
- Visual Studio Code configurado con las extensiones de Azure IoT Edge y Azure IoT Hub.
- Descargue e instale un sistema de administración de contenedores compatible con Docker en la máquina de desarrollo. Configúrelo para ejecutar contenedores de Linux.
Para desarrollar un módulo de IoT Edge en Java, instale los siguientes requisitos previos adicionales en la máquina de desarrollo:
Paquete de extensiones de Java para Visual Studio Code.
Java SE Development Kit 11 y establecer la variable de entorno
JAVA_HOME
para que apunte a la instalación de JDK.-
Sugerencia
Los procesos de instalación de Java y Maven agregan variables de entorno al sistema. Después de completar la instalación, reinicie las instancias del símbolo del sistema, PowerShell o cualquier terminal de Visual Studio Code abierta. Este paso garantiza que estas utilidades puedan reconocer los comandos Java y Maven en adelante.
Creación de un proyecto de módulo
Use los pasos siguientes para crear proyecto de módulo de IoT Edge basado en el paquete de plantillas de Maven de Azure IoT Edge y el SDK de dispositivo de Java de Azure IoT. El proyecto se crea con Visual Studio Code y la extensión Azure IoT Edge.
Creación de un nuevo proyecto
Cree una plantilla de solución de Java que pueda personalizar con su propio código.
En Visual Studio Code, seleccione Ver>Paleta de comandos para abrir la paleta de comandos de VS Code.
En la paleta de comandos, escriba y ejecute el comando Azure IoT Edge: New IoT Edge solution (Azure IoT Edge: nueva solución de IoT Edge). Para crear la solución, siga las indicaciones de la paleta de comandos.
Campo Value Seleccionar carpeta Elija la ubicación en el equipo de desarrollo en la que VS Code creará los archivos de la solución. Proporcionar un nombre de la solución Escriba un nombre descriptivo para la solución o acepte el valor predeterminado EdgeSolution. Seleccionar plantilla del módulo Elija Módulo de Java. Proporcionar un nombre de módulo Llame al módulo JavaModule. Proporcionar repositorio de imágenes de Docker del 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 con el nombre que proporcionó en el ú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 en la página de información general del registro de contenedor en Azure Portal.
El repositorio de imágenes final será similar a <nombre del Registro>.azurecr.io/javamodule.Proporcionar valor de groupId Escriba un valor de identificador de grupo o acepte el valor predeterminado com.edgemodule.
Si es la primera vez que crea un módulo de Java, puede que tarde varios minutos en descargar los paquetes de Maven. Cuando la solución esté lista, la ventana de VS Code cargará el área de trabajo de la solución de IoT Edge. El área de trabajo de la solución contiene cinco componentes de nivel superior.
- La carpeta modules contiene el código Java del módulo y los archivos de Docker para compilar el módulo como una imagen de contenedor.
- El archivo .env almacena las credenciales del registro de contenedor.
- El archivo deployment.template.json contiene la información que usa el entorno de ejecución de IoT Edge para implementar módulos en un dispositivo.
- El archivo deployment.debug.template.json contiene la versión de depuración de los módulos.
- En este tutorial, no se editarán la carpeta .vscode ni el archivo .gitignore.
Si no especificó un registro de contenedor al crear la solución y aceptó el valor predeterminado localhost:5000, no tendrá un archivo .env.
Adición de las credenciales del Registro
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 privadas 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. Compruebe si las credenciales ya están incluidas. Si no lo están, agréguelas ahora:
- En el explorador de VS Code, abra el archivo .env.
- Actualice los campos con los valores de nombre de usuario y contraseña que ha copiado del Registro de contenedor de Azure.
- 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.
Selección de la arquitectura de destino
Actualmente, Visual Studio Code puede desarrollar módulos de Java para dispositivos Linux AMD64 y Linux ARM32v7. Debe seleccionar qué arquitectura tiene como destino con cada solución, dado que el contenedor se crea y ejecuta de manera diferente para cada tipo de arquitectura. La opción predeterminada es Linux AMD64.
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.
En la paleta de comandos, seleccione la arquitectura de destino en la lista de opciones. Para este tutorial, usamos una máquina virtual Ubuntu como dispositivo IoT Edge, por lo que mantendrá el valor predeterminado amd64.
Actualización del módulo con código personalizado
En el Explorador de VS Code, abra modules>JavaModule>src>main>java>com>edgemodule>App.java.
Agregue el código siguiente en la parte superior del archivo para importar nuevas clases a las que se hace referencia.
import java.io.StringReader; import java.util.concurrent.atomic.AtomicLong; import java.util.HashMap; import java.util.Map; import javax.json.Json; import javax.json.JsonObject; import javax.json.JsonReader; import com.microsoft.azure.sdk.iot.device.DeviceTwin.Pair; import com.microsoft.azure.sdk.iot.device.DeviceTwin.Property; import com.microsoft.azure.sdk.iot.device.DeviceTwin.TwinPropertyCallBack;
Agregue la siguiente definición a la clase App. Esta variable establece un umbral de temperatura. La temperatura medida en la máquina no se notificará a IoT Hub hasta que supere este valor.
private static final String TEMP_THRESHOLD = "TemperatureThreshold"; private static AtomicLong tempThreshold = new AtomicLong(25);
Reemplace el método execute de MessageCallbackMqtt por el código siguiente. Se llama a este método cada vez que el módulo recibe un mensaje MQTT 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.
protected static class MessageCallbackMqtt implements MessageCallback { private int counter = 0; @Override public IotHubMessageResult execute(Message msg, Object context) { this.counter += 1; String msgString = new String(msg.getBytes(), Message.DEFAULT_IOTHUB_MESSAGE_CHARSET); System.out.println( String.format("Received message %d: %s", this.counter, msgString)); if (context instanceof ModuleClient) { try (JsonReader jsonReader = Json.createReader(new StringReader(msgString))) { final JsonObject msgObject = jsonReader.readObject(); double temperature = msgObject.getJsonObject("machine").getJsonNumber("temperature").doubleValue(); long threshold = App.tempThreshold.get(); if (temperature >= threshold) { ModuleClient client = (ModuleClient) context; System.out.println( String.format("Temperature above threshold %d. Sending message: %s", threshold, msgString)); client.sendEventAsync(msg, eventCallback, msg, App.OUTPUT_NAME); } } catch (Exception e) { e.printStackTrace(); } } return IotHubMessageResult.COMPLETE; } }
Agregue las dos clases internas estáticas siguientes a la clase App. Estas clases actualizan la variable tempThreshold cuando cambia la propiedad deseada en el módulo gemelo. 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.
protected static class DeviceTwinStatusCallBack implements IotHubEventCallback { @Override public void execute(IotHubStatusCode status, Object context) { System.out.println("IoT Hub responded to device twin operation with status " + status.name()); } } protected static class OnProperty implements TwinPropertyCallBack { @Override public void TwinPropertyCallBack(Property property, Object context) { if (!property.getIsReported()) { if (property.getKey().equals(App.TEMP_THRESHOLD)) { try { long threshold = Math.round((double) property.getValue()); App.tempThreshold.set(threshold); } catch (Exception e) { System.out.println("Faile to set TemperatureThread with exception"); e.printStackTrace(); } } } } }
Agregue las líneas siguientes al método main después de client.open() para suscribirse a las actualizaciones del módulo gemelo.
client.startTwin(new DeviceTwinStatusCallBack(), null, new OnProperty(), null); Map<Property, Pair<TwinPropertyCallBack, Object>> onDesiredPropertyChange = new HashMap<Property, Pair<TwinPropertyCallBack, Object>>() { { put(new Property(App.TEMP_THRESHOLD, null), new Pair<TwinPropertyCallBack, Object>(new OnProperty(), null)); } }; client.subscribeToTwinDesiredProperties(onDesiredPropertyChange); client.getTwin();
Guarde el archivo App.java.
En el explorador de VS Code, abra el archivo deployment.template.json en el área de trabajo de la solución de IoT Edge.
Agregue el módulo gemelo JavaModule al manifiesto de implementación. Inserte el siguiente contenido JSON en la parte inferior de la sección moduleContent, después del módulo gemelo $edgeHub:
"JavaModule": { "properties.desired":{ "TemperatureThreshold":25 } }
Guarde el archivo deployment.template.json.
Compilación e inserción del módulo
En la sección anterior, creó una solución de IoT Edge y agregó código a JavaModule para filtrar los mensajes en los que la temperatura registrada por la máquina está por debajo del límite aceptable. Ahora, compile la solución como una imagen de contenedor e insertarla en el registro de contenedor.
Abra el terminal integrado de VS Code, para lo que debe seleccionar View>Terminal (Ver > Terminal).
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.En el explorador de VS 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 de 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, ejecutadocker 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.
Implementación de módulos en el dispositivo
Utilice el explorador de Visual Studio Code y la extensión de Azure IoT Edge para implementar el proyecto de módulo en el dispositivo IoT Edge. Ya tiene un manifiesto de implementación preparado para su escenario, el archivo deployment.amd64.json de la carpeta config. Ahora todo lo que necesita hacer es seleccionar un dispositivo que reciba la implementación.
Asegúrese de que el dispositivo IoT Edge está en funcionamiento.
En el explorador de Visual Studio Code, en la sección Azure IoT Hub, expanda Dispositivos para ver la lista de dispositivos IoT.
Haga clic con el botón derecho en el nombre del dispositivo IoT Edge y seleccione Create Deployment for IoT Edge device (Crear una implementación para un dispositivo individual).
Seleccione el archivo deployment.amd64.json en la carpeta config y, a continuación, haga clic en Select Edge Deployment Manifest (Seleccionar manifiesto de implementación de Edge). No utilice el archivo deployment.template.json.
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 JavaModule en ejecución junto con el módulo SimulatedTemperatureSensor, así como $edgeAgent y $edgeHub.
Los módulos pueden 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 datos generados
Una vez aplicado el manifiesto de implementación al dispositivo de IoT Edge, el entorno de ejecución de IoT Edge del dispositivo recopila la información de implementación nueva y comienza a ejecutarse con ella. Los módulos que se ejecuten en el dispositivo y que no están incluidos en el manifiesto de implementación se detienen. Los módulos que falten en el dispositivo se inician.
En el explorador de Visual Studio Code, haga clic con el botón derecho en el nombre del dispositivo IoT Edge y seleccione Start Monitoring Built-in Event Endpoint (Iniciar supervisión del punto de conexión del evento integrado).
Vea los mensajes que llegan a IoT Hub. Los mensajes pueden tardar unos minutos en llegar. El dispositivo IoT Edge tiene que recibir la nueva implementación e iniciar todos los módulos. Después, los cambios realizados en el código JavaModule esperan hasta que la temperatura de la máquina alcanza los 25 grados antes de enviar los mensajes. También agrega el tipo de mensaje Alerta a los mensajes que llegan a ese umbral de temperatura.
Edición del módulo gemelo
Usamos el módulo gemelo JavaModule en el manifiesto de implementación para establecer el umbral de temperatura en 25 grados. Puede usar al módulo gemelo para cambiar la funcionalidad sin tener que actualizar el código del módulo.
En Visual Studio Code, expanda los detalles en el dispositivo IoT Edge para ver los módulos en ejecución.
Haga clic con el botón derecho en JavaModule y seleccione Editar módulo gemelo.
Busque TemperatureThreshold en las propiedades deseadas. Cambie su valor por una temperatura nueva de 5 a 10 grados más que la última temperatura registrada.
Guarde el archivo del módulo gemelo.
Haga clic con el botón derecho en cualquier parte del panel de edición del módulo gemelo y seleccione Actualizar módulo gemelo.
Supervise los mensajes entrantes del dispositivo a la nube. Debería ver que los mensajes se detienen hasta que se alcanza el nuevo umbral de temperatura.
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:
Inicie sesión en Azure Portal y después seleccione Grupos de recursos.
Seleccione el nombre del grupo de recursos que contiene los recursos de prueba de IoT Edge.
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 IoT Edge que filtra los datos sin procesar generados por el dispositivo IoT Edge.
Continúe 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.