你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
遥测、属性和命令有效负载
- 设备发送到服务的遥测数据。
- 设备与服务同步的属性。
- 服务在设备上调用的命令。
提示
Azure IoT Central 是遵循即插即用约定的服务。 在 IoT Central 中,设备模型是设备模板的一部分。 IoT Central 目前支持含 IoT Central 扩展的 DTDL v2。 IoT Central 应用程序需要接收 UTF-8 编码的 JSON 数据。
本文介绍设备为 DTDL 设备模型中定义的遥测、属性和命令发送和接收的 JSON 有效负载。
本文不介绍遥测、属性和命令有效负载的每个可能类型,但示例说明了关键类型。
每个示例都演示了设备模型中的代码片段,该代码片段定义了类型和示例 JSON 有效负载,以说明设备应如何与即插即用感知服务(如 IoT Central)交互。
本文中的示例 JSON 代码片段使用数字孪生定义语言 (DTDL) v2。 IoT Central 还使用一些 DTDL 扩展。
有关显示其中某些有效负载正在使用的示例设备代码,请参阅将 Linux 或 Windows 上运行的示例 IoT 即插即用设备应用程序连接到 IoT 中心教程或创建客户端应用程序并将其连接到 Azure IoT Central 应用程序教程。
查看原始数据
如果使用 IoT Central,可以查看设备发送到应用程序的原始数据。 此视图可用于排除发送自设备的有效负载的问题。 若要查看设备正在发送的原始数据:
有关更多故障排除提示,请参阅排查设备中的数据未显示在 Azure IoT Central 的原因。
遥测
若要了解有关 DTDL 遥测命名规则的详细信息,请参阅 DTDL > 遥测。 不能使用 _
字符启动遥测名称。
不要使用以下名称创建遥测类型。 IoT Central 在内部使用这些保留名称。 如果尝试使用这些名称,IoT Central 将忽略数据:
EventEnqueuedUtcTime
EventProcessedUtcTime
PartitionId
EventHub
User
$metadata
$version
组件中的遥测
如果在组件中定义遥测,请使用设备模型中定义的组件名称添加名为 $.sub
的自定义消息属性。 若要了解详细信息,请参阅教程:连接 IoT 即插即用多个组件设备应用程序。 本教程演示如何使用不同的编程语言从组件发送遥测数据。
重要
若要正确显示来自 IoT Edge 模块中承载的组件的遥测数据,请使用 IoT Edge 版本 1.2.4 或更高版本。 如果使用早期版本,来自 IoT Edge 模块中组件的遥测数据会显示为“_unmodeleddata”。
继承接口中的遥测
如果遥测是在继承接口中定义的,则设备会发送遥测数据,就好像在根接口中定义一样。 给定以下设备模型:
[
{
"@id": "dtmi:contoso:device;1",
"@type": "Interface",
"contents": [
{
"@type": [
"Property",
"Cloud",
"StringValue"
],
"displayName": {
"en": "Device Name"
},
"name": "DeviceName",
"schema": "string"
}
],
"displayName": {
"en": "Contoso Device"
},
"extends": [
"dtmi:contoso:sensor;1"
],
"@context": [
"dtmi:iotcentral:context;2",
"dtmi:dtdl:context;2"
]
},
{
"@context": [
"dtmi:iotcentral:context;2",
"dtmi:dtdl:context;2"
],
"@id": "dtmi:contoso:sensor;1",
"@type": [
"Interface",
"NamedInterface"
],
"contents": [
{
"@type": [
"Telemetry",
"NumberValue"
],
"displayName": {
"en": "Meter Voltage"
},
"name": "MeterVoltage",
"schema": "double"
}
],
"displayName": {
"en": "Contoso Sensor"
},
"name": "ContosoSensor"
}
]
设备使用以下有效负载发送计量电压遥测数据。 设备不包括有效负载中的接口名称:
{
"MeterVoltage": 5.07
}
基元类型
本部分介绍设备可以流式传输的基元遥测类型示例。
设备模型中的以下代码片段显示 boolean
遥测类型的定义:
{
"@type": "Telemetry",
"displayName": {
"en": "BooleanTelemetry"
},
"name": "BooleanTelemetry",
"schema": "boolean"
}
设备客户端应该以 JSON 形式发送遥测,如下例所示:
{ "BooleanTelemetry": true }
设备模型中的以下代码片段显示 string
遥测类型的定义:
{
"@type": "Telemetry",
"displayName": {
"en": "StringTelemetry"
},
"name": "StringTelemetry",
"schema": "string"
}
设备客户端应该以 JSON 形式发送遥测,如下例所示:
{ "StringTelemetry": "A string value - could be a URL" }
设备模型中的以下代码片段显示 integer
遥测类型的定义:
{
"@type": "Telemetry",
"displayName": {
"en": "IntegerTelemetry"
},
"name": "IntegerTelemetry",
"schema": "integer"
}
设备客户端应该以 JSON 形式发送遥测,如下例所示:
{ "IntegerTelemetry": 23 }
设备模型中的以下代码片段显示 double
遥测类型的定义:
{
"@type": "Telemetry",
"displayName": {
"en": "DoubleTelemetry"
},
"name": "DoubleTelemetry",
"schema": "double"
}
设备客户端应该以 JSON 形式发送遥测,如下例所示:
{ "DoubleTelemetry": 56.78 }
设备模型中的以下代码片段显示 dateTime
遥测类型的定义:
{
"@type": "Telemetry",
"displayName": {
"en": "DateTimeTelemetry"
},
"name": "DateTimeTelemetry",
"schema": "dateTime"
}
设备客户端应该以 JSON 形式发送遥测,如下例所示。DateTime
类型必须是 ISO 8061 格式:
{ "DateTimeTelemetry": "2020-08-30T19:16:13.853Z" }
设备模型中的以下代码片段显示 duration
遥测类型的定义:
{
"@type": "Telemetry",
"displayName": {
"en": "DurationTelemetry"
},
"name": "DurationTelemetry",
"schema": "duration"
}
设备客户端应该以 JSON 形式发送遥测,如下例所示。持续时间必须是 ISO 8601 格式:
{ "DurationTelemetry": "PT10H24M6.169083011336625S" }
复杂类型
本部分介绍设备可以流式传输的复杂遥测类型的示例。
设备模型中的以下代码片段显示 Enum
遥测类型的定义:
{
"@type": "Telemetry",
"displayName": {
"en": "EnumTelemetry"
},
"name": "EnumTelemetry",
"schema": {
"@type": "Enum",
"displayName": {
"en": "Enum"
},
"valueSchema": "integer",
"enumValues": [
{
"displayName": {
"en": "Item1"
},
"enumValue": 0,
"name": "Item1"
},
{
"displayName": {
"en": "Item2"
},
"enumValue": 1,
"name": "Item2"
},
{
"displayName": {
"en": "Item3"
},
"enumValue": 2,
"name": "Item3"
}
]
}
}
设备客户端应该以 JSON 形式发送遥测,如下所示。 值可能为 0
、1
和 2
,它们在 IoT Central 中显示为 Item1
、Item2
和 Item3
:
{ "EnumTelemetry": 1 }
设备模型中的以下代码片段显示 Object
遥测类型的定义。 此对象具有类型为 dateTime
、integer
和 Enum
的三个字段:
{
"@type": "Telemetry",
"displayName": {
"en": "ObjectTelemetry"
},
"name": "ObjectTelemetry",
"schema": {
"@type": "Object",
"displayName": {
"en": "Object"
},
"fields": [
{
"displayName": {
"en": "Property1"
},
"name": "Property1",
"schema": "dateTime"
},
{
"displayName": {
"en": "Property2"
},
"name": "Property2",
"schema": "integer"
},
{
"displayName": {
"en": "Property3"
},
"name": "Property3",
"schema": {
"@type": "Enum",
"displayName": {
"en": "Enum"
},
"valueSchema": "integer",
"enumValues": [
{
"displayName": {
"en": "Item1"
},
"enumValue": 0,
"name": "Item1"
},
{
"displayName": {
"en": "Item2"
},
"enumValue": 1,
"name": "Item2"
},
{
"displayName": {
"en": "Item3"
},
"enumValue": 2,
"name": "Item3"
}
]
}
}
]
}
}
设备客户端应该以 JSON 形式发送遥测,如下所示。 DateTime
类型必须符合 ISO 8061 标准。 Property3
值可能为 0
和 1
,它们在 IoT Central 中显示为 Item1
、Item2
和 Item3
:
{
"ObjectTelemetry": {
"Property1": "2020-09-09T03:36:46.195Z",
"Property2": 37,
"Property3": 2
}
}
设备模型中的以下代码片段显示 vector
遥测类型的定义:
{
"@type": "Telemetry",
"displayName": {
"en": "VectorTelemetry"
},
"name": "VectorTelemetry",
"schema": "vector"
}
设备客户端应该以 JSON 形式发送遥测,如下例所示:
{
"VectorTelemetry": {
"x": 74.72395045538597,
"y": 74.72395045538597,
"z": 74.72395045538597
}
}
设备模型中的以下代码片段显示 geopoint
遥测类型的定义:
{
"@type": "Telemetry",
"displayName": {
"en": "GeopointTelemetry"
},
"name": "GeopointTelemetry",
"schema": "geopoint"
}
注意
地理位置点架构类型是 DTDL IoT Central 扩展的一部分。 IoT Central 目前支持 geopoint 架构类型和 location 语义类型,以实现后向兼容性。
设备客户端应该以 JSON 形式发送遥测,如下所示。 IoT Central 在地图上以 pin 的形式显示值:
{
"GeopointTelemetry": {
"lat": 47.64263,
"lon": -122.13035,
"alt": 0
}
}
事件和状态类型
本部分显示设备发送到 IoT Central 应用程序的遥测事件和状态的示例。
注意
事件和状态架构类型是 DTDL IoT Central 扩展的一部分。
设备模型中的以下代码片段显示 integer
事件类型的定义:
{
"@type": [
"Telemetry",
"Event"
],
"displayName": {
"en": "IntegerEvent"
},
"name": "IntegerEvent",
"schema": "integer"
}
设备客户端应该以 JSON 形式发送事件数据,如下例所示:
{ "IntegerEvent": 74 }
设备模型中的以下代码片段显示 integer
状态类型的定义:
{
"@type": [
"Telemetry",
"State"
],
"displayName": {
"en": "IntegerState"
},
"name": "IntegerState",
"schema": {
"@type": "Enum",
"valueSchema": "integer",
"enumValues": [
{
"displayName": {
"en": "Level1"
},
"enumValue": 1,
"name": "Level1"
},
{
"displayName": {
"en": "Level2"
},
"enumValue": 2,
"name": "Level2"
},
{
"displayName": {
"en": "Level3"
},
"enumValue": 3,
"name": "Level3"
}
]
}
}
设备客户端应该以 JSON 形式发送状态,如下例所示。 整数状态值可能为 1
、2
和 3
:
{ "IntegerState": 2 }
属性
若要了解有关 DTDL 属性命名规则的详细信息,请参阅 DTDL > 属性。 不能使用 _
字符启动遥测名称。
组件中的属性
如果该属性是在组件中定义的,请将该属性包装在组件名称中。 以下示例将 maxTempSinceLastReboot
设置在 thermostat2
组件中。 标记 __t
指示此部分定义组件:
{
"thermostat2" : {
"__t" : "c",
"maxTempSinceLastReboot" : 38.7
}
}
若要了解详细信息,请参阅教程:创建客户端应用程序并将其连接到 Azure IoT Central 应用程序。
基元类型
本部分介绍设备发送到服务的基本属性类型的示例。
设备模型中的以下代码片段显示 boolean
属性类型的定义:
{
"@type": "Property",
"displayName": {
"en": "BooleanProperty"
},
"name": "BooleanProperty",
"schema": "boolean",
"writable": false
}
设备客户端应发送 JSON 有效负载,将其作为设备孪生中报告的属性,类似于以下示例:
{ "BooleanProperty": false }
设备模型中的以下代码片段显示 long
属性类型的定义:
{
"@type": "Property",
"displayName": {
"en": "LongProperty"
},
"name": "LongProperty",
"schema": "long",
"writable": false
}
设备客户端应发送 JSON 有效负载,将其作为设备孪生中报告的属性,类似于以下示例:
{ "LongProperty": 439 }
设备模型中的以下代码片段显示 date
属性类型的定义:
{
"@type": "Property",
"displayName": {
"en": "DateProperty"
},
"name": "DateProperty",
"schema": "date",
"writable": false
}
设备客户端应发送 JSON 有效负载,将其作为设备孪生中报告的属性,类似于以下示例。 Date
类型必须符合 ISO 8061 标准:
{ "DateProperty": "2020-05-17" }
设备模型中的以下代码片段显示 duration
属性类型的定义:
{
"@type": "Property",
"displayName": {
"en": "DurationProperty"
},
"name": "DurationProperty",
"schema": "duration",
"writable": false
}
设备客户端应发送 JSON 有效负载,将其作为设备孪生中报告的属性,类似于以下示例 - 持续时间必须符合 ISO 8601 Duration 标准:
{ "DurationProperty": "PT10H24M6.169083011336625S" }
设备模型中的以下代码片段显示 float
属性类型的定义:
{
"@type": "Property",
"displayName": {
"en": "FloatProperty"
},
"name": "FloatProperty",
"schema": "float",
"writable": false
}
设备客户端应发送 JSON 有效负载,将其作为设备孪生中报告的属性,类似于以下示例:
{ "FloatProperty": 1.9 }
设备模型中的以下代码片段显示 string
属性类型的定义:
{
"@type": "Property",
"displayName": {
"en": "StringProperty"
},
"name": "StringProperty",
"schema": "string",
"writable": false
}
设备客户端应发送 JSON 有效负载,将其作为设备孪生中报告的属性,类似于以下示例:
{ "StringProperty": "A string value - could be a URL" }
复杂类型
本部分介绍设备发送到服务的复杂属性类型的示例。
设备模型中的以下代码片段显示 Enum
属性类型的定义:
{
"@type": "Property",
"displayName": {
"en": "EnumProperty"
},
"name": "EnumProperty",
"writable": false,
"schema": {
"@type": "Enum",
"displayName": {
"en": "Enum"
},
"valueSchema": "integer",
"enumValues": [
{
"displayName": {
"en": "Item1"
},
"enumValue": 0,
"name": "Item1"
},
{
"displayName": {
"en": "Item2"
},
"enumValue": 1,
"name": "Item2"
},
{
"displayName": {
"en": "Item3"
},
"enumValue": 2,
"name": "Item3"
}
]
}
}
设备客户端应发送 JSON 有效负载,将其作为设备孪生中报告的属性,类似于以下示例。 值可能为 0
和 1
,它们在 IoT Central 中显示为 Item1
、Item2
和 Item3
:
{ "EnumProperty": 1 }
设备模型中的以下代码片段显示 Object
属性类型的定义。 此对象具有类型为 string
和 integer
的两个字段:
{
"@type": "Property",
"displayName": {
"en": "ObjectProperty"
},
"name": "ObjectProperty",
"writable": false,
"schema": {
"@type": "Object",
"displayName": {
"en": "Object"
},
"fields": [
{
"displayName": {
"en": "Field1"
},
"name": "Field1",
"schema": "integer"
},
{
"displayName": {
"en": "Field2"
},
"name": "Field2",
"schema": "string"
}
]
}
}
设备客户端应发送 JSON 有效负载,将其作为设备孪生中报告的属性,类似于以下示例:
{
"ObjectProperty": {
"Field1": 37,
"Field2": "A string value"
}
}
设备模型中的以下代码片段显示 vector
属性类型的定义:
{
"@type": "Property",
"displayName": {
"en": "VectorProperty"
},
"name": "VectorProperty",
"schema": "vector",
"writable": false
}
设备客户端应发送 JSON 有效负载,将其作为设备孪生中报告的属性,类似于以下示例:
{
"VectorProperty": {
"x": 74.72395045538597,
"y": 74.72395045538597,
"z": 74.72395045538597
}
}
设备模型中的以下代码片段显示 geopoint
属性类型的定义:
{
"@type": "Property",
"displayName": {
"en": "GeopointProperty"
},
"name": "GeopointProperty",
"schema": "geopoint",
"writable": false
}
注意
地理位置点架构类型是 DTDL IoT Central 扩展的一部分。 IoT Central 目前支持 geopoint 架构类型和 location 语义类型,以实现后向兼容性。
设备客户端应发送 JSON 有效负载,将其作为设备孪生中报告的属性,类似于以下示例:
{
"GeopointProperty": {
"lat": 47.64263,
"lon": -122.13035,
"alt": 0
}
}
可写属性类型
本部分介绍设备从服务接收的可写属性类型的示例。
如果在组件中定义了可写属性,则所需属性消息包含组件名称。 以下示例展示了请求设备更新 thermostat2
组件中 targetTemperature
的消息。 标记 __t
指示此部分定义组件:
{
"thermostat2": {
"targetTemperature": {
"value": 57
},
"__t": "c"
},
"$version": 3
}
若要了解详细信息,请参阅连接 IoT 即插即用多个组件设备应用程序。
设备或模块应通过发送报告的属性来确认已接收到属性。 报告的属性应包括:
value
- 属性的实际值(通常是接收到的值,但设备可能决定报告不同的值)。ac
- 使用 HTTP 状态代码的确认代码。av
- 引用所需属性的$version
的确认版本。 可在所需的属性 JSON 有效负载中找到该值。ad
- 可选确认说明。
若要详细了解这些字段,请参阅 IoT 即插即用约定 > 确认响应
设备模型中的以下代码片段显示了一个可写 string
属性类型的定义:
{
"@type": "Property",
"displayName": {
"en": "StringPropertyWritable"
},
"name": "StringPropertyWritable",
"writable": true,
"schema": "string"
}
设备从服务接收以下有效负载:
{
"StringPropertyWritable": "A string from IoT Central", "$version": 7
}
设备在处理更新后应将以下 JSON 有效负载发送到服务。 此消息包括从服务接收的原始更新的版本号。
提示
如果服务是 IoT Central,则会在收到此消息时将属性标记为在 UI 中同步:
{
"StringPropertyWritable": {
"value": "A string from IoT Central",
"ac": 200,
"ad": "completed",
"av": 7
}
}
设备模型中的以下代码片段显示了一个可写 Enum
属性类型的定义:
{
"@type": "Property",
"displayName": {
"en": "EnumPropertyWritable"
},
"name": "EnumPropertyWritable",
"writable": true,
"schema": {
"@type": "Enum",
"displayName": {
"en": "Enum"
},
"valueSchema": "integer",
"enumValues": [
{
"displayName": {
"en": "Item1"
},
"enumValue": 0,
"name": "Item1"
},
{
"displayName": {
"en": "Item2"
},
"enumValue": 1,
"name": "Item2"
},
{
"displayName": {
"en": "Item3"
},
"enumValue": 2,
"name": "Item3"
}
]
}
}
设备从服务接收以下有效负载:
{
"EnumPropertyWritable": 1 , "$version": 10
}
设备在处理更新后应将以下 JSON 有效负载发送到服务。 此消息包括从服务接收的原始更新的版本号。
提示
如果服务是 IoT Central,则会在收到此消息时将属性标记为在 UI 中同步:
{
"EnumPropertyWritable": {
"value": 1,
"ac": 200,
"ad": "completed",
"av": 10
}
}
命令
若要了解有关 DTDL 命令命名规则的详细信息,请参阅 DTDL > 命令。 不能使用 _
字符启动命令名称。
如果在组件中定义了命令,则设备接收的命令的名称包括组件名称。 例如,如果命令名称为 getMaxMinReport
,并且组件名称为 thermostat2
,则设备会收到请求,执行名称为 thermostat2*getMaxMinReport
的命令。
设备模型中的以下代码片段显示没有参数并且不要求设备返回任何内容的命令的定义:
{
"@type": "Command",
"displayName": {
"en": "CommandBasic"
},
"name": "CommandBasic"
}
设备在请求中接收到一个空的有效负载,并且应在响应中返回一个空的有效负载,同时使用 200
HTTP 响应代码指示成功。
设备模型中的以下代码片段显示具有整数参数并且要求设备返回整数值的命令的定义:
{
"@type": "Command",
"request": {
"@type": "CommandPayload",
"displayName": {
"en": "RequestParam"
},
"name": "RequestParam",
"schema": "integer"
},
"response": {
"@type": "CommandPayload",
"displayName": {
"en": "ResponseParam"
},
"name": "ResponseParam",
"schema": "integer"
},
"displayName": {
"en": "CommandSimple"
},
"name": "CommandSimple"
}
设备接收一个整数值作为请求有效负载。 设备应返回一个整数值作为响应有效负载,并返回 200
HTTP 响应代码以指示成功。
设备模型中的以下代码片段显示具有对象参数并且要求设备返回对象的命令的定义。 此示例中,两个对象都有整数和字符串字段:
{
"@type": "Command",
"request": {
"@type": "CommandPayload",
"displayName": {
"en": "RequestParam"
},
"name": "RequestParam",
"schema": {
"@type": "Object",
"displayName": {
"en": "Object"
},
"fields": [
{
"displayName": {
"en": "Field1"
},
"name": "Field1",
"schema": "integer"
},
{
"displayName": {
"en": "Field2"
},
"name": "Field2",
"schema": "string"
}
]
}
},
"response": {
"@type": "CommandPayload",
"displayName": {
"en": "ResponseParam"
},
"name": "ResponseParam",
"schema": {
"@type": "Object",
"displayName": {
"en": "Object"
},
"fields": [
{
"displayName": {
"en": "Field1"
},
"name": "Field1",
"schema": "integer"
},
{
"displayName": {
"en": "Field2"
},
"name": "Field2",
"schema": "string"
}
]
}
},
"displayName": {
"en": "CommandComplex"
},
"name": "CommandComplex"
}
以下代码片段显示发送到设备的示例请求有效负载:
{ "Field1": 56, "Field2": "A string value" }
以下代码片段显示发送自设备的示例响应有效负载。 使用 200
HTTP 响应代码指示成功:
{ "Field1": 87, "Field2": "Another string value" }
后续步骤
了解设备有效负载后,建议接下来的步骤是阅读设备开发人员指南。