Hi everyone,
after getting much input from this community I really would like to share some of my solutions and thoughts. Having some Hue bulbs in my bedroom and being hardly to motivate to wake up in the morning, I was looking for a solution to create a wake up light.
Basically you just can create an automation with a fixed start time and using the “light.turn_on” service, but this was to static for me and I wanted to have a more flexible solution. So I came up with the idea to use some “date_time-helpers” for setting the wake up time and the duration for transition. All information are adjustable through the UI.
As you can see, I do have two lights, I can set up the wake up time, the duration and choose which bulbs are used in the morning.
Starting with the code for the shown card. The code is pretty straight forward and just a collection of some entities:
type: vertical-stack
title: Licht Aufstehen
cards:
- type: entities
entities:
- entity: input_datetime.aufstehen
name: Weckzeit
- entity: input_datetime.aufstehen_offset
name: Überblendzeit (vor Wecker)
- entity: input_boolean.aufstehen_bulb1
name: Lampe 1
- entity: input_boolean.aufstehen_bulb2
name: Lampe 2
Moreover we do need the mentioned helpers. In my case three date_time-helpers and two boolean.
Names are: “input_datetime.aufstehen”, “input_datetime.aufstehen_offset”, “input_datetime.aufstehen_start”, “input_boolean.aufstehen_bulb1” and “input_boolean.aufstehen_bulb2”. The two lights are furthermore summarized in a group called “light.alles_schlafzimmer”.
For the less experienced users: You might have to add the lines:
input_boolean:
input_boolean:
in your configuration.yaml to activate the helpers.
Afterwards you can add the helpers under “settings->automatisation & scenes->helper”
Next step is an automatisation for calculating the time, when the transition should start (wake up time minus duration). Sounds simple, but this was quiet challenging to me, because calculation of date_time-helpers isn’t that easy.
Triggers for this automatisation is the change of either “input_datetime.aufstehen” or “input_datetime.aufstehen_offset” and the aim is to calculate the end time minus the offset and save this new time inside the helper “input_datetime.aufstehen_start”
Complete automation looks like this:
alias: 'Automatisierung: Setze Startzeit Licht Aufstehen'
description: ''
trigger:
- platform: state
entity_id: input_datetime.aufstehen
- platform: state
entity_id: input_datetime.aufstehen_offset
condition: []
action:
- service: input_datetime.set_datetime
data:
time: >
{% set offset_hour = state_attr('input_datetime.aufstehen_offset', 'hour') %}
{% set offset_minute = state_attr('input_datetime.aufstehen_offset', 'minute') %}
{% set end_hour = state_attr('input_datetime.aufstehen', 'hour') %}
{% set end_minute = state_attr('input_datetime.aufstehen', 'minute') %}
{% if offset_hour==0 %}
{% set offset_hour_calc = 0 %}
{% else %}
{% set offset_hour_calc = offset_hour * 60 %}
{%endif%}
{% if end_hour==0 %}
{% set end_hour_calc = 0 %}
{% else %}
{% set end_hour_calc = end_hour * 60 %}
{%endif%}
{% set minute_offset = offset_minute + offset_hour_calc %}
{% set minute_end = end_minute + end_hour_calc %}
{% set minute_start = minute_end - minute_offset %}
{% if minute_start<=0 %}
{% set start_hour = 0 %}
{% set start_minute = 0 %}
{% else %}
{% set start_hour = (minute_start / 60) | int %}
{% set start_minute = (((minute_start / 60) - start_hour) * 60) | round(0) %}
{%endif%}
{% set time_string = (start_hour | string) + ":" + (start_minute | string) + ":" + "00" %}
{{time_string}}
target:
entity_id: input_datetime.aufstehen_start
mode: single
For interested readers some explanations:
First block, saving the the set hours and minutes of the helpers in some variables.
Second block, recalculate the hours of offset into minutes.
Third block, recalculate the hours of end time into minutes.
Forth block, convert the input times into a value in minutes by adding.
Fifth block, calculate the start time by subtracting the end time minus offset. Afterwards check, if this value is getting negative. If yes, it would mean to start the light the day before. I think this won’t happen in a real case, but just to be sure, I will set the start time to “00:00” in this case. Otherwise calculate the start time and recalculate it in hours and minutes.
Last block, create a string containing our start time and giving the value as output.
Now, our start time will be calculated every time we change one of our helpers.
A second automatisation will turn on the lights in the morning, starting at the calculated start time and using the set duration for transition (just weekdays):
alias: 'Automatisierung: Licht Aufstehen Woche'
description: ''
trigger:
- platform: time
at: input_datetime.aufstehen_start
condition:
- condition: time
weekday:
- mon
- tue
- wed
- thu
- fri
action:
- service: light.turn_on
data:
brightness: 255
kelvin: 4000
transition: >
{% set offset_hour = state_attr('input_datetime.aufstehen_offset', 'hour') %}
{% set offset_minute = state_attr('input_datetime.aufstehen_offset', 'minute') %}
{% if offset_hour==0 %}
{% set offset_hour_calc = 0 %}
{% else %}
{% set offset_hour_calc = offset_hour * 60 %}
{%endif%}
{% set minute_offset = offset_minute + offset_hour_calc %}
{% set seconds_offset = minute_offset * 60 %}
{{seconds_offset}}
target:
entity_id: >
{% if is_state('input_boolean.aufstehen_bulb1', 'on') %}
{% if is_state('input_boolean.aufstehen_bulb2', 'on') %}
light.alles_schlafzimmer
{%else%}
light.schlafzimmer_bulb1
{%endif%}
{%else%}
{% if is_state('input_boolean.aufstehen_bulb2', 'on') %}
light.schlafzimmer_bulb2
{%else%}
{%endif%}
{%endif%}
mode: single
Here again some calculation for getting the transition time in seconds.
The used lights are selected through the booleans by some if-then-else inside an if-then-else. This isn’t the best solution, but I haven’t found a better way for this so far.
I hope this code might help someone.
And for sure… If you do have any suggestion for improving, I likely would hear them.
Kind regards and have fun,
Lars