4. 设备接入与MQTT协议实践
ThingsBoard 的设备接入层以 MQTT 作为最常用的传输协议之一。理解 MQTT 的发布/订阅模型、主题结构与 QoS 语义,是后续完成设备认证、遥测上报和属性同步的前提。本节围绕“设备如何连上平台、如何把数据送进去、如何确认平台已收到”这条主线展开,并给出可直接用于 MQTTBox 或 mosquitto 客户端的联调方法。
一、MQTT 协议基础与 ThingsBoard 的主题约定
MQTT 是一种基于 TCP 的轻量级消息协议,采用 Broker 中转的发布/订阅模型。设备(Client)不与彼此直连,而是把消息发布到某个主题(Topic),Broker 再按订阅关系转发。ThingsBoard 自身充当 MQTT Broker,设备通过 1883(TCP)或 8883(TLS)端口接入。协议中的三个关键参数是:ClientId(客户端标识)、Username/Password(认证凭据)、QoS(服务质量等级)。QoS 0 为“至多一次”,消息可能丢失;QoS 1 为“至少一次”,可能重复;QoS 2 为“恰好一次”,开销最大。遥测数据通常用 QoS 1 即可在可靠性与开销之间取得平衡。
ThingsBoard 对主题做了严格约定,设备必须发布到规定格式的主题才会被解析。常用主题如下:
v1/devices/me/telemetry:发布遥测数据(时序数据)。v1/devices/me/attributes:发布客户端属性(设备侧属性)。v1/devices/me/attributes/request/1:请求获取共享属性。v1/devices/me/attributes/response/+:订阅共享属性响应。v1/devices/me/rpc/request/+:订阅服务端下发的 RPC 命令。v1/devices/me/rpc/response/$request_id:发布 RPC 响应。
其中 me 表示“当前已认证设备自身”,平台会根据认证凭据自动识别设备身份,因此设备无需在主题里写自己的 ID。这一点是理解 ThingsBoard 接入的关键:身份来自认证,而非主题路径。
二、设备连接认证:访问令牌与凭据配置
ThingsBoard 默认使用“访问令牌(Access Token)”作为 MQTT 认证方式。在设备详情页点击“管理凭据”,可复制形如 a1b2c3d4e5f6g7h8i9j0 的令牌字符串。连接时把它填入 MQTT 客户端的 Username 字段,Password 留空,ClientId 可自定义但建议唯一。平台收到 CONNECT 报文后,用 Username 去设备表匹配令牌,匹配成功则返回 CONNACK 并建立会话。
需要注意两点:其一,令牌即身份,泄露等同于设备被冒用,生产环境应启用 TLS(8883)并定期轮换;其二,若使用 MQTTBox 连接失败,优先检查端口是否被防火墙拦截、令牌是否复制完整(首尾空格会导致认证失败)。在 ThingsBoard 中,设备连接状态可在“设备详情 → 最新遥测”或“活动”中观察,成功上报后会出现时间戳。
三、遥测数据上报与属性发布订阅
遥测(Telemetry)是随时间变化的时序数据,如温度、湿度、电压;属性(Attributes)是相对稳定的键值对,分客户端属性(设备上报)、共享属性(平台下发)和服务端属性(平台维护)。发布遥测时,向 v1/devices/me/telemetry 发送 JSON 即可:
{
"temperature": 26.5,
"humidity": 58,
"ts": 1718000000000
}
其中 ts 为毫秒时间戳,可省略,省略时平台以接收时间入库。若一次上报多个时间点,可用数组形式:[{"ts":1718000000,"values":{"temperature":26.5}}, ...]。发布属性则向 v1/devices/me/attributes 发送:
{
"firmwareVersion": "1.2.0",
"active": true
}
订阅共享属性时,设备先向 v1/devices/me/attributes/request/1 发布空消息或指定键列表,再订阅 v1/devices/me/attributes/response/+ 接收响应。响应 JSON 中 shared 字段即平台下发的共享属性。RPC 场景下,设备订阅 v1/devices/me/rpc/request/+,收到命令后向 v1/devices/me/rpc/response/$request_id 回复执行结果。
四、使用 MQTTBox 或 mosquitto 联调
联调的目标是验证“认证通过 → 数据入库 → 平台可见”这条链路。以 mosquitto 命令行客户端为例,先发布一条遥测:
mosquitto_pub -h 192.168.1.100 -p 1883 \
-u a1b2c3d4e5f6g7h8i9j0 -P "" \
-t v1/devices/me/telemetry \
-q 1 \
-m '{"temperature":26.5,"humidity":58}'
若返回无错误且平台“最新遥测”出现 temperature=26.5,说明认证与上报均正常。接着订阅 RPC 主题验证下行:
mosquitto_sub -h 192.168.1.100 -p 1883 \
-u a1b2c3d4e5f6g7h8i9j0 -P "" \
-t v1/devices/me/rpc/request/+ -q 1 -v
在平台设备详情点击“RPC 调试”,发送 {"method":"setSwitch","params":true},订阅端应收到 v1/devices/me/rpc/request/1 {"method":"setSwitch","params":true}。此时再向 v1/devices/me/rpc/response/1 发布 {"success":true},平台侧即完成一次双向交互。MQTTBox 的操作逻辑相同,只是把上述参数填入图形界面的 Host、Port、Username、Topic 字段,并选择对应 QoS。
五、联调检查表
| 检查项 | 正确取值 / 判断依据 | 常见错误 |
|---|---|---|
| Broker 地址与端口 | 平台 IP,1883 或 8883 | 误用 8080 或 1884 |
| Username | 设备访问令牌原文 | 首尾含空格、复制不全 |
| Password | 留空 | 误填令牌 |
| 遥测主题 | v1/devices/me/telemetry | 大小写或路径拼错 |
| QoS | 遥测建议 1 | 使用 2 造成额外开销 |
| JSON 格式 | 合法对象或数组 | 单引号、尾逗号 |
| 结果确认 | 设备详情出现最新遥测时间戳 | 只看客户端无报错 |