feat: add Presence Scene Controller and Time Of Day Selector blueprints
- 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
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
# Time of Day Selector Blueprint
|
||||
|
||||
Event-driven blueprint that updates an `input_select` based on a list of time triggers. Each trigger entity is mapped to a state name; when the trigger fires, the matching state becomes active.
|
||||
|
||||
This is a sibling to the [Time Of Day Controller](../Time%20Of%20Day%20Controller/README.md) blueprint, which uses minute-by-minute polling and threshold comparison. Use this one when you want exact event-based firing and the ability to attach multiple trigger sources (e.g. a sun event **or** a manual forced time) to the same state.
|
||||
|
||||
## How It Works
|
||||
|
||||
- Define a list of **time triggers** — `input_datetime` helpers and/or timestamp sensors such as `sensor.sun_next_rising` / `sensor.sun_next_dusk` / `sensor.sun_next_midnight`.
|
||||
- Define a parallel list of **state names** — one per trigger, in the same order.
|
||||
- When any trigger fires, the blueprint looks up the firing entity in the trigger list and selects the matching state name on the target `input_select`.
|
||||
- Duplicate state names produce **OR-override** behavior: whichever associated trigger fires first wins.
|
||||
|
||||
## Index Mapping
|
||||
|
||||
The two lists are matched by position:
|
||||
|
||||
| Index | Trigger entity | State name |
|
||||
|-------|---------------|------------|
|
||||
| 0 | `sensor.sun_next_rising` | `Утро` |
|
||||
| 1 | `input_datetime.dnevnoe_vremia` | `День` |
|
||||
| 2 | `sensor.sun_next_dusk` | `Вечер` |
|
||||
| 3 | `input_datetime.vechernee_vremia_prinuditelno` | `Вечер` |
|
||||
| 4 | `sensor.sun_next_midnight` | `Ночь` |
|
||||
| 5 | `input_datetime.polnochnoe_vremia_prinuditelno` | `Ночь` |
|
||||
|
||||
In this example, `Вечер` is set when either the natural dusk time or the forced datetime fires — whichever comes first.
|
||||
|
||||
## Supported Time Sources
|
||||
|
||||
- `input_datetime` entities (time-only: `HH:MM:SS`).
|
||||
- Timestamp sensors that report an ISO datetime (e.g. `sensor.sun_next_rising`).
|
||||
|
||||
## Configuration
|
||||
|
||||
| Input | Description |
|
||||
|-------|-------------|
|
||||
| **Time of Day Selector** | The `input_select` entity to update. Its options must include every state name in the list below. |
|
||||
| **Time of Day Triggers** | Ordered list of trigger entities. |
|
||||
| **Time of Day States** | Parallel list of state names, same length as triggers. |
|
||||
| **Debug mode** | When enabled, posts a persistent notification on each fire with the firing entity, resolved state, and previous state. |
|
||||
|
||||
## Behavioral Notes
|
||||
|
||||
- `input_select.select_option` is idempotent — repeated triggers for the same state cause no extra state changes.
|
||||
- A guard condition skips the action if the resolved state already matches the current `input_select` value.
|
||||
- On Home Assistant restart, the state is **not** retroactively corrected — it updates on the next trigger. If you need self-correcting state on restart, use the [Time Of Day Controller](../Time%20Of%20Day%20Controller/README.md) (polling) blueprint instead.
|
||||
|
||||
## Author
|
||||
|
||||
Alexei Dolgolyov (dolgolyov.alexei@gmail.com)
|
||||
@@ -0,0 +1,147 @@
|
||||
# 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 }}"
|
||||
Reference in New Issue
Block a user