Планирование и трансляция заданий (Node.js)

Центр Интернета вещей Azure позволяет планировать и отслеживать задания по обновлению для миллионов устройств. Что можно сделать с помощью заданий?

  • Обновление требуемых свойств
  • Обновление тегов
  • Вызов прямых методов

По сути, задание включает одно из этих действий, отслеживая ход его выполнения на наборе устройств (определяется запросом двойника устройства). Например, с помощью задания внутреннее приложение может вызывать метод перезагрузки на 10 000 устройств, определенных запросом двойника устройства и запланированных в будущем. Затем это приложение может отследить ход выполнения задания по мере получения и выполнения метода перезагрузки на каждом из этих устройств.

Дополнительные сведения о каждой из этих возможностей см. в следующих статьях:

Примечание

Функции, описанные в этой статье, доступны только на стандартном уровне Центра Интернета вещей. Дополнительные сведения о базовых и стандартных и бесплатных уровнях Центр Интернета вещей см. в статье Выбор подходящего уровня Центр Интернета вещей для решения.

В этой статье показано, как создать два приложения Node.js:

  • Приложение имитированного устройства Node.js (simDevice.js), которое реализует прямой метод lockDoor, вызываемый внутренним приложением.

  • Консольное приложение Node.js scheduleJobService.js, которое создает два задания. Одно задание вызывает прямой метод lockDoor, а другое задание отправляет нужные обновления свойств на несколько устройств.

Примечание

Дополнительные сведения о средствах SDK, доступных для создания приложения устройства и внутреннего приложения, см. в статье Пакеты SDK для Интернета вещей Azure.

Предварительные требования

  • Центр Интернета вещей. Создайте его с помощью CLI или портал Azure.

  • Зарегистрированное устройство. Зарегистрируйте его на портале Azure.

  • Node.js 10.0.x или более поздней версии. В разделе Подготовка среды разработки описана установка Node.js для работы с настоящей статьей в ОС Windows или Linux.

  • Убедитесь, что в брандмауэре открыт порт 8883. Пример устройства в этой статье использует протокол MQTT, который передает данные через порт 8883. В некоторых корпоративных и академических сетях этот порт может быть заблокирован. Дополнительные сведения и способы устранения этой проблемы см. в разделе о подключении к Центру Интернета вещей по протоколу MQTT.

Создание приложения виртуального устройства

В этом разделе вы создадите консольное приложение Node.js, отвечающее на прямой метод, вызванный из облака, который активирует имитированный метод lockDoor.

  1. Создайте пустую папку с именем simDevice. В папке simDevice создайте файл package.json, используя следующую команду в командной строке. Примите значения по умолчанию:

    npm init
    
  2. В командной строке в папке simDevice выполните следующую команду, чтобы установить пакет SDK для устройств azure-iot-device и пакет azure-iot-device-mqtt.

    npm install azure-iot-device azure-iot-device-mqtt --save
    
  3. В текстовом редакторе создайте файл simDevice.js в папке simDevice.

  4. Добавьте следующие инструкции require в начало файла simDevice.js:

    'use strict';
    
    var Client = require('azure-iot-device').Client;
    var Protocol = require('azure-iot-device-mqtt').Mqtt;
    
  5. Добавьте переменную connectionString, чтобы создать с ее помощью экземпляр клиента. Замените заполнитель {yourDeviceConnectionString} реальным значением строки подключения к устройству, которую вы скопировали ранее.

    var connectionString = '{yourDeviceConnectionString}';
    var client = Client.fromConnectionString(connectionString, Protocol);
    
  6. Добавьте следующую функцию для обработки метода 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. Добавьте следующий код для регистрации обработчика для метода 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. Сохраните и закройте файл simDevice.js.

Примечание

Для простоты в этой статье не реализуется политика повтора. В рабочем коде следует реализовать политики повторных попыток (например, с экспоненциальной задержкой), как указано в статье Обработка временных сбоев.

Получение строки подключения Центра Интернета вещей

В этой статье вы создадите серверную службу, которая планирует задание для вызова прямого метода на устройстве, планирует задание для обновления двойника устройства и отслеживает ход выполнения каждого задания. Для выполнения этих операций службе требуются разрешения registry read и registry write. По умолчанию каждый Центр Интернета вещей создается с помощью политики общего доступа, называемой registryReadWrite, которая предоставляет это разрешение.

Чтобы получить строку подключения Центра Интернета вещей для политики registryReadWrite, выполните следующие действия:

  1. На портале Azure выберите Группы ресурсов. Выберите группу ресурсов, в которой находится центр, а затем выберите центр из списка ресурсов.

  2. В левой части центра выберите Политики общего доступа.

  3. В списке политик выберите политику registryReadWrite.

  4. Скопируйте основную строку подключения и сохраните значение.

    Снимок экрана: получение строки подключения

Дополнительные сведения о политиках и разрешениях общего доступа Центра Интернета вещей см. в разделе Управления доступом и разрешения.

Планирование заданий для вызова прямого метода и обновления свойств двойника устройства

В этом разделе создается консольное приложение Node.js, которое инициирует удаленное действие lockDoor на устройстве с помощью прямого метода и обновляет свойства двойника устройства.

  1. Создайте пустую папку с именем scheduleJobService. В папке scheduleJobService создайте файл package.json, используя следующую команду в командной строке. Примите значения по умолчанию:

    npm init
    
  2. В командной строке в папке scheduleJobService выполните следующую команду, чтобы установить пакет SDK для устройств azure-iothub и пакет azure-iot-device-mqtt.

    npm install azure-iothub uuid --save
    
  3. В текстовом редакторе создайте файл scheduleJobService.js в папке scheduleJobService.

  4. Добавьте следующие инструкции require в начало файла scheduleJobService.js:

    'use strict';
    
    var uuid = require('uuid');
    var JobClient = require('azure-iothub').JobClient;
    
  5. Добавьте следующие объявления переменных. Замените заполнитель {iothubconnectionstring} реальным значением, которое вы скопировали в разделе Получение строки подключения центра Интернета вещей. Если вы зарегистрировали устройство с именем, отличным от myDeviceId, не забудьте изменить это значение в условии запроса.

    var connectionString = '{iothubconnectionstring}';
    var queryCondition = "deviceId IN ['myDeviceId']";
    var startTime = new Date();
    var maxExecutionTimeInSeconds =  300;
    var jobClient = JobClient.fromConnectionString(connectionString);
    
  6. Добавьте следующую функцию, которая используется, чтобы отслеживать выполнение задания:

    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. Добавьте следующий код, чтобы запланировать задание, которое вызывает метод устройства:

    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. Добавьте следующий код, чтобы запланировать задание, которое обновляет двойник устройства:

    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. Сохраните и закройте файл scheduleJobService.js.

Запуск приложений

Теперь все готово к запуску приложений.

  1. В командной строке в папке simDevice выполните следующую команду, чтобы начать прослушивание прямого метода перезагрузки:

    node simDevice.js
    
  2. В командной строке в папке scheduleJobService выполните следующую команду, чтобы активировать задачи для блокировки дверей и обновления двойника.

    node scheduleJobService.js
    
  3. В консоли вы увидите ответ устройства на прямой метод и состояние задания.

    Ниже показан ответ устройства на прямой метод:

    Выходные данные приложения имитированного устройства

    Ниже демонстрируются задания планирования обслуживания для прямого метода и обновление двойника устройства, а также выполнение этих заданий до успешного завершения:

    Запуск приложения виртуального устройства

Дальнейшие действия

По материалам этой статьи вы запланировали задания для запуска прямого метода и обновления свойств двойника устройства.

Для продолжения работы с Центром Интернета вещей и шаблонами управления устройствами обновите образ в соответствии с инструкциями из руководства по обновлению устройств для Центра Интернета вещей Azure: использование эталонного образа для Raspberry Pi 3 B +.