Selaa lähdekoodia

文档同步:设备号输入、全量/实时运行、compressor_alarm 落库与振动单段映射

18922397810 2 viikkoa sitten
vanhempi
commit
19d1f156a8

+ 1 - 0
models/markdown/README.md

@@ -9,5 +9,6 @@
 | `模型辅助确认方案.md` | 压力/振动共用的窗口、标签与规则联合判断约定 |
 | `跨机组泛化与样本扩充方案.md` | 跨机组泛化特征与样本扩充方案 |
 | `实时联合诊断方案.md` | 实时联合诊断与模型/规则联合输出方案 |
+| `全量与实时运行及告警落库.md` | 设备号输入、全量/实时运行、`compressor_alarm` 存储映射与定时服务 |
 
 原合并文档 `PKS润滑油压力与振动算法说明.md` 仍保留在项目根目录。

+ 103 - 0
models/markdown/全量与实时运行及告警落库.md

@@ -0,0 +1,103 @@
+# 全量与实时运行及告警落库
+
+本文档记录压力/振动算法在 `models/` 重构后的运行方式:设备号输入、全量/实时模式、
+`compressor_alarm` 存储映射与定时服务。对应代码:`models/scan_all.py`、
+`models/realtime_service.py`、`models/common/devices.py`、`models/common/alarm_store.py`。
+
+## 1. 设备号输入
+
+- 统一使用 `--device 7# 8# 9#`(默认 `7# 8# 9#`),也兼容 `7`、`7号机`。
+- 设备通过 `compressor_data_import.directory_path` 解析到 PKS 导入批次:
+
+```sql
+SELECT pls.*
+FROM pks_long_sample pls
+INNER JOIN compressor_data_import di ON di.id = pls.import_batch_id
+WHERE di.data_type = 'PKS' AND di.directory_path = '7#';
+```
+
+- `7#/8#/9#` 分别对应 7/8/9 号机;`4#/5#/6#` 暂不纳入本算法。
+- 算法内部**仍按 `批次` 划分周期**(与历史一致),因此本地全量结果与现有
+  `润滑油压力小时阶段段.csv`、`振动异常段.csv` 逐字节一致。
+
+## 2. 全量运行
+
+```bash
+# 本地:自动查询起止时间,先清理旧中间/结果再生成
+python models/scan_all.py --device 7# 8# 9# --store local
+
+# 数据库:本地结果照常生成,并额外写入 compressor_alarm
+python models/scan_all.py --device 7# 8# 9# --store db
+
+# 显式时间或复用小时中间表
+python models/scan_all.py --start "2025-01-01 00:00:00" --end "2026-09-01 00:00:00"
+python models/scan_all.py --hourly-csv models/datas/hourly/pks_hourly_full.csv
+```
+
+- **自动时间范围**:`start = floor(最小 sample_time)`,`end = floor(最大 sample_time) + 1h`
+  (保证最后一个完整整点小时纳入),按设备取范围。
+- **清理策略**:运行前删除旧的小时中间表与扫描结果(`models/datas/hourly/`、
+  `models/results/{common,pressure,vibration}` 中的扫描产物),不删除模型测试结果与
+  `models/datas/reference/`。
+- `--store db` 会按 `(device_code, alarm_type ∈ {润滑油压力故障, 振动故障})`
+  **先删除所选设备的旧告警,再插入新段**。
+
+## 3. 数据库存储映射(表 `compressor_alarm`)
+
+| 结果 | device_code | device_part | device_point | alarm_type | alarm_level |
+|---|---|---|---|---|---|
+| 压力段 | `7#` | `润滑油压力` | `YSJ_5` | `润滑油压力故障` | 压力阶段 |
+| 振动段 | `7#` | `联轴器端振动` / `链轮端振动` | `YSJ_10` / `YSJ_11` | `振动故障` | 振动阶段 |
+
+- **每个压力段落 1 行**;**每个振动段也落 1 行**,`device_part/device_point` 由该段
+  `最强异常侧` 决定(链轮端 → `YSJ_11`,联轴器端 → `YSJ_10`),与
+  `振动异常段.csv` 一行一段对应。
+- 其他字段:
+  - `alarm_des` = `阶段触发依据`(已迁移为 `VARCHAR(4000)`);
+  - `alarm_time_start` / `alarm_time_end` = `开始小时` / `结束小时`;
+  - `alarm_info_json` = 对应 CSV 行的 JSON(`阶段/基线/评分/触发依据/最强异常侧` 等全部字段);
+  - `status = 1`;`scan_start_time` / `scan_end_time` = 本次扫描范围。
+- 结构迁移:`models/migrations/alter_compressor_alarm_alarm_des_4000.sql`
+  (`ALTER TABLE compressor_alarm MODIFY alarm_des VARCHAR(4000)`)。
+
+## 4. 实时运行与合并规则
+
+```bash
+python models/realtime_service.py --once                    # 单次
+python models/realtime_service.py --loop --interval 300     # 每 5 分钟(命令行定时)
+```
+
+- 每次 tick:`end = min(floor(本机当前时间), floor(最新数据) + 1h)`,
+  `start = end - lookback`(默认 45 天),按设备跑与全量相同的算法得到段。
+- **合并写入**:对每段按 `(device_code, alarm_type, alarm_level)` 找时间重叠、或间隔
+  ≤6 小时的既有行:
+  - `alarm_time_start = min`、`alarm_time_end = max`,刷新 `alarm_des` / `alarm_info_json`
+    / `scan_*`;
+  - 合并键**不含部件/点位**,因此“最强异常侧”在 tick 之间切换也不会把连续段拆开;
+    合并时 `device_part/device_point` 更新为最新 `最强异常侧`;
+  - 同一时刻若新段桥接了两条既有行,会合并为一条(删除多余行);
+  - 不同等级(轻微/异常/严重异常)保留为不同行,与阶段 CSV 的行语义一致。
+- 因此“14 点和 15 点属于同一故障段”的场景会持续更新同一行,不会拆开。
+
+## 5. 定时服务
+
+| 平台 | 安装 | 卸载 |
+|---|---|---|
+| macOS | `bash models/service/mac/install.sh` | `bash models/service/mac/uninstall.sh` |
+| Linux | `sudo bash models/service/linux/install.sh` | `sudo bash models/service/linux/uninstall.sh` |
+| Windows | `models\service\windows\install_service.bat` | `models\service\windows\uninstall_service.bat` |
+
+均为每 5 分钟执行 `python models/realtime_service.py --once`;详见
+`models/service/README.md`(含 cron 备选与日志位置)。
+
+## 6. 冒烟测试与校验
+
+```bash
+# 顺序模拟多个时刻运行,结束后默认回滚数据库
+python models/realtime_service.py --simulate "2026-02-03 20:00:00,2026-02-04 00:00:00"
+
+# 校验本地结果与 golden 一致、DB 行数与 CSV 对应
+python models/common/verify.py --with-db
+```
+
+`--with-db` 会校验 `compressor_alarm` 行数与参考 CSV 对应:压力 72 行、振动 25 行,共 97 行。

+ 1 - 1
models/markdown/压力模型结果.md

@@ -39,7 +39,7 @@
 ### 3. 数据与切分
 
 - 窗口:3 小时与 6 小时各一套;标签:重叠即异常(含 1 小时“轻微”阶段,用前后小时补足窗口,不做过渡窗口降权)。
-- 数据来源:复用 `datasets/pressure/hourly.csv`(`--hourly-csv`,不查库);阶段来源 `cache/pks_scanner/evolution/润滑油压力小时阶段段.csv`。
+- 数据来源:复用 `models/datas/hourly/pks_hourly_full.csv`(`--hourly-csv`,不查库);阶段来源 `models/results/pressure/润滑油压力小时阶段段.csv`。
 - 切分:6.5 / 2 / 1.5,seed 20260921,事件组整体不拆,按(机组、标签)分层,并保证每机组 train 都有正常事件组。
 
 ## 二、数据范围

+ 25 - 16
models/markdown/压力算法说明.md

@@ -195,45 +195,54 @@ YSJ_41 > 0 表示设备运行
 
 ## 5. 运行方法
 
-重构后压力算法不依赖振动代码,公共逻辑在 `models/common/`。
+压力算法不依赖振动代码,公共逻辑在 `models/common/`。设备号输入、全量/实时模式与告警
+落库统一见 `全量与实时运行及告警落库.md`。
 
-### 5.1 复用小时中间表(推荐)
+### 5.1 全量扫描(推荐)
 
 ```bash
-python models/generalized/pressure_algorithm.py \
-  --hourly-csv models/datas/hourly/pks_hourly_full.csv \
-  --output-dir models/results/pressure
+# 按设备号,自动查询起止时间,先清理旧中间/结果再生成,结果写本地
+python models/scan_all.py --device 7# 8# 9# --store local
+
+# 本地结果照常生成,并额外写入 compressor_alarm
+python models/scan_all.py --device 7# 8# 9# --store db
 ```
 
-### 5.2 从数据库全量重跑(同时缓存小时中间表)
+### 5.2 单独运行压力算法
 
 ```bash
-python models/scan_all.py --save-hourly
-```
+# 复用小时中间表
+python models/generalized/pressure_algorithm.py \
+  --device 7# 8# 9# \
+  --hourly-csv models/datas/hourly/pks_hourly_full.csv \
+  --output-dir models/results/pressure
 
-`models/scan_all.py` 会一次生成压力与振动全部结果,并写入
-`models/datas/hourly/pks_hourly_full.csv`。
+# 连库扫描
+python models/generalized/pressure_algorithm.py --device 7# 8# 9#
+```
 
-### 5.3 只分析指定批次/机组
+### 5.3 只分析指定设备
 
 ```bash
 python models/generalized/pressure_algorithm.py \
-  --batch 31 \
+  --device 8# \
   --hourly-csv models/datas/hourly/pks_hourly_full.csv \
-  --output-dir models/results/pressure_batch31
+  --output-dir models/results/pressure_8
 ```
 
 参数含义与默认值:
 
 | 参数 | 含义 | 默认值 |
 |---|---|---|
-| `--batch` | 批次,可多选 | `compressor_data_import` 中全部 PKS 批次 |
-| `--start` | 开始时间(连库模式) | `2025-01-01 00:00:00` |
-| `--end` | 结束时间(连库模式) | `2026-09-01 00:00:00` |
+| `--device` | 压缩机编号,可多选,如 `7# 8# 9#` | `7# 8# 9#` |
+| `--start` / `--end` | 扫描起止(连库模式) | 自动:`floor(最小)..floor(最大)+1h` |
 | `--chunk-days` | 每个查询块的天数 | `14` |
 | `--hourly-csv` | 复用小时中间表,不查库 | 无 |
 | `--output-dir` | 输出目录 | `models/results/pressure` |
 
+说明:设备经 `compressor_data_import.directory_path` 解析到 PKS 批次;算法内部仍按批次
+划分周期,因此本地结果与历史 CSV 逐字节一致。
+
 ## 6. 结果解读建议(润滑油压力)
 
 ### 润滑油压力

+ 5 - 0
models/markdown/实时联合诊断方案.md

@@ -1,5 +1,10 @@
 # 实时联合诊断改造方案(压力,先记录,暂不实现)
 
+> 注意:本文件是“**模型辅助确认**”方向的后续方案记录,尚未实现。
+> 规则侧(压力/振动算法)的**实时扫描与告警落库已经实现**,见
+> `全量与实时运行及告警落库.md`(`models/realtime_service.py`,每 5 分钟写入
+> `compressor_alarm`)。两者不要混淆。
+
 本文件记录把泛化模型接入 `backend/scan_pks_fault_evolution.py` 实时检测的改造方案。当前只做方案记录,代码实现和阈值标定后续再讨论。
 
 ## 1. 目标与职责边界

+ 1 - 1
models/markdown/振动模型结果.md

@@ -31,7 +31,7 @@
 ### 3. 数据与切分
 
 - 窗口:3 小时与 6 小时各一套;标签:重叠即异常(含 1~2 小时短阶段,用前后小时补足);重启后首个有效小时不作样本。
-- 数据来源:复用 `data/hourly.csv`(`--hourly-csv`,不查库)。
+- 数据来源:复用 `models/datas/hourly/pks_hourly_full.csv`(`--hourly-csv`,不查库);阶段来源 `models/results/vibration/振动异常段.csv`。
 - 切分:6.5 / 2 / 1.5,seed 20260921,事件组不拆,按(机组、标签)分层,保证每机组 train 有正常事件组。
 - 异常事件分配用 `--positive-basis groups`(每个事件等权),避免个别长事件整组落入同一划分。
 

+ 28 - 16
models/markdown/振动算法说明.md

@@ -199,45 +199,57 @@ YSJ_41 > 0 表示设备运行
 
 ## 6. 运行方法
 
-重构后振动算法不依赖压力代码,公共逻辑在 `models/common/`。
+振动算法不依赖压力代码,公共逻辑在 `models/common/`。设备号输入、全量/实时模式与告警
+落库统一见 `全量与实时运行及告警落库.md`。
 
-### 6.1 复用小时中间表(推荐)
+### 6.1 全量扫描(推荐)
 
 ```bash
-python models/vibration/vibration_algorithm.py \
-  --hourly-csv models/datas/hourly/pks_hourly_full.csv \
-  --output-dir models/results/vibration
+# 按设备号,自动查询起止时间,先清理旧中间/结果再生成,结果写本地
+python models/scan_all.py --device 7# 8# 9# --store local
+
+# 本地结果照常生成,并额外写入 compressor_alarm
+python models/scan_all.py --device 7# 8# 9# --store db
 ```
 
-### 6.2 从数据库全量重跑(同时缓存小时中间表)
+### 6.2 单独运行振动算法
 
 ```bash
-python models/scan_all.py --save-hourly
-```
+# 复用小时中间表
+python models/vibration/vibration_algorithm.py \
+  --device 7# 8# 9# \
+  --hourly-csv models/datas/hourly/pks_hourly_full.csv \
+  --output-dir models/results/vibration
 
-`models/scan_all.py` 会一次生成压力与振动全部结果,并写入
-`models/datas/hourly/pks_hourly_full.csv`。
+# 连库扫描
+python models/vibration/vibration_algorithm.py --device 7# 8# 9#
+```
 
-### 6.3 只分析指定批次/机组
+### 6.3 只分析指定设备
 
 ```bash
 python models/vibration/vibration_algorithm.py \
-  --batch 31 \
+  --device 8# \
   --hourly-csv models/datas/hourly/pks_hourly_full.csv \
-  --output-dir models/results/vibration_batch31
+  --output-dir models/results/vibration_8
 ```
 
 参数含义与默认值:
 
 | 参数 | 含义 | 默认值 |
 |---|---|---|
-| `--batch` | 批次,可多选 | `compressor_data_import` 中全部 PKS 批次 |
-| `--start` | 开始时间(连库模式) | `2025-01-01 00:00:00` |
-| `--end` | 结束时间(连库模式) | `2026-09-01 00:00:00` |
+| `--device` | 压缩机编号,可多选,如 `7# 8# 9#` | `7# 8# 9#` |
+| `--start` / `--end` | 扫描起止(连库模式) | 自动:`floor(最小)..floor(最大)+1h` |
 | `--chunk-days` | 每个查询块的天数 | `14` |
 | `--hourly-csv` | 复用小时中间表,不查库 | 无 |
 | `--output-dir` | 输出目录 | `models/results/vibration` |
 
+### 6.4 写库说明
+
+每个振动段在 `compressor_alarm` 中**落 1 行**,`device_part/device_point` 由该段
+`最强异常侧` 决定(链轮端 → `YSJ_11`,联轴器端 → `YSJ_10`),与
+`振动异常段.csv` 一行一段一致。实时合并键为 `(设备, 告警类型, 等级)`,不拆段。
+
 ## 7. 结果解读建议(振动)
 
 ### 振动