feat: integrate N7Cockpit remote mode control

This commit is contained in:
vee
2026-08-13 10:36:24 +08:00
parent fd3c219c39
commit 78d758d3fb
108 changed files with 23150 additions and 16 deletions
+212
View File
@@ -0,0 +1,212 @@
# N7Cockpit 跨服务器迁移与联调手册
## 1. 部署拓扑
本工程采用统一服务端事件链路,不做网页自动点击:
```text
Android / N7Cockpit
| HTTPS/HTTP + Bearer token
| mode_id / execution_id / event sequence
v
服务器 A:Cognitive_Agent :8000
| 展开服务器预设模式、安全校验、执行与状态回读
+--> Web 控制台(同一事件流)
+--> CAN 盒与车端设备(仅 hardware + 本地批准时)
服务器 B:保存 N7Cockpit 源码、构建 APK、通过 ADB 安装到 Android
```
`127.0.0.1:8000` 只表示“当前机器”。Android 设备访问服务器 A 时必须使用
服务器 A 的可路由 IP 或 DNS 名。只有 Android Emulator 与服务器 A 同机时,APK
中的服务器 A 地址才使用 `http://10.0.2.2:8000`。
## 2. 服务器 A:启动 Cognitive_Agent
服务器 A 必须已经包含本项目配套修改后的 Cognitive_Agent。进入其工程目录,生成
至少 32 字符的随机设备令牌;令牌只在服务器 A 和服务器 B 的私密文件中保存:
```powershell
cd D:\path\to\Cognitive_Agent
$tokenBytes = New-Object byte[] 48
$rng = [Security.Cryptography.RandomNumberGenerator]::Create()
try { $rng.GetBytes($tokenBytes) } finally { $rng.Dispose() }
$deviceToken = [Convert]::ToBase64String($tokenBytes)
$deviceToken | Set-Content -NoNewline .\n7-device-token.txt
```
启动服务。当前 PowerShell 会话关闭后进程也会终止,生产环境应再配置 Windows
Service、NSSM 或反向代理进程守护:
```powershell
$env:PYTHONPATH = 'src'
$env:COGNITIVE_AGENT_DEVICE_API_TOKEN = (
Get-Content .\n7-device-token.txt -Raw
).Trim()
python -m cognitive_agent.server --host 0.0.0.0 --port 8000
```
服务器 A 防火墙只允许服务器 B、Android 车机和 Web 管理端访问 TCP 8000。生产
环境必须在服务器前配置 HTTPS;HTTP 仅适用于受信任的隔离局域网。
从服务器 B 检查网络。这里不能使用服务器 B 的 `127.0.0.1`:
```powershell
Test-NetConnection 192.168.1.10 -Port 8000
```
Web 控制台地址也应改为服务器 A 地址:`http://192.168.1.10:8000/`。服务器 A
本机访问时才使用 `http://127.0.0.1:8000/`。
## 3. 服务器 B:解压和初始化
安装以下依赖:
- Windows PowerShell 5.1 或 PowerShell 7;
- JDK 17 或更高版本;
- Android SDK Platform 35 和 Platform Tools;
- 首次构建可访问 Gradle/Google/Aliyun Maven 仓库。
解压 ZIP 后:
```powershell
cd D:\Deploy\N7Cockpit
powershell -NoProfile -ExecutionPolicy Bypass `
-File .\scripts\initialize-migration.ps1
```
编辑 `config\migration.psd1`:
```powershell
@{
ServerAUrl = 'http://192.168.1.10:8000'
AndroidServerAUrl = 'http://192.168.1.10:8000'
VehicleId = 'denza_n7'
HardwareClientId = 'hwc-n7cockpit-server-b-001'
ExecutionTarget = 'dry_run'
TokenFile = 'secrets/device-token.txt'
JavaHome = 'C:\Program Files\Android\Android Studio\jbr'
AndroidSdk = 'C:\Users\Administrator\AppData\Local\Android\Sdk'
GradleExecutable = ''
}
```
把服务器 A 的 `n7-device-token.txt` 安全复制到服务器 B 的
`secrets\device-token.txt`。不要通过聊天、代码仓库或普通邮件传输。配置和 secrets
目录均被打包规则排除。
先验证环境及服务器 A:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass `
-File .\scripts\verify-migration-environment.ps1
powershell -NoProfile -ExecutionPolicy Bypass `
-File .\scripts\check-server-a.ps1
```
两条命令都应返回 `Passed=True`,且 `PresetModes` 大于 0。
## 4. 构建和安装 Android APK
安全联调构建:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass `
-File .\scripts\build-migrated-apk.ps1 -Variant debug
```
脚本会先验证服务器 A、运行 Android 单元测试,再生成:
```text
dist\N7Cockpit-remote-debug.apk
dist\build-info.json
```
`GradleExecutable` 留空时使用包内 Gradle Wrapper;首次构建会下载 Gradle 8.9。
服务器若已安装 Gradle 8.9,可填写 `gradle.bat` 的绝对路径以避免重复下载。
设备开启开发者选项和 USB 调试,执行:
```powershell
adb devices
powershell -NoProfile -ExecutionPolicy Bypass `
-File .\scripts\install-migrated-apk.ps1 -Variant debug
```
如有多个设备,增加 `-Serial <adb序列号>`。远程调试包名为
`com.seeker.n7cockpit.remote`,可与正式包共存。
## 5. dry_run 联调验收
先进行不会访问 CAN 的服务器 A 冒烟测试:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass `
-File .\scripts\test-server-a-dry-run.ps1
```
必须看到:
- `Passed=True`;
- `CanExecuted=False`;
- `ExecutionTarget=dry_run`;
- `Status=succeeded`。
然后打开 Android 的“模式”页:
1. 顶部应显示服务器 A URL 和“编排服务已连接”;
2. 应加载宝宝午睡、零重力、小憩、轻松进出等服务器预设模式;
3. 点击“宝宝午睡模式”;
4. Android 显示 `queued/executing/succeeded`、execution_id 和车端模拟状态;
5. 打开服务器 A 的 Web 控制台,显示同一模式、`source:N7Cockpit`、同一
execution_id 和同步后的数字孪生状态。
此阶段不要点击“申请真实硬件控制”。
## 6. 实体 Android 与模拟器的地址选择
| 场景 | AndroidServerAUrl |
|---|---|
| 模拟器与服务器 A 同机 | `http://10.0.2.2:8000` |
| 模拟器在服务器 B,服务器 A 独立 | 服务器 A 的 LAN IP/DNS |
| 实体 Android/车机 | 服务器 A 的 LAN IP/DNS |
| 生产环境 | 服务器 A 的 HTTPS 域名 |
服务器 B 的 `ServerAUrl` 始终填写服务器 B 能访问的服务器 A 地址。
## 7. 切换真实 CAN(完成 dry_run 后单独进行)
真实硬件不属于默认迁移验收范围。确认急停、机械限位、CAN 通道和车端供电安全后:
1. 将配置改为 `ExecutionTarget='hardware'`;
2. 显式构建:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass `
-File .\scripts\build-migrated-apk.ps1 -Variant release -AllowHardware
```
3. Android 点击“申请真实硬件控制”;
4. 只能在服务器 A 本机打开 `/hardware-control` 批准对应 HardwareClientId;
5. 批准后才允许 hardware 任务进入 CAN 执行。
`-AllowHardware` 和服务器 A 本地批准是两层独立安全门,远程设备令牌不能自批准。
## 8. 常见故障
- `401`:服务器 A 与 APK 使用的设备令牌不一致,或服务重启时没有加载令牌。
- `Connection refused/timed out`:服务未监听 `0.0.0.0`、防火墙未放行,或 URL
错填为 Android/服务器 B 自己的 `127.0.0.1`。
- 模式为空:车型 ID 不匹配,或服务器 A 不是包含预设模式 API 的配套版本。
- Android 可访问但 Web 不更新:Web 未登录,或浏览器标签长期后台导致轮询暂停;
激活页面后会继续读取新事件。
- Gradle 下载失败:检查代理/DNS;工程已同时配置 Aliyun 与官方仓库。
- SDK XML 警告:Android Studio 与 command-line tools 版本差异警告,若构建最终
`BUILD SUCCESSFUL` 通常不影响 APK。
## 9. 安全说明
设备令牌会进入 APK BuildConfig。只应把 APK 安装到受控车机;如果 APK 可能公开
分发,应改为设备注册和短期凭据。令牌泄露后必须在服务器 A 生成新令牌、重启服务
并重新构建 APK。ZIP 源码包不会包含设备令牌、构建目录、历史 APK、测试截图或
本机 Gradle 缓存。