直连设备协议
本页是直连设备的 MQTT 协议参考:连接认证、遥测与属性上报的主题、报文格式与边界行为。操作入门版(带截图)见《直连设备上报数据》。
一、连接
Broker: 平台 MQTT 地址,端口 1883
UserName: 设备 Access Token
Password: 留空
ClientID: 全局唯一(建议直接用令牌)认证失败的统一表现与排查见《接入总览》。连接建立与断开都会被平台感知:连上即"在线",断开即"离线"——设备端不需要(也无法)上报自己的上下线状态。
二、遥测上报
主题
v1/devices/me/telemetry注意主题为复数 devices,me 表示"当前设备"(设备身份由连接时的令牌决定,报文里无需再带设备标识)。发布即可,无需订阅。
报文格式(三选一)
格式一:带时间戳(推荐)
json
{
"ts": 1735689600000,
"values": {
"temperature": 25.3,
"humidity": 60
}
}格式二:数据点数组
json
[
{ "temperature": 25.3 },
{ "humidity": 60 }
]数组元素也可以各自带 ts 与 values,平台按元素逐个处理。
格式三:扁平键值
json
{ "temperature": 25.3, "humidity": 60 }格式细节
| 细节 | 行为 |
|---|---|
ts | 毫秒时间戳,可省略;格式二/三整体不带 ts 时,全部数据点按服务器接收时间入库 |
| 多字段 | 同一报文内的多个字段作为同一时刻的多个数据点入库 |
| 值类型 | 支持数字、字符串、布尔;类型由值自动推断 |
| 嵌套对象 | 顶层字段值支持 JSON 对象/数组,按 json 类型存储 |
| 解析失败 | 非法 JSON、空报文被静默丢弃,无错误回执 |
上报节奏建议
- 上报频率由业务决定,但总量受租户每日消息配额约束:消息数 ≈ 设备数 × 每日报文数,超配额后当日报文被丢弃;
- 短间隔重复值建议设备端做本地阈值过滤(变化才报),既省配额又减少噪音。
三、属性上报
主题
v1/devices/me/attributes报文格式
扁平键值对象:
json
{ "firmwareVersion": "1.2.0", "location": "1号车间", "installedAt": "2026-01-15" }与遥测的区别
| 遥测 | 属性 | |
|---|---|---|
| 定位 | 随时间变化的测量数据 | 相对稳定的状态描述 |
| 存储 | 每条数据点独立存入时序库 | 同名字段只保留最新一个值(upsert) |
| 平台展示 | 实时数据卡片、历史曲线 | 设备详情的"客户端属性"标签页 |
| 适合放什么 | 温度、电压、流量…… | 型号、固件版本、安装位置…… |
属性类型同样自动推断:布尔 → Boolean、字符串 → String、整数 → Long、小数 → Double、对象/数组 → Json;值为 null 的字段会被忽略。
使用建议
- 属性适合低频更新的状态信息:设备启动时上报一次版本信息,升级后再报一次,不要每分钟报一次版本号;
- 需要画曲线、看趋势的数据一律走遥测。
四、设备在线状态
平台自动维护在线状态,设备端无需处理:
| 事件 | 平台行为 |
|---|---|
| MQTT 连接成功 | 状态置为在线,记录最后连接时间 |
| MQTT 连接断开(主动或网络断开) | 状态置为离线 |
| 每次成功上报 | 刷新"最后活跃"时间 |
注意:数据上报不会把离线设备改为在线——在线状态只由 MQTT 连接驱动。如果设备在线但未上报,"最后活跃"会停留在旧时间,这是判断"连接活着但程序卡死"的重要信号。
五、最小可用示例
以 Python 为例(多语言完整示例见《示例代码》):
python
import json, time
import paho.mqtt.client as mqtt # pip install paho-mqtt>=2.0
TOKEN = "设备 Access Token"
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=TOKEN)
client.username_pw_set(TOKEN) # 用户名 = 令牌,密码留空
client.connect("平台 MQTT 地址", 1883, keepalive=60)
client.loop_start()
client.publish(
"v1/devices/me/telemetry", # 复数 devices
json.dumps({"ts": int(time.time() * 1000),
"values": {"temperature": 25.3}}),
qos=1,
)下一步:网关与子设备的接入,请看《网关设备协议》;需要平台下发控制指令,请看《设备 RPC》。