@@ -64,11 +64,6 @@ psram:
6464 mode : octal
6565 speed : 80MHz
6666
67- external_components :
68- - source : github://jesserockz/esphome-components
69- components : [file]
70- refresh : 0s
71-
7267api :
7368 on_client_connected :
7469 - script.execute : draw_display
@@ -231,11 +226,35 @@ speaker:
231226 id : box_speaker
232227 i2s_dout_pin : GPIO15
233228 dac_type : external
234- sample_rate : 16000
229+ sample_rate : 48000
235230 bits_per_sample : 16bit
236231 channel : left
237232 audio_dac : es8156_dac
238- buffer_duration : 1000ms # The timer finished audio needs to fit entirely in the buffer
233+ buffer_duration : 100ms
234+
235+ media_player :
236+ - platform : speaker
237+ name : Media Player
238+ id : speaker_media_player
239+ announcement_pipeline :
240+ speaker : box_speaker
241+ format : FLAC
242+ sample_rate : 48000
243+ num_channels : 1 # S3 Box only has one output channel
244+ files :
245+ - id : timer_finished_sound
246+ file : https://github.com/esphome/home-assistant-voice-pe/raw/dev/sounds/timer_finished.flac
247+ on_announcement :
248+ - if :
249+ condition :
250+ lambda : return id(voice_assistant_phase) == ${voice_assist_idle_phase_id};
251+ then :
252+ - script.execute : stop_voice_assistant
253+ - lambda : id(voice_assistant_phase) = ${voice_assist_muted_phase_id};
254+ - script.execute : draw_display
255+ on_idle :
256+ - script.execute : start_voice_assistant
257+ - script.execute : draw_display
239258
240259micro_wake_word :
241260 models :
@@ -247,7 +266,7 @@ micro_wake_word:
247266voice_assistant :
248267 id : va
249268 microphone : box_mic
250- speaker : box_speaker
269+ media_player : speaker_media_player
251270 noise_suppression_level : 2
252271 auto_gain : 31dBFS
253272 volume_multiplier : 2.0
@@ -272,10 +291,12 @@ voice_assistant:
272291 - text_sensor.template.publish :
273292 id : text_response
274293 state : !lambda return x;
275- on_tts_stream_start :
276294 - lambda : id(voice_assistant_phase) = ${voice_assist_replying_phase_id};
277295 - script.execute : draw_display
278- on_tts_stream_end :
296+ on_end :
297+ - wait_until :
298+ not :
299+ media_player.is_announcing :
279300 - if :
280301 condition :
281302 switch.is_off : mute
@@ -284,15 +305,12 @@ voice_assistant:
284305 else :
285306 - lambda : id(voice_assistant_phase) = ${voice_assist_muted_phase_id};
286307 - script.execute : draw_display
287- on_end :
288- - wait_until :
289- not :
290- voice_assistant.is_running :
291308 - if :
292309 condition :
293310 and :
294311 - switch.is_off : mute
295312 - lambda : return id(wake_word_engine_location).state == "On device";
313+ - lambda : return id(voice_assistant_phase) != ${voice_assist_timer_finished_phase_id};
296314 then :
297315 - micro_wake_word.start :
298316 on_error :
@@ -317,6 +335,7 @@ voice_assistant:
317335 - script.execute : draw_display
318336 on_client_disconnected :
319337 - script.execute : stop_voice_assistant
338+ - lambda : id(voice_assistant_phase) = ${voice_assist_not_ready_phase_id};
320339 - script.execute : draw_display
321340 on_timer_started :
322341 - script.execute : draw_display
@@ -327,24 +346,10 @@ voice_assistant:
327346 on_timer_tick :
328347 - script.execute : draw_display
329348 on_timer_finished :
330- - script.execute : stop_voice_assistant
331- - lambda : id(voice_assistant_phase) = ${voice_assist_timer_finished_phase_id};
332349 - switch.turn_on : timer_ringing
333- - script.execute : draw_display
334- - wait_until :
335- not :
336- microphone.is_capturing :
337- - while :
338- condition :
339- switch.is_on : timer_ringing
340- then :
341- - lambda : id(box_speaker).play(id(timer_finished_wave_file), sizeof(id(timer_finished_wave_file)));
342- - delay : 1s
343350 - wait_until :
344- not :
345- speaker.is_playing :
346- - switch.turn_off : timer_ringing
347- - script.execute : start_voice_assistant
351+ media_player.is_announcing :
352+ - lambda : id(voice_assistant_phase) = ${voice_assist_timer_finished_phase_id};
348353 - script.execute : draw_display
349354
350355script :
@@ -532,7 +537,6 @@ script:
532537 then :
533538 - voice_assistant.stop :
534539 - micro_wake_word.stop :
535- - lambda : id(voice_assistant_phase) = ${voice_assist_not_ready_phase_id};
536540
537541switch :
538542 - platform : gpio
@@ -582,13 +586,35 @@ switch:
582586 - micro_wake_word.stop
583587 - lambda : id(voice_assistant_phase) = ${voice_assist_muted_phase_id};
584588 - script.execute : draw_display
585-
586589 - platform : template
587590 id : timer_ringing
588591 optimistic : true
589592 internal : true
590593 restore_mode : ALWAYS_OFF
594+ on_turn_off :
595+ # Turn off the repeat mode and disable the pause between playlist items
596+ - lambda : |-
597+ id(speaker_media_player)
598+ ->make_call()
599+ .set_command(media_player::MediaPlayerCommand::MEDIA_PLAYER_COMMAND_REPEAT_OFF)
600+ .set_announcement(true)
601+ .perform();
602+ id(speaker_media_player)->set_playlist_delay_ms(speaker::AudioPipelineType::ANNOUNCEMENT, 0);
603+ # Stop playing the alarm
604+ - media_player.stop :
605+ announcement : true
591606 on_turn_on :
607+ # Turn on the repeat mode and pause for 1000 ms between playlist items/repeats
608+ - lambda : |-
609+ id(speaker_media_player)
610+ ->make_call()
611+ .set_command(media_player::MediaPlayerCommand::MEDIA_PLAYER_COMMAND_REPEAT_ONE)
612+ .set_announcement(true)
613+ .perform();
614+ id(speaker_media_player)->set_playlist_delay_ms(speaker::AudioPipelineType::ANNOUNCEMENT, 1000);
615+ - media_player.speaker.play_on_device_media_file :
616+ media_file : timer_finished_sound
617+ announcement : true
592618 - delay : 15min
593619 - switch.turn_off : timer_ringing
594620
@@ -765,10 +791,6 @@ color:
765791 - id : paused_timer_color
766792 hex : " 3b89e3"
767793
768- file :
769- - id : timer_finished_wave_file
770- file : https://github.com/esphome/wake-word-voice-assistants/raw/main/sounds/timer_finished.wav
771-
772794spi :
773795 - id : spi_bus
774796 clk_pin : 7
0 commit comments