feat: expand companion platform, device controls, and memoir workflows
ci / verify (push) Canceled after 0s
ci / verify (push) Canceled after 0s
Add customer and operator login, BLE provisioning, device fleet controls, call memory, memoir generation, and refreshed family and maintenance portals. Include API contracts, migrations, firmware sources, tests, assets, and deployment documentation.
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
# EchoEar 出门前远程升级交付记录
|
||||
|
||||
日期:2026-09-30。目标设备为 COM6,工厂号 `KP01-020026091601`,型号 `ECHOEAR-S3`。
|
||||
|
||||
## 最新结果(2026-10-01)
|
||||
|
||||
真实 21 → 22 远程升级已成功,任务 `18216193-939f-47a4-b49b-96e9002eb05e` 于 09:44:31 北京时间回报成功。设备运行 `1.7.0-controls.22 / code 6`,MQTT 在线,配置 19/19、音量 56、原绑定数 1 保留。3,761,200 字节镜像下载、写入和安装校验耗时 41.003 秒,发起至重启成功回执共 67.394 秒。USB 只供电及采集日志,镜像经 Wi-Fi/HTTPS 下载;独立供电、受控实物启动失败回退和手机更换热点仍未验收。详细对照、失败过程及修复见 [性能验收记录](device-ota-performance-20261001.md)。
|
||||
|
||||
## 逐次验收记录
|
||||
|
||||
- 设备已通过 USB 安装 `1.7.0-controls.13`,只写已确认的活动应用槽 `ota_0 / 0x10000`;应用哈希校验成功。写入前已完整备份 16 MiB Flash,保留 NVS、工厂身份、分区、启动程序、OTA 数据及屏幕/语音资源。
|
||||
- 原设备停留在过期的 BLE 窗口,云端最后心跳为 9 月 27 日。本次安装后真实蓝牙扫描、连接、`get_info/get_status` 均通过。
|
||||
- 未提交新配网信息,5 分钟窗口到期后设备恢复原来保存的 `asus` Wi-Fi。20:53:59 北京时间云端确认实时在线、MQTT 已连接、`ota_supported=true`、设备空闲。
|
||||
- 原账号绑定数 1、音量 56、配置版本 19/19、正常运行状态均保留。用户提供了同名 Wi-Fi;因为设备已自行恢复联网,没有再写入密码,也没有将密码加入项目文件。
|
||||
- 云端已发布 `1.7.0-controls.14`,版本顺序号 **2**,状态 `READY`。它与串口安装的修复版仅版本字符串不同,用于真实远程升级和 A/B 槽切换验收。
|
||||
- 家属已完成新版拼图验证并登录。23:13:04 北京时间通过真实家庭端发起远程 OTA;设备接收任务并开始 HTTPS 下载,23:14:39 返回 `OTA failed: ESP_FAIL; original firmware retained`。原固件 `controls.13`、顺序号 0 和原绑定、音量、配置均保留。**该次真实 OTA 未通过,不能把编译、USB 刷写、HTTP 200 或 `ota_supported=true` 当成成功。**
|
||||
- 23:32:42 通过同一已登录家庭端发起一次受控重试;23:40:05 返回 `ESP_ERR_TIMEOUT`,原固件保留。该次 `/f/` 请求持续 430.039 秒,向设备发送 2,719,221 / 3,757,536 字节(72.36%),上游读取 2,739,701 字节。数据确认当前实物下载在固件 420 秒总期限内没有完成;不能把 HTTP 200 当作完整送达。
|
||||
- 临时传输日志仅记录固定脱敏路由、状态和计数,不记录下载票据、IP 或请求头。采样后已恢复网关原配置,SHA256 和所有容器 ID 一致。两个任务均失败,当前设备仍为 `controls.13` / code 0,MQTT 在线、配置 19/19、音量 56、绑定数 1。
|
||||
- 10 月 1 日 00:00 前后,用户将 USB 接回,已确认同一 MAC、原 `controls.13` 应用 SHA256、活动 `ota_0` 的有效选择数据与原分区表一致。只写 `0x10000` 的应用镜像 `controls.15`,完整读回 SHA256 为 `cdb2852dd113ce551f95742b7ea784a3c70bb96f23c369a665a04c47f89b4236`;没有写启动程序、分区、OTA 数据、NVS、身份或资源。分区表/OTA 数据写前写后逐字节相同。
|
||||
- 修复版将下载总期限改为 **900 秒**;同一连接无数据的 EAGAIN 最多连续等待三次,收到数据重置计数。每次等待按剩余总期限裁剪;提前 EOF 和其他负值不盲重试。失败回执包含具体阶段、成功写入字节数、原始读取值及 errno,不包含私有下载地址。
|
||||
- USB 本地更新后,云端真实确认 `controls.15` / code 0、MQTT 在线、支持 OTA;配置 19/19、音量 56、原绑定数 1 保留。**这只证明本地更新后的运行状态,不是远程升级通过。**
|
||||
- 配套 API `0.99.20-rc.ota-budget1` 已上线:已接收任务、下载授权和下载写入期限为 **20 分钟**,覆盖 15 分钟下载和 3 分钟启动健康确认;待接收仍为 30 秒,票据仍为 30 分钟,晚到真实终态回执的纠正行为保留。只重建 API;网页 19、其他容器 ID、运行环境/端口/挂载、滑块策略 4 和数据库版本 74 均保留。
|
||||
- `controls.16` / code **3** 已发布 `READY`,与本地启动修复版 15 仅版本宏不同,大小 3,758,224 字节、SHA256 `6868bcb45f6c211e5e91524e7be5944fe2989f2e377f3bb455f3cdaacfbe0ecf`。发布使用真实 SSH 维护服务身份并记录 service/null 审计,没有使用或构造用户/运营登录会话;公网 HTTPS 全量读回与冻结镜像相同。发布记录 `a67129e0-e9c1-45e2-a30b-141018f74c76`。
|
||||
- 当时 15 → 16 的无线验收尚未发起。后续在 17 → 18 排除 Flash 写入瓶颈,在 19 → 20 证实接收端提速并定位 PSRAM 栈安装错误,最终 21 → 22 完整成功;以上旧状态按发生顺序保留。
|
||||
|
||||
## 明天远程升级的方法
|
||||
|
||||
1. 设备持续通电,连接有互联网的 Wi-Fi 或 2.4 GHz 手机热点;设备状态须实时在线。
|
||||
2. 运营端“固件管理”上传 **应用固件 `.bin`**,填写准确型号、版本名称和更新说明,等待平台大小/摘要校验完成并发布。
|
||||
3. 用对该设备有管理权限的家属账号进入设备详情,在“固件与远程控制”点“更新固件”并确认。小程序的设备管理也沿用同一云端升级流程。设备通话中须结束通话后再发起。
|
||||
4. 观察“等待设备接收 → 设备正在升级 → 升级完成”;升级期间会短暂离线。只有重启确认和成功回执都完成,才算升级成功。
|
||||
5. 如果显示未接收/失败/超时,确认设备恢复在线,刷新状态再发起;旧的 30 秒接收窗口不会因重连自动延长。
|
||||
|
||||
当前修复上传包在 `artifacts/firmware/1.7.0-controls.22/echoear-1.7.0-controls.22.bin`。大小为 3,761,200 字节,SHA256:`c13ae3b2aab18431466d40b5d60b101a8c3345e438be87ef474f85ac8653616f`;同目录的 `verification.json` 记录真实成功回执和计时。之前的 14/16/18/20 仅用于前述分阶段验证,不代表最终修复。
|
||||
|
||||
该设备每个应用槽为 4 MiB;不得上传合并后的整片 Flash、工厂身份、分区表、模型或屏幕资源镜像。远程升级不会更新这些独立资源分区。后续构建完成后可用工具生成经过型号、芯片、大小及编译版本检查的上传包:
|
||||
|
||||
```powershell
|
||||
python tools/package-ota.py --model ECHOEAR-S3 --out <输出目录>
|
||||
```
|
||||
|
||||
## 升级与联网修复
|
||||
|
||||
MQTT 仅唤醒升级任务;设备通过 DEVREQ1 签名 HTTPS 请求取不可变升级清单,再检查型号、顺序号、有效期、大小和 SHA256,写入非活动应用槽。启动健康确认后才报告成功;结果暂时发不出去则持久化补报。固件下载和安装失败保留原槽,待确认镜像有启动健康期限和 bootloader 回退保护。
|
||||
|
||||
本次补齐清单请求暂时失败后的有限重试,避免 MQTT 已确认投递后丢失唯一唤醒;终态回执的本地持久化失败不会放行下一次升级。云端已完成任务的冲突响应也不会永久卡住后续升级。日志只记录运行槽、版本顺序号、字节数和阶段,不记录私有下载票据。
|
||||
|
||||
云端修复 fleet OTA 与已有 SaaS `ASSIGNED` 升级任务的互斥判断。API 最小增量 `0.99.17-rc.ota-ready1` 已上线,实际生产源码只改该判断;运行环境、端口及挂载保持一致,其余服务未重建。
|
||||
|
||||
网页最小增量 `0.99.18-rc.reconnect-copy1` 的配网提示更正为“长按设备屏幕底部中央 3 秒”,已通过类型检查、构建和静态文件哈希检查。当前生产 `0.99.19-rc.local-slide1` 保留上述 OTA 和配网修复,并已部署本地开源拼图验证码。当前本地小程序文案也已更正并通过测试,本次未发布小程序。
|
||||
|
||||
重新联网与重新配网的完整规则见 [重新联网说明](device-reconnect-20260930.md):正常掉线持续重试,异地开机旧网络失败自动进入 BLE,已有配网设备无人确认时超时返回旧网络。**操作入口为长按屏幕底部中央 3 秒,发送新网络后 60 秒内轻触确认;保留原绑定。**
|
||||
|
||||
## 验证边界
|
||||
|
||||
### 10 月 1 日 08:28 下载慢的复查
|
||||
|
||||
- 电脑通过真实家庭端取得同一个 16 固件的短下载地址,正常 TLS 校验、无重定向,全量下载 3,758,224 字节用时 5.812 秒(646.6 KB/s),SHA256 与冻结包一致。未启动设备升级、未写设备 Flash,私有下载地址只临时保存在本地并在测试后删除。
|
||||
- 设备当前实际 RSSI 为 -21 dBm,报告时间 08:23:50,固件仍 15、在线;该信号是当前值,不能充当昨夜下载全程的信号测量。
|
||||
- 设备旧实测 430.039 秒发送 2,719,221 字节(约 6.3 KB/s),这个速度包含设备同步读取、擦写、校验及调度产生的反压,不是单独的网络吞吐测量。电脑对照与已排查的服务端限速/负载表明,应进一步定位设备处理和到设备的网络路径。
|
||||
- 当前每次最多读 4 KiB,再同步 `esp_ota_write`,使用 `OTA_WITH_SEQUENTIAL_WRITES` 逐扇区擦除。16 镜像按 4 KiB 对齐为 918 扇区;本板两个应用分区均按 64 KiB 对齐,当前 SDK 允许 64 KiB block erase,按已验证大小预擦可形成 57 个 64 KiB 块加 6 个 4 KiB 扇区。这是可测的优化点,**尚无分段实物计时,不能把它认定为全部慢速的唯一原因,也不能按擦除次数推导提速倍数。**
|
||||
- 本机开启 PSRAM 指令/常量读取,不能泛称本板每次擦除都会关掉 Wi-Fi/双核缓存。SDK 的 600ms 是擦除超时上限,不是固定等待时间。
|
||||
- 截止此复查,未修改预擦算法、未启用额外设备计时、未写新固件;此前 900 秒预算修复没有证明下载已提速。后续需要分别记录 begin/read/write/SHA 耗时,对比预擦方案并验收完整 OTA。
|
||||
|
||||
- 最终生产 OTA C 全部故障注入场景通过 GCC AddressSanitizer、UndefinedBehaviorSanitizer 与 float-cast-overflow,覆盖真实 SHA256、正常安装/确认、两槽版本恢复、重复任务、非法清单、截断/重定向/下载失败、持久化与计时器故障及本次恢复路径。
|
||||
- 网络重连和 BLE 超时的生产函数测试通过 ASan/UBSan,原有 BLE Wi-Fi 22 项生命周期测试通过。家庭端微信一键登录改造后的当前小程序 140 项测试及 9 页原生编译检查通过;网页类型检查通过。
|
||||
- ESP-IDF 5.5.1 最终固件编译通过,`controls.14` 的 host 测试编译单元与已验证 `controls.13` 完全相同。
|
||||
- 云端升级生命周期使用隔离数据库和真实 MQTT broker 验证;发布包经公网 HTTPS 下载回读,大小和 SHA256 与冻结包一致。
|
||||
- 已确认真实 USB 应用写入、BLE 只读交互和无人操作后自动回旧 Wi-Fi;首次真实 OTA 失败后原槽继续运行,最终 21 → 22 完成真实 A/B 远程安装、重启确认和成功回执,原绑定和设置保留。**受控实物启动失败回滚和手机更换热点仍未验收。**
|
||||
- 下载时间限制已用精确生产源码和完整 Middleware/otel 包装,在真实 TCP 上做三组对照:40ms 默认写超时会截断,下载处理器覆盖至 15 分钟后完整传输且 SHA256 一致。MinIO 活动下载体没有 60/90 秒总超时。此证据排除所测服务器期限问题,不能代替实物下载成功。
|
||||
- 最终 20 分钟云端增量通过隔离 Linux 的 8 项真实数据库/MQTT 生命周期测试(0 跳过)和 3 项完整 HTTP 封装 TCP 测试;测试覆盖 19:59/20:01、待接收 29/31 秒、撤销票据与晚到终态纠正。固件读取修复的完整生产 C 测试 15 组通过,包含 11 个新增故障场景,ASan/UBSan 无错误;14 验证构建、15 启动包和 16 OTA 包均通过 ESP-IDF 编译,源哈希已冻结。
|
||||
|
||||
受限本机证据保存在工作区外的 `.local-evidence/com6-ota-20260930` 和 `.local-evidence/remote-ota-20260930`;完整备份包含设备凭据,不应作为上传固件分发。
|
||||
Reference in New Issue
Block a user