设备孪生入门 (Node)Get started with device twins (Node)

设备孪生是存储设备状态信息(元数据、配置和条件)的 JSON 文档。Device twins are JSON documents that store device state information (metadata, configurations, and conditions). IoT 中心为连接到它的每台设备保留一个设备孪生。IoT Hub persists a device twin for each device that connects to it.

Note

本文中所述的功能仅可在 IoT 中心的标准层中使用。The features described in this article are only available in the standard tier of IoT hub. 有关基本和标准 IoT 中心层的详细信息,请参阅如何选择合适的 IoT 中心层For more information about the basic and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

使用设备孪生可以:Use device twins to:

  • 存储来自解决方案后端的设备元数据。Store device metadata from your solution back end.
  • 通过设备应用报告当前状态信息,例如可用功能和条件(例如,使用的连接方法)。Report current state information such as available capabilities and conditions (for example, the connectivity method used) from your device app.
  • 同步设备应用和后端应用之间的长时间运行的工作流的状态(例如固件和配置更新)。Synchronize the state of long-running workflows (such as firmware and configuration updates) between a device app and a back-end app.
  • 查询设备的元数据、配置或状态。Query your device metadata, configuration, or state.

设备孪生旨在执行同步以及查询设备的配置和条件。Device twins are designed for synchronization and for querying device configurations and conditions. 了解设备孪生中提供了有关何时使用设备孪生的详细信息。More information on when to use device twins can be found in Understand device twins.

设备孪生存储在 IoT 中心内,其中包含:Device twins are stored in an IoT hub and contain:

  • 标记,仅可由解决方案后端访问的设备元数据;tags, device metadata accessible only by the solution back end;
  • 所需属性,可以由解决方案后端修改以及由设备应用观察的 JSON 对象;以及desired properties, JSON objects modifiable by the solution back end and observable by the device app; and
  • 报告属性,可由设备应用修改以及由解决方案后端读取的 JSON 对象。reported properties, JSON objects modifiable by the device app and readable by the solution back end. 标记和属性不能包含数组,但可以嵌套对象。Tags and properties cannot contain arrays, but objects can be nested.

显示功能的设备孪生图像

此外,解决方案后端可以根据上述所有数据查询设备孪生。Additionally, the solution back end can query device twins based on all the above data. 有关设备孪生的详细信息,请参阅了解设备孪生,有关查询的信息,请参阅 IoT 中心查询语言参考。Refer to Understand device twins for more information about device twins, and to the IoT Hub query language reference for querying.

本教程演示如何:This tutorial shows you how to:

  • 创建将标记添加到设备孪生的后端应用,以及将其连接通道作为设备孪生上的报告属性进行报告的模拟设备应用。Create a back-end app that adds tags to a device twin, and a simulated device app that reports its connectivity channel as a reported property on the device twin.
  • 使用标记上的筛选器和之前创建的属性通过后端应用查询设备。Query devices from your back-end app using filters on the tags and properties previously created.

在本教程结束时,你将拥有两个 Node.js 控制台应用:At the end of this tutorial, you will have two Node.js console apps:

  • AddTagsAndQuery.js(Node.js 后端应用),用于添加标记和查询设备孪生。AddTagsAndQuery.js, a Node.js back-end app, which adds tags and queries device twins.
  • TwinSimulatedDevice.js(Node.js 应用),用于模拟使用早先创建的设备标识连接到 IoT 中心的设备,并报告其连接状况。TwinSimulatedDevice.js, a Node.js app, which simulates a device that connects to your IoT hub with the device identity created earlier, and reports its connectivity condition.

Note

Azure IoT SDK 文章介绍了可用于构建设备和后端应用的 Azure IoT SDK。The article Azure IoT SDKs provides information about the Azure IoT SDKs that you can use to build both device and back-end apps.

若要完成本教程,需要满足以下条件:To complete this tutorial you need the following:

  • Node.js 版本 10.0.x 或更高版本。Node.js version 10.0.x or later.

  • 有效的 Azure 帐户。An active Azure account. 如果没有帐户,可以创建一个试用帐户,只需几分钟即可完成。(If you don't have an account, you can create a trial account in just a couple of minutes.)

创建 IoT 中心Create an IoT hub

此部分介绍如何使用 Azure 门户创建 IoT 中心。This section describes how to create an IoT hub using the Azure portal.

  1. 登录到 Azure 门户Log in to the Azure portal.

  2. 选择“+创建资源”,然后搜索市场,寻找 IoT 中心Choose +Create a resource, then Search the Marketplace for the IoT Hub.

  3. 选择“IoT 中心”,然后单击“创建”按钮 。Select IoT Hub and click the Create button. 随即显示 IoT 中心创建过程的第一个屏幕。You see the first screen for creating an IoT hub.

    在 Azure 门户中创建中心

    填充字段。Fill in the fields.

    订阅:请选择要用于 IoT 中心的订阅。Subscription: Select the subscription to use for your IoT hub.

    资源组:可创建新的资源组或使用现有资源组。Resource Group: You can create a new resource group or use an existing one. 若要新建一个,请单击“新建” ,并填写要使用的名称。To create a new one, click Create new and fill in the name you want to use. 若要使用现有资源组,请单击“使用现有资源组” 并从下拉列表中选择该组。To use an existing resource group, click Use existing and select the resource group from the dropdown list. 有关详细信息,请参阅管理 Azure 资源管理器资源组For more information, see Manage Azure Resource Manager resource groups.

    区域:这是要在其中设置中心的区域。Region: This is the region in which you want your hub to be located. 从下拉列表中选择最靠近自己的位置。Select the location closest to you from the dropdown list.

    IoT 中心名称:输入 IoT 中心的名称。IoT Hub Name: Put in the name for your IoT Hub. 此名称必须全局唯一。This name must be globally unique. 如果输入的名称可用,会显示一个绿色复选标记。If the name you enter is available, a green check mark appears.

    Important

    IoT 中心将公开为 DNS 终结点,因此,命名时请务必避免包含任何敏感信息。The IoT hub will be publicly discoverable as a DNS endpoint, so make sure to avoid any sensitive information while naming it.

  4. 单击“下一步: 大小和规模”,以便继续创建 IoT 中心。Click Next: Size and scale to continue creating your IoT hub.

    使用 Azure 门户为新的 IoT 中心设置大小和缩放级别

    在此屏幕上,可以采用默认值,只需在底部单击“查看+创建”即可 。On this screen, you can take the defaults and just click Review + create at the bottom.

    定价和缩放层:可以根据你需要的功能数以及每天通过解决方案发送的消息数从多个层中进行选择。Pricing and scale tier: You can choose from several tiers depending on how many features you want and how many messages you send through your solution per day. 免费层适用于测试和评估。The free tier is intended for testing and evaluation. 它允许 500 台设备连接到 IoT 中心,并且每天最多传输 8,000 条信息。It allows 500 devices to be connected to the IoT hub and up to 8,000 messages per day. 每个 Azure 订阅可以在免费层中创建一个 IoT 中心。Each Azure subscription can create one IoT Hub in the free tier.

    IoT 中心单元:每个单位每日允许的消息数取决于中心的定价层。IoT Hub units: The number of messages allowed per unit per day depends on your hub's pricing tier. 例如,如果希望 IoT 中心支持 700,000 条消息输入,则选择两个 S1 层单位。For example, if you want the IoT hub to support ingress of 700,000 messages, you choose two S1 tier units.

    有关其他层选项的详细信息,请参阅选择合适的 IoT 中心层For details about the other tier options, see Choosing the right IoT Hub tier.

    高级 / 设备到云分区:此属性将设备到云消息与这些消息的同步读取器数目相关联。Advanced / Device-to-cloud partitions: This property relates the device-to-cloud messages to the number of simultaneous readers of the messages. 大多数 IoT 中心只需要 4 个分区。Most IoT hubs only need four partitions.

  5. 单击“查看+创建” 可查看选择。Click Review + create to review your choices. 会显示类似于以下的屏幕。You see something similar to this screen.

    查看用于创建新 IoT 中心的信息

  6. 单击“创建”以创建新的 IoT 中心 。Click Create to create your new IoT hub. 创建中心需要几分钟时间。Creating the hub takes a few minutes.

检索 IoT 中心的连接字符串Retrieve connection string for IoT hub

创建中心以后,请检索中心的连接字符串。After your hub has been created, retrieve the connection string for the hub. 该字符串用于将设备和应用程序连接到中心。This is used to connect devices and applications to your hub.

  1. 单击中心,查看“IoT 中心”窗格,其中包含“设置”等内容。Click on your hub to see the IoT Hub pane with Settings, and so on. 单击“共享访问策略”。Click Shared access policies.

  2. 在“共享访问策略”中,选择 iothubowner 策略。In Shared access policies, select the iothubowner policy.

  3. 在“共享访问密钥”下,复制“连接字符串 -- 主密钥”供以后使用。Under Shared access keys, copy the Connection string -- primary key to be used later.

    显示如何检索连接字符串

    有关详细信息,请参阅“IoT 中心开发人员指南”中的访问控制For more information, see Access control in the "IoT Hub developer guide."

创建设备标识Create a device identity

在本部分中,将使用 Azure CLI 为本教程创建设备标识。In this section, you use the Azure CLI to create a device identity for this tutorial. Azure CLI 预先安装在 Azure Cloud Shell 中,也可以在本地安装The Azure CLI is preinstalled in the Azure Cloud Shell, or you can install it locally. 设备 ID 区分大小写。Device IDs are case sensitive.

  1. 在使用 Azure CLI 安装 IoT 扩展的命令行环境中运行以下命令:Run the following command in the command-line environment where you are using the Azure CLI to install the IoT extension:

    az extension add --name azure-cli-iot-ext
    
  2. 如果要在本地运行 Azure CLI,请使用以下命令登录 Azure 帐户(如果使用的是 Cloud Shell,则表示你已自动登录,并且无需运行此命令):If you are running the Azure CLI locally, use the following command to sign in to your Azure account (if you are using the Cloud Shell, you are signed in automatically and you don't need to run this command):

    az login
    
  3. 最后,使用以下命令创建一个名为 myDeviceId 的新设备标识并检索设备连接字符串:Finally, create a new device identity called myDeviceId and retrieve the device connection string with these commands:

    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 用于客户支持和故障排除,因此,在为日志命名时,请务必避免包含任何敏感信息。The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid any sensitive information while naming it.

记下结果中的设备连接字符串。Make a note of the device connection string from the result. 设备应用使用此设备连接字符串以设备身份连接到 IoT 中心。This device connection string is used by the device app to connect to your IoT Hub as a device.

创建服务应用Create the service app

在此部分,会创建一个 Node.js 控制台应用,将位置元数据添加到与 myDeviceId关联的设备孪生。In this section, you create a Node.js console app that adds location metadata to the device twin associated with myDeviceId. 然后,该应用将选择位于美国的设备来查询存储在 IoT 中心的设备孪生,然后查询报告移动电话网络连接的设备孪生。It then queries the device twins stored in the IoT hub selecting the devices located in the US, and then the ones that are reporting a cellular connection.

  1. 新建名为 addtagsandqueryapp的空文件夹。Create a new empty folder called addtagsandqueryapp. 在命令提示符下的addtagsandqueryapp 文件夹中,使用以下命令创建新的 package.json 文件。In the addtagsandqueryapp folder, create a new package.json file using the following command at your command prompt. 接受所有默认值:Accept all the defaults:

    npm init
    
  2. addtagsandqueryapp 文件夹的命令提示符下,运行以下命令以安装 azure-iothub 包:At your command prompt in the addtagsandqueryapp folder, run the following command to install the azure-iothub package:

    npm install azure-iothub --save
    
  3. 使用文本编辑器,在 addtagsandqueryapp 文件夹中创建一个新的 AddTagsAndQuery.js 文件。Using a text editor, create a new AddTagsAndQuery.js file in the addtagsandqueryapp folder.

  4. 将以下代码添加到 AddTagsAndQuery.js 文件,并将 {iot hub connection string} 占位符替换为创建中心时复制的 IoT 中心连接字符串:Add the following code to the AddTagsAndQuery.js file, and substitute the {iot hub connection string} placeholder with the IoT Hub connection string you copied when you created your hub:

         '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 对象公开从服务与设备孪生进行交互所需的所有方法。The Registry object exposes all the methods required to interact with device twins from the service. 前面的代码首先初始化 Registry 对象,然后检索 myDeviceId 的设备孪生,最后使用所需位置信息更新其标记。The previous code first initializes the Registry object, then retrieves the device twin for myDeviceId, and finally updates its tags with the desired location information.

    更新标记后,它将调用 queryTwins 函数 。After updating the tags it calls the queryTwins function.

  5. AddTagsAndQuery.js 末尾添加以下代码以实现 queryTwins 函数:Add the following code at the end of AddTagsAndQuery.js to implement the queryTwins function:

         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 工厂中的设备的设备孪生,第二个会优化查询以只选择还通过手机网络连接的设备。The previous code executes two queries: the first selects only the device twins of devices located in the Redmond43 plant, and the second refines the query to select only the devices that are also connected through cellular network.

    上面的代码创建 query 对象时,会指定返回的最大文档数 。The previous code, when it creates the query object, specifies a maximum number of returned documents. query 对象包含 hasMoreResults 布尔值属性,可以使用它多次调用 nextAsTwin 方法来检索所有结果。The query object contains a hasMoreResults boolean property that you can use to invoke the nextAsTwin methods multiple times to retrieve all results. 名为 next 的方法可用于非设备孪生的结果(例如聚合查询的结果) 。A method called next is available for results that are not device twins, for example, results of aggregation queries.

  6. 使用以下内容运行应用程序:Run the application with:

     node AddTagsAndQuery.js
    

    在查询位于 Redmond43 的所有设备的查询结果中,应该会看到一个设备,而在将结果限制为使用蜂窝网络的设备的查询结果中没有任何设备。You should see one device in the results for the query asking for all devices located in Redmond43 and none for the query that restricts the results to devices that use a cellular network.

在下一部分中,创建的设备应用会报告连接信息,并更改上一部分中查询的结果。In the next section, you create a device app that reports the connectivity information and changes the result of the query in the previous section.

创建设备应用Create the device app

在此部分,会创建一个 Node.js 控制台应用作为 myDeviceId连接到中心,并更新其设备孪生的报告属性,说明它是使用手机网络进行连接的。In this section, you create a Node.js console app that connects to your hub as myDeviceId, and then updates its device twin's reported properties to contain the information that it is connected using a cellular network.

  1. 新建名为 reportconnectivity的空文件夹。Create a new empty folder called reportconnectivity. reportconnectivity 文件夹的命令提示符处,使用以下命令创建新的 package.json 文件。In the reportconnectivity folder, create a new package.json file using the following command at your command prompt. 接受所有默认值:Accept all the defaults:

    npm init
    
  2. reportconnectivity 文件夹中,在命令提示符下运行以下命令以安装 azure-iot-device 包和 azure-iot-device-mqtt 包:At your command prompt in the reportconnectivity folder, run the following command to install the azure-iot-device, and azure-iot-device-mqtt package:

    npm install azure-iot-device azure-iot-device-mqtt --save
    
  3. 使用文本编辑器,在 reportconnectivity 文件夹中创建一个新的 ReportConnectivity.js 文件。Using a text editor, create a new ReportConnectivity.js file in the reportconnectivity folder.

  4. 将以下代码添加到 ReportConnectivity.js 文件,并将 {device connection string} 占位符替换为创建 myDeviceId 设备标识时复制的设备连接字符串:Add the following code to the ReportConnectivity.js file, and substitute the {device connection string} placeholder with the device connection string you copied when you created the myDeviceId device identity:

     '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 对象公开从该设备与设备孪生交互所需的所有方法。The Client object exposes all the methods you require to interact with device twins from the device. 上面的代码在初始化 Client 对象后会检索 myDeviceId 的设备孪生,并使用连接信息更新其报告属性。The previous code, after it initializes the Client object, retrieves the device twin for myDeviceId and updates its reported property with the connectivity information.

  5. 运行设备应用Run the device app

     node ReportConnectivity.js
    

    此时会显示消息 twin state reportedYou should see the message twin state reported.

  6. 现在设备报告了其连接信息,应出现在两个查询中。Now that the device reported its connectivity information, it should appear in both queries. 返回到 addtagsandqueryapp 文件夹,再次运行查询:Go back in the addtagsandqueryapp folder and run the queries again:

     node AddTagsAndQuery.js
    

    这次 myDeviceId 应出现在两个查询结果中。This time myDeviceId should appear in both query results.

后续步骤Next steps

本教程中,在 Azure 门户中配置了新的 IoT 中心,并在 IoT 中心的标识注册表中创建了设备标识。In this tutorial, you configured a new IoT hub in the Azure portal, and then created a device identity in the IoT hub's identity registry. 已从后端应用以标记形式添加了设备元数据,并编写了模拟的设备应用,用于报告设备孪生中的设备连接信息。You added device metadata as tags from a back-end app, and wrote a simulated device app to report device connectivity information in the device twin. 还学习了如何使用类似 SQL 的 IoT 中心查询语言来查询此信息。You also learned how to query this information using the SQL-like IoT Hub query language.

充分利用以下资源:Use the following resources to learn how to: