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 MQTT 设备接入数据流 设备 / MQTT 客户端 ClientId: tb-dev-01 Username: 访问令牌 Password: 空 ThingsBoard MQTT Broker 端口 1883 / 8883 认证:访问令牌校验 主题解析与路由 QoS 0 / 1 / 2 平台内部 遥测存储 属性更新 规则链处理 CONNECT PUBLISH telemetry 解析入库 SUBSCRIBE rpc/request/+ 常用主题与方向 v1/devices/me/telemetry 设备 → 平台(发布遥测) v1/devices/me/attributes 设备 → 平台(发布属性) v1/devices/me/rpc/request/+ 平台 → 设备(下发 RPC) v1/devices/me/attributes/response/+ 平台 → 设备(共享属性响应)

二、设备连接认证:访问令牌与凭据配置

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。

联调排查顺序建议:先确认 TCP 端口可达(telnet 或 nc),再确认令牌正确,然后确认主题拼写与大小写完全一致,最后检查 JSON 是否为合法格式。多数“连不上”或“数据不显示”都出在这四步中的某一步。

五、联调检查表

检查项正确取值 / 判断依据常见错误
Broker 地址与端口平台 IP,1883 或 8883误用 8080 或 1884
Username设备访问令牌原文首尾含空格、复制不全
Password留空误填令牌
遥测主题v1/devices/me/telemetry大小写或路径拼错
QoS遥测建议 1使用 2 造成额外开销
JSON 格式合法对象或数组单引号、尾逗号
结果确认设备详情出现最新遥测时间戳只看客户端无报错