Files
Michal ZaniewiczandClaude Sonnet 5 52d4a878b0 release: v1.0.1
Date the changelog entry for the mic gain fixes and move the pinned release tag
in the example config and README from v1.0.0 to v1.0.1.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-20 20:28:04 +02:00

165 lines
8.9 KiB
Markdown

# Changelog
## [1.0.1] - 2026-09-20
Patch release fixing the mic gain control. Tagged `v1.0.1`; the example config
now pins this tag.
### Fixed
- **Mic gain slider snapped back to its old value in Home Assistant.** The
`Mic gain (ES7210)` number had a `set_action` but was not `optimistic`, so the
new value was never published back. The ES7210 was reprogrammed correctly (the
device log showed the new gain), but HA kept displaying the previous value and
reset the slider on the next visit. The number now publishes its state after
every change.
- **A saved mic gain was not applied to the ES7210 after a reboot.** A template
number restores its value from flash in `setup()` and publishes it, but does
not run `set_action`, so HA showed the saved gain while the codec started at
the default from `audio_adc`. `on_boot` (priority -100) now pushes the restored
value to the ES7210. `set_mic_gain()` is safe to call there because the driver
stores the value even before its own setup completes.
## [1.0.0] - 2026-07-18
First stable release. The full voice assistant is confirmed on hardware, the
regressions found during bring-up testing are fixed, and the project ships with
complete documentation and a wiki. Tagged `v1.0.0`; the example config pins this
tag so a build is reproducible instead of tracking a moving `main`.
### Fixed
- **Boot loop into safe mode after selecting a ring effect.** The three
effect selects restore their saved option during `setup()` (at HARDWARE
priority), which fired `on_value` and ran the LED state machine before the
light/RMT and voice_assistant were initialised, painting an effect on an
uninitialised strip and crashing the boot. The `on_value` is now gated on
`init_in_progress` (cleared by `on_boot` at priority -100), so it only runs
once setup is complete; a live effect change from HA still repaints the ring.
### Changed
- **Boot chime is now a bundled sound, not the wake-word beep.**
`base/sounds/startup.mp3` (16 kHz mono, ~11 KB) plays on connect to HA and is
swappable through the `boot_sound_file` substitution (any URL or local
MP3/FLAC/WAV; the media player decodes all three).
### Removed
- **The Flicker ring effect** (weak visually); 15 effects remain.
## [0.2.0] - 2026-07-18
First on-hardware bring-up. The full voice assistant works: on-device wake word,
STT/intent/TTS, clean playback, no boot hiss - all on stock ESPHome components.
### Changed
- **Audio reworked to two I2S buses with the mic as master; the patched es8311
and `force_master` are gone.** The board shares BCLK/LRCLK between the DAC and
ADC, and ESPHome can't run one bus full-duplex (the speaker hits "Parent bus
is busy"). Two buses over the shared pins, with the always-capturing mic
mastering the clock and the speaker slaving to it, gives simultaneous capture
and playback on stock components. The mic is pinned to 16-bit so its master
frame matches the DAC (a 32-bit frame played back as noise).
- **The amplifier is gated on playback** (`ALWAYS_OFF` at boot, turned on by the
media_player `on_state`) to remove the idle hiss the always-on amp produced
before the first playback.
- **API encryption dropped** (LAN-only device); `secrets.yaml` is now just Wi-Fi.
Re-enable it via the commented block in `base/core.yaml` if you want it.
- **Timers are visible in HA** (the "Next timer" / "Next timer name" sensors are
no longer `disabled_by_default`).
- **Boot chime**: a short "ready" sound plays once the device connects to HA,
played after the mic (I2S master) is clocking so the slave speaker can output
it. New `boot_sound` switch toggles it. The sound ships with the repo
(`base/sounds/startup.mp3`, 16 kHz mono) and is swappable via the
`boot_sound_file` substitution (any URL or local MP3/FLAC/WAV).
### Added
- **Per-phase ring animation, pickable from HA.** New "Listening effect",
"Thinking effect" and "Replying effect" selects choose the animation for those
voice-assistant phases (the phase colour stays fixed). 15 effects to choose
from: solid, three pulses, Breathe, Wipe, Scan, Spinner, Comet, Twinkle,
Random Twinkle, Fireworks, Fire, and two rainbows. Breathe / Spinner /
Comet / Fire are custom `addressable_lambda` effects.
### Fixed
- **The Pulse LED effects showed a solid colour instead of pulsing.** Their
`update_interval` (16 ms) was shorter than the transition (300-1000 ms);
`update_interval` is how often the pulse flips its brightness target, so it
flipped faster than the brightness could move. Now ~2x the transition, with
30-100% min/max brightness.
- Compile-time issues found during bring-up: a quoted `mclk_multiple`
substitution (string vs the int a `cv.one_of` wants), a `template select`
missing its `options:`, `select` `.state` -> `current_option()`, the dead
microWakeWord model URLs (404), and a `/` in a switch name.
### Removed
- **The `stop` wake word.** This board has no usable hardware AEC, so the mic
hears the device's own TTS far louder than the user; "stop" is detected only
weakly and too late to be useful.
- **The daily-alarm entities** (Alarm time / Alarm on / Alarm action), the
device-clock text sensor, and the diagnostic mic-disable switch are now
`internal:` (hidden from HA). The logic stays; the clutter is gone.
- The dead "Mute and unmute sound" switch and its unused sound files.
- `components/es8311/` and the `external_components:` block - no longer needed.
## [0.1.0] - 2026-07-17
First cut. A working single-file config for the Waveshare ESP32-S3-AUDIO-Board,
restructured into a core package + a thin user config, with the patched
`es8311` component brought in-tree so nothing depends on an upstream repo that
has gone quiet.
### Added
- `base/core.yaml`: the always-on core with ES8311 speaker, ES7210 dual mic,
on-device wake word (`alexa` + `okay_nabu`), the HA Assist pipeline,
music/announcement mixing with ducking, the 7x WS2812 status ring state
machine, the three onboard buttons, voice timers and an alarm clock.
- `waveshare-va.yaml`: thin user config. Pulls the core from GitHub at compile
time, so it is the only file you keep.
- `components/es8311/`: vendored fork of ESPHome's `es8311` adding
`force_master` + `mclk_multiple`. Origin, credits and the licensing situation
are in the README.
- `docs/HARDWARE.md`: board pinout and the I2C device map.
- `skill/waveshare-esp32-s3-audio/`: Claude Code skill with pinout + gotchas.
- `scripts/validate.py`: offline YAML check (syntax, substitutions, duplicate
ids) so a typo does not cost a dashboard round trip.
- `scripts/esplog.py`: stream device logs over the native API.
### Fixed
Bugs carried over from the config this started as:
- **The mic was stopped on every boot.** The `diag_disable_mic` check was
inverted: with the switch in its default OFF position `on_boot` ran
`micro_wake_word.stop` + `microphone.stop_capture`. It only ever recovered
because `on_client_connected` restarted the wake word, so the switch also did
not actually work, in either direction.
- **"Microphone Mute" did not mute.** It dropped the ES7210 gain to `0.0f`,
but 0 dB is *unity* gain, not silence. The mic kept hearing the room and only
the wake-word handler ignored it. It now uses ESPHome's own `microphone.mute`,
which hands every consumer a zero-filled buffer, so the wake word hears actual
silence with no I2S restart.
- **A test sound fired on every LED repaint during boot.** A leftover
`id(play_sound).execute(1, id(wake_word_triggered_sound)); //TEST` sat in the
`init_in_progress` branch of `control_leds`.
- **Wake word sensitivity did nothing.** The select only set cutoffs on
`okay_nabu`, while the primary wake word is `alexa`. It now sets both.
- **Mic gain slider promised 42 dB.** The ES7210 caps at 37.5 dB and the driver
silently clamps, so the top third of the slider was a lie. Range is now
0 to 37.5 dB in 1.5 dB steps (the chip's real granularity), and the boot value
in `audio_adc` matches the number entity instead of contradicting it (24 dB vs
a 32 dB global).
- **The API encryption key was hard-coded in the config.** It now comes from
`!secret api_encryption_key`.
- **The `time:` block was half-commented-out**, leaving `id: rtc` dangling under
`platform: homeassistant`. Cleaned up. PCF85063 support is not in this build.
- **Two `on_boot: priority: -100` blocks** ran in an order nobody had chosen.
Merged into one.
### Changed
- All pins, audio format and the HA-facing values are `substitutions:` with
documented defaults, instead of literals scattered through the file.
- `${mic_channel_${which_mic}}` nested-substitution trickery replaced with two
plainly named knobs: `mic_channel` (the I2S slot) and `mic_va_channel` (the
index handed to Assist). These are genuinely different things and the old
names implied they were the same one.
- Dropped dead substitutions (`i2s_bits_per_sample`, `i2s_mode_speaker`,
`rtc_int`, `mic_channel_2`) and the now-unused `mic_gain_saved` global.
- Timezone is a `posix_timezone` substitution rather than a hard-coded `UTC0`.