Skip to content

Instantly share code, notes, and snippets.

@subutux
Last active February 12, 2024 20:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save subutux/de86b55dd2eed27e8653c77846385552 to your computer and use it in GitHub Desktop.
Save subutux/de86b55dd2eed27e8653c77846385552 to your computer and use it in GitHub Desktop.
Symfonisk Sound remote gen2 remote
blueprint:
# Media control via IKEA Symfonisk Gen2 - Shawsky April 2023 v1.52
# Updated May 2023 - Add group volume control
# Updated June 2023 - Resolve filtering issue where multiple devices are in use
# Updated August 2023 - Resolve a volume issue for media players with no group_memeber attribute
# Updated September 2023 - Further updates for group/non grouped behaviour / fix issue for volume hold for grouped/non grouped. Allow 100 volume steps.
# Volume changes partially based on https://gist.github.com/erkr/a437ebcb98a2b5ba2deebabd02f5ffae Eric Kreuwels
# and https://gist.github.com/alexwmaustin/2c25cfa1a0ade1ab9fc1ef0940289672 Alex Austin
name: Z2M - IKEA Symfonisk sound controller GEN2 for media
description:
'Control the selected media player (and any joined to it) with an IKEA Symfonisk sound controller GEN2 via Zigbee2MQTT (Z2M)
Supports single press on media buttons and single, double and long press for the "dot" buttons.'
domain: automation
input:
remote:
name: Remote
description: The IKEA Symfonisk controller GEN2 to use
selector:
device:
integration: mqtt
manufacturer: IKEA
model: SYMFONISK sound remote gen2 (E2123)
multiple: false
base_topic:
name: Zigbee2MQTT Base mqtt topic
description: The base topic configured in Zigbee2MQTT. If you haven't changed this, leave the default here ("zigbee2mqtt")
default: zigbee2mqtt
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:
name: Single Dot (Single)
description: Action to run on single dot press
default: []
selector:
action: {}
single_dot_double_press:
name: Single Dot (Double)
description: Action to run on single dot double press
default: []
selector:
action: {}
single_dot_long_press:
name: Single Dot (Long)
description: Action to run on single dot long press
default: []
selector:
action: {}
double_dot:
name: Double Dot (Single)
description: Action to run on double dot press
default: []
selector:
action: {}
double_dot_double_press:
name: Double Dot (Double)
description: Action to run on double dot double press
default: []
selector:
action: {}
double_dot_long_press:
name: Double Dot (Long)
description: Action to run on double dot long press
default: []
selector:
action: {}
mode: restart
max_exceeded: silent
trigger_variables:
base_topic: !input base_topic
controller: !input remote
trigger:
- platform: mqtt
topic: "{{ base_topic }}/+/+/action"
action:
- variables:
controllertopic: "{{ base_topic }}/{{ device_attr(controller, 'name') }}/action"
player: !input 'media_player'
steps: !input volume_steps
stepsize: '{{ 1.0 / steps }}'
- choose:
- conditions:
- "{{ trigger.payload != ''}}"
- "{{ trigger.topic == controllertopic }}"
sequence:
- choose:
## Commands
# Play / Pause
- conditions: "{{ trigger.payload == 'toggle' }}"
sequence:
- service: media_player.media_play_pause
entity_id: !input 'media_player'
# Next Track
- conditions: "{{ trigger.payload == 'track_next' }}"
sequence:
- service: media_player.media_next_track
entity_id: !input 'media_player'
# Previous Track
- conditions: "{{ trigger.payload == 'track_previous' }}"
sequence:
- service: media_player.media_previous_track
entity_id: !input 'media_player'
## Volume for media players supporting groups
# Volume Up Press
- conditions: "{{ trigger.payload == 'volume_up' and state_attr(player, 'group_members') != none and state_attr(player, 'group_members') != [] }}"
sequence:
- repeat:
for_each: "{{ state_attr(player, 'group_members') }}"
sequence:
- service: media_player.volume_set
target:
entity_id: "{{ repeat.item }}"
data:
volume_level: >-
{% set volume = state_attr(repeat.item, "volume_level") + stepsize %}
{{ 1.0 if volume > 1.0 else volume }}
# Volume Down Press
- conditions: "{{ trigger.payload == 'volume_down' and state_attr(player, 'group_members') != none and state_attr(player, 'group_members') != [] }}"
sequence:
- repeat:
for_each: "{{ state_attr(player, 'group_members') }}"
sequence:
- service: media_player.volume_set
target:
entity_id: "{{ repeat.item }}"
data:
volume_level: >-
{% set volume = state_attr(repeat.item, "volume_level") - stepsize %}
{{ 0.0 if volume < 0.0 else volume }}
# Volume Up Hold
- conditions: "{{ trigger.payload == 'volume_up_hold' and state_attr(player, 'group_members') != none and state_attr(player, 'group_members') != [] }}"
sequence:
- repeat:
for_each: "{{ state_attr(player, 'group_members') }}"
sequence:
- service: media_player.volume_up
target:
entity_id: "{{ repeat.item }}"
# Volume Down Hold
- conditions: "{{ trigger.payload == 'volume_down_hold' and state_attr(player, 'group_members') != none and state_attr(player, 'group_members') != [] }}"
sequence:
- repeat:
for_each: "{{ state_attr(player, 'group_members') }}"
sequence:
- service: media_player.volume_down
target:
entity_id: "{{ repeat.item }}"
## Volume for media players not supporting groups
# Volume Up
- conditions: "{{ trigger.payload == 'volume_up' and (state_attr(player, 'group_members') == none or state_attr(player, 'group_members') == []) }}"
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 Down Press
- conditions: "{{ trigger.payload == 'volume_down' and (state_attr(player, 'group_members') == none or state_attr(player, 'group_members') == []) }}"
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 Up Hold
- conditions: "{{ trigger.payload == 'volume_up_hold' and (state_attr(player, 'group_members') == none or state_attr(player, 'group_members') == []) }}"
sequence:
- service: media_player.volume_up
target:
entity_id: "{{ player }}"
# Volume Down Hold
- conditions: "{{ trigger.payload == 'volume_down_hold' and (state_attr(player, 'group_members') == none or state_attr(player, 'group_members') == []) }}"
sequence:
- service: media_player.volume_down
target:
entity_id: "{{ player }}"
## Actions
# Single Dot Press
- conditions: "{{ trigger.payload == 'dots_1_short_release' }}"
sequence: !input single_dot
# Single Dot Double Press
- conditions: "{{ trigger.payload == 'dots_1_double_press' }}"
sequence: !input single_dot_double_press
# Single Dot Long Press
- conditions: "{{ trigger.payload == 'dots_1_long_press' }}"
sequence: !input single_dot_long_press
# Double Dot Press
- conditions: "{{ trigger.payload == 'dots_2_short_release' }}"
sequence: !input double_dot
# Double Dot Double Press
- conditions: "{{ trigger.payload == 'dots_2_double_press' }}"
sequence: !input double_dot_double_press
# Double Dot Long Press
- conditions: "{{ trigger.payload == 'dots_2_long_press' }}"
sequence: !input double_dot_long_press
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment