以下五条用户流程是 App 的主要叙事骨架。每条都串起 用户动作 → 页面 → Provider/Service → BLE 流量 → 硬件响应 → UI 状态切换 全链路,供 agent 和新人快速建立端到端的心智模型。字节级细节(0x55AA 格式、锁刷新间隔、断开错误码 0x07、温度查表规则等)见 v4.2 BLE 协议规范 与 CM4 协议。
ScanPageScanPage 通过 activeDeviceServiceProvider.scanForDevices() 开始 BLE 扫描;ScanPage 在 rootRouteObserver 上 subscribe,子页面 push 上来时主动暂停扫描以让出 BLE 优先权(避免和重连循环抢扫描槽)Booster 模型(名称 / 信号 / 电量),用户点击某台设备ScanPage 调用 service.connect(deviceId, trigger: 'user-select')AE30 → 解析特征 AE03(写)+ AE05(通知) → BleDeviceService._transportFor(deviceId) 根据 deviceId.boosterFamily 懒创建 LegacyBoosterTransport 或 Cm4BoosterTransport → transport 写出 family-specific 独占锁刷新(legacy 0x55B1 每 45s / CM4 ASCII CNT_0 每 45s——per Liang 2026-06-06 / c613148 起两家族同 cadence)CookingPage(deviceId, probeNumber)(路由参数 (String, ProbeNumber),见 app.dart:136-146)CookingPage 从已有会话 / 待定参数 / 探针默认值中恢复 target / 肉种 / 熟度CookingSessionsNotifier 创建 CookingSession(isActive=true);iOS 上 cookingLiveActivitySyncProvider 同步 start 一张 Live Activity 卡(锁屏 / 灵动岛),Android 静默 no-opalarmStateProvider 驱动——main.dart 里的 container.listen(connectedBoostersProvider, ... container.refresh(alarmStateProvider)) 让每次新遥测都触发重评;额外有 5s Timer.periodic 兜底 no-telemetry 场景(probe-disconnect 阈值无新包不会自然触发)AlarmType.targetReached → 顶部 AlarmBannerHost banner(不是全屏;full-screen WarningPage 仅留给 internalOverTemp / ambientOverTemp 这两类 safety alarm,见 app.dart:63-90)+ 响铃 + 震动0x07 断开 → 检查 _lastDockEventAt:
_dockShutoffWindow=1s) → 归类为「入仓关机」,发 DeviceStatus.boosterShuttingDown → 10 秒过渡(_dockShutoffUiDelay=10s) → DeviceStatus.boosterOff;首次重连延迟 8 秒(_dockShutoffReconnectDelay)gracePeriod=90s),UI 继续显示最后已知温度;前台始终 15 秒一次扫描尝试重连AlarmType.boosterDisconnected 单声+通知GRACE_RECOVERED 日志、卡片无缝切回在线(用户甚至察觉不到);与之相应的 _DeviceState.lastConnectedAt 重新打点,alarm 评估器对此设备暂停 probe-disconnect 评估 60s(让残留 15B 静默自然刷新或被确认)0x55AA,_onAe05Rx 在 RX 时刻立即打点 _lastDockEventAt[deviceId](不在 handler 里打——0x07 断开可能在 ~65 ms 内到,先于 buffered handler)BleDeviceService._handleProbeStatus 将相应 Probe.isDocked = true;触发 AlarmType.probeDocked 单声+通知(per Liang 2026-04-30 #18 a)0x07 断开_lastDockEventAt 在 1s 内,归类为入仓关机:发 DeviceStatus.boosterShuttingDown → 等 10 秒过渡 → 发 DeviceStatus.boosterOff → 单声 AlarmType.boosterPoweredOff 通知(per Liang #18 — 期望行为也要明确确认)_transportFor 懒创建deviceId.hashCode 相位错峰(ble_service.dart:1354),不会同步堵塞 BLE 命令队列CookingSession 为 (CM4_A, ProbeNumber.probe1) 创建CookingSession 为 (CM3_B, ProbeNumber.probe3) 创建AlarmKey = (deviceId, ProbeNumber?, AlarmType) 三元组键(alarm_service.dart:117,TAPD 2026-05-11 多探针回归后定型;老代码曾以 deviceId 单键导致 Probe 1 vs Probe 2 同事件被吞)BleDeviceService.disconnect() → 停心跳、停 staleness/RSSI/no-probe-telemetry timers、关连接removeFromReconnectQueue(deviceId) → 清设备状态、重连队列、入仓时间戳、各种 timer、_devices 条目、_transports 条目KnownDevicesService.remove(deviceId) → 从 SharedPreferences 删除DEVICE_FORGOTTEN 事件字节级细节(0x55AA 格式、锁刷新间隔、断开错误码 0x07、温度查表规则、CM4 SET_RD / SET_01..04=ABCDEF 命令等)见:
本页只讲用户视角和 App 的反应。