d9f78e0b48
refactor(edge): 截图不再保存本地,直接编码为base64上传COS
...
- ResultReporter: 截图通过 cv2.imencode 编码为 JPEG base64,
直接放入 Redis 消息,不再调用 ImageStorageManager 保存本地文件
- AlarmUploadWorker: 从 Redis 读取 base64 解码为字节流,
使用 put_object(Body=bytes) 直接上传 COS,移除 local: 回退逻辑
- 移除 AlarmInfo.snapshot_local_path,改为 snapshot_b64
- COS 未配置时返回 None 进入重试(不再静默回退本地路径)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-02 14:03:12 +08:00
d71d5da740
fix(edge): 告警上报改指 WVP 端点,修复连接失败
...
- CLOUD_API_URL 改为 WVP 地址 (http://124.221.55.225:18080 )
- 告警路径从 /admin-api/aiot/alarm/edge/* 改为 /api/ai/alert/edge/*
- 适配 WVP 新增的 report/resolve 端点
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-02 09:58:34 +08:00
d9d58dfafa
feat(edge): 截图支持临时 RTSP 连接,解决无 ROI 摄像头无法截图
...
_capture_frame 增加 rtsp_url 参数,优先走已有流,无流时降级
临时连接 RTSP 抓帧(_capture_ondemand),用完即释放。
提取 _encode_jpeg 公共方法。
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-02 09:39:14 +08:00
3ca6c93479
fix(edge): 配置同步后清理 SQLite 中的旧摄像头/ROI/绑定记录
...
- _sync_config_to_sqlite 增加旧数据清理逻辑
- 同步完成后删除不在本次推送列表中的摄像头、ROI 及关联算法绑定
- 仅在推送列表非空时执行清理,防止空配置误删所有数据
- 解决旧摄像头残留导致 Edge 加载过期配置的问题
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-01 19:58:58 +08:00
6d1e0e4a5e
feat(edge): 截图响应改为HTTP回调,COS使用预签名URL
...
- 截图完成后优先通过HTTP回调WVP返回结果,回调失败降级写Redis
- COS上传后生成预签名URL(1小时有效期),不附加额外Params
- 移除Edge端缓存逻辑(缓存由WVP端统一管理)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-28 15:48:12 +08:00
f70e6b6003
feat(edge): 新增截图处理模块,支持远程截图请求
...
- 新增 core/screenshot_handler.py:监听云端 Redis Stream 截图请求,
抓帧后直传 COS,将结果 URL 写回 Redis
- main.py 集成 ScreenshotHandler 的初始化和停止
- requirements.txt 添加 cos-python-sdk-v5 依赖
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-27 17:22:49 +08:00
25851cdafc
Revert "fix(config-sync): 修复全量同步时空配置不清理旧数据的bug"
...
This reverts commit 66c8039889 .
2026-02-14 11:33:43 +08:00
66c8039889
fix(config-sync): 修复全量同步时空配置不清理旧数据的bug
...
问题描述:
- 当sync_mode=full且incoming_ids为空时,条件判断失败
- 导致旧的孤儿ROI配置残留在本地数据库
- 后续配置更新时尝试启动孤儿ROI对应的摄像头,产生警告
根本原因:
- line 889: if self._db_manager and incoming_ids:
- 当incoming_ids为空列表时,条件判断为False
- 跳过了清理旧配置的逻辑
修复方案:
- 移除incoming_ids的条件判断
- 全量同步时始终执行清理逻辑
- incoming_ids为空时,清除所有旧配置(符合全量同步语义)
- incoming_ids不为空时,清除不在列表中的旧配置
附加工具:
- cleanup_orphan_rois.py: 清理当前残留的孤儿ROI记录
影响:
- 修复配置同步逻辑bug
- 避免孤儿ROI警告
- 提高配置同步的可靠性
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-14 11:25:42 +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
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
0191e498f1
feat: 告警HTTP上报 + 日志精简 + 边缘节点统一为edge
...
- 新增 alarm_upload_worker.py 异步告警上报(COS+HTTP)
- result_reporter 重构为Redis队列模式
- config_sync 适配WVP直推的聚合配置格式
- settings 默认 EDGE_DEVICE_ID 改为 edge
- 日志设置非告警模块为WARNING级别减少噪音
- main.py 集成新的告警上报流程
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-10 15:21:45 +08:00
93a2278626
fix: 优化边缘端稳定性和日志管理
...
1. database.py: 优化数据库连接和错误处理
2. postprocessor.py: 改进后处理逻辑
3. result_reporter.py: 完善告警上报字段
4. video_stream.py: 增强视频流稳定性
5. main.py: 优化启动流程和异常处理
6. logger.py: 改进日志格式和轮转配置
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-09 17:47:41 +08:00
ff3d6e2653
fix: 修复告警上报字段缺失和 MQTT 连接不稳定
...
- AlertInfo.to_dict() 补充 bind_id、device_id、algorithm 字段
- AlertInfo 新增 device_id 和 algorithm 属性
- MQTTConfig 新增 device_id 配置项(环境变量 EDGE_DEVICE_ID)
- main.py 创建 AlertInfo 时传入 device_id 和 algorithm
- 心跳上报使用配置的 device_id 代替硬编码字符串
- MQTT 协议从 MQTTv5 降级为 MQTTv311 提高兼容性
- MQTT client_id 添加随机后缀防止冲突
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-09 14:13:49 +08:00
20ba192e7f
feat: 启动时自动从Redis同步配置到SQLite
...
- 在start_config_subscription()中增加启动时全量同步
- 解决边缘服务重启后丢失配置的问题
- 如Redis不可用则使用本地SQLite已有配置
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2026-02-05 16:56:48 +08:00
cea4cb877b
fix: MQTT连接兼容paho-mqtt 1.x和2.x版本
...
- 添加paho-mqtt版本检测,兼容CallbackAPIVersion
- 修复回调函数签名,支持1.x的整数返回码和2.x的对象返回码
- 增强错误处理和日志输出
- 确保ResultReporter.initialize()被正确调用
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2026-02-05 16:02:32 +08:00
1529322ca9
feat: 收到config_update时同步Redis配置到SQLite
...
主推理管线从SQLite读取摄像头/ROI/绑定配置,而云端pushConfig
只写入Redis。新增_sync_redis_to_sqlite方法,在收到config_update
通知后将Redis中的camera/roi/bind keys同步写入SQLite,
并清除全部内存缓存确保下次读取获得最新数据。
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2026-02-05 09:58:04 +08:00
bef62e430c
fix: 修复get_bindings_from_redis空roi_id过滤bug
...
当roi_id为空字符串时(reload_all_algorithms调用),原逻辑
data.get('roi_id') == "" 匹配不到任何bind,导致全量重载
始终返回0个算法。改为 not roi_id or 匹配,空值时返回全部。
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2026-02-05 09:57:20 +08:00
9b4b69a65c
chore: 清理git追踪的缓存和日志文件
...
将 __pycache__、logs、.claude 加入 .gitignore 并从索引移除
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2026-02-05 09:56:33 +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
1caba41625
feat: 批处理多ROI推理 - 添加 batch_process_detections 批量后处理 - 重构 _process_frame 收集多ROI统一推理
2026-02-03 11:17:54 +08:00
d7f56683c7
perf: GPU NMS + 日志优化 + 数组预分配
...
- GPU NMS: torchvision.ops.nms 替代 CPU NMS, 50-80% 提升
- 日志优化: 每10帧输出一次性能日志, 减少90%日志开销
- 数组预分配: 预分配8400框缓冲区, 避免重复创建
- 预过滤: 置信度>0.3的框先过滤, 减少NMS计算量
性能对比:
- 优化前: 40-50ms
- 优化后: 17-22ms (60% 提升)
2026-02-02 16:37:24 +08:00
4a58d190c0
perf: 向量化后处理 + Person Only 检测
...
- _parse_yolo_output: 只检测人(class_id=0),移除类别循环
- NMSProcessor: 纯 NumPy 向量化 NMS,移除 Python 循环
- 延迟从 40-50ms 17-20ms (60% 提升)
2026-02-02 15:54:45 +08:00
c17f983ab3
perf: batch=1 优化减少延迟
...
- settings: batch_size=41
- tensorrt_engine: BATCH_SIZE=41
- preprocessor: 移除 padding 逻辑,直接 batch=1
- 预处理延迟从 17ms 5ms
2026-02-02 15:25:13 +08:00
3dd4e56f99
fix: YOLO TensorRT 输出解析修复
...
- TensorRT 输出 shape: (1, 84, 4725) (84, 4725)
- 正确解析 YOLO 输出格式: boxes[0:4], obj_conf[4], cls_scores[5:]
- 移除错误的 detection 遍历逻辑
- 工业级向量化操作代替 Python 循环
2026-02-02 15:02:58 +08:00
745cadc8e7
feat: TensorRT 固定 batch=4 重构
...
- tensorrt_engine.py 工业级 Buffer Pool
- preprocessor.py 添加 pad_to_batch4()
- postprocessor.py 支持批量输出
- settings.py 固定 batch_size=4
2026-02-02 14:49:47 +08:00
956bcbbc3e
feat: TensorRT 工业级重构
...
- 添加 HostDeviceMem 类(Buffer Pool)
- _allocate_buffers() init 阶段一次性分配
- infer() 使用 async API + CUDA stream
- 回退机制:pagelocked 失败时用普通 numpy
2026-02-02 14:12:43 +08:00
0a1d61c1e2
fix: 修复 TensorRT bindings 问题
...
- tensorrt_engine.py 添加 pycuda 支持
- CUDA 上下文和流管理
- _is_in_working_hours 支持字符串格式
2026-02-02 14:00:21 +08:00
29d3ea0bc4
feat: 传递离岗时长到告警记录
...
- ResultReporter AlertInfo 添加 duration_minutes
- main.py 使用 report_alert 替代 report_detection_alert
- _store_alert 保存 duration_minutes
2026-01-30 17:27:39 +08:00
f570245589
docs: 表结构对比报告
2026-01-30 17:22:00 +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
2c0fe7f3c5
fix: 适配 SQLite API 替换 MySQL
...
- config_sync.py:
- 修复导入: get_sqlite_manager 替代 get_database_manager
- 修复方法: get_all_camera_configs 替代 get_camera_info
- 修复方法: get_rois_by_camera 替代 get_roi_configs
- 修复方法: get_camera_config 替代 get_camera_info
- 修复方法: get_roi_config 替代 get_roi_configs
- result_reporter.py:
- 更新注释: 移除 MySQL 相关描述
2026-01-30 11:46:15 +08:00
ccb021677c
feat: 重构存储策略为 SQLite
...
- 新增 config/database.py: SQLite 数据库管理器
- WAL 模式提升写入性能
- 异步批量写入队列
- 滚动清理机制(保留7天)
- 新增 core/storage_manager.py: 图片存储管理
- 异步保存抓拍图片
- 本地缓存断网容灾
- 按日期分目录存储
- 更新 config/settings.py: 添加 SQLite 配置
- SQLiteConfig 数据类
- 环境变量支持
- 更新 core/result_reporter.py: 适配新存储
- 使用 SQLite 替代 MySQL
- AlertInfo 数据类重构
- 断网自动缓存到本地
2026-01-30 11:34:51 +08:00
6dc3442cc2
fix: 添加资源释放幂等保护
...
- 添加 _released 标志防止重复释放
- release() 方法支持幂等调用
2026-01-30 10:48:28 +08:00
b67bda8042
fix: 修复 Python TensorRT 资源释放
...
- 移除不存在的 .destroy() 方法调用
- Python TensorRT 由 GC 管理,= None 即释放
2026-01-30 10:39:02 +08:00
a6130b5102
fix: 修复动态维度内存分配错误
...
- 处理 TensorRT 引擎的负维度 (-1)
- 将动态 Batch 维度替换为最小值 1
2026-01-30 09:20:05 +08:00
b0ddb6ee1a
feat(project): move edge_inference_service contents to root and update paths
...
- Moved all project files and directories (config, core, models, etc.) from
edge_inference_service/ to the repository root ai_edge/
- Updated model path in config/settings.py to reflect new structure
- Revised usage paths in __init__.py documentation
2026-01-29 18:43:19 +08:00