Skip to content

Instantly share code, notes, and snippets.

@aschamberger
Last active January 2, 2023 19:34
Show Gist options
  • Save aschamberger/ee3934d3d6fe87fae99da495c0065992 to your computer and use it in GitHub Desktop.
Save aschamberger/ee3934d3d6fe87fae99da495c0065992 to your computer and use it in GitHub Desktop.
HA Automation Blueprint: Control Logitech Squeezebox media player entities from KNX switching and relative dimming (DPT 3.007) telegrams.
blueprint:
name: KNX - Squeezebox control
description: Control Logitech Squeezebox media player entities from KNX switching and relative
dimming (DPT 3.007) telegrams.
domain: automation
input:
media_player:
name: Squeezebox media player
description: The Squeezebox instance that shall be controled.
selector:
entity:
domain: media_player
switch_address:
name: Switch group address
description: >
Group address for switching the player on and off (DPT 1.001).
Example: '8/3/20'
state_address:
name: State group address
description: >
Group address for player state (DPT 1.001).
Example: '8/3/21''
dimm_address:
name: Volume relative dimming address
description: >
Group address for dimming the volume (DPT 3.007).
Example: '8/3/22'
volume_state_address:
name: Volume state group address
description: >
Group address for player volume (DPT 5.001).
Example: '8/3/23'
favorite_address:
name: favorite group address
description: >
Group address for iterating the favorite list (DPT 1.007). Value: only 1.
Example: '8/3/24'
mute_address:
name: Mute group address
description: >
Group address for muting the player (DPT 1.001).
Example: '8/3/25'
mute_state_address:
name: Mute state group address
description: >
Group address for muting state of the player (DPT 1.001).
Example: '8/3/26'
player_state_entity:
name: Player state template entity.
description: >
Player state template entity that holds the state as binary value.
selector:
entity:
domain: binary_sensor
player_volume_entity:
name: Player volume template entity.
description: >
Player volume template entity that holds the volume as percent value.
selector:
entity:
domain: sensor
dimm_time:
name: Dimm time
description: Time dimming from 0 to 100% shall take.
selector:
number:
min: 1
max: 20
step: 0.1
unit_of_measurement: seconds
mode: slider
default: 4
dimm_steps:
name: Dimm steps
description: Steps used to dimm from 0 to 100%.
selector:
number:
min: 1
max: 100
step: 1
unit_of_measurement: steps
mode: slider
default: 40
source_url: https://gist.github.com/aschamberger/ee3934d3d6fe87fae99da495c0065992
# no matched condition stops repeat sequence to stop dimming (dimm 0)
mode: restart
max_exceeded: silent
variables:
media_player_entity_id: !input 'media_player'
_dimm_time: !input 'dimm_time'
_dimm_steps: !input 'dimm_steps'
dimm_time: '{{ _dimm_time|float }}'
dimm_steps: '{{ _dimm_steps|int }}'
dimm_step: '{{ (1 / dimm_steps) }}'
dimm_delay: '{{ dimm_time * 1000 / dimm_steps }}'
trigger:
- platform: homeassistant
event: start
id: initialize
- platform: event
event_type: automation_reloaded
id: initialize
# when KNX integration was reloaded
- platform: event
event_type: service_registered
event_data:
domain: knx
service: event_register
id: initialize
- platform: event
event_type: knx_event
event_data:
destination: !input 'switch_address'
telegramtype: GroupValueWrite
id: switch
- platform: event
event_type: knx_event
event_data:
destination: !input 'dimm_address'
telegramtype: GroupValueWrite
id: dimm
- platform: event
event_type: knx_event
event_data:
destination: !input 'favorite_address'
telegramtype: GroupValueWrite
id: favorite
- platform: event
event_type: knx_event
event_data:
destination: !input 'mute_address'
telegramtype: GroupValueWrite
id: mute
action:
- choose:
# TURN ON
- conditions:
condition: and
conditions:
- condition: trigger
id: switch
- '{{ trigger.event.data.data == 1 }}'
sequence:
- service: media_player.media_play
entity_id: !input 'media_player'
# TURN OFF
- conditions:
condition: and
conditions:
- condition: trigger
id: switch
- '{{ trigger.event.data.data == 0 }}'
sequence:
- service: media_player.turn_off
entity_id: !input 'media_player'
# VOLUME UP
- conditions:
condition: and
conditions:
- condition: trigger
id: dimm
- '{{ 9 <= trigger.event.data.data <= 15 }}'
sequence:
- repeat:
count: '{{ dimm_steps }}'
sequence:
- service: media_player.volume_set
entity_id: !input 'media_player'
data:
volume_level: '{% if state_attr(media_player_entity_id, "volume_level") == None %}{{ dimm_step }}{% else %}{{ ([0.01, state_attr(media_player_entity_id, "volume_level") + dimm_step, 1]|sort)[1] }}{% endif %}'
- delay:
milliseconds: '{{ dimm_delay }}'
# VOLUME DOWN
- conditions:
condition: and
conditions:
- condition: trigger
id: dimm
- '{{ 1 <= trigger.event.data.data <= 7 }}'
sequence:
- repeat:
count: '{{ dimm_steps }}'
sequence:
- service: media_player.volume_set
entity_id: !input 'media_player'
data:
volume_level: '{% if state_attr(media_player_entity_id, "volume_level") == None %}{{ dimm_step }}{% else %}{{ ([0.01, state_attr(media_player_entity_id, "volume_level") - dimm_step, 1]|sort)[1] }}{% endif %}'
- delay:
milliseconds: '{{ dimm_delay }}'
# FAVORITE
- conditions:
condition: and
conditions:
- condition: trigger
id: favorite
- '{{ trigger.event.data.data == 1 }}'
sequence:
# 1: get currently played item
- service: squeezebox.call_query
entity_id: !input 'media_player'
data:
command: path
parameters:
- '?'
# 2a: search if current item is a favorite
- service: squeezebox.call_query
entity_id: !input 'media_player'
data:
command: favorites
parameters:
- exists
- "{{ state_attr(media_player_entity_id, 'query_result')['_path'] }}"
# 2b: store result
- variables:
current_item: "{% if state_attr(media_player_entity_id, 'query_result')['exists'] == 1 %}{{ state_attr(media_player_entity_id, 'query_result')['index'] }}{% else %}-1{% endif %}"
# 3: get all favorites
- service: squeezebox.call_query
entity_id: !input 'media_player'
data:
command: favorites
parameters:
- items
- '0'
- 'item_id:'
# 4: play next item from favorites
- service: squeezebox.call_query
entity_id: !input 'media_player'
data:
command: favorites
parameters:
- playlist
- play
- >
{%- set ns = namespace(ids=[]) -%}
{%- for fav in state_attr(media_player_entity_id, 'query_result')['loop_loop'] if fav.isaudio == 1 -%}
{%- set ns.ids = ns.ids + [fav.id.split('.')[1]] -%}
{%- endfor -%}
{%- if current_item == -1 -%}
item_id:{{ ns.ids[0] }}
{%- else -%}
{%- if ns.ids.index(current_item|string)+1 == ns.ids|length -%}
item_id:{{ ns.ids[0] }}
{%- else -%}
item_id:{{ ns.ids[ns.ids.index(current_item|string)+1] }}
{%- endif -%}
{%- endif -%}
# MUTE
- conditions:
condition: and
conditions:
- condition: trigger
id: mute
- '{{ trigger.event.data.data == 1 }}'
sequence:
- service: media_player.volume_mute
entity_id: !input 'media_player'
data:
is_volume_muted: true
# UNMUTE
- conditions:
condition: and
conditions:
- condition: trigger
id: mute
- '{{ trigger.event.data.data == 0 }}'
sequence:
- service: media_player.volume_mute
entity_id: !input 'media_player'
data:
is_volume_muted: false
# INITIALIZE
- conditions:
condition: trigger
id: initialize
sequence:
- service: knx.event_register
data:
address: !input 'switch_address'
- service: knx.event_register
data:
address: !input 'dimm_address'
- service: knx.event_register
data:
address: !input 'favorite_address'
- service: knx.event_register
data:
address: !input 'mute_address'
- service: knx.send
data:
address: !input 'state_address'
payload: '{% if is_state(media_player_entity_id, "off") %}0{% else %}1{% endif %}'
- service: knx.send
data:
address: !input 'volume_state_address'
payload: '{% if state_attr(media_player_entity_id, "volume_level") == None %}0{% else %}{{state_attr(media_player_entity_id, "volume_level")*100 }}{% endif %}'
type: percent
- service: knx.exposure_register
data:
address: !input 'mute_state_address'
entity_id: !input 'media_player'
attribute: is_volume_muted
type: binary
default: 0
- service: knx.exposure_register
data:
address: !input 'state_address'
entity_id: !input 'player_state_entity'
type: binary
- service: knx.exposure_register
data:
address: !input 'volume_state_address'
entity_id: !input 'player_volume_entity'
type: percent
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment