Agendar e transmitir tarefas (Node.js)

Utilize Hub IoT do Azure para agendar e controlar tarefas que atualizam milhões de dispositivos. Utilizar tarefas para:

  • Atualizar as propriedades pretendidas
  • Atualizar etiquetas
  • Invocar métodos diretos

Conceptualmente, uma tarefa encapsula uma destas ações e controla o progresso da execução num conjunto de dispositivos, que é definido por uma consulta de dispositivo duplo. Por exemplo, uma aplicação de back-end pode utilizar uma tarefa para invocar um método de reinício em 10 000 dispositivos, especificado por uma consulta de dispositivo duplo e agendado numa hora futura. Essa aplicação pode, em seguida, controlar o progresso à medida que cada um desses dispositivos recebe e executa o método de reinício.

Saiba mais sobre cada uma destas capacidades nestes artigos:

Nota

As funcionalidades descritas neste artigo só estão disponíveis no escalão padrão de Hub IoT. Para obter mais informações sobre as camadas de Hub IoT básicas e padrão/gratuitas, consulte Escolher o escalão de Hub IoT adequado para a sua solução.

Este artigo mostra-lhe como criar duas aplicações Node.js:

  • Uma aplicação de dispositivo simulada Node.js, simDevice.js, que implementa um método direto chamado lockDoor, que pode ser chamado pela aplicação de back-end.

  • Uma aplicação de consola Node.js, scheduleJobService.js, que cria duas tarefas. Uma tarefa chama o método direto lockDoor e outra tarefa envia atualizações de propriedade pretendidas para vários dispositivos.

Nota

Veja SDKs do Azure IoT para obter mais informações sobre as ferramentas do SDK disponíveis para criar aplicações de back-end e dispositivos.

Pré-requisitos

  • Um hub IoT. Crie uma com a CLI ou a portal do Azure.

  • Um dispositivo registado. Registe um no portal do Azure.

  • Node.js versão 10.0.x ou posterior. Preparar o seu ambiente de desenvolvimento descreve como instalar Node.js para este artigo no Windows ou Linux.

  • Certifique-se de que a porta 8883 está aberta na firewall. O exemplo de dispositivo neste artigo utiliza o protocolo MQTT, que comunica através da porta 8883. Esta porta pode ser bloqueada em alguns ambientes de rede empresarial e educacional. Para obter mais informações e formas de resolver este problema, veja Ligar ao Hub IoT (MQTT).

Criar uma aplicação de dispositivo simulada

Nesta secção, vai criar uma aplicação de consola Node.js que responde a um método direto chamado pela cloud, que aciona um método lockDoor simulado.

  1. Crie uma nova pasta vazia chamada simDevice. Na pasta simDevice , crie um ficheiro package.json com o seguinte comando na linha de comandos. Aceite todas as predefinições:

    npm init
    
  2. Na linha de comandos na pasta simDevice , execute o seguinte comando para instalar o pacote Azure-iot-device Device SDK e o pacote azure-iot-device-mqtt :

    npm install azure-iot-device azure-iot-device-mqtt --save
    
  3. Com um editor de texto, crie um novo ficheiro simDevice.js na pasta simDevice .

  4. Adicione as seguintes instruções "exigir" no início do ficheiro desimDevice.js :

    'use strict';
    
    var Client = require('azure-iot-device').Client;
    var Protocol = require('azure-iot-device-mqtt').Mqtt;
    
  5. Adicione uma variável connectionString e utilize-a para criar uma instância do Cliente. Substitua o valor do {yourDeviceConnectionString} marcador de posição pela cadeia de ligação do dispositivo que copiou anteriormente.

    var connectionString = '{yourDeviceConnectionString}';
    var client = Client.fromConnectionString(connectionString, Protocol);
    
  6. Adicione a seguinte função para processar o 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. Adicione o seguinte código para registar o processador para o 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 e feche o ficheiro simDevice.js .

Nota

Para manter as coisas simples, este artigo não implementa uma política de repetição. No código de produção, deve implementar políticas de repetição (como um back-off exponencial), conforme sugerido no artigo Processamento Transitório de Falhas.

Obter a cadeia de ligação Hub IoT

Neste artigo, vai criar um serviço de back-end que agenda uma tarefa para invocar um método direto num dispositivo, agenda uma tarefa para atualizar o dispositivo duplo e monitoriza o progresso de cada tarefa. Para efetuar estas operações, o seu serviço precisa das permissões de escrita de registo e leitura do registo . Por predefinição, todos os hubs IoT são criados com uma política de acesso partilhado denominada registryReadWrite que concede estas permissões.

Para obter a cadeia de ligação Hub IoT para a política registryReadWrite, siga estes passos:

  1. Na portal do Azure, selecione Grupos de recursos. Selecione o grupo de recursos onde o hub está localizado e, em seguida, selecione o seu hub na lista de recursos.

  2. No painel do lado esquerdo do hub, selecione Políticas de acesso partilhado.

  3. Na lista de políticas, selecione a política registryReadWrite .

  4. Copie a cadeia de ligação Primária e guarde o valor.

    Captura de ecrã que mostra como obter a cadeia de ligação

Para obter mais informações sobre Hub IoT políticas e permissões de acesso partilhado, veja Controlo de acesso e permissões.

Agendar tarefas para chamar um método direto e atualizar as propriedades de um dispositivo duplo

Nesta secção, vai criar uma aplicação de consola Node.js que inicia um bloqueio remotoDoor num dispositivo através de um método direto e atualiza as propriedades do dispositivo duplo.

  1. Crie uma nova pasta vazia denominada scheduleJobService. Na pasta scheduleJobService , crie um ficheiro package.json com o seguinte comando na linha de comandos. Aceite todas as predefinições:

    npm init
    
  2. Na linha de comandos na pasta scheduleJobService , execute o seguinte comando para instalar o pacote Azure-iothub Device SDK e o pacote azure-iot-device-mqtt :

    npm install azure-iothub uuid --save
    
  3. Com um editor de texto, crie um novo ficheiro descheduleJobService.js na pasta scheduleJobService .

  4. Adicione as seguintes instruções "exigir" no início do ficheiro descheduleJobService.js :

    'use strict';
    
    var uuid = require('uuid');
    var JobClient = require('azure-iothub').JobClient;
    
  5. Adicione as seguintes declarações variáveis. Substitua o valor do {iothubconnectionstring} marcador de posição pelo valor que copiou em Obter a cadeia de ligação do hub IoT. Se tiver registado um dispositivo diferente de myDeviceId, certifique-se de que o altera na condição de consulta.

    var connectionString = '{iothubconnectionstring}';
    var queryCondition = "deviceId IN ['myDeviceId']";
    var startTime = new Date();
    var maxExecutionTimeInSeconds =  300;
    var jobClient = JobClient.fromConnectionString(connectionString);
    
  6. Adicione a seguinte função que é utilizada para monitorizar a execução da tarefa:

    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. Adicione o seguinte código para agendar a tarefa que chama o método do 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. Adicione o seguinte código para agendar a tarefa para atualizar o dispositivo duplo:

    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 e feche o ficheiro scheduleJobService.js .

Executar as aplicações

Pode agora executar as aplicações.

  1. Na linha de comandos na pasta simDevice , execute o seguinte comando para começar a escutar o método direto de reinício.

    node simDevice.js
    
  2. Na linha de comandos na pasta scheduleJobService , execute o seguinte comando para acionar as tarefas para bloquear a porta e atualizar o duplo

    node scheduleJobService.js
    
  3. Verá a resposta do dispositivo ao método direto e ao estado da tarefa na consola do .

    O seguinte mostra a resposta do dispositivo ao método direto:

    Saída da aplicação de dispositivo simulada

    O seguinte mostra as tarefas de agendamento do serviço para o método direto e a atualização do dispositivo duplo e as tarefas em execução até à conclusão:

    Executar a aplicação de dispositivo simulado

Passos seguintes

Neste artigo, agendou tarefas para executar um método direto e atualizar as propriedades do dispositivo duplo.

Para continuar a explorar padrões de gestão de Hub IoT e dispositivos, atualize uma imagem no tutorial Atualização de Dispositivos para Hub IoT do Azure com a Imagem de Referência Raspberry Pi 3 B+.