# Time of Day Selector Blueprint # Event-driven: sets an input_select when any configured time entity fires. # See README.md for detailed documentation. # # Author: Alexei Dolgolyov (dolgolyov.alexei@gmail.com) blueprint: name: "Custom: Time of Day Selector" description: > Event-driven time-of-day state machine. Maps a list of time entities to a parallel list of state names. When any time entity fires, the corresponding state is selected on the target input_select. Multiple entities mapping to the same state name produce OR-override behavior (e.g. sun_next_dusk OR a forced input_datetime — whichever fires first wins). domain: automation input: # ------------------------------------------------------------------------- # Output Configuration # ------------------------------------------------------------------------- tod_select: name: Time of Day Selector description: > The input_select entity whose option will be updated. Its options must include every state name listed below. selector: entity: domain: input_select # ------------------------------------------------------------------------- # Trigger / State Mapping # ------------------------------------------------------------------------- tod_times: name: Time of Day Triggers description: > Ordered list of time entities. Each fires when its configured time is reached. Accepts input_datetime (time-only) and timestamp sensors (e.g. sensor.sun_next_rising, sensor.sun_next_dusk). selector: entity: domain: - input_datetime - sensor multiple: true tod_states: name: Time of Day States description: > Parallel list of state names — one entry for each trigger above, in the same order. Each name must match an option of the target input_select exactly. Repeat a name to give that state multiple trigger sources (override / "whichever fires first" pattern). selector: text: multiple: true # ------------------------------------------------------------------------- # Debug # ------------------------------------------------------------------------- is_debug: name: Debug mode description: > When enabled, posts a persistent notification on each fire showing the firing entity, resolved state, and previous state. default: false selector: boolean: # Single mode is sufficient: select_option is idempotent and trigger collisions # are extremely rare (different time entities reaching the same instant). mode: single # ============================================================================= # Triggers # ============================================================================= trigger: - platform: time at: !input tod_times # ============================================================================= # Variables # ============================================================================= variables: tod_select: !input tod_select tod_times: !input tod_times tod_states: !input tod_states is_debug: !input is_debug # Index of the entity that fired, within tod_times. -1 if not found. fired_index: > {% set ns = namespace(idx=-1) %} {% for e in tod_times %} {% if e == trigger.entity_id %} {% set ns.idx = loop.index0 %} {% endif %} {% endfor %} {{ ns.idx }} # State name resolved from the firing entity. Empty if lookup failed # (e.g. mismatched list lengths or unknown trigger entity). target_state: > {%- if fired_index >= 0 and fired_index < tod_states | length -%} {{ tod_states[fired_index] }} {%- endif -%} previous_state: "{{ states(tod_select) }}" # ============================================================================= # Condition - Only proceed if a valid state was resolved and it differs # ============================================================================= condition: - condition: template value_template: "{{ target_state | length > 0 and target_state != previous_state }}" # ============================================================================= # Actions # ============================================================================= action: # --------------------------------------------------------------------------- # Debug Logging (optional) # --------------------------------------------------------------------------- - choose: - conditions: - condition: template value_template: "{{ is_debug }}" sequence: - service: persistent_notification.create data: title: "Time of Day Selector" message: > Fired entity: {{ trigger.entity_id }} Index in triggers list: {{ fired_index }} Previous state: {{ previous_state }} Target state: {{ target_state }} # --------------------------------------------------------------------------- # Update Time of Day State # --------------------------------------------------------------------------- - service: input_select.select_option target: entity_id: "{{ tod_select }}" data: option: "{{ target_state }}"