功能:边缘端 ROI 级告警去重 — 未 resolve 的告警不重复发送

新增 _active_alarms 字典(roi_id+alert_type → alarm_id),
告警创建时记录,resolve 时清除。同 ROI 同类型有活跃告警时跳过新告警。
解决违停/拥堵等持续性告警在冷却期过后重复触发的问题。
This commit is contained in:
2026-03-27 15:27:26 +08:00
parent 749257cb8a
commit 42a8cf3ce3

29
main.py
View File

@@ -81,6 +81,10 @@ class EdgeInferenceService:
self._camera_alert_cooldown: Dict[str, datetime] = {}
self._camera_cooldown_seconds = 30 # 同摄像头同类型告警最小间隔(秒)
# ROI级别告警去重同ROI+同类型未resolve的告警不重复发送
# key: f"{roi_id}_{alert_type}", value: alarm_id
self._active_alarms: Dict[str, str] = {}
self._logger.info("Edge_Inference_Service 初始化开始")
def _init_database(self):
@@ -801,21 +805,39 @@ class EdgeInferenceService:
# resolve 事件:更新已有告警,不创建新告警
if alert_type == "alarm_resolve":
resolve_alarm_id = alert.get("resolve_alarm_id")
resolve_data = {
"alarm_id": alert.get("resolve_alarm_id"),
"alarm_id": resolve_alarm_id,
"duration_ms": alert.get("duration_ms"),
"last_frame_time": alert.get("last_frame_time"),
"resolve_type": alert.get("resolve_type"),
}
if self._reporter:
self._reporter.report_alarm_resolve(resolve_data)
# 清除活跃告警记录,允许后续新告警
for k, v in list(self._active_alarms.items()):
if v == resolve_alarm_id:
del self._active_alarms[k]
self._logger.debug(f"[去重] 活跃告警已清除: {k} -> {resolve_alarm_id}")
break
self._logger.info(
f"离岗告警结束: alarm_id={resolve_data['alarm_id']}, "
f"告警结束: alarm_id={resolve_data['alarm_id']}, "
f"duration_ms={resolve_data['duration_ms']}, "
f"reason={resolve_data['resolve_type']}"
)
continue
# ROI级别去重同ROI+同类型有未resolve的告警时不重复发送
active_key = f"{roi_id}_{alert_type}"
if active_key in self._active_alarms:
self._logger.debug(
f"[去重] 跳过告警: roi={roi_id}, type={alert_type}, "
f"存在未结束告警={self._active_alarms[active_key]}"
)
continue
# 摄像头级别去重:同一摄像头+告警类型在冷却期内只上报一次
dedup_key = f"{camera_id}_{alert_type}"
now = frame.timestamp
@@ -868,6 +890,9 @@ class EdgeInferenceService:
)
self._reporter.report_alarm(alarm_info, screenshot=frame.image)
# 记录活跃告警(用于 ROI 级去重)
self._active_alarms[active_key] = alarm_info.alarm_id
# 回填 alarm_id 到算法实例(用于后续 resolve 追踪,泛化支持所有算法类型)
algo = self._algorithm_manager.algorithms.get(roi_id, {}).get(f"{roi_id}_{bind.bind_id}", {}).get(alert_type)
if algo and hasattr(algo, 'set_last_alarm_id'):