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

@@ -58,14 +58,26 @@ class ROICropper:
def _crop_rectangle(
self,
image: np.ndarray,
coordinates: List[List[float]]
coordinates: Union[List[List[float]], Dict[str, float]]
) -> Optional[np.ndarray]:
"""裁剪矩形区域"""
if len(coordinates) < 2:
return None
x1, y1 = int(coordinates[0][0]), int(coordinates[0][1])
x2, y2 = int(coordinates[1][0]), int(coordinates[1][1])
"""裁剪矩形区域
支持两种坐标格式:
1. dict: {"x": float, "y": float, "w": float, "h": float} — 归一化坐标(0-1)
2. list: [[x1,y1],[x2,y2]] — 像素坐标
"""
img_h, img_w = image.shape[:2]
if isinstance(coordinates, dict):
x1 = int(coordinates["x"] * img_w)
y1 = int(coordinates["y"] * img_h)
x2 = int((coordinates["x"] + coordinates["w"]) * img_w)
y2 = int((coordinates["y"] + coordinates["h"]) * img_h)
else:
if len(coordinates) < 2:
return None
x1, y1 = int(coordinates[0][0]), int(coordinates[0][1])
x2, y2 = int(coordinates[1][0]), int(coordinates[1][1])
x1 = max(0, min(x1, image.shape[1] - 1))
y1 = max(0, min(y1, image.shape[0] - 1))