Instantly share code, notes, and snippets.
Last active
March 1, 2026 16:34
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
-
Save Ltek/27a83afea0a073834052bd055995da4b to your computer and use it in GitHub Desktop.
Home Assistant Blueprint : Shelly i4 Button Controller by Ltek
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: π Shelly i4 Button Controller by LTek | |
| description: > | |
| π Shelly i4 Button Controller with scenes and single-button dimming and scenes | |
| π Version 2026.03.01.07c | |
| β Features: | |
| - Set any HA Action for Button presses (Single, Double, Triple, Down, Up, Long) | |
| - Single Button Dim any or all buttons (optional) | |
| - Dim Direction Start Boundary sets dim direction at start of dim; upward if below, downward if above | |
| - Dim Fine Tuning - Dim Percent per Step, Step Interval (time delay between steps), Transition Duration | |
| - Debug notifications show trigger and action, with timestamps | |
| ποΈ Dim Configuration Guide" | |
| **NOTE...** Dimming starts 1 second after the initial press-hold. (native Shelly device detection period for long_press) | |
| Default values balance dim speed, system latency, and smoothness control for Zigbee lights. | |
| - When Dim Function is Enabled, Basic Actions for Button Up and Long Press are disabled | |
| - if the Light is OFF, Long press turns on the Light then Dims | |
| These three settings work together to control dimming feel: | |
| - Dim Step Percent β brightness change per cycle. Smaller = finer steps but slower | |
| to traverse the full range. Larger = faster but more visible jumps. | |
| Default: 14% | |
| - Dim Interval β time between each step. This is the primary speed control. | |
| Shorter = faster dimming. | |
| Default: 0.2s | |
| - Transition Duration β the lights own transition between the current and new brightness. | |
| Must be LESS than Dim Interval or steps will overlap and stutter. | |
| Default: 0.0s | |
| β οΈ High-latency lights (Zigbee, Z-Wave): if dimming feels slow despite short intervals, | |
| set Transition Duration to 0.0 β the light's own fade response is adding delay to | |
| each loop cycle. The step frequency itself creates perceived smoothness. | |
| π Community Discussion, Help, and Details... https://community.home-assistant.io/t/shelly-i4-button-controller-by-ltek-with-single-button-dim-multi-press-functions/941400 | |
| source_url: https://gist.github.com/Ltek/27a83afea0a073834052bd055995da4b | |
| domain: automation | |
| input: | |
| shelly_device: | |
| name: π Shelly i4 Device | |
| selector: | |
| device: | |
| integration: shelly | |
| manufacturer: Shelly | |
| button1_basic_actions: | |
| name: "Button 1 - Basic Actions" | |
| description: Configure basic button press actions | |
| icon: mdi:numeric-1-box | |
| collapsed: true | |
| input: | |
| button1_single: | |
| name: Single Press | |
| selector: | |
| action: {} | |
| default: [] | |
| button1_double: | |
| name: Double Press | |
| selector: | |
| action: {} | |
| default: [] | |
| button1_triple: | |
| name: Triple Press | |
| selector: | |
| action: {} | |
| default: [] | |
| button1_down: | |
| name: Button Down | |
| selector: | |
| action: {} | |
| default: [] | |
| button1_up: | |
| name: Button Up | |
| description: when Dimming Function enabled, this setting is ignored. | |
| selector: | |
| action: {} | |
| default: [] | |
| button1_long: | |
| name: Long Press | |
| description: when Dimming Function enabled, this setting is ignored. | |
| selector: | |
| action: {} | |
| default: [] | |
| button1_dim_settings: | |
| name: "Button 1 - Dimming Settings" | |
| description: Configure dimming functionality for long press | |
| icon: mdi:brightness-6 | |
| collapsed: true | |
| input: | |
| button1_dim_enabled: | |
| name: Enable Dim Function | |
| description: When enabled the above actions for Long Press and Button Up are Disabled | |
| selector: | |
| boolean: {} | |
| default: false | |
| button1_dim_target: | |
| name: Light Entity or Group you want to Dim | |
| selector: | |
| entity: | |
| domain: light | |
| default: "" | |
| button1_dim_step: | |
| name: Dim Step Percent | |
| description: Change light Brightness this amount per dim cycle. (1 to 50) | |
| selector: | |
| number: | |
| min: 1 | |
| max: 50 | |
| unit_of_measurement: '%' | |
| default: 14 | |
| button1_dim_delay: | |
| name: Dim Interval (seconds) | |
| description: Time between each dim cycle. (0.05 to 2.0) | |
| selector: | |
| number: | |
| min: 0.05 | |
| max: 2 | |
| unit_of_measurement: seconds | |
| default: 0.2 | |
| button1_transition: | |
| name: Transition Duration (seconds) | |
| description: Duration of brightness transition for each dim step. Set to 0.0 for Zigbee/Z-Wave lights to avoid latency blocking the dim loop. (0.0 to 2.0) | |
| selector: | |
| number: | |
| min: 0.0 | |
| max: 2.0 | |
| step: 0.05 | |
| unit_of_measurement: seconds | |
| default: 0.0 | |
| button1_boundary: | |
| name: Dim Boundary Percent | |
| description: At Dim Start, if the light is Below this Brightness Level, the dim will Increase Brightness, otherwise it will Decreases Brightness | |
| selector: | |
| number: | |
| min: 0 | |
| max: 100 | |
| unit_of_measurement: '%' | |
| default: 50 | |
| button2_basic_actions: | |
| name: "Button 2 - Basic Actions" | |
| description: Configure basic button press actions | |
| icon: mdi:numeric-2-box | |
| collapsed: true | |
| input: | |
| button2_single: | |
| name: Single Short Press | |
| selector: | |
| action: {} | |
| default: [] | |
| button2_double: | |
| name: Double Short Press | |
| selector: | |
| action: {} | |
| default: [] | |
| button2_triple: | |
| name: Triple Short Press | |
| selector: | |
| action: {} | |
| default: [] | |
| button2_down: | |
| name: Button Down | |
| selector: | |
| action: {} | |
| default: [] | |
| button2_up: | |
| name: Button Up | |
| description: when Dimming Function enabled, this setting is ignored. | |
| selector: | |
| action: {} | |
| default: [] | |
| button2_long: | |
| name: Long Press | |
| description: when Dimming Function enabled, this setting is ignored. | |
| selector: | |
| action: {} | |
| default: [] | |
| button2_dim_settings: | |
| name: "Button 2 - Dimming Settings" | |
| description: Configure dimming functionality for long press | |
| icon: mdi:brightness-6 | |
| collapsed: true | |
| input: | |
| button2_dim_enabled: | |
| name: Enable Dim Function | |
| description: When enabled the above actions for Long Press and Button Up are Disabled | |
| selector: | |
| boolean: {} | |
| default: false | |
| button2_dim_target: | |
| name: Light Entity or Group you want to Dim | |
| selector: | |
| entity: | |
| domain: light | |
| default: "" | |
| button2_dim_step: | |
| name: Dim Step Percent | |
| description: Change light Brightness this amount per dim cycle. (1 to 50) | |
| selector: | |
| number: | |
| min: 1 | |
| max: 50 | |
| unit_of_measurement: '%' | |
| default: 14 | |
| button2_dim_delay: | |
| name: Dim Interval (seconds) | |
| description: Time between each dim cycle. (0.05 to 2.0) | |
| selector: | |
| number: | |
| min: 0.05 | |
| max: 2 | |
| unit_of_measurement: seconds | |
| default: 0.2 | |
| button2_transition: | |
| name: Transition Duration (seconds) | |
| description: Duration of brightness transition for each dim step. Set to 0.0 for Zigbee/Z-Wave lights to avoid latency blocking the dim loop. (0.0 to 2.0) | |
| selector: | |
| number: | |
| min: 0.0 | |
| max: 2.0 | |
| step: 0.05 | |
| unit_of_measurement: seconds | |
| default: 0.0 | |
| button2_boundary: | |
| name: Dim Boundary Percent | |
| description: At Dim Start, if the light is Below this Brightness Level, the dim will Increase Brightness, otherwise it will Decreases Brightness | |
| selector: | |
| number: | |
| min: 0 | |
| max: 100 | |
| unit_of_measurement: '%' | |
| default: 50 | |
| button3_basic_actions: | |
| name: "Button 3 - Basic Actions" | |
| description: Configure basic button press actions | |
| icon: mdi:numeric-3-box | |
| collapsed: true | |
| input: | |
| button3_single: | |
| name: Single Short Press | |
| selector: | |
| action: {} | |
| default: [] | |
| button3_double: | |
| name: Double Short Press | |
| selector: | |
| action: {} | |
| default: [] | |
| button3_triple: | |
| name: Triple Short Press | |
| selector: | |
| action: {} | |
| default: [] | |
| button3_down: | |
| name: Button Down | |
| selector: | |
| action: {} | |
| default: [] | |
| button3_up: | |
| name: Button Up | |
| description: when Dimming Function enabled, this setting is ignored. | |
| selector: | |
| action: {} | |
| default: [] | |
| button3_long: | |
| name: Long Press | |
| description: when Dimming Function enabled, this setting is ignored. | |
| selector: | |
| action: {} | |
| default: [] | |
| button3_dim_settings: | |
| name: "Button 3 - Dimming Settings" | |
| description: Configure dimming functionality for long press | |
| icon: mdi:brightness-6 | |
| collapsed: true | |
| input: | |
| button3_dim_enabled: | |
| name: Enable Dim Function | |
| description: When enabled the above actions for Long Press and Button Up are Disabled | |
| selector: | |
| boolean: {} | |
| default: false | |
| button3_dim_target: | |
| name: Light Entity or Group you want to Dim | |
| selector: | |
| entity: | |
| domain: light | |
| default: "" | |
| button3_dim_step: | |
| name: Dim Step Percent | |
| description: Change light Brightness this amount per dim cycle. (1 to 50) | |
| selector: | |
| number: | |
| min: 1 | |
| max: 50 | |
| unit_of_measurement: '%' | |
| default: 14 | |
| button3_dim_delay: | |
| name: Dim Interval (seconds) | |
| description: Time between each dim cycle. (0.05 to 2.0) | |
| selector: | |
| number: | |
| min: 0.05 | |
| max: 2 | |
| unit_of_measurement: seconds | |
| default: 0.2 | |
| button3_transition: | |
| name: Transition Duration (seconds) | |
| description: Duration of brightness transition for each dim step. Set to 0.0 for Zigbee/Z-Wave lights to avoid latency blocking the dim loop. (0.0 to 2.0) | |
| selector: | |
| number: | |
| min: 0.0 | |
| max: 2.0 | |
| step: 0.05 | |
| unit_of_measurement: seconds | |
| default: 0.0 | |
| button3_boundary: | |
| name: Dim Boundary Percent | |
| description: At Dim Start, if the light is Below this Brightness Level, the dim will Increase Brightness, otherwise it will Decreases Brightness | |
| selector: | |
| number: | |
| min: 0 | |
| max: 100 | |
| unit_of_measurement: '%' | |
| default: 50 | |
| button4_basic_actions: | |
| name: "Button 4 - Basic Actions" | |
| description: Configure basic button press actions | |
| icon: mdi:numeric-4-box | |
| collapsed: true | |
| input: | |
| button4_single: | |
| name: Single Short Press | |
| selector: | |
| action: {} | |
| default: [] | |
| button4_double: | |
| name: Double Short Press | |
| selector: | |
| action: {} | |
| default: [] | |
| button4_triple: | |
| name: Triple Short Press | |
| selector: | |
| action: {} | |
| default: [] | |
| button4_down: | |
| name: Button Down | |
| selector: | |
| action: {} | |
| default: [] | |
| button4_up: | |
| name: Button Up | |
| description: when Dimming Function enabled, this setting is ignored. | |
| selector: | |
| action: {} | |
| default: [] | |
| button4_long: | |
| name: Long Press | |
| description: when Dimming Function enabled, this setting is ignored. | |
| selector: | |
| action: {} | |
| default: [] | |
| button4_dim_settings: | |
| name: "Button 4 - Dimming Settings" | |
| description: Configure dimming functionality for long press | |
| icon: mdi:brightness-6 | |
| collapsed: true | |
| input: | |
| button4_dim_enabled: | |
| name: Enable Dim Function | |
| description: When enabled the above actions for Long Press and Button Up are Disabled | |
| selector: | |
| boolean: {} | |
| default: false | |
| button4_dim_target: | |
| name: Light Entity or Group you want to Dim | |
| selector: | |
| entity: | |
| domain: light | |
| default: "" | |
| button4_dim_step: | |
| name: Dim Step Percent | |
| description: Change light Brightness this amount per dim cycle. (1 to 50) | |
| selector: | |
| number: | |
| min: 1 | |
| max: 50 | |
| unit_of_measurement: '%' | |
| default: 14 | |
| button4_dim_delay: | |
| name: Dim Interval (seconds) | |
| description: Time between each dim cycle. (0.05 to 2.0) | |
| selector: | |
| number: | |
| min: 0.05 | |
| max: 2 | |
| unit_of_measurement: seconds | |
| default: 0.2 | |
| button4_transition: | |
| name: Transition Duration (seconds) | |
| description: Duration of brightness transition for each dim step. Set to 0.0 for Zigbee/Z-Wave lights to avoid latency blocking the dim loop. (0.0 to 2.0) | |
| selector: | |
| number: | |
| min: 0.0 | |
| max: 2.0 | |
| step: 0.05 | |
| unit_of_measurement: seconds | |
| default: 0.0 | |
| button4_boundary: | |
| name: Dim Boundary Percent | |
| description: At Dim Start, if the light is Below this Brightness Level, the dim will Increase Brightness, otherwise it will Decreases Brightness | |
| selector: | |
| number: | |
| min: 0 | |
| max: 100 | |
| unit_of_measurement: '%' | |
| default: 50 | |
| # ------------------------------------------------------------ | |
| # EXPERT SETTINGS | |
| # ------------------------------------------------------------ | |
| expert_settings: | |
| name: "Expert Settings" | |
| description: Advanced automation behavior settings. Only change these if you understand the implications. | |
| icon: mdi:tune | |
| collapsed: true | |
| input: | |
| mode_select: | |
| name: Execution Mode | |
| description: > | |
| Controls what happens when a new button event fires while the automation is already running. | |
| π Restart (default) β Stops any running instance and starts fresh. Required when using | |
| the Dimming Function β this is what stops the dim loop when you release the button (btn_up). | |
| Best for: setups using dimming on any button. | |
| βΈοΈ Single β Ignores new triggers while the automation is running. Useful if your button | |
| actions contain delays or multi-step sequences and you want to prevent them being | |
| interrupted by a second press. WARNING: incompatible with dimming β the dim loop will | |
| never stop because btn_up will be ignored while the loop is running. | |
| π Queued β New triggers wait in line and run after the current instance finishes. | |
| Useful if you want every press to be acted on, even rapid ones. WARNING: incompatible | |
| with dimming for the same reason as Single. | |
| β‘ Parallel β Every trigger starts a new independent instance simultaneously. Useful | |
| if buttons are truly independent and actions are fast fire-and-forget service calls | |
| with no delays. WARNING: incompatible with dimming β the dim loop will never stop. | |
| β οΈ If ANY button has Dimming enabled, you must use Restart. | |
| default: restart | |
| selector: | |
| select: | |
| options: | |
| - label: "π Restart β stops running instance; required for dimming (default)" | |
| value: restart | |
| - label: "βΈοΈ Single β ignores new triggers while running; no dimming" | |
| value: single | |
| - label: "π Queued β queues triggers to run in order; no dimming" | |
| value: queued | |
| - label: "β‘ Parallel β each trigger runs independently; no dimming" | |
| value: parallel | |
| debug_enabled: | |
| name: π Enable Debug Notifications | |
| description: Show combined trigger+action notifications for troubleshooting (disable after setup) | |
| selector: | |
| boolean: {} | |
| default: false | |
| mode: !input mode_select | |
| max_exceeded: silent | |
| trigger: | |
| # Button 1 Triggers | |
| - platform: event | |
| event_type: shelly.click | |
| event_data: | |
| device_id: !input shelly_device | |
| channel: 1 | |
| click_type: single_push | |
| id: btn1_single | |
| - platform: event | |
| event_type: shelly.click | |
| event_data: | |
| device_id: !input shelly_device | |
| channel: 1 | |
| click_type: double_push | |
| id: btn1_double | |
| - platform: event | |
| event_type: shelly.click | |
| event_data: | |
| device_id: !input shelly_device | |
| channel: 1 | |
| click_type: triple_push | |
| id: btn1_triple | |
| - platform: event | |
| event_type: shelly.click | |
| event_data: | |
| device_id: !input shelly_device | |
| channel: 1 | |
| click_type: btn_down | |
| id: btn1_down | |
| - platform: event | |
| event_type: shelly.click | |
| event_data: | |
| device_id: !input shelly_device | |
| channel: 1 | |
| click_type: btn_up | |
| id: btn1_up | |
| - platform: event | |
| event_type: shelly.click | |
| event_data: | |
| device_id: !input shelly_device | |
| channel: 1 | |
| click_type: long_push | |
| id: btn1_long | |
| # Button 2 Triggers | |
| - platform: event | |
| event_type: shelly.click | |
| event_data: | |
| device_id: !input shelly_device | |
| channel: 2 | |
| click_type: single_push | |
| id: btn2_single | |
| - platform: event | |
| event_type: shelly.click | |
| event_data: | |
| device_id: !input shelly_device | |
| channel: 2 | |
| click_type: double_push | |
| id: btn2_double | |
| - platform: event | |
| event_type: shelly.click | |
| event_data: | |
| device_id: !input shelly_device | |
| channel: 2 | |
| click_type: triple_push | |
| id: btn2_triple | |
| - platform: event | |
| event_type: shelly.click | |
| event_data: | |
| device_id: !input shelly_device | |
| channel: 2 | |
| click_type: btn_down | |
| id: btn2_down | |
| - platform: event | |
| event_type: shelly.click | |
| event_data: | |
| device_id: !input shelly_device | |
| channel: 2 | |
| click_type: btn_up | |
| id: btn2_up | |
| - platform: event | |
| event_type: shelly.click | |
| event_data: | |
| device_id: !input shelly_device | |
| channel: 2 | |
| click_type: long_push | |
| id: btn2_long | |
| # Button 3 Triggers | |
| - platform: event | |
| event_type: shelly.click | |
| event_data: | |
| device_id: !input shelly_device | |
| channel: 3 | |
| click_type: single_push | |
| id: btn3_single | |
| - platform: event | |
| event_type: shelly.click | |
| event_data: | |
| device_id: !input shelly_device | |
| channel: 3 | |
| click_type: double_push | |
| id: btn3_double | |
| - platform: event | |
| event_type: shelly.click | |
| event_data: | |
| device_id: !input shelly_device | |
| channel: 3 | |
| click_type: triple_push | |
| id: btn3_triple | |
| - platform: event | |
| event_type: shelly.click | |
| event_data: | |
| device_id: !input shelly_device | |
| channel: 3 | |
| click_type: btn_down | |
| id: btn3_down | |
| - platform: event | |
| event_type: shelly.click | |
| event_data: | |
| device_id: !input shelly_device | |
| channel: 3 | |
| click_type: btn_up | |
| id: btn3_up | |
| - platform: event | |
| event_type: shelly.click | |
| event_data: | |
| device_id: !input shelly_device | |
| channel: 3 | |
| click_type: long_push | |
| id: btn3_long | |
| # Button 4 Triggers | |
| - platform: event | |
| event_type: shelly.click | |
| event_data: | |
| device_id: !input shelly_device | |
| channel: 4 | |
| click_type: single_push | |
| id: btn4_single | |
| - platform: event | |
| event_type: shelly.click | |
| event_data: | |
| device_id: !input shelly_device | |
| channel: 4 | |
| click_type: double_push | |
| id: btn4_double | |
| - platform: event | |
| event_type: shelly.click | |
| event_data: | |
| device_id: !input shelly_device | |
| channel: 4 | |
| click_type: triple_push | |
| id: btn4_triple | |
| - platform: event | |
| event_type: shelly.click | |
| event_data: | |
| device_id: !input shelly_device | |
| channel: 4 | |
| click_type: btn_down | |
| id: btn4_down | |
| - platform: event | |
| event_type: shelly.click | |
| event_data: | |
| device_id: !input shelly_device | |
| channel: 4 | |
| click_type: btn_up | |
| id: btn4_up | |
| - platform: event | |
| event_type: shelly.click | |
| event_data: | |
| device_id: !input shelly_device | |
| channel: 4 | |
| click_type: long_push | |
| id: btn4_long | |
| variables: | |
| # OPT: debug_enabled and dim settings resolved once at trigger time, not re-evaluated per condition | |
| debug_enabled: !input debug_enabled | |
| trigger_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| dimming_active: false | |
| button1_dim_enabled: !input button1_dim_enabled | |
| button1_dim_target: !input button1_dim_target | |
| button1_dim_step: !input button1_dim_step | |
| button1_dim_delay: !input button1_dim_delay | |
| button1_transition: !input button1_transition | |
| button1_boundary: !input button1_boundary | |
| button2_dim_enabled: !input button2_dim_enabled | |
| button2_dim_target: !input button2_dim_target | |
| button2_dim_step: !input button2_dim_step | |
| button2_dim_delay: !input button2_dim_delay | |
| button2_transition: !input button2_transition | |
| button2_boundary: !input button2_boundary | |
| button3_dim_enabled: !input button3_dim_enabled | |
| button3_dim_target: !input button3_dim_target | |
| button3_dim_step: !input button3_dim_step | |
| button3_dim_delay: !input button3_dim_delay | |
| button3_transition: !input button3_transition | |
| button3_boundary: !input button3_boundary | |
| button4_dim_enabled: !input button4_dim_enabled | |
| button4_dim_target: !input button4_dim_target | |
| button4_dim_step: !input button4_dim_step | |
| button4_dim_delay: !input button4_dim_delay | |
| button4_transition: !input button4_transition | |
| button4_boundary: !input button4_boundary | |
| action: | |
| - choose: | |
| # ========== BUTTON 1 ========== | |
| - conditions: | |
| - condition: trigger | |
| id: btn1_single | |
| sequence: | |
| - choose: [] | |
| default: !input button1_single | |
| - if: | |
| # OPT: simplified boolean template (was: debug_enabled == true) | |
| - condition: template | |
| value_template: "{{ debug_enabled }}" | |
| then: | |
| - variables: | |
| action_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| - service: persistent_notification.create | |
| data: | |
| title: "π Button 1 Single" | |
| message: "β‘ Trigger: {{ trigger_time }} | π₯ Action: {{ action_time }}" | |
| notification_id: "shelly_btn1_single_{{ action_time }}" | |
| - conditions: | |
| - condition: trigger | |
| id: btn1_double | |
| sequence: | |
| - choose: [] | |
| default: !input button1_double | |
| - if: | |
| - condition: template | |
| value_template: "{{ debug_enabled }}" | |
| then: | |
| - variables: | |
| action_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| - service: persistent_notification.create | |
| data: | |
| title: "π Button 1 Double" | |
| message: "β‘ Trigger: {{ trigger_time }} | π₯ Action: {{ action_time }}" | |
| notification_id: "shelly_btn1_double_{{ action_time }}" | |
| - conditions: | |
| - condition: trigger | |
| id: btn1_triple | |
| sequence: | |
| - choose: [] | |
| default: !input button1_triple | |
| - if: | |
| - condition: template | |
| value_template: "{{ debug_enabled }}" | |
| then: | |
| - variables: | |
| action_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| - service: persistent_notification.create | |
| data: | |
| title: "π Button 1 Triple" | |
| message: "β‘ Trigger: {{ trigger_time }} | π₯ Action: {{ action_time }}" | |
| notification_id: "shelly_btn1_triple_{{ action_time }}" | |
| - conditions: | |
| - condition: trigger | |
| id: btn1_down | |
| sequence: | |
| - if: | |
| - condition: template | |
| value_template: "{{ not button1_dim_enabled }}" | |
| then: | |
| - choose: [] | |
| default: !input button1_down | |
| - if: | |
| - condition: template | |
| value_template: "{{ debug_enabled }}" | |
| then: | |
| - variables: | |
| action_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| - service: persistent_notification.create | |
| data: | |
| title: "π Button 1 Down" | |
| message: "β‘ Trigger: {{ trigger_time }} | π₯ Action: {{ action_time }}" | |
| notification_id: "shelly_btn1_down_{{ action_time }}" | |
| - conditions: | |
| - condition: trigger | |
| id: btn1_up | |
| sequence: | |
| # dimming_active: false is always set β this is what signals the loop to stop via mode: restart. | |
| # The user action is guarded so it only fires when dimming is NOT enabled. | |
| - variables: | |
| dimming_active: false | |
| - if: | |
| - condition: template | |
| value_template: "{{ not button1_dim_enabled }}" | |
| then: | |
| - choose: [] | |
| default: !input button1_up | |
| - if: | |
| - condition: template | |
| value_template: "{{ debug_enabled }}" | |
| then: | |
| - variables: | |
| action_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| - service: persistent_notification.create | |
| data: | |
| title: "π Button 1 Up" | |
| message: "β‘ Trigger: {{ trigger_time }} | π₯ Action: {{ action_time }}" | |
| notification_id: "shelly_btn1_up_{{ action_time }}" | |
| - conditions: | |
| - condition: trigger | |
| id: btn1_long | |
| sequence: | |
| - if: | |
| # OPT: merged two separate condition checks into a single template | |
| - condition: template | |
| value_template: "{{ button1_dim_enabled and button1_dim_target is defined and button1_dim_target != '' }}" | |
| then: | |
| - if: | |
| - condition: template | |
| value_template: "{{ debug_enabled }}" | |
| then: | |
| - variables: | |
| dim_start_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| - service: persistent_notification.create | |
| data: | |
| title: "π DIMMING START - Button 1" | |
| message: "β‘ Trigger: {{ trigger_time }} | π‘ Dim Start: {{ dim_start_time }}" | |
| notification_id: "shelly_dim_start_btn1_{{ dim_start_time }}" | |
| - if: | |
| - condition: template | |
| value_template: "{{ is_state(button1_dim_target, 'off') }}" | |
| then: | |
| - service: light.turn_on | |
| target: | |
| entity_id: "{{ button1_dim_target }}" | |
| # OPT: merged two variables blocks into one | |
| - variables: | |
| current_brightness: "{{ state_attr(button1_dim_target, 'brightness') | default(255) }}" | |
| start_pct: "{{ (current_brightness | int / 255 * 100) | round(0) }}" | |
| brightness_step_value: "{{ (button1_dim_step | float / 100 * 255) | round(0) }}" | |
| button1_dim_direction: "{{ '+' if start_pct < button1_boundary else '-' }}" | |
| dimming_active: true | |
| - repeat: | |
| while: | |
| - condition: template | |
| value_template: "{{ dimming_active }}" | |
| sequence: | |
| - if: | |
| - condition: template | |
| value_template: "{{ debug_enabled }}" | |
| then: | |
| - variables: | |
| loop_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| loop_count: "{{ repeat.index }}" | |
| - service: persistent_notification.create | |
| data: | |
| title: "π DIM CYCLE - Button 1" | |
| message: "β° {{ loop_time }} | #{{ loop_count }}" | |
| notification_id: "shelly_cycle_btn1_{{ loop_count }}_{{ loop_time }}" | |
| - service: light.turn_on | |
| target: | |
| entity_id: "{{ button1_dim_target }}" | |
| data: | |
| brightness_step: "{{ button1_dim_direction }}{{ brightness_step_value }}" | |
| transition: "{{ button1_transition }}" | |
| - delay: | |
| seconds: "{{ button1_dim_delay }}" | |
| else: | |
| - choose: [] | |
| default: !input button1_long | |
| - if: | |
| - condition: template | |
| value_template: "{{ debug_enabled }}" | |
| then: | |
| - variables: | |
| action_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| - service: persistent_notification.create | |
| data: | |
| title: "π Button 1 Long" | |
| message: "β‘ Trigger: {{ trigger_time }} | π₯ Action: {{ action_time }}" | |
| notification_id: "shelly_btn1_long_{{ action_time }}" | |
| # ========== BUTTON 2 ========== | |
| - conditions: | |
| - condition: trigger | |
| id: btn2_single | |
| sequence: | |
| - choose: [] | |
| default: !input button2_single | |
| - if: | |
| - condition: template | |
| value_template: "{{ debug_enabled }}" | |
| then: | |
| - variables: | |
| action_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| - service: persistent_notification.create | |
| data: | |
| title: "π Button 2 Single" | |
| message: "β‘ Trigger: {{ trigger_time }} | π₯ Action: {{ action_time }}" | |
| notification_id: "shelly_btn2_single_{{ action_time }}" | |
| - conditions: | |
| - condition: trigger | |
| id: btn2_double | |
| sequence: | |
| - choose: [] | |
| default: !input button2_double | |
| - if: | |
| - condition: template | |
| value_template: "{{ debug_enabled }}" | |
| then: | |
| - variables: | |
| action_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| - service: persistent_notification.create | |
| data: | |
| title: "π Button 2 Double" | |
| message: "β‘ Trigger: {{ trigger_time }} | π₯ Action: {{ action_time }}" | |
| notification_id: "shelly_btn2_double_{{ action_time }}" | |
| - conditions: | |
| - condition: trigger | |
| id: btn2_triple | |
| sequence: | |
| - choose: [] | |
| default: !input button2_triple | |
| - if: | |
| - condition: template | |
| value_template: "{{ debug_enabled }}" | |
| then: | |
| - variables: | |
| action_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| - service: persistent_notification.create | |
| data: | |
| title: "π Button 2 Triple" | |
| message: "β‘ Trigger: {{ trigger_time }} | π₯ Action: {{ action_time }}" | |
| notification_id: "shelly_btn2_triple_{{ action_time }}" | |
| - conditions: | |
| - condition: trigger | |
| id: btn2_down | |
| sequence: | |
| - if: | |
| - condition: template | |
| value_template: "{{ not button2_dim_enabled }}" | |
| then: | |
| - choose: [] | |
| default: !input button2_down | |
| - if: | |
| - condition: template | |
| value_template: "{{ debug_enabled }}" | |
| then: | |
| - variables: | |
| action_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| - service: persistent_notification.create | |
| data: | |
| title: "π Button 2 Down" | |
| message: "β‘ Trigger: {{ trigger_time }} | π₯ Action: {{ action_time }}" | |
| notification_id: "shelly_btn2_down_{{ action_time }}" | |
| - conditions: | |
| - condition: trigger | |
| id: btn2_up | |
| sequence: | |
| - variables: | |
| dimming_active: false | |
| - if: | |
| - condition: template | |
| value_template: "{{ not button2_dim_enabled }}" | |
| then: | |
| - choose: [] | |
| default: !input button2_up | |
| - if: | |
| - condition: template | |
| value_template: "{{ debug_enabled }}" | |
| then: | |
| - variables: | |
| action_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| - service: persistent_notification.create | |
| data: | |
| title: "π Button 2 Up" | |
| message: "β‘ Trigger: {{ trigger_time }} | π₯ Action: {{ action_time }}" | |
| notification_id: "shelly_btn2_up_{{ action_time }}" | |
| - conditions: | |
| - condition: trigger | |
| id: btn2_long | |
| sequence: | |
| - if: | |
| - condition: template | |
| value_template: "{{ button2_dim_enabled and button2_dim_target is defined and button2_dim_target != '' }}" | |
| then: | |
| - if: | |
| - condition: template | |
| value_template: "{{ is_state(button2_dim_target, 'off') }}" | |
| then: | |
| - service: light.turn_on | |
| target: | |
| entity_id: "{{ button2_dim_target }}" | |
| # OPT: merged two variables blocks into one | |
| - variables: | |
| current_brightness: "{{ state_attr(button2_dim_target, 'brightness') | default(255) }}" | |
| start_pct: "{{ (current_brightness | int / 255 * 100) | round(0) }}" | |
| brightness_step_value: "{{ (button2_dim_step | float / 100 * 255) | round(0) }}" | |
| button2_dim_direction: "{{ '+' if start_pct < button2_boundary else '-' }}" | |
| dimming_active: true | |
| - repeat: | |
| while: | |
| - condition: template | |
| value_template: "{{ dimming_active }}" | |
| sequence: | |
| - service: light.turn_on | |
| target: | |
| entity_id: "{{ button2_dim_target }}" | |
| data: | |
| brightness_step: "{{ button2_dim_direction }}{{ brightness_step_value }}" | |
| transition: "{{ button2_transition }}" | |
| - delay: | |
| seconds: "{{ button2_dim_delay }}" | |
| else: | |
| - choose: [] | |
| default: !input button2_long | |
| - if: | |
| - condition: template | |
| value_template: "{{ debug_enabled }}" | |
| then: | |
| - variables: | |
| action_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| - service: persistent_notification.create | |
| data: | |
| title: "π Button 2 Long" | |
| message: "β‘ Trigger: {{ trigger_time }} | π₯ Action: {{ action_time }}" | |
| notification_id: "shelly_btn2_long_{{ action_time }}" | |
| # ========== BUTTON 3 ========== | |
| - conditions: | |
| - condition: trigger | |
| id: btn3_single | |
| sequence: | |
| - choose: [] | |
| default: !input button3_single | |
| - if: | |
| - condition: template | |
| value_template: "{{ debug_enabled }}" | |
| then: | |
| - variables: | |
| action_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| - service: persistent_notification.create | |
| data: | |
| title: "π Button 3 Single" | |
| message: "β‘ Trigger: {{ trigger_time }} | π₯ Action: {{ action_time }}" | |
| notification_id: "shelly_btn3_single_{{ action_time }}" | |
| - conditions: | |
| - condition: trigger | |
| id: btn3_double | |
| sequence: | |
| - choose: [] | |
| default: !input button3_double | |
| - if: | |
| - condition: template | |
| value_template: "{{ debug_enabled }}" | |
| then: | |
| - variables: | |
| action_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| - service: persistent_notification.create | |
| data: | |
| title: "π Button 3 Double" | |
| message: "β‘ Trigger: {{ trigger_time }} | π₯ Action: {{ action_time }}" | |
| notification_id: "shelly_btn3_double_{{ action_time }}" | |
| - conditions: | |
| - condition: trigger | |
| id: btn3_triple | |
| sequence: | |
| - choose: [] | |
| default: !input button3_triple | |
| - if: | |
| - condition: template | |
| value_template: "{{ debug_enabled }}" | |
| then: | |
| - variables: | |
| action_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| - service: persistent_notification.create | |
| data: | |
| title: "π Button 3 Triple" | |
| message: "β‘ Trigger: {{ trigger_time }} | π₯ Action: {{ action_time }}" | |
| notification_id: "shelly_btn3_triple_{{ action_time }}" | |
| - conditions: | |
| - condition: trigger | |
| id: btn3_down | |
| sequence: | |
| - if: | |
| - condition: template | |
| value_template: "{{ not button3_dim_enabled }}" | |
| then: | |
| - choose: [] | |
| default: !input button3_down | |
| - if: | |
| - condition: template | |
| value_template: "{{ debug_enabled }}" | |
| then: | |
| - variables: | |
| action_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| - service: persistent_notification.create | |
| data: | |
| title: "π Button 3 Down" | |
| message: "β‘ Trigger: {{ trigger_time }} | π₯ Action: {{ action_time }}" | |
| notification_id: "shelly_btn3_down_{{ action_time }}" | |
| - conditions: | |
| - condition: trigger | |
| id: btn3_up | |
| sequence: | |
| - variables: | |
| dimming_active: false | |
| - if: | |
| - condition: template | |
| value_template: "{{ not button3_dim_enabled }}" | |
| then: | |
| - choose: [] | |
| default: !input button3_up | |
| - if: | |
| - condition: template | |
| value_template: "{{ debug_enabled }}" | |
| then: | |
| - variables: | |
| action_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| - service: persistent_notification.create | |
| data: | |
| title: "π Button 3 Up" | |
| message: "β‘ Trigger: {{ trigger_time }} | π₯ Action: {{ action_time }}" | |
| notification_id: "shelly_btn3_up_{{ action_time }}" | |
| - conditions: | |
| - condition: trigger | |
| id: btn3_long | |
| sequence: | |
| - if: | |
| - condition: template | |
| value_template: "{{ button3_dim_enabled and button3_dim_target is defined and button3_dim_target != '' }}" | |
| then: | |
| - if: | |
| - condition: template | |
| value_template: "{{ is_state(button3_dim_target, 'off') }}" | |
| then: | |
| - service: light.turn_on | |
| target: | |
| entity_id: "{{ button3_dim_target }}" | |
| # OPT: merged two variables blocks into one | |
| - variables: | |
| current_brightness: "{{ state_attr(button3_dim_target, 'brightness') | default(255) }}" | |
| start_pct: "{{ (current_brightness | int / 255 * 100) | round(0) }}" | |
| brightness_step_value: "{{ (button3_dim_step | float / 100 * 255) | round(0) }}" | |
| button3_dim_direction: "{{ '+' if start_pct < button3_boundary else '-' }}" | |
| dimming_active: true | |
| - repeat: | |
| while: | |
| - condition: template | |
| value_template: "{{ dimming_active }}" | |
| sequence: | |
| - service: light.turn_on | |
| target: | |
| entity_id: "{{ button3_dim_target }}" | |
| data: | |
| brightness_step: "{{ button3_dim_direction }}{{ brightness_step_value }}" | |
| transition: "{{ button3_transition }}" | |
| - delay: | |
| seconds: "{{ button3_dim_delay }}" | |
| else: | |
| - choose: [] | |
| default: !input button3_long | |
| - if: | |
| - condition: template | |
| value_template: "{{ debug_enabled }}" | |
| then: | |
| - variables: | |
| action_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| - service: persistent_notification.create | |
| data: | |
| title: "π Button 3 Long" | |
| message: "β‘ Trigger: {{ trigger_time }} | π₯ Action: {{ action_time }}" | |
| notification_id: "shelly_btn3_long_{{ action_time }}" | |
| # ========== BUTTON 4 ========== | |
| - conditions: | |
| - condition: trigger | |
| id: btn4_single | |
| sequence: | |
| - choose: [] | |
| default: !input button4_single | |
| - if: | |
| - condition: template | |
| value_template: "{{ debug_enabled }}" | |
| then: | |
| - variables: | |
| action_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| - service: persistent_notification.create | |
| data: | |
| title: "π Button 4 Single" | |
| message: "β‘ Trigger: {{ trigger_time }} | π₯ Action: {{ action_time }}" | |
| notification_id: "shelly_btn4_single_{{ action_time }}" | |
| - conditions: | |
| - condition: trigger | |
| id: btn4_double | |
| sequence: | |
| - choose: [] | |
| default: !input button4_double | |
| - if: | |
| - condition: template | |
| value_template: "{{ debug_enabled }}" | |
| then: | |
| - variables: | |
| action_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| - service: persistent_notification.create | |
| data: | |
| title: "π Button 4 Double" | |
| message: "β‘ Trigger: {{ trigger_time }} | π₯ Action: {{ action_time }}" | |
| notification_id: "shelly_btn4_double_{{ action_time }}" | |
| - conditions: | |
| - condition: trigger | |
| id: btn4_triple | |
| sequence: | |
| - choose: [] | |
| default: !input button4_triple | |
| - if: | |
| - condition: template | |
| value_template: "{{ debug_enabled }}" | |
| then: | |
| - variables: | |
| action_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| - service: persistent_notification.create | |
| data: | |
| title: "π Button 4 Triple" | |
| message: "β‘ Trigger: {{ trigger_time }} | π₯ Action: {{ action_time }}" | |
| notification_id: "shelly_btn4_triple_{{ action_time }}" | |
| - conditions: | |
| - condition: trigger | |
| id: btn4_down | |
| sequence: | |
| - if: | |
| - condition: template | |
| value_template: "{{ not button4_dim_enabled }}" | |
| then: | |
| - choose: [] | |
| default: !input button4_down | |
| - if: | |
| - condition: template | |
| value_template: "{{ debug_enabled }}" | |
| then: | |
| - variables: | |
| action_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| - service: persistent_notification.create | |
| data: | |
| title: "π Button 4 Down" | |
| message: "β‘ Trigger: {{ trigger_time }} | π₯ Action: {{ action_time }}" | |
| notification_id: "shelly_btn4_down_{{ action_time }}" | |
| - conditions: | |
| - condition: trigger | |
| id: btn4_up | |
| sequence: | |
| - variables: | |
| dimming_active: false | |
| - if: | |
| - condition: template | |
| value_template: "{{ not button4_dim_enabled }}" | |
| then: | |
| - choose: [] | |
| default: !input button4_up | |
| - if: | |
| - condition: template | |
| value_template: "{{ debug_enabled }}" | |
| then: | |
| - variables: | |
| action_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| - service: persistent_notification.create | |
| data: | |
| title: "π Button 4 Up" | |
| message: "β‘ Trigger: {{ trigger_time }} | π₯ Action: {{ action_time }}" | |
| notification_id: "shelly_btn4_up_{{ action_time }}" | |
| - conditions: | |
| - condition: trigger | |
| id: btn4_long | |
| sequence: | |
| - if: | |
| - condition: template | |
| value_template: "{{ button4_dim_enabled and button4_dim_target is defined and button4_dim_target != '' }}" | |
| then: | |
| - if: | |
| - condition: template | |
| value_template: "{{ is_state(button4_dim_target, 'off') }}" | |
| then: | |
| - service: light.turn_on | |
| target: | |
| entity_id: "{{ button4_dim_target }}" | |
| # OPT: merged two variables blocks into one | |
| - variables: | |
| current_brightness: "{{ state_attr(button4_dim_target, 'brightness') | default(255) }}" | |
| start_pct: "{{ (current_brightness | int / 255 * 100) | round(0) }}" | |
| brightness_step_value: "{{ (button4_dim_step | float / 100 * 255) | round(0) }}" | |
| button4_dim_direction: "{{ '+' if start_pct < button4_boundary else '-' }}" | |
| dimming_active: true | |
| - repeat: | |
| while: | |
| - condition: template | |
| value_template: "{{ dimming_active }}" | |
| sequence: | |
| - service: light.turn_on | |
| target: | |
| entity_id: "{{ button4_dim_target }}" | |
| data: | |
| brightness_step: "{{ button4_dim_direction }}{{ brightness_step_value }}" | |
| transition: "{{ button4_transition }}" | |
| - delay: | |
| seconds: "{{ button4_dim_delay }}" | |
| else: | |
| - choose: [] | |
| default: !input button4_long | |
| - if: | |
| - condition: template | |
| value_template: "{{ debug_enabled }}" | |
| then: | |
| - variables: | |
| action_time: "{{ now().strftime('%H:%M:%S.%f')[:-3] }}" | |
| - service: persistent_notification.create | |
| data: | |
| title: "π Button 4 Long" | |
| message: "β‘ Trigger: {{ trigger_time }} | π₯ Action: {{ action_time }}" | |
| notification_id: "shelly_btn4_long_{{ action_time }}" |
Comments are disabled for this gist.