When enabling scenes/scripts via Google Assistant on my Sonos speakers I wanted to respond using the same device that I talk to. There’s already amazing script by @TheFes but I couldn’t make it to work with Sonos.
The trick I’m using is to:
- Run script that reads the volume levels of all the speakers, save it to
input_number
variables - Increase the volume of the current speaker by 1% via Google Assistant action
- Run script that compares current volume levels with ones saved in step 1, save last active speaker id as
input_select
variable - Do whatever I need with the above information
It’s not as extensible as the solution mentioned above, but it works for me and I wanted to share it with the community. For the sake of clarity I only include 2 of my speakers, but it works for much bigger number.
Home Assistant configuration
First I need to define input variables in configuration.yaml
input_select:
last_active_speaker:
name: "Last active speaker"
options:
- media_player.salon_speakers
- media_player.sonos_sypialnia
input_number:
volume_salon_speakers:
name: "Volume of Salon Speakers"
initial: 0
min: 0
max: 100
volume_sonos_sypialnia:
name: "Volume of Sypialnia"
initial: 0
min: 0
max: 100
Then I create a script (in my case called debug_script
) that will be the first step in my Google Home routine:
debug_script:
alias: Get Current Speaker Volumes
sequence:
- variables:
volume_current_salon_speakers:
"{{ state_attr('media_player.salon_speakers',
'volume_level') }}"
volume_current_sonos_sypialnia:
"{{ state_attr('media_player.sonos_sypialnia',
'volume_level') }}"
- service: input_number.set_value
target:
entity_id: input_number.volume_salon_speakers
data:
value: "{{volume_current_salon_speakers}}"
- service: input_number.set_value
target:
entity_id: input_number.volume_sonos_sypialnia
data:
value: "{{volume_current_sonos_sypialnia}}"
Another script is going to be called as 3rd step of the routine. In this one I need to iterate through the devices and compare their current volume level with the one saved in the corresponding input variable. In the last step I use the input_select.last_active_speaker
to trigger TTS.
debug_script_2:
alias: Determine Which Speaker Was Used
icon: mdi:debug-step-into
mode: single
sequence:
- variables:
volume_current_salon_speakers: "{{ state_attr('media_player.salon_speakers', 'volume_level') }}"
volume_current_sonos_sypialnia: "{{ state_attr('media_player.sonos_sypialnia', 'volume_level') }}"
volume_previous_salon_speakers: "{{ states('input_number.volume_salon_speakers') | float }}"
volume_previous_sonos_sypialnia: "{{ states('input_number.volume_sonos_sypialnia') | float }}"
target: >
{% if volume_previous_salon_speakers != volume_current_salon_speakers %}
media_player.salon_speakers
{% elif volume_previous_sonos_sypialnia != volume_current_sonos_sypialnia %}
media_player.sonos_sypialnia
{% endif %}
- service: logbook.log
data:
name: "Target speaker from template"
message: "{{ target }}"
- service: input_text.set_value
target:
entity_id: input_text.last_active_speaker
data:
value: "{{ target }}"
- service: tts.cloud_say
data:
cache: false
entity_id: "{{ target }}"
message: Test
Google Home Routine
In the Google Home I create a new routine - in this case one called Debug
for troubleshooting purposes. Its steps are:
- Enable
debug_script
scene - Change volume by 1%
- Enable
debug_script_2
scene - Change back volume by 1%
It seems to work pretty well, let me know what you think!