网关设备上报数据
当现场设备数量多、通信方式各异时,通常由一台网关统一汇聚数据,再由网关连接平台。本章介绍网关与子设备的数据上报规则。
一、角色分工:谁连平台,谁上报
| 角色 | 是否连接平台 | 使用凭证 |
|---|---|---|
| 网关 | 连接 | 网关自己的 Access Token |
| 子设备 | 不连接平台 | 无需令牌,由网关代为上报 |
也就是说:网关只建立一条 MQTT 连接,其下所有子设备的数据都通过网关转发,平台按子设备的外部 ID自动区分数据归属。
二、前置条件:子设备必须先建档
这是网关接入最容易出错的一点,请务必先完成:
- 在平台「设备台账」中创建网关设备(设备类型选择网关设备)并取得网关令牌;
- 在该网关下逐台创建子设备:设备类型选普通设备,"所属网关"选择该网关,外部 ID 必填;
- 子设备的外部 ID,必须与网关上报报文里的设备名完全一致(平台会自动去掉首尾空格,但内部的空格、大小写、下划线必须一致)。
未在平台建档的子设备,其报文会被直接跳过(平台记录日志告警),同一批报文里的其他子设备不受影响。此外,同一网关下外部 ID 不可重复。


三、上报主题
| 用途 | 主题 |
|---|---|
| 子设备遥测数据 | v1/gateway/telemetry |
| 子设备上线通知 | v1/gateway/connect |
| 子设备下线通知 | v1/gateway/disconnect |
网关自己也有采集数据时,用直连设备的主题上报;子设备的数据一律走 v1/gateway/... 主题。
四、报文格式
子设备遥测
顶层是"子设备外部 ID → 数据点数组"的结构,一条报文可以同时上报多台子设备:
json
{
"Device A": [
{ "ts": 1735689600000, "values": { "temperature": 42, "humidity": 55 } }
],
"Device B": [
{ "ts": 1735689600000, "values": { "temperature": 38 } },
{ "ts": 1735689660000, "values": { "temperature": 39 } }
]
}- 键名(
Device A、Device B)就是子设备的外部 ID,必须与平台建档时填写的一致。 - 每台子设备对应的值是数组,数组里每个元素是一个数据点,均含
ts与values。 ts可省略,省略时按平台收到报文的服务器时间记录。- 字段名规则与直连设备一致:平台不做映射,上报什么名字就显示什么名字。
子设备上/下线
json
{ "device": "Device A" }网关感知到子设备接入或断开时,分别向 v1/gateway/connect、v1/gateway/disconnect 发送该报文,平台据此更新对应子设备的连接状态。建议在子设备首次上报数据前先发一次上线通知。
另外,网关本身断开连接时,平台会把该网关名下所有子设备一并置为离线,不会出现"网关已掉线、子设备还显示在线"的情况。因此子设备的在线状态始终跟随网关,无需设备端额外维护。
五、上报示例(Python)
python
import json, time
import paho.mqtt.client as mqtt # pip install paho-mqtt>=2.0
GATEWAY_TOKEN = "网关设备详情页复制的 Access Token"
BROKER = "平台 MQTT 地址"
PORT = 1883
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=GATEWAY_TOKEN)
client.username_pw_set(GATEWAY_TOKEN) # 只需用户名,密码留空
client.connect(BROKER, PORT, keepalive=60)
client.loop_start()
now = int(time.time() * 1000)
# 1) 先通知平台:子设备上线
client.publish("v1/gateway/connect", json.dumps({"device": "Device A"}), qos=1)
# 2) 再上报子设备数据(一条报文可带多台子设备)
payload = {
"Device A": [{"ts": now, "values": {"temperature": 42, "humidity": 55}}],
"Device B": [{"ts": now, "values": {"temperature": 38}}],
}
client.publish("v1/gateway/telemetry", json.dumps(payload), qos=1)
time.sleep(1)
client.loop_stop()
client.disconnect()六、常见问题
| 现象 | 排查方向 |
|---|---|
| 只有部分子设备有数据 | 这些子设备未在平台建档,或报文里的设备名与外部 ID 不一致(注意空格与大小写) |
| 全部子设备都无数据 | 网关自身是否在线;网关用的是否为网关设备类型(普通设备发的网关报文会被忽略) |
| 子设备显示离线但数据在刷新 | 未发送上线通知(数据上报只刷新"最后活跃",不会把状态改为在线) |
| 某台子设备数据时断时续 | 该子设备的报文格式有误;平台按台逐个处理,坏报文只影响它自己 |
| 数据量大了之后不再入库 | 租户每日消息量达到上限,超限部分被丢弃,请联系平台管理员 |
下一步:想让客户直接查看这些设备,请参考《客户与设备分配》。