Подключение устройства к акселератору решения для удаленного мониторинга (Node.js)
В этом руководстве вы реализуете устройство Chiller, которое отправляет следующие данные телеметрии в акселератор решений для удаленного мониторинга:
- температура;
- Давление
- влажность.
Чтобы упростить задачу, при помощи кода создаются примеры значений телеметрии для Chiller. Вы можете расширить пример, подключив к устройству физические датчики, которые будут отправлять реальные данные телеметрии.
Устройство в примере также:
- отправляет в решение метаданные для описания его возможностей;
- реагирует на действия, активированные на странице решения Устройства;
- реагирует на изменения конфигурации, сведения о которых отправляются со страницы решения Устройства.
Для работы с этим руководством требуется активная учетная запись Azure. Если ее нет, можно создать бесплатную пробную учетную запись всего за несколько минут. Дополнительные сведения см. в разделе Бесплатная пробная версия Azure.
Перед началом работы
Прежде чем писать код для устройства, разверните акселератор решения для удаленного мониторинга и добавьте в решение новое реальное устройство.
Развертывание акселератора решения для удаленного мониторинга
Созданное в этом руководстве устройство Chiller отправляет данные в экземпляр акселератора решений для удаленного мониторинга. Если вы еще не подготовили этот акселератор решений в своей учетной записи Azure, изучите статью Развертывание акселератора решения для удаленного мониторинга.
После завершения развертывания решения для удаленного мониторинга нажмите кнопку Запустить, чтобы открыть панель мониторинга этого решения в браузере.
Добавление устройства в решение для удаленного мониторинга
Примечание
Если вы уже добавили устройство в решение, пропустите этот шаг. Однако для следующего шага требуется строка подключения вашего устройства. Вы можете получить строку подключения устройства на портале Azure или с помощью средства CLI az iot.
Чтобы устройство смогло подключиться к акселератору решений, оно должно пройти идентификацию в Центре Интернета вещей с использованием допустимых учетных данных. При добавлении устройства в решение есть возможность сохранить строку подключения устройства, содержащую эти учетные данные. Вы добавите эту строку подключения в клиентское приложение далее в этом руководстве.
Чтобы добавить устройство в решение для удаленного мониторинга, выполните следующие действия на странице решения Обозреватель устройств:
Щелкните + Новое устройство, а затем для параметра Тип устройства выберите значение Реальное:
Введите значение Physical-chiller в качестве идентификатора устройства. Выберите параметры Симметричный ключ и Автоматически создавать ключи:
Нажмите кнопку Применить. Затем запишите значения параметров Идентификатор устройства, Первичный ключ и Строка подключения — первичный ключ:
Вы добавили реальное устройство в акселератор решения для удаленного мониторинга и записали его строку подключения. В следующих разделах реализуется клиентское приложение, которое использует строку подключения устройства для подключения к решению.
Клиентское приложение реализует встроенную модель устройства Chiller. Модель устройства с акселератором решений указывает следующие данные устройства:
- Сведения о свойствах, которые устройство передает в решение. Например, устройство Chiller передает сведения о своей микропрограмме и расположении.
- Сведения о типах данных телеметрии, которые устройство отправляет в решение. Например, устройство Chiller отправляет показатели температуры, влажности и давления.
- Сведения о методах, запуск которых можно запланировать на устройстве при помощи решения. Например, устройство Chiller должно реализовать методы Reboot, FirmwareUpdate, EmergencyValveRelease и IncreasePressure.
В этом руководстве показано, как подключить реальное устройство к акселератору решения для удаленного мониторинга. В этом руководстве используется Node.js, поэтому оно подходит для сред с минимальными ограничениями ресурсов.
Если вы предпочитаете имитацию устройства, см. раздел Создание и тестирование нового имитированного устройства.
Создание решения Node.js
Убедитесь, что на компьютере разработки установлен компонент Node.js версии 4.0.0 или более поздней. Можно запустить node --version
в командной строке, чтобы проверить версию.
Создайте папку с именем
remotemonitoring
на компьютере для разработки. Перейдите к этой папке в среде командной строки.Чтобы скачать и установить пакеты, необходимые для выполнения примера приложения, выполните следующие команды:
npm init npm install async azure-iot-device azure-iot-device-mqtt --save
В папке
remotemonitoring
создайте файл с именем remote_monitoring.js. Откройте этот файл в текстовом редакторе.Откройте файл remote-monitoring.js и добавьте следующие инструкции
require
:var Protocol = require('azure-iot-device-mqtt').Mqtt; var Client = require('azure-iot-device').Client; var Message = require('azure-iot-device').Message; var async = require('async');
После операторов
require
добавьте указанные ниже объявления переменных. Замените значение заполнителя{device connection string}
ранее записанным значением для своего устройства, подготовленного в решении для удаленного мониторинга:var connectionString = '{device connection string}';
Чтобы определить базовые данные телеметрии, добавьте следующие переменные:
var temperature = 50; var temperatureUnit = 'F'; var humidity = 50; var humidityUnit = '%'; var pressure = 55; var pressureUnit = 'psig';
Чтобы определить некоторые значения свойств, добавьте следующие переменные:
var schema = "real-chiller;v1"; var deviceType = "RealChiller"; var deviceFirmware = "1.0.0"; var deviceFirmwareUpdateStatus = ""; var deviceLocation = "Building 44"; var deviceLatitude = 47.638928; var deviceLongitude = -122.13476; var deviceOnline = true;
Добавьте следующую переменную, чтобы определить, какие передаваемые свойства должны отправляться в решение. Эти свойства содержат метаданные, отображаемые в пользовательском веб-интерфейсе.
var reportedProperties = { "SupportedMethods": "Reboot,FirmwareUpdate,EmergencyValveRelease,IncreasePressure", "Telemetry": { [schema]: "" }, "Type": deviceType, "Firmware": deviceFirmware, "FirmwareUpdateStatus": deviceFirmwareUpdateStatus, "Location": deviceLocation, "Latitude": deviceLatitude, "Longitude": deviceLongitude, "Online": deviceOnline }
Добавьте следующую вспомогательную функцию для вывода результатов операции:
function printErrorFor(op) { return function printError(err) { if (err) console.log(op + ' error: ' + err.toString()); }; }
Добавьте следующую вспомогательную функцию для создания случайных значений телеметрии:
function generateRandomIncrement() { return ((Math.random() * 2) - 1); }
Добавьте приведенную ниже общую функцию для обработки вызовов прямого метода из решения. Функция отвечает за отображение сведений о вызванном прямом методе. В этом примере ее использование не приводит к каким-либо изменениям устройства. Решение использует прямые методы для выполнения действий на устройствах:
function onDirectMethod(request, response) { // Implement logic asynchronously here. console.log('Simulated ' + request.methodName); // Complete the response response.send(200, request.methodName + ' was called on the device', function (err) { if (err) console.error('Error sending method response :\n' + err.toString()); else console.log('200 Response to method \'' + request.methodName + '\' sent successfully.'); }); }
Добавьте приведенную ниже функцию для обработки вызовов прямого метода FirmwareUpdate из решения. Функция отвечает за проверку параметров, переданных в полезные данные прямого метода, и асинхронный запуск моделирования для обновления встроенного ПО:
function onFirmwareUpdate(request, response) { // Get the requested firmware version from the JSON request body var firmwareVersion = request.payload.Firmware; var firmwareUri = request.payload.FirmwareUri; // Ensure we got a firmware values if (!firmwareVersion || !firmwareUri) { response.send(400, 'Missing firmware value', function(err) { if (err) console.error('Error sending method response :\n' + err.toString()); else console.log('400 Response to method \'' + request.methodName + '\' sent successfully.'); }); } else { // Respond the cloud app for the device method response.send(200, 'Firmware update started.', function(err) { if (err) console.error('Error sending method response :\n' + err.toString()); else { console.log('200 Response to method \'' + request.methodName + '\' sent successfully.'); // Run the simulated firmware update flow runFirmwareUpdateFlow(firmwareVersion, firmwareUri); } }); } }
Добавьте следующую функцию для моделирования длительного потока обновления встроенного ПО с передачей в решение сведений о ходе выполнения:
// Simulated firmwareUpdate flow function runFirmwareUpdateFlow(firmwareVersion, firmwareUri) { console.log('Simulating firmware update flow...'); console.log('> Firmware version passed: ' + firmwareVersion); console.log('> Firmware URI passed: ' + firmwareUri); async.waterfall([ function (callback) { console.log("Image downloading from " + firmwareUri); var patch = { FirmwareUpdateStatus: 'Downloading image..' }; reportUpdateThroughTwin(patch, callback); sleep(10000, callback); }, function (callback) { console.log("Downloaded, applying firmware " + firmwareVersion); deviceOnline = false; var patch = { FirmwareUpdateStatus: 'Applying firmware..', Online: false }; reportUpdateThroughTwin(patch, callback); sleep(8000, callback); }, function (callback) { console.log("Rebooting"); var patch = { FirmwareUpdateStatus: 'Rebooting..' }; reportUpdateThroughTwin(patch, callback); sleep(10000, callback); }, function (callback) { console.log("Firmware updated to " + firmwareVersion); deviceOnline = true; var patch = { FirmwareUpdateStatus: 'Firmware updated', Online: true, Firmware: firmwareVersion }; reportUpdateThroughTwin(patch, callback); callback(null); } ], function(err) { if (err) { console.error('Error in simulated firmware update flow: ' + err.message); } else { console.log("Completed simulated firmware update flow"); } }); // Helper function to update the twin reported properties. function reportUpdateThroughTwin(patch, callback) { console.log("Sending..."); console.log(JSON.stringify(patch, null, 2)); client.getTwin(function(err, twin) { if (!err) { twin.properties.reported.update(patch, function(err) { if (err) callback(err); }); } else { if (err) callback(err); } }); } function sleep(milliseconds, callback) { console.log("Simulate a delay (milleseconds): " + milliseconds); setTimeout(function () { callback(null); }, milliseconds); } }
Добавьте приведенный ниже код для отправки данных телеметрии в решение. Клиентское приложение добавляет свойства в сообщение, чтобы определить его схему:
function sendTelemetry(data, schema) { if (deviceOnline) { var d = new Date(); var payload = JSON.stringify(data); var message = new Message(payload); message.properties.add('iothub-creation-time-utc', d.toISOString()); message.properties.add('iothub-message-schema', schema); console.log('Sending device message data:\n' + payload); client.sendEvent(message, printErrorFor('send event')); } else { console.log('Offline, not sending telemetry'); } }
Добавьте следующий код для создания экземпляра клиента:
var client = Client.fromConnectionString(connectionString, Protocol);
Добавьте следующий код, который:
открывает подключение;
настраивает обработчик для требуемых свойств;
отправляет сообщаемые свойства;
регистрирует обработчики для прямых методов; В примере используется отдельный обработчик для прямого метода обновления встроенного ПО.
начинает отправку данных телеметрии.
client.open(function (err) { if (err) { printErrorFor('open')(err); } else { // Create device Twin client.getTwin(function (err, twin) { if (err) { console.error('Could not get device twin'); } else { console.log('Device twin created'); twin.on('properties.desired', function (delta) { // Handle desired properties set by solution console.log('Received new desired properties:'); console.log(JSON.stringify(delta)); }); // Send reported properties twin.properties.reported.update(reportedProperties, function (err) { if (err) throw err; console.log('Twin state reported'); }); // Register handlers for all the method names we are interested in. // Consider separate handlers for each method. client.onDeviceMethod('Reboot', onDirectMethod); client.onDeviceMethod('FirmwareUpdate', onFirmwareUpdate); client.onDeviceMethod('EmergencyValveRelease', onDirectMethod); client.onDeviceMethod('IncreasePressure', onDirectMethod); } }); // Start sending telemetry var sendDeviceTelemetry = setInterval(function () { temperature += generateRandomIncrement(); pressure += generateRandomIncrement(); humidity += generateRandomIncrement(); var data = { 'temperature': temperature, 'temperature_unit': temperatureUnit, 'humidity': humidity, 'humidity_unit': humidityUnit, 'pressure': pressure, 'pressure_unit': pressureUnit }; sendTelemetry(data, schema) }, 5000); client.on('error', function (err) { printErrorFor('client')(err); if (sendTemperatureInterval) clearInterval(sendTemperatureInterval); if (sendHumidityInterval) clearInterval(sendHumidityInterval); if (sendPressureInterval) clearInterval(sendPressureInterval); client.close(printErrorFor('client.close')); }); } });
Сохраните изменения в файле remote_monitoring.js.
Чтобы запустить пример приложения, выполните следующую команду в командной строке:
node remote_monitoring.js
Просмотр телеметрии устройства
Вы можете просмотреть данные телеметрии, отправленные с устройства, на странице Обозреватель устройств в решении.
Выберите подготовленное устройство в списке устройств на странице Обозреватель устройств. На панели отображаются сведения об устройстве, включая график телеметрии устройства:
Выберите Pressure (Давление) для изменения порядка отображения телеметрии:
Чтобы просмотреть диагностические сведения об устройстве, прокрутите вниз до раздела Diagnostics (Диагностика):
Действия на устройстве
Для вызова методов на устройствах используйте страницу Обозреватель устройств в решении для удаленного мониторинга. Например, в устройствах решения для удаленного мониторинга Chiller реализован метод перезагрузки.
Выберите Устройства для перехода к странице Обозреватель устройств в решении.
Выберите подготовленное устройство в списке устройств на странице Обозреватель устройств:
Чтобы отобразить список методов, которые можно вызвать на устройстве, выберите Задания > Методы. Чтобы запланировать выполнение задания на нескольких устройствах, можно выбрать несколько устройств в списке. На панели Jobs (Задания) отображаются типы метода, который является общим для всех выбранных устройств.
Выберите Перезагрузка, задайте имя задания RebootPhysicalChiller и щелкните Применить:
Когда имитированное устройство обрабатывает метод, в консоли отображается последовательность сообщений о выполнении кода устройства.
Примечание
Для отслеживания состояния задания в решении выберите Просмотреть состояние задания.
Дальнейшие действия
Способы настройки акселератора решений описаны в статье Настройка акселератора решения для удаленного мониторинга.