diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..c28a7e0 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,366 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## 项目概述 + +边缘 AI 推理服务,部署在客户现场边缘端。通过 TensorRT GPU 加速实时分析视频流,检测离岗、入侵等异常行为,上报告警到云端。支持配置热更新、截图上传、告警去重等功能。 + +**部署位置:** 边缘端(客户现场) +**运行方式:** 裸机部署或 Docker(需要 GPU 支持) +**主要功能:** +- RTSP 视频流接入(从 WVP 平台拉流) +- TensorRT GPU 推理(批量处理,8 帧/批次) +- 多算法支持(leave_post 离岗、intrusion 入侵) +- 告警去重(ROI 级 + 摄像头级冷却) +- 配置热更新(Redis Stream 订阅) +- 截图上传(腾讯云 COS) +- 告警上报(HTTP POST 到云端) + +## 常用命令 + +### 本地开发 + +```bash +# 安装依赖(Python 3.8+) +pip install -r requirements.txt + +# 配置环境 +cp .env.example .env +# 编辑 .env: +# DEVICE_ID=edge_device_001 +# CLOUD_REDIS_HOST=腾讯云Redis地址 +# CLOUD_REDIS_PORT=6379 +# CLOUD_REDIS_PASSWORD=密码 +# LOCAL_REDIS_HOST=localhost +# LOCAL_REDIS_PORT=6379 +# COS_SECRET_ID=腾讯云COS密钥ID +# COS_SECRET_KEY=腾讯云COS密钥KEY +# COS_BUCKET=your-bucket +# COS_REGION=ap-beijing +# CLOUD_API_URL=http://云端IP:8000 + +# 运行推理服务 +python main.py +``` + +### 测试 + +```bash +# 运行完整工作流测试 +python test_leave_post_full_workflow.py + +# 运行无持续时长测试 +python test_leave_post_no_duration.py + +# 运行单元测试 +pytest tests/ +pytest -v tests/test_config_sync.py +``` + +### 工具脚本 + +```bash +# 诊断缺失摄像头配置 +python diagnose_missing_cameras.py + +# 清理旧的 ROI 配置 +python cleanup_old_rois.py + +# 恢复摄像头配置 +python restore_cameras.py +``` + +### Docker 部署(生产环境) + +```bash +# 构建镜像(需要 CUDA 12.1 + TensorRT 8.6 基础镜像) +docker build -t edge-inference:latest . + +# 运行容器(需要 GPU 支持) +docker run -d \ + --name edge-inference \ + --gpus all \ + --restart=always \ + -v /path/to/models:/app/models \ + -v /path/to/.env:/app/.env \ + -v /path/to/data:/app/data \ + edge-inference:latest + +# 查看日志 +docker logs -f edge-inference + +# 重启容器 +docker restart edge-inference + +# 进入容器调试 +docker exec -it edge-inference /bin/bash + +# 检查 GPU 使用情况 +nvidia-smi +``` + +## 架构概览 + +### 核心模块(core/) + +- **config_sync.py** — 配置同步管理器 + - 订阅云端 Redis Stream: `device_config_stream` + - 拉取配置:`GET device:{device_id}:config` + - 版本控制、自动回滚、离线可用 + - 热更新视频流(启停摄像头) + +- **video_stream.py** — 多流管理器 + - RTSP 拉流、解码、帧缓存 + - 多路并发处理 + - 流状态监控、自动重连 + +- **preprocessor.py** — 图像预处理 + - Resize、Normalize、NCHW 转换 + - 批量预处理(8 帧/批次) + +- **tensorrt_engine.py** — TensorRT 推理引擎 + - Engine 缓存管理 + - 批量推理(提升吞吐量) + - GPU 内存优化 + +- **postprocessor.py** — 后处理器 + - NMS(非极大值抑制) + - ROI 区域过滤(point-in-polygon) + - 算法分发(根据 algorithm_code) + +- **result_reporter.py** — 结果上报器 + - 生成 alarm_id:`edge_{device_id}_{timestamp}_{uuid6}` + - LPUSH 到本地 Redis: `local:alarm:pending` + - 零阻塞(立即返回) + +- **alarm_upload_worker.py** — 告警上传 Worker + - 独立线程,BRPOP 消费队列 + - 上传截图到腾讯云 COS + - HTTP POST 到云端:`/api/ai/alert/edge/report` + - 失败重试(3 次)→ 死信队列 + +- **screenshot_handler.py** — 截图处理器 + - XREADGROUP 订阅云端 Redis Stream: `edge_snap_request` + - 从视频流获取最新帧 + - 上传 COS,HTTP 回调 WVP + +### 算法模块(algorithms.py) + +**已实现算法:** +- **LeavePostAlgorithm** — 离岗检测 + - 检测 ROI 内是否有人 + - 持续无人触发告警 + - 人员回归发送 resolve 通知 + +- **IntrusionAlgorithm** — 入侵检测 + - 检测 ROI 内是否有人入侵 + - 立即触发告警 + +**算法接口:** +```python +class AlgorithmBase: + def process(self, detections, roi_info, camera_id, bind_info): + """ + 处理检测结果 + Args: + detections: 检测框列表 [{class_id, confidence, bbox}] + roi_info: ROI 配置 {roi_id, polygon, ...} + camera_id: 摄像头 ID + bind_info: 算法绑定配置 {threshold, cooldown, ...} + Returns: + 告警信息或 None + """ + pass +``` + +### 数据流 + +``` +配置下发: + WVP → XADD device_config_stream → Edge XREADGROUP + → 拉取 Redis config → 版本校验 → 热更新视频流 + +视频推理: + RTSP 拉流 → 解码 → 预处理 → TensorRT 推理 + → NMS → ROI 过滤 → 算法处理 → 告警去重 + → LPUSH local:alarm:pending + +告警上报: + BRPOP 队列 → 上传 COS 截图 → HTTP POST 云端 + → 失败重试 → 死信队列 + +截图请求: + WVP → XADD edge_snap_request → Edge XREADGROUP + → 获取帧 → 上传 COS → HTTP 回调 WVP +``` + +## Redis Key 设计 + +### 云端 Redis +- `device:{device_id}:config` — 设备最新配置 JSON +- `device:{device_id}:version` — 配置版本号 +- `device_config_stream` — 配置变更 Stream +- `edge_snap_request` — 截图请求 Stream + +### 本地 Redis +- `local:device:config:current` — 当前生效配置 +- `local:device:config:backup` — 上次成功配置(回滚用) +- `local:device:config:version` — 当前版本号 +- `local:alarm:pending` — 待上报告警队列 +- `local:alarm:retry` — 重试队列 +- `local:alarm:dead` — 死信队列 + +## 配置文件 + +### .env 环境变量(关键配置) + +```bash +# 设备标识 +DEVICE_ID=edge_device_001 + +# 云端 Redis(配置同步) +CLOUD_REDIS_HOST=腾讯云Redis地址 +CLOUD_REDIS_PORT=6379 +CLOUD_REDIS_PASSWORD=密码 + +# 本地 Redis(告警队列、配置缓存) +LOCAL_REDIS_HOST=localhost +LOCAL_REDIS_PORT=6379 + +# 腾讯云 COS(截图上传) +COS_SECRET_ID=your_secret_id +COS_SECRET_KEY=your_secret_key +COS_BUCKET=your-bucket-1234567890 +COS_REGION=ap-beijing + +# 云端 API(告警上报) +CLOUD_API_URL=http://云端IP:8000 +``` + +### config/ 目录(YAML 配置) + +- `settings.py` — 配置加载器(读取 .env) +- `database.py` — SQLite 管理器(本地配置持久化) +- `config_models.py` — 配置数据模型 + +## 告警上报数据格式 + +### 告警触发(POST /api/ai/alert/edge/report) + +```json +{ + "alarm_id": "edge_device001_20260305120000_a1b2c3", + "alarm_type": "leave_post", + "device_id": "camera_001", + "scene_id": "roi_001", + "event_time": "2026-03-05T12:00:00Z", + "alarm_level": 2, + "snapshot_url": "https://cos.ap-beijing.myqcloud.com/...", + "confidence_score": 0.92, + "algorithm_code": "YOLO", + "ext_data": { + "bind_id": "bind_123", + "bbox": [100, 100, 300, 400], + "first_frame_time": "2026-03-05T12:00:00Z" + } +} +``` + +### 告警结束(POST /api/ai/alert/edge/resolve) + +```json +{ + "alarm_id": "edge_device001_20260305120000_a1b2c3", + "duration_ms": 120000, + "last_frame_time": "2026-03-05T12:02:00Z", + "resolve_type": "PERSON_RETURN" +} +``` + +## 开发工作流 + +### 添加新算法 +1. 在 `algorithms.py` 创建新的算法类,继承 `AlgorithmBase` +2. 实现 `process()` 方法 +3. 在 `AlgorithmManager` 注册算法 +4. 更新 WVP 后端的算法配置表 + +### 修改推理流程 +1. 修改 `main.py` 中的 `EdgeInferenceService` +2. 调整批量大小:`self._max_batch_size` +3. 调整冷却时间:`self._camera_cooldown_seconds` + +### 调整告警去重策略 +- ROI 级冷却:每个 ROI 独立冷却 +- 摄像头级冷却:同摄像头同类型告警冷却 +- 修改:`main.py` 中的 `_camera_alert_cooldown` 逻辑 + +### 优化性能 +1. **批量推理**:调整 `_max_batch_size`(默认 8) +2. **GPU 内存**:减少视频流并发数 +3. **告警队列**:监控 Redis 队列长度 +4. **TensorRT 引擎**:确保引擎缓存命中 + +## 常见问题 + +### TensorRT 引擎加载慢 +首次运行会构建引擎(5-10 分钟),之后会缓存。 +检查 `models/` 目录下是否有 `.engine` 文件。 + +### 告警上报失败 +检查云端 API 是否可达: +```bash +curl http://云端IP:8000/health +``` + +检查 COS 配置: +```bash +# 查看 .env 中的 COS 配置 +cat .env | grep COS +``` + +### 配置不更新 +检查云端 Redis 连接: +```bash +redis-cli -h 云端Redis地址 -p 6379 -a 密码 ping +``` + +检查配置版本: +```bash +redis-cli GET device:edge_device_001:version +redis-cli GET local:device:config:version +``` + +### 视频流断开 +检查 RTSP 地址是否可访问: +```bash +ffprobe rtsp://云端IP:10002/... +``` + +检查 WVP 流媒体服务: +```bash +docker logs vsp-zlmedia +``` + +### GPU 内存不足 +降低批量大小或减少并发流数量。 +检查 GPU 使用情况: +```bash +nvidia-smi +``` + +## Git 提交规范 + +在修改代码后,使用中文提交信息: + +```bash +git add . +git commit -m "功能:添加XXX功能 + +详细说明... + +Co-Authored-By: Claude Sonnet 4.5 " +``` + +**不要立即 push**,等待用户指示再推送到远程。