Skip to content

Instantly share code, notes, and snippets.

@ql-owo-lp
Last active December 2, 2023 07:45
Show Gist options
  • Save ql-owo-lp/bf76710d34efa925b4161ee7c6efd021 to your computer and use it in GitHub Desktop.
Save ql-owo-lp/bf76710d34efa925b4161ee7c6efd021 to your computer and use it in GitHub Desktop.
blueprint:
name: State Based Entity Control2
description: Change the target entity to desired entity state base on the trigger entity's state, illuminance sensor's state, Sun elevation and so on.
domain: automation
input:
trigger_entities:
name: Trigger Entities
selector:
entity:
multiple: true
trigger_conditions_on:
name: Conditions for "On"
description: These will trigger the "on" actions.
selector:
condition:
trigger_conditions_off:
name: (Optional) Trigger Condition - Off
description: >-
When these conditions are met,
try to change the target entity's state to desired state with target
entity's turn off action (defined below).
If this value is left empty, then any states that is not "Trigger Entity States"
defined above will trigger the turn off action.
This value supports regular expression,
i.e. you can list multiple values as "state_1|state_2|state_3".
default:
selector:
condition:
target_entities:
name: Target Entity
description: Any entity that can be operated with below action.
selector:
target:
target_conditions_on:
name: (Optional) Target Entity Desired State
description: >-
When the target entity state is of this value,
the target entity is considered turned on.
When this value is set to 'none', the automation
will be triggered only based on trigger entity's state,
which means target entity won't be turned off if it's
manually turned on.
This value supports regular expression,
i.e. you can list multiple values as "state_1|state_2|state_3".
default:
selector:
condition:
target_conditions_off:
name: (Optional) Turn Off Target Entity
description: >-
If set, instead of the original "Target Entity", this entity will be
turned off with the "Turn off action" defined below.
This is usually helpful when the "Target Entity" is a scene. Then here
you want to put another scene to revert the applied scene.
default:
selector:
condition:
actions_on:
name: (Optional) Target Entity Turn On Action
description: >-
Action that will change target entity's state to desired state.
If this value is left empty, it will default to "homeassistant.turn_on".
default:
- service: homeassistant.turn_on
selector:
action:
actions_off:
name: (Optional) Target Entity Turn Off Action
description: >-
Action that will change target entity's state away from desired state.
It doesn't necessary have to set the entity's state to 'off',
as long as it's not the desired state it will be fine.
If this value is left empty, it will default to "homeassistant.turn_off".
default:
- service: homeassistant.turn_off
selector:
action:
trigger_timeout:
name: (Optional) Trigger Timeout.
description: >-
After "trigger entity" is no longer at "trigger entity state" for
this time (in seconds), "turn off" the target entity.
You can also put the time as "HH:MM:SS". i.e. "01:02:03" means
one hour two mintues three seconds.
If left empty, by default this will be 30 seconds.
default:
seconds: 30
selector:
duration:
alt_trigger_timeouts:
name: (OPTIONAL) Alternate Trigger Timeout
description: >-
Alternate trigger timeout values to use besides the main trigger
timeout.
Follow format
`alternate_time_start_1-alternate_time_end_1,timeout_1`
Use `HH:MM:SS` for "alternate_time_start" and "alternate_time_end".
Multiple time ranges are allowed (separate using new lines).
Time ranges must not overlap.
Timeout can either be a number (meaning timeout in seconds), or
"HH:MM:SS" value.
e.g.
"17:00:00-19:30:00,30
19:30:00-20:00:00,00:20:00
23:00:00-1:00:00,60" means from 17:00:00 to 19:30:00,
use 30 seconds as timeout; from 19:30:00 to 20:00:00, use 20 minutes as timeout;
from 23:00:00 to 1:00:00, use 60 seconds as timeout.
default:
selector:
text:
multiline: true
execution_time_ranges:
name: (OPTIONAL) Execution Time Ranges
description: >-
Time ranges when this automation will be executed. If specified, this automation
will only execute when current time is within any given time range.
Follow format
"time_start_1-time_end_1"
Use "HH:MM:SS" for "time_start" and "time_end".
Multiple time ranges are allowed (separate using new lines).
Time ranges must not overlap.
e.g.
"17:00:00-19:00:00
19:30:00-20:00:00" means this automation will be enabled
from 17:00:00 to 19:00:00 and from 19:30:00 to 20:00:00 everyday.
default:
selector:
text:
multiline: true
mode: restart
variables:
_alt_trigger_timeouts: !input alt_trigger_timeouts
_alt_trigger_timeout: >-
{% set _alt_trigger_timeouts = _alt_trigger_timeouts | replace(' ', '') %}
{% set current_time = now().strftime("%H:%M:%S") %}
{% for alt in (_alt_trigger_timeouts or '').split(';') if alt %}
{% set val = alt.split(',') %}
{% if val | length == 2 and val[0] %}
{% set t = val[0].split('-') %}
{% if t | length == 2 %}
{% if t[0] == t[1] or
(t[0] < t[1] and t[0] <= current_time and current_time <= t[1]) or
(t[0] > t[1] and (current_time >= t[0] or current_time <= t[1]))
%}
{{ val[1] | default(0, true) }}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
trigger_timeout: >-
{% set _alt_trigger_timeout = _alt_trigger_timeout | replace(' ', '') %}
{% set _trigger_timeout = _trigger_timeout | replace(' ', '') %}
{% if _alt_trigger_timeout or _alt_trigger_timeout == 0 %}
{{ _alt_trigger_timeout }}
{% elif _trigger_timeout or _trigger_timeout == 0 %}
{{ _trigger_timeout }}
{% else %}
{{ 30 }}
{% endif %}
_execution_time_ranges: !input execution_time_ranges
execution_time_ranges: "{{ (_execution_time_ranges or '') | replace(' ', '') }}"
execution_time_range_matched: >-
{% set current_time = now().strftime("%H:%M:%S") %}
{% for val in (execution_time_ranges or '').split(';') if val -%}
{% set t = val.split('-') %}
{% if t | length == 2 -%}
{% if t[0] == t[1] or
(t[0] < t[1] and t[0] <= current_time and current_time <= t[1]) or
(t[0] > t[1] and (current_time >= t[0] or current_time <= t[1]))
-%}
{{ val }}
{%- endif %}
{%- endif %}
{%- endfor %}
# At least one trigger entity should be available.
trigger_entities_available: >-
{% for e in trigger_entities if e -%}
{% if states(e) != 'unknown' and not is_state(e, 'unavailable') -%}
{{ e }}:{{ states(e) }};
{%- endif %}
{%- endfor %}
triggered_entity: >-
{% if trigger and trigger.platform == 'state' %}
{% for e in trigger_entities if e -%}
{% if e == trigger.entity_id -%}
{{ e }}
{%- endif %}
{%- endfor %}
{% endif %}
trigger:
- platform: event
# Check immediately after the automation is changed.
event_type: automation_reloaded
- platform: homeassistant
# Check immediately after homeassistant is started.
event: start
- platform: state
# Trigger on any state change of the motion sensor, so we make sure the delay in action will be restarted every time.
entity_id: !input trigger_entities
# - platform: state
# # Trigger on any state change of the target, including manually turned on the target from switch/hass app.
# entity_id: !input target_entities
# # Prevent this automation from triggerring if the light was on and off immediately.
# for:
# seconds: 3
condition:
- condition: template
# Trigger entity (sensor) must be active. If it's not connected due to dead battery or connectivity issue, we shouldn't execute this automation.
# Thus the target can still be operated manually.
value_template: "{{ trigger_entities_available != '' }}"
action:
- choose:
- conditions:
- condition: template
# When execution_time_ranges is defined, but right now it's outside of execution time range.
value_template: "{{ execution_time_ranges != '' and execution_time_range_matched == '' }}"
sequence:
- service: system_log.write
data:
message: "Skip executing service since it's outside of execution time range."
level: info
# - conditions:
# - condition: template
# # This prevent the rule from turning on target entity that is turned off manually from UI/App or from physical switch, even though the trigger entity's state is not cleared.
# value_template: "{{ not trigger or triggered_entity != '' }}"
# {{ trigger_conditions_on }}
# {{ trigger_conditions_off }}
# sequence:
# - service: logbook.log
# # Add a logbook entry to indicate what triggered this action.
# data_template:
# name: "{{ state_attr(target_entity, 'friendly_name') or target_entity }}"
# message: "is executing service {{ target_entity_action_on }}"
# {{ actions_on }}
# - conditions:
# {{ target_conditions_on }}
# {{ trigger_conditions_off }}
# sequence:
# # We don't need to do a "wait for trigger" action.
# # As we listen to any state change of the motion_sensor/target_entity,
# # if the motion_sensor is changed to 'on' during this delay, this automation will be restarted.
# - service: logbook.log
# # Add a logbook entry to indicate what triggered this action.
# data_template:
# name: "{{ state_attr(target_entity_off, 'friendly_name') or target_entity_off }}"
# message: >-
# will execute service {{ target_entity_action_off }} after {{ trigger_timeout }}
# {% set num_timeout = trigger_timeout | int(-1) %}
# {% if num_timeout > 1 %}
# seconds.
# {% elif num_timeout >= 0 %}
# second.
# {% else %}
# .
# {% endif %}
# entity_id: "{{ target_entity_off }}"
# - delay: "{{ trigger_timeout }}"
# - service: logbook.log
# # Add a logbook entry to indicate what triggered this action.
# data_template:
# name: "{{ state_attr(target_entity_off, 'friendly_name') or target_entity_off }}"
# message: "is executing service {{ target_entity_action_off }}"
# entity_id: "{{ target_entity_off }}"
# {{ actions_off }}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment