feat(aiot): 告警冷却时间调整 + 截图本地保留 + 中文路径修复

- 离岗检测冷却时间: 300s → 600s(10分钟)
- 入侵检测冷却时间: 120s → 300s(5分钟)
- 入侵告警级别改为高(alarm_level=3)
- COS 不可用时保留本地截图文件,不再上报后删除
- 修复 cv2.imwrite 中文路径失败,改用 imencode + write_bytes
- 配置订阅在 LOCAL 模式下跳过 Redis 连接

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-11 09:57:02 +08:00
parent e828f4e09b
commit 181623428a
8 changed files with 532 additions and 66 deletions

View File

@@ -27,7 +27,7 @@ class LeavePostAlgorithm:
self,
confirm_on_duty_sec: int = 10,
confirm_leave_sec: int = 10,
cooldown_sec: int = 300,
cooldown_sec: int = 600,
working_hours: Optional[List[Dict]] = None,
target_class: Optional[str] = "person",
):
@@ -223,7 +223,7 @@ class LeavePostAlgorithm:
class IntrusionAlgorithm:
def __init__(
self,
cooldown_seconds: int = 120,
cooldown_seconds: int = 300,
confirm_seconds: int = 5,
target_class: Optional[str] = None,
):
@@ -297,6 +297,7 @@ class IntrusionAlgorithm:
"camera_id": camera_id,
"bbox": bbox,
"alert_type": "intrusion",
"alarm_level": 3,
"message": "检测到周界入侵",
}]
@@ -395,11 +396,11 @@ class AlgorithmManager:
"leave_post": {
"confirm_on_duty_sec": 10,
"confirm_leave_sec": 10,
"cooldown_sec": 300,
"cooldown_sec": 600,
"target_class": "person",
},
"intrusion": {
"cooldown_seconds": 120,
"cooldown_seconds": 300,
"confirm_seconds": 5,
"target_class": None,
},
@@ -419,6 +420,9 @@ class AlgorithmManager:
try:
from config.settings import get_settings
settings = get_settings()
if settings.config_sync_mode != "REDIS":
logger.info("CONFIG_SYNC_MODE=LOCAL: 跳过 Redis 配置订阅")
return
redis_client = redis.Redis(
host=settings.redis.host,
port=settings.redis.port,
@@ -496,7 +500,17 @@ class AlgorithmManager:
with self._update_lock:
roi_id = bind_config.get("roi_id")
algo_code = bind_config.get("algo_code", "leave_post")
params = bind_config.get("params", {})
raw_params = bind_config.get("params")
if isinstance(raw_params, str):
try:
import json
params = json.loads(raw_params) or {}
except Exception:
params = {}
elif isinstance(raw_params, dict):
params = raw_params
else:
params = {}
if roi_id not in self.algorithms:
self.algorithms[roi_id] = {}
@@ -507,7 +521,7 @@ class AlgorithmManager:
algo_params = {
"confirm_on_duty_sec": params.get("confirm_on_duty_sec", 10),
"confirm_leave_sec": params.get("confirm_leave_sec", 10),
"cooldown_sec": params.get("cooldown_sec", 300),
"cooldown_sec": params.get("cooldown_sec", 600),
"working_hours": params.get("working_hours", []),
"target_class": params.get("target_class", bind_config.get("target_class", "person")),
}
@@ -532,7 +546,7 @@ class AlgorithmManager:
logger.info(f"已从Redis加载算法: {key}")
elif algo_code == "intrusion":
algo_params = {
"cooldown_seconds": params.get("cooldown_seconds", 120),
"cooldown_seconds": params.get("cooldown_seconds", 300),
"confirm_seconds": params.get("confirm_seconds", 5),
"target_class": params.get("target_class", bind_config.get("target_class")),
}
@@ -625,13 +639,13 @@ class AlgorithmManager:
self.algorithms[roi_id][key]["leave_post"] = LeavePostAlgorithm(
confirm_on_duty_sec=algo_params.get("confirm_on_duty_sec", 10),
confirm_leave_sec=algo_params.get("confirm_leave_sec", 10),
cooldown_sec=algo_params.get("cooldown_sec", 300),
cooldown_sec=algo_params.get("cooldown_sec", 600),
working_hours=roi_working_hours,
target_class=algo_params.get("target_class", "person"),
)
elif algorithm_type == "intrusion":
self.algorithms[roi_id][key]["intrusion"] = IntrusionAlgorithm(
cooldown_seconds=algo_params.get("cooldown_seconds", 120),
cooldown_seconds=algo_params.get("cooldown_seconds", 300),
confirm_seconds=algo_params.get("confirm_seconds", 5),
target_class=algo_params.get("target_class"),
)