网关(4G)物模型 API
基于MQTT协议接入云平台, 版本V1.1
本协议面向「4G 网关(下位机)+ 其代理的子设备 + MQTT 云平台」的上行数据上报与下行命令通道。
智能鱼塘养殖
具体划分哪些子系统
(增氧 / 水质监测 / 投喂 / 换水 / 储能多能互补)。
智能设备品类汇总:
品类 名称 状态 rly4p34 组 × 3 相继电器开关 已上线(不改动)【必须】 gw4g4G 网关-设备上网代理中枢 新增 wq8in1/wq4in1八合一 / 四合一水质仪 完善 / 新增 ems储能能量管理系统 完善 vfd增氧机变频器(变频闭环) 新增 feed投饵机 新增 pump水泵(换水 / 循环) 新增 gate电动闸门 / 电动阀 新增 wlevel水位计 新增 wxst气象站 新增 pv光伏 MPPT 控制器 新增 gen柴油发电机 新增 pmet配电 / 电表监测 新增 camAI 视觉盒(浮头 / 死鱼 / 生长) 预留
gw4g 品类补充说明gw4g(4G 网关-设备上网代理中枢),
网关定位是子设备上网的代理通道,它不是业务上的功能设备。
而是帮助其它功能设备上网。
- 纯转发:只负责代理子设备上云、转发子设备的上行数据与下行命令,本身不产生业务数据;
- 网络配置由产品方专属工具管理:4G 卡 / APN / 心跳 / MQTT 连接参数、
主题前缀等由产品方小工具(配网 / 调试工具)配置下发,第三方平台无需处理;- 第三方平台可不处理
gw4g(可选处理):网关自身的status/data(信号、SIM、缓存、
子设备清单等)仅作网关级监控与运维,忽略不影响业务;- 直接按子设备身份收数据:第三方平台只须依据子设备的身份信息(
sn/product_id/
完整标识sn.product_id)订阅对应主题,即可直接接收子设备数据,无需关心网关内部结构。补充约定:子设备报文中的
gw4g_sn字段仅供平台侧(可选)做网关归集与路由,非业务必需;
网关换卡 / 换机 / 重启不影响子设备的主题与数据通道。
核心概念:
product_id(品类 / 产品标识):一类产品(决定字段字典),一个品类下可有多台设备;sn(设备序列号):某品类下的具体设备,全局唯一(即使在不同品类下也不会重复);- 完整标识 =
sn.product_id(如sz0001.rly4p3),主题中间段与 JSON 的sn字段存此值,
全局唯一。
本版范围(重要,请先读):
- 本 API 只描述「下位机网关(4G 控制器)及其代理的子设备」 的接入与物模型;不覆盖平台内部、
APP / 小程序 / 第三方系统之间的接口(那部分走平台开放 API,另行定义)。- 网关本体也按一个品类建模(
gw4g,见 7.2)。
一个 MQTT 连接 = 一个 4G 网关(client_id = XXXX-XXXX-XXXX.gw4g,即网关 MAC 6 字节 Hex);
网关下每台子设备(传感器 / 执行器 / 储能 / 配电等)各占一个sn.product_id、各自一组主题、
各自独立 JSON。rly4p3(原名relay4)为客控现网定义,字段字典不改(6.2 / 6.3 / 7.1 仅同步改名),
仅以「改进建议」形式给出意见, 汇总见 7.1 注与第 13 章清单;
其余品类(ems/wq8in1及新增品类)为规划产品,本版已直接完善。- 一个 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}
│ └─ ... 其它子设备
└──────────────────────────┘
要点:
- 一个 MQTT 连接 = 一个 4G 网关;
网关负责把子设备数据统一上云、把下行命令路由到对应子设备(RS485 / 继电器 / 变频器); - 子设备的
sn全局唯一,
网关自身也分配一个sn(建议取 MAC 去横线,如0025CA3B6F01),品类为gw4g; - 断网自治:本地闭环(DO→增氧联动)不依赖云端,
数据缓存断网不丢、恢复补传(见 9.5); - 平台侧通过通配订阅
aqua/+/up等收全量(见 4.5)。
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后缀,
如 MAC00:25:CA:3B:6F:01→0025-CA3B-6F01.gw4g;与 BLE 配置通道info回复的dev_id一致。
要点:Client ID 是「整台代理网关」的连接层标识,与具体设备的业务定义无关——一台网关下代理的
所有子设备共用同一个 Client ID,
子设备之间靠各自的主题<sn.product_id>与 JSONsn字段区分(见 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,
子设备 / 品类的区分只发生在主题中间段与 JSONsn字段(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 |
- 网关内存维护一张子设备注册表:
{gw4g_sn, [{sub_sn, product_id, alias, modbus_addr, online}]},
通过gw4g.devices字段上报平台(见 7.2),平台据此建立每台子设备的影子; - 一台子设备只能归属一个网关;
换网关/迁移需重新注册(平台侧流程,见第 13 章待办)。
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(下行),
靠 JSONtype字段区分(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 扩展规则:
type使用小写字母与下划线(如ota_start),新增值不修改既有字段结构;- 平台对未知
type不得丢弃整个报文,应按通用骨架解析身份与时间戳后记录; - 扩展类型仍必须携带
sn与timestamp,保证身份与时间可追溯; - 新增类型需同步更新本表与对应品类字典(见第 7 节)。
- 所有
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 去重与序号
- 上行
data:携带seq(每设备独立计数);
平台按(sn, seq)或msg_id去重; - 下行
cmd:平台分配seq;
设备执行后cmd_result回显同一seq;
设备对重复seq幂等(不重复执行); - 补传报文:平台按
(sn, collect_ts)归档,重复msg_id丢弃。
5.6 时间戳规范
timestamp不是物模型字段,而是所有数据包共有的公共通信参数(报文生成 / 发送时间),与sn/type同属通信层,不进任何品类字典;- 适用范围:上行
status/data/event/cmd_result,下行cmd/config;推荐每个报文都带上,便于平台排序、去重、超时判定与追溯; - 格式:ISO8601,固定
YYYY-MM-DDTHH:MM:SS+08:00(秒级精度,不带毫秒),时区固定为+08:00(例如2026-09-20T17:36:50+08:00); - 设备时钟来自 NTP 同步(见 9.7),未同步时
ntp_ok=false并在 status 中上报; timestamp= 报文生成(发送)时间;collect_ts= 数据采集时间;
两者不同即视为补传。
6. 报文示例
6.1 ~ 6.6 为 v1.0 原文(rly4p3 客控相关,结构未改动;仅 v1.2 把溶氧字段
dissolved_oxygen改名oxygen,见 7.1)。6.5event、
6.6cmd在 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 |
要点:
- 同一品类(如
rly4p3)下有多台设备(多个sn),字段字典一致,仅sn/ 主题不同; - 同一台网关可挂多个品类,各品类设备用不同的
sn(全局唯一),sn.product_id不冲突; - 不同网关的同类设备(
sz0001.rly4p3与sz0011.rly4p3)也靠sn区分。
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"}
反馈要求:
request_id必须原样返回,不能重新生成。success必须是 JSON 布尔值true/false,不能写成字符串"true"/"false"。- 成功时返回四路继电器执行后的真实状态(
switch1~switch4)。 - 反馈仍然发布到设备上报主题
aqua/sz0001.rly4p3/up。 - 反馈报文
"type"固定为"cmd_result"(不再用旧草案名"ack")。 - 失败时加
"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=无,品类内定义) |
字段元数据约定:
- 单位唯一、量程固定:每个字段一个单位、固定量程、固定精度(规则引擎无需二次换算);
- 读写权限:字典中标
W(可写)的字段才能出现在下行cmd.params/config中;
未标默认只读R; - 类型:
number/boolean/string/enum(字符串枚举)/array/object; - 上报周期:每品类默认周期见 12.6,可经
config.report_interval_s调整;
开关、频率等状态变化即时上报; - 量程 / 精度:
range表示量程、acc表示精度,未标注按品类默认。 - 品类命名:
product_id不带数字后缀即默认第 1 版;
出现不兼容新版时递增数字(如vfd的下一版为vfd2)。
名称内嵌数字属产品类型本身,不算版本号(rly4p3的4p3=4 组 3 相、wq8in1/wq4in1的4/8=合一参数数)。 - 字段名规范(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 信号强度 |
⚠️ 改进建议(仅意见,未落地;客控方评审通过后另行升级):
- 增加每路控制模式位
swN_mode(N=1~4,manual/auto/remote),
明确本地联动 / 云端 / 手动的仲裁优先级(配合 8.5);- 增加
swN_run_s(累计运行秒)与swN_cnt(动作次数),支撑能耗与寿命统计;
(switchN_*写法超出 10 字符,按 7.0-7 规范统一用swN_*);oxygen与wq8in1重复,建议标注为「冗余采集」或后续由wq8in1统一,
避免两路数据打架;- 建议补充量程 / 精度列(如
voltage0~60V ±0.1V,current0~30A ±0.1A,oxygen0~20 mg/L ±0.2);signal/voltage/current属公共字段,建议移入 7.0,字典只保留业务字段(需要客控方配合);- 下行
cmd增加seq+cmd_result闭环(现 6.6 为单向示例),平台侧才能确认执行结果;- 增加
fault(继电器粘连 / 过流)字段或转用event上报,便于告警与工单。- 字段名收口(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 物模型设计约定(为规则引擎预留)
- 单位唯一、量程固定:每个字段只有一个单位、固定量程,规则引擎无需二次换算
(如溶氧固定 mg/L,
阈值4.0即 mg/L); - 数据点与可控点分离:测量类字段只读(
sz0012.wq8in1.*),
控制类字段可写(sz0001.rly4p3.switch*); - 按类型匹配:数值字段用于阈值比较(
<、>=、区间),布尔字段用于状态判断,
枚举字段用于模式匹配; - 与下行
cmd共用同一套可控点:本地联动写switch*与云端下发cmd(见 6.7)语义一致,
避免两套控制逻辑打架; - 持续时长去抖:规则条件可带「持续 N 秒/分」再触发,防止瞬时抖动误动作;
- 本版只定骨架:规则对象字段与可选项见 8.4(含
condition/action字段表),正式格式待后续迭代定型。 - 字段寻址唯一:条件与动作的字段必须带设备完整标识,
即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 新增)
- 执行顺序(高→低):本地安全规则(
safety:true)> 云端指令(source=cloud/app)> 本地普通规则 > 手动; - 云端
cmd必须携带source,设备按上述优先级仲裁; - 安全规则(如 DO<3 强制开机)不允许被云端 / 手动覆盖,
且动作后上发event=rule_triggered与cmd_result可追溯; - 规则动作与云端下发共用同一套可控点(
sz0001.rly4p3.switch*/sz0021.vfd.set_freq等,同样带设备完整标识),语义一致,
避免两套控制逻辑打架(对应 8.3-4)。
9. 设备接入与管理(v1.1 新增)
9.1 首次激活 / 注册
- 网关首次上电:上报
gw4gstatus(含mac、fw、sim_iccid、devices清单); - 平台登记设备档案;未登记设备默认可接入(现网匿名),生产环境建议一机一密(见第 10 章);
- 子设备上总线后由网关在
gw4g.devices中声明,平台据此建影子。
9.2 上线 / 下线
- 上线:网关报
gw4gstatus(online=true),子设备逐个报各自 status(online=true); - 正常下线:
status(online=false)后断开; - 异常掉线:依赖 LWT 标记离线(2.1);
平台判定「离线」= 超过 3×Keepalive 无任何消息。
9.3 心跳保活与重连
- Keepalive 60s(可配置);空窗期由周期上报 data 充当心跳;
- 重连:指数退避 5s→60s + 随机 ±30% 抖动,无限重试;
- 重连成功:补报 status → 补传缓存(9.5)→ 校时(9.7)。
9.4 数据上报频率
- 默认周期见 12.6(数据点 60s、状态点 30s、事件即时);
- 每品类
report_interval_s可经config调整; - 越限提速:关键指标(DO / pH / 氨氮)越阈值时切
fast_report(如 10s),恢复后回周期。
9.5 离线缓存与补传
- 断网期间数据落 Flash 环形缓冲(建议 ≥10000 条),记录
collect_ts; - 恢复后按
collect_ts顺序补发,报文带"cache":true,平台按(sn, collect_ts)归档去重; - 缓存满溢出:丢弃最旧;
cache_cnt反映未补传条数(丢弃条数不单独建模)。
9.6 命令下发闭环
- 平台下发
cmd(seq、source、timeout_ms); - 设备校验(命令白名单 / 参数合法性 / 本地仲裁)后执行;
- 设备回
cmd_result(request_id原样回传,success+message;下发带seq时一并回显seq); - 平台超时未收到:按幂等重试(同
seq设备侧去重)或标记失败; seq每设备 0~65535 环形递增。
9.7 时间同步
- 网关经 NTP 同步(服务器可配置,如
ntp.aliyun.com),或由平台经config校时; gw4g.ntp_ok上报同步状态;所有时间戳使用设备本地时间 + 时区偏移。
9.8 OTA(预留骨架)
- 平台→设备(订阅主题
aqua/<gw4g_sn>.gw4g/cmd,type:"ota"):{"type":"ota","cmd":"start","url":"https://...","version":"1.3.0","md5":"...","seq":3001}; - 设备→平台:进度经
event=ota_progress(value=0~100)、结果经cmd_result,均发布到up主题; - 双分区 A/B,失败自动回滚;灰度发布由平台控制。详细流程待 OTA 专项设计。
9.9 日志上报与远程调试(预留骨架)
- 发布到上报主题
aqua/<gw4g_sn>.gw4g/up:{"type":"log","level":"info","msg":"...","seq":...}; - 运维经
config下发日志级别(off / error / warn / info / debug),用于远程排障。
9.10 配置管理
- 下行
config→cmd_result确认;设备持久化,重启生效; - 网关上报
cfg_ver,平台比对不一致即补下发; - 覆盖范围:上报周期、规则表(8.4)、设备参数(阈值 / 时段 / 可写点)、OTA 参数等。
9.11 设备影子(预留)
- 平台侧为每台子设备维护影子(desired / reported);
本版先用gw4g.devices+ 周期 data 近似,shadow主题后续启用。
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 · 下位机网关及其代理子设备接入规范