Created
November 27, 2025 23:14
-
-
Save fcayci/412f6588fd880cfb4c5364b1cccc0522 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| blueprint: | |
| name: IKEA Styrbar - control multiple Light/Switch Entities | |
| description: "**Manage multiple Light/Switch Entities with the IKEA Styrbar Switch\nRemote via Zigbee2MQTT**\n\n_Release Notes_:\n\n**Version 1.4** (2025-10-28):\n- Make smooth dimming transition max 2s.\n- Add per-entity smooth dimming selection so only chosen lights use transition-based smooth dimming.\n- Keep raw targets list (do not expand groups) so group entities are treated as single targets.\n- Add option to prevent a lamp from being turned fully off while dimming, with a configurable threshold slider.\n" | |
| domain: automation | |
| input: | |
| switch_remote: | |
| name: Styrbar switch remote | |
| description: Choose IKEA Styrbar switch remote | |
| selector: | |
| device: | |
| integration: mqtt | |
| manufacturer: IKEA | |
| model: STYRBAR remote control | |
| multiple: false | |
| targets: | |
| name: Light/Switch | |
| description: Choose one or more Light/Switch Entities you want to control | |
| selector: | |
| entity: | |
| filter: | |
| - domain: | |
| - light | |
| - switch | |
| multiple: true | |
| reorder: false | |
| selected_target: | |
| name: Selected Light/Switch Input Number Helper | |
| description: Choose the Input Number Helper to be exclusively used by the selected | |
| Styrbar switch remote to retain the last selected target Entity index | |
| selector: | |
| entity: | |
| multiple: false | |
| filter: | |
| - domain: | |
| - input_number | |
| reorder: false | |
| arrow_left_hold: | |
| name: Long press - left | |
| description: Action to execute when the Left button (left arrow icon) is held | |
| down | |
| default: [] | |
| selector: | |
| action: {} | |
| arrow_left_release: | |
| name: Release press - left | |
| description: Action to execute when the Left button (left arrow icon) is released | |
| after a long press | |
| default: [] | |
| selector: | |
| action: {} | |
| arrow_right_hold: | |
| name: Long press - right | |
| description: Action to execute when the Right button (right arrow icon) is held | |
| down | |
| default: [] | |
| selector: | |
| action: {} | |
| arrow_right_release: | |
| name: Release press - right | |
| description: Action to execute when the Right button (right arrow icon) is released | |
| after a long press | |
| default: [] | |
| selector: | |
| action: {} | |
| force_brightness: | |
| name: Set the brightness to the Brightness Level (%) option value for every | |
| On command | |
| selector: | |
| boolean: {} | |
| default: false | |
| brightness_pct: | |
| name: Brightness (%) when the Force Brightness option is enabled | |
| selector: | |
| number: | |
| min: 0.0 | |
| max: 100.0 | |
| step: 1.0 | |
| mode: slider | |
| default: 50 | |
| repeat_delay: | |
| name: Delay for brightness decrement/increment (in milliseconds) | |
| selector: | |
| number: | |
| min: 0.0 | |
| max: 1000.0 | |
| step: 1.0 | |
| mode: slider | |
| default: 150 | |
| repeat_count: | |
| name: Maximum number of iterations for brightness decrement/increment | |
| selector: | |
| number: | |
| min: 0.0 | |
| max: 100.0 | |
| step: 1.0 | |
| mode: slider | |
| default: 20 | |
| brightness_step_pct: | |
| name: Brightness Level step for each iteration (%) | |
| selector: | |
| number: | |
| min: 0.0 | |
| max: 100.0 | |
| step: 1.0 | |
| mode: slider | |
| default: 20 | |
| blink_time: | |
| name: Delay after changing the selected Light/Switch State to indicate selected | |
| target (in milliseconds) | |
| selector: | |
| number: | |
| min: 0.0 | |
| max: 1000.0 | |
| step: 1.0 | |
| mode: slider | |
| default: 100 | |
| smooth_dimming: | |
| name: Enable smooth dimming for brightness up/down (global) | |
| description: Use transition-based smooth dimming instead of immediate step increments. | |
| selector: | |
| boolean: {} | |
| default: true | |
| smooth_dimming_targets: | |
| name: Entities using smooth dimming | |
| description: If empty, smooth dimming applies to all targets when enabled. Otherwise only the selected entities will use smooth dimming. | |
| selector: | |
| entity: | |
| filter: | |
| - domain: | |
| - light | |
| - switch | |
| multiple: true | |
| reorder: false | |
| default: [] | |
| smooth_step_pct: | |
| name: Smooth dimming step (%) per repeat iteration | |
| description: Percent change applied per repeat when smooth_dimming is enabled for the target. | |
| selector: | |
| number: | |
| min: 1.0 | |
| max: 100.0 | |
| step: 1.0 | |
| mode: slider | |
| default: 5 | |
| dimming_transition: | |
| name: Transition time for smooth dimming (seconds) | |
| description: Transition duration passed to light.turn_on for each step (seconds). Maximum 2.0s. | |
| selector: | |
| number: | |
| min: 0.0 | |
| max: 2.0 | |
| step: 0.1 | |
| default: 0.5 | |
| prevent_turn_off_when_dimming: | |
| name: Prevent turning off when dimming | |
| description: When enabled, dimming down will not turn lights fully off. Brightness will not go below the configured threshold. | |
| selector: | |
| boolean: {} | |
| default: true | |
| dimming_off_threshold_pct: | |
| name: Minimum brightness (%) when preventing turn off | |
| description: If Prevent turning off when dimming is enabled, this slider sets the minimum brightness (%) the automation will allow while dimming down. | |
| selector: | |
| number: | |
| min: 0.0 | |
| max: 100.0 | |
| step: 1.0 | |
| mode: slider | |
| default: 1 | |
| source_url: https://github.com/jtosic/home_assistant/blob/58b72200bac2c5b0fdfe97653368a12d3b5cfc1a/automation/ikea_styrbar_remote-control_multiple_entities.yaml | |
| description: '' | |
| mode: restart | |
| trigger: | |
| - id: 'on' | |
| device_id: !input switch_remote | |
| domain: mqtt | |
| type: action | |
| subtype: 'on' | |
| trigger: device | |
| - id: 'off' | |
| device_id: !input switch_remote | |
| domain: mqtt | |
| type: action | |
| subtype: 'off' | |
| trigger: device | |
| - id: brightness_move_up | |
| device_id: !input switch_remote | |
| domain: mqtt | |
| type: action | |
| subtype: brightness_move_up | |
| trigger: device | |
| - id: brightness_move_down | |
| device_id: !input switch_remote | |
| domain: mqtt | |
| type: action | |
| subtype: brightness_move_down | |
| trigger: device | |
| - id: brightness_stop | |
| device_id: !input switch_remote | |
| domain: mqtt | |
| type: action | |
| subtype: brightness_stop | |
| trigger: device | |
| - id: arrow_left_click | |
| device_id: !input switch_remote | |
| domain: mqtt | |
| type: action | |
| subtype: arrow_left_click | |
| trigger: device | |
| - id: arrow_left_hold | |
| device_id: !input switch_remote | |
| domain: mqtt | |
| type: action | |
| subtype: arrow_left_hold | |
| trigger: device | |
| - id: arrow_left_release | |
| device_id: !input switch_remote | |
| domain: mqtt | |
| type: action | |
| subtype: arrow_left_release | |
| trigger: device | |
| - id: arrow_right_click | |
| device_id: !input switch_remote | |
| domain: mqtt | |
| type: action | |
| subtype: arrow_right_click | |
| trigger: device | |
| - id: arrow_right_hold | |
| device_id: !input switch_remote | |
| domain: mqtt | |
| type: action | |
| subtype: arrow_right_hold | |
| trigger: device | |
| - id: arrow_right_release | |
| device_id: !input switch_remote | |
| domain: mqtt | |
| type: action | |
| subtype: arrow_right_release | |
| trigger: device | |
| action: | |
| - variables: | |
| targets: !input targets | |
| selected_target: !input selected_target | |
| brightness_step_pct: !input brightness_step_pct | |
| # Smooth dimming inputs available as variables | |
| smooth_dimming: !input smooth_dimming | |
| smooth_dimming_targets: !input smooth_dimming_targets | |
| smooth_step_pct: !input smooth_step_pct | |
| dimming_transition: !input dimming_transition | |
| # new inputs to prevent turning off while dimming | |
| prevent_turn_off_when_dimming: !input prevent_turn_off_when_dimming | |
| dimming_off_threshold_pct: !input dimming_off_threshold_pct | |
| # Use the raw selected targets list (do NOT expand groups) so a group entity | |
| # selected by the user is treated as a single target. | |
| target_index: >- | |
| {% set tlist = targets | list %} | |
| {% set count = tlist | count | int %} | |
| {% set cur = states(selected_target) | int %} | |
| {% if cur < 0 %}0{% elif cur >= count %}{{ count - 1 }}{% else %}{{ cur }}{% endif %} | |
| # Access entity id directly from the targets list (no expand — avoids expanding group members) | |
| target_entity_id: '{{ (targets | list)[target_index] }}' | |
| target_entity_domain: '{{ target_entity_id.split(''.'')[0] }}' | |
| # computed: is smooth dimming enabled for this target? | |
| smooth_enabled: >- | |
| {{ smooth_dimming and ((smooth_dimming_targets | list | count) == 0 or target_entity_id in (smooth_dimming_targets | list)) }} | |
| - service: system_log.write | |
| data: | |
| level: info | |
| message: 'Blueprint Script - IKEA Styrbar - control multiple Lights/Switches: | |
| command = {{ trigger.id }}, selected_target = {{ states(selected_target) | int | |
| }}, target_index = {{ target_index }}, target_entity_id = {{ target_entity_id | |
| }}, target_entity_domain = {{ target_entity_domain }}, target_status = {{ states(target_entity_id) | |
| }}' | |
| - choose: | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ trigger.id == ''on'' }}' | |
| - condition: template | |
| value_template: '{{ target_entity_domain == ''light'' }}' | |
| - condition: template | |
| value_template: !input force_brightness | |
| sequence: | |
| - service: '{{ target_entity_domain }}.turn_on' | |
| target: | |
| entity_id: '{{ target_entity_id }}' | |
| data: | |
| brightness_pct: !input brightness_pct | |
| alias: on_force | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ trigger.id == ''on'' }}' | |
| sequence: | |
| - service: '{{ target_entity_domain }}.turn_on' | |
| target: | |
| entity_id: '{{ target_entity_id }}' | |
| alias: 'on' | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ trigger.id == ''off'' }}' | |
| sequence: | |
| - service: '{{ target_entity_domain }}.turn_off' | |
| target: | |
| entity_id: '{{ target_entity_id }}' | |
| alias: 'off' | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ trigger.id == ''brightness_move_up'' }}' | |
| - condition: template | |
| value_template: '{{ target_entity_domain == ''light'' }}' | |
| sequence: | |
| - choose: | |
| # If smooth dimming enabled for this specific target, use transition-based smooth steps | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ smooth_enabled }}' | |
| sequence: | |
| - repeat: | |
| count: !input repeat_count | |
| sequence: | |
| - variables: | |
| # current brightness in percent (0..100) | |
| cur_brightness: >- | |
| {{ (state_attr(target_entity_id, 'brightness') | int(0) * 100 / 255) | round(0) }} | |
| # new brightness (min 100) | |
| new_brightness: >- | |
| {{ [ (cur_brightness | int) + (smooth_step_pct | int), 100 ] | min }} | |
| - service: light.turn_on | |
| data: | |
| brightness_pct: '{{ new_brightness }}' | |
| transition: '{{ dimming_transition }}' | |
| target: | |
| entity_id: '{{ target_entity_id }}' | |
| - delay: | |
| hours: 0 | |
| minutes: 0 | |
| seconds: 0 | |
| milliseconds: !input repeat_delay | |
| # default: existing step-based (instant) brightness_step_pct used previously | |
| default: | |
| - repeat: | |
| count: !input repeat_count | |
| sequence: | |
| - service: light.turn_on | |
| metadata: {} | |
| data: | |
| brightness_step_pct: '{{ brightness_step_pct }}' | |
| target: | |
| entity_id: '{{ target_entity_id }}' | |
| - delay: | |
| hours: 0 | |
| minutes: 0 | |
| seconds: 0 | |
| milliseconds: !input repeat_delay | |
| alias: brightness_move_up | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ trigger.id == ''brightness_move_down'' }}' | |
| - condition: template | |
| value_template: '{{ target_entity_domain == ''light'' }}' | |
| sequence: | |
| - choose: | |
| # Smooth dimming down: use transition-based smooth steps | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ smooth_enabled }}' | |
| sequence: | |
| - repeat: | |
| count: !input repeat_count | |
| sequence: | |
| - variables: | |
| cur_brightness: >- | |
| {{ (state_attr(target_entity_id, 'brightness') | int(0) * 100 / 255) | round(0) }} | |
| off_threshold: >- | |
| {% if prevent_turn_off_when_dimming %}{{ dimming_off_threshold_pct | int }}{% else %}0{% endif %} | |
| new_brightness: >- | |
| {{ [ (cur_brightness | int) - (smooth_step_pct | int), off_threshold ] | max }} | |
| - service: light.turn_on | |
| data: | |
| brightness_pct: '{{ new_brightness }}' | |
| transition: '{{ dimming_transition }}' | |
| target: | |
| entity_id: '{{ target_entity_id }}' | |
| - delay: | |
| hours: 0 | |
| minutes: 0 | |
| seconds: 0 | |
| milliseconds: !input repeat_delay | |
| default: | |
| - repeat: | |
| count: !input repeat_count | |
| sequence: | |
| - variables: | |
| cur_brightness: >- | |
| {{ (state_attr(target_entity_id, 'brightness') | int(0) * 100 / 255) | round(0) }} | |
| off_threshold: >- | |
| {% if prevent_turn_off_when_dimming %}{{ dimming_off_threshold_pct | int }}{% else %}0{% endif %} | |
| new_brightness: >- | |
| {{ [ (cur_brightness | int) - (brightness_step_pct | int), off_threshold ] | max }} | |
| - service: light.turn_on | |
| metadata: {} | |
| data: | |
| brightness_pct: '{{ new_brightness }}' | |
| target: | |
| entity_id: '{{ target_entity_id }}' | |
| - delay: | |
| hours: 0 | |
| minutes: 0 | |
| seconds: 0 | |
| milliseconds: !input repeat_delay | |
| alias: brightness_move_down | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ trigger.id == ''brightness_stop'' }}' | |
| - condition: template | |
| value_template: '{{ target_entity_domain == ''light'' }}' | |
| sequence: [] | |
| alias: brightness_stop | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ trigger.id == ''arrow_left_click'' }}' | |
| sequence: | |
| - choose: | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ states(selected_target) | int <= 0 }}' | |
| sequence: | |
| - service: input_number.set_value | |
| data_template: | |
| entity_id: !input selected_target | |
| value: '{{ (targets | list | count | int) - 1 }}' | |
| default: | |
| - service: input_number.decrement | |
| entity_id: !input selected_target | |
| - variables: | |
| target_index: !input selected_target | |
| target_entity_id: '{{ (targets | list)[states(selected_target) | int] }}' | |
| target_entity_domain: '{{ target_entity_id.split(''.'')[0] }}' | |
| - sequence: | |
| - service: '{{ target_entity_domain }}.turn_{% if states(target_entity_id) == | |
| ''off'' %}on{% else %}off{% endif %}' | |
| target: | |
| entity_id: '{{ target_entity_id }}' | |
| - delay: | |
| hours: 0 | |
| minutes: 0 | |
| seconds: 0 | |
| milliseconds: !input blink_time | |
| - service: '{{ target_entity_domain }}.turn_{% if states(target_entity_id) == | |
| ''off'' %}on{% else %}off{% endif %}' | |
| target: | |
| entity_id: '{{ target_entity_id }}' | |
| alias: arrow_left_click | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ trigger.id == ''arrow_left_hold'' }}' | |
| sequence: !input arrow_left_hold | |
| alias: arrow_left_hold | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ trigger.id == ''arrow_left_release'' }}' | |
| sequence: !input arrow_left_release | |
| alias: arrow_left_release | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ trigger.id == ''arrow_right_click'' }}' | |
| sequence: | |
| - choose: | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ states(selected_target) | int >= (targets | list | count | int) - 1 }}' | |
| sequence: | |
| - service: input_number.set_value | |
| entity_id: !input selected_target | |
| data: | |
| value: 0 | |
| default: | |
| - service: input_number.increment | |
| entity_id: !input selected_target | |
| - variables: | |
| target_index: !input selected_target | |
| target_entity_id: '{{ (targets | list)[states(selected_target) | int] }}' | |
| target_entity_domain: '{{ target_entity_id.split(''.'')[0] }}' | |
| - sequence: | |
| - service: '{{ target_entity_domain }}.turn_{% if states(target_entity_id) == | |
| ''off'' %}on{% else %}off{% endif %}' | |
| target: | |
| entity_id: '{{ target_entity_id }}' | |
| - delay: | |
| hours: 0 | |
| minutes: 0 | |
| seconds: 0 | |
| milliseconds: !input blink_time | |
| - service: '{{ target_entity_domain }}.turn_{% if states(target_entity_id) == | |
| ''off'' %}on{% else %}off{% endif %}' | |
| target: | |
| entity_id: '{{ target_entity_id }}' | |
| alias: arrow_right_click | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ trigger.id == ''arrow_right_hold'' }}' | |
| sequence: !input arrow_right_hold | |
| alias: arrow_right_hold | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ trigger.id == ''arrow_right_release'' }}' | |
| sequence: !input arrow_right_release | |
| alias: arrow_right_release |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment