四、系统配置
系统配置业务全流程Topic 映射
所有系统配置统一使用 sys 通道,通过 m (method) 区分具体动作。
| 功能场景 | Topic 路径 | 方向 | Method (m) | 说明 |
|---|---|---|---|---|
| 设备上报 | {PK}/{GWID}/self/sys/u | Up | conf.report | 网关和云端是通过 id 和 业务逻辑上下文 来区分; |
| 设备端发起同步请求 (conf.get) | {PK}/{GWID}/self/sys/u | Up | conf.get | 设备主动请求配置 (Boot 或 定期重置) |
| 系统配置下发 (conf.push) | {PK}/{GWID}/self/sys/d | Down | conf.push | 云端收到请求后,返回高精度的服务器时间及环境配置。 |
完整 Payload 示例
设备上报(conf.report)
网关可以将 conf.report 理解为:“向云端同步我当前的配置快照”。
身份 A(响应推送):云端 conf.push -> 网关应用 -> conf.report(含执行结果 res)。
身份 B(主动同步):网关上线/配置变更 -> conf.report(告知云端我现在的真实样子)。
设备开机上报使用这个进行上报。
- Topic (Down):
{PK}/{GWID}/self/sys/u - Method (Key):
conf.report
{
"id": "801", // 设备生成ID
"m": "conf.report", // 请求方法
"if": { // 设备接口,在自定义接口被勾选的时候会进行下发
"RS485_1": { // 接口名为 key
"pt": 1, // 通信端口号
"bd": 9600, //波特率
"dbs": 8, // 数据位
"pty": 0, // 停止位
"sbs": 1, //校验位
"fi": 50, //分帧毫秒
"to": 1000 // 通信超时时间毫秒
},
"ETH_0": {
"md": 1, // IP模式,1:DHCP; 0:静态IP
"ip": "192.168.1.100", // IP地址
"nm": "255.255.255.0", //子网掩码
"gw": "192.168.1.1",//默认网关
"lp": 502, //端口
"dns1": "8.8.8.8" // DNS
}
},
"sub": { // 物模型,在勾选支持物模型功能的时候进行下发和获取
"sub_dev_sn_001": { //
"m_id": "temp_sensor_v1", // 模型名称
"proto": 1, //协议类型ID
"addr": 1, //从站地址
"bind_if": "RS485_1", //s
"c_t": 5000, //通信超时毫秒
"c_r": 500, //采集上报间隔秒
"params": [
{
"id": "temp_val", //唯一
"f_c": 3, //功能码
"add": "0x0001", //寄存器
"d_t": 2, //数据类型ID
"bit": [0, 1, 2, 3, 4, 5, 6, 7], //位序,当type为Bit 或 具体协议功能必须解析是 bit 时必填,这里表示单个寄存器,多个位。
"b_o": 0, //字节顺序
"f_": "x * 1.0", //自定义公式
"si": 100, //采集间隔毫秒
"sbr": 1, //是否上报 1上报 0 不上报
"co": 1.5, //变化偏移值,变化上报时⽣效,表⽰值变化在这个值的正负范围外才触发变化上报。0表示变化上报,不填代表不变化上报。
"rh": 10 //整点上报(单位:分钟),指定每⼏分钟上报⼀次
}
]
},
"sub_dev_sn_002": { // DLT数据
"m_id": "power_meter_k3",
"proto": "modbus_rtu",
"addr": 2,
"bind_if": "RS485_1",
"pl_int": 10000,
"c_t_m": 1000,
"params": [
{
"id": "temp_val", //唯一
"add": "0x0001", //DLT协议为表地址,不⽀持⼴播地
"d_t": 2, //数据类型ID
"bit": [0, 1, 2, 3, 4, 5, 6, 7], //位序,当type为Bit 或 具体协议功能必须解析是 bit 时必填,这里表示单个寄存器,多个位。
"b_o": 0, //字节顺序
"f_": "x * 1.0", //自定义公式
"si": 100, //采集间隔毫秒
"sbr": 1, //是否上报 1上报 0 不上报
"co": 1.5, //变化偏移值,变化上报时⽣效,表⽰值变化在这个值的正负范围外才触发变化上报。0表示变化上报,不填代表不变化上报。
"rh": 10 //整点上报(单位:分钟),指定每⼏分钟上报⼀次
}
]
},
"sub_dev_sn_003": { // JSON数据
"m_id": "power_meter_k3",
"proto": "modbus_rtu",
"addr": 2,
"bind_if": "RS485_1",
"pl_int": 10000,
"c_t_m": 1000,
"params": [
{
"id": "temp_val", //唯一
"f_": "x * 1.0", //自定义公式
"si": 100, //采集间隔毫秒
"sbr": 1, //是否上报 1上报 0 不上报
"co": 1.5, //变化偏移值,变化上报时⽣效,表⽰值变化在这个值的正负范围外才触发变化上报。0表示变化上报,不填代表不变化上报。
"rh": 10 //整点上报(单位:分钟),指定每⼏分钟上报⼀次
}
]
}
},
"ext": { // 系统参数,管理网关自身的生命周期与运维功能;业务相关的状态控制放在物模型中。
"addr": "iot.platform.com:1883", // 设备 mqtt 指向地址
"hb_int": 60, // 心跳间隔
"rtty": 1, // 是否开启rtty,1开启
"fV": "1.0.0", // 设备固件版本号
"hV": "1.0.0", // 设备硬件版本号
"cfV": "1.0.0", // 定制固件版本号,如果是定制⽹关,才会上报该字段
"flashTotal": 1024000, // 硬盘总量
"supportProtocols": [1, 2, 3], // 支持的协议类型ID列表
"gatewayFrp": "12345678901234567890123456789012", // 网关 FRP
"compressMode": 1, // 压缩模式 1 GZIP 0 无
"ntpServer": "ntp.aliyun.com", // NTP 服务器地址
"memTotal": 1024000 // 内存总量
}
}
设备获取配置(conf.get)
设备开机上报使用这个进行上报。
- Topic (Down):
{PK}/{GWID}/self/sys/u - Method (Key):
conf.get
{
"id": "801",
"m": "conf.get",
"p":{
"key":["if","sub","ext"] // 根据需要获取,如果为空则代表获取全部
}
}系统配置下发 (conf.push)
该指令用于云端向网关推送全量或增量配置,是网关运行的“大脑”指令。
根据设备需要获取的参数进行下发
- Topic (Down):
{PK}/{GWID}/self/sys/d - Method (Key):
conf.push
{
"id": "801",
"m": "conf.push",
"v_conf": "20260306",
"addr": "iot.platform.com:1883",
"if": {
"RS485_1": {
"pt": 1, "bd": 9600, "dbs": 8, "pty": 0, "sbs": 1, "fi": 50, "to": 1000
},
"ETH_0": {
"md": 1, "ip": "192.168.1.100", "nm": "255.255.255.0", "gw": "192.168.1.1",
"lp": 502, "dns1": "8.8.8.8"
}
},
"sub": {
"sub_dev_sn_001": { //
"m_id": "temp_sensor_v1", // 模型名称
"v": "v3.0.0",
"proto": 1, //协议类型ID
"addr": 1, //从站地址
"bind_if": "RS485_1", //s
"c_t": 5000, //通信超时毫秒
"c_r": 500, //采集上报间隔秒
"params": [
{
"id": "temp_val", //唯一
"f_c": 3, //功能码
"add": "0x0001", //寄存器
"d_t": 2, //数据类型ID
"bit": [0, 1, 2, 3, 4, 5, 6, 7], //位序,当type为Bit 或 具体协议功能必须解析是 bit 时必填,这里表示单个寄存器,多个位。
"b_o": 0, //字节顺序
"f_": "x * 1.0", //自定义公式
"si": 100, //采集间隔毫秒
"sbr": 1, //是否上报 1上报 0 不上报
"co": 1.5, //变化偏移值,变化上报时⽣效,表⽰值变化在这个值的正负范围外才触发变化上报。0表示变化上报,不填代表不变化上报。
"rh": 10 //整点上报(单位:分钟),指定每⼏分钟上报⼀次
}
]
},
"sub_dev_sn_002": { // DLT数据
"m_id": "power_meter_k3",
"proto": "modbus_rtu",
"add": 2,
"bind_if": "RS485_1",
"pl_int": 10000,
"c_t_m": 1000,
"params": [
{
"id": "temp_val", //唯一
"add": "0x0001", //DLT协议为表地址,不⽀持⼴播地
"d_t": 2, //数据类型ID
"bit": [0, 1, 2, 3, 4, 5, 6, 7], //位序,当type为Bit 或 具体协议功能必须解析是 bit 时必填,这里表示单个寄存器,多个位。
"b_o": 0, //字节顺序
"f_": "x * 1.0", //自定义公式
"si": 100, //采集间隔毫秒
"sbr": 1, //是否上报 1上报 0 不上报
"co": 1.5, //变化偏移值,变化上报时⽣效,表⽰值变化在这个值的正负范围外才触发变化上报。0表示变化上报,不填代表不变化上报。
"rh": 10 //整点上报(单位:分钟),指定每⼏分钟上报⼀次
}
]
},
"sub_dev_sn_003": { // JSON数据
"m_id": "power_meter_k3",
"proto": "modbus_rtu",
"addr": 2,
"bind_if": "RS485_1",
"pl_int": 10000,
"c_t_m": 1000,
"params": [
{
"id": "temp_val", //唯一
"f_": "x * 1.0", //自定义公式
"si": 100, //采集间隔毫秒
"sbr": 1, //是否上报 1上报 0 不上报
"co": 1.5, //变化偏移值,变化上报时⽣效,表⽰值变化在这个值的正负范围外才触发变化上报。0表示变化上报,不填代表不变化上报。
"rh": 10 //整点上报(单位:分钟),指定每⼏分钟上报⼀次
}
]
}
},
"ext": {
"addr": "iot.platform.com:1883", // 网关 mqtt 指向地址
"hb_int": 60, // 心跳间隔
"rtty": 1, // 是否开启rtty,1开启
"fV": "1.0.0", // 设备固件版本号
"hV": "1.0.0", // 设备硬件版本号
"cfV": "1.0.0", // 定制固件版本号,如果是定制⽹关,才会上报该字段
"flashTotal": 1024000, // 硬盘总量
"supportProtocols": [1, 2, 3], // 支持的协议类型ID列表
"gatewayFrp": "12345678901234567890123456789012", // 网关 FRP
"compressMode": 1, // 压缩模式 1 GZIP 0 无
"ntpServer": "ntp.aliyun.com", // NTP 服务器地址
"memTotal": 1024000 // 内存总量
}
}
设计结构描述
1. 基础信息层 (Metadata)
id: 消息 ID。用于异步通信对齐,设备回复时必须携带此 ID。m: 方法类型标识。用于异步通信对齐,设备回复时必须携带此 ID。v_conf: 配置版本号。网关以此判断配置是否发生变化,实现“增量应用”或“跳过重复配置”。addr: 网关 MQTT 连接地址。允许云端动态迁移网关的接入集群。
2. 硬件接口层 (if)
设计意图:抹平不同厂家网关的硬件接口差异。Key(如 RS485_1)是抽象句柄,网关根据自身硬件映射表开启对应的物理驱动。
- 串口参数:涵盖了工业级通信必备的流控参数(如分帧间隔
fi和超时to)。 - 网口参数:支持静态/动态 IP 切换,及本地服务监听端口
lp(用于网关级联或本地调试)。
3. 子设备映射层 (sub)
设计意图:实现“软件定义网关”。通过 SN 作为 Key,灵活绑定物理通道与逻辑协议。
bind_if: 核心逻辑,将子设备定向到特定的物理接口。pl_int/c_t_m: 实现针对每个设备的精细化调度逻辑(有的设备快采,有的慢采)。
4. 边缘解析层 (params)
设计意图:定义从原始二进制到结构化数据的转换逻辑。
- 功能码与地址 (
f_c,r_a): 标准协议定位。 - 数据加工 (
c_,f_):c_(系数):处理简单的线性放缩。f_(公式):支持边缘计算公式(如温度补偿或单位转换),降低云端计算压力。
b_o(字节顺序):解决工业现场大端/小端的“高低字节交换”痛点(如 ABCD, CDAB 等)。
5. 系统扩展层 (ext)
设计意图:管理网关自身的生命周期与运维功能。
watchdog: 开启硬件看门狗,确保极端环境下网关死机能自动重启。vpn_en: 远程运维开关,仅在需要排查问题时开启隧道。
设备端反馈 (sys.conf.report)
网关应用配置后,必须通过上行通道反馈执行结果。
- Topic (Up):
{ProductKey}/{GatewayID}/self/sys/u - Method (Key):
conf.report(ID 需与 Push 保持一致)
{
"id": "801",
"m": "conf.report",
"res": 0,
"applied": ["if", "ext"],
"failed": ["sub"],
"msg": "Sub-device model v1 not found locally"
}设备反馈报文 (conf.report) 详细说明
| 字段名称 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
| id | String | 是 | 消息 ID。必须与下发指令 conf.push 中的 ID 一致,用于云端匹配请求。 | "801" |
| m | String | 是 | 方法标识。固定为 "conf.report"。 | "conf.report" |
| res | Number | 是 | 执行结果状态码。0 表示成功,非 0 表示各类异常。 | 0 |
| applied | Array | 否 | 成功应用的分桶 Key。列出已生效的配置大类。 | ["if", "ext"] |
| failed | Array | 否 | 应用失败的分桶 Key。指示哪些模块配置未生效。 | ["sub"] |
| msg | String | 否 | 错误详细描述。便于运维人员在后台排查具体原因。 | "Sub-device model..." |
不会上报sub。sub只能平台下发。
结果状态码枚举说明 (res)
为了让云端后台能够自动处理异常(如自动重发或告警),建议定义以下细分状态码:
| 枚举值 | 名称 | 场景描述 | 运维建议 |
|---|---|---|---|
| 0 | SUCCESS | 全量或增量配置已成功写入 Flash 并生效。 | 无需操作 |
| 1 | PARTIAL_SUCCESS | 部分配置生效(如串口成功,但子设备物模型不存在)。 | 检查子设备物模型同步状态 |
| 2 | INVALID_PARAM | 参数格式错误或超出硬件范围(如波特率设为 100)。 | 校验后台参数合法性 |
| 3 | HARDWARE_ERROR | 硬件接口占用或损坏(如串口被其他进程抢占)。 | 远程重启网关或检查硬件 |
| 4 | VER_CONFLICT | 版本号校验失败或配置回滚。 | 重新下发最新版本配置 |
| 5 | RESOURCE_LIMIT | 网关内存或存储不足,无法加载更多的子设备映射。 | 清理无效的子设备模型 |
配置应用逻辑细节
1. 增量反馈机制
当网关只成功应用了部分配置时(如您的示例:硬件接口 if 成功,但子设备 sub 失败):
- 网关应保持旧的
sub配置运行,而不应删除已有的子设备,防止业务完全中断。 - 云端收到
failed: ["sub"]后,应触发“物模型补发”流程。