Files
DCU_DesktopController/docs/compose/spec/device-link.md
T

81 lines
3.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
feature: device-link
status: delivered
updated: 2026-09-16
branch: feat/device-link
commits: be26f4daa27cba70b4baeaeb3865f38ed51b2e71..6b5a9f9
---
# Device Link(全链路统一连接层)
## Report
**What was built** — `js/common/device-link.js` 在 `tabs.html` 以 Owner 身份常驻轮询
ESP32 `/system/status` 与 EtherCAT `/ecat/api/status`+`app/load`,经
`BroadcastChannel('dcu-device-link')` 广播快照;功能页 Client 订阅。
`connection.js` 的连接灯在快照 <5s 时只覆盖**在线布尔**,保留「设备忙」等语义文案。
LAN9252 页 SPI 失败显示「设备在线 · SPI 失败」,不再误标设备离线。
BLE GATT 在通知开启成功后 `reportBle(true)`,失败/断开上报 false。
**Verification** —
- `node --check`:device-link.js / connection.js / gatt.js PASS
- tabs.html、lan9252_pm 内联 script 抽出 `node --check` PASS
- 独立评审后修复:ECAT `Promise.all` 补 `.catch`+必重挂;去掉跨 iframe 无效的
`window.__dcuDeviceLinkSnap`;BLE 半开连接不再 sticky online
**Journey log** —
- 「共用 IP」≠「共用连接」——健康态必须有单一 Owner
- 外壳 Owner + 页内 Client 双 BC 实例符合 BroadcastChannel 语义(同上下文不自发自收)
- SPI/业务失败与设备离线必须分文案,否则子系统故障会伪装成掉线
- ECAT 轮询的 reschedule 必须在 `.catch` 之后,否则一次异常永久停摆
## [S1] Problem
多 iframe 保活后,各页仍**各自** `fetch` 设备,只是共用 `localStorage.dcu_esp_ip`:
- OTA 页轮询 `/system/status` → 顶栏「WiFi 已连接」
- LAN9252 页轮询 `/spi/send` → 同一 IP 却显示「连接失败 · signal timed out」
- EtherCAT 负载/状态又是一条独立轮询
- BLE 在页内 GATT,其它页完全不知
用户直觉是「同一条设备连接」,实现却是 N 条互不证明的 HTTP/蓝牙会话。
## [S2] Design
### 原则
1. **外壳持有链路健康轮询**(tabs.html 常驻),功能页不再各自判定「设备在线」。
2. **BroadcastChannel**(`dcu-device-link`)广播快照;页内只订阅渲染。
3. **命令仍页内发**,但**连接灯只认 DeviceLink**(布尔优先,文案保留调用方语义)。
4. SPI 失败 →「设备在线 · SPI 失败」;DeviceLink offline 才显示离线。
5. 独立直开页:无快照时回退本地轮询。
### 模块
`js/common/device-link.js` Owner+Client;消息:`hello` / `snapshot` / `set-ip` / `ble-state`。
### 接入
| 位置 | 行为 |
|------|------|
| `tabs.html` | Owner |
| `connection.js` | 快照新鲜时覆盖 connected 布尔 |
| `lan9252_pm.html` | 订阅灯 + `setSpiFail` |
| `js/ble/gatt.js` | 通知成功后 reportBle(true),失败/断 false |
## [S3] Out of Scope
- 不串行化 SPI/CAN/OTA 命令队列
- 不迁 SharedWorker
- 不改固件协议
- BLE GATT 仍留在页内(只广播状态)
## Tasks
- [x] T1: device-link.js Owner+Client + BC 协议 (covers: S2)
- [x] T2: tabs.html 启动 Owner (covers: S2)
- [x] T3: OTA connection.js 接入 DeviceLink (covers: S2)
- [x] T4: LAN9252 灯与 SPI 文案 (covers: S2)
- [x] T5: BLE 状态上报 (covers: S2)
- [x] T6: 语法检查 + 评审修复 (covers: S2)