diff --git a/app/routers/edge_compat.py b/app/routers/edge_compat.py index 2b3e7db..85c4d81 100644 --- a/app/routers/edge_compat.py +++ b/app/routers/edge_compat.py @@ -48,6 +48,7 @@ async def edge_alarm_report( # 异步触发 VLM 复核 + 企微通知(不阻塞响应) try: from app.services.notify_dispatch import process_alarm_notification + ext_data = report.ext_data or {} notify_data = { "alarm_id": alarm.alarm_id, "alarm_type": alarm.alarm_type, @@ -57,6 +58,7 @@ async def edge_alarm_report( "alarm_level": alarm.alarm_level, "snapshot_url": alarm.snapshot_url, "area_id": alarm.area_id, + "skip_vlm": ext_data.get("skip_vlm", False), } asyncio.create_task(process_alarm_notification(notify_data)) except Exception as e: diff --git a/app/services/notify_dispatch.py b/app/services/notify_dispatch.py index cf13b97..93b3b9f 100644 --- a/app/services/notify_dispatch.py +++ b/app/services/notify_dispatch.py @@ -46,11 +46,10 @@ async def process_alarm_notification(alarm_data: Dict): event_time = alarm_data.get("event_time", "") area_id = alarm_data.get("area_id") - logger.info(f"开始处理告警通知: {alarm_id}") + skip_vlm = alarm_data.get("skip_vlm", False) + logger.info(f"开始处理告警通知: {alarm_id}" + (" (跳过VLM)" if skip_vlm else "")) try: - # ========== 1. VLM 复核 ========== - vlm_service = get_vlm_service() scene_id = alarm_data.get("scene_id", "") # 查询摄像头名称(从 WVP 获取,优先 cameraName) @@ -67,29 +66,37 @@ async def process_alarm_notification(alarm_data: Dict): # snapshot_url 可能是 COS object key,需转为可访问的预签名URL presigned_snapshot_url = _get_presigned_url(snapshot_url) - vlm_result = await vlm_service.verify_alarm( - snapshot_url=presigned_snapshot_url, - alarm_type=alarm_type, - camera_name=camera_name, - roi_name=roi_name, - ) + description = "" + if not skip_vlm: + # ========== 1. VLM 复核 ========== + vlm_service = get_vlm_service() - # 写入 alarm_llm_analysis 表 - _save_vlm_result(alarm_id, vlm_result) + vlm_result = await vlm_service.verify_alarm( + snapshot_url=presigned_snapshot_url, + alarm_type=alarm_type, + camera_name=camera_name, + roi_name=roi_name, + ) - # VLM 明确判定为误报(非降级跳过)→ 更新告警状态,不通知 - if not vlm_result.get("confirmed", True) and not vlm_result.get("skipped"): - _mark_false_alarm(alarm_id) - logger.info(f"VLM 判定误报,跳过通知: {alarm_id}") - return + # 写入 alarm_llm_analysis 表 + _save_vlm_result(alarm_id, vlm_result) - # VLM 跳过(降级)且 confirmed=False → 不改告警状态,仅跳过通知 - if not vlm_result.get("confirmed", True) and vlm_result.get("skipped"): - logger.info(f"VLM 降级跳过,不推送但保留告警状态: {alarm_id}") - return + # VLM 明确判定为误报(非降级跳过)→ 更新告警状态,不通知 + if not vlm_result.get("confirmed", True) and not vlm_result.get("skipped"): + _mark_false_alarm(alarm_id) + logger.info(f"VLM 判定误报,跳过通知: {alarm_id}") + return + + # VLM 跳过(降级)且 confirmed=False → 不改告警状态,仅跳过通知 + if not vlm_result.get("confirmed", True) and vlm_result.get("skipped"): + logger.info(f"VLM 降级跳过,不推送但保留告警状态: {alarm_id}") + return + + description = vlm_result.get("description", "") + else: + logger.info(f"跳过 VLM 复核: {alarm_id}") # ========== 2. 查表获取通知人员 ========== - description = vlm_result.get("description", "") area_name = area_name_for_vlm _, area_id_int, persons = _get_notify_persons(device_id, alarm_level)