Skip to content

网关设备协议 ​

本页是网关类设备的 MQTT 协议参考:网关如何代表子设备上报数据、通知上下线。操作入门版见《网关设备上报数据》。

一、角色模型 ​

平台 ◀── 一条 MQTT 连接(网关令牌认证)── 网关 ──现场总线── 子设备 xN
  • 网关:设备类型为"网关设备"的平台建档实体,是唯一连接平台的角色;
  • 子设备:在平台建档为普通设备并挂在网关下,不连接平台、无令牌;
  • 数据归属:报文里的子设备外部 ID 决定数据记在哪台子设备名下。

网关自己有传感器数据时,用《直连设备协议》的 v1/devices/me/telemetry 上报,数据记在网关名下;子设备数据一律走 v1/gateway/... 主题。

二、子设备上报的前置条件 ​

平台按「网关 + 外部 ID」定位子设备,因此:

  1. 子设备必须先在平台建档(挂在该网关下);
  2. 建档时的外部 ID 必须与报文里的设备名完全一致(平台仅忽略首尾空格,内部空格、大小写、下划线都必须一致);
  3. 同一网关下外部 ID 不可重复。

未建档或名字对不上的子设备报文会被跳过(平台记录日志),同一批报文里的其他子设备不受影响——这个隔离设计让一台子设备的配置错误不至于拖垮整个网关。

三、子设备遥测 ​

主题 ​

v1/gateway/telemetry

报文格式 ​

顶层是「子设备外部 ID → 数据点数组」的字典,一条报文可同时带多台子设备、多个数据点:

json
{
  "Device A": [
    { "ts": 1735689600000, "values": { "temperature": 42, "humidity": 55 } }
  ],
  "Device B": [
    { "ts": 1735689600000, "values": { "temperature": 38 } },
    { "ts": 1735689660000, "values": { "temperature": 39 } }
  ]
}
要素说明
顶层键子设备外部 ID(即建档时填写的名称标识)
值必须为数组,每个元素是一个数据点
数据点{ "ts": 毫秒时间戳, "values": { 字段: 值 } };ts 可省略,按平台接收时间入库
字段名规则与直连设备一致:原样存储、类型保持一致
处理粒度平台逐台子设备、逐个数据点处理;单点失败不影响其余

四、子设备属性 ​

主题 ​

v1/gateway/attributes

报文格式 ​

顶层是「子设备外部 ID → 属性字典」,值为对象(不包数组):

json
{
  "Device A": { "firmwareVersion": "2.1", "protocol": "modbus-rtu" },
  "Device B": { "firmwareVersion": "1.0" }
}

属性按子设备 upsert,只保留每个字段的最新值,规则与直连设备属性一致。

五、子设备上下线通知 ​

主题与报文 ​

v1/gateway/connect      子设备上线
v1/gateway/disconnect   子设备下线

报文:{ "device": "Device A" }

device 填子设备外部 ID。平台据此更新对应子设备的连接状态。

使用建议 ​

  • 子设备首次上报数据前先发一次 connect,让状态先于数据变为在线;
  • 子设备从现场总线上消失时发 disconnect;
  • 不需要为每条数据报文重复发送上下线通知。

子设备在线状态的连带规则 ​

事件平台行为
网关连接成功仅网关自身置在线(子设备状态不受影响)
网关断开连接该网关名下所有子设备一并置为离线
收到 connect/disconnect对应子设备置在线/离线

子设备的在线状态始终跟随网关:网关掉线后,即使子设备还在总线上活着,平台也一律显示离线——因为平台已无法从网关获取它们的数据。设备端无需为此做任何补偿逻辑。

六、配额与频率 ​

  • 每个子设备的每个数据点都计入该子设备所属租户的每日消息配额(子设备与租户同属一家,通常即网关的租户);
  • 配额耗尽时丢弃发生在单台子设备、单条数据点粒度,不会因一台子设备超限影响其他子设备。

七、最小可用示例 ​

python
import json, time
import paho.mqtt.client as mqtt          # pip install paho-mqtt>=2.0

GW = "网关设备的 Access Token"
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=GW)
client.username_pw_set(GW)
client.connect("平台 MQTT 地址", 1883, keepalive=60)
client.loop_start()

now = int(time.time() * 1000)

# 1) 子设备上线
client.publish("v1/gateway/connect",
               json.dumps({"device": "Device A"}), qos=1)

# 2) 子设备遥测(可多台子设备一条报文)
client.publish("v1/gateway/telemetry", json.dumps({
    "Device A": [{"ts": now, "values": {"temperature": 42}}],
}), qos=1)

# 3) 子设备属性
client.publish("v1/gateway/attributes", json.dumps({
    "Device A": {"firmwareVersion": "2.1"},
}), qos=1)

下一步:从平台向网关/子设备下发控制指令,请看《设备 RPC》。