Sonos group volume button

Hello,

I am using the mini media player which has a feature that allows me to sync the volume with all speakers that are in the same group. This works however I do not like using the volume slider. I’m wanting to instead have a volume + and volume - button that controls the volume on only speakers in the group. I’m not concerned with having the volume be ‘synced’ or exactly the same on all speakers but rather just increase or decrease speakers in the group from whatever their current level is.

Creating the button to increase and decrease the volume on one speaker was no problem. I also understand I can use the Universal Media Player integration, the problem with the Universal method is that this setup would be static. My speaker groups change often so I need this functionality to be dynamic.

Any help with this is greatly appreciated. I thought template at first but haven’t been able to find any similar examples that I could use myself. I also thought maybe automation but not sure how to have the action only apply to the speakers in the group.

Not sure if this fits what you need. The way I did a sort of control of groups is by having a hidden card that only shows up when any sonos is playing. Then I can see multiple sonos and control the volume individually. They will also show if the the sonos are not group. It is like a consolidated card.

type: entity-filter
entities:
  - media_player.kitchen
  - media_player.move
  - media_player.patio_dining
  - media_player.living_room
  - media_player.move_2
group: false
state_filter:
  - playing
card:
  title: SONOS GROUP
  state_color: true
  show_header_toggle: false
  icon: 'mdi:cast-audio'
show_empty: false

Hi reyrios! Thanks for the replay. I’m actually doing something very similar in my setup currently. My goal is to get rid of the volume slider as the means to control volume and instead use a button. My issue with the slider is that it’s difficult to make very small adjustments.

Here is a pic with the buttons I have in mind. Currently they only control one speaker. I’m trying to figure out how to get the buttons to control the speakers in the same group as well.

image

I’ve created a automation and script to do this

as soon the buttons are pressed I call the script and all grouped speakers will get the same volume

Automation

- id: '1614106691093'
  alias: 'Sonos: Lautstärke anpassen'
  description: ''
  trigger:
  - platform: event
    event_type: call_service
    event_data:
      domain: media_player
      service: volume_up
  - platform: event
    event_type: call_service
    event_data:
      domain: media_player
      service: volume_down
  condition:
  - condition: state
    entity_id: input_boolean.sync_volume
    state: 'on'
  action:
  - service: script.sonos_set_volume
    data:
      sonos_id: '{{ trigger.event.data.service_data.entity_id | regex_replace(find="media_player.",
        replace="") }}'
  mode: single

Script

sonos_set_volume:
  alias: 'Sonos: Set Volume'
  fields:
    sonos_id:
      description: ID von sonos
      example: ids
  sequence:
  - condition: template
    value_template: '{{ states.media_player[sonos_id].attributes["sonos_group"] |
      regex_replace(find="''",replace="") | regex_replace(find="[\[]", replace="")|
      regex_replace(find="[\]]", replace="") !=  states.media_player[sonos_id].entity_id  }}'
  - delay:
      hours: 0
      minutes: 0
      seconds: 0
      milliseconds: 200
  - service: media_player.volume_set
    data:
      entity_id: '{{ states.media_player[sonos_id].attributes["sonos_group"]  }}'
      volume_level: '{{ states.media_player[sonos_id].attributes["volume_level"]  }}'
  mode: single
1 Like

Perfect! This works exactly as I wanted it. Thank you very much deluxestyle!

I get the following error.

Stopped because an error was encountered at May 27, 2021, 2:29:41 PM (runtime: 0.02 seconds)

Error rendering data template: UndefinedError: 'dict object' has no attribute 'event'

Is there a way to test this line in the development tools?

  sonos_id: >-
    {{ trigger.event.data.service_data.entity_id |
    regex_replace(find="media_player.", replace="") }}

not sure. but the automation will work only if it is triggered by an event as I’m using the trigger event to get the correspoind mediaplayer

Hi,

i am quiet new to home assistant so pls be patient :slight_smile:
I am looking for the solution you discussed in this topic.
When i copied the code for automation i get the error “message malformed expected dictionary”. I
For the script it says: Message malformed: extra keys not allowed @ data[‘sonos_set_volume’]

Do you have any clue?
Thank you for your help

can you show your code?

i just copied your code to my home assistant :confused:

could be a problem with the indentation, there it would be good, if you can post your code (please formated)

If you allow the automation to call the script with the entire entity_id (instead of stripping away the media_player domain to leave only the entity’s object_id) the templates can be simplified.

Automation:

- id: '1614106691093'
  alias: 'Sonos: Lautstärke anpassen'
  description: ''
  trigger:
  - platform: event
    event_type: call_service
    event_data:
      domain: media_player
      service: volume_up
  - platform: event
    event_type: call_service
    event_data:
      domain: media_player
      service: volume_down
  condition:
  - condition: state
    entity_id: input_boolean.sync_volume
    state: 'on'
  action:
  - service: script.sonos_set_volume
    data:
      sonos_id: '{{ trigger.event.data.service_data.entity_id }}'
  mode: single

Script

sonos_set_volume:
  alias: 'Sonos: Set Volume'
  fields:
    sonos_id:
      description: ID von sonos
      example: ids
  sequence:
  - condition: template
    value_template: "{{ state_attr(sonos_id, 'sonos_group') | count > 1 }}"
  - delay:
      milliseconds: 200
  - service: media_player.volume_set
    target:
      entity_id: "{{ state_attr(sonos_id, 'sonos_group') }}"
    data:
      volume_level: "{{ state_attr(sonos_id, 'volume_level') }}"
  mode: single
1 Like

I managed to get rid of the errors :slight_smile:
how do i link the script to the buttons? and how does the script know what button is up and what is down?

the automation knows it based on the trigger. and the automation is calling then the script

Now it works :slight_smile: thank you all

You can do that all with this simple mini media player card with “sync volume”.

type: custom:mini-media-player
hide:
  power: true
speaker_group:
  platform: sonos
  show_group_count: true
  sync_volume: true
  entities:
    - entity_id: media_player.sonos_roam_2
      name: Sonos Badezimmer
    - entity_id: media_player.sonos_roam
      name: Sonos Wohnzimmer
entities:
  - type: custom:mini-media-player
    entity: media_player.multiroom_player
    group: true
    source: icon
    artwork: cover
    info: short
    hide:
      volume: true
      power: true
  - type: custom:mini-media-player
    entity: media_player.sonos_roam_2
    group: true
    hide:
      controls: true
  - type: custom:mini-media-player
    entity: media_player.sonos_roam
    group: true
    hide:
      controls: true
entity: media_player.sonos_roam
volume_stateless: false

image

The volumes of both speakers can be controlled with just one volume control.

1 Like

I have three speakers and I cant get them to group together. Can you look and tell me what I have wrong? Is the multiroom player a helper? I tried with and without that option.

type: custom:mini-media-player
hide:
  power: true
speaker_group:
  platform: sonos
  show_group_count: true
  sync_volume: true
  entities:
    - entity_id: media_player.move
      name: kitchen
    - entity_id: media_player.playroom
      name: gameroom
    - entity_id: media_player.living_room_sonos
      name: living room
entities:
  - type: custom:mini-media-player
    entity: media_player.mulitroom_player
    group: true
    source: icon
    artwork: cover
    info: short
    hide:
      volume: true
      power: true
  - type: custom:mini-media-player
    entity: media_player.move
    group: true
    hide:
      controls: true
  - type: custom:mini-media-player
    entity: media_player.playroon
    group: true
    hide:
      controls: true
  - type: custom:mini-media-player
    entity: media_player.living_room_sonos
    group: true
    hide:
      controls: true
entity: media_player.move
volume_stateless: false
group: false

Seems mini media player needs an update after 2022.5

Hi, I’m getting this error, does anyone know if this is still working?

Logger: homeassistant.helpers.template
Source: helpers/template.py:230
First occurred: May 8, 2023 at 11:54:34 PM (1 occurrences)
Last logged: May 8, 2023 at 11:54:34 PM

Template variable error: ‘dict object’ has no attribute ‘event’ when rendering ‘{{ trigger.event.data.service_data.entity_id }}’