Agendar e transmitir trabalhos (Node.js)

Use o Hub IoT do Azure para agendar e controlar os trabalhos que atualizam milhões de dispositivos. Use trabalhos para:

  • Atualizar as propriedades desejadas
  • Marcas de atualização
  • Chamar métodos diretos

Conceitualmente, um trabalho encapsula uma dessas ações e rastreia o progresso da execução com relação a um conjunto de dispositivos, definido por uma consulta do dispositivo gêmeo. Por exemplo, um aplicativo de back-end pode usar um trabalho para invocar um método de reinicialização em 10.000 dispositivos, especificado por uma consulta do dispositivo gêmeo e agendado no futuro. Esse aplicativo pode acompanhar o progresso à medida que cada um desses dispositivos recebe e executa o método de reinicialização.

Saiba mais sobre cada um desses recursos nestes artigos:

Observação

Os recursos descritos neste artigo estão disponíveis apenas na camada padrão do Hub IoT. Para obter mais informações sobre as camadas básica e padrão/gratuita do Hub IoT, confira Escolher a camada certa do Hub IoT para sua solução.

Este artigo mostra como criar dois aplicativos Node.js:

  • Um aplicativo de dispositivo simulado Node.js, simDevice.js que implementa um método direto chamado lockDoor que pode ser chamado pelo aplicativo de back-end.

  • Um aplicativo de console Node.js, scheduleJobService.js, que cria dois trabalhos. Um trabalho chama o método direto lockDoor e outro envia atualizações de propriedade desejadas para vários dispositivos.

Observação

Consulte os SDKs da IoT do Azure para obter mais informações sobre as ferramentas do SDK disponíveis para compilar aplicativos de dispositivo e back-end.

Pré-requisitos

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

  • Um dispositivo registrado. Registre um no portal do Azure.

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

  • Verifique se a porta 8883 está aberta no firewall. O exemplo de dispositivo deste artigo usa o protocolo MQTT, que se comunica pela porta 8883. Essa porta poderá ser bloqueada em alguns ambientes de rede corporativos e educacionais. Para obter mais informações e maneiras de resolver esse problema, confira Como se conectar ao Hub IoT (MQTT).

Criar um aplicativo de dispositivo simulado

Nesta seção, você cria um aplicativo de console do Node.js que responde a um método direto chamado pela nuvem, que aciona um método lockDoor simulado.

  1. Crie uma nova pasta vazia denominada simDevice. Na pasta simDevice, crie um arquivo package.json usando o comando a seguir no seu prompt de comando. Aceite todos os padrões:

    npm init
    
  2. No prompt de comando, na pasta simDevice, execute o seguinte comando para instalar o pacote azure-iot-device do SDK do Dispositivo e o pacote azure-iot-device-mqtt:

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

  4. Adicione as seguintes instruções "require" no início do arquivo simDevice.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 use-a para criar um Cliente do dispositivo. Substitua o valor do espaço reservado {yourDeviceConnectionString} pela cadeia de conexão do dispositivo que você copiou anteriormente.

    var connectionString = '{yourDeviceConnectionString}';
    var client = Client.fromConnectionString(connectionString, Protocol);
    
  6. Adicione a seguinte função para manipular 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 registrar o manipulador do 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. Salve e feche o arquivo simDevice.js.

Observação

Para simplificar, este artigo não implementa nenhuma política de repetição. No código de produção, implemente políticas de repetição (como uma retirada exponencial), conforme sugerido no artigo Tratamento de falhas transitórias.

Obter a cadeia de conexão do Hub IoT

Neste artigo, você cria um serviço de back-end que agenda um trabalho para invocar um método direto em um dispositivo, agenda um trabalho para atualizar o dispositivo gêmeo e monitora o progresso de cada trabalho. Para executar essas operações, o seu serviço precisa das permissões leitura de registro e gravação de registro. Por padrão, todo hub IoT é criado com uma política de acesso compartilhado chamada registryReadWrite que concede essas permissões.

Para obter a cadeia de conexão do Hub IoT para a política registryReadWrite, siga estas etapas:

  1. No portal do Azure, selecione Grupos de recursos. Selecione o grupo de recursos em que 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 compartilhado.

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

  4. Copie a Cadeia de conexão primária e salve o valor.

    Captura de tela que mostra como recuperar a cadeia de conexão

Para obter mais informações sobre permissões e políticas de acesso compartilhado do Hub IoT, consulte Controle de acesso e permissões.

Agendar trabalhos para chamar um método direto e atualizar as propriedades do dispositivo gêmeo

Nesta seção, é possível criar um aplicativo de console do Node.js que inicia um lockDoor remoto em um dispositivo usando um método direto e atualizar as propriedades do dispositivo gêmeo.

  1. Crie uma nova pasta vazia denominada scheduleJobService. Na pasta scheduleJobService, crie um arquivo package.json usando o comando a seguir no prompt de comando. Aceite todos os padrões:

    npm init
    
  2. No prompt de comando, na pasta scheduleJobService, execute o seguinte comando para instalar o pacote azure-iothub do SDK do Dispositivo e o pacote azure-iot-device-mqtt:

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

  4. Adicione as seguintes instruções "require" no início do arquivo scheduleJobService.js:

    'use strict';
    
    var uuid = require('uuid');
    var JobClient = require('azure-iothub').JobClient;
    
  5. Adicione as declarações de variável a seguir. Substitua o valor de espaço reservado {iothubconnectionstring} pelo valor que você copiou em Obter a cadeia de conexão do hub IoT. Se você registrou um dispositivo diferente de myDeviceId, altere-o 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 é usada para monitorar a execução do trabalho:

    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 o trabalho que chama o 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. Adicione o seguinte código para agendar o trabalho para atualizar o dispositivo gêmeo:

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

Executar os aplicativos

Agora você está pronto para executar os aplicativos.

  1. No prompt de comando, na pasta simDevice, execute o seguinte comando para começar a escutar o método direto de reinicialização.

    node simDevice.js
    
  2. No prompt de comando da pasta scheduleJobService, execute o seguinte comando para disparar os trabalhos para bloquear a porta e atualizar o twin

    node scheduleJobService.js
    
  3. Você vê a resposta do dispositivo ao método direto e o status do trabalho no console.

    A seguir, a resposta do dispositivo para o método direto:

    Saída do aplicativo de dispositivo simulado

    A seguir, trabalhos de agendamento de serviço para o método direto e a atualização do dispositivo gêmeo, e os trabalhos em execução para a conclusão:

    Executar um aplicativo de dispositivo simulado

Próximas etapas

Neste artigo, você agendou trabalhos para executar um método direto e atualizar as propriedades do dispositivo gêmeo.

Para continuar explorando os padrões de Hub IoT e de gerenciamento de dispositivo, atualize uma imagem no tutorial Atualização de dispositivo para o Hub IoT do Azure usando a imagem de referência do Raspberry Pi 3 B +.