Programación y difusión de trabajos (Node.js)

Use Azure IoT Hub para programar y realizar el seguimiento de los trabajos que actualizan millones de dispositivos. Use los trabajos para:

  • Actualizar las propiedades deseadas
  • Actualizar etiquetas
  • Invocar métodos directos

Conceptualmente, un trabajo contiene una de estas acciones y realiza un seguimiento del progreso de ejecución en un conjunto de dispositivos, que define una consulta de dispositivo gemelo. Por ejemplo, una aplicación back-end puede usar un trabajo para invocar un método de reinicio en 10 000 dispositivos, especificado por una consulta de dispositivos gemelos y programada en el futuro. Esa aplicación puede después seguir el progreso cuando cada uno de estos dispositivos reciben y ejecutan el método de reinicio.

Más información sobre estas funcionalidades en estos artículos:

Nota

Las características descritas en este artículo solo están disponibles en el nivel estándar de IoT Hub. Para obtener más información sobre los niveles Básico y Estándar o Gratis de IoT Hub, consulte Elección del nivel adecuado de IoT Hub para la solución.

En este artículo se muestra cómo crear dos aplicaciones de Node.js:

  • Una aplicación de dispositivo simulado en Node.js, simDevice.js, que implementa un método directo llamado lockDoor, que puede ser llamado por la aplicación back-end.

  • Una aplicación de consola de Node.js, scheduleJobService.js, que crea dos trabajos. Un trabajo llama al método directo lockDoor y otro trabajo envía actualizaciones de propiedades deseadas a varios dispositivos.

Nota

Consulte los SDK de Azure IoT para obtener más información sobre las herramientas de SDK disponibles para compilar aplicaciones de dispositivo y back-end.

Requisitos previos

  • Una instancia de IoT Hub. Cree uno con la CLI o el Azure Portal.

  • Dispositivo registrado. Registre uno en el Azure Portal.

  • Node.js versión 10.0.x o posteriores. En Preparación del entorno de desarrollo se describe cómo instalar Node.js para este artículo ya sea en Windows o en Linux.

  • Asegúrese de que está abierto el puerto 8883 del firewall. En el ejemplo de dispositivo de este artículo se usa el protocolo MQTT, que se comunica mediante el puerto 8883. Este puerto puede estar bloqueado en algunos entornos de red corporativos y educativos. Para más información y para saber cómo solucionar este problema, consulte el artículo sobre la conexión a IoT Hub (MQTT).

Creación de una aplicación de dispositivo simulado

En esta sección, creará una aplicación de consola de Node.js que responda a un método directo al que la nube llama, que desencadena un método lockDoor simulado.

  1. Cree una nueva carpeta vacía denominada simDevice. En la carpeta simDevice, cree un archivo package.json con el siguiente comando en el símbolo del sistema. Acepte todos los valores predeterminados:

    npm init
    
  2. En el símbolo del sistema, en la carpeta simDevice, ejecute el siguiente comando para instalar el paquete del SDK de dispositivo azure-iot-device y el paquete azure-iot-device-mqtt:

    npm install azure-iot-device azure-iot-device-mqtt --save
    
  3. Con un editor de texto, cree un nuevo archivo simDevice.js en la carpeta simDevice.

  4. Agregue las siguientes instrucciones "require" al principio del archivo simDevice.js:

    'use strict';
    
    var Client = require('azure-iot-device').Client;
    var Protocol = require('azure-iot-device-mqtt').Mqtt;
    
  5. Agregue una variable connectionString y utilícela para crear una instancia de cliente. Sustituya el valor del marcador de posición {yourDeviceConnectionString} por la cadena de conexión del dispositivo que copió anteriormente.

    var connectionString = '{yourDeviceConnectionString}';
    var client = Client.fromConnectionString(connectionString, Protocol);
    
  6. Agregue la siguiente función para controlar el método lockDoor.

    var onLockDoor = function(request, response) {
    
        // Respond the cloud app for the direct method
        response.send(200, function(err) {
            if (err) {
                console.error('An error occurred when sending a method response:\n' + err.toString());
            } else {
                console.log('Response to method \'' + request.methodName + '\' sent successfully.');
            }
        });
    
        console.log('Locking Door!');
    };
    
  7. Agregue el código siguiente para registrar el controlador del método lockDoor.

    client.open(function(err) {
         if (err) {
             console.error('Could not connect to IotHub client.');
         }  else {
             console.log('Client connected to IoT Hub. Register handler for lockDoor direct method.');
             client.onDeviceMethod('lockDoor', onLockDoor);
         }
    });
    
  8. Guarde y cierre el archivo simDevice.js.

Nota

Por simplificar, este artículo no implementa ninguna directiva de reintentos. En el código de producción, deberá implementar directivas de reintentos (por ejemplo, retroceso exponencial), tal y como se sugiere en el artículo Control de errores transitorios.

Obtener la cadena de conexión de IoT Hub

En este artículo se creará un servicio de back-end que programa un trabajo para que invoque un método directo en un dispositivo, programa un trabajo para actualizar el dispositivo gemelo y supervisa el progreso de cada trabajo. Para realizar estas operaciones, el servicio necesita los permisos de lectura del registro y escritura en el registro. De manera predeterminada, todas las instancias del centro de IoT se crean con una directiva de acceso compartido denominada registryReadWrite que concede estos permisos.

Para obtener la cadena de conexión de IoT Hub para la directiva registryReadWrite, siga estos pasos:

  1. En Azure Portal, seleccione Grupos de recursos. Seleccione el grupo de recursos donde se encuentra el centro y, a continuación, seleccione el centro en la lista de recursos.

  2. En el panel de la izquierda del centro, seleccione Directivas de acceso compartido.

  3. En la lista de directivas, seleccione la directiva registryReadWrite.

  4. Copie la Cadena de conexión principal y guarde el valor.

    Captura de pantalla que muestra cómo recuperar la cadena de conexión

Para obtener más información sobre las directivas de acceso compartido y los permisos de IoT Hub, consulte Permisos y control del acceso.

Programación de trabajos para llamar un método directo y actualización de las propiedades de un dispositivo gemelo

En esta sección, creará una aplicación de consola de Node.js que inicia un lockDook remoto en un dispositivo con un método directo y actualiza las propiedades del dispositivo gemelo.

  1. Cree una nueva carpeta vacía denominada scheduleJobService. En la carpeta scheduleJobService, cree un archivo package.json con el siguiente comando en el símbolo del sistema. Acepte todos los valores predeterminados:

    npm init
    
  2. En el símbolo del sistema, en la carpeta scheduleJobService, ejecute el siguiente comando para instalar el paquete del SDK de dispositivo azure-iothub y el paquete azure-iot-device-mqtt:

    npm install azure-iothub uuid --save
    
  3. Con un editor de texto, cree un nuevo archivo scheduleJobService.js en la carpeta scheduleJobService.

  4. Agregue las siguientes instrucciones "require" al principio del archivo scheduleJobService.js:

    'use strict';
    
    var uuid = require('uuid');
    var JobClient = require('azure-iothub').JobClient;
    
  5. Agregue las siguientes declaraciones de variable. Reemplace el valor del marcador de posición {iothubconnectionstring} por el valor que copió en Obtención de la cadena de conexión de IoT Hub. Si registró un dispositivo distinto de myDeviceId, asegúrese de cambiarlo en la condición de consulta.

    var connectionString = '{iothubconnectionstring}';
    var queryCondition = "deviceId IN ['myDeviceId']";
    var startTime = new Date();
    var maxExecutionTimeInSeconds =  300;
    var jobClient = JobClient.fromConnectionString(connectionString);
    
  6. Agregue la función siguiente que se utiliza para supervisar la ejecución del trabajo:

    function monitorJob (jobId, callback) {
        var jobMonitorInterval = setInterval(function() {
            jobClient.getJob(jobId, function(err, result) {
            if (err) {
                console.error('Could not get job status: ' + err.message);
            } else {
                console.log('Job: ' + jobId + ' - status: ' + result.status);
                if (result.status === 'completed' || result.status === 'failed' || result.status === 'cancelled') {
                clearInterval(jobMonitorInterval);
                callback(null, result);
                }
            }
            });
        }, 5000);
    }
    
  7. Agregue el código siguiente para programar el trabajo que llama al método de dispositivo:

    var methodParams = {
        methodName: 'lockDoor',
        payload: null,
        responseTimeoutInSeconds: 15 // Timeout after 15 seconds if device is unable to process method
    };
    
    var methodJobId = uuid.v4();
    console.log('scheduling Device Method job with id: ' + methodJobId);
    jobClient.scheduleDeviceMethod(methodJobId,
                                queryCondition,
                                methodParams,
                                startTime,
                                maxExecutionTimeInSeconds,
                                function(err) {
        if (err) {
            console.error('Could not schedule device method job: ' + err.message);
        } else {
            monitorJob(methodJobId, function(err, result) {
                if (err) {
                    console.error('Could not monitor device method job: ' + err.message);
                } else {
                    console.log(JSON.stringify(result, null, 2));
                }
            });
        }
    });
    
  8. Agregue el código siguiente para programar el trabajo para que actualice el dispositivo gemelo:

    var twinPatch = {
       etag: '*',
       properties: {
           desired: {
               building: '43',
               floor: 3
           }
       }
    };
    
    var twinJobId = uuid.v4();
    
    console.log('scheduling Twin Update job with id: ' + twinJobId);
    jobClient.scheduleTwinUpdate(twinJobId,
                                queryCondition,
                                twinPatch,
                                startTime,
                                maxExecutionTimeInSeconds,
                                function(err) {
        if (err) {
            console.error('Could not schedule twin update job: ' + err.message);
        } else {
            monitorJob(twinJobId, function(err, result) {
                if (err) {
                    console.error('Could not monitor twin update job: ' + err.message);
                } else {
                    console.log(JSON.stringify(result, null, 2));
                }
            });
        }
    });
    
  9. Guarde y cierre el archivo scheduleJobService.js.

Ejecución de las aplicaciones

Ahora está preparado para ejecutar las aplicaciones.

  1. En el símbolo del sistema dentro de la carpeta simDevice, ejecute el siguiente comando para iniciar la escucha del método directo de reinicio.

    node simDevice.js
    
  2. En el símbolo del sistema de la carpeta scheduleJobService, ejecute el siguiente comando para desencadenar los trabajos a fin de bloquear la puerta y actualizar el dispositivo gemelo.

    node scheduleJobService.js
    
  3. Verá la respuesta del dispositivo al método directo y el estado del trabajo en la consola.

    A continuación, puede ver la respuesta del dispositivo al método directo:

    Salida de una aplicación de dispositivo simulado

    A continuación se muestran los trabajos de programación del servicio para el método directo, la actualización del dispositivo gemelo y los trabajos que se ejecutan hasta su finalización:

    Ejecución de una aplicación de dispositivo simulada

Pasos siguientes

En este artículo, ha programado trabajos para ejecutar un método directo y actualizar las propiedades del dispositivo gemelo.

Para continuar explorando el IoT Hub y los patrones de administración de dispositivos, actualice una imagen en el tutorial de Actualización de Dispositivos para Azure IoT Hub mediante la Imagen de Referencia de Raspberry Pi 3 B+.