Last active
July 28, 2024 23:02
-
-
Save haberda/f17694969a6de15d75267667b7c955ac to your computer and use it in GitHub Desktop.
Periodic lights
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: Periodic lights | |
description: "Dim and adjust color temperature of lights progressively throughout the evening (RGB bulbs probably won't change temperature). This is indexed to the midpoint between sunset and sunrise and fit to a sin function, so the midpoint will be minimum brightness and midpoint +12hr will be maximum brightness. The midpoint can be offset by a fixed amount if lights are too dim or bright at the desired time." | |
domain: automation | |
source_url: https://gist.github.com/haberda/f17694969a6de15d75267667b7c955ac | |
input: | |
light: | |
name: Light(s) | |
description: The light(s) to control | |
selector: | |
entity: | |
multiple: true | |
domain: light | |
min_brightness: | |
name: Minimum Brightness | |
description: Minimum brightness of the light(s) | |
default: 1 | |
selector: | |
number: | |
min: 0.0 | |
max: 100.0 | |
mode: slider | |
step: 1.0 | |
unit_of_measurement: "%" | |
max_brightness: | |
name: Maximum Brightness | |
description: Maximum brightness of the light(s) | |
default: 100 | |
selector: | |
number: | |
min: 0.0 | |
max: 100.0 | |
mode: slider | |
step: 1.0 | |
unit_of_measurement: "%" | |
min_temperature: | |
name: Minimum Temperature | |
description: Minimum temperature of the light(s) (Kelvin) | |
default: 2200 | |
selector: | |
number: | |
min: 1800 | |
max: 6000 | |
mode: slider | |
step: 100.0 | |
unit_of_measurement: "K" | |
max_temperature: | |
name: Maximum Temperature | |
description: Maximum temperature of the light(s) (Kelvin) | |
default: 5000 | |
selector: | |
number: | |
min: 1800 | |
max: 6000 | |
mode: slider | |
step: 100.0 | |
unit_of_measurement: "K" | |
threshold_brightness: | |
name: Brightness change threshold | |
description: Threshold value, above which the lights will not be adjusted (+ or -). This is the residual value between the current brightness level and the level it would adjust to. | |
default: 10 | |
selector: | |
number: | |
min: 0.0 | |
max: 100.0 | |
mode: slider | |
step: 1.0 | |
unit_of_measurement: "%" | |
transition: | |
name: Transition | |
description: Transition time (s) | |
default: 0 | |
selector: | |
number: | |
min: 0.0 | |
max: 30.0 | |
mode: slider | |
step: 1.0 | |
unit_of_measurement: "s" | |
midnight_offset: | |
name: Offset middle of the night | |
description: Offset from middle of the night (e.g. dimmest lights). Positive for brighter evening and dimmer morning. Negative for dimmer evening and brighter morning. | |
default: 0 | |
selector: | |
number: | |
min: -120.0 | |
max: 120.0 | |
step: 1.0 | |
unit_of_measurement: min | |
mode: slider | |
light_on_adjust: | |
name: Adjust lights when they are turned on | |
description: "If true adjusts a light immediately when it is turned on." | |
default: true | |
selector: | |
boolean: | |
entity_off_adjust: | |
name: Adjust lights when disable entity is turned off | |
description: "If true adjusts a light immediately when the disable entity is turned off." | |
default: true | |
selector: | |
boolean: | |
disable_entity: | |
name: Disable entity | |
description: Binary sensor or input boolean that when on disables the updating of lights. | |
selector: | |
entity: | |
multiple: true | |
event_fired: | |
name: Event | |
description: The name of the event that will force an update. | |
default: "periodic_lights" | |
mode: parallel | |
max_exceeded: silent | |
variables: | |
light_list: !input "light" | |
threshold_brightness: !input "threshold_brightness" | |
min_brightness: !input "min_brightness" | |
max_brightness: !input "max_brightness" | |
min_temperature: !input "min_temperature" | |
max_temperature: !input "max_temperature" | |
midnight_offset: !input "midnight_offset" | |
light_on_adjust: !input light_on_adjust | |
entity_off_adjust: !input entity_off_adjust | |
pct: > | |
{% if (states('sun.sun') == 'below_horizon') %} | |
{% set sunset = as_timestamp(states.sun.sun.attributes.next_setting)|float - 86400 %} | |
{% set sunrise = as_timestamp(states.sun.sun.attributes.next_rising)|float %} | |
{% else %} | |
{% set sunset = as_timestamp(states.sun.sun.attributes.next_setting)|float %} | |
{% set sunrise = as_timestamp(states.sun.sun.attributes.next_rising)|float %} | |
{% endif %} | |
{% set midpoint = (sunset |float + sunrise |float) / 2 + (midnight_offset|float * 60) | float %} | |
{{ sin(((as_timestamp(now())|float - midpoint)/86400)*pi) |abs }} | |
brightness_percent: "{{ (min_brightness|int+(max_brightness|int-min_brightness|int) * pct) | int }}" | |
kelvin_temperature: "{{ (min_temperature|int+(max_temperature|int-min_temperature|int) * pct) | int }}" | |
on_lights: > | |
{{ expand(light_list) | selectattr('state', 'eq', 'on') | |
| map(attribute='entity_id') | list }} | |
compliant_lights: > | |
{{ expand(on_lights) | selectattr('attributes.brightness','ge',((brightness_percent-threshold_brightness)*2.55)) | |
| selectattr('attributes.brightness','le',((brightness_percent+threshold_brightness)*2.55)) | |
| map(attribute='entity_id') | list }} | |
# brightness_lights: > | |
# {{ expand(on_lights) | selectattr('attributes.color_mode','eq','brightness') | |
# | map(attribute='entity_id') | list }} | |
# color_temp_lights: > | |
# {{ expand(on_lights) | selectattr('attributes.color_mode','in',['color_temp','white']) | |
# | map(attribute='entity_id') | list }} | |
# color_lights: > | |
# {{ expand(on_lights) | selectattr('attributes.color_mode','in',['xy','rgb','rgbw','rgbww','HS']) | |
# | map(attribute='entity_id') | list }} | |
trigger: | |
- platform: time_pattern | |
minutes: "/5" | |
id: "time_change" | |
- platform: state | |
entity_id: !input "light" | |
to: "on" | |
id: "light_on" | |
- platform: state | |
entity_id: !input "disable_entity" | |
to: "off" | |
id: "disable_off" | |
- platform: event | |
event_type: !input event_fired | |
id: "event_fired" | |
condition: | |
- condition: state | |
entity_id: !input disable_entity | |
state: "off" | |
- condition: template | |
value_template: "{{ on_lights|length > 0 }}" | |
action: | |
- delay: | |
hours: 0 | |
minutes: 0 | |
seconds: 0 | |
milliseconds: 500 | |
- choose: | |
- conditions: | |
- or: | |
- condition: trigger | |
id: "event_fired" | |
- and: | |
- condition: trigger | |
id: "disable_off" | |
- condition: template | |
value_template: "{{ entity_off_adjust }}" | |
sequence: | |
- service: light.turn_on | |
data: | |
entity_id: "{{ on_lights }}" | |
brightness_pct: "{{ brightness_percent|int }}" | |
kelvin: "{{ kelvin_temperature|int }}" | |
transition: !input transition | |
- conditions: | |
- condition: trigger | |
id: "light_on" | |
- condition: template | |
value_template: "{{ light_on_adjust }}" | |
sequence: | |
- service: light.turn_on | |
data: | |
entity_id: "{{ trigger.entity_id }}" | |
brightness_pct: "{{ brightness_percent|int }}" | |
kelvin: "{{ kelvin_temperature|int }}" | |
default: | |
- condition: template | |
value_template: "{{ compliant_lights|length > 0 }}" | |
- service: light.turn_on | |
data: | |
entity_id: "{{ compliant_lights }}" | |
brightness_pct: "{{ brightness_percent|int }}" | |
kelvin: "{{ kelvin_temperature|int }}" | |
transition: !input transition |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment