Commit Graph

20 Commits

Author SHA1 Message Date
37fc48e34d fix(intrusion): 修复代码质量问题 - 空值检查和常量提取
修复内容:
1. 添加 state_start_time 空值检查(CONFIRMING_INTRUSION 和 CONFIRMING_CLEAR 状态)
2. 移除 get_state() 未使用的 roi_id 参数
3. get_state() 接受 current_time 参数,避免直接调用 datetime.now()
4. 提取魔法数字:ALARM_LEVEL_INTRUSION = 3

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 10:23:14 +08:00
2d90f00b11 feat(intrusion): 添加自动告警处理功能 - 状态机和resolve事件
- 新增状态机: IDLE → CONFIRMING_INTRUSION → ALARMED → CONFIRMING_CLEAR → IDLE
- 入侵消失后,连续confirm_seconds秒无人,自动发送alarm_resolve
- 告警追踪: _last_alarm_id, _intrusion_start_time
- 冷却期逻辑保留,防止重复告警

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 10:14:46 +08:00
690eb66277 fix(aiot): 告警触发时不发送持续时长,等待回岗后再计算
修改算法层告警触发逻辑:
- 移除 duration_minutes 字段(告警触发时不计算持续时长)
- 新增 first_frame_time 字段(记录离开时间)
- 修改消息为固定文本"人员离岗告警"

持续时长改为在人员回岗时由 alarm_resolve 事件计算

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-13 09:42:25 +08:00
5b2440c467 refactor(aiot): 离岗检测算法v2.0 - 全面重构
重构目标:
- 更清晰的状态机设计
- 滑动窗口平滑检测结果
- 更准确的告警判断逻辑

核心改进:
1. 状态机优化(6个状态 → 7个状态)
   - INIT: 初始化
   - CONFIRMING_ON_DUTY: 上岗确认中
   - ON_DUTY: 在岗
   - CONFIRMING_OFF_DUTY: 离岗确认中
   - OFF_DUTY_COUNTDOWN: 离岗倒计时
   - ALARMED: 已告警
   - NON_WORK_TIME: 非工作时间

2. 滑动窗口机制
   - 10秒滑动窗口,存储检测历史
   - 计算命中率(person_count / total_frames)
   - 上岗条件:命中率 ≥ 70%(允许30%漏检)
   - 离岗条件:命中率 = 0(窗口内完全没人)

3. 参数优化
   - confirm_on_duty_sec: 上岗确认(默认10秒)
   - confirm_off_duty_sec: 离岗确认(默认30秒)
   - confirm_return_sec: 回岗确认(默认10秒)
   - leave_countdown_sec: 离岗倒计时(默认300秒)
   - 向后兼容:confirm_leave_sec → confirm_off_duty_sec

4. 状态监控增强
   - get_state() 返回详细状态信息
   - 包含倒计时剩余时间、检测命中率等

5. 日志分级
   - INFO: 关键状态转换(确认上岗、确认离岗)
   - DEBUG: 次要状态转换(进入确认状态)
   - WARNING: 告警触发

技术细节:
- 使用deque实现O(1)滑动窗口更新
- 兼容旧参数名(confirm_leave_sec)
- 回岗自动发送resolve事件
- 非工作时间自动清理状态

影响范围:
- 告警判断更准确(抗漏检干扰)
- 状态转换更合理(细化确认流程)
- 调试更友好(详细状态信息)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-12 15:41:05 +08:00
7496a6fe04 feat(aiot): 实现离岗倒计时功能 - 修复持续时长过短问题
问题描述:
- 用户反馈告警持续时长只有48秒、103秒
- 预期:离岗倒计时5分钟后才告警,持续时长应>5.5分钟
- 根因:代码在"离岗确认"后立即触发告警,缺少倒计时环节

业务流程:
1. 上岗确认期:10秒(confirm_on_duty_sec)
2. 离岗确认期:30秒(confirm_leave_sec)
3. 离岗倒计时:300秒(leave_countdown_sec)← 新增
4. 告警冷却期:600秒(cooldown_sec)

修改内容:
1. LeavePostAlgorithm 构造函数
   - 新增 leave_countdown_sec 参数(默认300秒)
   - 新增 _off_duty_start_time 状态变量
   - 新增 _alarm_triggered 告警标志

2. LEAVING → OFF_DUTY 状态转换(Line 197-207)
   - 移除立即告警逻辑
   - 进入OFF_DUTY后仅记录时间,开始倒计时

3. OFF_DUTY 状态处理(Line 209-258)
   - 新增倒计时检查:off_duty_elapsed >= leave_countdown_sec
   - 倒计时结束才触发告警
   - 人员回岗时检查是否已告警,决定是否发送resolve事件

4. 算法实例创建(Line 600-607, 701-708)
   - 从配置读取 leave_countdown_sec(默认300秒)

5. reset() 方法
   - 清理新增状态变量

影响范围:
- 告警时机:从离岗确认后立即告警 → 倒计时结束后告警
- 持续时长:现在必然 >= 330秒(30s确认 + 300s倒计时)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-12 15:06:46 +08:00
4ebded3385 fix: 统一告警resolve事件的时间戳格式
问题描述:
- 告警结束时间使用 isoformat() 包含微秒
- 导致前端显示格式不一致(2026-02-12T14:23:42.331566)

修改内容:
- algorithms.py (2处)
  - 非工作时间resolve事件(line 135)
  - 人员回岗resolve事件(line 233)
  - 使用 strftime('%Y-%m-%d %H:%M:%S') 替代 isoformat()

影响范围:
- 告警resolve事件上报格式
- 与service端时间戳格式保持一致

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-12 14:57:22 +08:00
ecebdd514f 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(离岗开始时间)
2026-02-11 17:55:35 +08:00
b6fba4639d fix(aiot): 修复离岗检测启动立即报警的三个Bug
Bug#1(严重): 无人帧不调用算法
- _batch_process_rois 中 len(boxes)>0 才调用 _handle_detections
- 导致离岗检测永远收不到"人走了"的信号
- 修复: 无论检测结果是否为空都调用算法
- 同时移除 _handle_detections 中 tracks 为空的 early return

Bug#2(高): WAITING 一帧就跳 ON_DUTY
- 检测到人第一帧就立即从 WAITING 跳到 ON_DUTY
- confirm_on_duty_sec 参数完全未被使用
- 修复: 新增 CONFIRMING 状态,需连续 10s 检测到人才确认上岗

Bug#3(中): confirm_leave_sec 默认值过短
- 默认 10 秒,用户预期 30 秒
- 修复: 所有默认值统一改为 30s

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 10:01:20 +08:00
181623428a 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>
2026-02-11 09:57:02 +08:00
3065bb948e chore: 注释掉人群聚集检测算法
- 注释 CrowdDetectionAlgorithm 类
- 注释 AlgorithmManager 中的 crowd_detection 相关代码
- 保留代码以便后续需要时启用

当前仅保留2个算法:leave_post、intrusion

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 15:16:47 +08:00
e4605e8702 fix: AlgorithmManager处理type=full配置更新时全量重载
之前_config_update_worker只处理type=roi和type=bind,
收到type=full或type=camera时静默忽略,导致全量推送不生效。
现在对未识别的type统一执行reload_all_algorithms()。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 09:59:48 +08:00
98595402c6 fix: 修复10个关键bug提升系统稳定性和性能
1. YOLO11输出解析错误: 移除不存在的objectness行,正确使用class_scores.max()
2. CPU NMS逻辑错误: keep_mask同时标记保留和抑制框导致NMS失效,改用独立suppressed集合
3. 坐标映射缺失: _build_tracks中scale_info未使用,添加revert_boxes还原到ROI裁剪空间
4. batch=1限制: 恢复真正的动态batch推理(1~8),BatchPreprocessor支持多图stack
5. 帧率控制缺失: _read_frame添加time.monotonic()间隔控制,按target_fps跳帧
6. 拉流推理耦合: 新增独立推理线程(InferenceWorker),生产者-消费者模式解耦
7. 攒批形同虚设: 添加50ms攒批窗口+max_batch阈值,替代>=1立即处理
8. LeavePost双重等待: LEAVING确认后直接触发告警,不再进入OFF_DUTY二次等待
9. register_algorithm每帧调用: 添加_registered_keys缓存,O(1)快速路径跳过
10. GPU context线程安全: TensorRT infer()内部加锁,防止多线程CUDA context竞争

附带修复:
- reset_algorithm中未定义algorithm_type变量(NameError)
- update_roi_params中循环变量key覆盖外层key
- AlertInfo缺少bind_id字段(TypeError)
- _logger.log_alert在标准logger上不存在(AttributeError)
- AlarmStateMachine死锁(Lock改为RLock)
- ROICropper.create_mask坐标解析错误
- 更新测试用例适配新API

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 16:47:26 +08:00
fa0304aa47 feat: 重构数据库schema分离空间与业务配置 - 新增algorithm_registry和roi_algo_bind表 - roi_configs简化为纯空间配置 - 新增AlgorithmInfo/ROIAlgoBind数据模型 2026-02-03 14:26:52 +08:00
0a1d61c1e2 fix: 修复 TensorRT bindings 问题
- tensorrt_engine.py 添加 pycuda 支持
- CUDA 上下文和流管理
- _is_in_working_hours 支持字符串格式
2026-02-02 14:00:21 +08:00
f90ff60f6c feat: 添加离岗时长记录
- alert_records 添加 duration_minutes 字段
- AlgorithmManager 输出 duration_minutes
- AlertRecord 添加 duration_minutes 字段
2026-01-30 17:26:12 +08:00
4632ae74f3 fix: 修复运行错误
- algorithms.py 添加 threading/redis/logger 导入
- ResultReporter 添加 report_heartbeat() 和 close() 方法
2026-01-30 15:15:09 +08:00
101b26fc95 feat: 实现配置热更新机制
数据库扩展:
- roi_configs 新增算法参数字段(working_hours, confirm_on_duty_sec等)
- 新增 config_update_log 表记录配置变更日志

Redis缓存:
- ROI/摄像头配置缓存到 Redis(TTL 1小时)
- sync_all_to_redis() 批量同步配置
- notify_config_change() 发布配置变更通知

热更新:
- AlgorithmManager 订阅 Redis config_update 频道
- load_from_redis() 从 Redis 加载算法参数
- reload_algorithm() 热更新单个算法
- reload_all_algorithms() 重新加载所有算法

配置模型:
- ROIInfo 添加算法参数字段
2026-01-30 13:51:58 +08:00
56820622c6 fix: 统一算法参数
- confirm_seconds 默认值改为 5 秒
- 同步 default_params 中的默认值为 5
2026-01-30 13:27:28 +08:00
c4baf2fd1f fix: 重构算法逻辑
LeavePostAlgorithm:
- 重构状态机:WAITING  ON_DUTY  LEAVING  OFF_DUTY
- 移除 INIT 状态,增加 LEAVING 确认期防抖动
- 添加目标类型过滤 (target_class)
- 统一使用 datetime

IntrusionAlgorithm:
- 修复冷却逻辑 Bug:只在告警后重置
- 添加确认机制:持续检测 N 秒才触发告警
- 添加目标类型过滤 (target_class)
- 二次告警时间改为 2 分钟 (120秒)

AlgorithmManager:
- 更新默认参数
- 统一参数命名
2026-01-30 13:23:22 +08:00
6733344b11 初始化边缘推理服务 2026-01-29 18:33:12 +08:00