Hello, is there some way how to set volume to predefined together with TTS command (tts.google_translate_say) and after is done turn it to previous level?
The data_template instead of data advice does not apply if you are on the current version.
what are you talking about?
The answer in the link you pasted:
Try it like this, with data_template: instead of data:…
This only applies to home assistant versions prior to 0.115.
So there is no chance to get the volume_set working actually?
Sure there is. I use a script for that. I will post it later. Here you go:
scripts.yaml:
announce_downstairs:
alias: 'Announce downstairs'
sequence:
- service: media_player.volume_mute # The first part gets rid of the default Google Home bloop-bloop sound. First mutes the speaker...
data:
entity_id: media_player.googlehome_downstairs
is_volume_muted: true
- service: media_player.play_media # then plays a random 1 second silent track ...
data:
entity_id: media_player.googlehome_downstairs
media_content_type: music
media_content_id: "{{ states('input_text.base_url') + '/local/audio/1sec.mp3' }}"
- delay:
seconds: 1
- service: media_player.volume_set # then sets the desired volume ...
data:
entity_id: media_player.googlehome_downstairs
volume_level: >-
{% if now().hour > 18 or now().hour < 7 %} 0.35
{% else %} 0.65
{% endif %}
- service: media_player.volume_mute # only then unmutes, so you don't hear the volume changing sounds
data:
entity_id: media_player.googlehome_downstairs
is_volume_muted: false
- service: media_player.play_media # then it plays a nice ding-dong sound
data:
entity_id: media_player.googlehome_downstairs
media_content_type: music
media_content_id: "{{ states('input_text.base_url') + '/local/audio/announcement.mp3' }}"
# My base_url is contained in an input_text, so that I could put it in secrets.yaml. You can just put the external url to your HA frontend here. NB an internal url won't work in my experience.
- delay:
seconds: 2
# milliseconds: 800
- service: tts.google_say # then finally here's your TTS message :-)
data:
entity_id: media_player.googlehome_downstairs
message: "{{my_message}}"
Calling the script from an automation:
- service: script.announce_downstairs
data:
my_message: "Have a great day"
@Emphyrio wow must try today. May I ask you for your nice ding dang? I have only Scarry dong dang kong. Thank you
I see you have volume-setting capabilities in your script, but I don’t see anything that saves the previous volume setting and restores it after the announcement. Have you figured out a way to acquire the current volume setting before you make changes? Restoring should be pretty simple after that.
I will try to figure that out for you.
Here’s an adaptation that also restores the volume to its original volume, after the announcement.
announce_downstairs:
alias: 'Announce downstairs'
sequence:
- service: media_player.volume_mute # The first part gets rid of the default Google Home bloop-bloop sound. First mutes the speaker...
data:
entity_id: media_player.googlehome_downstairs
is_volume_muted: true
- service: media_player.play_media # then plays a random 1 second silent track ...
data:
entity_id: media_player.googlehome_downstairs
media_content_type: music
media_content_id: "{{ states('input_text.base_url') + '/local/audio/1sec.mp3' }}"
- delay:
seconds: 1
- service: input_number.set_value # store the current volume level (should be after playing 1sec because only then the volume_level attribute is available)
data:
entity_id: input_number.current_volume
value: "{{ state_attr('media_player.googlehome_downstairs','volume_level') }}"
- service: media_player.volume_set # then sets the desired volume for the announcement ...
data:
entity_id: media_player.googlehome_downstairs
volume_level: >-
{% if now().hour > 18 or now().hour < 7 %} 0.35
{% else %} 0.65
{% endif %}
- service: media_player.volume_mute # only then unmutes, so you don't hear the volume changing sounds
data:
entity_id: media_player.googlehome_downstairs
is_volume_muted: false
- service: media_player.play_media # then it plays a nice ding-dong sound
data:
entity_id: media_player.googlehome_downstairs
media_content_type: music
media_content_id: "{{ states('input_text.base_url') + '/local/audio/announcement.mp3' }}"
# My base_url is contained in an input_text, so that I could put it in secrets.yaml. You can just put the external url to your HA frontend here. NB an internal url won't work in my experience.
- delay:
seconds: 2
# milliseconds: 800
- service: tts.google_say # then finally here's your TTS message :-)
data:
entity_id: media_player.googlehome_downstairs
message: "{{my_message}}"
- delay: # Set this delay for the maximum length of your announcement messages
seconds: 4
- service: media_player.volume_mute # Again, muting to prevent volume changing sounds
data:
entity_id: media_player.googlehome_downstairs
is_volume_muted: true
- service: media_player.volume_set
data:
entity_id: media_player.googlehome_downstairs
volume_level: "{{ states('input_number.current_volume') }}"
- delay:
seconds: 1
- service: media_player.volume_mute
data:
entity_id: media_player.googlehome_downstairs
is_volume_muted: false
This requires an input_number to be defined in configuration.yaml:
input_number:
current_volume:
name: 'Current volume'
min: 0
max: 1
Although in the latest HA versions you might be able to use an on-the-fly variable, but I haven’t used that before so there’s that.
I took @Emphyrio’s example above and parameterized it to make it easier to use generically - i.e. use any media_player
entity (or several!), use a specificed volume, etc.
First, a setup script:
# Turns on Google smart speaker(s), bypassing the Google chime by muting
#
# Args:
# announcement_volume (float): speaker volume_level for announcement (0 <= x <= 1)
# player_id (entity or list of entities): media_player(s) on which to play announcement
#
# Usage Example:
# - service: script.google_speaker_announcement_startup
# data:
# announcement_volume: "{{ states('input_number.volume_announcement') }}"
# player_id: media_player.office_display, media_player.family_room_speaker
google_speaker_announcement_startup:
alias: 'GoogleSpeakerAnnouncementStartup'
sequence:
- service: media_player.volume_mute
data:
entity_id: "{{ player_id }}"
is_volume_muted: true
- delay:
milliseconds: 200
- service: media_player.play_media
data:
entity_id: "{{ player_id }}"
media_content_type: music
media_content_id: "{{ states('input_text.home_assistant_url_internal') + '/local/sounds/silence-1sec.mp3' }}"
- delay:
seconds: 1
- service: media_player.volume_set
data_template:
entity_id: "{{ player_id }}"
volume_level: "{{ announcement_volume }}"
- delay:
seconds: 2
- service: media_player.volume_mute
data:
entity_id: "{{ player_id }}"
is_volume_muted: false
- service: media_player.play_media
data:
entity_id: "{{ player_id }}"
media_content_type: music
media_content_id: "{{ states('input_text.home_assistant_url_internal') + '/local/sounds/announcement_chime.mp3' }}"
- delay:
seconds: 3
Note that I’ve found this eliminates the Google chime most of the time, but not all of the time. I played with lots of variations of this sequence in terms of order, timing, etc., and haven’t gotten it to be silent 100% of the time. But this one is close…
Then there’s a shutdown script:
# Turns off Google smart speaker(s), restoring volume to default
#
# Args:
# player_id (entity or list of entities): media_player(s) to shut down
#
# Usage Example:
# - service: script.google_speaker_announcement_shutdown
# data:
# player_id: media_player.office_display, media_player.family_room_speaker
google_speaker_announcement_shutdown:
alias: 'GoogleSpeakerAnnouncementShutdown'
sequence:
- service: media_player.volume_set
data_template:
entity_id: "{{ player_id }}"
volume_level: "{{ states('input_number.volume_smart_speaker_default') }}"
- delay:
seconds: 1
- service: media_player.turn_off
data:
entity_id: "{{ player_id }}"
And finally, there’s the announcement itself:
# Plays an TTS announcement on Google smart speaker(s) with specificed volume
#
# Args:
# announcement_length (int): number of seconds to delay after starting announcement
# before assuming it has completed
# announcement_message (string): message used as input to text-to-speech
# announcement_volume (float): speaker volume_level for announcement (0 <= x <= 1)
# player_id (entity or list of entities): media_player(s) on which to play announcement
#
# Usage Example:
# - service: script.announce
# data:
# announcement_length: 10
# announcement_message: "This is a test. This is only a test of the Home Asssistant alert system."
# announcement_volume: "{{ states('input_number.volume_announcement') }}"
# player_id: media_player.office_display, media_player.family_room_speaker
announcement:
alias: 'Announcement'
sequence:
- service: script.google_speaker_announcement_startup
data:
player_id: "{{ player_id }}"
announcement_volume: "{{ announcement_volume}}"
- service: tts.cloud_say
data:
entity_id: "{{ player_id }}"
message: "{{ announcement_message }}"
- delay:
seconds: "{{ announcement_length }}"
- service: script.google_speaker_announcement_shutdown
data:
player_id: "{{ player_id }}"
So to use this, you just call the script.announce
from an automation or other script, as shown in the example above.
Also, to address @Jiran’s original question (how to restore the volume to its previous level after the announcement), I tried this:
announcement_with_volume_restore:
alias: 'AnnouncementWithVolumeRestore'
variables:
previous_volume: >
"{% if is_state('media_player.office_display', 'playing')
or is_state('media_player.office_display', 'on')
or is_state('media_player.office_display', 'paused')
%}
{{ state_attr('media_player.office_display', 'volume_level') | float | round(2) }}
{% else %}
{{ states('input_number.volume_smart_speaker_default') | float | round(2) }}
{% endif %}"
sequence:
- service: script.google_speaker_announcement_startup
data:
player_id: "{{ player_id }}"
announcement_volume: "{{ announcement_volume}}"
- service: tts.cloud_say
data:
entity_id: "{{ player_id }}"
message: "{{ announcement_message }}"
- delay:
seconds: 10
- service: media_player.volume_set
data_template:
entity_id: "{{ player_id }}"
volume_level: "{{ previous_volume }}" # doesn't seem to be a float, and casting as float makes it 0
- service: media_player.turn_off
data:
entity_id: "{{ player_id }}"
That example has the entity for the previous volume hardcoded to a specific media player since I was experimenting. If the device is off (not playing), the above works by restoring the value of volume_smart_speaker_default
to the device after the announcement.
In the case of the device being originally in the playing
state, the value of previous_volume is saved and able to be read back with a second TTS call. However, when trying to restore the volume (line with comment above), it complains about it not being a float. If I cast it as a float (add | float
), then the volume is restored as a value of zero.
I’ve tried a bunch of stuff to get this part to work, but haven’t been successful. Other ideas welcome!
My adapted script works for me to restore the volume. It doesn’t for you?
Apparently I can’t read.
I read your post above as setting up a static input_number
to have as the restored value and missed that you were calling the service to set it within the script. My bad.
That works as long as you don’t have multiple announcements going at the same time… which I’m guessing for most people would be rare.
Any thoughts on how to do it without adding an extra input_number
to keep things simpler?
Oh how to decide which one is better?
Yes, use a variable
Hi all!
Fantastic post and love the solution by you, @Emphyrio. I also tried to implement a minimal setup as a script, however, when running it, I do script/automation that calls it does not turn back the volume. Here is what I implemented:
broadcast_msg_single_device:
alias: 'Broadcast a message on a single device'
sequence:
- service: tts.google_say
data_template:
entity_id: "{{ device_name }}"
message: "{{ msg }}"
language: "{{ lang }}"
- delay:
seconds: 2
- service: input_number.set_value
data_template:
entity_id: input_number.current_volume
value: "{{ state_attr( device_name ,'volume_level') }}"
- service: media_player.volume_set
data_template:
entity_id: "{{ device_name }}"
volume_level: 0.7
- service: tts.google_say
data_template:
entity_id: "{{ device_name }}"
message: "{{ msg }}"
language: "{{ lang }}"
- delay:
seconds: 2
- service: media_player.volume_set
data_template:
entity_id: "{{ device_name }}"
volume_level: "{{ states(input_number.current_volume) }}"
- service: tts.google_say
data_template:
entity_id: "{{ device_name }}"
message: "{{ msg }}"
language: "{{ lang }}"
It still plays the second message but not the third anymore. When commenting out the following command, then also the 3rd message is played:
- service: media_player.volume_set
data_template:
entity_id: "{{ device_name }}"
volume_level: "{{ states(input_number.current_volume) }}"
Would appreciate if you had any idea how to solve this. Probably some beginner’s issue . Thank you!