网关(4G)物模型 API

基于MQTT协议接入云平台, 版本V1.1
本协议面向「4G 网关(下位机)+ 其代理的子设备 + MQTT 云平台」的上行数据上报与下行命令通道。

智能鱼塘养殖
具体划分哪些子系统

(增氧 / 水质监测 / 投喂 / 换水 / 储能多能互补)。

智能设备品类汇总:

品类 名称 状态
rly4p3 4 组 × 3 相继电器开关 已上线(不改动)【必须】
gw4g 4G 网关-设备上网代理中枢 新增
wq8in1 / wq4in1 八合一 / 四合一水质仪 完善 / 新增
ems 储能能量管理系统 完善
vfd 增氧机变频器(变频闭环) 新增
feed 投饵机 新增
pump 水泵(换水 / 循环) 新增
gate 电动闸门 / 电动阀 新增
wlevel 水位计 新增
wxst 气象站 新增
pv 光伏 MPPT 控制器 新增
gen 柴油发电机 新增
pmet 配电 / 电表监测 新增
cam AI 视觉盒(浮头 / 死鱼 / 生长) 预留

gw4g 品类补充说明
gw4g(4G 网关-设备上网代理中枢),
网关定位是子设备上网的代理通道,它不是业务上的功能设备。
而是帮助其它功能设备上网。

  1. 纯转发:只负责代理子设备上云、转发子设备的上行数据与下行命令,本身不产生业务数据;
  2. 网络配置由产品方专属工具管理:4G 卡 / APN / 心跳 / MQTT 连接参数、
    主题前缀等由产品方小工具(配网 / 调试工具)配置下发,第三方平台无需处理;
  3. 第三方平台可不处理 gw4g(可选处理):网关自身的 status / data(信号、SIM、缓存、
    子设备清单等)仅作网关级监控与运维,忽略不影响业务;
  4. 直接按子设备身份收数据:第三方平台只须依据子设备的身份信息(sn / product_id /
    完整标识 sn.product_id)订阅对应主题,即可直接接收子设备数据,无需关心网关内部结构。

补充约定:子设备报文中的 gw4g_sn 字段仅供平台侧(可选)做网关归集与路由,非业务必需;
网关换卡 / 换机 / 重启不影响子设备的主题与数据通道。

核心概念:

本版范围(重要,请先读):

  1. 本 API 只描述「下位机网关(4G 控制器)及其代理的子设备」 的接入与物模型;不覆盖平台内部、
    APP / 小程序 / 第三方系统之间的接口(那部分走平台开放 API,另行定义)。
  2. 网关本体也按一个品类建模(gw4g,见 7.2)。
    一个 MQTT 连接 = 一个 4G 网关(client_id = XXXX-XXXX-XXXX.gw4g,即网关 MAC 6 字节 Hex);
    网关下每台子设备(传感器 / 执行器 / 储能 / 配电等)各占一个 sn.product_id、各自一组主题、
    各自独立 JSON。
  3. rly4p3(原名 relay4)为客控现网定义,字段字典不改(6.2 / 6.3 / 7.1 仅同步改名),
    仅以「改进建议」形式给出意见, 汇总见 7.1 注与第 13 章清单;
    其余品类(ems / wq8in1 及新增品类)为规划产品,本版已直接完善。
  4. 一个 JSON 报文只描述一台设备(一个 sn)的一次数据(属性快照),不做多设备拼接。

0. 版本与修订记录

版本 日期 修订内容
v1.0 2026-09-20 初版:rly4p3 客控定义 + wq8in1 / ems 规划
v1.1 2026-09-21 ① 补齐 MQTT 接入与管理:Keepalive / LWT / 重连 / 会话 / 离线补传;② 新增公共字段字典与网关本体品类 gw4g;③ 完善 wq8in1、ems(量程 / 精度 / 可写点 / 状态机);④ 新增 vfd feed pump gate wlevel wxst pv gen pmet cam 品类;⑤ 新增命令闭环 ack、事件 event、配置 config、OTA、日志 log 通道与报文;⑥ relay4 改名 rly4p3(字典不动),附改进建议(见 7.1、13);⑦ 补充第 13 章遗漏点清单;⑧ 执行反馈类型 ack 更名 cmd_result(按现场实测报文统一,见 5.2 / 6.7)
v1.2 2026-09-24 物模型字段名规范化(见 7.0-7):新增字段统一 ≤10 字符、同概念跨品类同名;dissolved_oxygen → oxygen(rly4p3 / wq8in1 同步);客户平台已用的字段名一律不改,rly4p3 的 air_pressure(12 字符)即为此类,永久保留;同步更新 6.2 / 6.3 / 6.10 示例、第 8 章规则示例与各品类字典

1. 总体架构

 ┌──────────────┐    TCP:1883      ┌─────────────────┐
 │  4G 网关/设备 │ ──────────────▶ │  MQTT Broker    │ ─▶ 云平台/应用
 │ (多品类/多设备)│ ◀────────────── │  puzhizhineng.com│ ◀─ 应用下发 cmd
 └──────────────┘     订阅 cmd     └─────────────────┘
     │
     │ 品类 rly4p3(4组三相开关,下挂多台设备)
     ├─ sn=sz0001 → 主题 aqua/sz0001.rly4p3/{up,cmd}
     ├─ sn=sz0002 → 主题 aqua/sz0002.rly4p3/{up,cmd}
     │ 品类 wq8in1(八合一水质传感器,下挂多台设备)
     ├─ sn=sz0012 → 主题 aqua/sz0012.wq8in1/{up,cmd}
     │ 品类 ems(储能管理系统,下挂多台设备)
     └─ sn=sz0005 → 主题 aqua/sz0005.ems/{up,cmd}

关键概念:

概念 说明 示例
品类 product_id 一类产品(如 4 组三相开关、八合一水质传感器、储能管理系统),决定该设备上报的字段字典 rly4p3、wq8in1、ems
设备 sn 品类下的具体设备序列号,全局唯一(不同品类也不会重复) sz0001、sz0002
完整标识 sn.product_id 主题中间段与 JSON sn 字段使用的组合标识,全局唯一 sz0001.rly4p3

关系:一个 product_id(品类)下有多台设备(多个 sn);
一台 4G 网关可挂 多个品类(多个 product_id)的设备。因为 sn 全局唯一,
所以 sn.product_id 组合也必然唯一,主题与 JSON 不冲突。


1.1 本版架构定位(网关 = 下位机,子设备 = 代理对象)

 ┌──────────────────────────┐   TCP:1883 (QoS1)   ┌─────────────────┐
 │ 4G 网关(下位机)         │ ──────────────────▶ │  MQTT Broker    │ ─▶ 云平台/应用
 │ client_id=<MAC>.gw4g     │ ◀────────────────── │ puzhizhineng.com│ ◀─ 应用下发 cmd
 │ └─ 代理子设备(各占主题)  │      订阅 cmd       └─────────────────┘
  │    ├─ gw4g 网关本体   → aqua/<gw4g_sn>.gw4g/{up,cmd,...}  (网关自身状态)
  │    ├─ rly4p3 三相开关 → aqua/sz0001.rly4p3/{up,cmd}  (客控现网)
  │    ├─ wq8in1 水质   → aqua/sz0012.wq8in1/{up,cmd}
  │    ├─ wq4in1 水质   → aqua/sz0013.wq4in1/{up,cmd}
  │    ├─ ems 储能      → aqua/sz0005.ems/{up,cmd}
  │    ├─ vfd 增氧变频 → aqua/sz0021.vfd/{up,cmd}
 │    └─ ... 其它子设备
 └──────────────────────────┘

要点:


2. 配置MQTT连接

连接配置相关参数:

项 值 说明
服务器(Broker) puzhizhineng.com 云平台 MQTT 服务器
端口 1883 MQTT over TCP
协议 MQTT TCP 无 TLS
TLS 关闭 —
账号 / 密码 不需要(匿名) 也可支持,见第 9 节扩展
Client ID 0025-CA3B-6F01.gw4g 代理网关(4G 网关)的连接层标识,即网关的 dev_id,与子设备无关:格式 XXXX-XXXX-XXXX.gw4g,12 个 X = 网关 MAC 6 字节的 Hex 值(按 2 字节分 3 组)
QoS 1 至少一次,配合业务去重
Retain false 默认不保留

连接层建议:Client ID 直接用代理网关(4G 网关)的 dev_id(参考 at4g 设备码 dev_id),
格式 XXXX-XXXX-XXXX.gw4g:网关 MAC 6 字节 Hex(按 2 字节分 3 组)+ .gw4g 后缀,
如 MAC 00:25:CA:3B:6F:01 → 0025-CA3B-6F01.gw4g;与 BLE 配置通道 info 回复的 dev_id 一致。
要点:Client ID 是「整台代理网关」的连接层标识,与具体设备的业务定义无关——一台网关下代理的
所有子设备共用同一个 Client ID,
子设备之间靠各自的主题 <sn.product_id> 与 JSON sn 字段区分(见 3.3 / 3.4)。
这样 Broker 侧便于统计与 ACL 控制。


2.1 连接管理参数(v1.1 补充,未改动上表)

项 值 说明
MQTT 版本 3.1.1(兼容 3.1) 建议固定 3.1.1
Keepalive 60 s 心跳保活;Broker 侧 3 个周期(180s)无消息判离线,见 9.3
遗嘱 LWT 主题 aqua/<gw4g_sn>.gw4g/up,Payload {"type":"status","sn":"<gw4g_sn>.gw4g","online":false},QoS1,Retain=false 异常掉线自动上报离线
Clean Session true(默认短会话) 离线缓存由设备侧自管理(见 9.5),不强依赖 Broker 会话
自动重连 指数退避 5s→60s 封顶 + 随机 ±30% 抖动 无限重试;恢复后补状态 + 补传 + 校时
上行 QoS 1 至少一次,配合 msg_id 业务去重(见 5.5)
下行 QoS 1 命令不丢;应答走 cmd_result 闭环(见 6.7 / 9.6)
Retain false 默认不保留

2.2 连接时序(上线流程)

 网关上电 → 初始化(RS485/传感器/子设备) → 连接 Broker
   → ① 上报网关本体 status(online=true, fw, signal, devices 清单)  主题 aqua/<gw4g_sn>.gw4g/up
   → ② 各子设备依次 status(online=true)                             主题 aqua/<sn>.<product_id>/up
   → ③ 周期上报 data + 心跳(Keepalive)
   → ④ 正常下线: status(online=false) → DISCONNECT
   → ⑤ 异常掉线: Broker 依据 LWT 标记离线(网关与全部子设备)

3. 对象层级管理

3.1 身份层级

product_id(品类 / 产品标识,如 rly4p3)
   └── sn(设备序列号,该品类下的多台设备,全局唯一)
          └── 完整标识 = sn + "." + product_id(主题与 JSON `sn` 字段,全局唯一)

3.2 身份字段一览

字段 所在层 含义 是否身份字段 示例 必填
product_id JSON(可选)/ 主题 品类标识(决定字段字典),一个品类下有多台设备 是 rly4p3 推荐
sn(设备序列号) JSON(可选)/ 主题 品类下的具体设备,全局唯一 是 sz0001 推荐
完整标识 sn.product_id JSON sn 字段 / 主题 主题中间段与 JSON sn 字段的值,全局唯一 是 sz0001.rly4p3 必填
client_id MQTT 连接层(网关级) 代理网关(4G 网关)的 dev_id = 网关 MAC Hex(12 位,2-2-2 分组)+ .gw4g;不等于子设备的 sn.product_id,一台网关只有一个 是(网关身份) 0025-CA3B-6F01.gw4g 连接层
type JSON 报文类型(status / data / 扩展) 否 data 必填
timestamp JSON 公共通信参数:报文生成/发送时间(ISO8601 带时区),非物模型字段 否 2026-09-20T17:36:50+08:00 推荐

术语说明:概念上的「设备序列号 sn」与 JSON 里的 sn 字段名称相同,
但 JSON 的 sn 字段存放的是完整标识 sn.product_id(与主题中间段一致)。需要显式区分时,
可在 JSON 中附上 device_sn(设备序列号)与 product_id(品类)两个字段。

身份字段判定:能回答「哪类产品、哪台设备、哪个实例」的字段即为身份字段。 type、
timestamp 描述的是报文本身,不标识设备,故不算身份字段。

3.3 身份在「主题 / JSON」中的体现

位置 身份写法 示例
发布主题 aqua/<sn.product_id>/up aqua/sz0001.rly4p3/up
订阅主题 aqua/<sn.product_id>/cmd aqua/sz0001.rly4p3/cmd
Client ID(连接层 / 网关级) 代理网关 dev_id = 网关 MAC Hex + .gw4g(XXXX-XXXX-XXXX.gw4g),不是 sn.product_id 0025-CA3B-6F01.gw4g
JSON sn 字段 sn.product_id "sn":"sz0001.rly4p3"
JSON 拆分字段 device_sn / product_id 分别给出 "device_sn":"sz0001","product_id":"rly4p3"

推荐发送方同时给出 sn(完整标识)与拆分的 device_sn /
product_id: 服务端订阅 aqua/+/up 通配时,仅凭 sn 也能拆出设备与品类;
拆字段便于按 product_id 路由到对应品类解析器。

Client ID 特别说明:Client ID 属 MQTT 连接层,
标识的是代理网关本身(由网关 MAC 推导出的 dev_id), 与「哪台设备、哪个品类」无关;
一台 4G 网关代理的全部子设备共用同一个 Client ID,
子设备 / 品类的区分只发生在主题中间段与 JSON sn 字段(sn.product_id)。
因此 Client ID ≠ sn.product_id(详见第 2 节与 3.4)。


3.4 网关身份与子设备身份(v1.1 补充)

层 身份写法 示例
连接层(网关) client_id = 网关 dev_id(网关 MAC Hex,2-2-2 分组 + .gw4g) 0025-CA3B-6F01.gw4g
网关本体(品类 gw4g) <gw4g_sn>.gw4g(gw4g_sn = 网关 MAC 去横线) 0025CA3B6F01.gw4g
代理子设备 sn.product_id sz0001.rly4p3、sz0012.wq8in1

4. 主题设计

4.1 主题基本规律与规则

主题固定三段:<域> / <sn.product_id> / <动作>,动作只有 up / cmd 两个。

aqua / <sn>.<product_id> / up    设备 → 平台(status / data / event / cmd_result / log 等,靠 type 区分)
aqua / <sn>.<product_id> / cmd   平台 → 设备(cmd / config / ota 等,靠 type 区分)
段 取值 说明
域 aqua 固定前缀,可区分业务 / 租户
中间 <sn>.<product_id> 完整标识,sn 为设备序列号、product_id 为品类
动作 up / cmd 上行统一 up / 下行统一 cmd;具体报文用 type 字段区分

各类业务报文均发布到各自设备的 /up(上行)或 /cmd(下行),
靠 JSON type 字段区分(type 定义见 5.2 / 12.1)。

up / cmd 动作说明

动作 方向 用途 承载 type
up 设备→平台 所有上行(状态 / 数据 / 事件 / 应答 / 日志) status data event cmd_result log err ...
cmd 平台→设备 所有下行(命令 / 配置 / OTA) cmd config ota ...

4.2 一个品类下多台设备 → 多组主题

品类 rly4p3 下有两台设备 sz0001、sz0002,则各有其主题:

品类 product_id 设备 sn 完整标识 发布主题 订阅主题
rly4p3 sz0001 sz0001.rly4p3 aqua/sz0001.rly4p3/up aqua/sz0001.rly4p3/cmd
rly4p3 sz0002 sz0002.rly4p3 aqua/sz0002.rly4p3/up aqua/sz0002.rly4p3/cmd
ems sz0005 sz0005.ems aqua/sz0005.ems/up aqua/sz0005.ems/cmd

同一品类(rly4p3)的多台设备共享同一份字段字典,只是 sn / 主题不同; 一台 4G 网关挂多个品类时,
各设备按各自的 sn.product_id 分别走各自主题。

4.3 扩展方式(主题固定,按 type 扩展)

主题动作固定只有 up / cmd 两个,不再新增动作段;
新的业务类型(事件、应答、日志、OTA 等)一律通过报文的 type 字段扩展(见 5.2)。

方向 主题动作 承载的 type 状态
设备→平台 up status / data / event / cmd_result / log / err ... 已启用
平台→设备 cmd cmd / config / ota ... 已启用

扩展只需在 5.2 的 type 表中新增小写 type 值即可,不改变既有主题结构,向后兼容。


4.4 平台侧通配订阅

通配 用途
aqua/+/up 全部上行(status / data / event / cmd_result / log 等,靠 type 区分)
aqua/+/cmd 全部下行(cmd / config / ota 等,靠 type 区分)

平台解析 sn 字段即得设备与品类;
再按 type 分派处理、按 product_id 分派到对应品类解析器。


5. JSON 报文结构

5.1 通用骨架

每个上行报文由 4 段组成:

{
  "type":       "<类型段>",
  "sn":         "<完整标识段 sn.product_id>",
  "device_sn":  "<设备序列号段-可选>",
  "product_id": "<品类段-可选>",
  "<业务数据段...>",
  "timestamp":  "<时间戳段>"
}
段 字段 类型 必填 说明
类型段 type string 是 报文类型,取值见 5.2,开放扩展
完整标识段 sn string 是 sn.product_id,设备 + 品类的完整标识,全局唯一
设备序列号段(可选) device_sn string 推荐 设备序列号 sn,显式拆分便于路由
品类段(可选) product_id string 推荐 品类标识,决定业务字段字典
业务数据段 (随品类而定) number / string / bool 按品类 见各品类物模型字典,示例见第 6 节
时间戳段 timestamp string 建议 ISO8601 带时区,如 2026-09-20T17:36:50+08:00

5.2 type 取值定义(开放扩展)

type 方向 含义 典型报文 状态
status 设备→平台 上下线状态、设备健康信息 开机上报、掉线上报 已启用
data 设备→平台 设备属性数据(业务数据快照) 周期上报采样值 已启用
event 设备→平台 事件 / 告警 超温告警(规范见 6.8) 已启用(v1.1)
cmd_result 设备→平台 命令 / 配置执行结果反馈(配合 cmd / config) 执行结果回执(实测协议,规范见 6.7 / 6.9) 已启用(v1.1)
log 设备→平台 运行日志 关键日志 预留(v1.1 定骨架)
cmd 平台→设备 命令下发 下行通道,结构另行约定 下行使用
config 平台→设备 参数 / 规则 / 上报周期下发 配置下发(规范见 6.9) 已启用(v1.1)

type 扩展规则:

  1. type 使用小写字母与下划线(如 ota_start),新增值不修改既有字段结构;
  2. 平台对未知 type 不得丢弃整个报文,应按通用骨架解析身份与时间戳后记录;
  3. 扩展类型仍必须携带 sn 与 timestamp,保证身份与时间可追溯;
  4. 新增类型需同步更新本表与对应品类字典(见第 7 节)。
  5. 所有 type 均走统一主题:设备→平台发布到 <sn.product_id>/up,平台→设备下发到 <sn.product_id>/cmd。

cmd_result 即当前实测使用的执行反馈类型(v1.1 草案里叫 ack,现统一改名 cmd_result),
字段以实测报文为准:request_id + success / message,可选回显 cmd / seq / code。

5.3 字段类型约定

数据类型 说明 示例
number 数值(整数 / 浮点),用于温度、压力、电压等 25.6、101.3
boolean 布尔,用于开关状态 true / false
string 字符串,用于标识、状态文本、序列号 "sz0001.rly4p3"
timestamp 字符串 ISO8601 带时区 "2026-09-20T17:36:50+08:00"

单位约定(建议):温度 ℃、气压 hPa、电压 V、电流 A、功率 kW、能量 kWh、频率 Hz、 溶解氧 mg/L、
氨氮/亚硝酸盐 mg/L、电导率 μS/cm、浊度 NTU、pH 无量纲、信号强度 dBm。 各品类的具体字段名、单位、
量程由各自的物模型字典定义(见第 7 节)。


5.4 通用字段补充(v1.1 新增,未改动 5.1 骨架)

字段 类型 必填 说明
msg_id string 否 报文去重 ID(建议 sn+seq 拼接),配合 QoS1 去重
seq number 条件 每设备单调递增序号(0~65535 环形);下行 cmd 必带,上行 cmd_result 回显同一 seq
source string 否 指令来源:app / cloud / auto(供本地仲裁,见 8.5)
gw4g_sn string 否 所属网关 sn(多网关场景便于平台路由)
collect_ts string 否 采集时间(离线补传时与 timestamp 分离,见 9.5)
cache boolean 否 true = 离线缓存补传报文

5.5 去重与序号

5.6 时间戳规范


6. 报文示例

6.1 ~ 6.6 为 v1.0 原文(rly4p3 客控相关,结构未改动;仅 v1.2 把溶氧字段 dissolved_oxygen 改名 oxygen,见 7.1)。6.5 event、
6.6 cmd 在 v1.1 中升级为正式通道, 完整规范见 6.7 / 6.8;6.6 为单向示例,
真实下发走 6.7 的 seq + cmd_result 闭环。

6.1 status — 上线 / 下线

设备开机后先上报上线,online 为必填;其余为可扩展的健康字段。

最简单形式:

{"type":"status","sn":"sz0001.rly4p3","online":true}

带扩展信息(运行时长、固件版本、IP):

{
  "type": "status",
  "sn": "sz0001.rly4p3",
  "device_sn": "sz0001",
  "product_id": "rly4p3",
  "online": true,
  "uptime_s": 3600,
  "fw": "1.0.0",
  "ip": "10.0.0.8",
  "timestamp": "2026-09-20T17:36:50+08:00"
}

字段说明:

字段 类型 必填 说明
type string 是 固定 "status"
sn string 是 完整标识 sn.product_id,身份字段
device_sn string 推荐 设备序列号,身份字段
product_id string 推荐 品类标识,身份字段
online boolean 是 true 上线 / false 下线
uptime_s number 否 已运行秒数(扩展)
fw string 否 固件版本(扩展)
ip string 否 本机 IP(扩展)
timestamp string 建议 ISO8601 带时区

6.2 data — 单台设备数据

一个 JSON 只描述一台设备(一个 sn)的一帧数据(sz0001 的 rly4p3 品类:4 组三相开关 + 溶氧度 + 环境量):

{"type":"data","sn":"sz0001.rly4p3","water_temp":25.6,"air_temp":28.3,"air_pressure":101.3,"oxygen":5.2,"voltage":12.2,"current":0.8,"switch1":false,"switch2":false,"switch3":false,"switch4":false,"signal":20,"timestamp":"2026-09-20T17:36:50+08:00"}

字段说明:

字段 类型 必填 说明
type string 是 固定 "data"
sn string 是 完整标识 sn.product_id,身份字段
water_temp number 按品类 水温 ℃
air_temp number 按品类 气温 ℃
air_pressure number 按品类 气压 hPa
oxygen number 按品类 溶氧度 mg/L(鱼塘关键指标)
voltage number 按品类 电压 V
current number 按品类 电流 A
switch1 ~ switch4 boolean 按品类 4 组三相开关状态
signal number 按品类 4G 信号强度 dBm
timestamp string 建议 ISO8601 带时区

业务字段随 product_id 的品类字典而不同:ems 品类设备的 data 字段是储能系统的 SOC、充放电功率、
各路电源功率等,与 rly4p3 完全不同(见 6.4)。字段是否必填以对应品类字典为准。

6.3 同一品类,多台设备 → 各自独立上报

品类 rly4p3 下有两台设备 sz0001、sz0002,各自发到各自主题、各自 JSON。

设备 sz0001(品类 rly4p3) → 主题 aqua/sz0001.rly4p3/up:

{"type":"data","sn":"sz0001.rly4p3","device_sn":"sz0001","product_id":"rly4p3","oxygen":5.2,"switch1":false,"switch2":false,"voltage":12.2,"timestamp":"2026-09-20T17:36:50+08:00"}

设备 sz0002(品类 rly4p3) → 主题 aqua/sz0002.rly4p3/up:

{"type":"data","sn":"sz0002.rly4p3","device_sn":"sz0002","product_id":"rly4p3","oxygen":4.1,"switch1":true,"switch2":true,"voltage":12.1,"timestamp":"2026-09-20T17:36:50+08:00"}

二者同属品类 rly4p3,共享同一份字段字典,但设备 sn 不同、主题不同、完整标识不同。
不要把两台设备的数据塞进同一个 JSON。

6.4 一台 4G 网关挂多个品类 → 各自独立上报

一台 4G 网关可同时挂多个品类的设备;每个品类(如 rly4p3)下又有多台设备。
由于 sn 全局唯一(不同品类不重复),各设备的 sn.product_id 不冲突:

4G 网关 品类 product_id 设备 sn 完整标识 发布主题 上报字段(示例)
网关A rly4p3 sz0001 sz0001.rly4p3 aqua/sz0001.rly4p3/up switch1~switch4、voltage
网关A rly4p3 sz0002 sz0002.rly4p3 aqua/sz0002.rly4p3/up switch1~switch4、voltage
网关A ems sz0005 sz0005.ems aqua/sz0005.ems/up soc、chg_power、pv_power、grid_power
网关B rly4p3 sz0011 sz0011.rly4p3 aqua/sz0011.rly4p3/up switch1~switch4、voltage
网关B wq8in1 sz0012 sz0012.wq8in1 aqua/sz0012.wq8in1/up ph、oxygen、ammonia

要点:

6.5 扩展 type 示例(预留)

新增 event(事件上报,配合扩展规则),用于超温告警:

{
  "type": "event",
  "sn": "sz0001.rly4p3",
  "event": "over_temperature",
  "level": "warning",
  "value": 35.2,
  "timestamp": "2026-09-20T17:36:50+08:00"
}

6.6 下行 cmd(预留)

平台 → 设备,下发控制(结构另行约定,此处为示例):

{"type":"cmd","cmd":"set","sn":"sz0001.rly4p3","params":{"switch1":true},"seq":1001,"timestamp":"2026-09-22T11:15:00+08:00"}

timestamp 是公共通信参数(非物模型字段),推荐每个报文都带;格式见 5.6。

6.7 命令闭环 cmd → cmd_result(v1.1 正式规范)

下发(平台 → 设备,主题 aqua/sz0001.rly4p3/cmd):

{"type":"cmd","cmd":"set","sn":"sz0001.rly4p3","request_id":"REQ-1790046772049-E7LGFH","params":{"switch1":true},"seq":1001,"source":"app","timeout_ms":5000,"timestamp":"2026-09-22T11:15:00+08:00"}

反馈(设备 → 平台,发布到上报主题 aqua/sz0001.rly4p3/up,type:"cmd_result"):

{"type":"cmd_result","sn":"sz0001.rly4p3","request_id":"REQ-1790046772049-E7LGFH","cmd":"set","seq":1001,"success":true,"message":"四路继电器已打开","data":{"switch1":true},"timestamp":"2026-09-22T11:15:00+08:00"}
字段 类型 必填 说明
type string 是 固定 cmd_result,与 data 上报区分
sn string 是 sn.product_id 完整标识
request_id string 是 原样回传下发报文的 request_id,不能重新生成
success boolean 是 true 执行成功 / false 失败(JSON 布尔值,不能写成字符串)
message string 是 结果说明(如“四路继电器已打开” / “继电器控制失败”)
cmd string 否 回显下发的 cmd(如 set),便于平台按命令分派
seq number 条件 下发报文带 seq 时回显同一 seq;纯 request_id 关联时可省
code number 否 业务结果码(0=成功),见 12.3
data object 否 执行后状态快照(可选;实测把 switch1~switch4 直接平铺在报文里)
timestamp string 是 反馈时间(ISO8601)

cmd_result 为当前实测采用的执行反馈类型:v1.1 草案里的 ack 已统一改名 cmd_result,
字段以实测为准(request_id + success / message),cmd / seq / code 为可选补充。

超时与重试:平台按 timeout_ms(默认 5000ms)等待 cmd_result;
未收到则按幂等重试(同 seq / request_id)或标记失败。详见 9.6。


实测报文(现场抓包,type:"cmd_result",发往上报主题 up)

反馈与 data 上报共用同一上报主题 aqua/sz0001.rly4p3/up,仅靠报文的 type 区分;
request_id 与下发报文一一对应,必须原样回传。

反馈主题(设备 → 平台,与数据上报同主题):

aqua/sz0001.rly4p3/up

执行成功反馈示例:

{"type":"cmd_result","sn":"sz0001.rly4p3","request_id":"REQ-1790046772049-E7LGFH","success":true,"message":"四路继电器已打开","switch1":true,"switch2":true,"switch3":true,"switch4":true,"timestamp":"2026-09-22T11:15:00+08:00"}

执行失败反馈示例:

{"type":"cmd_result","sn":"sz0001.rly4p3","request_id":"REQ-1790046772049-E7LGFH","success":false,"message":"继电器控制失败","timestamp":"2026-09-22T11:15:00+08:00"}

反馈要求:

  1. request_id 必须原样返回,不能重新生成。
  2. success 必须是 JSON 布尔值 true / false,不能写成字符串 "true" / "false"。
  3. 成功时返回四路继电器执行后的真实状态(switch1~switch4)。
  4. 反馈仍然发布到设备上报主题 aqua/sz0001.rly4p3/up。
  5. 反馈报文 "type" 固定为 "cmd_result"(不再用旧草案名 "ack")。
  6. 失败时加 "success":false 与 "message":"继电器控制失败" 等说明。

说明:cmd_result 为当前实测采用的执行反馈类型(v1.1 草案名 ack 已废弃);
反馈统一发往 up 主题,与 data 同主题、靠 type 区分,最终以平台对接验收为准。

6.8 事件 event 规范(v1.1 正式)

事件 = 告警 / 通知,设备主动上发(发布到上报主题 aqua/<sn>.<product_id>/up,type:"event")。

{"type":"event","sn":"sz0012.wq8in1","event":"do_low","level":"warning","value":3.2,"threshold":4.0,"duration_s":60,"timestamp":"2026-09-20T17:36:50+08:00"}
字段 类型 必填 说明
event string 是 事件码,见 12.4 事件码表
level string 是 info / warning / critical
value number 否 触发值
threshold number 否 阈值
duration_s number 否 持续时长(去抖后触发,见 8.3-5)

事件需去抖(持续 N 秒再发)、可带恢复事件(event 同名 + level:"info" + clear:true),
冷却期内不重复推送。

6.9 配置下发 config → cmd_result(v1.1 正式)

下发(平台 → 设备,订阅主题 aqua/sz0001.vfd/cmd,type:"config"):

{"type":"config","sn":"sz0001.vfd","config":{"report_interval_s":30,"do_map":[{"do":3,"freq":50},{"do":4,"freq":35},{"do":5,"freq":20},{"do":6,"freq":0}],"min_run_s":600},"seq":2001}

确认:设备应用后回 cmd_result(cmd:"config"、success:true,回显 seq / request_id,data 带 cfg_ver)。
设备持久化配置,重启生效;
网关在 status 中上报 cfg_ver,平台比对后补下发缺失配置(见 9.10)。

6.10 离线补传示例

{"type":"data","sn":"sz0012.wq8in1","cache":true,"collect_ts":"2026-09-20T17:36:50+08:00","water_temp":26.1,"ph":7.8,"oxygen":3.9,"signal":0,"timestamp":"2026-09-21T08:00:01+08:00"}

7. 物模型字典(字段级定义)

7.0 物模型通用规范(v1.1 新增,先读)

公共字段(所有品类可选携带,不写入各品类必填列):

字段 类型 单位 说明
fw string — 固件版本
mac string — MAC 地址(hex)
signal number dBm 4G / Wi-Fi 信号强度(-113~-51)
voltage number V 供电电压
temp number ℃ 设备本体温度
uptime_s number s 已运行秒数
fault_code number — 故障码(0=无,品类内定义)

字段元数据约定:

  1. 单位唯一、量程固定:每个字段一个单位、固定量程、固定精度(规则引擎无需二次换算);
  2. 读写权限:字典中标 W(可写)的字段才能出现在下行 cmd.params / config 中;
    未标默认只读 R;
  3. 类型:number / boolean / string / enum(字符串枚举)/ array / object;
  4. 上报周期:每品类默认周期见 12.6,可经 config.report_interval_s 调整;
    开关、频率等状态变化即时上报;
  5. 量程 / 精度:range 表示量程、acc 表示精度,未标注按品类默认。
  6. 品类命名:product_id 不带数字后缀即默认第 1 版;
    出现不兼容新版时递增数字(如 vfd 的下一版为 vfd2)。
    名称内嵌数字属产品类型本身,不算版本号(rly4p3 的 4p3=4 组 3 相、
    wq8in1 / wq4in1 的 4/8=合一参数数)。
  7. 字段名规范(v1.2 新增,硬约束):字段名一律小写 snake_case,总长 ≤10 字符(含下划线);
    同一概念在各品类用同一字段名(如溶氧统一 oxygen,电导率统一 ec);
    常用缩写:temp 温度 / volt 电压 / curr 电流 / power 功率 / pres 气压 / lvl 位(料位 / 水位 / 油位)/ cnt 计数 / state 状态机(长度不足时用 st)/ sum 累计 / day_ 当日 / chg_ 充电 / dis_ 放电 / mot_ 电机 / gen_ 柴发 / tou_ 峰谷时段(time-of-use);
    功率三兄弟用 p_power / q_power / s_power(有功 / 无功 / 视在),功率因数用 pf;
    三相量用 _a / _b / _c 后缀(如 voltage_a);
    已在客户平台上线使用的字段名一律不改(含超长者):rly4p3 的 switch1 ~ switch4、air_pressure(12 字符,客控平台已用)属此类,永久保留、不再列入改名计划(见 7.1);长度规范只约束新增字段。

7.1 rly4p3 — 4 组 × 3 相继电器开关(客控现网定义,仅 oxygen 改名)【必须】

以下字典与 6.2 / 6.3 示例为线上在用协议:v1.1 未改动任何字段;
v1.2 仅按字段名规范把溶氧 dissolved_oxygen 改名为 oxygen(单位 / 数值 / 语义不变),
该品类其余字段与报文结构一律不动;air_pressure(12 字符)客控平台已在使用,永久保留不改。

以 rly4p3 为例(4 组 × 3 相继电器开关,可接增氧机 / 水泵 / 投料机等,并采集溶氧度):

字段 类型 单位 必填 说明
water_temp number ℃ 否 水温
air_temp number ℃ 否 气温
air_pressure number hPa 否 气压
oxygen number mg/L 是 溶氧度(鱼塘关键指标,宜 ≥5)
voltage number V 是 供电电压
current number A 否 工作电流
switch1 ~ switch4 boolean — 是 4 组三相开关(可控点,规则引擎可写)
signal number dBm 否 4G 信号强度

⚠️ 改进建议(仅意见,未落地;客控方评审通过后另行升级):

  1. 增加每路控制模式位 swN_mode(N=1~4,manual / auto / remote),
    明确本地联动 / 云端 / 手动的仲裁优先级(配合 8.5);
  2. 增加 swN_run_s(累计运行秒)与 swN_cnt(动作次数),支撑能耗与寿命统计;
    (switchN_* 写法超出 10 字符,按 7.0-7 规范统一用 swN_*);
  3. oxygen 与 wq8in1 重复,建议标注为「冗余采集」或后续由 wq8in1 统一,
    避免两路数据打架;
  4. 建议补充量程 / 精度列(如 voltage 0~60V ±0.1V,current 0~30A ±0.1A,
    oxygen 0~20 mg/L ±0.2);
  5. signal / voltage / current 属公共字段,建议移入 7.0,字典只保留业务字段(需要客控方配合);
  6. 下行 cmd 增加 seq + cmd_result 闭环(现 6.6 为单向示例),平台侧才能确认执行结果;
  7. 增加 fault(继电器粘连 / 过流)字段或转用 event 上报,便于告警与工单。
  8. 字段名收口(v1.2 已定):air_pressure(12 字符)已被客控平台使用,不改名、永久保留,
    作为 7.0-7 的唯一豁免;switch1 ~ switch4 本身 7 字符、符合规范,一并保留。
    今后每路扩展字段统一用 swN_* 前缀(sw1_mode / sw1_run_s / sw1_cnt),避免 switchN_* 超长。

7.2 gw4g — 4G 网关(下位机本体)

字段 类型 单位 必填 可写 说明
run boolean — 是 R 网关运行状态
uptime_s number s 否 R 已运行秒数
fw string — 是 R 固件版本
mac string — 是 R MAC(hex 12 位,无分隔符);client_id = 本 MAC(按 2 字节分 3 组)+ .gw4g
signal number dBm 是 R 4G 信号强度(-113~-51)
sim_iccid string — 否 R SIM 卡 ICCID
sim_state enum — 否 R ok / error / no_card / no_signal
mqtt_state boolean — 是 R 云连接状态
rs485_bus boolean — 否 R RS485 总线 1(传感器)通信正常
cache_cnt number 条 否 R 离线缓存未补传条数
dev_cnt number 台 是 R 代理子设备数量
devices array — 否 R 子设备清单 [{"sn":"sz0001","product_id":"rly4p3","online":true,"modbus_addr":1},...]
ntp_ok boolean — 否 R 时钟是否已同步(NTP)
cfg_ver number — 否 R 配置版本号(平台比对补下发)
tank_id string — 否 R/W 塘口 / 点位编号(多塘管理,config 下发)
lat / lng number ° 否 R 经纬度(可选)

status 示例(网关本体):

{"type":"status","sn":"0025CA3B6F01.gw4g","device_sn":"0025CA3B6F01","product_id":"gw4g","online":true,"fw":"1.2.0","mac":"0025CA3B6F01","signal":-72,"sim_state":"ok","mqtt_state":true,"rs485_bus":true,"cache_cnt":0,"dev_cnt":5,"devices":[{"sn":"sz0001","product_id":"rly4p3","online":true},{"sn":"sz0012","product_id":"wq8in1","online":true}],"ntp_ok":true,"tank_id":"P01","timestamp":"2026-09-20T17:36:50+08:00"}

7.3 wq8in1 — 八合一水质传感器【完善】

市场常见的多参数探头(如「水质 8 合 1」)大同小异,
通常在温度 / pH / 溶解氧 / 电导率 / 浊度 / 盐度 / ORP / 氨氮 / 亚硝酸盐等中选 8 项组合。
本字典选用了水产养殖最常用的组合, 需要盐度 / 余氯 / 叶绿素等参数时,
在字典中追加字段即可(见第 9 节扩展性约定)。

字段 类型 单位 必填 可写 量程 / 精度 说明
water_temp number ℃ 是 R — 水温
ph number — 是 R — pH 酸碱度(0~14)
oxygen number mg/L 是 R — 溶解氧(鱼塘最关键的指标,宜 ≥5)
ec number μS/cm 否 R — 电导率
turbidity number NTU 否 R — 浊度
ammonia number mg/L 否 R — 氨氮 NH₃-N
nitrite number mg/L 否 R — 亚硝酸盐 NO₂⁻-N
orp number mV 否 R — 氧化还原电位
signal number dBm 否 R — 4G 信号强度
tds number ppm 否 R 0~100000 / ±2%FS 总溶解固体
salinity number % 否 R 0.01~25.00 / ±0.5% 盐度(海水 / 咸淡水)
sg number — 否 R 0.9~1.1 比重
oxygen_sat number % 否 R 0~200 溶氧饱和度(可选)
probe_st enum — 否 R — ok / fouled(生物污损) / fault / calibrate_due
clean_cnt number 次 否 R — 自动清洗累计次数
last_cal string — 否 R — 最近校准时间(ISO8601)

量程 / 精度(建议按探头选配,供规则引擎用):
water_temp 0~40℃ ±0.5℃;
ph 0~14 ±0.05;
oxygen 0~20 mg/L ±0.2;
ec 0~200 mS/cm;
turbidity 0~4000 NTU ±5%;
ammonia 0~100 mg/L ±5%FS;
nitrite 0~10 mg/L ±5%FS;
orp -999~+999 mV ±5mV。

对应 wq8in1 品类的 data 报文示例(设备 sz0012 → 主题 aqua/sz0012.wq8in1/up):

{"type":"data","sn":"sz0012.wq8in1","device_sn":"sz0012","product_id":"wq8in1","water_temp":26.3,"ph":7.8,"oxygen":4.2,"ec":380,"turbidity":12.5,"ammonia":0.3,"nitrite":0.05,"orp":180,"signal":20,"timestamp":"2026-09-20T17:36:50+08:00"}

7.4 wq4in1 — 四合一水质仪(低成本探头,对应 OT.AS.4in1)

字段 类型 单位 必填 可写 量程 / 精度 说明
water_temp number ℃ 是 R 0~40 / ±0.1 水温
ph number — 是 R 0~14 / ±0.05 pH 酸碱度
tds number ppm 是 R 0~100000 总溶解固体
ec number μS/cm 是 R 0~200 mS/cm 电导率
signal number dBm 否 R — 信号强度(公共)

7.5 ems — 储能能量管理系统【完善】

管理市电 / 储能 / 光伏 / 柴发多能互补,
对应 PPT「光储柴微网」四态状态机(S1 市电优先 → S2 储能独立 → S3 柴发补能 → S4 恢复待机)。

字段 类型 单位 必填 可写 说明
run boolean — 是 R 储能系统运行状态
mode string — 是 W 工作模式:self_use 自发自用 / peak_valley 削峰填谷 / demand 需量控制
soc number % 是 R 电池荷电状态(0~100)
soh number % 否 R 电池健康状态
bat_volt number V 否 R 电池组电压
bat_curr number A 否 R 电池组电流(正=充电,负=放电)
bat_temp number ℃ 否 R 电池温度
chg_power number kW 否 R 充电功率
dis_power number kW 否 R 放电功率
pv_power number kW 否 R 太阳能(光伏)发电功率
wind_power number kW 否 R 风电功率
hyd_power number kW 否 R 水电功率
coal_power number kW 否 R 煤电功率
grid_power number kW 否 R 并网功率(正=上网,负=下网/购电)
load_power number kW 否 R 负荷功率
grid_freq number Hz 否 R 电网频率
chg_energy number kWh 否 R 累计充电量
dis_energy number kWh 否 R 累计放电量
ems_state enum — 否 R 调度状态机:grid(市电) / battery(储能独立) / genset(柴发补能) / recovery(恢复待机)
source enum — 否 R 当前供电来源:grid / battery / genset / pv
grid_state enum — 否 R 市电状态:normal / outage
gen_state enum — 否 R 柴发状态:off / starting / running / stopping / fault
chg_limit number kW 否 W 充电功率上限
dis_limit number kW 否 W 放电功率上限
valley_chg boolean — 否 W 谷电充电使能
gen_auto boolean — 否 W 柴发自动补能使能
gen_start number % 否 W 柴发启动 SOC 阈值(默认 20)
gen_stop number % 否 W 柴发停机 SOC 阈值(默认 40)
tou_peak array — 否 W 峰段时段 [{"start":"10:00","end":"12:00"},...]
tou_valley array — 否 W 谷段时段
cab_temp number ℃ 否 R 机柜温度
day_chg number kWh 否 R 当日充电量
day_dis number kWh 否 R 当日放电量
fault_code number — 否 R BMS / EMS 故障码(0=无)

对应 ems 品类的 data 报文示例(设备 sz0005 → 主题 aqua/sz0005.ems/up):

{"type":"data","sn":"sz0005.ems","device_sn":"sz0005","product_id":"ems","run":true,"mode":"peak_valley","soc":68.5,"soh":95.2,"bat_volt":384.2,"bat_curr":12.5,"bat_temp":28.4,"chg_power":4.8,"dis_power":0.0,"pv_power":3.2,"wind_power":1.5,"hyd_power":0.0,"coal_power":0.0,"grid_power":-2.3,"load_power":9.5,"grid_freq":50.02,"chg_energy":1200.5,"dis_energy":890.3,"signal":20,"timestamp":"2026-09-20T17:36:50+08:00"}

下行可写点(cmd.params):
mode、chg_limit、dis_limit、valley_chg、
gen_auto、gen_start、gen_stop、tou_peak、
tou_valley。

7.6 vfd — 增氧机变频器(变频闭环核心,对应 PPT 第 14 页)

由 4G 网关经 RS485 Modbus 直控;
本地按 do_map 四档 DO→频率映射自动调速,断网可跑。

字段 类型 单位 必填 可写 说明
run boolean — 是 W 运行状态(false=停机)
mode enum — 是 W off / manual / auto / remote
freq number Hz 是 R 当前输出频率 0~50
set_freq number Hz 否 W 设定频率 0~50
mot_volt number V 否 R 输出电压
mot_curr number A 否 R 输出电流
mot_power number kW 否 R 输出功率
rpm number rpm 否 R 估算转速
energy_sum number kWh 否 R 累计耗电量
do_map array — 否 W DO→频率四档映射,如 [{"do":3,"freq":50},{"do":4,"freq":35},{"do":5,"freq":20},{"do":6,"freq":0}]
min_run_s number s 否 W 最短运行时长防抖(默认 600)
hysteresis number mg/L 否 W 溶氧滞回(防频繁启停)
fault_code number — 否 R 0 无 / 1 过流 / 2 过压 / 3 欠压 / 4 过热 / 5 缺相
signal number dBm 否 R 信号强度(公共)

7.7 feed — 投饵机

字段 类型 单位 必填 可写 说明
run boolean — 是 W 运行状态
mode enum — 是 W off / manual / plan(定时计划) / auto(摄食联动,预留)
feeding boolean — 否 R 正在投喂
feed_rate number g/s 否 W 投喂速率
feed_total number kg 否 R 累计投喂量
hopper_lvl number % 否 R 料仓料位
spread_m number m 否 W 抛撒距离
schedule array — 否 W 定时投喂计划(config 下发)[{"time":"06:00","dose_kg":1.5},...]
fault_code number — 否 R 0 无 / 1 堵料 / 2 缺料 / 3 电机过载 / 4 仓门未关

7.8 pump — 水泵(换水 / 循环)

字段 类型 单位 必填 可写 说明
run boolean — 是 W 运行状态
mode enum — 是 W off / manual / auto / timer
flow_rate number m³/h 否 R 流量
pressure number kPa 否 R 出口压力
mot_curr number A 否 R 工作电流
mot_power number kW 否 R 功率
run_sum_s number s 否 R 累计运行时长
fault_code number — 否 R 0 无 / 1 过载 / 2 缺相 / 3 空转 / 4 漏水

7.9 gate — 电动闸门 / 电动阀

字段 类型 单位 必填 可写 说明
pos number % 是 W 开度 0~100
state enum — 是 R opening / closing / stopped / open / closed / fault
target_pos number % 否 R 目标开度
lim_open boolean — 否 R 开限位
lim_close boolean — 否 R 关限位
torque number % 否 R 力矩百分比(堵转检测)
fault_code number — 否 R 0 无 / 1 堵转 / 2 超时 / 3 限位失效

7.10 wlevel — 水位计

字段 类型 单位 必填 可写 说明
water_lvl number m 是 R 水位(相对基准)
distance number m 否 R 探头距水面距离(超声波)
water_temp number ℃ 否 R 水温
voltage number V 否 R 供电 / 电池电压
signal number dBm 否 R 信号强度(公共)

7.11 wxst — 气象站

字段 类型 单位 必填 可写 说明
air_temp number ℃ 是 R 气温
air_pres number hPa 是 R 气压
humidity number % 是 R 相对湿度
wind_speed number m/s 否 R 风速
wind_dir number ° 否 R 风向 0~359
rainfall number mm 否 R 累计雨量
rain_rate number mm/h 否 R 雨强
solar_rad number W/m² 否 R 光照辐照(光伏预测 / 藻类)
uv_index number — 否 R 紫外线指数
signal number dBm 否 R 信号强度(公共)

7.12 pv — 光伏 MPPT 控制器

字段 类型 单位 必填 可写 说明
pv_volt number V 是 R 光伏输入电压
pv_curr number A 是 R 光伏输入电流
pv_power number kW 是 R 光伏功率
chg_power number kW 是 R 充电功率
chg_energy number kWh 否 R 累计充电量
bat_volt number V 否 R 母线 / 电池电压
mppt_state enum — 否 R off / mppt / float / bulk / fault
temp number ℃ 否 R 控制器温度
fault_code number — 否 R 故障码(0=无)

7.13 gen — 柴油发电机

字段 类型 单位 必填 可写 说明
run boolean — 是 R 运行状态
state enum — 是 R off / starting / running / stopping / fault
fuel_lvl number % 是 R 油位
fuel_rate number L/h 否 R 油耗
oil_pres number kPa 否 R 机油压力
cool_temp number ℃ 否 R 水温
rpm number rpm 否 R 转速
voltage number V 否 R 输出电压
current number A 否 R 输出电流
power number kW 否 R 输出功率
run_sum_s number s 否 R 累计运行时长
auto_en boolean — 否 W 自动补能使能(EMS 联动)
fault_code number — 否 R 故障码(0=无)

7.14 pmet — 配电 / 电表监测

字段 类型 单位 必填 可写 说明
voltage_a / voltage_b / voltage_c number V 是 R 三相电压
current_a / current_b / current_c number A 是 R 三相电流
p_power number kW 是 R 总有功功率
q_power number kVar 否 R 无功功率
s_power number kVA 否 R 视在功率
pf number — 否 R 功率因数
freq number Hz 否 R 电网频率
energy_sum number kWh 是 R 累计电量
day_energy number kWh 否 R 当日电量
grid_state enum — 否 R normal / outage(市电检测)
rcd_trip boolean — 否 R 漏电保护跳闸(告警,对应 event rcd_trip)
spd_ok boolean — 否 R 防雷 SPD 正常
signal number dBm 否 R 信号强度(公共)

7.15 cam — AI 视觉盒【预留】

对应 PPT 阶段 5:浮头 / 集群识别、死鱼识别取证、生长监测、摄食行为决策。
本版先定骨架,识别策略云端配置。

字段 类型 单位 必填 可写 说明
alive boolean — 是 R 视觉盒在线
cpu_load number % 否 R 算力负载
disk_used number % 否 R 存储占用
detect_cnt number 次 否 R 当日识别事件数
events array — 否 R 最近事件 [{"type":"floating_head","conf":0.92,"time":"...","image_url":""}]
fw string — 否 R 固件版本

7.16 规划中品类(待现场验证后补字典)

品类 说明
ras 循环水 / 工厂化养殖(水位、流量、滤器反冲洗、UV / 臭氧、温控)
light 集鱼灯 / 诱虫灯(照度、时段)
net 电子围栏 / 入侵报警
muldo 多点溶氧融合(1 网关多探头,加权 / 最劣值决策)

8. 本地联动 / 小规则引擎(预留设计)

规划:后续在设备端实现「本地条件联动」——即小规则引擎:无需云端,
根据一个或几个 数据点(条件)自动触发设备输出(动作)。本协议第 7 节的物模型字段即按此要求设计,
保证后续规则引擎无需改动字段语义即可接入。

8.1 字段角色

角色 定义 示例字段(完整标识,含设备)
数据点(只读测量值) 规则引擎的「条件」输入 sz0012.wq8in1.oxygen、sz0012.wq8in1.ph、sz0012.wq8in1.ammonia
可控点(可写输出) 规则引擎的「动作」目标 sz0001.rly4p3.switch1 ~ sz0001.rly4p3.switch4
模式 / 枚举字段 规则的目标值或分组条件 sz0005.ems.mode(self_use / peak_valley / demand)
网关本体字段 网关级条件(信号 / 总线 / 缓存等) 0025CA3B6F01.gw4g.signal

字段寻址规范(v1.1 修订):condition 的数据点与 action 的可控点,
一律用完整标识 + 字段名寻址,即 sn.product_id.field,
如 sz0012.wq8in1.oxygen;
网关本体字段用 <gw4g_sn>.gw4g.field,如 0025CA3B6F01.gw4g.signal。
不允许只写 product_id.field(如 wq8in1.oxygen):一个品类下可有多台设备,
见 6.4 中网关A 同时挂 sz0001.rly4p3 与 sz0002.rly4p3,不带设备标识就无法定位到唯一设备,
规则既无法执行、也无法追溯(event=rule_triggered 的 sn 只到设备级)。
需要压缩报文长度时,可在规则对象上声明作用域 device(见 8.4);
作用域内 field 才允许只写字段名。

8.2 规则示例(若…则…)

规则 条件(数据点) 动作(可控点 / 上报) 鱼塘场景
低氧自动增氧 sz0012.wq8in1.oxygen < 4.0 持续 60s sz0001.rly4p3.switch1 = true 夜间低氧自动开增氧机
溶氧恢复停机 sz0012.wq8in1.oxygen >= 6.0 持续 5min sz0001.rly4p3.switch1 = false 防增氧机频繁启停
氨氮超标换水 sz0012.wq8in1.ammonia > 0.5 sz0001.rly4p3.switch2 = true(换水泵) 水质恶化自动换水
高温告警上报 sz0012.wq8in1.water_temp > 32 上发 type=event 告警(sn = sz0012.wq8in1) 高温预警
峰谷电价储能 sz0005.ems.mode == "peak_valley" 依据 sz0005.ems.soc 自动充放 削峰填谷

8.3 物模型设计约定(为规则引擎预留)

  1. 单位唯一、量程固定:每个字段只有一个单位、固定量程,规则引擎无需二次换算 (如溶氧固定 mg/L,
    阈值 4.0 即 mg/L);
  2. 数据点与可控点分离:测量类字段只读(sz0012.wq8in1.*),
    控制类字段可写(sz0001.rly4p3.switch*);
  3. 按类型匹配:数值字段用于阈值比较(<、>=、区间),布尔字段用于状态判断,
    枚举字段用于模式匹配;
  4. 与下行 cmd 共用同一套可控点:本地联动写 switch* 与云端下发 cmd (见 6.7)语义一致,
    避免两套控制逻辑打架;
  5. 持续时长去抖:规则条件可带「持续 N 秒/分」再触发,防止瞬时抖动误动作;
  6. 本版只定骨架:规则对象字段与可选项见 8.4(含 condition / action 字段表),正式格式待后续迭代定型。
  7. 字段寻址唯一:条件与动作的字段必须带设备完整标识,
    即 sn.product_id.field(网关本体为 <gw4g_sn>.gw4g.field);
    只写 product_id.field 的规则视为无效(见 8.1)。

8.4 规则配置下发(config 通道,v1.1 新增)

规则由云端可视化配置,经 config 下发到网关本地执行(断网自治)。
示例(下发到网关本体 gw4g):

{"type":"config","sn":"0025CA3B6F01.gw4g","config":{"rules":[
  {"id":1,"name":"低氧增氧","enable":true,"safety":true,"priority":1,
   "condition":{"field":"sz0012.wq8in1.oxygen","op":"<","value":4.0,"duration_s":60},
   "action":{"target":"sz0021.vfd","set":{"run":true,"freq":50}}},
  {"id":2,"name":"溶氧恢复停机","enable":true,"safety":false,"priority":2,
   "condition":{"field":"sz0012.wq8in1.oxygen","op":">=","value":6.0,"duration_s":300},
   "action":{"target":"sz0021.vfd","set":{"run":false}}},
  {"id":3,"name":"氨氮超标换水","enable":true,"safety":false,"priority":2,
   "device":"sz0012.wq8in1",
   "condition":{"field":"ammonia","op":">","value":0.5,"duration_s":120},
   "action":{"target":"sz0001.rly4p3","set":{"switch2":true}}}
]}}

规则对象字段(config.rules[]):

字段 类型 必填 说明
id number 是 规则 ID,网关内唯一;平台按此覆盖 / 删除
condition object 是 触发条件,字段见下表
action object 是 执行动作,字段见下表
name string 否 规则名称(可视化展示用,网关不解析)
enable boolean 否 是否启用,默认 true;false 时保留规则但不执行
safety boolean 否 是否安全规则(仲裁优先级见 8.5),默认 false
priority number 否 同层规则的执行顺序(小者优先),默认 100
device string 否 作用域:<sn.product_id>(或网关本体 <gw4g_sn>.gw4g);声明后本规则内 field / set 的键可只写字段名

condition(触发条件)字段:

字段 类型 必填 说明
field string 是 数据点:<sn.product_id>.<字段>(如 sz0012.wq8in1.oxygen);声明 device 时可只写 <字段>
op enum 是 比较符:< / <= / > / >= / == / != / in
value number / boolean / string / array 是 比较值;op=in 时为数组:区间 [3,6]、集合 ["grid","battery"]
duration_s number 否 条件需持续 N 秒才触发(去抖,见 8.3-5),默认 0
recover object 否 恢复条件 {"value":6.0,"duration_s":300},满足即解除告警 / 动作(滞回),避免反复启停

action(执行动作)字段:

字段 类型 必填 说明
target string 否 目标设备 <sn.product_id>(如 sz0021.vfd);声明 device 时可省略,默认取作用域设备
set object 否 可控点目标值,键为该设备内的字段名(可写点见各品类字典),如 {"run":true,"freq":50}
event string 否 触发后同时上发的事件码(见 12.4),如 rule_triggered / do_low
level enum 否 事件级别:info / warning / critical,默认 info

set 与 event 至少出现一项(只上报不动作、或只动作不上报都合法);
只写 event 而不写 target 时,事件按条件字段所属设备(或作用域设备)上报。

寻址说明(与 8.1 一致):condition.field 写 <sn.product_id>.<字段>(示例 id=1 / id=2);
规则对象声明了作用域 device 时,该规则内 field 可只写字段名
(示例 id=3,等价于 sz0012.wq8in1.ammonia)。
action.target 已含设备标识,action.set 的键是该设备内的字段名
(如 run、freq、switch2),不再重复写设备前缀。

示例 1 / 2 是「两条规则」写法(先升后停各一条);也可压成一条带 recover 的规则:
触发侧用 duration_s 去抖(< 4.0 持续 60s 开机),
恢复侧用 recover(>= 6.0 持续 300s 停机),
动作只需要一条 set(如 {"run":true,"freq":50}),停机由 recover 自动解除,避免两处阈值打架。

下发语义:config.rules 为全量下发(按 id 覆盖、缺项即删除),
网关持久化配置并在 status.cfg_ver 回带版本,平台比对不一致即重下发(见 9.10);
未识别字段必须忽略而非拒绝整条规则,保证向后兼容。

8.5 仲裁与安全优先级(v1.1 新增)

  1. 执行顺序(高→低):本地安全规则(safety:true)> 云端指令(source=cloud/app)> 本地普通规则 > 手动;
  2. 云端 cmd 必须携带 source,设备按上述优先级仲裁;
  3. 安全规则(如 DO<3 强制开机)不允许被云端 / 手动覆盖,
    且动作后上发 event=rule_triggered 与 cmd_result 可追溯;
  4. 规则动作与云端下发共用同一套可控点(sz0001.rly4p3.switch* / sz0021.vfd.set_freq 等,同样带设备完整标识),语义一致,
    避免两套控制逻辑打架(对应 8.3-4)。

9. 设备接入与管理(v1.1 新增)

9.1 首次激活 / 注册

  1. 网关首次上电:上报 gw4g status(含 mac、fw、sim_iccid、devices 清单);
  2. 平台登记设备档案;未登记设备默认可接入(现网匿名),生产环境建议一机一密(见第 10 章);
  3. 子设备上总线后由网关在 gw4g.devices 中声明,平台据此建影子。

9.2 上线 / 下线

9.3 心跳保活与重连

9.4 数据上报频率

9.5 离线缓存与补传

9.6 命令下发闭环

  1. 平台下发 cmd(seq、source、timeout_ms);
  2. 设备校验(命令白名单 / 参数合法性 / 本地仲裁)后执行;
  3. 设备回 cmd_result(request_id 原样回传,success + message;下发带 seq 时一并回显 seq);
  4. 平台超时未收到:按幂等重试(同 seq 设备侧去重)或标记失败;
  5. seq 每设备 0~65535 环形递增。

9.7 时间同步

9.8 OTA(预留骨架)

9.9 日志上报与远程调试(预留骨架)

9.10 配置管理

9.11 设备影子(预留)


10. 安全(增强)

现状:puzhizhineng.com:1883 匿名 TCP、QoS1(v1.0 不变)。

演进建议(按上线节奏分步实施):

阶段 措施 说明
近期 一机一密 client_id + username/password(token),由平台签发、可轮换;未登记设备拒绝接入
近期 命令白名单 + 频率限制 平台侧校验 cmd 合法性与限流
中期 MQTT over TLS(8883) 或先对敏感 payload 加密
中期 主题 ACL 每设备仅可读写自己的 aqua/<sn.product_id>/#
中期 防重放 上行 msg_id 去重、下行 seq 校验
长期 数据脱敏 位置、ICCID、SIM 号脱敏存储

注意:Client ID 是网关级标识(见第 2 节、3.3),
故「一机一密」与「主题 ACL」的鉴权主体是代理网关; 需要子设备级隔离时,
须由网关内部按 sn.product_id 做二次管控,或改为子设备各自建连(各占一个 Client ID)。


11. 扩展性约定

扩展点 方式 示例
type 取值 新增小写 type 值,不破坏既有结构 event、cmd_result、log
主题动作 固定 up / cmd,业务类型用 type 区分 仅 aqua/<sn.product_id>/{up,cmd}
品类 / 产品 新 product_id + 字典 新增 feed(投料机)
设备数量 品类下登记新 sn(全局唯一即可) 品类 rly4p3 新增 sz0003
业务字段 在字典中新增字段,可选不向前兼容 字典追加字段
连接安全 预留账号 / 密码、TLS、ClientID 鉴权 见第 2 节

补充(v1.1):

扩展点 方式 示例
事件码 12.4 事件码表新增 do_low、power_loss
命令结果码 12.3 code 码表新增 100+ 设备自定义
品类 新 product_id + 字典 + 默认上报周期(12.6) ras(循环水)
本地规则 config.rules 新增规则(8.4) DO 联动、氨氮换水

12. 附录

12.1 type 速查

type 方向 用途 状态
status 设备→平台 上下线 / 健康信息 已启用
data 设备→平台 属性数据快照 已启用
event 设备→平台 事件 / 告警 已启用(v1.1)
cmd_result 设备→平台 命令 / 配置执行结果反馈 已启用(v1.1,实测)
config 平台→设备 参数 / 规则下发 已启用(v1.1)
log 设备→平台 运行日志 预留
ota 双向 固件升级 预留
err 双向 错误 / 异常 预留

12.2 主题动作速查

主题动作固定:up(上行)/ cmd(下行);业务类型见 12.1 与 5.2(如 status data event cmd_result config log ota)。

12.3 命令结果码表(cmd_result.code,可选字段)

code 含义
0 成功
1 未知命令
2 参数错误
3 设备忙 / 执行超时
4 未找到目标设备
5 无权限
6 被本地安全规则拒绝
7 执行失败(硬件 / 通信)
100+ 设备自定义

12.4 事件码表

event 含义 默认级别
do_low 溶氧过低 warning / critical
do_high 溶氧过高 info
temp_high 水温过高 warning
ph_out pH 超限 warning
ammonia_high 氨氮超标 warning
power_loss 市电停电 critical
genset_start / genset_fault 柴发启动 / 故障 info / critical
ems_state_change EMS 状态机切换 info
device_offline 子设备离线 warning
rcd_trip 漏电保护跳闸 critical
rule_triggered 本地规则触发 info
ota_progress OTA 进度 info
fault 设备故障(随 fault_code) warning

12.5 单位速查

温度 ℃ / 气压 hPa / 湿度 % / 电压 V / 电流 A / 功率 kW / 电量 kWh / 频率 Hz /
溶氧 mg/L / 氨氮、亚硝酸盐 mg/L / 电导率 μS/cm / 浊度 NTU / 盐度 % / pH 无量纲 / ORP mV /
信号 dBm / 风速 m/s / 雨量 mm / 辐照 W/m² / 水位 m / 开度 % / 流量 m³/h

12.6 默认上报周期表

品类 数据周期 状态周期 说明
gw4g 60s 30s 信号 / 总线 / 缓存 / 子设备清单
rly4p3 60s 30s 开关变化即时上报
wq8in1 / wq4in1 60s 60s 越限切 10s 快速上报
ems 30s 30s 能源调度,状态机切换即时
vfd 60s 30s 频率变化即时
feed 60s 30s 投喂开始 / 结束即时
pump / gate 60s 30s 状态变化即时
wlevel 60s 60s 变化即时
wxst 300s 60s 天气变化慢,可放宽
pv / gen 60s 30s —
pmet 60s 60s 跳闸即时

12.7 字段速查表(v1.0 附录保留)

字段 类型 用途 身份字段
type string 报文类型(开放扩展) 否
sn string 完整标识 sn.product_id(设备 + 品类) 是
device_sn string 设备序列号 是
product_id string 品类标识 是
client_id string(连接层) MQTT 客户端标识 = 代理网关 dev_id(网关 MAC Hex + .gw4g),网关级身份,非 sn.product_id 是
timestamp string 采集时间 ISO8601 否
业务字段 number / boolean / string 设备属性(见品类字典) 否

13. 遗漏点与待办清单(v1.1 评审重点)

回答「原 v1.0 有哪些节点是遗漏的」:按优先级列出,标注本版处理状态。

P0 连接与身份(必须补,本版已补)

# 遗漏点 本版处理
1 心跳 Keepalive / 掉线判定未定义 §2.1、9.3
2 遗嘱 LWT(异常掉线离线通知)未定义 §2.1、9.2
3 重连退避与恢复流程未定义 §2.1、9.3
4 离线缓存与补传语义未定义(采集时间 vs 上报时间) §5.4、9.5、6.10
5 网关本体没有物模型(信号 / 总线 / 缓存 / 固件 / 子设备清单) §7.2
6 公共字段(fw / mac / signal / voltage / fault)未统一 §7.0
7 设备时钟来源与时间同步未定义 §5.6、9.7

P1 通信闭环与运维(重要,本版已补骨架)

# 遗漏点 本版处理
8 cmd 无应答闭环(v1.0 §6.6 单向示例) §6.7、9.6、12.3
9 事件 event 无事件码表 / 级别 / 去抖 / 恢复 §6.8、12.4
10 配置下发 config 通道缺失(参数 / 规则 / 上报周期) §6.9、9.10
11 本地规则引擎无下发格式与仲裁优先级 §8.4、8.5
12 上报频率 / 越限提速未定义 §9.4、12.6
13 OTA 只有一句话,无主题与报文骨架 §9.8
14 日志 / 远程调试通道未定义 §9.9
15 安全仅匿名 TCP,无鉴权 / ACL / 防重放 §10

P2 产品与运营(规划,部分已补 / 待专项)

# 遗漏点 本版处理
16 缺产品品类:变频增氧 / 投饵 / 水泵 / 闸门 / 水位 / 气象 / 光伏 / 柴发 / 配电监测 / AI 视觉 §7.6~7.15
17 多塘 / 塘口维度(tank / 点位 / 分组)未建模 gw4g.tank_id 已建模;平台侧关联待定
18 设备档案 / 绑定 / 解绑 / 换卡 / 换网关迁移流程未定义 建议平台侧专项(§9.1 骨架)
19 计量计费(峰谷电价、能耗单价、套餐订阅) ems.peak/tou_valley 已建模;计费在平台
20 循环水 / 工厂化(ras)、灯光、围栏、多点溶氧 §7.16 规划中
21 rly4p3 改进建议 7 条未落地 §7.1 注,待客控方评审
22 rly4p3 历史字段名 air_pressure(12 字符)与 ≤10 规范冲突 不改:客控平台已用,作 7.0-7 长期豁免;每路扩展字段用 swN_*(§7.1 注-8)

文档结束 · v1.2 · 下位机网关及其代理子设备接入规范