# PRD ④ 控制端配置窗口(GUI)对接方案(templates/instances-only) > 适用版本:V1(2026-01) > > 范围:**仅控制端 GUI/managerd 如何调用设备端 rk3588-agent**。 > - 本项目中已在 `agent + media-server` 实现本文档所需能力。 > - **不包含**配置程序(前端/后端)具体 UI 代码实现细节。 --- ## 1. 目标 让非技术人员通过 GUI 完成: 1) 新增/删除一路摄像头通道(channel) 2) 选择流程模板(转码/YOLO/报警/人脸检测/人脸识别)并配置参数 3) 一键应用配置(写盘 + reload;失败自动 rollback) 4) 人脸库(SQLite `face_gallery.db`)上传并**无需重启**立即生效 --- ## 2. 核心约束(必须遵守) 1) GUI **只支持 `templates/instances` 模式**: - 不提供手写 `graphs` 的编辑。 - 运行态 graphs 只读查看(用于监控/联调)。 2) 人脸数据通过上传整个 SQLite 文件:`face_gallery.db`。 3) 人脸库默认路径:`./models/face_gallery.db`。 - 要求部署时 **media-server 的工作目录** 与 **agent.models_dir** 关系合理,使该相对路径能找到 agent 上传的 db。 - 推荐:`media_server_process.work_dir=` 且 `agent.models_dir=/models`。 --- ## 3. 鉴权与错误处理 ### 3.1 鉴权 - Header:`X-RK-Token: ` - 写接口(会写盘/改状态)必须鉴权。 - 读接口默认可不鉴权;若设备端配置 `agent.require_token_for_read=true`,则读接口也必须鉴权。 ### 3.2 统一错误返回 - 成功:`2xx`,一般为 `{"ok":true,...}` 或业务 JSON - 失败:`4xx/5xx`,返回 `{"error":"..."}` 常见 HTTP: - `401`:unauthorized - `400`:validation failed / invalid json - `404`:not found - `409`:conflict - `500`:internal error --- ## 4. GUI 页面与调用流程 ### 4.1 设备详情页(只读) 1) 设备信息:`GET /v1/info` 2) 运行态通道摘要:`GET /v1/graphs` 3) 单通道详情(可选):`GET /v1/graphs/{name}` 4) 日志:`GET /v1/logs/recent?limit=200` ### 4.2 通道配置页(核心:instances) #### 4.2.1 初始化 1) 获取 schema(渲染表单):`GET /v1/config/ui/schema` 2) 获取当前 state(回显):`GET /v1/config/ui/state` GUI 侧以 `instances[]` 为“通道列表”。 #### 4.2.2 校验/预览(dry-run) 用户编辑完成后: - `POST /v1/config/ui/plan` 返回: - `generated_config`:生成出来的 root config(可用于预览/导出) - `diff`:added/removed/changed(实例级别) > 说明:plan 的校验是“基础校验”(必填字段/模板名/实例名唯一)。 > 真正的构图/插件/模型加载等校验发生在 apply → media-server reload 阶段。 #### 4.2.3 应用配置 - `POST /v1/config/ui/apply` 行为: 1) agent 生成新的 root config(只包含 `global/queue/templates/instances`) 2) 写盘到 `agent.config_path` 3) 调用 media-server reload 4) reload 失败则自动 rollback 并返回 500 #### 4.2.4 回滚(手动) - `POST /v1/media-server/rollback` > 回滚语义:回滚到“上一次成功的**源配置**”(保留 templates/instances,不会被 expanded 覆盖),便于 GUI 二次编辑。 ### 4.3 人脸库管理页 #### 4.3.1 上传人脸库 - `PUT /v1/face-gallery` - Content-Type:`application/octet-stream` - Body:SQLite 文件二进制(`face_gallery.db`) 保存位置:`/face_gallery.db` #### 4.3.2 立即生效(无需重启) - `POST /v1/face-gallery/reload` 行为: - agent 遍历所有 graphs,找到 `type==ai_face_recog` 的节点 - 对每个节点下发 runtime config patch:bump `gallery.reload_seq` - 节点收到后会重新加载 SQLite db --- ## 5. Agent 对外 API(控制端对接清单) > Base:`http://:`(默认 9100) ### 5.1 设备信息 #### `GET /v1/info` 用于设备列表/详情。 ### 5.2 运行态(只读代理) #### `GET /v1/graphs` #### `GET /v1/graphs/{name}` #### `GET /v1/logs/recent?limit=200` ### 5.3 配置文件(root config) #### `GET /v1/config` 返回 `agent.config_path` 对应 JSON(用于导出/高级查看)。 #### `PUT /v1/config` 上传完整 root config JSON(写盘 + reload;失败自动 rollback)。 ### 5.4 语义化配置(GUI 推荐使用) #### `GET /v1/config/ui/schema` 返回:可选模板列表 + 字段 schema(类型/默认/必填)。 #### `GET /v1/config/ui/state` 返回:当前 config 映射到 GUI state(主要是 `instances[]`)+ 内置模板列表。 #### `POST /v1/config/ui/plan` 输入 desired state(instances 列表),返回生成 config 与 diff。 #### `POST /v1/config/ui/apply` 同 plan,但会写盘并 reload(失败自动 rollback)。 ### 5.5 模型管理(可选,但建议 GUI 支持) #### `PUT /v1/models/{name}` 上传模型(.rknn),返回可引用的 `path`。 #### `GET /v1/models` 列出已上传模型(包含 `name/path/sha256/mtime_ms`)。 ### 5.6 人脸库 #### `GET /v1/face-gallery` 返回当前 db 文件信息(exists/size/mtime/path)。 #### `PUT /v1/face-gallery` 上传 `face_gallery.db`。 #### `POST /v1/face-gallery/reload` 让所有 `ai_face_recog` 节点热加载新 db。 --- ## 6. `config/ui/*` 的数据结构(控制端直接照此传) ### 6.1 `POST /v1/config/ui/plan|apply` Request ```json { "global": { }, "queue": { }, "instances": [ { "name": "cam1", "template": "face_det_recog_rtsp_hls", "params": { "url": "rtsp://10.0.0.5:8554/cam", "fps": 30, "src_w": 1280, "src_h": 720, "det_model_path": "./models/RetinaFace_mobile320.rknn", "recog_model_path": "./models/mobilefacenet_arcface.rknn", "gallery_path": "./models/face_gallery.db", "gop": 60, "bitrate_kbps": 2000, "rtsp_port": 8555, "hls_path": "./web/hls/cam1/index.m3u8" } } ] } ``` 说明: - `global/queue` 可省略:agent 会沿用当前 config 中的值。 - `instances` 为全量期望状态:控制端应把当前列表 + 修改后的列表一起提交。 - 当前实现会生成新的 root config(只包含 `global/queue/templates/instances`),不会保留 `graphs`。 ### 6.2 `POST /v1/config/ui/plan|apply` Response ```json { "ok": true, "generated_config": { "global":{}, "queue":{}, "templates":{}, "instances":[] }, "diff": { "added": ["cam1"], "removed": [], "changed": [] }, "warnings": [] } ``` --- ## 7. 内置流程模板与必填参数表 > 模板名来自 `GET /v1/config/ui/schema` 的 `templates[]`。 ### 7.1 `transcode_rtsp_hls` - 必填:`url` - 常用:`fps,src_w,src_h,gop,bitrate_kbps,rtsp_port,hls_path` ### 7.2 `yolo_rtsp_hls` - 必填:`url, model_path` ### 7.3 `yolo_alarm_minio` - 必填:`url, model_path, minio_endpoint, minio_bucket, minio_ak, minio_sk` - 常用:`cooldown_ms`(默认 3000) ### 7.4 `face_det_rtsp_hls` - 必填:`url, det_model_path` ### 7.5 `face_det_recog_rtsp_hls` - 必填:`url, det_model_path, recog_model_path` - 默认:`gallery_path=./models/face_gallery.db`,`thr_accept=0.45`,`thr_margin=0.05` --- ## 8. 人脸库路径对齐建议(避免“上传了但识别不到”) 1) 默认推荐(最省事): - media-server work_dir:`/opt/rk3588sys` - agent.models_dir:`/opt/rk3588sys/models` - ai_face_recog.gallery.path:`./models/face_gallery.db` 2) 若你们的 work_dir/models_dir 不是这种关系: - 控制端在 instances params 里把 `gallery_path` 设置为**绝对路径**(例如 `/opt/rk3588sys/models/face_gallery.db`)。 --- ## 9. 验收标准 1) GUI 新增通道 → apply 成功后:`GET /v1/graphs` 出现该通道;`GET /v1/graphs/{name}` 能看到节点链路。 2) 删除通道 → apply 成功后 graphs 中消失。 3) 上传 `face_gallery.db` → `POST /v1/face-gallery/reload` 后无需重启即可生效。 4) apply 失败时:自动 rollback,且 rollback 后 config 仍为 templates/instances 源结构。