Last active
January 3, 2026 20:52
-
-
Save MartinNuc/dd641782e1dacc5433353bbff9f4e802 to your computer and use it in GitHub Desktop.
Adaptive Hue Wall Switch Scene Cycler for Home Assistant
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: Adaptive Hue Wall Switch Scene Cycler | |
| description: | | |
| ### 💡 How it works: | |
| 1. **First press (Lights Off):** Activates the scene assigned to the current time. | |
| 2. **Subsequent presses (within 3s):** Cycles to the next defined scene. | |
| 3. **Long delay press (Lights On > 3s):** Turns the lights off. | |
| ### 🛠 Requirement: | |
| You must create an **input_number** helper for each automation instance to store the current scene index. | |
| * **Min:** 0 | |
| * **Max:** 10 | |
| * **Step:** 1 | |
| domain: automation | |
| input: | |
| hue_device: | |
| name: Hue Wall Switch Device | |
| description: The Hue Wall Switch Module to use as a trigger. | |
| selector: | |
| device: | |
| integration: hue | |
| button_subtype: | |
| name: Button Number | |
| description: Select which button on the device to use (1 or 2). | |
| default: 1 | |
| selector: | |
| number: | |
| min: 1 | |
| max: 2 | |
| light_target: | |
| name: Lights to Control | |
| description: The lights or light group to be controlled by the scenes. | |
| selector: | |
| target: | |
| entity: | |
| domain: light | |
| scene_helper: | |
| name: Scene Index Helper | |
| description: An input_number helper used to remember which scene is active. | |
| selector: | |
| entity: | |
| domain: input_number | |
| # Scene Configuration | |
| scene_1: | |
| name: Scene 1 | |
| selector: | |
| entity: | |
| domain: scene | |
| scene_1_start: | |
| name: Scene 1 Start Time | |
| default: "06:00:00" | |
| selector: | |
| time: {} | |
| scene_2: | |
| name: Scene 2 | |
| selector: | |
| entity: | |
| domain: scene | |
| scene_2_start: | |
| name: Scene 2 Start Time | |
| default: "09:00:00" | |
| selector: | |
| time: {} | |
| scene_3: | |
| name: Scene 3 | |
| selector: | |
| entity: | |
| domain: scene | |
| scene_3_start: | |
| name: Scene 3 Start Time | |
| default: "18:00:00" | |
| selector: | |
| time: {} | |
| scene_4: | |
| name: Scene 4 | |
| default: "" | |
| selector: | |
| entity: | |
| domain: scene | |
| scene_4_start: | |
| name: Scene 4 Start Time | |
| default: "22:00:00" | |
| selector: | |
| time: {} | |
| mode: restart | |
| trigger: | |
| - platform: event | |
| event_type: hue_event | |
| event_data: | |
| device_id: !input hue_device | |
| type: initial_press | |
| subtype: !input button_subtype | |
| action: | |
| - variables: | |
| helper: !input scene_helper | |
| light_target: !input light_target | |
| # Robustly identify the first light to check state | |
| first_light: > | |
| {% set ent = light_target.entity_id %} | |
| {% if ent is string %} {{ ent }} | |
| {% elif ent is sequence %} {{ ent[0] }} | |
| {% else %} none {% endif %} | |
| # Map and Filter active scenes | |
| all_configs: | |
| - {"scene": !input scene_1, "time": !input scene_1_start} | |
| - {"scene": !input scene_2, "time": !input scene_2_start} | |
| - {"scene": !input scene_3, "time": !input scene_3_start} | |
| - {"scene": !input scene_4, "time": !input scene_4_start} | |
| active_scenes: > | |
| {% set filtered = namespace(items=[]) %} | |
| {% for item in all_configs %} | |
| {% if item.scene != "" and item.scene != none and item.scene != 'none' %} | |
| {% set filtered.items = filtered.items + [item] %} | |
| {% endif %} | |
| {% endfor %} | |
| {{ filtered.items }} | |
| # Calculate the time-based starting index | |
| time_idx: > | |
| {% set t = now().strftime('%H:%M:%S') %} | |
| {% set count = active_scenes | count %} | |
| {% set res = namespace(idx=0) %} | |
| {% for i in range(count) %} | |
| {% if t >= active_scenes[i].time %}{% set res.idx = i %}{% endif %} | |
| {% endfor %} | |
| {% if t < active_scenes[0].time %}{% set res.idx = count - 1 %}{% endif %} | |
| {{ res.idx }} | |
| - choose: | |
| # --- BRANCH 1: SMART OFF --- | |
| # If light is on and has been stable for more than 3 seconds | |
| - conditions: | |
| - condition: template | |
| value_template: > | |
| {{ is_state(first_light, 'on') and | |
| (as_timestamp(now()) - as_timestamp(states[first_light].last_changed) > 3) }} | |
| sequence: | |
| - action: light.turn_off | |
| target: !input light_target | |
| # --- BRANCH 2: ACTIVATE / CYCLE --- | |
| - conditions: | |
| - condition: template | |
| value_template: "{{ active_scenes | count > 0 }}" | |
| sequence: | |
| - variables: | |
| new_idx: > | |
| {% if is_state(first_light, 'off') %} | |
| {{ time_idx | int }} | |
| {% else %} | |
| {{ (states(helper) | int + 1) % (active_scenes | count) }} | |
| {% endif %} | |
| # Store the index in the helper | |
| - action: input_number.set_value | |
| target: | |
| entity_id: !input scene_helper | |
| data: | |
| value: "{{ new_idx }}" | |
| # Trigger the scene | |
| - action: scene.turn_on | |
| target: | |
| entity_id: "{{ active_scenes[new_idx | int].scene }}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment