设备孪生入门 (Node)

设备孪生是存储设备状态信息(元数据、配置和条件)的 JSON 文档。 IoT 中心为连接到它的每台设备保留一个设备孪生。

Note

本文中所述的功能仅可在 IoT 中心的标准层中使用。 有关基本和标准 IoT 中心层的详细信息,请参阅如何选择合适的 IoT 中心层

使用设备孪生可以:

  • 存储来自解决方案后端的设备元数据。
  • 通过设备应用报告当前状态信息,例如可用功能和条件(例如,使用的连接方法)。
  • 同步设备应用和后端应用之间的长时间运行的工作流的状态(例如固件和配置更新)。
  • 查询设备的元数据、配置或状态。

设备孪生旨在执行同步以及查询设备的配置和条件。 了解设备孪生中提供了有关何时使用设备孪生的详细信息。

设备孪生存储在 IoT 中心内,其中包含:

  • 标记,仅可由解决方案后端访问的设备元数据;
  • 所需属性,可以由解决方案后端修改以及由设备应用观察的 JSON 对象;以及
  • 报告属性,可由设备应用修改以及由解决方案后端读取的 JSON 对象。 标记和属性不能包含数组,但可以嵌套对象。

此外,解决方案后端可以根据上述所有数据查询设备孪生。 有关设备孪生的详细信息,请参阅了解设备孪生,有关查询的参考,请参阅 IoT 中心查询语言

本教程演示如何:

  • 创建将标记添加到设备孪生的后端应用,以及将其连接通道作为设备孪生上的报告属性进行报告的模拟设备应用。
  • 使用标记上的筛选器和之前创建的属性通过后端应用查询设备。

在本教程结束时,你将拥有两个 Node.js 控制台应用:

  • AddTagsAndQuery.js(Node.js 后端应用),用于添加标记和查询设备孪生。
  • TwinSimulatedDevice.js(Node.js 应用),用于模拟使用早先创建的设备标识连接到 IoT 中心的设备,并报告其连接状况。

Note

Azure IoT SDK 文章介绍了可用于构建设备和后端应用的 Azure IoT SDK。

若要完成本教程,需要满足以下条件:

  • Node.js 版本 4.0.x 或更高版本。

  • 有效的 Azure 帐户。 如果没有帐户,可以创建一个试用帐户,只需几分钟即可完成。

创建 IoT 中心

此部分介绍如何使用 Azure 门户创建 IoT 中心。

  1. 登录到 Azure 门户

  2. 选择+“创建资源”,然后选择“物联网”。

  3. 在右侧列表中单击“Iot 中心”。 随即显示 IoT 中心创建过程的第一个屏幕。

    显示了在 Azure 门户中创建中心的屏幕截图

    填充字段。

    订阅:请选择要用于 IoT 中心的订阅。

    资源组:可创建新的资源组或使用现有资源组。 若要新建一个,请单击“新建”,并填写要使用的名称。 若要使用现有资源组,请单击“使用现有资源组”并从下拉列表中选择该组。 有关详细信息,请参阅使用资源组管理 Azure 资源

    区域:这是要在其中设置中心的区域。 从下拉列表中选择最靠近自己的位置。

    IoT 中心名称:输入 IoT 中心的名称。 此名称必须全局唯一。 如果输入的名称可用,会显示一个绿色复选标记。

    Important

    IoT 中心将公开为 DNS 终结点,因此,命名时请务必避免包含任何敏感信息。

  4. 单击“下一步: 大小和规模”,以便继续创建 IoT 中心。

    屏幕截图显示使用 Azure 门户为新的 IoT 中心设置大小和缩放级别

    在此屏幕上,可以采用默认值,只需在底部单击“查看+创建”即可。

    定价和缩放层级:可以根据需要的功能数以及每天通过解决方案发送的消息数从多个层中进行选择。 免费层适用于测试和评估。 它允许 500 台设备连接到 IoT 中心,并且每天最多传输 8,000 条信息。 每个 Azure 订阅可以在免费层中创建一个 IoT 中心。

    IoT 中心单位:每日每单位允许的消息数取决于中心的定价层。 例如,如果希望 IoT 中心支持 700,000 条消息输入,则选择两个 S1 层单位。

    有关其他层选项的详细信息,请参阅选择合适的 IoT 中心层

    高级/设备到云的分区:此属性将设备到云消息与这些消息的同步读取器数目相关联。 大多数 IoT 中心只需要 4 个分区。

  5. 单击“查看+创建”可查看选择。 会显示类似于以下的屏幕。

    屏幕截图显示用于创建新 IoT 中心的信息

  6. 单击“创建”以创建新的 IoT 中心。 创建中心需要几分钟时间。

检索 IoT 中心的连接字符串

创建中心以后,请检索中心的连接字符串。 该字符串用于将设备和应用程序连接到中心。

  1. 单击中心,查看“IoT 中心”窗格,其中包含“设置”等内容。 单击“共享访问策略”。

  2. 在“共享访问策略”中,选择 iothubowner 策略。

  3. 在“共享访问密钥”下,复制“连接字符串 -- 主密钥”供以后使用。

    显示如何检索连接字符串

    有关详细信息,请参阅“IoT 中心开发人员指南”中的访问控制

创建设备标识

在本部分中,将使用 Azure CLI 为本教程创建设备标识。设备 ID 区分大小写。

  1. 在使用 Azure CLI 安装 IoT 扩展的命令行环境中运行以下命令:

    az extension add --name azure-cli-iot-ext
    
  2. 如果要在本地运行 Azure CLI,请使用以下命令登录 Azure 帐户(如果使用的是 Cloud Shell,则表示你已自动登录,并且无需运行此命令):

    az login
    
  3. 最后,使用以下命令创建一个名为 myDeviceId 的新设备标识并检索设备连接字符串:

    az iot hub device-identity create --device-id myDeviceId --hub-name {Your IoT Hub name}
    az iot hub device-identity show-connection-string --device-id myDeviceId --hub-name {Your IoT Hub name} -o table
    

    Important

    收集的日志中可能会显示设备 ID 用于客户支持和故障排除,因此,在为日志命名时,请务必避免包含任何敏感信息。

记下结果中的设备连接字符串。 设备应用使用此设备连接字符串以设备身份连接到 IoT 中心。

创建服务应用

在此部分,会创建一个 Node.js 控制台应用,将位置元数据添加到与 myDeviceId 关联的设备孪生。 然后,该应用将选择位于中国的设备来查询存储在 IoT 中心的设备孪生,然后查询报告移动电话网络连接的设备孪生。

  1. 新建名为 addtagsandqueryapp 的空文件夹。在命令提示符下的 addtagsandqueryapp 文件夹中,使用以下命令创建新的 package.json 文件。接受所有默认值:

    npm init
    
  2. addtagsandqueryapp 文件夹的命令提示符下,运行以下命令以安装 azure-iothub 包:

    npm install azure-iothub --save
    
  3. 使用文本编辑器,在 addtagsandqueryapp 文件夹中创建一个新的 AddTagsAndQuery.js 文件。
  4. 将以下代码添加到 AddTagsAndQuery.js 文件,并将 {iot hub connection string} 占位符替换为创建中心时复制的 IoT 中心连接字符串:

    'use strict';
    var iothub = require('azure-iothub');
    var connectionString = '{iot hub connection string}';
    var registry = iothub.Registry.fromConnectionString(connectionString);
    
    registry.getTwin('myDeviceId', function(err, twin){
        if (err) {
            console.error(err.constructor.name + ': ' + err.message);
        } else {
            var patch = {
                tags: {
                    location: {
                        region: 'CN',
                        plant: 'Redmond43'
                  }
                }
            };
    
            twin.update(patch, function(err) {
              if (err) {
                console.error('Could not update twin: ' + err.constructor.name + ': ' + err.message);
              } else {
                console.log(twin.deviceId + ' twin updated successfully');
                queryTwins();
              }
            });
        }
    });
    

    Registry 对象公开从服务与设备孪生进行交互所需的所有方法。 前面的代码首先初始化 Registry 对象,然后检索 myDeviceId 的设备孪生,最后使用所需位置信息更新其标记。

    更新标记后,它将调用 queryTwins 函数。

  5. AddTagsAndQuery.js 末尾添加以下代码以实现 queryTwins 函数:

    var queryTwins = function() {
        var query = registry.createQuery("SELECT * FROM devices WHERE tags.location.plant = 'Redmond43'", 100);
        query.nextAsTwin(function(err, results) {
            if (err) {
                console.error('Failed to fetch the results: ' + err.message);
            } else {
                console.log("Devices in Redmond43: " + results.map(function(twin) {return twin.deviceId}).join(','));
            }
        });
    
        query = registry.createQuery("SELECT * FROM devices WHERE tags.location.plant = 'Redmond43' AND properties.reported.connectivity.type = 'cellular'", 100);
        query.nextAsTwin(function(err, results) {
            if (err) {
                console.error('Failed to fetch the results: ' + err.message);
            } else {
                console.log("Devices in Redmond43 using cellular network: " + results.map(function(twin) {return twin.deviceId}).join(','));
            }
        });
    };
    

    前面的代码执行两个查询:第一个只选择位于 Redmond43 工厂中的设备的设备孪生,第二个会优化查询以只选择还通过手机网络连接的设备。

    上面的代码创建 query 对象时,会指定返回的最大文档数。 query 对象包含 hasMoreResults 布尔值属性,可以使用它多次调用 nextAsTwin 方法来检索所有结果。 名为 next 的方法可用于非设备孪生的结果(例如聚合查询的结果)。

  6. 使用以下内容运行应用程序:

    node AddTagsAndQuery.js
    

    在查询位于 Redmond43 的所有设备的查询结果中,应该会看到一个设备,而在将结果限制为使用蜂窝网络的设备的查询结果中没有任何设备。

在下一部分中,创建的设备应用会报告连接信息,并更改上一部分中查询的结果。

创建设备应用

在此部分,会创建一个 Node.js 控制台应用作为 myDeviceId连接到中心,并更新其设备孪生的报告属性,说明它是使用手机网络进行连接的。

  1. 新建名为 reportconnectivity 的空文件夹。在 reportconnectivity 文件夹的命令提示符处,使用以下命令创建新的 package.json 文件。接受所有默认值:

    npm init
    
  2. reportconnectivity 文件夹中,在命令提示符下运行以下命令以安装 azure-iot-device 包和 azure-iot-device-mqtt 包:

    npm install azure-iot-device azure-iot-device-mqtt --save
    
  3. 使用文本编辑器,在 reportconnectivity 文件夹中创建一个新的 ReportConnectivity.js 文件。
  4. 将以下代码添加到 ReportConnectivity.js 文件,并将 {device connection string} 占位符替换为创建 myDeviceId 设备标识时复制的设备连接字符串:

    'use strict';
    var Client = require('azure-iot-device').Client;
    var Protocol = require('azure-iot-device-mqtt').Mqtt;
    
    var connectionString = '{device connection string}';
    var client = Client.fromConnectionString(connectionString, Protocol);
    
    client.open(function(err) {
    if (err) {
        console.error('could not open IotHub client');
    }  else {
        console.log('client opened');
    
        client.getTwin(function(err, twin) {
        if (err) {
            console.error('could not get twin');
        } else {
            var patch = {
                connectivity: {
                    type: 'cellular'
                }
            };
    
            twin.properties.reported.update(patch, function(err) {
                if (err) {
                    console.error('could not update twin');
                } else {
                    console.log('twin state reported');
                    process.exit();
                }
            });
        }
        });
    }
    });
    

    Client 对象公开从该设备与设备孪生交互所需的所有方法。 上面的代码在初始化 Client 对象后会检索 myDeviceId 的设备孪生,并使用连接信息更新其报告属性。

  5. 运行设备应用

    node ReportConnectivity.js
    

    此时会显示消息twin state reported

  6. 现在设备报告了其连接信息,应出现在两个查询中。 返回到 addtagsandqueryapp 文件夹,再次运行查询:

    node AddTagsAndQuery.js
    

    这次 myDeviceId 应出现在两个查询结果中。

后续步骤

本教程中,在 Azure 门户中配置了新的 IoT 中心,并在 IoT 中心的标识注册表中创建了设备标识。 已从后端应用以标记形式添加了设备元数据,并编写了模拟的设备应用,用于报告设备孪生中的设备连接信息。 还学习了如何使用类似 SQL 的 IoT 中心查询语言来查询此信息。

充分利用以下资源: