fafcf116be
- Presence Scene Controller: per-room presence-aware time-of-day scenes with vacant/sleep scenes and Motion Light coexistence - Time Of Day Selector: event-driven state machine that sets an input_select when a configured time entity fires - List both blueprints in the root README - Bump version to 2.13.0
148 lines
5.3 KiB
YAML
148 lines
5.3 KiB
YAML
# 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 }}"
|