Last active
April 28, 2022 12:20
-
-
Save snowyu/1bc65cb8d635d880473bc31b5e102c37 to your computer and use it in GitHub Desktop.
HA Blueprints
This file contains 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: | |
# INTRODUCTION | |
name: Advanced Circadian Lighting Brightness | |
description: >- | |
This automation adjusts light brightness, temperature, and color hue, | |
based on current time and sun position. | |
Available features: | |
- Works with lights supporting different types of color modes. | |
- Adjusts brightness, temperature and hue based on the circadian cycle. | |
- The circadian cycle can be defined based on sunrise and sunset times. | |
- Sunrise and sunset times can also be defined manually. | |
- Light attributes can be adjusted following various types of functions. | |
- The minimum and maximum brightness and temperature can be configured. | |
- This option can be deactivated. | |
- Gets automatically activated when a light is turned on. | |
- Runs when the turn on service does not define light brightness or color. | |
- Does not run when the turn on service also defines light attributes, e.g. in scenes. | |
- Stops running when light attributes are manually changed. | |
- The light will still turn off automatically. | |
domain: automation | |
# INPUT | |
input: | |
# Input - Lights | |
lights_target: | |
name: Lights | |
description: >- | |
List of lights to adjust. | |
brightness, temperature and color modes are supported. | |
selector: | |
target: | |
entity: | |
domain: light | |
# Input - Circadian | |
circadian_type: | |
name: Circadian cycle | |
description: >- | |
Determines how the circadian cycle will be defined. | |
Select sun to use actual sunrise and sunset times. | |
Select time to override with manual sunrise and sunset times. | |
selector: | |
select: | |
options: | |
- Sun | |
- Time | |
default: Time | |
circadian_sunrise: | |
name: Circadian manual sunrise time | |
description: >- | |
Defines the start of daytime when the circadian rhythm is time-based. | |
This value is ignored when using actual sunrise and sunset times. | |
selector: | |
time: | |
default: "07:30:00" | |
circadian_sunset: | |
name: Circadian manual sunset time | |
description: >- | |
Defines the end of daytime when the circadian rhythm is time-based. | |
This value is ignored when using sunrise and sunset times. | |
selector: | |
time: | |
default: "21:30:00" | |
circadian_function: | |
name: Circadian function | |
description: >- | |
Determines the function used for circadian cycle adjustments. | |
Use day-only or night-only to adjust lights in daytime or nightime. | |
Day & night half-sine functions are similar to the full cycle cosine. | |
Select day & night cosine functions for smoother transitions. | |
Select none to skip circadian cycle adjustments. | |
default: Day-only (half-sine) | |
selector: | |
select: | |
options: | |
- Day-only (half-sine) | |
- Day-only (cosine) | |
- Night-only (half-sine) | |
- Night-only (cosine) | |
- Day & night (cosine) | |
- None | |
circadian_brightness_midday: | |
name: Circadian brightness at midday | |
description: >- | |
Sets the maximum (or minimum) value that light brightness | |
will reach at midday. | |
This value is also used when circadian lighting is disabled. | |
default: 100 | |
selector: | |
number: | |
min: 0 | |
max: 100 | |
unit_of_measurement: "%" | |
mode: slider | |
step: 5 | |
circadian_brightness_midnight: | |
name: Circadian brightness at midnight | |
description: >- | |
Sets the minimum (or maximum) value that light brightness | |
will reach at midnight. | |
This value is ignored when circadian lighting is disabled. | |
default: 10 | |
selector: | |
number: | |
min: 0 | |
max: 100 | |
unit_of_measurement: "%" | |
mode: slider | |
step: 5 | |
circadian_temperature_midday: | |
name: Circadian temperature at midday | |
description: >- | |
Sets the maximum (or minimum) value that color temperature | |
will reach at midday. | |
This value is also used when circadian lighting is disabled. | |
default: 4100 | |
selector: | |
number: | |
min: 2700 | |
max: 6500 | |
unit_of_measurement: "Kelvin" | |
mode: slider | |
step: 100 | |
circadian_temperature_midnight: | |
name: Circadian temperature at midnight | |
description: >- | |
Sets the minimum (or maximum) value that color temperature | |
will reach at midnight. | |
This value is ignored when circadian lighting is disabled. | |
default: 2700 | |
selector: | |
number: | |
min: 2700 | |
max: 6500 | |
unit_of_measurement: "Kelvin" | |
mode: slider | |
step: 100 | |
circadian_hue_default: | |
name: Circadian default hue | |
description: >- | |
Sets the hue value to be used for when circadian lighting is disabled. | |
default: 180 | |
selector: | |
number: | |
min: 0 | |
max: 360 | |
unit_of_measurement: "°" | |
mode: slider | |
step: 5 | |
circadian_saturation_default: | |
name: Circadian default saturation | |
description: >- | |
Sets the color saturation value to be used for circadian adjustments. | |
default: 100 | |
selector: | |
number: | |
min: 0 | |
max: 100 | |
unit_of_measurement: "%" | |
mode: slider | |
step: 5 | |
# Input Elevation | |
elevation_switch_on: | |
name: Dim lights on based on sun elevation | |
description: >- | |
Normally, the lights will dim on at sunset, | |
and they will be turned on during nightime. | |
default: true | |
selector: | |
boolean: | |
elevation_switch_off: | |
name: Dim lights off based on sun elevation | |
description: >- | |
Normally, the lights will dim off at sunrise, | |
and they will be turned off during daytime. | |
default: true | |
selector: | |
boolean: | |
elevation_inverse: | |
name: Inverse light dimming behaviour | |
description: >- | |
Dim the lights on at sunrise and off at sunset. | |
The lights will be turned on during daytime | |
and off during nightime. | |
default: false | |
selector: | |
boolean: | |
elevation_sunrise_start: | |
name: Sunrise start elevation | |
description: >- | |
Defines the beginning of sunrise in terms of sun elevation. | |
Normally, this is when lights start to dim off. | |
When dimming is inversed, this is when lights turn on. | |
default: -8 | |
selector: | |
number: | |
min: -20 | |
max: 10 | |
unit_of_measurement: "°" | |
mode: slider | |
step: 1 | |
elevation_sunrise_end: | |
name: Sunrise end elevation | |
description: >- | |
Defines the end of sunrise in terms of sun elevation. | |
Normally, this is when lights turn off. | |
When dimming is inversed, this is when lights have fully dimmed on. | |
default: 6 | |
selector: | |
number: | |
min: -10 | |
max: 20 | |
unit_of_measurement: "°" | |
mode: slider | |
step: 1 | |
elevation_sunset_start: | |
name: Sunset start elevation | |
description: >- | |
Defines the beginning of sunset in terms of sun elevation. | |
Normally, this is when lights turn on. | |
When dimming is inversed, this is when lights start to dim off. | |
default: 6 | |
selector: | |
number: | |
min: -10 | |
max: 20 | |
unit_of_measurement: "°" | |
mode: slider | |
step: 1 | |
elevation_sunset_end: | |
name: Sunset end elevation | |
description: >- | |
Defines the end of sunset in terms of sun elevation. | |
Normally, this is when light have fully dimmed on. | |
When dimming is inversed, this is when lights turn off. | |
default: -8 | |
selector: | |
number: | |
min: -20 | |
max: 10 | |
unit_of_measurement: "°" | |
mode: slider | |
step: 1 | |
# VARIABLES | |
variables: | |
# Variables Circadian | |
circadian_type: !input circadian_type | |
circadian_sunrise: !input circadian_sunrise | |
circadian_sunset: !input circadian_sunset | |
circadian_function: !input circadian_function | |
circadian_position: >- | |
{# Define next sunrise and sunset times based on sun or manual input #} | |
{%- set time_current = now()|as_timestamp -%} | |
{%- if circadian_type == 'Sun' and states('sun.sun') != 'unknown' -%} | |
{%- set time_sunrise = state_attr('sun.sun','next_rising')|as_timestamp -%} | |
{%- set time_sunset = state_attr('sun.sun','next_setting')|as_timestamp -%} | |
{%- else -%} | |
{%- set time_sunrise = today_at(circadian_sunrise)|as_timestamp -%} | |
{%- set time_sunset = today_at(circadian_sunset)|as_timestamp -%} | |
{# Fix input times so that they reflect the next sunrise and sunset #} | |
{%- if time_sunrise < time_current -%} | |
{% set time_sunrise = time_sunrise + 86400 -%} | |
{%- endif -%} | |
{%- if time_sunset < time_current -%} | |
{% set time_sunset = time_sunset + 86400 -%} | |
{%- endif -%} | |
{%- endif -%} | |
{# Calculate sun position, from -1 to 0 in nightime and 0 to 1 in daytime. #} | |
{%- if time_sunrise > time_sunset -%} | |
{%- set time_sunrise = [time_sunrise-86400,time_current]|min -%} | |
{%- set position = (time_current-time_sunrise) / (time_sunset-time_sunrise) -%} | |
{%- else -%} | |
{%- set time_sunset = [time_sunset-86400,time_current]|min -%} | |
{%- set position = (time_current-time_sunrise) / (time_sunrise-time_sunset) -%} | |
{%- endif -%} | |
{# Return calculated result #} | |
{{ position }} | |
circadian_coefficient: >- | |
{# Calculate coefficient based on selected circadian function #} | |
{%- set coefficient = 1.0 -%} | |
{%- if circadian_function == 'Day-only (half-sine)' -%} | |
{%- set coefficient = sin( pi*([circadian_position,0]|max) ) -%} | |
{%- elif circadian_function == 'Day-only (cosine)' -%} | |
{%- set coefficient = 0.5 - 0.5 * cos( 2*pi*([circadian_position,0]|max) ) -%} | |
{%- elif circadian_function == 'Night-only (half-sine)' -%} | |
{%- set coefficient = 1 - sin( pi*([circadian_position,0]|min) ) -%} | |
{%- elif circadian_function == 'Night-only (cosine)' -%} | |
{%- set coefficient = 0.5 + 0.5 * cos( 2*pi*([circadian_position,0]|min) ) -%} | |
{%- elif circadian_function == 'Day & night (cosine)' -%} | |
{%- set coefficient = 0.5 + 0.5 * sin( pi*circadian_position ) -%} | |
{%- else -%} | |
{%- set coefficient = -1.0 -%} | |
{%- endif -%} | |
{# Return calculated result #} | |
{{ coefficient }} | |
circadian_angle: >- | |
{# Calculate angle based on selected circadian function #} | |
{%- set angle = 0.5 -%} | |
{%- if circadian_function == 'Day-only (half-sine)' | |
or circadian_function == 'Day-only (cosine)' -%} | |
{%- set angle = [circadian_position,0]|max -%} | |
{%- elif circadian_function == 'Night-only (half-sine)' | |
or circadian_function == 'Night-only (cosine)' -%} | |
{%- if circadian_position < -0.5 -%} | |
{%- set angle = 1.5 + circadian_position -%} | |
{%- else -%} | |
{%- set angle = 0.5 + [circadian_position,0]|min -%} | |
{%- endif -%} | |
{%- elif circadian_function == 'Day & night (cosine)' -%} | |
{%- if circadian_position < -0.5 -%} | |
{%- set angle = 1.25 + 0.5 * circadian_position -%} | |
{%- else -%} | |
{%- set angle = 0.25 + 0.5 * circadian_position -%} | |
{%- endif -%} | |
{%- else -%} | |
{%- set angle = -1.0 -%} | |
{%- endif -%} | |
{# Return calculated result #} | |
{{ angle }} | |
circadian_brightness_midday: !input circadian_brightness_midday | |
circadian_brightness_midnight: !input circadian_brightness_midnight | |
circadian_brightness_value: >- | |
{# Light brightness value to adjust to #} | |
{%- if circadian_coefficient < 0 -%} | |
{{ [ ( 2.54 * circadian_brightness_midday|float + 0.5)|int , 1]|max }} | |
{%- else -%} | |
{{ [ ( 2.54 * ( circadian_brightness_midnight|float + circadian_coefficient * ( circadian_brightness_midday|float - circadian_brightness_midnight|float ) ) + 0.5)|int , 1]|max }} | |
{%- endif -%} | |
circadian_temperature_midday: !input circadian_temperature_midday | |
circadian_temperature_midnight: !input circadian_temperature_midnight | |
circadian_temperature_value: >- | |
{# Color temperature value to adjust to #} | |
{%- if circadian_coefficient < 0 -%} | |
{{ ( 1000000/circadian_temperature_midday + 0.5)|int }} | |
{%- else -%} | |
{{ ( 1000000/circadian_temperature_midnight|float + circadian_coefficient * ( 1000000/circadian_temperature_midday|float - 1000000/circadian_temperature_midnight|float ) + 0.5)|int }} | |
{%- endif -%} | |
circadian_hue_default_input: !input circadian_hue_default | |
circadian_hue_default: '{{ circadian_hue_default_input|float }}' | |
circadian_hue_value: >- | |
{# Color hue value to adjust to #} | |
{%- if circadian_angle < 0 -%} | |
{{ circadian_hue_default }} | |
{%- else -%} | |
{{ (360 * circadian_angle + 0.5)|int }} | |
{%- endif -%} | |
circadian_saturation_default_input: !input circadian_saturation_default | |
circadian_saturation_default: '{{ circadian_saturation_default_input|float }}' | |
# Variables Sunrise/Sunset | |
elevation_switch_on: !input elevation_switch_on | |
elevation_switch_off: !input elevation_switch_off | |
elevation_inverse: !input elevation_inverse | |
elevation_sunrise_start_input: !input elevation_sunrise_start | |
elevation_sunrise_start: "{{ elevation_sunrise_start_input | float }}" | |
elevation_sunrise_end_input: !input elevation_sunrise_end | |
elevation_sunrise_end: "{{ elevation_sunrise_end_input | float }}" | |
elevation_sunset_start_input: !input elevation_sunset_start | |
elevation_sunset_start: "{{ elevation_sunset_start_input | float }}" | |
elevation_sunset_end_input: !input elevation_sunset_end | |
elevation_sunset_end: "{{ elevation_sunset_end_input | float }}" | |
elevation_dim_on: >- | |
{# Boolean for dimming on #} | |
{{ elevation_switch_on | |
and ( ( not elevation_inverse | |
and not state_attr('sun.sun','rising') | |
and ( ( state_attr('sun.sun','elevation') < elevation_sunset_start | |
and state_attr('sun.sun','elevation') > elevation_sunset_end ) | |
or ( trigger is defined | |
and trigger.platform == 'numeric_state' | |
and trigger.from_state.entity_id == 'sun.sun' | |
and trigger.from_state.attributes.elevation < elevation_sunset_start | |
and trigger.from_state.attributes.elevation > elevation_sunset_end ) ) ) | |
or ( elevation_inverse | |
and state_attr('sun.sun','rising') | |
and ( ( state_attr('sun.sun','elevation') > elevation_sunrise_start | |
and state_attr('sun.sun','elevation') < elevation_sunrise_end ) | |
or ( trigger is defined | |
and trigger.platform == 'numeric_state' | |
and trigger.from_state.entity_id == 'sun.sun' | |
and trigger.from_state.attributes.elevation > elevation_sunrise_start | |
and trigger.from_state.attributes.elevation < elevation_sunrise_end ) ) ) ) }} | |
elevation_dim_off: >- | |
{# Boolean for dimming off #} | |
{{ elevation_switch_off | |
and ( ( not elevation_inverse | |
and state_attr('sun.sun','rising') | |
and state_attr('sun.sun','elevation') > elevation_sunrise_start | |
and state_attr('sun.sun','elevation') < elevation_sunrise_end ) | |
or ( elevation_inverse | |
and not state_attr('sun.sun','rising') | |
and state_attr('sun.sun','elevation') < elevation_sunset_start | |
and state_attr('sun.sun','elevation') > elevation_sunset_end ) ) }} | |
elevation_brightness: >- | |
{# Calculate coefficient to be multiplied with brightness #} | |
{%- if elevation_dim_on or elevation_dim_off -%} | |
{%- set elevation_current = state_attr('sun.sun','elevation') -%} | |
{%- if state_attr('sun.sun','rising') -%} | |
{%- set coefficient = 1.0 - (elevation_current-elevation_sunrise_start) / (elevation_sunrise_end-elevation_sunrise_start) -%} | |
{%- else -%} | |
{%- set coefficient = (elevation_current-elevation_sunset_start) / (elevation_sunset_end-elevation_sunset_start) -%} | |
{%- endif -%} | |
{%- if elevation_inverse -%} | |
{%- set coefficient = 1.0 - coefficient -%} | |
{%- endif -%} | |
{%- else -%} | |
{%- set coefficient = 1.0 -%} | |
{%- endif -%} | |
{# Return calculated result #} | |
{# Alternative: 0.5 - 0.5*cos(pi*coefficient) #} | |
{{ [ ( coefficient * circadian_brightness_value + 0.5 )|int , 1]|max }} | |
# Variables Trigger | |
turnon_trigger: >- | |
{# Boolean for light.turn_on event trigger #} | |
{{ trigger is defined | |
and trigger.platform == 'event' | |
and trigger.event.data.service_data is defined | |
and trigger.event.data.service_data.entity_id is defined }} | |
# Variables Lights | |
lights_target_input: !input lights_target | |
lights_target: >- | |
{# This is the full list of targetted lights #} | |
{# Ensure that the variable is a list #} | |
{%- if lights_target_input.entity_id is string -%} | |
{%- set lights_list = [lights_target_input] -%} | |
{%- else -%} | |
{%- set lights_list = lights_target_input -%} | |
{%- endif -%} | |
{{ expand(lights_list) | |
|selectattr('state', 'eq', 'on') | |
|map(attribute='entity_id') | |
|list | |
}} | |
lights_dim_all: >- | |
{# This is the list of lights that are being dimmed #} | |
{%- set lights_select = namespace(entities=[]) -%} | |
{%- if elevation_dim_on or elevation_dim_off -%} | |
{%- for i_entity in lights_target -%} | |
{# Check that the light is being dimmed in one direction #} | |
{# Also check that other circadian values are being followed #} | |
{%- if ( state_attr(i_entity,'brightness') != none | |
and ( elevation_dim_on | |
and state_attr(i_entity,'brightness') < elevation_brightness+15 ) | |
or ( elevation_dim_off | |
and state_attr(i_entity,'brightness') > elevation_brightness-15 ) ) | |
and ( ( state_attr(i_entity,'color_temp') == none | |
and state_attr(i_entity,'hs_color') == none ) | |
or ( state_attr(i_entity,'hs_color') != none | |
and state_attr(i_entity,'hs_color')|first > circadian_hue_value-30 | |
and state_attr(i_entity,'hs_color')|first < circadian_hue_value+30 ) | |
or ( state_attr(i_entity,'color_temp') != none | |
and state_attr(i_entity,'color_temp') > circadian_temperature_value-20 | |
and state_attr(i_entity,'color_temp') < circadian_temperature_value+20 ) ) -%} | |
{%- set lights_select.entities = lights_select.entities + [i_entity] -%} | |
{%- endif -%} | |
{%- endfor -%} | |
{%- endif -%} | |
{{ lights_select.entities }} | |
lights_on_all: >- | |
{# This is the list of lights that follow the circadian cycle #} | |
{%- set lights_select = namespace(entities=[]) -%} | |
{%- for i_entity in lights_target -%} | |
{# Check that the light is following all circadian values #} | |
{# Also check that the light is not being dimmed #} | |
{%- if (state_attr(i_entity,'brightness') == none | |
or ( state_attr(i_entity,'brightness') != none | |
and state_attr(i_entity,'brightness') > circadian_brightness_value-15 | |
and state_attr(i_entity,'brightness') < circadian_brightness_value+15 ) ) | |
and ( | |
( state_attr(i_entity,'color_temp') == none and state_attr(i_entity,'hs_color') == none ) | |
or ( state_attr(i_entity,'hs_color') != none | |
and state_attr(i_entity,'hs_color')|first > circadian_hue_value-30 | |
and state_attr(i_entity,'hs_color')|first < circadian_hue_value+30 ) | |
or ( state_attr(i_entity,'color_temp') != none | |
and state_attr(i_entity,'color_temp') > circadian_temperature_value-20 | |
and state_attr(i_entity,'color_temp') < circadian_temperature_value+20 ) ) | |
and i_entity not in lights_dim_all -%} | |
{%- set lights_select.entities = lights_select.entities + [i_entity] -%} | |
{%- endif -%} | |
{%- endfor -%} | |
{{ lights_select.entities }} | |
lights_off_all: >- | |
{# This is the list of lights that are currently off #} | |
{%- set lights_select = namespace(entities=[]) -%} | |
{%- for i_entity in lights_target -%} | |
{# Check that the light is off #} | |
{%- if is_state(i_entity,'off') -%} | |
{%- set lights_select.entities = lights_select.entities + [i_entity] -%} | |
{%- endif -%} | |
{%- endfor -%} | |
{{ lights_select.entities }} | |
lights_trigger_all: >- | |
{# This is the list of lights that have been triggered #} | |
{%- set lights_select = namespace(entities=[]) -%} | |
{%- if turnon_trigger -%} | |
{# Ensure that the triggered lights are a list #} | |
{%- if trigger.event.data.service_data.entity_id is string -%} | |
{%- set lights_list = [trigger.event.data.service_data.entity_id] -%} | |
{%- else -%} | |
{%- set lights_list = trigger.event.data.service_data.entity_id -%} | |
{%- endif -%} | |
{# Check for individual entities within a group light #} | |
{%- set group_list = namespace(entities=[]) -%} | |
{%- for i_entity in lights_list -%} | |
{%- if state_attr(i_entity,'entity_id') is not none -%} | |
{%- if state_attr(i_entity,'entity_id') is string -%} | |
{%- set group_list.entities = group_list.entities + [state_attr(i_entity,'entity_id')] -%} | |
{%- else -%} | |
{%- set group_list.entities = group_list.entities + state_attr(i_entity,'entity_id') -%} | |
{%- endif -%} | |
{%- endif -%} | |
{%- endfor -%} | |
{%- set lights_list = lights_list + group_list.entities -%} | |
{%- for i_entity in lights_list -%} | |
{# Check that the light is in the target list #} | |
{# Also check that its properties are not being set #} | |
{%- if i_entity in lights_target | |
and ( trigger.event.data.service_data|length == 1 | |
or ( is_state(i_entity,'on') | |
and trigger.event.data.service_data|length <=2 | |
and trigger.event.data.service_data.brightness is not defined | |
and trigger.event.data.service_data.brightness_pct is not defined ) ) -%} | |
{%- set lights_select.entities = lights_select.entities + [i_entity] -%} | |
{%- endif -%} | |
{%- endfor -%} | |
{%- endif -%} | |
{{ lights_select.entities }} | |
lights_dim_brightness: >- | |
{%- set lights_select = namespace(entities=[]) -%} | |
{%- for i_entity in lights_dim_all -%} | |
{%- if state_attr(i_entity,'color_mode') == 'brightness' -%} | |
{%- set lights_select.entities = lights_select.entities + [i_entity] -%} | |
{%- endif -%} | |
{%- endfor -%} | |
{{ lights_select.entities }} | |
lights_dim_color: >- | |
{%- set lights_select = namespace(entities=[]) -%} | |
{%- for i_entity in lights_dim_all -%} | |
{%- if state_attr(i_entity,'color_mode') in ['rgb','rgbw','rgbww','xy','hs'] -%} | |
{%- set lights_select.entities = lights_select.entities + [i_entity] -%} | |
{%- endif -%} | |
{%- endfor -%} | |
{{ lights_select.entities }} | |
lights_dim_temperature: >- | |
{%- set lights_select = namespace(entities=[]) -%} | |
{%- for i_entity in lights_dim_all -%} | |
{%- if state_attr(i_entity,'color_mode') == 'color_temp' -%} | |
{%- set lights_select.entities = lights_select.entities + [i_entity] -%} | |
{%- endif -%} | |
{%- endfor -%} | |
{{ lights_select.entities }} | |
lights_on_brightness: >- | |
{%- set lights_select = namespace(entities=[]) -%} | |
{%- for i_entity in lights_on_all -%} | |
{%- if state_attr(i_entity,'color_mode') == 'brightness' -%} | |
{%- set lights_select.entities = lights_select.entities + [i_entity] -%} | |
{%- endif -%} | |
{%- endfor -%} | |
{{ lights_select.entities }} | |
lights_on_color: >- | |
{%- set lights_select = namespace(entities=[]) -%} | |
{%- for i_entity in lights_on_all -%} | |
{%- if state_attr(i_entity,'color_mode') in ['rgb','rgbw','rgbww','xy','hs'] -%} | |
{%- set lights_select.entities = lights_select.entities + [i_entity] -%} | |
{%- endif -%} | |
{%- endfor -%} | |
{{ lights_select.entities }} | |
lights_on_temperature: >- | |
{%- set lights_select = namespace(entities=[]) -%} | |
{%- for i_entity in lights_on_all -%} | |
{%- if state_attr(i_entity,'color_mode') == 'color_temp' -%} | |
{%- set lights_select.entities = lights_select.entities + [i_entity] -%} | |
{%- endif -%} | |
{%- endfor -%} | |
{{ lights_select.entities }} | |
# AUTOMATION | |
mode: 'queued' | |
# TRIGGER | |
trigger: | |
- platform: time_pattern | |
minutes: "/1" | |
- platform: numeric_state | |
entity_id: sun.sun | |
attribute: elevation | |
above: !input elevation_sunrise_start | |
- platform: numeric_state | |
entity_id: sun.sun | |
attribute: elevation | |
above: !input elevation_sunrise_end | |
- platform: numeric_state | |
entity_id: sun.sun | |
attribute: elevation | |
below: !input elevation_sunset_start | |
- platform: numeric_state | |
entity_id: sun.sun | |
attribute: elevation | |
below: !input elevation_sunset_end | |
- platform: event | |
event_type: call_service | |
event_data: | |
domain: light | |
service: turn_on | |
# ACTION | |
action: | |
# Default (on lights to circadian, dim lights to elevation brightness) | |
- choose: | |
- conditions: "{{ lights_on_brightness | length > 0 }}" | |
sequence: | |
- service: light.turn_on | |
data: | |
entity_id: "{{ lights_on_brightness }}" | |
brightness: "{{ circadian_brightness_value }}" | |
- choose: | |
- conditions: "{{ lights_on_color | length > 0 }}" | |
sequence: | |
- service: light.turn_on | |
data: | |
entity_id: "{{ lights_on_color }}" | |
brightness: "{{ circadian_brightness_value }}" | |
hs_color: | |
- "{{ circadian_hue_value }}" | |
- "{{ circadian_saturation_default }}" | |
- choose: | |
- conditions: "{{ lights_on_temperature | length > 0 }}" | |
sequence: | |
- service: light.turn_on | |
data: | |
entity_id: "{{ lights_on_temperature }}" | |
brightness: "{{ circadian_brightness_value }}" | |
color_temp: "{{ circadian_temperature_value }}" | |
- choose: | |
- conditions: "{{ lights_dim_brightness | length > 0 }}" | |
sequence: | |
- service: light.turn_on | |
data: | |
entity_id: "{{ lights_dim_brightness }}" | |
brightness: "{{ elevation_brightness }}" | |
- choose: | |
- conditions: "{{ lights_dim_color | length > 0 }}" | |
sequence: | |
- service: light.turn_on | |
data: | |
entity_id: "{{ lights_dim_color }}" | |
brightness: "{{ elevation_brightness }}" | |
hs_color: | |
- "{{ circadian_hue_value }}" | |
- "{{ circadian_saturation_default }}" | |
- choose: | |
- conditions: "{{ lights_dim_temperature | length > 0 }}" | |
sequence: | |
- service: light.turn_on | |
data: | |
entity_id: "{{ lights_dim_temperature }}" | |
brightness: "{{ elevation_brightness }}" | |
color_temp: "{{ circadian_temperature_value }}" |
This file contains 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: Presence-activated Light Off with Illuminance and sun's Elevation | |
description: Turn off a light when presence is not detected, or illuminance is above a set Lux level or sun's elevation or in time range. | |
domain: automation | |
source_url: https://gist.github.com/snowyu/1bc65cb8d635d880473bc31b5e102c37/#file-motion-light-off-yaml | |
input: | |
motion_entity: | |
name: Presence Sensor | |
description: >- | |
This can be a device_tracker, an input_boolean, a binary_sensor, | |
or any entity that can switch to "on" or "home". | |
It can also be a media_player that can swith to "playing" or "paused". | |
selector: | |
entity: | |
# domain: binary_sensor | |
# device_class: motion | |
default: "device_tracker.me" | |
motion_duration: | |
name: Presence Sensor Duration Time (Optional) | |
description: The state lasts at least. | |
default: 0 | |
selector: | |
number: | |
min: 0 | |
max: 3600 | |
unit_of_measurement: seconds | |
sunrise_elevation: | |
name: Sunrise elevation (Optional) | |
description: turn off after Sunrise elevation. Elevation is the angle between the sun and the horizon. Negative values mean the sun is BELOW the horizon. | |
default: false | |
selector: | |
number: | |
min: -90 | |
max: 90 | |
unit_of_measurement: degrees | |
sunset_elevation: | |
name: Sunset elevation (Optional) | |
description: turn off before Sunset elevation. Elevation is the angle between the sun and the horizon. Negative values mean the sun is BELOW the horizon. | |
default: false | |
selector: | |
number: | |
min: -90 | |
max: 90 | |
unit_of_measurement: degrees | |
lux_entity: | |
name: Illuminance Sensor (Optional) | |
default: false | |
selector: | |
entity: | |
domain: sensor | |
device_class: illuminance | |
lux_level: | |
name: Illuminance level (Optional) | |
description: If lux is above this value, the light will turn off. | |
default: false | |
selector: | |
number: | |
min: 0 | |
max: 1000 | |
light_target: | |
name: Light | |
selector: | |
target: | |
entity: | |
domain: light | |
start_time: | |
name: Light off start time (Optional) | |
description: only light off after start time | |
default: '' | |
selector: | |
time: | |
end_time: | |
name: Light off end time (Optional) | |
description: only light off before end time | |
default: '' | |
selector: | |
time: | |
no_motion_wait: | |
name: Wait time before turn off (Optional) | |
description: Time to leave the light on after last motion is detected. | |
default: 0 | |
selector: | |
number: | |
min: 0 | |
max: 3600 | |
unit_of_measurement: seconds | |
mode: restart | |
max_exceeded: silent | |
trigger_variables: | |
sunset_elevation: !input sunset_elevation | |
sunrise_elevation: !input sunrise_elevation | |
lux_entity: !input lux_entity | |
lux_level: !input lux_level | |
variables: | |
motion_entity: !input motion_entity | |
sunset_elevation: !input sunset_elevation | |
sunrise_elevation: !input sunrise_elevation | |
lux_entity: !input lux_entity | |
lux_level: !input lux_level | |
no_motion_wait: !input no_motion_wait | |
start_time: !input start_time | |
end_time: !input end_time | |
ts_start: "{{ start_time and today_at(start_time)|as_timestamp }}" | |
ts_end: "{{ end_time and today_at(end_time)|as_timestamp }}" | |
ts_now: "{{ now().timestamp() }}" | |
elevation: "{{ sunset_elevation if ts_now > today_at('12:00:00')|as_timestamp else sunrise_elevation }}" | |
trigger: | |
- platform: state | |
entity_id: !input motion_entity | |
for: | |
seconds: !input motion_duration | |
- platform: template | |
value_template: "{{ (lux_entity != false) and (states(lux_entity)|float(0) > lux_level|float(0)) }}" | |
- platform: template | |
value_template: >- | |
{%- set ts_now = now().timestamp() -%} | |
{%- set elevation = sunset_elevation if ts_now > today_at('12:00:00')|as_timestamp else sunrise_elevation -%} | |
{{ (elevation != false) and (state_attr('sun.sun','elevation') > elevation|float(90)) }} | |
condition: | |
# - condition: state | |
# entity_id: !input light_target | |
# state: "on" | |
- condition: or | |
conditions: | |
- condition: template | |
value_template: >- | |
{{( states(motion_entity) == 'unknown') or not (states(motion_entity) in ['on','home','playing','paused']) }} | |
- condition: template | |
value_template: "{{ (lux_entity != false) and (states(lux_entity)|float(0) > lux_level|float(0)) }}" | |
- condition: template | |
value_template: "{{ (elevation != false) and (state_attr('sun.sun','elevation') > elevation|float(90)) }}" | |
- condition: template | |
value_template: >- | |
{%- if ts_end and ts_start and (ts_end < ts_start) -%} | |
{{ (ts_now >= ts_start and ts_now <= today_at('23:59:59')|as_timestamp) or (ts_now >= today_at('00:00:00')|as_timestamp and ts_now <= ts_end) }} | |
{%- else -%} | |
{{ (not ts_start or ts_now >= ts_start) and (not ts_end or ts_now <= ts_end) }} | |
{%- endif -%} | |
action: | |
- delay: !input no_motion_wait | |
- choose: | |
- alias: "check conditions again" | |
conditions: | |
- condition: or | |
conditions: | |
- condition: template | |
value_template: >- | |
{{( states(motion_entity) == 'unknown') or not (states(motion_entity) in ['on','home','playing','paused']) }} | |
- condition: template | |
value_template: "{{ (lux_entity != false) and (states(lux_entity)|float(0) > lux_level|float(0)) }}" | |
- condition: template | |
value_template: "{{ (elevation != false) and (state_attr('sun.sun','elevation') > elevation|float(90)) }}" | |
- condition: template | |
value_template: >- | |
{%- if ts_end and ts_start and (ts_end < ts_start) -%} | |
{{ (ts_now >= ts_start and ts_now <= today_at('23:59:59')|as_timestamp) or (ts_now >= today_at('00:00:00')|as_timestamp and ts_now <= ts_end) }} | |
{%- else -%} | |
{{ (not ts_start or ts_now >= ts_start) and (not ts_end or ts_now <= ts_end) }} | |
{%- endif -%} | |
sequence: | |
- service: light.turn_off | |
target: !input light_target |
This file contains 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: Motion-activated Light On with Illuminance and sun's Elevation | |
description: Turn on a light when presence is detected, illuminance is below a set Lux level and sun's elevation. | |
domain: automation | |
source_url: https://gist.github.com/snowyu/1bc65cb8d635d880473bc31b5e102c37/#file-motion-light-on-yaml | |
input: | |
motion_entity: | |
name: Presence Sensor | |
description: >- | |
This can be a device_tracker, an input_boolean, a binary_sensor, | |
or any entity that can switch to "on" or "home". | |
It can also be a media_player that can swith to "playing" or "paused". | |
selector: | |
entity: | |
# domain: binary_sensor | |
# device_class: motion | |
default: "device_tracker.me" | |
motion_duration: | |
name: Presence Sensor Duration Time (Optional) | |
description: The state lasts at least. | |
default: 0 | |
selector: | |
number: | |
min: 0 | |
max: 3600 | |
unit_of_measurement: seconds | |
sunset_elevation: | |
name: Sunset elevation (Optional) | |
description: turn on after sunset elevation. Elevation is the angle between the sun and the horizon. Negative values mean the sun is BELOW the horizon. | |
default: false | |
selector: | |
number: | |
min: -90 | |
max: 90 | |
unit_of_measurement: degrees | |
sunrise_elevation: | |
name: Sunrise elevation (Optional) | |
description: turn on before sunrise elevation. Elevation is the angle between the sun and the horizon. Negative values mean the sun is BELOW the horizon. | |
default: false | |
selector: | |
number: | |
min: -90 | |
max: 90 | |
unit_of_measurement: degrees | |
lux_entity: | |
name: Illuminance Sensor (Optional) | |
default: false | |
selector: | |
entity: | |
domain: sensor | |
device_class: illuminance | |
lux_level: | |
name: Illuminance level (Optional) | |
description: If lux is below this value and motion is detected, the light will turn on. | |
default: false | |
selector: | |
number: | |
min: 0 | |
max: 1000 | |
light_target: | |
name: Light | |
selector: | |
target: | |
entity: | |
domain: light | |
start_time: | |
name: Light on start time (Optional) | |
description: only light on after start time | |
default: '' | |
selector: | |
time: | |
end_time: | |
name: Light on end time (Optional) | |
description: only light on before end time | |
default: '' | |
selector: | |
time: | |
mode: restart | |
max_exceeded: silent | |
trigger_variables: | |
sunset_elevation: !input sunset_elevation | |
sunrise_elevation: !input sunrise_elevation | |
lux_entity: !input lux_entity | |
lux_level: !input lux_level | |
variables: | |
motion_entity: !input motion_entity | |
sunset_elevation: !input sunset_elevation | |
sunrise_elevation: !input sunrise_elevation | |
lux_entity: !input lux_entity | |
lux_level: !input lux_level | |
start_time: !input start_time | |
end_time: !input end_time | |
ts_start: "{{ start_time and today_at(start_time)|as_timestamp }}" | |
ts_end: "{{ end_time and today_at(end_time)|as_timestamp }}" | |
ts_now: "{{ now().timestamp() }}" | |
elevation: "{{ sunset_elevation if ts_now > today_at('12:00:00')|as_timestamp else sunrise_elevation }}" | |
trigger: | |
- platform: state | |
entity_id: !input motion_entity | |
for: | |
seconds: !input motion_duration | |
- platform: template | |
value_template: "{{ (lux_entity != false) and (states(lux_entity)|float(0) <= lux_level|float(0)) }}" | |
- platform: template | |
value_template: >- | |
{%- set ts_now = now().timestamp() -%} | |
{%- set elevation = sunset_elevation if ts_now > today_at('12:00:00')|as_timestamp else sunrise_elevation -%} | |
{{ (elevation != false) and (state_attr('sun.sun','elevation') <= elevation|float(90)) }} | |
condition: | |
- condition: template | |
value_template: >- | |
{{( states(motion_entity) == 'unknown') or states(motion_entity) in ['on','home','playing','paused'] }} | |
- condition: template | |
value_template: "{{ (states(lux_entity) == 'unknown') or (states(lux_entity)|float(0) <= lux_level|float(0)) }}" | |
- condition: template | |
value_template: "{{ (elevation == false) or (state_attr('sun.sun','elevation') <= elevation|float(90)) }}" | |
- condition: template | |
value_template: >- | |
{%- if ts_end and ts_start and (ts_end < ts_start) -%} | |
{{ (ts_now >= ts_start and ts_now <= today_at('23:59:59')|as_timestamp) or (ts_now >= today_at('00:00:00')|as_timestamp and ts_now <= ts_end) }} | |
{%- else -%} | |
{{ (not ts_start or ts_now >= ts_start) and (not ts_end or ts_now <= ts_end) }} | |
{%- endif -%} | |
action: | |
- service: light.turn_on | |
target: !input light_target |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment