|
@@ -0,0 +1,219 @@
|
|
|
|
|
+# 双机 16 路单屏部署说明
|
|
|
|
|
+
|
|
|
|
|
+本系统支持用 **两台 RK3588** 组成 16 路视频监控,并通过一块 HDMI 屏幕以 4×4 宫格显示。
|
|
|
|
|
+两台板运行**同一份程序**,仅配置不同;`master` / `slave` 角色可在网页中切换(重启生效)。
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 1. 架构
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+ 千兆交换机
|
|
|
|
|
+ ┌───────────────┴───────────────┐
|
|
|
|
|
+8×摄像头(子码流) 8×摄像头(子码流)
|
|
|
|
|
+ │ │
|
|
|
|
|
+ 节点2 (slave, 无屏) 节点1 (master, HDMI)
|
|
|
|
|
+ ·8路解码 + 姿态推理 ·8路解码 + 姿态推理
|
|
|
|
|
+ ·输出 /stream 供对端拉取 ·拉取对端8路画面 → 4×4 一屏
|
|
|
|
|
+ ·本地报警入库 ·本地报警 + 聚合对端报警
|
|
|
|
|
+ ·Web / 手机 APP 统一入口
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+- **master**:接 HDMI 屏,负责 16 宫格显示、Web/手机访问、报警聚合。
|
|
|
|
|
+- **slave**:不接屏(也可接),专注采集与推理,暴露 `/stream`、报警 API 供对端读取。
|
|
|
|
|
+- 两台各自把报警写入本地 SQLite;master 在查询时合并两台数据。
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 2. 通道编号规则(重要)
|
|
|
|
|
+
|
|
|
|
|
+每台板有一个固定不变的 `local_base`:
|
|
|
|
|
+
|
|
|
|
|
+| 板子 | `local_base` | 拥有通道 |
|
|
|
|
|
+|---|---|---|
|
|
|
|
|
+| 节点1 | `0` | CH0 ~ CH7 |
|
|
|
|
|
+| 节点2 | `8` | CH8 ~ CH15 |
|
|
|
|
|
+
|
|
|
|
|
+`local_base` **与角色无关**:无论谁当 master,编号都不变。
|
|
|
|
|
+角色只决定“谁显示、谁聚合”。
|
|
|
|
|
+
|
|
|
|
|
+> 界面中的通道号从 0 开始(CH0~CH15)。
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 3. 配置示例
|
|
|
|
|
+
|
|
|
|
|
+### 3.1 节点1(master,接屏)
|
|
|
|
|
+
|
|
|
|
|
+`config/config.json` 关键项:
|
|
|
|
|
+
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "node_role": "master",
|
|
|
|
|
+ "local_base": 0,
|
|
|
|
|
+ "grid_output": true,
|
|
|
|
|
+ "steel_output": false,
|
|
|
|
|
+ "enable_bucket": false,
|
|
|
|
|
+ "display_fps": 12,
|
|
|
|
|
+ "watchdog_sec": 120,
|
|
|
|
|
+
|
|
|
|
|
+ "peer": {
|
|
|
|
|
+ "enabled": true,
|
|
|
|
|
+ "host": "192.168.1.232",
|
|
|
|
|
+ "port": 8080,
|
|
|
|
|
+ "username": "admin",
|
|
|
|
|
+ "password": "admin",
|
|
|
|
|
+ "local_base": 8,
|
|
|
|
|
+ "count": 8,
|
|
|
|
|
+ "fps": 8
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ "rtsp": [
|
|
|
|
|
+ { "id": 0, "name": "cam1", "url": "rtsp://user:pass@192.168.1.121:554/Streaming/Channels/102" },
|
|
|
|
|
+ { "id": 1, "name": "cam2", "url": "rtsp://user:pass@192.168.1.122:554/Streaming/Channels/102" },
|
|
|
|
|
+ { "id": 2, "name": "cam3", "url": "rtsp://user:pass@192.168.1.123:554/Streaming/Channels/102" },
|
|
|
|
|
+ { "id": 3, "name": "cam4", "url": "rtsp://user:pass@192.168.1.124:554/Streaming/Channels/102" },
|
|
|
|
|
+ { "id": 4, "name": "cam5", "url": "rtsp://user:pass@192.168.1.125:554/Streaming/Channels/102" },
|
|
|
|
|
+ { "id": 5, "name": "cam6", "url": "rtsp://user:pass@192.168.1.126:554/Streaming/Channels/102" },
|
|
|
|
|
+ { "id": 6, "name": "cam7", "url": "rtsp://user:pass@192.168.1.127:554/Streaming/Channels/102" },
|
|
|
|
|
+ { "id": 7, "name": "cam8", "url": "rtsp://user:pass@192.168.1.128:554/Streaming/Channels/102" }
|
|
|
|
|
+ ]
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 3.2 节点2(slave,无屏)
|
|
|
|
|
+
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "node_role": "slave",
|
|
|
|
|
+ "local_base": 8,
|
|
|
|
|
+ "grid_output": false,
|
|
|
|
|
+ "steel_output": false,
|
|
|
|
|
+ "enable_bucket": false,
|
|
|
|
|
+ "peer": { "enabled": false },
|
|
|
|
|
+
|
|
|
|
|
+ "rtsp": [
|
|
|
|
|
+ { "id": 0, "name": "cam9", "url": "rtsp://user:pass@192.168.1.129:554/Streaming/Channels/102" },
|
|
|
|
|
+ { "id": 1, "name": "cam10", "url": "rtsp://user:pass@192.168.1.130:554/Streaming/Channels/102" },
|
|
|
|
|
+ { "id": 2, "name": "cam11", "url": "rtsp://user:pass@192.168.1.131:554/Streaming/Channels/102" },
|
|
|
|
|
+ { "id": 3, "name": "cam12", "url": "rtsp://user:pass@192.168.1.132:554/Streaming/Channels/102" },
|
|
|
|
|
+ { "id": 4, "name": "cam13", "url": "rtsp://user:pass@192.168.1.133:554/Streaming/Channels/102" },
|
|
|
|
|
+ { "id": 5, "name": "cam14", "url": "rtsp://user:pass@192.168.1.134:554/Streaming/Channels/102" },
|
|
|
|
|
+ { "id": 6, "name": "cam15", "url": "rtsp://user:pass@192.168.1.135:554/Streaming/Channels/102" },
|
|
|
|
|
+ { "id": 7, "name": "cam16", "url": "rtsp://user:pass@192.168.1.136:554/Streaming/Channels/102" }
|
|
|
|
|
+ ]
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 3.3 配置项说明
|
|
|
|
|
+
|
|
|
|
|
+| 配置项 | 说明 |
|
|
|
|
|
+|---|---|
|
|
|
|
|
+| `node_role` | `standalone` / `master` / `slave` |
|
|
|
|
|
+| `local_base` | 本机通道全局起点,节点1=0,节点2=8 |
|
|
|
|
|
+| `peer.enabled` | master 才需要开启 |
|
|
|
|
|
+| `peer.host` / `peer.port` | 对端板 IP 与 Web 端口 |
|
|
|
|
|
+| `peer.username` / `peer.password` | 对端登录凭据(用于拉流/报警/截图) |
|
|
|
|
|
+| `peer.local_base` | 对端通道起点(节点1填8,节点2填0) |
|
|
|
|
|
+| `peer.count` | 拉取对端通道数量(默认8) |
|
|
|
|
|
+| `peer.fps` | 拉取对端画面帧率(默认8) |
|
|
|
|
|
+| `display_fps` | 本机显示帧生成帧率(默认12) |
|
|
|
|
|
+| `watchdog_sec` | 主循环卡死看门狗,超时自动重启(默认120,0=禁用) |
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 4. 网页切换 A/B 角色(谁当主)
|
|
|
|
|
+
|
|
|
|
|
+1. 浏览器登录该板 Web(默认 `admin/admin`)。
|
|
|
|
|
+2. 进入 **系统设置 → 双机模式**。
|
|
|
|
|
+3. 设置:
|
|
|
|
|
+ - 本机角色:`主节点` 或 `从节点` / `单机`
|
|
|
|
|
+ - 本机通道起点:节点1=`0`,节点2=`8`
|
|
|
|
|
+ - 对端 IP / 端口 / 用户名 / 密码
|
|
|
|
|
+ - 对端通道起点:与对端 `local_base` 一致
|
|
|
|
|
+4. 保存后**重启生效**(页面会提示)。
|
|
|
|
|
+5. 把 HDMI 屏接到新的 master 板上。
|
|
|
|
|
+
|
|
|
|
|
+> 也可直接修改 `config/config.json` 后重启服务。
|
|
|
|
|
+
|
|
|
|
|
+重启命令:
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+systemctl restart zone_alarm
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 5. 性能与带宽
|
|
|
|
|
+
|
|
|
|
|
+基于 RK3588 实测(8 路/台,**仅姿态识别**,子码流 1280×720,skip_frames=9):
|
|
|
|
|
+
|
|
|
|
|
+| 项 | 参考值 |
|
|
|
|
|
+|---|---|
|
|
|
|
|
+| 单板 CPU | 约 80 ~ 130% |
|
|
|
|
|
+| NPU | 三核各约 60 ~ 90% |
|
|
|
|
|
+| 跨机流量(master ← slave) | 约 8 Mbps(8 路 JPEG@8fps) |
|
|
|
|
|
+| 千兆交换机 | 充裕 |
|
|
|
|
|
+
|
|
|
|
|
+建议:
|
|
|
|
|
+
|
|
|
|
|
+- **全部使用子码流**(`.../Channels/102`)。
|
|
|
|
|
+- 16 路**仅姿态**;如同时开目标识别,建议降 `pose_input_size`(640→416)或增大 `skip_frames`。
|
|
|
|
|
+- 非重点通道可在姿态配置里关闭。
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 6. 部署检查清单
|
|
|
|
|
+
|
|
|
|
|
+- [ ] 两台板在同一千兆交换机、同网段,互相能 `ping` 通。
|
|
|
|
|
+- [ ] 两台板 **NTP 对时**(否则报警合并排序会乱)。
|
|
|
|
|
+- [ ] 节点1 `local_base=0`、节点2 `local_base=8`,且互不重复。
|
|
|
|
|
+- [ ] master 的 `peer.host` 指向对端 IP(不能填本机同一端口)。
|
|
|
|
|
+- [ ] 两台 Web 登录凭据与 `peer.username/password` 一致。
|
|
|
|
|
+- [ ] HDMI 接在 master 上。
|
|
|
|
|
+- [ ] 花生壳/外网访问**只需映射 master**。
|
|
|
|
|
+- [ ] 防火墙放行 8080(或配置的 `web_port`)。
|
|
|
|
|
+- [ ] 若使用工位/钢包位功能,请确认 `enable_bucket` 与 `local_base` 不冲突(16 路场景建议关闭)。
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 7. 验证方法
|
|
|
|
|
+
|
|
|
|
|
+在 master 上登录后检查:
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+# 角色与通道(应看到本机8 + 对端8,共16路)
|
|
|
|
|
+curl -s -b cookies.txt http://<master-ip>:8080/api/status
|
|
|
|
|
+
|
|
|
|
|
+# 对端通道画面(用于确认跨机拉流)
|
|
|
|
|
+curl -s -b cookies.txt -o test.jpg http://<master-ip>:8080/stream/8
|
|
|
|
|
+
|
|
|
|
|
+# 合并后的姿态报警
|
|
|
|
|
+curl -s -b cookies.txt "http://<master-ip>:8080/api/pose/alarms?limit=5"
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+- `/api/status` 中 `"remote": true` 的通道来自对端,`online` 为在线状态。
|
|
|
|
|
+- 报警条目带 `"src": "local"` 或 `"peer"`,用于区分来源与删除分发。
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 8. 故障排查
|
|
|
|
|
+
|
|
|
|
|
+| 现象 | 排查 |
|
|
|
|
|
+|---|---|
|
|
|
|
|
+| 对端通道一直离线 | 检查 `peer.host/port`、网络、对端 `node_role=slave` 且 Web 可访问;查看 master 日志 `[Peer]` |
|
|
|
|
|
+| 对端通道画面黑/无数据 | 确认对端已加载对应摄像头且 `online`;对端 `/stream/<其全局id>` 是否可访问 |
|
|
|
|
|
+| 报警不合并 | 确认 master `peer.enabled=true`;对端时间是否同步;检查 `peer.local_base` 是否与对端 `local_base` 一致 |
|
|
|
|
|
+| 对端截图打不开 | 检查 `/api/peer/image/<文件名>`;确认对端 `data/screenshots` 存在该文件 |
|
|
|
|
|
+| 保存角色后不生效 | 角色需**重启**生效;确认写入的是运行目录下的 `config/config.json` |
|
|
|
|
|
+| 对端地址填成本机 | 程序会提示并禁用对端(防止状态查询递归死锁) |
|
|
|
|
|
+| 画面卡顿 | 检查 master CPU/NPU;适当降低 `peer.fps` / `display_fps`,或增大 `skip_frames` |
|
|
|
|
|
+| 服务反复重启 | 查看 `journalctl -u zone_alarm`;看门狗触发说明主循环卡死(NPU 异常会自动恢复) |
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 9. 单机与双机切换
|
|
|
|
|
+
|
|
|
|
|
+- **单机(8 路)**:`node_role=standalone`,`peer.enabled=false`。
|
|
|
|
|
+- **双机(16 路)**:一台 `master` + 一台 `slave`,配置如上。
|
|
|
|
|
+- 切换到双机或互换角色:只需调整 `node_role` / `peer` 并重启,**无需重新编译**。
|