feat(aiot): 离岗检测重写 - 单次告警 + 回岗确认 + 持续时长追踪
算法逻辑修改: - OFF_DUTY状态只告警一次,不再每600秒重复告警 - 人员回岗后需经CONFIRMING(10秒)重新确认才恢复ON_DUTY - 确认在岗后清除冷却记录,允许新一轮离岗检测 - 非工作时间进入时清除冷却记录 持续时长追踪(新增resolve机制): - 离岗告警记录alarm_id和leave_start_time - 人员回岗确认后生成resolve事件(duration_ms + last_frame_time) - 进入非工作时间时也生成resolve事件 - ResultReporter新增report_alarm_resolve()写入Redis队列 - AlarmUploadWorker新增_process_resolve() HTTP POST到云端 - main.py区分普通告警和resolve事件,回填alarm_id到算法实例 - 告警ext_data附加first_frame_time(离岗开始时间)
This commit is contained in:
@@ -173,6 +173,11 @@ class AlarmUploadWorker:
|
||||
self._logger.error(f"告警 JSON 解析失败: {e}")
|
||||
return
|
||||
|
||||
# 如果是 resolve 事件,走单独的处理逻辑
|
||||
if alarm_data.get("_type") == "resolve":
|
||||
self._process_resolve(alarm_data)
|
||||
return
|
||||
|
||||
alarm_id = alarm_data.get("alarm_id", "unknown")
|
||||
retry_count = alarm_data.get("_retry_count", 0)
|
||||
|
||||
@@ -241,6 +246,36 @@ class AlarmUploadWorker:
|
||||
# HTTP 上报失败,进入重试
|
||||
self._handle_retry(alarm_json, "HTTP 上报失败")
|
||||
|
||||
def _process_resolve(self, resolve_data: dict):
|
||||
"""处理告警结束事件 - HTTP POST 到云端"""
|
||||
upload_cfg = self._settings.alarm_upload
|
||||
base_url = upload_cfg.cloud_api_url.rstrip("/")
|
||||
url = f"{base_url}/admin-api/aiot/alarm/edge/resolve"
|
||||
|
||||
headers = {"Content-Type": "application/json"}
|
||||
if upload_cfg.edge_token:
|
||||
headers["Authorization"] = f"Bearer {upload_cfg.edge_token}"
|
||||
|
||||
payload = {
|
||||
"alarm_id": resolve_data.get("alarm_id"),
|
||||
"duration_ms": resolve_data.get("duration_ms"),
|
||||
"last_frame_time": resolve_data.get("last_frame_time"),
|
||||
"resolve_type": resolve_data.get("resolve_type"),
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.post(url, json=payload, headers=headers, timeout=10)
|
||||
if response.status_code == 200:
|
||||
body = response.json()
|
||||
if body.get("code") == 0:
|
||||
self._logger.info(f"告警结束上报成功: {resolve_data.get('alarm_id')}")
|
||||
else:
|
||||
self._logger.warning(f"告警结束上报业务错误: {body}")
|
||||
else:
|
||||
self._logger.warning(f"告警结束上报失败: status={response.status_code}")
|
||||
except Exception as e:
|
||||
self._logger.warning(f"告警结束上报异常: {e}")
|
||||
|
||||
def _upload_snapshot_to_cos(
|
||||
self, local_path: str, alarm_id: str, device_id: str
|
||||
) -> Optional[str]:
|
||||
|
||||
Reference in New Issue
Block a user