帮你快速理解、总结文档立即下载

物模型通信

最近更新时间:2026-09-11 16:05:32
我的收藏
本文将介绍设备连接物联网开发平台后,如何通过物模型 Topic 上报设备属性和事件,以及接收云端属性控制和行为调用。
物模型用于将设备能力以统一的数据结构进行描述。产品定义物模型后,平台可以按照属性、事件和行为理解设备数据,并对设备上报的数据格式进行校验。

功能介绍

物模型(Thing Model)是设备在云端的数字化描述,通过属性、事件和行为三个维度定义产品能力。
类型
含义
典型场景
属性 Property
设备当前状态或可配置参数。
开关、温度、亮度。
事件 Event
设备主动上报的业务事件。
告警、故障、信息。
行为 Action
云端调用设备执行具体动作。
开锁、调整音量、执行任务。
其中,属性可由设备主动上报;对于可写属性,云端也可以向设备下发设置请求。事件由设备主动上报,事件类型包括 alertfaultinfo。行为由云端发起调用,设备执行后返回结果。
物模型通信使用平台规定的 Topic 和 JSON 协议。设备上报的数据需要与产品中定义的属性、事件和行为保持一致,平台会对物模型数据进行校验,不符合物模型定义的数据不会被正常存储和展示。

物模型 Topic

物模型主要使用以下 Topic:
能力
上行 Topic
下行 Topic
属性
$thing/up/property/{ProductID}/{DeviceName}
$thing/down/property/{ProductID}/{DeviceName}
事件
$thing/up/event/{ProductID}/{DeviceName}
$thing/down/event/{ProductID}/{DeviceName}
行为
$thing/up/action/{ProductID}/{DeviceName}
$thing/down/action/{ProductID}/{DeviceName}
不同 Topic 对应不同物模型语义:
属性 Topic 用于属性上报、属性控制及相关响应。
事件 Topic 用于事件上报及事件响应。
行为 Topic 用于行为调用及行为执行结果返回。

通信流程

物模型通信主要包含两类链路:


前提条件

使用物模型通信前,请确认:
已创建产品和设备,详见 创建产品创建设备
已在产品中完成物模型定义。
设备已完成 MQTT 身份认证并成功连接物联网开发平台。
设备端使用的属性标识符、事件标识符、行为标识符及对应参数,与产品物模型定义保持一致。
物模型协议使用这些标识符描述具体设备能力,因此设备端不能自行修改字段名称或数据类型。

使用限制

单设备 MQTT 上行消息存在速率限制:
QoS
单设备最大上行速率
QoS 0
30 条/秒
QoS 1
10 条/秒
超过限制时,可在设备行为日志中看到:
Fail, reach max limit

使用注意事项

物模型 Topic 由平台定义,不需要像自定义 Topic 一样创建 Topic 类。
设备上报和接收的数据必须遵循物模型协议规定的 JSON 结构。
属性、事件、行为标识符以及参数必须与产品物模型定义保持一致。
属性下行 Topic 中可能同时包含 report_replycontrolget_status_reply 等消息,应结合 method 判断具体消息类型。
属性控制完成后,应返回 control_reply;行为执行完成后,应返回 action_reply
clientToken 用于关联请求和响应,设备回复时应保持一致。
事件的 type 应使用 alertfaultinfo
timestamp 统一使用毫秒级 Unix 时间戳;如果无特殊时间需求,可以不填写,由平台使用当前系统时间。
timestamp 与服务端当前时间相差超过24小时时,平台会返回 405
行为调用后,设备应在5秒内返回 action_reply,否则平台会判定调用超时。
物模型数据不符合定义时,平台不会正常存储对应数据。
单设备消息上报应遵守 QoS 对应的速率限制。

操作步骤

步骤 1:订阅物模型下行 Topic

设备连接平台后,需要根据实际业务订阅对应的物模型下行 Topic,用于接收平台响应、属性控制及行为调用。
以下代码以 Python Paho MQTT 为例,假设 MQTT Client 已经完成身份认证并成功连接平台。
property_down_topic = (
f"$thing/down/property/{product_id}/{device_name}"
)

event_down_topic = (
f"$thing/down/event/{product_id}/{device_name}"
)

action_down_topic = (
f"$thing/down/action/{product_id}/{device_name}"
)

client.subscribe(property_down_topic, qos=1)
client.subscribe(event_down_topic, qos=1)
client.subscribe(action_down_topic, qos=1)
设备需要保持 MQTT 消息循环运行:
client.loop_forever()
实际项目只需要订阅业务使用到的 Topic,不要求同时使用属性、事件和行为。

步骤 2:上报设备属性

设备属性用于描述设备当前状态,例如开关状态、温度和亮度。
属性上报 Topic:
$thing/up/property/{ProductID}/{DeviceName}
设备按照物模型属性协议构造消息,例如:
{
"method": "report",
"clientToken": "123",
"params": {
"power_switch": 1,
"color": 1,
"brightness": 32
}
}
主要字段:
字段
说明
method
属性上报固定为 report
clientToken
消息 ID,用于关联请求和响应。
timestamp
Unix 时间戳,单位为毫秒,可选;不填写时由平台使用当前系统时间。
params
本次上报的属性键值。
如果无特殊时间需求,可以不填写 timestamp。如需填写,应使用当前毫秒级 Unix 时间戳;上报时间与服务端当前时间相差超过24小时时,平台会返回 405
Python 示例:
import json
import time

topic = (
f"$thing/up/property/"
f"{product_id}/{device_name}"
)

payload = {
"method": "report",
"clientToken": "property-001",
"timestamp": int(time.time() * 1000),
"params": {
"power_switch": 1,
"brightness": 32
}
}

client.publish(
topic,
json.dumps(payload),
qos=1,
)
params 中的字段必须已在产品物模型中定义,并符合对应数据类型和取值范围。
平台处理完成后,会通过属性下行 Topic 返回 report_reply
{
"method": "report_reply",
"clientToken": "123",
"code": 0,
"status": ""
}
其中,clientToken 与属性上报请求保持一致,code = 0 表示平台成功处理本次属性上报。

步骤 3:接收并处理属性控制

对于可写属性,平台可以通过以下 Topic 向设备下发控制消息:
$thing/down/property/{ProductID}/{DeviceName}
典型控制消息:
{
"method": "control",
"clientToken": "123",
"params": {
"brightness": 66
}
}
设备收到后,需要先判断 method == "control",再根据 params 执行业务逻辑。
def on_message(client, userdata, msg):
data = json.loads(
msg.payload.decode("utf-8")
)

if (
msg.topic == property_down_topic
and data.get("method") == "control"
):
handle_property_control(data)
这里必须判断 method,因为属性下行 Topic 中还可能收到 report_replyget_status_reply 等消息,不能把所有属性下行消息都当成控制指令。
设备完成控制后,需要向属性上行 Topic 返回 control_reply
{
"method": "control_reply",
"clientToken": "123",
"code": 0,
"status": ""
}
回复中的 clientToken 应与控制请求保持一致,用于平台关联本次请求和响应。

步骤 4:上报设备事件

事件适用于设备主动上报告警、故障和信息类业务状态。
事件上报 Topic:
$thing/up/event/{ProductID}/{DeviceName}
事件响应 Topic:
$thing/down/event/{ProductID}/{DeviceName}
事件请求示例:
{
"method": "event_post",
"clientToken": "123",
"version": "1.0",
"eventId": "PowerAlarm",
"type": "fault",
"params": {
"Voltage": 2.8,
"Percent": 20
}
}
主要字段:
字段
说明
method
固定为 event_post
clientToken
消息 ID,用于关联请求和响应。
version
协议版本,当前默认 1.0
eventId
产品物模型中定义的事件标识。
type
事件类型:alertfaultinfo
timestamp
事件发生时间,Unix 时间戳,单位为毫秒,可选。
params
产品物模型中定义的事件参数。
其中,eventIdtype 是事件上报的关键字段,设备需要根据产品物模型定义填写对应事件标识和事件类型。
如果需要携带事件发生时间,应填写当前毫秒级 Unix 时间戳;无特殊时间需求时可以省略 timestamp
平台处理后通过事件下行 Topic 返回:
{
"method": "event_reply",
"clientToken": "123",
"version": "1.0",
"code": 0,
"status": "",
"data": {}
}
code = 0 表示事件上报成功。

步骤 5:接收并处理行为调用

行为适用于云端调用设备执行具体动作,并实时获取执行结果的场景。
行为调用下行 Topic:
$thing/down/action/{ProductID}/{DeviceName}
设备执行完成后,通过以下 Topic 返回结果:
$thing/up/action/{ProductID}/{DeviceName}
例如云端调用设备调整音量:
{
"method": "action",
"clientToken": "20a4ccfd-d308-****-86c6-5254008a4f10",
"actionId": "control_volume",
"params": {
"action": "set",
"volume": 50
}
}
主要字段:
字段
说明
method
行为调用固定为 action
clientToken
本次行为调用 ID。
actionId
产品物模型中定义的行为标识。
timestamp
行为调用时间,Unix 时间戳,单位为毫秒,可选。
params
行为输入参数。
如果需要填写 timestamp,应使用当前毫秒级 Unix 时间戳;否则可以省略。
设备根据 actionIdparams 执行业务逻辑后,需要返回 action_reply
{
"method": "action_reply",
"clientToken": "20a4ccfd-d308-****-86c6-5254008a4f10",
"code": 0,
"status": "",
"response": {
"volume": 50
}
}
其中:
字段
说明
method
行为回复固定为 action_reply
clientToken
与行为调用请求保持一致。
code
行为执行结果,0 表示成功。
status
执行结果或错误信息。
response
物模型中定义的行为输出参数。
行为回复中的返回参数必须放在 response 中,而不是 params
设备需要在5秒内返回行为执行结果,否则平台会判定本次行为调用超时。

步骤 6:统一处理下行消息

如果同时使用属性、事件和行为,可以先根据 Topic 将下行消息分发到对应处理逻辑,再根据 method 判断具体消息类型。
def on_message(client, userdata, msg):
data = json.loads(
msg.payload.decode("utf-8")
)

method = data.get("method")

if msg.topic == property_down_topic:
if method == "control":
handle_property_control(data)
elif method == "report_reply":
handle_property_report_reply(data)
elif method == "get_status_reply":
handle_status_reply(data)

elif msg.topic == event_down_topic:
if method == "event_reply":
handle_event_reply(data)

elif msg.topic == action_down_topic:
if method == "action":
handle_action(data)
如果处理 get_status_reply,属性数据位于 data.reported 下,例如:
{
"method": "get_status_reply",
"code": 0,
"clientToken": "123",
"type": "report",
"data": {
"reported": {
"power_switch": 1,
"brightness": 66
}
}
}
因此读取属性值时,应从 data.reported 获取,而不是直接从 data 根节点读取。
建议业务实现同时结合 clientTokeneventIdactionId 等字段关联请求和响应。

验证物模型通信

设备成功上报合法物模型数据后,可以在设备详情的物模型数据或相关日志页面查看平台处理结果。
验证时建议依次检查:
是否发布到了正确的物模型 Topic。
Payload 是否为合法 JSON。
method 是否正确。
属性、事件和行为标识符是否与产品物模型定义一致。
参数类型和取值范围是否符合物模型定义。
如填写 timestamp,是否为毫秒级 Unix 时间戳,且与服务端当前时间相差不超过24小时。

常见问题

返回码 / 现象
排查建议
400
Payload 不是合法 JSON,检查 JSON 格式。
403
检查 method 是否正确,或属性、事件、行为标识符是否与产品物模型定义一致。
405
时间戳错误。确认 timestamp 为毫秒级 Unix 时间戳,并检查与服务端当前时间是否相差超过 24 小时。
406
参数不符合物模型定义,检查数据类型、枚举值、数值范围等。例如整型枚举不要使用字符串 "0""1"
503
平台服务端处理异常,可结合日志进行重试或进一步排查。
MQTT 已连接,但属性上报后没有数据。
检查属性 Topic、JSON 格式、method、属性标识符及数据类型。
云端修改属性后设备没有收到。
检查是否订阅 $thing/down/property/...,并确认回调中正确处理 method = control
属性控制已执行,但平台仍认为失败。
检查是否返回 control_reply,以及 clientToken 是否与控制请求一致。
事件上报后没有记录。
检查事件 Topic、eventIdtypeparams 是否与产品物模型定义一致。
行为调用后平台提示超时。
检查设备是否订阅行为下行 Topic,并确认是否在5秒内返回 action_reply
行为回复后平台无法解析结果。
检查输出参数是否放在 response 中,而不是 params
get_status_reply 中读取不到属性值。
属性数据位于 data.reported 下,不在 data 根节点。
行为日志出现 Fail, reach max limit
检查设备是否超过单设备 MQTT 上行速率限制。
Payload 为二进制或私有协议。
建议使用自定义透传。
仅需传输自定义业务消息。
企业实例可使用自定义 Topic,具体以当前实例能力为准。