feat(n7web): enhance control workflows and status feedback
This commit is contained in:
@@ -8,6 +8,29 @@ Web 控制台与同源 API 由同一个 Python 服务提供。本地启动:
|
||||
.\.venv\Scripts\python.exe .\tools\start_n7web.py
|
||||
```
|
||||
|
||||
启动脚本会先安装缺失的前端依赖并执行 Vue 3 + Vite 生产构建,然后启动 `8000` 主服务和独立的 `8090` 只读模式卡服务。已经有可复用的 `apps/web-console/dist` 时,可使用 `--skip-web-build` 跳过本次构建。
|
||||
|
||||
### Vue 3 + Vite 前端
|
||||
|
||||
前端根应用位于 `apps/web-console/src/App.vue`,入口为 `src/main.js`。Vue 和 Vite 均由 npm 锁定版本管理,浏览器不再依赖 CDN 或全局 `window.Vue`。现有 MQTT、NFC、语音、模式卡和车辆控制脚本作为兼容运行层继续使用原 DOM 契约,由 Vue 根应用承载页面结构。
|
||||
|
||||
单独进行前端开发时,先保持 Python 主服务运行,再启动 Vite:
|
||||
|
||||
```powershell
|
||||
cd .\apps\web-console
|
||||
npm ci
|
||||
npm run dev
|
||||
```
|
||||
|
||||
开发页面为 `http://127.0.0.1:5173/`,`/api` 与 `/artifacts` 会代理到 `http://127.0.0.1:8000`。生成生产静态资源:
|
||||
|
||||
```powershell
|
||||
cd .\apps\web-console
|
||||
npm run build
|
||||
```
|
||||
|
||||
构建输出位于 `apps/web-console/dist`;Python 主服务检测到该目录后会优先提供生产构建。上述流程不会改变主页的 `8000` 端口,也不会改变模式卡服务的 `8090` 端口。
|
||||
|
||||
Windows PowerShell 未安装 `make` 时可直接运行:
|
||||
|
||||
```powershell
|
||||
@@ -186,6 +209,41 @@ config/gesture/default.yaml
|
||||
|
||||
同步由模式注册表的创建、更新、删除、恢复和显式重载事件触发,不会持续扫描目录。每次变更只重新生成并原子替换一份小型 JSON;独立目录服务在收到 HTTP 请求时才读取它。因此空闲时的额外开销主要是一个等待请求的 Python 进程和一个 UDP 发现线程,而不是持续的 CPU 或磁盘轮询。
|
||||
|
||||
前端通过 `POST /api/mode-profiles` 新增模式卡片,或通过 `POST /api/mode-profiles/{id}` 修改模式卡控制流后,主服务会先完成 YAML 持久化和 `/n7/scenes` 原子同步,再从同一份目录投影中按模式 ID 提取一个 `scenes[]` 元素,并在 1 秒内以约 333 ms 间隔向 MQTT `from_pc/scenes` 发布 3 次。每帧都是完全相同的更新后单卡 JSON,不包含目录外层或其他已有卡片,QoS 沿用车辆 MQTT 配置且 `retain=false`。删除和页面刷新只更新原有持久化/目录链路,不会触发该 Topic。
|
||||
|
||||
检测到已绑定外设的 NFC 卡时,主服务会按英文稳定 `device_id` 对已学习且启用的红外能力分组,并向 MQTT `extension/toy` 发布 3 帧相同的设备能力消息(约在 0、333、666 ms 发布,QoS 1、`retain=false`)。`extension_name` 使用中文显示名,`actions[].target_scope` 使用英文 `device_id`;卡片持续停留不会重复发送,移开后再次检测才会重新发送。该消息仅广播能力目录,不会触发红外发射。
|
||||
|
||||
车端需要控制这些 TCP 红外外设时,向同一个车辆 MQTT Broker 的 `extension/ctl` 发布 QoS 1、`retain=false` 的 JSON。PC 主服务固定订阅该 Topic;消息外层必须且只能包含 `domain`、`operation_count`、`actions`,其中 `domain` 为 `self_extension`,`operation_count` 必须与动作数量一致(1–64),`actions` 使用 `/n7/scenes` 中的红外动作格式:
|
||||
|
||||
```json
|
||||
{
|
||||
"domain": "self_extension",
|
||||
"operation_count": 2,
|
||||
"actions": [
|
||||
{
|
||||
"type": "infrared_emit",
|
||||
"at_ms": 0,
|
||||
"domain": "self_extension",
|
||||
"capability": "infrared.emit",
|
||||
"target_scope": "toy-light-001",
|
||||
"operation": "emit",
|
||||
"parameters": {"action": "打开", "slot": 2}
|
||||
},
|
||||
{
|
||||
"type": "infrared_emit",
|
||||
"at_ms": 1000,
|
||||
"domain": "self_extension",
|
||||
"capability": "infrared.emit",
|
||||
"target_scope": "toy-light-001",
|
||||
"operation": "emit",
|
||||
"parameters": {"action": "切换为蓝色", "slot": 5}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
服务在执行首条动作前会对完整控制流做原子鉴权:每一项都必须与本机目录中“已学习、已启用、具有持久 NFC 绑定”的 `device_id + action + slot` 完全一致;NFC 卡此时无需仍在感应区。执行前还会逐项重新鉴权,以阻止排队期间已被禁用或删除的能力。动作按 `at_ms` 排序后通过本机 TCP 红外网关串行下发,相邻发射至少间隔 800 ms;任一动作失败即停止剩余控制流。为避免重连误执行,retained 消息和 MQTT `dup` 重投消息都会被拒绝,消息体上限为 256 KiB。接收、鉴权、排队、执行结果和拒绝原因可在 `GET /api/extension/health` 的 `extension_control` 字段查看。
|
||||
|
||||
如果只需单独启动 UDP 发现和只读目录服务,也可以在另一个 PowerShell 终端运行:
|
||||
|
||||
```powershell
|
||||
|
||||
Reference in New Issue
Block a user