ZHA - IKEA Symfonisk sound remote GEN2 (media control, dot buttons, volume up/down hold)

After getting the gen2 sound remote this week, I played around with the blueprints from Atlantis_one (ZHA - Ikea Symfonisk sound controller GEN2 (the square one) with dot-button support for new firmware), James Crook, and Shawsky to try and get the most out of my automations.

Taking code from all three, I created this ZHA blueprint with the following features:

  • Configurable volume step amount when doing single tap volume control
  • Long press volume control support
  • Dot and double dot button support (single tap, double tap, and long press)

Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.

blueprint:
  name: ZHA - IKEA Symfonisk sound remote GEN2
  description: Media control and shortcut button support for the IKEA Symfonisk sound remote GEN2.
  domain: automation
  source_url: https://community.home-assistant.io/t/zha-ikea-symfonisk-sound-remote-gen2-media-control-dot-buttons-volume-up-down-hold/673094
  input:
    remote:
      name: Remote
      description: IKEA Symfonisk controller GEN2 to use
      selector:
        device:
          integration: zha
          manufacturer: IKEA of Sweden
          model: SYMFONISK sound remote gen2
          multiple: false
    media_player:
      name: Media Player
      description: The media player to control with this automation
      selector:
        entity:
          domain: media_player
          multiple: false
    volume_steps:
      name: Volume number of steps
      description: Controls the volume scale. The default of 25 is the same scale as the Sonos app.
      default: 25
      selector:
        number:
          min: 5
          max: 100
          step: 5
          unit_of_measurement: "Num"
          mode: slider
    single_dot_single_press:
      name: Single dot (Single press)
      description: Action to run on single dot press
      default: []
      selector:
        action: {}
    single_dot_double_press:
      name: Single dot (Double press)
      description: Action to run on single dot double press
      default: []
      selector:
        action: {}
    single_dot_long_press:
      name: Single dot (Long press)
      description: Action to run on single dot long press
      default: []
      selector:
        action: {}
    double_dot_single_press:
      name: Double dot (Single press)
      description: Action to run on double dot press
      default: []
      selector:
        action: {}
    double_dot_double_press:
      name: Double dot (Double press)
      description: Action to run on double dot double press
      default: []
      selector:
        action: {}
    double_dot_long_press:
      name: Double dot (Long press)
      description: Action to run on double dot long press
      default: []
      selector:
        action: {}
mode: single
max_exceeded: silent
trigger:
  - platform: event
    event_type: zha_event
    event_data:
      device_id: !input remote
action:
  - variables:
      command: "{{ trigger.event.data.command }}"
      cluster_id: "{{ trigger.event.data.cluster_id }}"
      endpoint_id: "{{ trigger.event.data.endpoint_id }}"
      args: "{{ trigger.event.data.args }}"
      player: !input media_player
      steps: !input volume_steps
      stepsize: "{{ 1.0 / steps }}"
  - choose:
      #Play Pause
      - conditions:
          - "{{ command == 'toggle' }}"
          - "{{ cluster_id == 6 }}"
          - "{{ endpoint_id == 1 }}"
        sequence:
          - service: media_player.media_play_pause
            target:
              entity_id: "{{ player }}"
      #Volume Up Press
      - conditions:
          - "{{ command == 'move_with_on_off' }}"
          - "{{ cluster_id == 8 }}"
          - "{{ endpoint_id == 1 }}"
          - "{{ trigger.event.data.params.move_mode == 0}}"
        sequence:
          - service: media_player.volume_set
            target:
              entity_id: "{{ player }}"
            data:
              volume_level: >-
                {% set volume = state_attr(player, "volume_level") + stepsize %}
                {{ 1.0 if volume > 1.0 else volume }}
      #Volume Up Hold
      - conditions:
          - "{{ command == 'move' }}"
          - "{{ cluster_id == 8 }}"
          - "{{ endpoint_id == 1 }}"
          - "{{ trigger.event.data.params.move_mode == 0}}"
        sequence:
          - service: media_player.volume_up
            target:
              entity_id: "{{ player }}"
      #Volume Down Press
      - conditions:
          - "{{ command == 'move_with_on_off' }}"
          - "{{ cluster_id == 8 }}"
          - "{{ endpoint_id == 1 }}"
          - "{{ trigger.event.data.params.move_mode == 1}}"
        sequence:
          - service: media_player.volume_set
            target:
              entity_id: "{{ player }}"
            data:
              volume_level: >-
                {% set volume = state_attr(player, "volume_level") - stepsize %}
                {{ 0.0 if volume < 0.0 else volume }}
      #Volume Down Hold
      - conditions:
          - "{{ command == 'move' }}"
          - "{{ cluster_id == 8 }}"
          - "{{ endpoint_id == 1 }}"
          - "{{ trigger.event.data.params.move_mode == 1 }}"
        sequence:
          - service: media_player.volume_down
            target:
              entity_id: "{{ player }}"
      #Next Track
      - conditions:
          - "{{ command == 'step' }}"
          - "{{ cluster_id == 8 }}"
          - "{{ endpoint_id == 1 }}"
          - "{{ trigger.event.data.params.step_mode == 0 }}"
        sequence:
          - service: media_player.media_next_track
            target:
              entity_id: "{{ player }}"
      #Last Track
      - conditions:
          - "{{ command == 'step' }}"
          - "{{ cluster_id == 8 }}"
          - "{{ endpoint_id == 1 }}"
          - "{{ trigger.event.data.params.step_mode == 1 }}"
        sequence:
          - service: media_player.media_previous_track
            target:
              entity_id: "{{ player }}"
      #Single Dot Press
      - conditions:
          - "{{ command == 'short_release' }}"
          - "{{ endpoint_id == 2 }}"
        sequence: !input single_dot_single_press
      #Single Dot Double Press
      - conditions:
          - "{{ command == 'multi_press_complete' }}"
          - "{{ endpoint_id == 2 }}"
        sequence: !input single_dot_double_press
      #Single Dot Long Press
      - conditions:
          - "{{ command == 'long_press' }}"
          - "{{ endpoint_id == 2 }}"
        sequence: !input single_dot_long_press
      #Double Dot Press
      - conditions:
          - "{{ command == 'short_release' }}"
          - "{{ endpoint_id == 3 }}"
        sequence: !input double_dot_single_press
      #Double Dot Double Press
      - conditions:
          - "{{ command == 'multi_press_complete' }}"
          - "{{ endpoint_id == 3 }}"
        sequence: !input double_dot_double_press
      #Double Dot Long Press
      - conditions:
          - "{{ command == 'long_press' }}"
          - "{{ endpoint_id == 3 }}"
        sequence: !input double_dot_long_press

This is my first time coding anything in Home Assistant ( I have only used the UI up till now) so hopefully it works as expected!

Thanks,

Dan

3 Likes

Thank you, this was exactly what I was looking for.

But when I saw that you added support for press and hold the volume buttons,I wondered, would it also be possible to create support for press and hold the next and previous button so we can fast forward a song instead of skipping it?

That would make it the perfect Blueprint

Even when not possible, this is already a great improvement for my case.

This one works like a charm for me! I am successfully controlling my bluesound player in the bedroom and since I have a chromecast sound output connected to my bluesound player as well, I can also use it to control the volume when watching a movie.
But one thought struck me. It would be awesome if I somehow could program the play/pause button to go towards the chromecast when it is on but then to the bluesound player then the chromecast is off. Currently I programmed the single dot button for that but it is a bit counter-intuitive since I have the huge play/pause button on the thing. Does anyone have any ideas how I could go about doing that?

Ok to respond to my own question if anyone else needs this. This was easy to change, I just swapped out the default media player action in the blueprint for the toggle command to a customizable action that then would let me check if my Chromecast is on or not and play/pause the correct media player accordingly.

Here is my tweaked blueprint if anyone else is interested in this:

blueprint:
  name: ZHA - IKEA Symfonisk sound remote GEN2
  description: Media control and shortcut button support for the IKEA Symfonisk sound
    remote GEN2.
  domain: automation
  source_url: https://community.home-assistant.io/t/zha-ikea-symfonisk-sound-remote-gen2-media-control-dot-buttons-volume-up-down-hold/673094/4
  input:
    remote:
      name: Remote
      description: IKEA Symfonisk controller GEN2 to use
      selector:
        device:
          integration: zha
          manufacturer: IKEA of Sweden
          model: SYMFONISK sound remote gen2
          multiple: false
    media_player:
      name: Media Player
      description: The media player to control with this automation
      selector:
        entity:
          domain:
          - media_player
          multiple: false
    volume_steps:
      name: Volume number of steps
      description: Controls the volume scale. The default of 25 is the same scale
        as the Sonos app.
      default: 25
      selector:
        number:
          min: 5.0
          max: 100.0
          step: 5.0
          unit_of_measurement: Num
          mode: slider
    play_pause_press:
      name: Play pause
      description: Action to run on press of play/pause button
      default: []
      selector:
        action: {}          
    single_dot_single_press:
      name: Single dot (Single press)
      description: Action to run on single dot press
      default: []
      selector:
        action: {}
    single_dot_double_press:
      name: Single dot (Double press)
      description: Action to run on single dot double press
      default: []
      selector:
        action: {}
    single_dot_long_press:
      name: Single dot (Long press)
      description: Action to run on single dot long press
      default: []
      selector:
        action: {}
    double_dot_single_press:
      name: Double dot (Single press)
      description: Action to run on double dot press
      default: []
      selector:
        action: {}
    double_dot_double_press:
      name: Double dot (Double press)
      description: Action to run on double dot double press
      default: []
      selector:
        action: {}
    double_dot_long_press:
      name: Double dot (Long press)
      description: Action to run on double dot long press
      default: []
      selector:
        action: {}
mode: single
max_exceeded: silent
trigger:
- platform: event
  event_type: zha_event
  event_data:
    device_id: !input remote
action:
- variables:
    command: '{{ trigger.event.data.command }}'
    cluster_id: '{{ trigger.event.data.cluster_id }}'
    endpoint_id: '{{ trigger.event.data.endpoint_id }}'
    args: '{{ trigger.event.data.args }}'
    player: !input media_player
    steps: !input volume_steps
    stepsize: '{{ 1.0 / steps }}'
- choose:
  - conditions:
    - '{{ command == ''toggle'' }}'
    - '{{ cluster_id == 6 }}'
    - '{{ endpoint_id == 1 }}'
    sequence: !input play_pause_press
  - conditions:
    - '{{ command == ''move_with_on_off'' }}'
    - '{{ cluster_id == 8 }}'
    - '{{ endpoint_id == 1 }}'
    - '{{ trigger.event.data.params.move_mode == 0}}'
    sequence:
    - service: media_player.volume_set
      target:
        entity_id: '{{ player }}'
      data:
        volume_level: '{% set volume = state_attr(player, "volume_level") + stepsize
          %} {{ 1.0 if volume > 1.0 else volume }}'
  - conditions:
    - '{{ command == ''move'' }}'
    - '{{ cluster_id == 8 }}'
    - '{{ endpoint_id == 1 }}'
    - '{{ trigger.event.data.params.move_mode == 0}}'
    sequence:
    - service: media_player.volume_up
      target:
        entity_id: '{{ player }}'
  - conditions:
    - '{{ command == ''move_with_on_off'' }}'
    - '{{ cluster_id == 8 }}'
    - '{{ endpoint_id == 1 }}'
    - '{{ trigger.event.data.params.move_mode == 1}}'
    sequence:
    - service: media_player.volume_set
      target:
        entity_id: '{{ player }}'
      data:
        volume_level: '{% set volume = state_attr(player, "volume_level") - stepsize
          %} {{ 0.0 if volume < 0.0 else volume }}'
  - conditions:
    - '{{ command == ''move'' }}'
    - '{{ cluster_id == 8 }}'
    - '{{ endpoint_id == 1 }}'
    - '{{ trigger.event.data.params.move_mode == 1 }}'
    sequence:
    - service: media_player.volume_down
      target:
        entity_id: '{{ player }}'
  - conditions:
    - '{{ command == ''step'' }}'
    - '{{ cluster_id == 8 }}'
    - '{{ endpoint_id == 1 }}'
    - '{{ trigger.event.data.params.step_mode == 0 }}'
    sequence:
    - service: media_player.media_next_track
      target:
        entity_id: '{{ player }}'
  - conditions:
    - '{{ command == ''step'' }}'
    - '{{ cluster_id == 8 }}'
    - '{{ endpoint_id == 1 }}'
    - '{{ trigger.event.data.params.step_mode == 1 }}'
    sequence:
    - service: media_player.media_previous_track
      target:
        entity_id: '{{ player }}'
  - conditions:
    - '{{ command == ''short_release'' }}'
    - '{{ endpoint_id == 2 }}'
    sequence: !input single_dot_single_press
  - conditions:
    - '{{ command == ''multi_press_complete'' }}'
    - '{{ endpoint_id == 2 }}'
    sequence: !input single_dot_double_press
  - conditions:
    - '{{ command == ''long_press'' }}'
    - '{{ endpoint_id == 2 }}'
    sequence: !input single_dot_long_press
  - conditions:
    - '{{ command == ''short_release'' }}'
    - '{{ endpoint_id == 3 }}'
    sequence: !input double_dot_single_press
  - conditions:
    - '{{ command == ''multi_press_complete'' }}'
    - '{{ endpoint_id == 3 }}'
    sequence: !input double_dot_double_press
  - conditions:
    - '{{ command == ''long_press'' }}'
    - '{{ endpoint_id == 3 }}'
    sequence: !input double_dot_long_press

Hi, I imported this blueprint successfully but I‘m not able to use it as my remote does not show up in the devices list… Do you know how I can fix that? The remote is integrated via Zigbee2MQTT.

This is the BEST Symfonisk Remote Gen 2 Blueprint I’ve found so far. Good work!
But I can’t work our the volume steps. My volume doesn’t always jump the same amount up and down (e.g. when set to 25, the volume goes up 0 > 4 > 8 > 12, but then down to 7).
The default Sonos steps are in 2% intervals.
How is the stepping calculated in your Blueprint?