Pianificare e trasmettere processi (Node.js)

Usare l'hub IoT per pianificare e tenere traccia dei processi che aggiornano milioni di dispositivi. Usare i processi per:

  • Aggiornare le proprietà desiderate
  • Aggiornare i tag
  • Richiamare metodi diretti

Concettualmente, un processo esegue il wrapping di una di queste azioni e tiene traccia dell'avanzamento dell'esecuzione rispetto a un set di dispositivi, definito da una query di dispositivi gemelli. Grazie a un processo, ad esempio, un'app back-end può richiamare un metodo di riavvio in 10.000 dispositivi, specificato da una query di dispositivi gemelli e pianificato in un secondo momento. Tale applicazione può quindi tenere traccia dello stato di avanzamento quando ognuno di questi dispositivi riceve ed esegue il metodo di riavvio.

Altre informazioni su queste funzionalità sono disponibili in questi articoli:

Nota

Le funzionalità descritte in questo articolo sono disponibili solo nel livello Standard dell'hub IoT. Per altre informazioni sui livelli di hub IoT standard e standard, vedere Scegliere il livello di hub IoT appropriato per la soluzione.

Questo articolo illustra come creare due app Node.js:

  • UnNode.js'app per dispositivi simulati ,simDevice.js, che implementa un metodo diretto denominato lockDoor, che può essere chiamato dall'app back-end.

  • Un'app console di Node.js, scheduleJobService.js, che crea due processi. Un processo chiama il metodo diretto lockDoor e un altro processo invia gli aggiornamenti delle proprietà desiderati a più dispositivi.

Nota

Vedere Azure IoT SDK per altre informazioni sugli strumenti SDK disponibili per creare app per dispositivi e back-end.

Prerequisiti

  • Un hub IoT. Crearne uno con l'interfaccia della riga di comando o il portale di Azure.

  • Un dispositivo registrato. Registrarne uno nel portale di Azure.

  • Node.js 10.0.x o versione successiva. Preparare l'ambiente di sviluppo descrive come installare Node.js per questo articolo in Windows o Linux.

  • Assicurarsi che la porta 8883 sia aperta nel firewall. L'esempio di dispositivo di questo articolo usa il protocollo MQTT, che comunica tramite la porta 8883. Questa porta potrebbe essere bloccata in alcuni ambienti di rete aziendali e didattici. Per altre informazioni e soluzioni alternative per questo problema, vedere Connettersi all'hub IoT (MQTT).

Creare un'app di dispositivo simulato

In questa sezione viene creata un'applicazione console Node.js che risponde a un metodo chiamato dal cloud, che attiva un metodo lockDoor simulato.

  1. Creare una nuova cartella vuota chiamata simDevice. Nella cartella simDevice creare un file package.json eseguendo questo comando al prompt dei comandi. Accettare tutte le impostazioni predefinite:

    npm init
    
  2. Eseguire questo comando al prompt dei comandi nella cartella simDevice per installare il pacchetto SDK per dispositivi azure-iot-device e il pacchetto azure-iot-device-mqtt:

    npm install azure-iot-device azure-iot-device-mqtt --save
    
  3. Con un editor di testo creare un nuovo file simDevice.js nella cartella simDevice.

  4. Aggiungere le istruzioni "require" seguenti all'inizio del file simDevice.js:

    'use strict';
    
    var Client = require('azure-iot-device').Client;
    var Protocol = require('azure-iot-device-mqtt').Mqtt;
    
  5. Aggiungere una variabile connectionString e usarla per creare un'istanza Client. Sostituire il {yourDeviceConnectionString} valore segnaposto con la stringa di connessione del dispositivo copiata in precedenza.

    var connectionString = '{yourDeviceConnectionString}';
    var client = Client.fromConnectionString(connectionString, Protocol);
    
  6. Aggiungere la funzione seguente per gestire il metodo 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. Aggiungere il codice seguente per registrare il gestore per il metodo 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. Salvare e chiudere il file simDevice.js.

Nota

Per semplificare le operazioni, questo articolo non implementa criteri di ripetizione dei tentativi. Nel codice di produzione è consigliabile implementare criteri di ripetizione dei tentativi, ad esempio un backoff esponenziale, come suggerito nell'articolo Gestione degli errori temporanei.

Ottenere la stringa di connessione hub IoT

In questo articolo viene creato un servizio back-end che pianifica un processo per richiamare un metodo diretto in un dispositivo, pianifica un processo per l'aggiornamento del dispositivo gemello e monitora lo stato di ogni processo. Per eseguire queste operazioni, è necessario che il servizio disponga delle autorizzazioni di lettura del registro di sistema e scrittura del registro di sistema. Per impostazione predefinita, ogni hub IoT viene creato con un registryReadWrite con nome di criteri di accesso condiviso che concede tale autorizzazione.i.

Per ottenere la stringa di connessione dell'hub IoT per i criteri registryReadWrite, seguire questa procedura:

  1. Nel portale di Azure fare clic su Gruppi di risorse. Selezionare il gruppo di risorse in cui si trova l'hub e quindi selezionare l'hub dall'elenco di risorse.

  2. Nel riquadro sinistro dell'hub selezionare Criteri di accesso condiviso.

  3. Dall'elenco dei criteri selezionare il criterio registryReadWrite.

  4. Copiare la stringa di connessione primaria e salvare il valore.

    Acquisizione schermata che mostra come recuperare la stringa di connessione

Per altre informazioni sui criteri di accesso condiviso e sulle autorizzazioni dell'hub IoT, vedere Controllo dell'accesso e autorizzazioni.

Pianificare i processi per chiamare un metodo diretto e aggiornare le proprietà dei dispositivi gemelli

In questa sezione viene creata un'app console di Node.js che avvia una porta di blocco remota in un dispositivo usando un metodo diretto e si aggiornano le proprietà del dispositivo gemello.

  1. Creare una nuova cartella vuota chiamata scheduleJobService. Nella cartella scheduleJobService creare un file package.json eseguendo questo comando al prompt dei comandi. Accettare tutte le impostazioni predefinite:

    npm init
    
  2. Eseguire questo comando al prompt dei comandi nella cartella scheduleJobService per installare il pacchetto SDK per dispositivi azure-iothub e il pacchetto azure-iot-device-mqtt:

    npm install azure-iothub uuid --save
    
  3. Usando un editor di testo, creare un nuovo file scheduleJobService.js nella cartella scheduleJobService.

  4. Aggiungere le istruzioni "require" seguenti all'inizio del file scheduleJobService.js :

    'use strict';
    
    var uuid = require('uuid');
    var JobClient = require('azure-iothub').JobClient;
    
  5. Aggiungere le dichiarazioni di variabili seguenti. Sostituire il {iothubconnectionstring} valore segnaposto con il valore copiato in Ottenere la stringa di connessione dell'hub IoT. Se è stato registrato un dispositivo diverso da myDeviceId, assicurarsi di modificarlo nella condizione di query.

    var connectionString = '{iothubconnectionstring}';
    var queryCondition = "deviceId IN ['myDeviceId']";
    var startTime = new Date();
    var maxExecutionTimeInSeconds =  300;
    var jobClient = JobClient.fromConnectionString(connectionString);
    
  6. Aggiungere la funzione seguente che verrà usata per monitorare l'esecuzione del processo:

    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. Aggiungere il codice seguente per pianificare il processo che chiama il metodo del 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. Aggiungere il codice seguente per pianificare il processo che aggiorna il dispositivo gemello:

    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. Salvare e chiudere il file scheduleJobService.js.

Eseguire le applicazioni

A questo punto è possibile eseguire le applicazioni.

  1. Al prompt dei comandi nella cartella simDevice eseguire questo comando per iniziare l'ascolto del metodo diretto di riavvio.

    node simDevice.js
    
  2. Eseguire il comando riportato di seguito al prompt dei comandi nella cartella scheduleJobService per attivare i processi per bloccare la porta e aggiornare il dispositivo gemello

    node scheduleJobService.js
    
  3. Viene visualizzata la risposta del dispositivo al metodo diretto e lo stato del processo nella console.

    Di seguito viene illustrata la risposta del dispositivo al metodo diretto:

    Output dell'app del dispositivo simulato

    Di seguito vengono illustrati i processi di pianificazione del servizio per il metodo diretto e l'aggiornamento del dispositivo gemello e i processi in esecuzione fino al completamento:

    Eseguire un'app di dispositivo simulato

Passaggi successivi

In questo articolo sono stati pianificati processi per eseguire un metodo diretto e aggiornare le proprietà del dispositivo gemello.

Per continuare a esplorare hub IoT e i modelli di gestione dei dispositivi, aggiornare un'immagine in Aggiornamento dispositivi per hub IoT di Azure esercitazione usando l'immagine di riferimento Raspberry Pi 3 B+.