# AGENTS.md ## What This Is DSH (德胜河) dual-camera safety detection system. A panorama + PTZ camera pair detects people in a construction zone, captures PTZ close-ups, uploads images to S3-compatible OSS, and pushes batch reports to a third-party platform. Two subdirectories: - `dual_camera_system/` — main FastAPI service (production code) - `testrk3588/` — standalone test scripts for RK3588 NPU inference (not part of the main app) ## Running the Service ```bash # Local dev (macOS) cd dual_camera_system pip install -r requirements.txt python main.py --port 8000 # On RK3588 device conda activate rknn cd /home/admin/dsh/dual_camera_system python main.py --host 0.0.0.0 --port 8000 # Service management (on device) ./service.sh start|stop|restart|status ``` Model selection is automatic per platform via `config/detection.py:_default_model()`: - ARM64 (RK3588): uses RKNN model at `/home/admin/testrk3588/yolo26n_end2end.rknn` - macOS: uses `/Users/wenhongquan/Desktop/阿里云同步/项目/dnn/sb/model/yolo11n.pt` - Other Linux: uses `/home/wen/dsh/yolo/yolo11n.pt` Override with `--model ` and `--model-size n|s|m|l|x` CLI flags. ## Critical Quirk: Missing `config/device.py` `config/__init__.py` imports `from .device import DEVICE_CONFIG, THIRD_PARTY_CONFIG, STORAGE_CONFIG` but **no `device.py` exists in the repo**. This means `import config` will fail with `ImportError`. You must create `config/device.py` with these three dicts before the service can start. Check `devices.md` and `oss.py` for the expected shape. ## Architecture ``` main.py → app.py (FastAPI factory) ├── StreamManager (RTSP capture threads) ├── DetectorService (YOLO/RKNN inference) ├── CaptureUploader (image save + OSS upload) ├── ThirdPartyPusher (HTTP batch report to platform) └── FileCleanup workers ``` Config lives in `config/` split by concern: `camera.py`, `detection.py`, `oss.py`, `system.py`, `device.py` (missing). ## Environment & Deployment - **Target hardware**: RK3588 (Radxa Rock 5B), NPU 6 TOPS, conda env `rknn` - **Test env**: `192.168.8.3` (SSH admin/admin) - **Prod env**: `10.126.126.1` (SSH admin/admin) - **RTSP**: cameras on `192.168.8.x` (test) / `192.168.20.x` (prod), port 554 - **OSS**: S3-compatible at `http://58.213.48.57:15900`, bucket `wvp` - **API docs**: `devices.md` has full device inventory, RTSP URLs, SSH commands ## OpenCV FFmpeg Thread Safety `panorama_camera.py` sets env var before importing cv2: ```python os.environ['OPENCV_FFMPEG_CAPTURE_OPTIONS'] = 'rtsp_transport;tcp|threads;1' ``` This must happen **before** cv2 import to prevent FFmpeg `async_lock` assertion crashes. All RTSP reads go through `video_lock.py:safe_read()` with per-camera locks. ## Key Gotchas - No lint/typecheck/test tooling is configured. `.ruff_cache` and `.mypy_cache` are gitignored but no ruff/mypy config exists. - No CI/CD pipelines in the repo. - `testrk3588/` is standalone test code with its own `requirements.txt` — not a dependency of the main service. - Config has hardcoded IPs and credentials in `config/camera.py` and `config/oss.py`. These match `devices.md` — update both when changing devices. - `service.sh` hardcodes paths to `/home/admin/dsh/dual_camera_system` — only works on the RK3588 device. ## Deployment History ### 2026-08-27 标段1 (10.126.126.1) - 配置:`config/camera.py` — `install_address='德胜河桥-西侧'` - 配置:`config/system.py` — `STORAGE_CONFIG` 改为 `retention_days: 1` - 日志:`/etc/logrotate.d/dsh-dual-camera` — 10MB/5份/7天过期 - 代码:`third_party_pusher.py` — 添加第三方上报 payload 日志(第362行) - 代码:`app.py`、`core/capture_uploader.py` — `install_address` 传递链路 - 服务管理:使用 `systemctl restart|stop|start|status dsh-dual-camera` - device_id:未改动 ### 2026-08-27 标段2 (192.168.8.3 测试环境) - 配置:`config/camera.py` — `install_address` 按测试环境配置 - 代码:同上,install_address 传递链路已部署 - 服务管理:同上,systemctl ### 2026-08-27 标段3 (10.11.13.1) - 配置:`config/camera.py` — `install_address='保通桥-西侧'` - 代码:`third_party_pusher.py` — payload 日志已部署 - 服务管理:`systemctl restart dsh-dual-camera` - device_id:`93cb0645-36dd-48f2-b75a-e1a016ee92c9`(未改动) ### 2026-08-27 标段4 (10.11.12.1) - 配置:`config/camera.py` — `install_address='新芮庄桥-东侧'` - 代码:`third_party_pusher.py` — payload 日志已部署 - 服务管理:`systemctl restart dsh-dual-camera` - device_id:`356c1808-d06b-443b-b84b-ea12c6443d20`(未改动)