Former SmartThings user, new HA user, first post here. Thanks so much for your help!
I’ve always found it frustrating that when listening to TV with a group of Sonos speakers, and I press the TV mute button, only the Sonos connected to the TV is muted while the rest of the group continues playing. So I’m trying to create an automation that detects when my Sonos Beam speaker (connected to my TV) is muted, and then mute the other Sonos speakers in the group. (This is not surround sound - just basic sonos speaker grouping.) I am immediately thwarted in creating such an automation because there is apparently no such “muted” attribute for the sonos speaker to detect a status change. I can see that there is an “Action” of “is_volume_muted”, but as far as this newb can tell, actions can be set but cannot be used to trigger an automation (?). So I can set the mute status, but I am struggling to create an automation that detects a change in this status to mute the other speakers. I’ve searched the hell out of these forums and the internets for a solution before posting here, to no avail. If someone could point me in the right direction, I would be very greatful.
so you can trigger off of the “is_volume_muted” attribute of the TV Sonos speaker to run the action “media_player.volume_mute” on the other desired Sonos speakers.
That should get you pointed in the right direction but if you need more “pointing” then post back here and I or someone else can give you further help.
Hi @finity thanks for the response. Let me state my challenge another way…. If I try to create a new automation from scratch, in the “When” section I select my Sonos speaker as the device, but in the following Trigger section, none of the available triggers are related to the speaker being muted.
I don’t use the UI. And when helping people to write automations it’s recommended to post the properly formatted yaml so we can easily edit the text instead of trying to describe what to do in the UI.
But I’ll try to help…
first I don’t think you can use a device trigger for this. Device stuff seems to be more limited. You will probably need to use an entity state trigger.
then in the entity state trigger there will be an attribute portion to fill in. that’s where you will put the “is_volume_muted” attribute.
then in the actions section is where you will also likely need to use an action call (previously it was called a service call) to tell the other speakers to mute using the above action call.
that’s a lot of words to describe (incompletely) what you need to do in the UI. Which is why it’s not recommended.
in yaml it would like like this:
alias: mute one other speaker
triggers:
- trigger: state
entity_id: media_player.your_beam_entity
attribute: is_volume_muted
to: 'true'
actions:
- action: media_player.volume_mute
entity_id: media_player.your_other_speaker
and if you want to mute more than one speaker:
alias: mute more than one other speakers
triggers:
- trigger: state
entity_id: media_player.your_beam_entity
attribute: is_volume_muted
to: 'true'
actions:
- action: media_player.volume_mute
entity_id:
- media_player.your_other_speaker
- media_player.your_some_other_speaker
- media_player.and_then_another_speaker
you might be able to copy that code snippet into the UI editor but you’ll need to correct the entity id’s with your own correct entities. Those are found in the developers tools states tab list.
We have progress, but not a working automation. I was able to create yaml entries that look identical to yours. It just doesn’t do anything - muting the TV has not impact on the other speakers. I think I saw another thread struggling to overcome similar issues, so I will research there.
I got it working. The UI adds quotes to to: “true”, but it should be to: true (without quotes). Removing the quotes fixes it. Here’s the full code from my automations.yaml.
My one remaining question is, how to efficiently enhance this to handle both mute & unmute triggers. Rather than creating two separate automations, can I remove the ‘to: true’ entirely (so that either state triggers) and then tell the other two speakers to mirror the is_volume_muted value of the TV Sonos?
Edited to add: ^ I’m not asking for help here, just thinking out loud about next steps. I appreciate your help so far and am happy with the current state.
Why are you using grouped speakers for TV audio playback? That typically would introduce enough of a delay for lipsync issues to become visible, which I could never live with.
Anyway, my personal very similar annoyance is that there is no way to force Sonos to always use the exact same volume level for all grouped speakers. I made a pretty spiffy blueprint to deal with this which monitors media players (speakers) for changed to group status, volume level and mute and enforces synchronization. Probably should finalize the last bits of documentation and release it…
Yes, I would be very interested in your automation. Syncing volumes was going to be my next project. Ideally as a % rather than an absolute value or in-kind increments.
I use grouped speakers to share TV sound in other nearby rooms, such as the Kitchen where the TV is line-of-sight, but speakers are far away. I’ve never had any serious delay issues with Sonos speakers in a group being out of sync.
As long as your network can keep up speakers should always be in sync with each other, but as soon as you start using groups (and not just a soundbar + surrounds + subs) there will always be a delay to ensure speakers stay in sync. While this is user configurable you cannot go lower than 75 ms, which would be 4-5 frames at 60 Hz or 2 frames at 24 Hz. For many that would be enough to annoy.
I’ve put the current version of my blueprint below. Suggested usage would be to copy and paste everything into a new file at /config/blueprints/automation/synchronize_group_volume.yaml, then reload automations and create a new automation from blueprint.
Not much in the way of documentation aside from the short explanations of the settings, but should be easy enough to figure out. Note that selected speakers are not forcibly synchronized against each other, rather they are synchronized against other members of their respective groups.
While synchronization with different scaling factors would certainly be possible, I don’t see how one could include it into a streamlined blueprint UI. What can be done in UI is just too limited right now and would either involve lots of duplicate UI elements (one set for each anticipated volume factor group) or require the user to enter values as raw YAML in an object field.
Easiest way to deal with it, assuming you always want the proportionality to be the same, would be to set appropriate volume limits on the speakers in the Sonos app. What this does is re-scale how big each volume step is. At work I lowered the volume level down to like 50% on our Play:5 speakers or else the usable volume range was not more than a handful of steps.
blueprint:
name: Synchronize Group Volume
author: Magnus Helin <[email protected]>
description: ...
domain: automation
homeassistant:
min_version: 2024.10.0
input:
media_players:
name: Media player(s)
description: Media player(s) to sync volume levels for (within respective groups).
selector:
entity:
filter:
domain: media_player
supported_features:
- media_player.MediaPlayerEntityFeature.GROUPING
- media_player.MediaPlayerEntityFeature.VOLUME_SET
multiple: true
sync_propagation:
name: Automatic progagation
description: Automatically propagate or prevent volume changes.
selector:
select:
mode: list
options:
- label: Any member's volume change propagates to all in group
value: "on"
- label: Prevent volume changes not originating from group leader
value: first
- label: Only sync on custom or manual trigger
value: "off"
default: "on"
sync_triggers:
name: Synchronization triggers
description: Custom synchronization triggers, typically a dashboard or physical button.
selector:
trigger:
default: []
sync_volume_mute:
name: Synchronize volume mute
description: Whether to synchronize volume mute, when off only synchronize volume level.
selector:
boolean:
default: true
mode: single
max_exceeded: silent
trace:
stored_traces: 10
trigger_variables:
media_players: !input media_players
sync_propagation: !input sync_propagation
sync_volume_mute: !input sync_volume_mute
triggers:
- trigger: state
entity_id: !input media_players
attribute: group_members
enabled: "{{ bool(sync_propagation, true) }}"
id: group_members
- trigger: state
entity_id: !input media_players
attribute: volume_level
enabled: "{{ bool(sync_propagation, true) }}"
id: volume_level
- trigger: state
entity_id: !input media_players
attribute: is_volume_muted
enabled: "{{ bool(sync_propagation, true) and sync_volume_mute }}"
id: is_volume_muted
- trigger: event
event_type: automation_reloaded
enabled: "{{ bool(sync_propagation, true) }}"
- triggers: !input sync_triggers
variables:
group_members: "{{ state_attr(trigger.entity_id, 'group_members') or [] }}"
origin: "{{ trigger.entity_id if bool(sync_propagation, false) else group_members | first }}"
conditions:
- or:
- "{{ trigger.platform is none or trigger.idx | int >= 3 }}"
- "{{ trigger.id == 'group_members' and trigger.entity_id == group_members | first }}"
- "{{ group_members | reject('is_state_attr', trigger.id, state_attr(origin, trigger.id)) | list | count > 0 }}"
actions:
- if: "{{ trigger.idx | int < 3 }}"
then:
- variables:
volume_level: "{{ state_attr(origin, 'volume_level') }}"
is_volume_muted: "{{ state_attr(origin, 'is_volume_muted') }}"
- if: "{{ trigger.id in ['volume_level', 'group_members'] }}"
then:
- action: media_player.volume_set
data:
entity_id: "{{ group_members | reject('is_state_attr', 'volume_level', volume_level) | list }}"
volume_level: "{{ volume_level }}"
- if: "{{ trigger.id in ['is_volume_muted', 'group_members'] }}"
then:
- action: media_player.volume_mute
data:
entity_id: "{{ group_members | reject('is_state_attr', 'is_volume_muted', is_volume_muted) | list }}"
is_volume_muted: "{{ is_volume_muted }}"
enabled: "{{ sync_volume_mute }}"
else:
- repeat:
for_each: "{{ media_players | map('state_attr', 'group_members') | map('first') | unique | list }}"
sequence:
- variables:
group_members: "{{ state_attr(repeat.item, 'group_members') }}"
volume_level: "{{ state_attr(repeat.item, 'volume_level') }}"
is_volume_muted: "{{ state_attr(repeat.item, 'is_volume_muted') }}"
- action: media_player.volume_set
data:
entity_id: "{{ group_members | reject('is_state_attr', 'volume_level', volume_level) | list }}"
volume_level: "{{ volume_level }}"
- action: media_player.volume_mute
data:
entity_id: "{{ group_members | reject('is_state_attr', 'is_volume_muted', is_volume_muted) | list }}"
is_volume_muted: "{{ is_volume_muted }}"
enabled: "{{ sync_volume_mute }}"