60 lines
2.1 KiB
Python
60 lines
2.1 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""炉层杂质预警规则引擎冒烟脚本(Issue #72)。
|
||
|
||
直接运行验证:模板规则资产可加载、规则引擎对急升温特征向量产出 P0 告警、
|
||
无异常时不告警。零第三方依赖。
|
||
"""
|
||
import importlib.util
|
||
import os
|
||
import sys
|
||
|
||
_PKG_DIR = os.path.dirname(os.path.abspath(__file__))
|
||
|
||
|
||
def _load_pkg(name, path):
|
||
if name in sys.modules:
|
||
return
|
||
spec = importlib.util.spec_from_file_location(
|
||
name, os.path.join(path, "__init__.py"),
|
||
submodule_search_locations=[path])
|
||
mod = importlib.util.module_from_spec(spec)
|
||
sys.modules[name] = mod
|
||
spec.loader.exec_module(mod)
|
||
|
||
|
||
_load_pkg("impurity_forecast", _PKG_DIR)
|
||
|
||
from impurity_forecast import AlertRuleEngine, AlertSeverity # noqa: E402
|
||
|
||
CONFIG = os.path.join(_PKG_DIR, "config", "alert_rules.template.yaml")
|
||
|
||
|
||
def main() -> int:
|
||
eng = AlertRuleEngine.from_template_config(CONFIG)
|
||
print(f"[OK] 规则配置加载: {len(eng.rules)} 条预警规则")
|
||
for r in eng.rules:
|
||
print(f" {r.describe()} (sop={r.sop or '-'})")
|
||
|
||
# 1) 正常工况不告警
|
||
normal = eng.evaluate(1, {"炉温_ema5": 850.0, "炉温_rate10": 0.01,
|
||
"氯气流量_std10": 3.0, "炉压_rate10": 0.01,
|
||
"炉层状态_mean10": 60.0})
|
||
assert not normal, "正常工况不应告警"
|
||
print("[OK] 正常工况:无告警")
|
||
|
||
# 2) 急升温 + 炉压急变 → P0 红色告警(PRD 场景A)
|
||
abnormal = eng.evaluate(2, {"炉温_ema5": 905.0, "炉温_rate10": 0.06,
|
||
"氯气流量_std10": 4.0, "炉压_rate10": 0.09,
|
||
"炉层状态_mean10": 60.0})
|
||
assert abnormal, "异常工况应触发告警"
|
||
primary = eng.primary_alert(abnormal)
|
||
assert primary.severity == AlertSeverity.P0, "主告警应为 P0"
|
||
print(f"[OK] 异常工况:主告警 {primary.severity.value}({primary.message})"
|
||
f" sop={primary.sop}")
|
||
print("炉层杂质预警规则引擎冒烟通过 ✅")
|
||
return 0
|
||
|
||
|
||
if __name__ == "__main__":
|
||
raise SystemExit(main())
|