# 本地模块与事件合约 > Silver Pose 没有后端 API;本文定义 V1/V2 必须保持一致的本地配置、数据和事件合约。 ## 配置合约 `v1/config.example.json` 的最小形状: ```json { "source": { "id": "lobby-camera-01", "rtsp_url_env": "SILVER_POSE_RTSP_URL", "roi_normalized": [0.0, 0.0, 1.0, 1.0] }, "model": { "path": "models/best.pt", "sha256": "0000000000000000000000000000000000000000000000000000000000000000", "confidence_threshold": 0.25 }, "event": { "keypoint_confidence_threshold": 0.4, "suspect_window_seconds": 0.5, "confirm_window_seconds": 1.0, "recovery_window_seconds": 2.0, "cooldown_seconds": 10.0 }, "artifacts": { "event_dir": "../artifacts/events" } } ``` - `rtsp_url_env` 必填;应用从同名环境变量读取真实 URL。 - 数值是待现场录像校准的默认值;每个值必须真正进入事件逻辑。示例中的全零 SHA-256 只占位配置形状,T-103 必须以受控模型的真实哈希替换并验证后才能启动推理。 - 缺少环境变量、模型不存在或哈希不符时,应用显示配置错误,不启动监控。 ## 核心数据 ```text Keypoint = { x: float, y: float, confidence: float } PersonPose = { track_id: string, detected_at_monotonic: float, box_xyxy: [float, float, float, float], box_confidence: float, keypoints: Keypoint[17] } PoseQuality = { accepted: bool, reason: string, visible_joint_count: int } FallEvent = { event_id: string, source_id: string, track_id: string, started_at_utc: string, confirmed_at_utc: string, latency_seconds: float, state: "CONFIRMED", evidence: { horizontal_pose: bool, rapid_vertical_change: bool, persistence_seconds: float }, screenshot_path: string, config_version: string } ``` `FallEvent` 只在状态首次进入 `CONFIRMED` 时创建一次。连续帧更新 UI 状态,但不重复创建事件。 ## 视频来源帧合约 ```text FramePacket = { image: ndarray | null, timestamp_monotonic: float, status: "connected" | "retrying" | "error" | "eof" | "closed", error: string | null } ``` - 录像优先使用容器时间戳;首帧时间戳无效或倒退时,回退为帧序号/FPS,保证回放时间单调。 - `retrying`、`error`、`eof` 和 `closed` 都没有图像,且绝不伪造人员、姿态或摔倒事件。 - 可重连来源以有界指数退避重新打开;断流不推进状态机的证据时间。 ## 事件合约 | 事件 | 触发者 | 负载 | 结果 | | --- | --- | --- | --- | | `source.connected` | 视频源 | `source_id`、时间 | UI 显示在线。 | | `source.error` | 视频源 | `source_id`、错误码、可重试标记 | UI 显示异常;不报警。 | | `person.updated` | 跟踪与 Pose | `PersonPose`、`PoseQuality`、状态 | UI 绘制骨架与 ID。 | | `fall.suspected` | 状态机 | `track_id`、开始时间 | UI 显示黄色疑似状态。 | | `fall.confirmed` | 状态机 | `FallEvent` | 红色叠加、声音、弹窗、截图、JSONL。 | | `fall.recovered` | 状态机 | `track_id`、时间 | UI 恢复绿色正常状态。 | ## 副作用边界 - 仅 `alerts` 模块可写事件截图、播放声音、弹窗和追加 JSONL。 - 仅 `video_source` 模块读 RTSP 或本地视频。 - 仅 `pose` 模块加载模型;UI 不得直接调用模型。 - V2 可以改变实现语言,但不得改变配置含义、`FallEvent` 字段和事件幂等语义。