feat(scada): add calibrated monitoring and incident recovery

This commit is contained in:
2026-11-07 19:44:58 +08:00
parent 26fa5d1909
commit ff8aba4964
109 changed files with 9165 additions and 629 deletions
+125 -12
View File
@@ -16,10 +16,35 @@
本版冻结设备、区间、规则及批次输出,按批次原始值摘要校验源变更。完整月度数据清单、全月源版本摘要、独立事件真值和检测效果评估仍是后续数据准备工作;能力接口仅判断回放存储是否存在与当前操作权限,不声明月度数据已经就绪。现有 14 天数据不能当作一个月验收。
Agent 查询本轮已检测的固定批次快照,受任务的 replay_id、knowledge_cutoff、batch_sequence 约束。开始前历史只供后台基线初始化,本版调查查询不返回该部分;爆管定位已支持受回放截止约束的冻结输入适配,其他未适配计算工具继续拒绝。新 [SCADA 调查 Skill](../resources/work-order-skills/scada-anomaly/SKILL.md) 要求据实说明这些证据限制。运行异常自动建立调查,数据质量异常仅建立告警,不触发模型;恢复时推进调查代次。真实模型推理与报告效果尚未联调。
Agent 查询本轮已检测的固定批次快照,受任务的 replay_id、knowledge_cutoff、batch_sequence 和设备集合约束。新回放首次监测以只读一致快照冻结开始前 15 天历史,负序号静默基线按最多 2,000 行分块暂存为 `clean_prepared`;全部读取完成后,在一个 BizDB 短事务中把批次转为 `detected` 并原子发布基线与初始化标记,历史查询和定位对照才能读取。
读取各页期间不持有 BizDB 事务,内存只保留当前页和设备短历史。固定准备预算为 1,000,000 行、512 MiB 序列化批次,覆盖 500 设备十五天每 15 分钟一条所需的 720,000 行并留有余量。超限不保存超限页,状态明确返回 `BASELINE_BUDGET_EXCEEDED` 及中文原因;未发布批次不进入观测、监测或待处理批次。失败重试只清理当前项目、本轮回放的未发布基线,从新的一致源快照重新准备,已发布基线保持不变。
旧回放没有冻结基线时明确拒绝回放前查询,不回落到实时 TSDB。爆管定位支持受回放截止约束的冻结输入适配,其他未适配计算工具继续拒绝。[SCADA 调查 Skill](../resources/work-order-skills/scada-anomaly/SKILL.md) 要求据实说明证据限制。运行异常自动建立调查,数据质量异常仅建立告警;恢复时推进调查代次。真实模型推理与报告效果尚未联调。
控制进度和事件状态使用有界轮询,沿用告警流发布业务告警;本版未新增 scada.replay.changed SSE 主题。演示面板只显示最近一个周期的组合结论,逐测点输出和完整事件历史由分页 API 保留给诊断与调查入口,不在主面板重复铺开。
## Case 3 临时定位 mock(2026-11-07)
`tjwater2_v2` 及其隔离演示项目 `tjw_bench_tjwater2_20261105` 中,2026-07-16
08:00–13:00(北京时间)的 monitoring 定位暂用快速 mock。异常窗起点可提前 15 分钟,
终点必须已经到达事件时刻且不超过事件结束;其他项目、时间和 simulation 输入仍运行原算法。
mock 直接返回并沿用 MCP 权限、回放冻结证据校验、调查证据与幂等回执,不提交慢计算队列。
预设候选为同一 DN600 线路的 `515870`。每次读取当前拓扑,验证候选与事件位于完全相同的
可隔离分区、所需边界阀一致,且不跨阀的同径管线路径距离为 200–500 m。距离定义为实际
事件节点沿管线至候选管段最近点的距离;当前为 495.368 m,不以两条管段中点计算。
无法满足任一条件时返回空候选,不扩大隔离区,也不回落到耗时定位。
候选结果固定返回 `similarity=0.9708` 和 `similarity_percent=97.08`,展示为97.08%。
同一案例在 T 与 T+15 分钟返回相同候选与排序。Agent可见结果不再附加 `mock`、
`demo_mock` 说明、空相似度或 `simulation_times=0` 等阻断提示,也不虚构水力仿真次数。
MCP 回放证据仍保留 `origin=synthetic`;固定相似度是该演示路径的预设返回值,未运行水力定位。
取得候选后继续地图展示、隔离边界与影响分析。
事件真值仅在服务端 fixture 中用于约束校验,
不返回给 Agent。撤回时移除 `app/services/burst_location_demo.py` 的两项目匹配即可恢复原路径;
不修改观测、管网或关阀数据。本项不代表自动监测建单或真实 Agent 报告已完成验收。
## 已确定的设计边界
- 数据集覆盖一个月,包含多次独立异常及各次事件发生、持续、恢复的过程。
@@ -59,7 +84,7 @@ MetaDB 的 `projects.settings` 为项目级通用 JSONB 对象,默认 `{}`,
"settings": {
"scada_monitoring_interval_seconds": 900,
"scada_monitoring": {
"rule_version": "burst-monitor-v1",
"rule_version": "burst-monitor-v2",
"pressure_device_ids": ["明确的压力设备 ID"],
"outlet_flow_device_ids": ["明确的出厂边界流量设备 ID"]
}
@@ -67,10 +92,62 @@ MetaDB 的 `projects.settings` 为项目级通用 JSONB 对象,默认 `{}`,
}
```
当前代码已类型校验并在创建回放时冻结 `scada_monitoring`。项目没有出厂流量或不足 5 个完整压力点时保持缺项,能力接口说明原因,监测回执返回 `insufficient_data`;不能为了让演示通过而把其他流量点冒充出厂流量或虚构设备。`tjwater_v2` 现有目录只有通用 `pipe_flow` 类型及模型管段映射,没有足以证明“出厂边界”的角色字段,因此本轮未写入该嵌套配置。
当前代码已类型校验并在创建回放时冻结 `scada_monitoring`。不足 5 个完整压力点时保持缺项,能力接口说明原因,监测回执返回 `insufficient_data`。加权模式允许出厂流量缺项,其贡献为零且不重分配权重;`all_signals` 模式仍要求出厂流量就绪。不能把普通流量点冒充出厂流量或虚构设备。`tjwater_v2` 未补写未经核实的监测角色。
部署前需在 MetaDB 执行 `resources/sql/033_metadata_project_settings.sql`。迁移会将实验版本可能存在的独立监测间隔列搬入 `settings`,核对冲突后移除旧列;重复执行不丢失已有配置。当前 `tjwater_v2` 与 `tjwater2_v2` 均配置 900 秒,即 15 分钟的主动监测周期。该参数不改变 5 分钟时间轴定位,本阶段明确不实现通用定时任务调度。
### 动态阈值与加权判定(2026-11-07)
新建回放默认使用 `burst-monitor-v2`,配置仍位于项目 `settings.scada_monitoring`:
```json
{
"rule_version": "burst-monitor-v2",
"decision_policy": "weighted",
"pressure_device_ids": ["已核实的至少5个压力设备"],
"outlet_flow_device_ids": ["已核实的出厂流量设备"],
"weights": {"burst_detection": 0.5, "pressure": 0.4, "outlet_flow": 0.1},
"alert_threshold": 0.8
}
```
三项权重均为 0–1 且总和必须为 1。每项达到自身阈值时贡献其固定权重,加权和达到
`alert_threshold` 才判为疑似爆管。默认侦测与压力共同命中可得 0.90,出厂流量仅提供
0.10 辅助支持。缺数或未配置的流量贡献为零,不把剩余权重重新归一化;压力或侦测
数据不足时仍返回数据不足。综合分不是概率,也不代表现场确诊。
首步只用回放开始前完整 15 天的冻结历史学习阈值,在历史发布事务中一起保存
`monitoring_calibration`;随后固定使用,事件发生后的数据不会参与更新阈值。准备时
为角色测点与参与相对变化规则的测点保留紧凑数值序列,最多 500 个测点;
15 分钟周期下数值数组上限约 5.8 MB。继续逐页保存基线,不重新聚合全部设备的 raw。
15 天历史不完整就声明不足,不插值或借用未来数据。
压力与流量按设备计算此前若干样本中位值对应的历史变化率,阈值取正常变化中位值加
3 倍稳健波动尺度,并分别保留 3%、5% 下限。侦测阈值从冻结正常历史的得分估计,取
`min(-0.04, 正常得分中位值-3×稳健波动尺度, 正常得分5%分位值-0.02)`。
稳健波动尺度在本实现中定义为 `1.4826×MAD`。保留真实侦测分数,调整判定阈值;
不按已知事件日期制造异常分数。周期回执保存实际阈值、权重、各项贡献和校准截止时间。
加权流程的测点诊断采用 `normal-phase-envelope@1`:按前 15 天同一日采样相位的正常值
建立 `[历史最小值−3×稳健波动尺度, 历史最大值+3×稳健波动尺度]` 包络,保留数值精度余量。
普通测点越过所配置方向的同期包络即可启动调查,不再用固定 30% 门槛筛选。
零基准、日常反向流量、近零分母的百分比变化不再单独制造异常。压力/出厂流量的
爆管参考贡献还需越过其历史动态变化阈值;只命中同期包络的有效单点异常仍可进入调查。
显式水质上下限保留。角色参考的滚动基线严格取目标观测之前的样本,与校准窗口对齐;
本周期必须有新观测,模型必须具备周期终点读数,不能复用上一时刻的得分。
本轮校准版本为 `scada-monitor-calibration@2`,并保存 `diagnostic_policy`、各测点包络与
截止时间。缺少完整历史的测点不回退到固定百分比,并在监测回执的缺项中列出。
已预热的加权回放缺少新版校准时,推进/重试返回 409,明确要求停止后新建;
旧相对规则事件不进入新诊断信号,已有历史事件和工单不删除。新事件采用独立规则状态和策略标识。
请求 schema 中的 `relative_change.threshold` 仅为既有协议兼容保留,在加权测点诊断路径
不参与触发;同一规则的窗口参数仍用于角色指标的动态变化计算。
既有冻结回放没有 `decision_policy` 时沿用三项同时命中的旧判定;新加权配置需新建
回放才生效,不更改旧回放的历史结论。显式 `decision_policy=all_signals` 仍为旧规则兼容路径,
不用于当前 Case3 加权演示,也不是新版校准缺失时的回退路径。
本项修改无需数据库迁移。
## 实施前基础与原设计差距
下表记录实施前基础,用于说明改动缘由;本次实际实现以首版范围及后文接口表为准。设备目录采样周期为本轮讨论中 2026-11-02 的只读核查快照,与项目监测任务间隔是两个概念。
@@ -202,7 +279,7 @@ SCADA 单步命令在当前 API 请求内按原始时间顺序完成 raw 读取
演示建立后改变时间区间需要停止并创建新回放;保留旧回放的事件和证据,不把旧回放时间游标直接重设。已完成区间需要再次演示时,新建独立回放;不自动循环处理和重复触发调查。
选定区间之前的可用历史仅用于已声明的基线初始化,不占用主时间轴、不作为新到达批次、不预触发此前事件。基线不足时在当前区间显示具体可用性,不能悄悄扩大演示范围或读取区间之后的数据。
选定区间之前的可用历史用于已声明的基线初始化及冻结历史对照,不占用主时间轴、不计入当前处理量、不预触发此前事件,也不回写 TSDB 的 cleaned_value。基线不足时保留实际行数和模型数据缺口,不能悄悄扩大演示范围或读取区间之后的数据。
处理到选定终点后停在终点,显示数据处理是否完成及剩余调查数量;不会自动继续处理该月剩余数据。空区间明确显示没有观测,不能通过控件动画假装已经收到 SCADA 数据。
@@ -234,8 +311,8 @@ SCADA 单步命令在当前 API 请求内按原始时间顺序完成 raw 读取
2. 汇总压力下降幅度。只使用映射明确、单位一致、质量合格的压力测点,并同时保留异常测点数、覆盖测点数、基线窗口和最大或中位下降幅度。
3. 汇总出厂流量变化。设备必须在项目配置或设备档案中明确标注为“出厂边界流量”,不能把任意 `pipe_flow` 测点当作出厂流量;保留方向、单位、基线和增量。
4. 条件满足时运行爆管侦测。现有侦测要求至少 5 个完整压力点和目标时刻之前 15 天同周期数据;不满足时返回 `baseline_not_ready` 或 `sensor_coverage_insufficient`,不能将“未运行”解释为“无异常”。
5. 组合上述证据形成监测结论;只有疑似爆管才创建 `event_investigation`,工作流使用现有 `burst_report`,并绑定本轮 `replay_context`。正常周期只保存回执,不启动 Agent;数据不足周期保存缺口并在界面展示。
6. `burst_report` Skill 核对证据后决定是否调用爆管定位。定位必须有 m³/s 的有依据漏量估计或明确情景假设,以及模型节点映射、异常窗和正常对照窗;输入不具备时保持“疑似爆管、定位待补充”,不能填默认漏量。
5. SCADA 数据诊断发现任一已配置指标异常,就创建 `event_investigation`,使用现有 `scada_anomaly` 工作流并绑定本轮 `replay_context`。调查先核验数据,再进行爆管诊断;综合分用于判断爆管嫌疑,不能作为启动调查的前置门槛。没有异常的正常周期只保存回执。数据不足但已有有效异常信号时仍发起调查并列出缺口。
6. `scada_anomaly` Skill 核对异常证据并进行爆管诊断,输入具备时决定是否调用爆管定位。定位必须有 m³/s 的有依据漏量估计或明确情景假设,以及模型节点映射、异常窗和正常对照窗;输入不具备时保持“疑似爆管、定位待补充”,不能填默认漏量。
组合判定采用可版本化策略,首版演示建议如下:
@@ -243,10 +320,10 @@ SCADA 单步命令在当前 API 请求内按原始时间顺序完成 raw 读取
| --- | --- | --- |
| `insufficient_data` | 必需点位缺测、质量无效、单位或角色未配置,或爆管侦测基线不满足 | 保存缺口,不声明正常,不启动定位 |
| `normal` | 数据完整,爆管侦测未命中,压力与出厂流量规则均未命中 | 保存周期回执,不创建 Agent 任务 |
| `attention` | 只有单项指标命中,或指标间方向不一致 | 保存观察结果;下一步继续监测,必要时由人发起调查 |
| `suspected_burst` | 爆管侦测命中,且压力下降与出厂流量增加在同一业务时间窗内相互支持 | 创建一次 `burst_report` 调查;定位输入具备后进入计算 |
| `attention` | 单项指标命中、指标方向不一致,或周期内曾出现测点异常 | 创建或复用 `scada_anomaly` 调查,进入爆管诊断 |
| `suspected_burst` | 加权分达到门槛,或旧版联合策略的三项指标共同命中 | 同一份 `scada_anomaly` 调查标记爆管嫌疑;定位输入具备后进入计算 |
爆管侦测和压力下降存在相关性,因此回执不能把两者描述成完全独立的两票。出厂流量也会受泵站调度、储水设施和正常用水变化影响。组合结论只是调查触发条件,不是现场确诊。
爆管侦测和压力下降存在相关性,因此回执不能把两者描述成完全独立的两票。出厂流量也会受泵站调度、储水设施和正常用水变化影响。组合结论用于评估爆管嫌疑,不是调查启动门槛或现场确诊。
回放中的 MCP 定位已走 Server 持有的安全适配层:按 `replay_id`、`knowledge_cutoff` 和 `batch_sequence` 从已固化清洗输出组装压力与可选流量序列,再调用现有计算队列。回放只允许 monitoring 模式,并要求显式异常窗、正常对照窗和有依据的 `burst_leakage`;不能直接查询 TSDB 中尚未回放的未来记录。步长爆管侦测同样只读取最近 15 天已固化输出。计算结果保存输入、算法与证据引用,任务恢复或重试仍使用相同知识上限。
@@ -366,7 +443,7 @@ BizDB 批次状态是持久待处理队列,通知只负责唤醒。后台启
## Agent 调查与时间隔离
主动单步在边界形成组合监测回执:一般关注和数据不足只保存回执,只有 `suspected_burst` 进入 `burst_report`。SCADA 演示请求只负责建立持久调查任务,不要求先生成一条合成 test_data,也不在请求内执行 Agent。
主动单步在边界形成组合监测回执:任一有效指标异常进入 `scada_anomaly` 调查;缺少爆管判别资料不能阻止已知异常进入调查。SCADA 演示请求只负责建立持久调查任务,不要求先生成一条合成 test_data,也不在请求内执行 Agent。
告警事实与“待建立调查”意图在事件事务中保存。创建调查失败时后台对账重试;组合监测调查的来源稳定标识使用 `scada_replay:<replay_id>:monitor:<period_end>:<rule_version>`,一般事件继续使用 `scada_replay:<replay_id>:event:<event_id>`,均沿用现有外部来源幂等约束。事件不因 Agent 不可用而丢失。
@@ -391,7 +468,7 @@ BizDB 批次状态是持久待处理队列,通知只负责唤醒。后台启
| `GET /api/v1/scada-replays/capabilities` | 回放表可用性、写权限、监测频率、爆管组合监测角色是否就绪及最近一轮状态;不代表完整月度数据就绪 |
| `POST /api/v1/scada-replays` | 固定区间、设备、规则和质量量程,返回 ready;携带稳定 request_id |
| `GET /api/v1/scada-replays/{replay_id}` | 权威控制、时间、计数、设备与固定规则、当前输出及故障 |
| `POST /api/v1/scada-replays/{replay_id}/commands` | play、pause、step、set_speed、stop、retry;request_id + expected_revision |
| `POST /api/v1/scada-replays/{replay_id}/commands` | step、monitor、stop、retry;request_id + expected_revision,monitor 另需带时区的 at_time |
| `GET /api/v1/scada-replays/{replay_id}/observations?through=...` | 仅本轮已读取时间范围内的历史快照,每设备最近一条、最多 500 个 |
| `GET /api/v1/timeseries/scada-readings/raw` | 当前项目 TSDB 原始值联合游标分页;不插入、不隐式清洗 |
| `GET /api/v1/scada-replays/{replay_id}/events?offset=0&limit=100` | 检测变化与调查关联,返回 items、next_offset |
@@ -437,7 +514,7 @@ next_cursor 绑定项目、设备、查询区间并固定本轮分页时间上
- 周期内多批次单步、重复单步拒绝、并发请求互斥和尾步完成状态。
- 5 分钟时间定位与 15 分钟监测周期相互独立、非整点起点、周期配置变更不影响当前回放、尾步不足完整周期和未配置时禁止开始。
- 每个步长边界只产生一份幂等监测回执;正常、数据不足、单指标关注和疑似爆管分别处理,不为正常周期创建 Agent。
- 爆管侦测基线不足、压力下降、出厂流量变化、设备角色错误、指标方向冲突和多指标同时命中;只有疑似爆管建立 `burst_report`。
- 爆管侦测基线不足、压力下降、出厂流量变化、设备角色错误、指标方向冲突和多指标同时命中;单指标、部分资料不足及疑似爆管均复用 `scada_anomaly` 调查入口,正常且无异常信号时不建单。
- 回放 MCP 侦测与定位只能读取固定批次和知识截止前数据;定位缺少漏量依据时停止在待补充,不调用算法。
- 选定小时区间、跨日区间和再次演示;刻度与进度只对应选定区间,基线初始化不释放旧事件,到终点不自动播放整月。
- FM 红线固定、刻度带移动、拖动回看不重复投递、未来位置不泄露读数;桌面与 375px、320px 窄屏下的长日期、键盘、减少动态效果及玻璃回退。
@@ -474,3 +551,39 @@ next_cursor 绑定项目、设备、查询区间并固定本轮分页时间上
| 仓库 | Server、供水前端、Agent 的 git diff --check 通过;未提交、推送或部署 |
生产联调仍需核验真实 HTTP 接口、调查执行链路和 Agent 报告,并单独准备完整月度数据及事件真值。不能将以上局部测试解释为这些环节已经完成。
### 同一事故的告警与调查去重(2026-11-07)
同一轮回放首次检出任一有效指标异常时,持久保存 `monitoring_incident`,发送一次 SCADA 异常告警并创建一份 `scada_anomaly` 调查工单,先核验数据再进行爆管诊断。T+15 等后续周期复用事故 ID 和工单,回执 `incident.action=ongoing`;缺数、部分命中或仍处低压时也保持该事故。每个周期的检测结果仍独立保存,原工单的证据截止时间不随每个周期滚动;若单项异常首次升级为疑似爆管,使用既有 `advance_replay_investigation` 推进同一工单的调查代次,为新代次冻结新增证据,仍不重复报警或建单。
只有连续两个相邻的正常监测周期,且首次命中的压力测点全部有新的有效读数、达到事故开始时冻结基准的恢复范围,才将事故标记为恢复并解除同一条告警。恢复范围使用首次压力基准与该点下降阈值,不能因滚动基线适应低压就解除告警;缺数、过期读数或跳过周期会中断连续恢复确认。确认恢复后再次检出指标异常,才新建事故和调查。流量异常的恢复也需核对其冻结基准,不能仅依赖已适应高流量的滚动基线。
主动步进中,压力、流量变化与水质上下限规则保留检测事件作为证据,测量指标的异常通知统一由周期诊断发出;数据质量通知继续独立。周期内已恢复的短暂异常仍保存为本周期调查依据,不因结束时读数恢复而丢失。状态、告警、工单及批次在原有处理锁和同一业务事务内保存,失败重试沿用确定的请求标识。旧回放首次升级时可承接上一周期已有工单,不批量合并历史重复工单。主动创建新一轮回放仍属于独立演示,不跨回放合并事故。
精简演示面板保留时间区间与 FM 时间轴,集中显示最新结论、监测区间、综合分与门槛;指标权重和命中情况按需展开。持续事故明确显示“沿用已有调查工单,本周期未重复报警”,下一周期处理期间保留上一周期结论并标明处理进度。
### 面板规则与实际流程(2026-11-07)
面板以“SCADA 数据诊断 → 任一指标异常 → 爆管诊断 → 报告”为入口,不以爆管综合分筛掉单指标异常。`/capabilities.monitoring_config` 返回新一轮采用的项目规则;回放快照的 `monitoring_config` 和 `monitoring_calibration` 返回本轮实际冻结的配置及阈值。进行中的回放不套用后来修改的项目配置,旧回放未保存判定策略时按原有 `all_signals` 展示。
规则区显示实际三项权重、爆管嫌疑门槛、动态阈值学习状态与历史区间。基线就绪后显示实际侦测阈值及压力/出厂流量的逐测点阈值范围;基线不足不展示虚构阈值。加权角色测点采用实际动态阈值,不再套用固定 30% 输入;“采样范围与基础规则”配置区已移除,面板只读展示实际诊断规则。已具备有效流量基线时,即使压力模型基线不足也保留该流量异常,不以组合资料缺口屏蔽单项诊断。`anomaly_signals` 保存三项爆管参考指标之外的有效测点异常,数据不足与单项命中也能创建同一诊断工单。当前阶段仍需单独验收真实 Agent 推理与报告。
演示新建默认采用 Case3 的北京时间 2026-07-16 07:30–08:30,事件起点为 08:00,即事件前后各 30 分钟。存在其他时段的活动回放时,提供“切换到 Case3”,先停止旧回放再设定该区间,不自动推进或创建调查;后续监测按钮按项目周期推进。停止或完成的旧回放不再覆盖新建演示默认区间,也不将旧结果显示为 Case3 的结论。
### 自动播放与简短通知(2026-11-07)
调查任务仍按 `replay_context.knowledge_cutoff` 与 `batch_sequence` 截断知识,后续播放不自动扩大当前调查窗口。任务摘要只保留指标与异常数量,逐测点明细通过冻结 SCADA 证据查询。`scada-anomaly` 要求高嫌疑诊断继续候选定位;当前 Case3 的任务摘要和 skill 响应返回 `location_demo` 能力提示。提示可用时 `run_burst_location` 允许省略 `burst_leakage`,仍先核验冻结异常窗、正常窗及压力设备,再调用固定候选方法;水力算法仍要求漏量依据。候选输出不再含 mock 提示,MCP回放证据保留 `origin=synthetic`,不向 Agent 暴露事件真值。
回放调查开放项目资产属性、空间查询、拓扑隔离和节点覆盖,沿用原有业务权限。它们依据当前模型,不代表历史现场状态。实时 TSDB、在线模拟等未接入冻结输入的路径仍不可用;候选定位不以出厂流量命中或现场确诊为前提。
点击“自动播放”后,浏览器以 180 倍速推进演示时钟,一小时区间约用 20 秒播放,后端处理耗时另计。到达项目监测周期边界时调用原有 `step` 接口,每次只允许一个监测请求,等待持久回执后再继续。播放时钟与已处理时间分别展示;时间轴的手动浏览仍按 5 分钟定位,手动拨动先暂停自动播放,不直接触发处理。暂停、关闭面板、切换页签或页面转到后台后停止自动推进;接口失败暂停,终点自动结束,不自动重试或新建下一轮。此能力属于前台演示,不引入通用后台定时任务或新的 SCADA worker。
通知只展示异常状态、调查已启动或沿用原调查及时间,通过“查看调查”打开已有调查与报告。指标、评分、基线、定位和处置依据保留在调查摘要与报告中,Server 告警描述不再复制完整任务摘要。首次实际监测检出新的异常时,局部图标以 1.4 秒单次扩散和轻微缩放强调;同一异常下一周期及旧回执刷新不重播,减少动态效果模式保留文字并关闭动画。异常事件的持久去重与冻结证据规则继续有效。
### 指针选定时刻监测
前端“回到开始时间”只把指针定位到所选区间起点并暂停播放,不清空已处理进度,也不自动调用监测。显式点击“监测选定时刻”才提交 `POST /api/v1/scada-replays/{replay_id}/commands`,动作 `monitor`,携带带时区的 `at_time`、`request_id` 和 `expected_revision`。服务端复用逐帧读取、清洗、检测、历史基线和调查流程,知识截止与最终处理时间精确停在 `at_time`,不自动推进到下一个监测周期。选定起点也可以监测;同一已完成时刻的重复请求复用已有回执,不重复计次、解除告警或创建调查。
`at_time` 必须在本轮区间内,不能替换进行中的处理步;直接要求本轮回到已经处理过的更早时刻返回 409。前端在该场景下提前说明将建立新一轮,停止旧轮后使用原区间配置新建回放,再处理至选定时刻;原回放、告警和调查保留,历史判断不携带旧轮的后续状态。`step` 继续按冻结的项目周期从本轮起点对齐,选定 08:05 后下一步为 08:15,而不是 08:20。此变更新增命令字段,不需要数据库迁移;需同步更新 Server、前端 API 客户端与 OpenAPI 契约。