跳到主要内容

图 4 - 设备状态机转换图

整个设备的"心情"由 11 个状态描述,状态之间只有特定的合法跳转——这张图把所有跳转列全了。

如果上方图无法显示,点这里看 PNG 版本

11 个状态总览

状态中文屏幕/灯效含义
Unknown未知还没初始化
Starting启动中滚动条正在执行各种 Init
WifiConfiguring配网配网图标没 Wi-Fi 凭证或连不上
Activating激活中激活码需要用户在 App 输码激活
Idle待机时钟/表情监听唤醒词中
Connecting连接中加载圈正在打开音频通道
Listening听话中蓝光收音上传到云
Speaking说话中绿光播放云端 TTS
Upgrading升级中进度条跑 OTA
FatalError致命错误红光+错码不可恢复错误
AudioTesting自检测试图工厂烧录时跑音频测试

合法跳转的关键规则

代码里 IsValidTransition() 函数定义了所有合法跳转。不允许跳转的会被 ERROR 日志阻止——这是保证状态一致性的重要手段。

几个高频规则:

  1. Idle 是中枢:基本所有功能性状态都从 Idle 出发,结束后也回到 Idle。
  2. Listening ↔ Speaking 自由切换:用户打断 / 连续对话场景下来回切。
  3. Upgrading 是单向:进了就只能 esp_restart 出来,不允许回退。
  4. FatalError 也是单向:进了等用户重启。
  5. WifiConfiguring 是 Starting 的特殊分支:配完会回 Starting 重新走一遍流程。

监听者模式

任何模块都可以 RegisterListener(callback) 监听状态变更。Application 主要用这个机制:

  • 状态变了 → 监听器把"主线程事件" set 起来 → 主循环 HandleStateChangedEvent() 根据新状态做对应反应(开关唤醒词、切 LED、切屏幕等)。

注意线程安全:监听器列表用 mutex 保护;通知时先拷贝列表再调回调,防止回调内部修改列表造成死锁。

一句话讲清

"设备就 11 种心情,每种心情该亮什么灯、显示什么、监听什么音频都是写死的。所有交互都体现为状态间的跳转,跳转规则由 IsValidTransition() 集中管控,非法跳转会被丢弃并打日志。"

关联章节

  • /03-state-machine 整章