【免费下载链接】EchoMuse
Alexa replacement and controller for Echo Dot 2nd Generation device.
EchoMuse 是一款将 Echo Dot(第二代)改造为开源 Alexa 替代助手的硬件项目。由于设备没有屏幕,那一圈LED 光环(LED Ring)就是它唯一的界面——绿色表示正在聆听、红色表示麦克风已静音、橙色脉冲表示控制器失联。本文带你完整理解 EchoMuse 的灯环状态模型、5 种内置场景和led_anim动画开发机制,并给出可上手的源码路径与调参指南。
为什么灯环需要一套"状态模型"?
EchoMuse 的硬件只有 12 颗环状 LED 加 1 颗独立的静音按钮 LED。整个项目的核心要求是:灯环必须不打断、一致、可理解——"一个点亮了却毫无下文的光环,比从不点亮的光环更糟糕"。
官方文档 docs/led-ring-states.md 是灯环行为的权威规格书,定义了每个状态的归属、事件与结果。想看懂下文,先记住一条总原则:
反馈在本地,决策在远端。设备只点亮自己能直接感知的事(按钮被按下、扬声器缓冲清空、已静音);控制器负责需要全局信息的事(是否说了唤醒词、哪台设备应答)。
灯环所有权阶梯:谁在控制这圈光?
当多个"系统"同时想点亮灯环时,EchoMuse 用一套优先级阶梯(priority ladder)仲裁:最高层的激活者赢得物理点亮权,低层仍会把状态记录到baseLEDs,以便到期后无缝交还。
| 优先级 | 拥有者 | 外观 | 寿命 | 主权 |
|---|---|---|---|---|
| 1 | 音量弧 | 青色,12 格中按比例亮 N 格 | 2 秒窗口 | 设备本地 |
| 2 | 静音环 | 纯红(180,0,0)+ 按钮 LED | 直到取消静音;重启和 OTA 后仍保留 | 设备绝对主权 |
| 3 | 链接状态 | 橙色正弦脉冲(失联)/ 白色慢脉冲(待批准) | 直到链接恢复 | 设备本地 |
| 4 | 对话/媒体动画 | solid·spin·rotate·pulse·meter·off | 被替换或ttlSec到期(聆听 30s / 转圈 135s) | 控制器指定、设备渲染 |
| 5 | 方向叠加 | 在波束角度处把基础色提亮趋白 | 聆听光环存在期间 | 设备本地 |
| 6 | 空闲 | 全灭 | — | — |
几个关键仲裁细节:
- 静音环压制一切。无论控制器发来什么动画,静音时红灯不闪不撤。这是隐私指示器,不是装饰——代码见 device/internal/server/mute.go。
- 音量弧压制动画但不压制用户。2 秒内动画帧(约 80ms 一帧)不会覆盖青色音量弧;但按下动作按钮会立即取消这个"持有",聆听环立刻接管。代码见 device/internal/server/volume.go。
- 动画替换是原子的。生成计数器(generation counter)保证过期的动画协程永远不会覆盖新动画——这是整个灯环最容易被破坏的不变量之一。
永不改变的颜色词汇表
EchoMuse 坚持"一个信号只有一个含义":新增故障模式会归入现有词汇,而不是发明用户必须重新学习的信号。以下三种颜色在所有场景中固定不变:
- 🔴红色 = 麦克风静音(隐私指示器,跨重启保留)
- 🟠橙色 = 控制器不可达 / 上游链路故障
- 🔵青色 = 音量弧线
正因如此,controller/em_scenes.py 里的 "malevolent" 场景刻意不使用纯红(180,0,0),而用深绯红——避免与静音环混淆。
5 种灯环场景:从经典绿到旋转彩虹
场景(Scene)决定"聆听"(实心环)和"思考"(旋转点)长什么样。配置键为ledScene,支持全局或按设备设置,推送后即时生效(实现见 controller/em_scenes.py):
| 场景 | 聆听环 | 思考动画 | 一句话点评 |
|---|---|---|---|
standard | 经典绿 | 绿色头部 + 暗绿尾迹旋转 | 默认场景,复刻 Alexa 观感 |
airy | 淡雅天蓝 | 浅蓝旋转 | 低饱和、平静 |
malevolent | 深绯红 | 炭火色旋转 | 刻意避开纯红,保持静音语义无歧义 |
pride | 12 色彩虹环 | 彩虹环整体旋转(rotate) | 每个 LED 一个色相 |
custom | 自定义ledListenColor | 自定义ledThinkColor | 填#RRGGBB十六进制色值 |
未知场景名会回退到standard,过期的坏配置永远不会弄坏灯环——这是场景解析resolve()的设计兜底。
场景配置入口在 Dashboard 的 Ring 面板,完整字段文档见 docs/configuration.md 的 "04 — Ring" 一节。
开发指南:led_anim动画引擎核心概念
v2.9+ 固件引入了能力位led_anim:控制器不再逐帧推灯效,而是发送一条动画规格(AnimSpec),设备在本地按自己的 ticker 渲染。转圈动画的流畅度从此与 WiFi 抖动、控制器事件循环负载彻底解耦。协议字段定义在 device/internal/server/animator.go,控制消息格式见 docs/device-controller-interface.md。
六种动画模式(Pattern)
| 模式 | 含义 | 颜色语义 | 周期 |
|---|---|---|---|
off | 全灭 | — | — |
solid | 整环实心点亮 | 单色=整环;多色=逐灯 | — |
spin | "头部+尾迹"旋转点 | [head, trail]双色 | periodMs,默认 80ms |
rotate | 调色板整体绕环旋转(彩虹 spinner) | 调色板每帧旋转一格 LED | periodMs,默认 80ms |
pulse | 正弦呼吸 | 被亮度调制的调色板 | 一个完整呼吸周期,默认 2000ms |
meter | 亮度跟随实时扬声器 RMS | 被音频电平调制的调色板 | 固定 40ms tick |
关键设计点
ttlSec死人开关。每个动画规格都带 TTL:聆听 30 秒、思考转圈 135 秒、播放 meter 按音频时长按max(30s, 2×时长+20s)计算。控制器中途死掉时,灯环会自我熄灭,而不是永远转圈。listening: true标志。它标记"这是聆听环",是方向叠加(波束成形高亮)生效的开关。- 方向叠加只提亮、不硬编码。波束角度处把场景基础色向白色提亮,绝不画一个写死的绿色——在非标准场景下绿色会看起来像故障。
- 旧固件降级路径。不支持
led_anim的旧固件仍走逐帧leds消息,由控制器渲染每一帧;两种路径通过led_anim_capable自动切换。
Meter:让光环跟随声音"呼吸"
meter是 EchoMuse 最有表现力的动画:响应语音播放时,灯环亮度跟随扬声器输出的实时电平脉动。注意它测量的是语音平面(音乐混音之前),这样 AEC 远端信号与灯环各取所需,灯环不会为没人要求可视化的歌曲而跳动。
响应曲线(response curve)被设计为可调的口味参数——通过仪表盘调参刷新页面即可,无需每次迭代都做固件 OTA。六个参数(配置键 → 线上字段):
| 参数 | 作用 | 默认 | 范围 |
|---|---|---|---|
meterAttack(attack) | 包络上升系数(每 40ms tick) | 0.6 | 0.05–1.0 |
meterDecay(decay) | 包络衰减系数;0.30 → τ≈133ms,恰好跟住音节节奏 | 0.30 | 0.02–1.0 |
meterFloor(floor) | 静音时的感知亮度底 | 0.06 | 0.0–0.6 |
meterGamma(gamma) | 输出 gamma,>1 扩展暗端 | 2.2 | 1.0–3.5 |
meterRef(ref) | 映射到满刻度的 RMS 参考值 | 0.22 | 0.02–1.0 |
meterCurve(curve) | 输入指数,<1 抬升安静细节 | 0.7 | 0.3–2.0 |
设备侧在 device/internal/server/animator.go 的resolveMeter()中做独立钳位——一条错误的配置推送不能把灯环调成"死灯"或癫痫级闪烁。
结束线索:用节奏而非颜色讲故事
红、橙、青已各有归属,所以"对话如何结束"用节奏来区分(规格见 controller/em_scenes.py 的 outcome 动画):
- 一次慢呼吸(900ms 周期)——"我在听,但没听到任何话。"
- 几次快速闪烁(220ms 周期)——"出错了。"
- 灯环直接熄灭——正常结束,或你主动取消了。
- 两次橙色脉动——"听到了你,但上游没有 Home Assistant 可对话"(复用失联橙,无需图例即可读懂)。
- 1 秒稳定保持——"听到了,没有更多要做的"(HA 卫星配置毫秒级结束对话时的确认反馈)。
开发者速查:核心文件地图
| 关注点 | 文件 |
|---|---|
| 灯环行为权威规格(状态表、不变量、风险注记) | docs/led-ring-states.md |
| 场景调色板与 outcome 动画规格 | controller/em_scenes.py |
| 设备端动画引擎(AnimSpec、meter 钳位) | device/internal/server/animator.go |
动画文件格式解析(12 灯.animation) | device/pkg/led/animation.go |
| 静音环(设备主权 + 持久化) | device/internal/server/mute.go |
| 音量弧(2s 窗口 + mute 感知交还) | device/internal/server/volume.go |
| 用户文档:场景、Remote volume arc、结束线索 | docs/configuration.md |
控制协议:led_anim消息与配置推送字段 | docs/device-controller-interface.md |
结语
EchoMuse 的 LED 光环之所以"会说话",靠的是一整套纪律:固定颜色词汇、优先级仲裁、死人 TTL、原子替换,以及"设备知道的事设备说了算"的主权原则。作为开发者,你可以从场景预设开始定制观感,从 meter 响应曲线开始打磨"光环随声呼吸"的手感——所有调参都即时热推送,无需触碰固件。
【免费下载链接】EchoMuse
Alexa replacement and controller for Echo Dot 2nd Generation device.
相关推荐
告别单调灯光:ESPHome打造会"说话"的LED矩阵艺术屏
告别单调灯光:ESPHome打造会"说话"的LED矩阵艺术屏 你是否厌倦了千篇一律的LED灯带效果?还在为复杂的Arduino代码望而却步?本文将带你用ESPH
嵌入式物联网智能家居CLI无缝开发体验:Daytona会话状态与环境配置全攻略
无缝开发体验:Daytona会话状态与环境配置全攻略 你是否曾在切换开发任务时丢失工作进度?是否因环境配置不一致导致代码运行异常?Daytona作为开源开发环境
gz-sim 灯光动态配置指南:用 `/world/<world name>/light_config` 服务实时修改场景灯光
gz sim 灯光动态配置指南:用 /world/<world name /light_config 服务实时修改场景灯光 本教程介绍 Gazebo Sim(g
机器人
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考