fix(service): Alarm creation without duration - aligns with ai_edge changes

Changes:
1. Modified create_from_mqtt to parse first_frame_time from MQTT data
2. Removed duration_minutes processing logic
3. Set duration_ms=None and last_frame_time=None on alarm creation
4. Updated _determine_alarm_level to handle duration_ms=None (returns level 2 for leave_post)

This ensures alarms are created with status=NEW and no duration/end time,
which will be populated later when the alarm is resolved.

Test: test_alarm_create_no_duration.py validates the new behavior.

Related: Task 2 of alarm status management fix

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-13 09:50:53 +08:00
parent 789dc6a373
commit 683791d1c9
2 changed files with 74 additions and 10 deletions

View File

@@ -28,9 +28,14 @@ def _determine_alarm_level(alarm_type: str, confidence: float, duration_ms: Opti
if alarm_type == "intrusion":
return 3 # 严重
elif alarm_type == "leave_post":
if duration_ms and duration_ms > 30 * 60 * 1000:
# 告警触发时 duration_ms 为 None设置为一般级别
if duration_ms is None:
return 2 # 一般级别(刚触发,持续时长未知)
# 根据持续时长判断级别
if duration_ms > 30 * 60 * 1000:
return 3 # 严重
elif duration_ms and duration_ms > 10 * 60 * 1000:
elif duration_ms > 10 * 60 * 1000:
return 2 # 一般
return 1 # 提醒
elif confidence and confidence > 0.9:
@@ -63,6 +68,15 @@ class AlarmEventService:
else:
event_time = datetime.now(timezone.utc)
# 解析 first_frame_time告警首次触发时间
first_frame_str = mqtt_data.get("first_frame_time")
first_frame_time = None
if first_frame_str:
try:
first_frame_time = datetime.fromisoformat(first_frame_str.replace("Z", "+00:00"))
except ValueError:
pass
# 置信度保持 float 0-1
confidence = mqtt_data.get("confidence")
if confidence is not None:
@@ -71,14 +85,9 @@ class AlarmEventService:
if confidence > 1:
confidence = confidence / 100.0
# duration_minutes → duration_ms
duration_minutes = mqtt_data.get("duration_minutes")
duration_ms = None
if duration_minutes is not None:
duration_ms = int(float(duration_minutes) * 60 * 1000)
alarm_type = mqtt_data.get("alert_type", "unknown")
alarm_level = _determine_alarm_level(alarm_type, confidence or 0, duration_ms)
# 告警创建时不传递 duration_ms,传递 None
alarm_level = _determine_alarm_level(alarm_type, confidence or 0, None)
alarm = AlarmEvent(
alarm_id=alarm_id,
@@ -87,7 +96,9 @@ class AlarmEventService:
device_id=mqtt_data.get("camera_id", "unknown"),
scene_id=mqtt_data.get("roi_id"),
event_time=event_time,
duration_ms=duration_ms,
first_frame_time=first_frame_time,
duration_ms=None,
last_frame_time=None,
alarm_level=alarm_level,
confidence_score=confidence,
alarm_status="NEW",