了解并在 IoT 中心内使用设备孪生Understand and use device twins in IoT Hub

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

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.

本文介绍:This article describes:

  • 设备孪生的结构:标记、所需的属性和报告的属性。The structure of the device twin: tags, desired and reported properties.
  • 设备应用和后端可在设备孪生上执行的操作。The operations that device apps and back ends can perform on device twins.

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

  • 将设备特定的元数据存储在云中。Store device-specific metadata in the cloud. 例如,存储在自动售货机的部署位置。For example, the deployment location of a vending machine.
  • 通过设备应用报告当前状态信息,例如可用功能和条件。Report current state information such as available capabilities and conditions from your device app. 例如,通过移动电话网络或 WiFi 连接到 IoT 中心的设备。For example, a device is connected to your IoT hub over cellular or WiFi.
  • 同步设备应用与后端应用之间的长时间运行工作流的状态。Synchronize the state of long-running workflows between device app and back-end app. 例如,当解决方案后端指定要安装的新固件版本以及设备应用报告更新过程的各个阶段时。For example, when the solution back end specifies the new firmware version to install, and the device app reports the various stages of the update process.
  • 查询设备的元数据、配置或状态。Query your device metadata, configuration, or state.

有关使用报告的属性、设备到云的消息或文件上传的指导,请参阅设备到云的通信指南Refer to Device-to-cloud communication guidance for guidance on using reported properties, device-to-cloud messages, or file upload. 有关使用所需的属性、直接方法或云到设备的消息的指导,请参阅云到设备的通信指南Refer to Cloud-to-device communication guidance for guidance on using desired properties, direct methods, or cloud-to-device messages.

设备孪生Device twins

设备孪生存储具有以下用途的设备相关信息:Device twins store device-related information that:

  • 设备和后端可以使用这些信息来同步设备状态和配置。Device and back ends can use to synchronize device conditions and configuration.
  • 解决方案后端可以使用这些信息来查询和定位长时间运行的操作。The solution back end can use to query and target long-running operations.

设备孪生的生命周期链接到相应的 设备标识The lifecycle of a device twin is linked to the corresponding device identity. 在 IoT 中心创建或删除设备标识时,将隐式创建和删除设备孪生。Device twins are implicitly created and deleted when a device identity is created or deleted in IoT Hub.

设备孪生是一个 JSON 文档,其中包含:A device twin is a JSON document that includes:

  • 标记Tags. 解决方案后端可从中读取和写入数据的 JSON 文档的某个部分。A section of the JSON document that the solution back end can read from and write to. 标记对设备应用不可见。Tags are not visible to device apps.
  • 所需的属性Desired properties. 与报告的属性结合使用,同步设备配置或状态。Used along with reported properties to synchronize device configuration or conditions. 解决方案后端可设置所需的属性,并且设备应用可进行读取。The solution back end can set desired properties, and the device app can read them. 此外,当所需的属性发生更改时,设备应用可收到通知。The device app can also receive notifications of changes in the desired properties.
  • 报告的属性Reported properties. 与所需的属性结合使用,同步设备配置或状态。Used along with desired properties to synchronize device configuration or conditions. 设备应用可设置报告的属性,并且解决方案后端可进行读取和查询。The device app can set reported properties, and the solution back end can read and query them.
  • 设备标识属性Device identity properties. 设备孪生 JSON 文档的根包含标识注册表中存储的相应设备标识的只读属性。The root of the device twin JSON document contains the read-only properties from the corresponding device identity stored in the identity registry.

设备孪生属性的屏幕截图

以下示例显示了一个设备孪生 JSON 文档:The following example shows a device twin JSON document:

{
    "deviceId": "devA",
    "etag": "AAAAAAAAAAc=", 
    "status": "enabled",
    "statusReason": "provisioned",
    "statusUpdateTime": "0001-01-01T00:00:00",
    "connectionState": "connected",
    "lastActivityTime": "2015-02-30T16:24:48.789Z",
    "cloudToDeviceMessageCount": 0, 
    "authenticationType": "sas",
    "x509Thumbprint": {     
        "primaryThumbprint": null, 
        "secondaryThumbprint": null 
    }, 
    "version": 2, 
    "tags": {
        "$etag": "123",
        "deploymentLocation": {
            "building": "43",
            "floor": "1"
        }
    },
    "properties": {
        "desired": {
            "telemetryConfig": {
                "sendFrequency": "5m"
            },
            "$metadata" : {...},
            "$version": 1
        },
        "reported": {
            "telemetryConfig": {
                "sendFrequency": "5m",
                "status": "success"
            },
            "batteryLevel": 55,
            "$metadata" : {...},
            "$version": 4
        }
    }
}

根对象中包含设备标识属性,以及 tagsreporteddesired 属性的容器对象。In the root object are the device identity properties, and container objects for tags and both reported and desired properties. properties 容器包含一些只读元素($metadata$etag$version),设备孪生元数据乐观并发部分描述了这些元素。The properties container contains some read-only elements ($metadata, $etag, and $version) described in the Device twin metadata and Optimistic concurrency sections.

报告属性示例Reported property example

在上面的示例中,设备孪生包含设备应用报告的 batteryLevel 属性。In the previous example, the device twin contains a batteryLevel property that is reported by the device app. 使用此属性可以根据上次报告的电池电量水平查询和操作设备。This property makes it possible to query and operate on devices based on the last reported battery level. 其他示例包括让设备应用报告设备功能或连接选项。Other examples include the device app reporting device capabilities or connectivity options.

Note

报告的属性如何简化解决方案后端获取属性最后一个已知值的方案。Reported properties simplify scenarios where the solution back end is interested in the last known value of a property. 如果解决方案后端需要以带时间戳的事件序列(例如时间序列)的形式处理设备遥测数据,可以使用设备到云的消息Use device-to-cloud messages if the solution back end needs to process device telemetry in the form of sequences of timestamped events, such as time series.

所需属性示例Desired property example

在上面的示例中,解决方案后端和设备应用使用 telemetryConfig 设备孪生的所需和报告属性来同步此设备的遥测配置。In the previous example, the telemetryConfig device twin desired and reported properties are used by the solution back end and the device app to synchronize the telemetry configuration for this device. 例如:For example:

  1. 解决方案后端使用所需配置值设置所需属性。The solution back end sets the desired property with the desired configuration value. 下面是包含所需属性集的文档的一部分:Here is the portion of the document with the desired property set:

    ...
    "desired": {
        "telemetryConfig": {
            "sendFrequency": "5m"
        },
        ...
    },
    ...
    
  2. 连接后或者首次重新连接时,设备应用会立即收到更改通知。The device app is notified of the change immediately if connected, or at the first reconnect. 然后,设备应用报告更新的配置(或使用 status 属性报告错误状态)。The device app then reports the updated configuration (or an error condition using the status property). 下面是报告属性的一部分:Here is the portion of the reported properties:

    ...
    "reported": {
        "telemetryConfig": {
            "sendFrequency": "5m",
            "status": "success"
        }
        ...
    }
    ...
    
  3. 解决方案后端可以通过查询设备孪生,跟踪多个设备上的配置操作结果。The solution back end can track the results of the configuration operation across many devices, by querying device twins.

Note

为便于阅读,上述代码片段示例经过优化,演示了为设备配置及其状态进行编码的一种方式。The preceding snippets are examples, optimized for readability, of one way to encode a device configuration and its status. IoT 中心不会对设备孪生中的所需属性和报告属性施加特定的架构。IoT Hub does not impose a specific schema for the device twin desired and reported properties in the device twins.

可以使用孪生来同步长时间运行的操作,例如固件更新。You can use twins to synchronize long-running operations such as firmware updates. 有关如何使用属性来同步和跟踪各设备中长时间运行的操作的详细信息,请参阅使用所需的属性来配置设备For more information on how to use properties to synchronize and track a long running operation across devices, see Use desired properties to configure devices.

后端操作Back-end operations

解决方案后端使用以下通过 HTTPS 公开的原子操作对设备孪生执行操作:The solution back end operates on the device twin using the following atomic operations, exposed through HTTPS:

  • 按 ID 检索设备孪生。此操作返回设备孪生文档,包括标记、所需的系统属性和报告的系统属性。Retrieve device twin by id. This operation returns the device twin document, including tags and desired and reported system properties.

  • 部分更新设备孪生Partially update device twin. 解决方案后端可以使用此操作部分更新设备孪生中的标记或所需属性。This operation enables the solution back end to partially update the tags or desired properties in a device twin. 部分更新以 JSON 文档的形式表示,可添加或更新任何属性。The partial update is expressed as a JSON document that adds or updates any property. 将删除设置为 null 的属性。Properties set to null are removed. 以下示例创建值为 {"newProperty": "newValue"} 的新所需属性,将现有值 existingProperty 覆盖为 "otherNewValue",并删除 otherOldPropertyThe following example creates a new desired property with value {"newProperty": "newValue"}, overwrites the existing value of existingProperty with "otherNewValue", and removes otherOldProperty. 不会对现有的所需属性或标记进行其他任何更改:No other changes are made to existing desired properties or tags:

    {
        "properties": {
            "desired": {
                "newProperty": {
                    "nestedProperty": "newValue"
                },
                "existingProperty": "otherNewValue",
                "otherOldProperty": null
            }
        }
    }
    
  • 替换所需属性Replace desired properties. 解决方案后端可以使用此操作完全覆盖所有现有的所需属性,并使用新 JSON 文档替代 properties/desiredThis operation enables the solution back end to completely overwrite all existing desired properties and substitute a new JSON document for properties/desired.

  • 替换标记Replace tags. 解决方案后端可以使用此操作完全覆盖所有现有标记,并使用新 JSON 文档替代 tagsThis operation enables the solution back end to completely overwrite all existing tags and substitute a new JSON document for tags.

  • 接收孪生通知Receive twin notifications. 此操作允许解决方案后端在修改孪生时收到通知。This operation allows the solution back end to be notified when the twin is modified. 为此,IoT 解决方案需要创建一个路由,并且将“数据源”设置为等于 twinChangeEventsTo do so, your IoT solution needs to create a route and to set the Data Source equal to twinChangeEvents. 默认情况下没有此类路由预先存在,因此不会发送孪生通知。By default, no such routes pre-exist, so no twin notifications are sent. 如果更改速率太高,或由于其他原因(例如内部故障),IoT 中心可能会只发送一个包含所有更改的通知。If the rate of change is too high, or for other reasons such as internal failures, the IoT Hub might send only one notification that contains all changes. 因此,如果应用程序需要可靠地审核和记录所有中间状态,则应使用设备到云消息。Therefore, if your application needs reliable auditing and logging of all intermediate states, you should use device-to-cloud messages. 孪生通知消息包括属性和正文。The twin notification message includes properties and body.

    • 属性Properties

      NameName Value
      $content-type$content-type application/jsonapplication/json
      $iothub-enqueuedtime$iothub-enqueuedtime 发送通知的时间Time when the notification was sent
      $iothub-message-source$iothub-message-source twinChangeEventstwinChangeEvents
      $content-encoding$content-encoding utf-8utf-8
      deviceIddeviceId 设备 IDId of the device
      hubNamehubName IoT 中心的名称Name of IoT Hub
      operationTimestampoperationTimestamp ISO8601 操作时间戳ISO8601 timestamp of operation
      iothub-message-schemaiothub-message-schema deviceLifecycleNotificationdeviceLifecycleNotification
      opTypeopType “replaceTwin”或“updateTwin”"replaceTwin" or "updateTwin"

      消息系统属性以 $ 符号作为前缀。Message system properties are prefixed with the $ symbol.

    • 正文Body

      本部分包括 JSON 格式的所有孪生更改。This section includes all the twin changes in a JSON format. 它使用与修补程序相同的格式,不同的是它可以包含所有孪生节:标记、properties.reported、properties.desired,并且它包含“$metadata”元素。It uses the same format as a patch, with the difference that it can contain all twin sections: tags, properties.reported, properties.desired, and that it contains the “$metadata” elements. 例如,For example,

      {
        "properties": {
            "desired": {
                "$metadata": {
                    "$lastUpdated": "2016-02-30T16:24:48.789Z"
                },
                "$version": 1
            },
            "reported": {
                "$metadata": {
                    "$lastUpdated": "2016-02-30T16:24:48.789Z"
                },
                "$version": 1
            }
        }
      }
      

上述所有操作均支持乐观并发,并需要安全性一文中定义的 ServiceConnect 权限。All the preceding operations support Optimistic concurrency and require the ServiceConnect permission, as defined in the Security article.

除了上述操作以外,解决方案后端还可以:In addition to these operations, the solution back end can:

设备操作Device operations

设备应用使用以下原子操作对设备孪生执行操作:The device app operates on the device twin using the following atomic operations:

  • 检索设备孪生Retrieve device twin. 此操作返回当前连接的设备的设备孪生文档(包括所需的系统属性和报告的系统属性)。This operation returns the device twin document (including desired and reported system properties) for the currently connected device. (标记对设备应用不可见。)(Tags are not visible to device apps.)

  • 部分更新报告属性Partially update reported properties. 使用此操作可以部分更新当前连接的设备的报告属性。This operation enables the partial update of the reported properties of the currently connected device. 此操作使用的 JSON 更新格式与解决方案后端用于部分更新所需属性的格式相同。This operation uses the same JSON update format that the solution back end uses for a partial update of desired properties.

  • 观察所需属性Observe desired properties. 当前连接的设备可以选择在所需属性发生更新时接收通知。The currently connected device can choose to be notified of updates to the desired properties when they happen. 设备收到的更新格式与解决方案后端执行的更新格式相同(部分或完全替换)。The device receives the same form of update (partial or full replacement) executed by the solution back end.

上述所有操作都需要控制对 IoT 中心的访问中定义的 DeviceConnect 权限。All the preceding operations require the DeviceConnect permission, as defined in Control Access to IoT Hub.

借助 Azure IoT 设备 SDK,可通过多种语言和平台轻松使用上述操作。The Azure IoT device SDKs make it easy to use the preceding operations from many languages and platforms. 有关用于同步所需属性的 IoT 中心基元的详细信息,请参阅设备重新连接流For more information on the details of IoT Hub primitives for desired properties synchronization, see Device reconnection flow.

标记和属性格式Tags and properties format

标记、所需的属性和报告的属性是具有以下限制的 JSON 对象:Tags, desired properties, and reported properties are JSON objects with the following restrictions:

  • JSON 对象中的所有键是区分大小写的 64 字节 UTF-8 UNICODE 字符串。All keys in JSON objects are case-sensitive 64 bytes UTF-8 UNICODE strings. 允许的字符不包括 UNICODE 控制字符(段 C0 和 C1)以及 .$ 和 SP。Allowed characters exclude UNICODE control characters (segments C0 and C1), and ., $, and SP.

  • JSON 对象中的所有值可采用以下 JSON 类型:布尔值、数字、字符串、对象。All values in JSON objects can be of the following JSON types: boolean, number, string, object. 不允许数组。Arrays are not allowed. 最大整数值为 4503599627370495,而最小整数值为 -4503599627370496。The maximum value for integers is 4503599627370495 and the minimum value for integers is -4503599627370496.

  • 标记、所需属性和报告属性中的所有 JSON 对象的最大嵌套深度为 5 层。All JSON objects in tags, desired, and reported properties can have a maximum depth of 5. 例如,以下对象是有效的:For instance, the following object is valid:

    {
        ...
        "tags": {
            "one": {
                "two": {
                    "three": {
                        "four": {
                            "five": {
                                "property": "value"
                            }
                        }
                    }
                }
            }
        },
        ...
    }
    
  • 所有字符串的值的长度最多为 512 个字节。All string values can be at most 512 bytes in length.

设备孪生的大小Device twin size

IoT 中心对 tagsproperties/desiredproperties/reported(不包括只读元素)的各个总值强制实施 8KB 大小限制。IoT Hub enforces an 8KB size limitation on each of the respective total values of tags, properties/desired, and properties/reported, excluding read-only elements. 该大小的计算考虑到了所有字符,但不包括 UNICODE 控制字符(段 C0 和 C1),以及出现在字符串常量外部的空格。The size is computed by counting all characters, excluding UNICODE control characters (segments C0 and C1) and spaces that are outside of string constants. IoT 中心拒绝将这些文档的大小增加到超出限制的所有操作,在这种情况下还会返回错误。IoT Hub rejects with an error all operations that would increase the size of those documents above the limit.

设备孪生的元数据Device twin metadata

IoT 中心保留设备孪生所需属性和报告属性中每个 JSON 对象的上次更新时间戳。IoT Hub maintains the timestamp of the last update for each JSON object in device twin desired and reported properties. 时间戳采用 UTC,以 ISO8601 格式编码YYYY-MM-DDTHH:MM:SS.mmmZThe timestamps are in UTC and encoded in the ISO8601 format YYYY-MM-DDTHH:MM:SS.mmmZ.

例如:For example:

{
    ...
    "properties": {
        "desired": {
            "telemetryConfig": {
                "sendFrequency": "5m"
            },
            "$metadata": {
                "telemetryConfig": {
                    "sendFrequency": {
                        "$lastUpdated": "2016-03-30T16:24:48.789Z"
                    },
                    "$lastUpdated": "2016-03-30T16:24:48.789Z"
                },
                "$lastUpdated": "2016-03-30T16:24:48.789Z"
            },
            "$version": 23
        },
        "reported": {
            "telemetryConfig": {
                "sendFrequency": "5m",
                "status": "success"
            },
            "batteryLevel": "55%",
            "$metadata": {
                "telemetryConfig": {
                    "sendFrequency": "5m",
                    "status": {
                        "$lastUpdated": "2016-03-31T16:35:48.789Z"
                    },
                    "$lastUpdated": "2016-03-31T16:35:48.789Z"
                },
                "batteryLevel": {
                    "$lastUpdated": "2016-04-01T16:35:48.789Z"
                },
                "$lastUpdated": "2016-04-01T16:24:48.789Z"
            },
            "$version": 123
        }
    }
    ...
}

会在每个级别(而不仅仅是 JSON 结构的叶级别)保留此信息,以便保留删除了对象键的更新。This information is kept at every level (not just the leaves of the JSON structure) to preserve updates that remove object keys.

乐观并发Optimistic concurrency

标记、所需的属性和报告的属性都支持乐观并发。Tags, desired, and reported properties all support optimistic concurrency. 标记包含一个符合 RFC7232 规范的 ETag,它是标记的 JSON 表示形式。Tags have an ETag, as per RFC7232, that represents the tag's JSON representation. 可在解决方案后端上的条件更新操作中使用 ETag 来确保一致性。You can use ETags in conditional update operations from the solution back end to ensure consistency.

设备孪生所需的属性和报告的属性不包含 ETag,但包含一个保证可递增的 $version 值。Device twin desired and reported properties do not have ETags, but have a $version value that is guaranteed to be incremental. 更新方可以使用类似于 ETag 的版本来强制实施更新一致性。Similarly to an ETag, the version can be used by the updating party to enforce consistency of updates. 例如,报告的属性的设备应用,或者所需的属性的解决方案后端。For example, a device app for a reported property or the solution back end for a desired property.

当监视代理(例如,监视所需属性的设备应用)必须协调检索操作结果与更新通知之间的资源争用时,版本也很有用。Versions are also useful when an observing agent (such as the device app observing the desired properties) must reconcile races between the result of a retrieve operation and an update notification. 设备重新连接流部分提供了详细信息。The Device reconnection flow section provides more information.

设备重新连接流Device reconnection flow

IoT 中心不会保留已断开连接设备的所需属性更新通知。IoT Hub does not preserve desired properties update notifications for disconnected devices. 它遵循的原则是:连接的设备必须检索整个所需属性文档,此外还要订阅更新通知。It follows that a device that is connecting must retrieve the full desired properties document, in addition to subscribing for update notifications. 如果更新通知与完全检索之间存在资源争用的可能性,则必须确保遵循以下流:Given the possibility of races between update notifications and full retrieval, the following flow must be ensured:

  1. 设备应用连接到 IoT 中心。Device app connects to an IoT hub.
  2. 设备应用订阅所需属性更新通知。Device app subscribes for desired properties update notifications.
  3. 设备应用检索所需属性的完整文档。Device app retrieves the full document for desired properties.

设备应用可以忽略 $version 小于或等于完全检索文档的版本的所有通知。The device app can ignore all notifications with $version less or equal than the version of the full retrieved document. 之所以能够使用此方法,是因为 IoT 中心保证版本始终是递增的。This approach is possible because IoT Hub guarantees that versions always increment.

Note

此逻辑已在 Azure IoT 设备 SDK 中实现。This logic is already implemented in the Azure IoT device SDKs. 仅当设备应用无法使用任何 Azure IoT 设备 SDK,必须直接为 MQTT 接口编程时,这段说明才有作用。This description is useful only if the device app cannot use any of Azure IoT device SDKs and must program the MQTT interface directly.

其他参考资料Additional reference material

IoT 中心开发人员指南中的其他参考主题包括:Other reference topics in the IoT Hub developer guide include:

后续步骤Next steps

了解设备孪生后,可以根据兴趣参阅以下 IoT 中心开发人员指南主题:Now you have learned about device twins, you may be interested in the following IoT Hub developer guide topics:

要尝试本文中介绍的一些概念,请参阅以下 IoT 中心教程:To try out some of the concepts described in this article, see the following IoT Hub tutorials: