4. 报警分级规则引擎
固定阈值分级只能回答“当前值是否越限”,而真实设备报警往往需要回答更复杂的问题:这个越限持续了多久?是否同时满足多个测点条件?当两条规则给出不同级别时,最终应该听谁的?规则引擎的价值,就是把“分级判断”从散落在代码里的 if-else 中抽离出来,变成可配置、可解释、可追溯的规则集合。
规则引擎的基本工作模型可以概括为:事实(Fact)进入工作内存 → 规则条件(LHS)匹配 → 冲突集(Agenda)产生 → 冲突消解策略选择 → 执行动作(RHS)输出分级结果。其中“冲突消解”正是处理优先级冲突的核心环节。下面这张图展示了从设备测点数据到最终报警级别的完整规则处理链路,包括阈值规则、持续时间规则、组合条件规则以及优先级仲裁的汇合点。
规则的四类核心要素
一条报警分级规则通常由四部分构成:条件(LHS)、动作(RHS)、优先级(salience)和生效范围(agenda-group / activation-group)。条件决定“什么时候触发”,动作决定“输出什么级别”,优先级决定“多条规则同时命中时谁先执行”,生效范围决定“哪些规则互斥、哪些规则可以并行”。
以温度测点为例,可以定义三条规则:
rule "温度预警"
salience 10
when
$t : Temperature( value > 85, value <= 95 )
then
raiseAlarm("TEMP_HIGH", "预警", $t.getValue());
end
rule "温度严重"
salience 20
when
$t : Temperature( value > 95 )
then
raiseAlarm("TEMP_CRITICAL", "严重", $t.getValue());
end
rule "温度持续升级"
salience 30
when
$t : Temperature( value > 85 )
$w : DurationWindow( duration >= 30s )
then
raiseAlarm("TEMP_SUSTAINED", "严重", $t.getValue());
end
当温度达到 96℃ 且持续 35 秒时,三条规则可能同时命中。此时 salience 最高的“温度持续升级”先执行,输出“严重”;“温度严重”也输出“严重”;“温度预警”输出“预警”。最终结果取最高级别“严重”,并记录触发规则为 TEMP_SUSTAINED。这就是冲突消解的基本逻辑:先按优先级排序,再按严重度合并。
持续时间规则的实现要点
持续时间规则不能简单地在单次事实中判断,需要引入滑动窗口或状态累积。常见做法有两种:一是用规则引擎的 DurationWindow 事实,由外部定时器每 5 秒更新一次窗口内满足条件的持续时长;二是在规则中维护一个 Accumulate 累积器,统计最近 N 个采样点中连续越限的次数。
以 1 秒采样周期为例,若要求“温度 > 85℃ 持续 30 秒”,则窗口内需要至少 30 个连续采样点满足条件。规则可以写成:
rule "温度持续30秒升级"
salience 30
when
$t : Temperature( value > 85 )
accumulate(
$s : Temperature( value > 85 ) over window:length(30),
$cnt : count($s);
$cnt >= 30
)
then
raiseAlarm("TEMP_SUSTAINED", "严重", $t.getValue());
end
这里的关键参数是窗口长度和采样周期。窗口长度 30 对应 30 秒,前提是采样周期为 1 秒。如果采样周期变为 500 毫秒,窗口长度应调整为 60,否则持续时间判断会缩短一半。工程上建议把窗口长度和采样周期都作为可配置参数,避免硬编码。
组合条件与优先级冲突的工程处理
组合条件规则用于表达“多个测点同时异常”的场景。例如“温度 > 85℃ 且 振动 > 4.5mm/s”比单一温度越限更严重,因为两者同时出现往往意味着设备存在复合故障。组合条件规则的 salience 通常设置得比单条件规则更高,以确保复合异常优先输出。
优先级冲突的常见来源有三类:同一测点的不同阈值规则冲突、不同测点的规则同时命中、持续时间规则与瞬时规则冲突。处理策略如下:
- 同一测点不同阈值:按 salience 排序,高优先级先执行;若输出级别不同,取最高级别。
- 不同测点同时命中:若属于同一设备,合并为一条报警,级别取最高,证据字段记录所有触发测点。
- 持续时间规则与瞬时规则冲突:持续时间规则 salience 更高,因为它代表异常已持续,风险更高。
- 互斥规则:使用 activation-group 分组,同组内只执行 salience 最高的一条,避免重复报警。
一个可执行的规则配置示例
下面给出一个面向温度与振动测点的规则配置表,可直接作为规则引擎的输入。表中 salience 值越大优先级越高,activation-group 相同的规则互斥。
| 规则ID | 条件 | 输出级别 | salience | activation-group |
|---|---|---|---|---|
| TEMP_WARN | 温度 > 85 且 ≤ 95 | 预警 | 10 | temp_level |
| TEMP_CRIT | 温度 > 95 | 严重 | 20 | temp_level |
| TEMP_SUSTAINED | 温度 > 85 持续 ≥ 30s | 严重 | 30 | temp_level |
| VIB_WARN | 振动 > 4.5 且 ≤ 7.1 | 预警 | 10 | vib_level |
| VIB_CRIT | 振动 > 7.1 | 严重 | 20 | vib_level |
| COMBO_CRIT | 温度 > 85 且 振动 > 4.5 | 严重 | 40 | combo_level |
假设某时刻温度 88℃、振动 5.2mm/s,且温度已持续 35 秒。此时 TEMP_WARN、TEMP_SUSTAINED、VIB_WARN、COMBO_CRIT 四条规则同时命中。按 salience 排序:COMBO_CRIT(40)先执行,输出“严重”;TEMP_SUSTAINED(30)输出“严重”;TEMP_WARN(10)和 VIB_WARN(10)输出“预警”。最终合并结果为“严重”,触发规则记录为 COMBO_CRIT 和 TEMP_SUSTAINED,证据字段包含温度 88℃、振动 5.2mm/s、持续 35 秒。