Skip to content

EchoMuse v2.13.0

Latest

Choose a tag to compare

@github-actions github-actions released this 26 Aug 08:30
· 3 commits to main since this release

First device firmware since v2.12.0 (2026-08-17). One change you can see, and
one you cannot but should know about.

The listening ring lights the moment the device hears you. On an Echo
running owwOnDevice=on, the device already knew it had triggered and then
waited for the ring animation to travel back through the controller before
anything moved — measured at +522ms, on a link whose control-plane tail
reaches two seconds (#139). The acknowledgement was two hops behind the event
that caused it. It now draws the ring locally, at its own wake crossing, and
the controller's authoritative frame takes over when it lands.

This only changes devices set to owwOnDevice=on. Shadow mode is unchanged,
and a muted crossing keeps its existing path. Nothing about which sounds wake
the device changes — only how quickly the ring says so.

It needs controller 2.21.0 to do anything, because the ring's appearance
is pushed from there and this firmware draws what it was last sent. On an
older controller this build behaves exactly like v2.12.0, with no error and
nothing to configure. Updating in either order is fine.

The other change is that this release exists. The firmware had been
unbuildable with its own pinned compiler since 2026-08-18 — go.mod required a
Go version the pinned image does not carry, and the pin deliberately refuses
to fetch another, since a floating toolchain is exactly what the pin exists to
prevent. Nothing shipped in that state and no device was affected; a released
binary simply could not be produced. Fixed, and CI now builds the firmware
with the pinned compiler on every push and checks the result is an ARM binary,
so this cannot go unnoticed for four days again.

There are no other behaviour changes, no new configuration, and nothing to
change on your devices.

Update one device first and let it come back before doing the rest. The A/B
slot system rolls back on its own if the new binary fails to start three
times, and the update leaves the slot it is replacing intact so there is
something to roll back to — but watching one device is still cheaper than
watching all of them.

What's Changed

  • Fix ingress login crash: get_user_by_ha_id calls _conn as a function by @finik in #218
  • Stop openwakeword scoring its own reset noise by @dmndru in #215
  • Build the controller image on PRs that change what goes into it by @wilbowes in #221
  • Bump golang.org/x/sys from 0.32.0 to 0.47.0 in /device in the go-dependencies group across 1 directory by @dependabot[bot] in #128
  • chore(deps): bump the actions group across 1 directory with 11 updates by @dependabot[bot] in #205
  • Align the controller-image job with the bumped action versions by @wilbowes in #222
  • Take the routine half of #129, and fix the guard the other half slipped past by @wilbowes in #223
  • docs: the unlock needs Linux, not macOS by @wilbowes in #220
  • Write down the project's direction: portable, and not dependent on Amazon by @wilbowes in #228
  • Add a look-ahead limiter to the speaker path, so EQ boost stops clipping by @wilbowes in #232
  • Add a dynamic bass guard, so the driver is not asked for excursion it lacks by @wilbowes in #233
  • Write down how we answer people by @wilbowes in #238
  • Give each release channel its own satellite port range by @wilbowes in #237
  • Let the output chain change while a track is playing by @wilbowes in #239
  • Early Access 2.20.2-ea.2 by @wilbowes in #240
  • Carry the output chain to the running controller on a config save by @wilbowes in #241
  • Early Access 2.20.2-ea.3 by @wilbowes in #242
  • docs: the output chain, and the day's journal entry by @wilbowes in #234
  • docs: the evening's two bugs, and what the tuning knob actually does by @wilbowes in #244
  • docs: split CLAUDE.md into root + device/ + controller/ by @wilbowes in #245
  • Default the bass guard depth to -30dB by @wilbowes in #246
  • Instrument the output chain, and collapse its controls to one toggle by @wilbowes in #248
  • Count reachable admins, not user rows, when provisioning a Home Assistant user by @wilbowes in #249
  • Stop the device barging in on its own response by @wilbowes in #250
  • Stop the wake listener dying quietly, and recover a stuck pause by @wilbowes in #253
  • Fix the barge-in disconnect: two initialisers stranded after a return by @wilbowes in #256
  • Add LICENSE, NOTICE and CONTRIBUTING by @wilbowes in #257
  • Give each device a stored ESPHome identity, fixing MAC collisions by @wilbowes in #254
  • Trust a private CA, for a Home Assistant served over HTTPS with one by @wilbowes in #259
  • docs: the day's changes, and a journal entry for it by @wilbowes in #260
  • forge: run control, browser credentials, dashboard theming, and a published image by @wilbowes in #265
  • Say what an Early Access entry is built on by @wilbowes in #192
  • Stop the denoiser gating speech to digital silence by @wilbowes in #264
  • Give every device every stock wake word, and check it has one on connect (#191) by @wilbowes in #209
  • Check the controller imports and boots, and name the owners by @wilbowes in #287
  • Close the other way update checks reach GitHub while disabled by @wilbowes in #289
  • Say when automatic update checks are off by @wilbowes in #292
  • Let the firmware upload through again after the aiohttp bump by @wilbowes in #297
  • Record a playback barge as barged, which #251 missed by @wilbowes in #303
  • Pin the import job's base image by digest by @wilbowes in #298
  • Read the version compile.sh actually embeds, and stop claiming rollbacks by @wilbowes in #304
  • Record why a turn ended early, not just that it did by @wilbowes in #305
  • Record two things today cost, in the file that exists for it by @wilbowes in #308
  • Fix #306: loop_lag_peak_ms reads the running module, not a fresh import by @chr-braun in #309
  • Fix #197: Users tab in Settings — promote/demote without the API by @chr-braun in #310
  • Fix #326: darken the ring on the device that loses arbitration by @wilbowes in #327
  • Fix #329: a timed-out turn must serialise like an aborted one by @wilbowes in #330
  • Fix #331: drain the limiter tail before padding the final period by @wilbowes in #332
  • Serialise HA's run at turn teardown, not on the path that noticed by @wilbowes in #333
  • Fix #337: drop the thinking-phase low tier, whose cause was fixed elsewhere by @wilbowes in #340

New Contributors

Full Changelog: v2.12.0...v2.13.0