docs: 补充实时故障显示需求说明

main
wangqiyang 3 days ago
parent 55d581100b
commit ecb6bf5ad3

@ -0,0 +1,370 @@
# 实时故障显示需求说明
日期2026-07-23
来源:`新需求.png`
## 需求目标
当前故障需要在实时监控页即时、准确、明确地显示出来,不能再依赖 10 分钟一次的历史扫描后才出现在报警预览中。
本次需求涉及四块:
1. 0x17 回路分控器参数解析调整
2. 实时监控页新增当前故障显示
3. 报警预览历史记录即时写入
4. 未定义回路不参与轮询
## 当前问题
### 实时监控页没有故障信息
当前实时监控页只展示回路开关状态、电压、电流、功率、调光值等信息,没有展示当前故障条目。
结果是:即使设备已经返回故障,用户也无法在实时监控页直接看到。
### 报警预览显示太慢
后台当前通过 `ScanM9z` 定时扫描故障,定时周期是 10 分钟:
```go
AddTaskByFunc("ScanM9z", "ScanM9z", "@every 10m", m9zTtyApi.ScanM9z)
```
所以用户看到“十几分钟后报警预览才有故障内容”,和当前代码行为一致。
### 故障文案不够准确
当前故障文案包含:
```text
欠压/短路故障
过压/开路故障
电源故障
未知异常
```
新需求要求按实际故障类型显示,不再混用“欠压/过压”描述。
### 回路电流解析需要调整
当前 0x17 解析中,回路总电流按 `0.1A` 处理。
新需求示例:
```text
01 BF = 0.447A
```
也就是 `0x01BF = 447`,应按 `0.001A` 解析。
## 当前故障显示区域
“当前故障显示区域”指实时监控页上一块专门展示当前故障的区域。
它不是历史报警列表,也不是报警预览页,而是当前设备正在发生的故障提示。
建议位置:
```text
实时监控页右上方空白区域
或实时监控页底部空白区域
```
建议显示内容:
```text
当前故障:
回路1短路故障
回路2开路故障
回路3设备1/2电源故障
```
没有故障时显示:
```text
当前无故障
```
每条故障建议包含:
| 字段 | 说明 |
| --- | --- |
| 回路号 | 例如回路1、回路2 |
| 故障类型 | 短路故障、开路故障、电源故障 |
| 设备号 | 仅电源故障需要显示例如设备1、设备2 |
| 故障码 | 可选显示例如01、02、04 01、04 03 |
## 故障码解析规则
0x17 返回的故障码按以下规则解析:
| 故障码 | 含义 | 显示文案 |
| --- | --- | --- |
| `0x01` | 短路故障 | 回路n短路故障 |
| `0x02` | 开路故障 | 回路n开路故障 |
| `0x04 + 设备掩码` | 电源故障 | 回路n设备x电源故障 |
电源故障示例:
| 故障码 | 含义 | 显示文案 |
| --- | --- | --- |
| `04 01` | 设备1电源故障 | 回路n设备1电源故障 |
| `04 02` | 设备2电源故障 | 回路n设备2电源故障 |
| `04 03` | 设备1/2电源故障 | 回路n设备1/2电源故障 |
如果同一回路同时存在多类故障,应拆成多条故障显示,或合并为一条清晰文案。
## 收到故障无需确认
“收到故障无需确认”指设备返回故障数据后,系统直接显示并记录,不弹窗询问用户是否确认。
正确流程:
```text
设备返回故障 -> 后端解析 -> 实时监控显示 -> 写入报警历史
```
不需要:
```text
设备返回故障 -> 弹窗问用户是否确认 -> 用户确认后才显示/记录
```
报警预览页里“批量删除”的确认弹窗可以保留,因为它属于用户删除操作确认,不属于故障进入系统前的确认。
## 未定义设备不轮询
当前代码固定轮询 10 个回路:
```go
for i := 0; i < 10; i++ {
// read 0x17
}
```
新需求要求未定义设备不参与轮询。
建议行为:
```text
配置了 4 路:只轮询 0~3
配置了 8 路:只轮询 0~7
配置了 10 路:轮询 0~9
```
好处:
1. 减少串口请求
2. 避免无效设备超时
3. 提升实时监控响应速度
4. 报警预览可以更快出现有效故障
如果暂时没有回路数量配置,建议新增配置项,例如:
```json
{
"deviceInfo": {
"loopCount": 10
}
}
```
没有配置时默认 `10`,但现场可以按实际回路数量调整。
## 后端改动点
### 1. 调整 0x17 数据解析
文件:
```text
internal/library/m9z/m9z_SubLoopParameters.go
```
改动:
1. 回路总电流从 `0.1A` 比例调整为 `0.001A`
2. 保留 `AlarmStatus``AlarmCode`
3. 增加结构化故障列表,例如 `Faults []LoopFault`
建议结构:
```go
type LoopFault struct {
LoopIdx uint `json:"loop_idx"`
DeviceIdx uint `json:"device_idx,omitempty"`
Type string `json:"type"`
Message string `json:"message"`
Code string `json:"code"`
}
```
### 2. 统一故障文案生成
建议新增公共函数,供实时接口和历史扫描共用:
```go
func BuildLoopFaults(loopIdx uint, alarmStatus uint16, alarmCode string) []LoopFault
```
输出示例:
```text
回路1短路故障
回路2开路故障
回路3设备1/2电源故障
```
### 3. 实时接口返回故障字段
文件:
```text
internal/module/m9zTtyApi/read.go
```
接口:
```text
/m9z/getDeviceStatus2
```
每个回路建议增加字段:
```json
{
"has_fault": true,
"fault_msg": "回路1短路故障",
"fault_code": "01",
"faults": []
}
```
同时把实时监控中的回路电流改为直接使用 0x17 的回路总电流字段,不再累加子模块电流。
### 4. 实时写入报警历史
文件:
```text
internal/module/m9zTtyApi/cron.go
```
当前历史报警只由 `ScanM9z` 10 分钟扫描写入。新需求应改为:
```text
实时接口读到故障 -> 立即写入 data/data.json
```
同时需要做去重,避免实时接口每次刷新都重复插入同一条故障。
建议去重维度:
```text
comm_uid + loop_idx + fault_code + fault_msg + 未处理状态
```
### 5. 轮询数量配置化
把以下固定循环:
```go
for i := 0; i < 10; i++ {
}
```
改成:
```go
for i := 0; i < loopCount; i++ {
}
```
`loopCount` 从配置读取,未配置默认 10。
涉及位置:
```text
internal/module/m9zTtyApi/read.go
internal/module/m9zTtyApi/cron.go
```
## 前端改动点
### 1. 实时监控页增加当前故障区域
页面:
```text
实时监控
```
展示:
```text
当前故障:
回路1短路故障
回路2开路故障
```
无故障时:
```text
当前无故障
```
### 2. 适配实时接口字段
调用接口:
```text
/m9z/getDeviceStatus2
```
读取字段:
```text
Loops[].has_fault
Loops[].fault_msg
Loops[].fault_code
Loops[].faults
```
### 3. 报警预览保持历史列表
页面:
```text
报警预览
```
接口继续使用:
```text
/m9z/fault/list
```
后端实时写入后,用户刷新报警预览即可更快看到记录。
### 4. 删除确认保留
报警预览页的批量删除确认弹窗可以保留。
“收到故障无需确认”只针对故障进入系统,不针对删除操作。
## 建议实施顺序
1. 后端先完成 0x17 解析和故障文案统一
2. 后端改 `/m9z/getDeviceStatus2` 返回当前故障
3. 后端增加实时写入历史和去重
4. 后端增加 `loopCount` 配置
5. 前端实时监控页增加当前故障区域
6. 前端适配接口字段
7. 联调真实 0x17 报文:`01`、`02`、`04 01`、`04 02`、`04 03`
## 待确认点
1. `loopCount` 放在哪个配置节点:建议放在 `deviceInfo.loopCount`
2. 电源故障的设备掩码最大支持几个设备目前图片只展示设备1、设备2
3. 同一回路多故障时前端展示为多行,还是合并为一行
Loading…
Cancel
Save