本文将介绍设备连接物联网开发平台后,如何通过自定义透传 Topic 收发业务数据。
自定义透传适用于设备已有私有数据协议,或需要使用二进制、非 JSON 等自定义数据格式进行通信的场景。设备与业务系统自行约定 Payload 的数据格式和业务语义,物联网开发平台不解析 Payload 中的业务内容。当前平台“基本概念”也将自定义透传定义为基于 MQTT 自由定义 Payload、平台不进行解析的通信方式。
功能介绍
创建产品时,数据协议默认采用物模型,也可以选择自定义协议进行透传。
自定义透传使用平台规定的上下行透传 Topic:
Topic | 方向 | 用途 |
$thing/up/raw/{ProductID}/{DeviceName} | 设备 → 云端 | 设备上报自定义透传数据。 |
$thing/down/raw/{ProductID}/{DeviceName} | 云端 → 设备 | 设备接收自定义透传数据。 |
上行数据发布至
$thing/up/raw/{ProductID}/{DeviceName},下行数据通过订阅 $thing/down/raw/{ProductID}/{DeviceName} 接收。 自定义透传只定义数据传输方式。Payload 中各字段的含义、长度、编码和业务协议由设备端与业务系统自行约定。
与物模型、自定义 Topic 的区别
对比项 | 物模型 | 自定义透传 | 自定义 Topic |
数据语义 | 属性、事件、行为。 | 业务自行定义。 | 业务自行定义。 |
Topic | 平台定义。 | 平台规定的 Raw Topic。 | 用户定义后续 Topic 层级。 |
Payload | 遵循物模型协议。 | 自定义,常用于二进制、非 JSON 或私有协议。 | 自定义。 |
平台业务解析 | 按物模型处理。 | 不解析。 | 不解析。 |
典型场景 | 标准化设备能力。 | 已有私有设备协议、二进制协议。 | 自定义 MQTT 业务消息。 |
透传 Topic 用于非 JSON 格式业务数据,自定义 Topic 则允许用户自行定义 Topic 后续层级。
通信流程
通信流程参见下图:

前提条件
使用自定义透传进行通信前,请确认:
已创建数据协议为自定义透传的产品和设备。
设备已完成 MQTT 身份认证并成功连接物联网开发平台。
已确定设备端与业务系统之间使用的数据协议。
已明确 Payload 的字段、长度、数据类型、编码方式及字节序。
如果尚未完成设备 MQTT 连接,请先参见设备密钥认证或设备证书认证相关文档。
使用限制
项目 | 限制 |
MQTT 协议版本 | MQTT 3.1.1 |
QoS | 支持 QoS 0、QoS 1,不支持 QoS 2。 |
Retain Message | 不支持。 |
单条 MQTT Publish 消息 | 最大16KB。 |
腾讯云当前 MQTT 接入协议明确不支持 QoS 2 和 Retain Message;产品限制规定单条 MQTT 发布消息最大为16KB。
注意事项
自定义透传使用平台规定的透传 Topic,不应与自定义 Topic 混用。
Payload 的数据格式和业务语义由设备端与业务系统自行约定。
ProductID 和 DeviceName 必须与当前连接设备身份一致。
上下行两端应保持字段定义、长度、数据类型和字节序一致。
二进制协议应显式完成序列化和反序列化,避免直接依赖设备内存结构。
设备需要保持 MQTT 消息循环运行,才能持续接收下行数据。
本文使用的12字节二进制协议仅为示例,不是平台强制协议。
操作步骤
步骤 1:定义透传数据格式
自定义透传不限定 Payload 的数据格式。开发者需要根据实际设备能力自行设计通信协议。
以下以一个简单的智能灯二进制协议为例。
上行数据格式
字节偏移 | 长度 | 字段 | 示例值 | 说明 |
0 | 2 Byte | Header | AA 55 | 帧头 |
2 | 1 Byte | MessageType | 01 | 数据上报 |
3 | 1 Byte | Reserved | 00 | 保留 |
4 | 4 Byte | ClientId | 00 00 00 00 | 消息标识 |
8 | 1 Byte | PowerSwitch | 01 | 开关状态 |
9 | 1 Byte | Color | 01 | 颜色 |
10 | 1 Byte | Brightness | 38 | 亮度 |
11 | 1 Byte | Reserved | 00 | 保留 |
对应示例 Payload:
AA 55 01 00 00 00 00 00 01 01 38 00现有示例程序实际发送的上行数据即采用该字节结构,其中
0x01 表示数据上报、0x20 表示控制消息。说明:
上述协议仅用于说明自定义透传数据的组织方式,不是物联网开发平台规定的 Payload 格式。实际产品可根据自身协议自行定义。
步骤 2:订阅下行透传 Topic
设备连接平台后,需要订阅下行透传 Topic:
down_topic = (f"$thing/down/raw/"f"{product_id}/{device_name}")client.subscribe(down_topic,qos=1,)
其中,
ProductID 和 DeviceName 应与当前 MQTT 连接对应的设备身份保持一致。现有透传示例同样使用 QoS 1 订阅该下行 Topic。
步骤 3:接收并解析下行数据
设备通过 MQTT 消息回调接收下行二进制 Payload。
def on_message(client, userdata, msg):payload = msg.payloadprint(f"Topic:{msg.topic}")print(f"Payload:{payload.hex(' ').upper()}")# 根据自定义协议解析 Payloadclient.on_message = on_message
例如设备收到:
AA 55 20 00 CC CC CC CC FF 01 FF FF其中
0x20 表示控制消息。现有示例实际接收的下行 Payload 也采用该格式。例如,可以根据本文示例协议读取相应字段:
msg_type = payload[2]power_switch = payload[8]color = payload[9]brightness = payload[10]if msg_type == 0x20:# 执行设备控制逻辑pass
实际开发中,应按照设备自身协议约定的字段偏移、长度和编码方式解析 Payload。
步骤 4:发布上行透传数据
设备需要向平台上报数据时,首先按照自定义协议构造 Payload。
例如:
payload = bytes([0xAA, 0x55,0x01,0x00,0x00, 0x00, 0x00, 0x00,0x01,0x01,0x38,0x00,])
然后发布至上行透传 Topic:
up_topic = (f"$thing/up/raw/"f"{product_id}/{device_name}")client.publish(up_topic,payload=payload,qos=0,)
现有实现也是将二进制 Payload 直接发布至
$thing/up/raw/{ProductID}/{DeviceName}。本文示例上行使用 QoS 0、下行订阅使用 QoS 1,这不是自定义透传 Topic 的强制要求。物联网开发平台支持 QoS 0 和 QoS 1,不支持 QoS 2。
步骤 5:业务系统下发透传数据
业务系统需要向设备下发数据时,可以通过物联网开发平台提供的设备透传指令控制能力向设备订阅的 Topic 发送消息。
对于二进制数据,业务系统可以先将原始 Payload 进行 Base64 编码,并在调用
PublishMessage 时设置:参数 | 取值 |
ProductID | 目标设备所属产品 ID。 |
DeviceName | 目标设备名称。 |
Topic | $thing/down/raw/{ProductID}/{DeviceName} |
Payload | Base64 编码后的二进制数据。 |
PayloadEncoding | base64 |
QoS | 0 或 1。 |
当
PayloadEncoding 设置为 base64 时,平台会将业务系统提交的 Base64 内容转换回二进制数据后发送至设备。例如设备需要收到:
AA 55 20 00 CC CC CC CC FF 01 FF FF,业务系统应首先对该二进制数据进行 Base64 编码,再通过透传指令控制接口进行下发。设备收到消息后,按照 步骤 3 中定义的协议解析 Payload 并执行业务逻辑。二进制协议设计建议
使用自定义透传时,协议本身由业务定义。建议至少明确以下内容:
项目 | 说明 |
帧头 | 用于识别数据帧及协议版本。 |
消息类型 | 区分数据上报、控制、应答等消息。 |
消息标识 | 用于请求、应答或消息去重。 |
字段偏移与长度 | 明确每个字段在 Payload 中的位置。 |
数据类型 | 明确整数、字符串、位字段等表示方式。 |
字节序 | 多字节整数应明确采用大端或小端。 |
无效值 | 明确字段不存在或未设置时的表示方式。 |
数据长度 | 可根据协议复杂度增加长度字段。 |
数据校验 | 对可靠性要求较高时可增加 CRC、Checksum 等校验字段。 |
常见问题
现象 | 排查建议 |
上行透传数据发送失败。 | 检查 MQTT 连接状态,以及上行 Topic 中的 ProductID、DeviceName 是否正确。 |
设备无法收到下行数据。 | 检查是否已成功订阅 $thing/down/raw/{ProductID}/{DeviceName},并确认 MQTT 消息循环持续运行。 |
收到数据但解析结果异常。 | 检查字段偏移、长度、数据类型和字节序是否与业务协议一致。 |
相同结构在不同芯片上发送结果不同。 | 检查结构体 Padding 和 CPU 字节序,不建议直接发送结构体内存。 |
二进制下发后设备收到的数据不一致。 | 检查业务系统 Base64 编码是否正确,并确认下发接口设置 PayloadEncoding=base64。 |
自定义透传和自定义 Topic 有什么区别。 | 自定义透传使用平台规定的 Raw Topic;自定义 Topic 的 Topic 后续层级由用户自行定义。 |