- Windows C 上的
- Linux 上的 C
- Node.js
场景概述
在此方案中,你将创建一个设备,用于将以下遥测数据发送到远程监视 预配置解决方案:
- 外部温度
- 内部温度
- 湿度
为简单起见,设备上的代码会生成示例值,但我们建议你通过将真实传感器连接到设备并发送实际遥测数据来扩展示例。
设备还能够响应从解决方案仪表板调用的方法和解决方案仪表板中设置的所需属性值。
若要完成本教程,需要一个有效的 Azure 帐户。 如果没有帐户,只需花费几分钟就能创建一个免费试用帐户。 有关详细信息,请参阅 Azure 免费试用。
开始之前
在为设备编写任何代码之前,必须预配远程监视预配置解决方案并在该解决方案中预配新的自定义设备。
配置您的远程监控预配置解决方案
本教程中创建的设备将数据发送到 远程监视 预配置解决方案的实例。 如果尚未在 Azure 帐户中预配远程监视预配置解决方案,请使用以下步骤:
- 在 https://www.azureiotsolutions.com/ 页面上,单击 + 以创建解决方案。
- 单击“选择”远程监视面板以创建解决方案。
- 在 “创建远程监视解决方案 ”页上,输入所选 的解决方案名称 ,选择要部署到 的区域 ,然后选择要使用的 Azure 订阅。 然后单击“ 创建解决方案”。
- 等待预配过程完成。
警告
预配置的解决方案使用可计费的 Azure 服务。 使用完预配置解决方案后,请务必从您的订阅中删除,以避免产生任何不必要的费用。 可以通过访问 https://www.azureiotsolutions.com/ 页面,从订阅中完全删除预配置解决方案。
远程监视解决方案的预配过程完成后,单击“ 启动 ”以在浏览器中打开解决方案仪表板。
在远程监控解决方案中配置设备
注释
如果已在解决方案中预配了设备,则可以跳过此步骤。 创建客户端应用程序时,需要知道设备凭据。
若要使设备连接到预配置解决方案,它必须使用有效的凭据将自身标识到 IoT 中心。 可以从解决方案仪表板检索设备凭据。 在本教程中,稍后您将在客户端应用程序中包含设备凭据。
若要将设备添加到远程监视解决方案,请在解决方案仪表板中完成以下步骤:
在仪表板的左下角,单击 添加设备。
在 自定义设备 面板中,单击 添加新。
选择让我定义自己的设备ID。 输入设备 ID(如 mydevice),单击 “检查 ID ”以验证名称是否尚未使用,然后单击“ 创建 ”预配设备。
记下设备凭据(设备 ID、IoT 中心主机名和设备密钥)。 客户端应用程序需要这些值才能连接到远程监视解决方案。 然后单击“完成”。
在解决方案仪表板的设备列表中选择设备。 然后,在 设备详细信息 面板中,单击 启用设备。 设备当前状态为 运行。 远程监视解决方案现在可以从设备接收遥测数据,并在设备上调用方法。
创建 node.js 示例解决方案
确保在开发计算机上安装 Node.js 版本 0.11.5 或更高版本。 可以在命令行中运行 node --version 以检查版本。
在开发计算机上创建名为 RemoteMonitoring 的文件夹。 在命令行环境中导航到此文件夹。
运行以下命令,下载并安装完成示例应用所需的包:
npm init npm install azure-iot-device azure-iot-device-mqtt --save在 RemoteMonitoring 文件夹中,创建名为 remote_monitoring.js的文件。 在文本编辑器中打开此文件。
在 remote_monitoring.js 文件中,添加以下
require语句:'use strict'; var Protocol = require('azure-iot-device-mqtt').Mqtt; var Client = require('azure-iot-device').Client; var ConnectionString = require('azure-iot-device').ConnectionString; var Message = require('azure-iot-device').Message;在语句后面
require添加以下变量声明。 将占位符值 [Device Id] 和 [Device Key] 替换为在远程监视解决方案仪表板中为设备记录的值。 使用解决方案仪表板中的 IoT 中心主机名替换 [IoTHub 名称]。 例如,如果 IoT 中心主机名 contoso.azure-devices.net,请将 [IoTHub Name] 替换为 contoso:var connectionString = 'HostName=[IoTHub Name].azure-devices.net;DeviceId=[Device Id];SharedAccessKey=[Device Key]'; var deviceId = ConnectionString.parse(connectionString).DeviceId;添加以下变量以定义一些基本遥测数据:
var temperature = 50; var humidity = 50; var externalTemperature = 55;添加以下辅助函数以打印操作结果:
function printErrorFor(op) { return function printError(err) { if (err) console.log(op + ' error: ' + err.toString()); }; }添加以下帮助程序函数以用于随机化遥测值:
function generateRandomIncrement() { return ((Math.random() * 2) - 1); }为设备启动时发送的 DeviceInfo 对象添加以下定义:
var deviceMetaData = { 'ObjectType': 'DeviceInfo', 'IsSimulatedDevice': 0, 'Version': '1.0', 'DeviceProperties': { 'DeviceID': deviceId, 'HubEnabledState': 1 } };为设备孪生报告的值添加以下定义。 此定义包括设备支持的直接方法的说明:
var reportedProperties = { "Device": { "DeviceState": "normal", "Location": { "Latitude": 47.642877, "Longitude": -122.125497 } }, "Config": { "TemperatureMeanValue": 56.7, "TelemetryInterval": 45 }, "System": { "Manufacturer": "Contoso Inc.", "FirmwareVersion": "2.22", "InstalledRAM": "8 MB", "ModelNumber": "DB-14", "Platform": "Plat 9.75", "Processor": "i3-9", "SerialNumber": "SER99" }, "Location": { "Latitude": 47.642877, "Longitude": -122.125497 }, "SupportedMethods": { "Reboot": "Reboot the device", "InitiateFirmwareUpdate--FwPackageURI-string": "Updates device Firmware. Use parameter FwPackageURI to specifiy the URI of the firmware file" }, }添加以下函数以处理 Reboot 直接方法调用:
function onReboot(request, response) { // Implement actual logic here. console.log('Simulated reboot...'); // Complete the response response.send(200, "Rebooting device", 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.' ); } }); }添加以下函数来处理 InitiateFirmwareUpdate 直接方法调用。 此直接方法使用参数指定要下载的固件映像的位置,并异步启动设备上的固件更新:
function onInitiateFirmwareUpdate(request, response) { console.log('Simulated firmware update initiated, using: ' + request.payload.FwPackageURI); // Complete the response response.send(200, "Firmware update initiated", 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.' ); } }); // Add logic here to perform the firmware update asynchronously }添加以下代码以创建客户端实例:
var client = Client.fromConnectionString(connectionString, Protocol);将以下代码添加到:
- 打开连接。
- 发送 DeviceInfo 对象。
- 为所需属性设置处理程序。
- 发送已报告的属性。
- 为直接方法设置处理程序。
- 开始发送遥测数据。
client.open(function (err) { if (err) { printErrorFor('open')(err); } else { console.log('Sending device metadata:\n' + JSON.stringify(deviceMetaData)); client.sendEvent(new Message(JSON.stringify(deviceMetaData)), printErrorFor('send metadata')); // 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) { 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 direct methods client.onDeviceMethod('Reboot', onReboot); client.onDeviceMethod('InitiateFirmwareUpdate', onInitiateFirmwareUpdate); } }); // Start sending telemetry var sendInterval = setInterval(function () { temperature += generateRandomIncrement(); externalTemperature += generateRandomIncrement(); humidity += generateRandomIncrement(); var data = JSON.stringify({ 'DeviceID': deviceId, 'Temperature': temperature, 'Humidity': humidity, 'ExternalTemperature': externalTemperature }); console.log('Sending device event data:\n' + data); client.sendEvent(new Message(data), printErrorFor('send event')); }, 5000); client.on('error', function (err) { printErrorFor('client')(err); if (sendInterval) clearInterval(sendInterval); client.close(printErrorFor('client.close')); }); } });保存对 remote_monitoring.js 文件的更改。
在命令提示符处运行以下命令以启动示例应用程序:
node remote_monitoring.js
在仪表板中查看设备遥测
借助远程监视解决方案中的仪表板,可以查看设备发送到 IoT 中心的遥测数据。
在浏览器中,返回到远程监视解决方案仪表板,单击左侧面板中 的设备 以导航到 “设备”列表。
在 “设备”列表中,应会看到设备的状态为 “正在运行”。 否则,请在“设备详细信息”面板中单击“启用设备”。
单击 “仪表板 ”返回到仪表板,在 “设备查看 ”下拉列表中选择设备以查看其遥测数据。 示例应用程序中的遥测数据是内部温度的 50 个单位,外部温度为 55 个单位,湿度为 50 个单位。
在设备上调用方法
通过远程监视解决方案中的仪表板,可以通过 IoT 中心调用设备上的方法。 例如,在远程监视解决方案中,可以调用一种方法来模拟重启设备。
在远程监视解决方案仪表板中,单击左侧面板中 的“设备 ”以导航到 “设备”列表。
在“设备”列表中单击设备的设备 ID。
在 “设备详细信息 ”面板中,单击“ 方法”。
在 “方法 ”下拉列表中,选择 “InitiateFirmwareUpdate”,然后在 FWPACKAGEURI 中输入虚拟 URL。 单击 “调用方法 ”以调用设备上的方法。
当运行设备代码时,当设备处理该方法时,您将在控制台中看到一条消息。 方法的结果将添加到解决方案门户中的历史记录中:
后续步骤
自定义预配置解决方案的文章介绍了扩展此示例的一些方法。 可能的扩展包括使用实际传感器和实现其他命令。
可以了解有关 azureiotsuite.com 站点上权限的详细信息。