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.
Thanks, finity! I had to do some troubleshooting, but your template helped get me started in the right direction. The main issue was that the condition template was never triggering. I added a default action to message me the value of the template, and saw that trigger.to_state.state was returning a value of “playing” (the state of the speaker, rather than the mute attribute of interest). I also think your true/false logic was backwards in the first condition, and the second condition was changing the volume level rather than the mute state. All together, I got the following working:
I was hoping to clean this up even further by replacing the multiple conditions with a single template to set the mute state of the other 2 speakers to match the mute state of the master TV speaker, regardless of its state. Something like the following. But so far I can’t quite get it to work - HA complains about my yaml syntax and won’t let me save this. I also tried using the “template” syntax here, but still got syntax errors.
Thanks Mayhem_SWE! I can’t quite figure out how to implement this either. What I was going for is if the main TV volume changed from (for example) 28 to 35, then the other speaker volumes would need to be changed by *35/28. This would require capturing the volume both before and after the trigger. So far I haven’t seen a good way to capture the “before” volume.
I’m fairly sure I tried that, but I can check again. Everything I tried gave me the new volume. Which kinda makes sense - it can’t check the volume until the trigger is fired, and the trigger is the volume changing.
Edit: trigger.from_state.attributes.volume_level gives me the last volume value in the transition as I was changing the volume. So for example, if I change the volume from 15 to 20 by pressing volume+ on the remote 5 times, the from_state will return 19.