249 lines
6.4 KiB
Markdown
249 lines
6.4 KiB
Markdown
# 设备端远程管理接口清单表(V1:对外 rk3588-agent;对内 media-server)
|
||
|
||
> 目标:供管理端(Go)与设备端联调对照。
|
||
>
|
||
> 约定:
|
||
> - 对外:`rk3588-agent` HTTP 端口默认 `9100`(可配置),UDP 发现端口默认 `35688`。
|
||
> - 对内:`media-server` 继续提供现有 `/api/*`(默认 9000),由 agent 本机调用。
|
||
|
||
---
|
||
|
||
## 0. 通用规范
|
||
|
||
### 0.1 基础 URL
|
||
- Agent Base: `http://<device_ip>:<agent_port>`
|
||
- Media-server Base(仅 agent 使用): `http://127.0.0.1:<media_port>`
|
||
|
||
### 0.2 鉴权(agent 对外)
|
||
- Header:`X-RK-Token: <token>`
|
||
- **必须鉴权**:所有写接口(PUT/POST 会改变设备状态或写盘)
|
||
- **读接口**:默认可不鉴权;若 `agent.require_token_for_read=true` 则也必须鉴权
|
||
|
||
### 0.3 统一响应格式
|
||
- 成功(通用):`{"ok":true}`
|
||
- 失败(通用):`{"error":"<message>"}`(与现有 `ErrorJson()` 风格一致)
|
||
|
||
### 0.4 统一错误码/HTTP 状态(agent 对外)
|
||
agent 不要求返回结构化 error_code(保持 `{"error":...}`),但**要求 HTTP 状态码语义稳定**:
|
||
|
||
| 场景 | HTTP | error.message 示例 |
|
||
|---|---:|---|
|
||
| 未鉴权/Token 错误/缺失 | 401 | `unauthorized` |
|
||
| JSON 解析失败 / 字段缺失 / 校验失败 | 400 | `invalid json: ...` / `validation failed: ...` |
|
||
| 资源不存在 | 404 | `not found` |
|
||
| 方法不允许 | 405 | `method not allowed` |
|
||
| 冲突(如 node_id 不唯一等) | 409 | `... not unique ...` |
|
||
| 写盘失败/内部异常/reload 崩溃性失败 | 500 | `internal error: ...` |
|
||
| 上传过大 | 413(推荐)或 400 | `payload too large` |
|
||
|
||
### 0.5 端口与协议
|
||
- UDP 发现:`35688/udp`(可配置)
|
||
- Agent HTTP:`9100/tcp`(默认,可配置)
|
||
- Media-server HTTP:`9000/tcp`(默认,可配置)
|
||
|
||
---
|
||
|
||
## 1. UDP 发现协议(Option A)
|
||
|
||
### 1.1 Discover 请求(manager → broadcast)
|
||
**发送目标**:同网段广播地址 `255.255.255.255:35688` 或各网卡广播地址
|
||
|
||
**数据格式**:两行 UTF-8 文本
|
||
|
||
Line1(固定魔法串):
|
||
```
|
||
RK3588SYS_DISCOVERY_V1
|
||
```
|
||
|
||
Line2(JSON):
|
||
```json
|
||
{"type":"discover","req_id":"<uuid>","reply_port":0}
|
||
```
|
||
|
||
字段:
|
||
- `type`: 固定 `discover`
|
||
- `req_id`: 管理端生成 UUID,用于匹配回复
|
||
- `reply_port`: 保留字段(V1 可固定 0)
|
||
|
||
### 1.2 Discover 回复(device → manager 单播)
|
||
**发送目标**:请求报文 source ip:source port
|
||
|
||
两行文本:
|
||
|
||
Line1:
|
||
```
|
||
RK3588SYS_DISCOVERY_V1
|
||
```
|
||
|
||
Line2(JSON):
|
||
```json
|
||
{
|
||
"type":"discover_reply",
|
||
"req_id":"<uuid>",
|
||
"device_id":"rk3588-...",
|
||
"device_name":"rk3588-cam-01",
|
||
"hostname":"rk3588",
|
||
"ip":"10.0.0.21",
|
||
"agent_port":9100,
|
||
"media_port":9000,
|
||
"version":"0.0.0-dev",
|
||
"git_sha":"e5894c2",
|
||
"uptime_sec":12345
|
||
}
|
||
```
|
||
|
||
字段说明:
|
||
- `device_id`: 稳定唯一(优先 `/etc/machine-id`,否则 MAC/序列号;最后 fallback 生成并落盘)
|
||
- `device_name`: 可配置的人类可读名称(agent 配置 `device_name`)
|
||
- `agent_port`: agent HTTP 端口
|
||
- `media_port`: media-server HTTP 端口(用于调试/展示;管理端可不直连)
|
||
|
||
---
|
||
|
||
## 2. 设备信息(agent 对外)
|
||
|
||
### 2.1 `GET /v1/info`
|
||
用途:设备列表/详情页展示、联调确认端口/版本/配置路径。
|
||
|
||
**Auth**:读接口(见 0.2)
|
||
|
||
Response 200:
|
||
```json
|
||
{
|
||
"device_id":"rk3588-...",
|
||
"device_name":"rk3588-cam-01",
|
||
"hostname":"rk3588",
|
||
"ip":"10.0.0.21",
|
||
"agent_port":9100,
|
||
"media_port":9000,
|
||
"version":"0.0.0-dev",
|
||
"git_sha":"e5894c2",
|
||
"config_path":"/etc/rk3588sys/config.json",
|
||
"last_good_path":"/etc/rk3588sys/config.json.last_good.json",
|
||
"uptime_sec":12345
|
||
}
|
||
```
|
||
|
||
失败:401/500 + `{"error":"..."}`
|
||
|
||
---
|
||
|
||
## 3. 配置下发(agent 对外)
|
||
|
||
### 3.1 `PUT /v1/config`
|
||
用途:管理端上传完整 root config(可含 templates/instances),agent 原子写盘后触发 `media-server` reload。
|
||
|
||
**Auth**:必须(401)
|
||
|
||
Headers:
|
||
- `Content-Type: application/json`
|
||
- `X-RK-Token: ...`
|
||
|
||
Body:root config JSON
|
||
|
||
agent 处理步骤(必须满足):
|
||
1) 解析 JSON(语法有效即可;语义校验交由 media-server reload)
|
||
2) 原子写入 `config_path`
|
||
3) 调用 media-server:`POST /api/config/reload`
|
||
4) 若 reload 失败:调用 media-server:`POST /api/config/rollback`,并返回 500(包含 reload/rollback 错误信息)
|
||
|
||
Response 200:
|
||
```json
|
||
{"ok":true}
|
||
```
|
||
|
||
失败:
|
||
- 400:JSON 解析失败
|
||
- 500:写盘失败 / reload 失败(已尝试 rollback)
|
||
|
||
---
|
||
|
||
## 4. 模型管理(agent 对外)
|
||
|
||
### 4.1 `PUT /v1/models/{name}`
|
||
用途:上传模型文件并落盘,维护 manifest,返回可引用的 `path`。
|
||
|
||
**Auth**:必须(401)
|
||
|
||
Path params:
|
||
- `name`: string(建议仅允许 `[A-Za-z0-9._-]`,超出则 400)
|
||
|
||
Headers:
|
||
- `Content-Type: application/octet-stream`
|
||
- `Content-Length: <n>`(必须)
|
||
- `X-RK-Token: ...`
|
||
- `X-Model-Sha256: <hex>`(可选;若存在必须匹配实际 sha256,否则 400)
|
||
|
||
Body:二进制文件(建议限制扩展名白名单 `.rknn`;V1 可由 name 或内容类型控制)
|
||
|
||
Response 200:
|
||
```json
|
||
{
|
||
"ok": true,
|
||
"name": "yolov5s-640",
|
||
"sha256": "...",
|
||
"path": "/opt/rk3588sys/models/files/yolov5s-640__abcd.rknn",
|
||
"size": 12345678
|
||
}
|
||
```
|
||
|
||
失败:
|
||
- 400:缺 Content-Length / name 非法 / sha256 不匹配
|
||
- 413(推荐)或 400:超过 `max_upload_mb`
|
||
- 500:写盘失败/manifest 更新失败
|
||
|
||
### 4.2 `GET /v1/models`
|
||
用途:列出设备端已有模型。
|
||
|
||
**Auth**:读接口(见 0.2)
|
||
|
||
Response 200:
|
||
```json
|
||
{
|
||
"items": [
|
||
{
|
||
"name": "yolov5s-640",
|
||
"sha256": "...",
|
||
"path": "/opt/rk3588sys/models/files/...",
|
||
"size": 123,
|
||
"mtime_ms": 1730000000000
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
失败:500 + `{"error":"..."}`
|
||
|
||
---
|
||
|
||
## 5. 业务图热更新/回滚(agent 对外)
|
||
|
||
### 5.1 `POST /v1/media-server/reload`
|
||
用途:触发本机 media-server `POST /api/config/reload`。
|
||
|
||
**Auth**:必须(401)
|
||
|
||
Response 200:`{"ok":true}`
|
||
|
||
失败:500 + `{"error":"..."}`
|
||
|
||
### 5.2 `POST /v1/media-server/rollback`
|
||
用途:触发本机 media-server `POST /api/config/rollback`。
|
||
|
||
**Auth**:必须(401)
|
||
|
||
Response 200:`{"ok":true}`
|
||
|
||
失败:500 + `{"error":"..."}`
|
||
|
||
## 6. 只读代理接口(agent 对外,推荐管理端统一走 agent)
|
||
|
||
### 6.1 `GET /v1/graphs`
|
||
代理 media-server:`GET /api/graphs`
|
||
|
||
### 6.2 `GET /v1/graphs/{name}`
|
||
代理 media-server:`GET /api/graphs/{name}`
|
||
|
||
### 6.3 `GET /v1/logs/recent?limit=200`
|
||
代理 media-server:`GET /api/logs/recent?limit=...`
|