@BramNH Sadly I have exactly the same problem
so at least you are not alone
I can compile, flash and get all entities in home assistant. But the assistant never seems to go “active” in home assistant. In the logs, I do see that the wakeword is detected, but then the logs stop after setting state to “streaming_microphone”. I can put logs here later.
For now I just want to see if any older versions do work, or that it is just very unstable.
Oh okay then you are getting further than I do haha. Hoep someday there will be a solution. For me it is just stuck at “Preparing installation”.
On what system are you trying to build? I read it could use quite a bit of RAM.
My home assistant is running in a VM on an old laptop, it has 2GB of RAM. As I try to install it using the ESPHome add on I think this is the system you meant isn’t it?
Yes, quote from this site: On device wake word on ESP32-S3 is here - Voice: Chapter 6 - Home Assistant
“Changing the default “okay nabu” wake word will require adjusting your ESPHome configuration and recompiling the firmware, which may take a long time and requires a machine with more than 2GB of RAM.”
Oh okay, thank you. I got it to run through (took over 2000 seconds) and it said successfully installed but later wasn’t able to connect to the ESP:
Linking .pioenvs/m5stack-atom-echo/firmware.elf
/data/cache/platformio/packages/toolchain-xtensa-esp32/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: missing --end-group; added as last command line option
RAM: [= ] 10.6% (used 34684 bytes from 327680 bytes)
Flash: [======== ] 79.8% (used 1463925 bytes from 1835008 bytes)
Building .pioenvs/m5stack-atom-echo/firmware.bin
Creating esp32 image...
Successfully created esp32 image.
esp32_create_combined_bin([".pioenvs/m5stack-atom-echo/firmware.bin"], [".pioenvs/m5stack-atom-echo/firmware.elf"])
Wrote 0x177020 bytes to file /data/build/m5stack-atom-echo/.pioenvs/m5stack-atom-echo/firmware.factory.bin, ready to flash to offset 0x0
esp32_copy_ota_bin([".pioenvs/m5stack-atom-echo/firmware.bin"], [".pioenvs/m5stack-atom-echo/firmware.elf"])
======================== [SUCCESS] Took 2116.20 seconds ========================
INFO Successfully compiled program.
INFO Resolving IP address of m5stack-atom-echo.local
ERROR Error resolving IP address of m5stack-atom-echo.local. Is it connected to WiFi?
ERROR (If this error persists, please set a static IP address: https://esphome.io/components/wifi.html#manual-ips)
ERROR Error resolving IP address: Error resolving address with mDNS: Did not respond. Maybe the device is offline., [Errno -5] No address associated with hostname
Which does not make sense to me as I can see it in my routers network settings.
In my ESPHome the device I created with the configuration is shown as offline but next to it a new m5Stack Atom Echo has been discovered and I can adopt it.
It all looks very unclear to me.
I am also having issues with the domain name. Don’t install the firmware OTA, there should be an option to download manually and flash over usb
Sadly I did install it via USB :(. I will fiddle around a bit more and will hopefully find a solution haha
When I try to do that, I get an error, at the line I moved. could you please provide the complete working code.
---
substitutions:
name:
friendly_name: Atom Echo
static_ip: 192.xxxxxxx
micro_wake_word_model: okay_nabu # alexa, hey_jarvis, hey_mycroft are also supported
esphome:
name: "${name}"
friendly_name: "${friendly_name}"
name_add_mac_suffix: false
project:
name: m5stack.atom-echo-voice-assistant
version: "1.0"
min_version: 2024.6.0
esp32:
board: m5stack-atom
framework:
type: esp-idf
logger:
api:
encryption:
key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ota:
- platform: esphome
id: ota_esphome
- platform: http_request
id: ota_http_request
update:
- platform: http_request
id: update_http_request
name: Firmware
source: https://firmware.esphome.io/wake-word-voice-assistant/m5stack-atom-echo/manifest.json
dashboard_import:
package_import_url: github://esphome/firmware/voice-assistant/m5stack-atom-echo.yaml@main
http_request:
wifi:
networks:
- ssid: !secret wifi_ssid
password: !secret wifi_password
manual_ip:
static_ip: ${static_ip}
gateway: 192.xxxxxxxxx
subnet: 255.255.255.0
button:
- platform: factory_reset
id: factory_reset_btn
name: Factory reset
- platform: restart
name: "${friendly_name} Restart"
i2s_audio:
- id: i2s_audio_bus
i2s_lrclk_pin: GPIO33
i2s_bclk_pin: GPIO19
microphone:
- platform: i2s_audio
id: echo_microphone
i2s_din_pin: GPIO23
adc_type: external
pdm: true
speaker:
- platform: i2s_audio
id: echo_speaker
i2s_dout_pin: GPIO22
dac_type: external
# mode: mono
voice_assistant:
id: va
microphone: echo_microphone
speaker: echo_speaker
noise_suppression_level: 2
auto_gain: 31dBFS
volume_multiplier: 2.0
vad_threshold: 3
on_wake_word_detected:
- microphone.stop_capture:
- wait_until:
not:
microphone.is_capturing:
- lambda: id(echo_speaker).play(id(ok_sound), sizeof(id(ok_sound)));
on_listening:
- light.turn_on:
id: led
blue: 100%
red: 0%
green: 0%
effect: "Slow Pulse"
on_stt_vad_end:
- light.turn_on:
id: led
blue: 100%
red: 0%
green: 0%
effect: "Fast Pulse"
on_tts_start:
- light.turn_on:
id: led
blue: 100%
red: 0%
green: 0%
brightness: 100%
effect: none
on_end:
- delay: 100ms
- voice_assistant.stop:
- wait_until:
not:
voice_assistant.is_running:
- wait_until:
not:
switch.is_on: timer_ringing
- if:
condition:
lambda: return id(wake_word_engine_location).state == "On device";
then:
- micro_wake_word.start:
- script.execute: reset_led
else:
- voice_assistant.start_continuous:
- script.execute: reset_led
on_error:
- light.turn_on:
id: led
red: 100%
green: 0%
blue: 0%
brightness: 100%
effect: none
- delay: 2s
- script.execute: reset_led
on_client_connected:
- delay: 2s # Give the api server time to settle
- if:
condition:
lambda: return id(wake_word_engine_location).state == "On device";
then:
- micro_wake_word.start:
else:
- voice_assistant.start_continuous:
- script.execute: reset_led
on_client_disconnected:
- voice_assistant.stop:
- micro_wake_word.stop:
on_timer_finished:
- voice_assistant.stop:
- micro_wake_word.stop:
- switch.turn_on: timer_ringing
- wait_until:
not:
microphone.is_capturing:
- light.turn_on:
id: led
red: 0%
green: 100%
blue: 0%
brightness: 100%
effect: "Fast Pulse"
- while:
condition:
switch.is_on: timer_ringing
then:
- lambda: id(echo_speaker).play(id(timer_finished_wave_file), sizeof(id(timer_finished_wave_file)));
- delay: 1s
- wait_until:
not:
speaker.is_playing:
- light.turn_off: led
- switch.turn_off: timer_ringing
- if:
condition:
lambda: return id(wake_word_engine_location).state == "On device";
then:
- micro_wake_word.start:
- script.execute: reset_led
else:
- voice_assistant.start_continuous:
- script.execute: reset_led
binary_sensor:
# button does the following:
# short click - stop a timer
# if no timer then restart either microwakeword or voice assistant continuous
- platform: gpio
pin:
number: GPIO39
inverted: true
name: Button
disabled_by_default: true
entity_category: diagnostic
id: echo_button
on_multi_click:
- timing:
- ON for at least 50ms
- OFF for at least 50ms
then:
- if:
condition:
switch.is_on: timer_ringing
then:
- switch.turn_off: timer_ringing
else:
- if:
condition:
lambda: return id(wake_word_engine_location).state == "On device";
then:
- voice_assistant.stop
- micro_wake_word.stop:
- delay: 1s
- script.execute: reset_led
- script.wait: reset_led
- micro_wake_word.start:
else:
- if:
condition: voice_assistant.is_running
then:
- voice_assistant.stop:
- script.execute: reset_led
- voice_assistant.start_continuous:
- timing:
- ON for at least 10s
then:
- button.press: factory_reset_btn
light:
- platform: esp32_rmt_led_strip
id: led
name: None
disabled_by_default: true
entity_category: config
pin: GPIO27
default_transition_length: 0s
chipset: SK6812
num_leds: 1
rgb_order: grb
rmt_channel: 0
effects:
- pulse:
name: "Slow Pulse"
transition_length: 250ms
update_interval: 250ms
min_brightness: 50%
max_brightness: 100%
- pulse:
name: "Fast Pulse"
transition_length: 100ms
update_interval: 100ms
min_brightness: 50%
max_brightness: 100%
script:
- id: reset_led
then:
- if:
condition:
- lambda: return id(wake_word_engine_location).state == "On device";
- switch.is_on: use_listen_light
then:
- light.turn_on:
id: led
red: 100%
green: 89%
blue: 71%
brightness: 60%
effect: none
else:
- if:
condition:
- lambda: return id(wake_word_engine_location).state != "On device";
- switch.is_on: use_listen_light
then:
- light.turn_on:
id: led
red: 0%
green: 100%
blue: 100%
brightness: 60%
effect: none
else:
- light.turn_off: led
switch:
- platform: template
name: Use listen light
id: use_listen_light
optimistic: true
restore_mode: RESTORE_DEFAULT_ON
entity_category: config
on_turn_on:
- script.execute: reset_led
on_turn_off:
- script.execute: reset_led
- platform: template
id: timer_ringing
optimistic: true
internal: true
restore_mode: ALWAYS_OFF
on_turn_on:
- delay: 15min
- switch.turn_off: timer_ringing
select:
- platform: template
entity_category: config
name: Wake word engine location
id: wake_word_engine_location
optimistic: true
restore_value: true
options:
- In Home Assistant
- On device
initial_option: On device
on_value:
- if:
condition:
lambda: return x == "In Home Assistant";
then:
- micro_wake_word.stop
- delay: 500ms
- lambda: id(va).set_use_wake_word(true);
- voice_assistant.start_continuous:
- if:
condition:
lambda: return x == "On device";
then:
- lambda: id(va).set_use_wake_word(false);
- voice_assistant.stop
- delay: 500ms
- micro_wake_word.start
external_components:
- source: github://pr#5230
components:
- esp_adf
refresh: 0s
- source: github://jesserockz/esphome-components
components: [file]
refresh: 0s
esp_adf:
file:
- id: ok_sound
file: wakeword_detected3.raw
- id: timer_finished_wave_file
file: https://github.com/esphome/firmware/raw/main/voice-assistant/sounds/timer_finished.wav
micro_wake_word:
on_wake_word_detected:
- lambda: id(echo_speaker).play(id(ok_sound), sizeof(id(ok_sound)));
- voice_assistant.start:
wake_word: !lambda return wake_word;
vad:
models:
- model: ${micro_wake_word_model}
Edit: I now understand that micro_wake_word differs from open_wake_word.
More details here:
https://github.com/kahrendt/microWakeWord/issues/28#issuecomment-2236199393
Original Post:
I have successfully changed my on-device micro_wake_word to Hey Jarvis.
Has anyone managed to use a custom wake word?
I followed the directions at:
https://www.home-assistant.io/voice_control/create_wake_word/
I have a hey_eddie.tflite and hey_eddie.jason model in my Github repo.
I have successfully uploaded it to Home Assistant as a custom wake word, but using a custom on-device wake word eludes me. Has anyone managed it?
Thanks for your Code.
Now I get this error and don’t know where to get that file:
Could not find file ‘/config/esphome/wakeword_detected3.raw’. Please make sure it exists (full path: /config/esphome/wakeword_detected3.raw).
I share the file @Merc send to me.
Why is on_wake_word_detected repeated?
I am not 100% sure (I copied this code from other threads and adjusted it to make it work) but I think one is for normal voice assistant and the other if you run micro wake word on device.
I cannot tell you if this is double dipping or whether it would work the same way if one is removed.
But it definitely works like that.
I managed to get a custom wake word working. I used this training notebook as a guide. It took a bit of finessing to get it to work, but it resulted in a .tflite file that was significantly smaller, and it fixed the “Failed to allocate tensors for the streaming model” issue.
In the new esphome update, they have expanded media player support and simplified media interaction.
Looks like we need to rebuild the configuration files.
A new version of the code has already been released, but it lacks the wake-up sound. Added broadcast functionality that was introduced earlier this month.
I’m trying this out here, and am getting a message that reads:
INFO ESPHome 2025.2.1
INFO Reading configuration /config/esphome/m5-atom-echo.yaml...
INFO Updating https://github.com/esphome/esphome.git@pull/5230/head
INFO Updating https://github.com/kahrendt/esphome@mww-v2-external-library
Failed config
external_components: [source /config/esphome/m5-atom-echo.yaml:273]
- source: github://pr#5230
components:
- esp_adf
refresh: 0s
-
couldn't find remote ref mww-v2-external-library.
source:
type: git
url: https://github.com/kahrendt/esphome
ref: mww-v2-external-library
refresh: 0s
components:
- micro_wake_word
This refers to line 293, the source: github://pr#5230. Any assistance is appreciated.
external_components:
- source: github://pr#5230
components:
- esp_adf
refresh: 0s
- source:
type: git
url: https://github.com/kahrendt/esphome
ref: mww-v2-external-library
refresh: 0s
components: [ micro_wake_word ]
What does your config look like. I have no more than:
substitutions:
name: m5stack-atom-echo-80bfd4
friendly_name: M5Stack Atom Echo 80bfd4
packages:
m5stack.atom-echo-voice-assistant: github://esphome/firmware/wake-word-voice-assistant/m5stack-atom-echo.yaml
api:
encryption:
key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
And it installs. (I was going to say cleanly… but there are a bunch of warnings, so I won’t!)