Hello, so I’ve been trying to turn off my wakeword/ use no wakeword after Voice assistant replies and have had no luck. I’m not sure if I’m just not using the right commands or if it’s even possible at this current time. I’m running H.A. 2024.11.2 on a raspberry pi 4 and off loaded Whisper, Piper, and Ollama3.2 to my server. I am using wyoming for future plans to integrate more satellites around my house. Essentially i’m trying to have a continues conversation without using the ake word every time, I originally started by trying to make an automation that was similar to the tapaction to start the mic.
But I cant seem to to get that to work, I spent probably about 6 days now trying different things, chat gpt has been meh and been researching like crazy, I can’t find anything that seems to work. Here are a few of the “Solutions” That I have found but none seem to have the command to just restart the pipeline/ reactivate Voice assistant.
ww.home-assistant. io/ voice_control/ voice_remote_local_assistant/ - helpful till it wasn’t, is there a page just for commands? services? hidden services or actions? I found a few (turning off services n such) while scripting in configuration.yaml over the gui that seems to be restrictive for scripts and automations. I honestly don’t know how many different commands Ive tried and different approaches and the best I got was to shutting services off, like whisper or the mic and any documentation I find seems to be out pf date or for an esp32
Here’s one of the many different attempts I’ve made, any help would be greatly appreciated.
continuous_conversation:
alias: Continuous Conversation
description: Continuous conversation without requiring repeated wake words.
mode: restart
sequence:
- alias: Start Session
service: conversation.process
data:
text: "How can I assist you today?"
- alias: Continuous Response Loop
repeat:
until:
- condition: state
entity_id: input_boolean.continuous_conversation
state: "off"
sequence:
- wait_for_trigger:
- platform: event
event_type: intent_received
- platform: state
entity_id: input_boolean.continuous_conversation
to: "off"
- choose:
- conditions:
- condition: template
value_template: >
{{ trigger.event.event_type == 'intent_received' }}
sequence:
- service: conversation.process
data_template:
text: >
{{ trigger.event.data.text }}
- delay:
seconds: 1
- service: assist_pipeline.assist
data:
entity_id: assist_satellite.assist_microphone
pipeline_id: preferred
start_listening: false # Explicitly stop listening first
- delay:
seconds: 0.5 # Short pause to ensure proper reset
- service: assist_pipeline.assist
data:
entity_id: assist_satellite.assist_microphone
pipeline_id: preferred
start_listening: true # Restart listening
- conditions:
- condition: state
entity_id: input_boolean.continuous_conversation
state: "off"
sequence:
- service: conversation.process
data:
text: "Goodbye! Have a great day!"
It should work by starting the conversation Wakeword Asks question
H.A. replies
H.A. reactivates as if the wakeword was spoken again
I ask question
H.A. replies
H.A. reactivates, doesn’t hear anything as if false activation
Here is another attempt, I was debating on downloading openWakeWords source code and seeing if I could modify that some how to add in a function to “use_wakeword = false/true” or something…
The automation “Restart Voice Pipeline After Speaking” (automation.restart_voice_pipeline_after_speaking ) has an unknown action: assist.pipeline_run .
When I run this automation
- alias: Restart Voice Pipeline After Speaking
description: "Automatically restart the voice pipeline after the assistant finishes speaking."
trigger:
- platform: event
event_type: tts-end
event_data:
engine: tts.piper_2
condition:
- condition: state
entity_id: assist_satellite.assist_microphone
state: listening
action:
- service: assist.pipeline_run
data:
pipeline: "01JDFTE249KXXSKXAYK1VZ401B"
start_stage: "intent"
input: "Listening for your next request..."
Any ideas why I can’t use the events in script but I can fire them?
I started looking into pipeline.py in the source code (core/homeassistant/components/assist_pipeline/pipeline.py) and I’m taking an interest in lines 1404 - 1489. I feel like this is a good place to inject a follow-up process to repeat from the stt stage after the wake word has been confirmed.
I have modified pipeline.py, manifest n such so it’s named assist_pipeline_follow_up. I then added the folder to custom components to try and get H.A. to use that pipeline instead but I can’t get it to replace Assist_pipeline. Any ideas?
LOL Right when I post this I got it to work, Had to power off the raspberry pi to hard reset H.A.
Unfortunately the mod didn’t work, but that’s ok I think I’m on the right track and can test now without reinstalling H.A.
I’ve spent countless hours attempting to replace wyoming with a modified version leaving me to modify assist_satellite as well, I figured things where going good when I couldn’t get assist_microphone to activate, I was mislead. This just turned out to be what I was trying to avoid, The default integration of assist_pipeline with no way to edit or remove it, I figured I’d play it smart by finding a way to disable this hidden foe. After many attempts and following the instructions described within the H.A. main frame, I have come up empty handed. Not with knowledge, but with results. The commands of “assist_pipeline: false” in the realm of configuration.yaml does not work leaving me to once again start from the beginning of a new way to approach this hidden gem of continuous conversation.
I shall start by acquiring a version without such integration’s hopefully allowing me to have full control of my modifications. I don’t know but I may have already achieved continuous conversation without knowing, only time will give the answers.
I think I have something like this close to working. I’m still working out some kinks, but this is essentially continued conversation. I’m using micro_wake_word but I suspect something similar could work with wyoming. It reads the state of voice assistant and starts a timer any time it changes from “responding” to any other state (which is basically when it is done talking). If it responds again during before the timer is up, it resets the timer. If the time expires, it runs a script to stop listening and the wakeword goes live again. The next step is to work out some sort of “stop listening” command to make it stop before the timer is up if i want to.
captive_portal:
external_components:
- source:
type: git
url: https://github.com/esphome/voice-kit
ref: dev
components:
- aic3204
- audio_dac
- media_player
- micro_wake_word
- microphone
- nabu
- nabu_microphone
- voice_assistant
- voice_kit
refresh: 0s
- source: github://pr#7605
components: [ audio, i2s_audio, speaker]
refresh: 0s
- source:
type: git
url: https://github.com/formatBCE/Respeaker-Lite-ESPHome-integration
ref: main
components: [ respeaker_lite ]
refresh: 0s
i2s_audio:
- id: i2s_output
i2s_lrclk_pin:
number: GPIO7
allow_other_uses: true
i2s_bclk_pin:
number: GPIO8
allow_other_uses: true
i2s_mclk_pin:
number: GPIO9
allow_other_uses: true
- id: i2s_input
i2s_lrclk_pin:
number: GPIO7
allow_other_uses: true
i2s_bclk_pin:
number: GPIO8
allow_other_uses: true
i2s_mclk_pin:
number: GPIO9
allow_other_uses: true
i2c:
- id: bus_a
sda: GPIO5
scl: GPIO6
scan: true
respeaker_lite:
id: respeaker
i2c_id: bus_a
reset_pin: GPIO2
mute_state:
internal: true
id: mute_state
firmware_version:
icon: mdi:application-cog
name: XMOS firmware version
internal: false
id: firmware_version
microphone:
- platform: nabu_microphone
id: xiao_mic
adc_type: external
i2s_din_pin: GPIO44
pdm: false
sample_rate: 16000
bits_per_sample: 32bit
i2s_mode: secondary
i2s_audio_id : i2s_input
channel_0:
id: nabu_mic_mww
channel_1:
id: nabu_mic_va
speaker:
- platform: i2s_audio
id: xiao_speaker
dac_type: external
i2s_dout_pin: GPIO43
i2s_mode: secondary
sample_rate: 16000
bits_per_sample: 32bit
i2s_audio_id: i2s_output
channel: mono
media_player:
- platform: nabu
id: nabu_media_player
name: Media Player
internal: false
speaker: xiao_speaker
sample_rate: 16000
volume_increment: 0.05
volume_min: 0.4
volume_max: 0.85
files:
- id: timer_audio
file: https://github.com/esphome/firmware/raw/main/voice-assistant/sounds/timer_finished.wav
script:
- id: start_idle_timer
then:
- delay: 15s
- if:
condition:
lambda: 'return id(is_idle);'
then:
- voice_assistant.stop
- logger.log: "Voice Assistant stopped after 30 seconds of inactivity."
- id: reset_idle_timer
then:
- logger.log: "Voice Assistant activity detected. Resetting idle timer."
- globals.set:
id: is_idle
value: "false"
- script.stop: start_idle_timer
globals:
- id: is_idle
type: bool
initial_value: "false"
- id: previous_va_status
type: std::string
initial_value: ""
text_sensor:
- platform: homeassistant
id: va_status
entity_id: assist_satellite.${device_name}_assist_satellite
name: "VA Status"
on_value:
then:
- lambda: |-
// Check if the state changes to "responding"
if (x == "responding" && id(previous_va_status) != "responding") {
// If state changes to "responding", reset idle timer
id(reset_idle_timer).execute();
}
// Check if the state changes from "responding" to anything else
else if (id(previous_va_status) == "responding" && x != "responding") {
// If state changes from "responding" to something else, start idle timer
id(start_idle_timer).execute();
id(is_idle) = true; // Set global variable to true
}
// Update the previous state to the current state
id(previous_va_status) = x;
# just for debugging. Logs the state of VA Status every 5 seconds
interval:
- interval: 5s # Adjust this interval as needed (e.g., every 5 seconds)
then:
- lambda: |-
ESP_LOGD("main", "VA Status: %s", id(va_status).state.c_str());
micro_wake_word:
vad:
microphone: nabu_mic_mww
on_wake_word_detected:
- voice_assistant.start_continuous:
#wake_word: !lambda return wake_word;
#silence_detection: true
- light.turn_on:
id: led
red: 80%
green: 0%
blue: 80%
brightness: 60%
effect: fast pulse
#- homeassistant.service:
# service: tts.speak
# data:
# entity_id: tts.piper
# cache: 'true'
# media_player_entity_id: media_player.respeaker_media_player
#message: I'm here
models:
- model: hey_jarvis
voice_assistant:
microphone: nabu_mic_va
noise_suppression_level: 0
auto_gain: 0dBFS
volume_multiplier: 1
id: assist
media_player: nabu_media_player
#on_stt_end:
#then:
#- light.turn_off: led
#on_idle:
# then:
# - delay: 10s
# - voice_assistant.stop
#removed the on_error debugging because every time it heard a noise it would trigger an error and reset the wakeword, thus ruining continuous conversation.
#on_error:
# - micro_wake_word.start:
on_end:
then:
- light.turn_off: led
- wait_until:
not:
voice_assistant.is_running:
- micro_wake_word.start:
# timer functionality
on_timer_finished:
- switch.turn_on: timer_ringing
- light.turn_on:
id: led
effect: "Slow Pulse"
red: 80%
green: 0%
blue: 30%
brightness: 80%
- while:
condition:
switch.is_on: timer_ringing
then:
- nabu.play_local_media_file: timer_audio
- delay: 2s
- light.turn_off: led
- micro_wake_word.start:
switch:
- platform: template
id: timer_ringing
optimistic: true
internal: False
name: "Timer Ringing"
restore_mode: ALWAYS_OFF
light:
- platform: esp32_rmt_led_strip
id: led
name: "Led Light"
pin: GPIO1
default_transition_length: 0s
chipset: ws2812
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%
I’m rooting for both of you guys!
That’s one thing I would also want to have. I’ve stopped talking to it because I can’t stand having to say Hey Jarvis every phrase.
I hope you guys figure it out!