本文将介绍设备连接物联网开发平台后,如何通过自定义 Topic 发布和订阅业务消息。
当物模型无法满足业务需求,或者需要自行定义 MQTT Payload 数据格式时,可以使用自定义 Topic。
功能介绍
自定义 Topic 是基于 MQTT 发布/订阅机制提供的自定义消息通道。
自定义 Topic 的前两个层级固定为:
${ProductID}/${DeviceName}
后续层级可以根据业务需要定义,例如:
${ProductID}/${DeviceName}/custom/report${ProductID}/${DeviceName}/custom/control
其中:
Topic | 用途 |
${ProductID}/${DeviceName}/custom/report | 设备向云端上报业务数据。 |
${ProductID}/${DeviceName}/custom/control | 设备接收云端下发的业务消息。 |
自定义 Topic 支持以下设备端操作权限:发布、订阅、发布和订阅。
说明:
自定义 Topic 只定义消息通信通道。Payload 的数据格式、字段和业务语义由设备端与业务系统自行约定。
平台默认为每个设备提供 ${ProductID}/${DeviceName}/data Topic,该 Topic 具有发布和订阅权限,也可以直接用于自定义消息通信。
前提条件
在使用自定义 Topic 进行消息通信前,请确认已完成以下准备:
设备已完成 MQTT 身份认证并成功连接物联网开发平台。
已配置需要使用的自定义 Topic。
已根据消息方向配置 Topic 的发布或订阅权限。
说明:
设备实际发布或订阅的 Topic 必须与产品配置的自定义 Topic 保持一致,其中
${ProductID} 和 ${DeviceName} 应替换为当前设备实际的产品 ID 和设备名称。注意事项
设备实际使用的 Topic 必须与产品配置的自定义 Topic 保持一致。
Topic 中的 ProductID 和 DeviceName 应与当前连接设备的身份一致。
Topic 的发布、订阅权限应与实际消息方向一致。
自定义 Topic 的 Payload 格式和业务语义由设备端与业务系统自行定义。
自定义 Topic 与透传 Topic 是不同的通信能力;自定义 Topic 不触发云端解析。
通信流程

步骤 1:准备自定义 Topic
本示例分别使用一个 Topic 进行设备数据上报和消息下发:
Topic | 设备权限 | 用途 |
${ProductID}/${DeviceName}/custom/report | 发布 | 设备向平台上报业务数据。 |
${ProductID}/${DeviceName}/custom/control | 订阅 | 设备接收业务消息。 |
注意:
Topic 权限从设备端视角定义。“发布”表示设备向平台发送消息;“订阅”表示设备接收平台下发的消息。设备使用无对应权限的 Topic 时,平台会拒绝该操作。
步骤 2:订阅下行 Topic
设备连接平台后,需要订阅用于接收业务消息的自定义 Topic。
以下代码以 Python Paho MQTT 为例。示例假设 MQTT Client 已经完成身份认证并成功连接平台。
subscribe_topic = (f"{product_id}/{device_name}/custom/control")result, mid = client.subscribe(subscribe_topic,qos=1)if result != 0:print(f"订阅请求失败:{result}")else:print(f"正在订阅:{subscribe_topic}")
订阅成功后,设备需要保持 MQTT 消息循环运行,才能持续接收平台发送的消息。
client.loop_forever()
步骤 3:接收并处理下行消息
注册
on_message 回调处理已订阅 Topic 的消息:def on_message(client, userdata, msg):payload = msg.payload.decode("utf-8")print(f"Topic:{msg.topic}")print(f"Payload:{payload}")# 根据业务协议解析 Payload,并执行设备逻辑client.on_message = on_message
例如业务下发:
{"command": "set_mode","mode": "eco"}
设备收到后,可以根据自行约定的 Payload 格式解析 command、mode 等字段并执行对应业务逻辑。
说明:
自定义 Topic 不规定 Payload 的字段结构和业务语义。设备端与业务系统需要自行约定消息格式,并确保双方实现一致。
步骤 4:发布上行消息
设备需要上报业务数据时,向具有发布权限的自定义 Topic 发布消息。
例如上报温度和湿度:
import jsonpublish_topic = (f"{product_id}/{device_name}/custom/report")payload = {"temperature": 26.5,"humidity": 60}info = client.publish(publish_topic,payload=json.dumps(payload),qos=1)if info.rc != 0:print(f"消息发布失败:{info.rc}")
如果需要等待 QoS 1 消息发送完成,可以调用:
info.wait_for_publish()
自定义 Topic 的 Payload 可以根据实际业务自行定义,平台不会按照物模型结构解析其中的业务字段。
自定义 Topic 与其他 Topic 的区别
Topic 类型 | 主要用途 | Payload 处理方式 |
物模型 Topic | 属性、事件、行为等标准设备能力。 | 按物模型协议处理和校验。 |
透传 Topic | 自定义透传数据与物模型之间转换。 | - |
自定义 Topic | 自定义业务消息通信。 | Payload 由业务自行定义和解析。 |
常见问题
现象 | 排查建议 |
MQTT 已连接,但发布消息失败。 | 检查 Topic 是否与产品配置一致,并确认设备具有发布权限。 |
设备订阅失败。 | 检查 Topic 是否正确,并确认设备具有订阅权限。 |
业务系统下发消息后设备未收到。 | 确认设备已经成功订阅对应 Topic,并保持 MQTT 消息循环运行。 |
收到消息但业务解析失败。 | 检查设备端与业务系统使用的 Payload 格式、字段和编码是否一致。 |
希望将私有协议数据转换为物模型数据。 | 不应使用自定义 Topic 的方式处理,请使用自定义透传及云端解析能力。 |