Wake-up light alarm with sunrise effect

Hi,

I hope all these requests aren’t too much, but I got one myself :roll_eyes:
When I snooze my alarm, the wake-up light turns on instantly, because the automation is triggered again. Could we change this to only trigger once per day or that it’s not triggered again by snoozing?
Maybe a delay of 10 minutes at the end of the automation would be enough (as it’s in a “single” mode)

What do you think?

1 Like

@Maggiifixx you can set an input_datetime as timestamp sensor (even when you cannot select it in the dropdown) by manually inputting it in the timestamp sensor input. However it needs to be an input_datetime that has both date & time set.

@capstan1: I guess I could add a custom action block that runs after the sunrise where you could do that.

1 Like

Hi, thank you for making this blueprint. It is great.
I have an improvement proposal. It is possible to turn off the light during sunrise, but it is not possible to set it to full brightness during sunrise. At least for me it goes back to the brightness level it was at.
What do you think?

New update posted.

  • The initial turn-on has been improved to not skip the first minute in some cases.
  • Template conditions have been cleaned a bit.
  • You can define post-sunrise actions now.
  • The automation now checks not only for the light having been turned off manually but also if it has been set to a brightness value at or above the max. brightness. In either case the sunrise effect is halted.
3 Likes

Thanks for your quick reply and update.

Unfortunately I don’t have an iOS shortcut for the timestamp sensor yet, only an input for the time and an on/off switch for the automation. Maybe someone has an idea or a link to a solution, in which then also the required date is included.

You could create a template sensor in your configuration.

sensor:
  - platform: template
    sensors:
      alarm_time:
        value_template: "{{states('sensor.date') ~ ' ' ~ states('input_datetime.XYZ')}}"
        device_class: timestamp

and then use the resulting sensor.alarm_time

2 Likes

works perfectly, thank you very much!

Edit:
I noticed that the alarm time falls on the same day and not the next when using your template sensor from here.
Is there perhaps also a solution for this?

I use the following iOS shortcut command:
https://www.icloud.com/shortcuts/5bc9cfa0af234f349f48486782b39348

2 Likes

Great blueprint!

What kind of lights do you use? I am using LIDL GU10 bulbs and they seem to not respond to the minimal brightness and color temperature adjustments done by the blueprint.

Maybe it is an idea to add a list of supported bulbs?

Hi,

Love this Blueprint - works great!

I’ve a suggestion for an improvement, and one question.

For the improvement, you have a variable for how long BEFORE the alarm the routine starts. Can you add to that how long AFTER the alarm it should finish (Default=0). This would mean that you can:

  • Start the sunrise effect and finish at the alarm time (as is)
  • Start the sunrise effect before the alarm and finish sometime after (e.g. 5 mins before to 10 mins after)
  • Start the sunrise effect at the alarm time (e.g. at alarm time, for 10 mins).

I “think” this would be a relatively trivial change to add a second variable and add this number of minutes to the alarm time. And it would be a great improvement to the functionality!

Also, for the question - can you have the start and end brightness the other way around - so that you can go from bright to dim/off? e.g. I could set a manual time of 10pm and have the lights dim down to 0 starting 15 mins before? If not, again, this could be a great addition too.

Thanks!

Hi All,

A little new to HA but have been adding custom blueprints and changing Config files for a few months now and I cannot seem to get this to work. I get the automation to trigger right on time but my bulbs dont turn on. One time they did but then they didnt cycle the colors or brightness (was doing a 5min sunrise test).

I am using TP-Link Kasa TL-130 smart bulbs that have pretty robust integration with HA but dont seem to want to work with this (19 supported features, min_mireds:111, max_mireds:400, color temp, etc.) I followed all of the troubleshooting steps but still no avail. Below is my YAML and 2 template errors I cant decode from my log file.

Any help would be much appreciated by my wife!

Logger: homeassistant.helpers.event
Source: helpers/template.py:355
First occurred: 7:55:00 AM (4 occurrences)
Last logged: 7:56:11 AM

Error while processing template: Template("{{0 < as_timestamp(states(sensor) if sensor != ‘none’ else states(‘sensor.date’) ~ ’ ’ ~ manual_time) - as_timestamp(states(‘sensor.date_time_iso’)) <= float(seconds) and states(check_entity) in [‘unknown’, ‘on’, ‘home’]}}")
Error while processing template: {{0 < as_timestamp(states(sensor) if sensor != ‘none’ else states(‘sensor.date’) ~ ’ ’ ~ manual_time) - as_timestamp(states(‘sensor.date_time_iso’)) <= float(seconds) and states(check_entity) in [‘unknown’, ‘on’, ‘home’]}}
Traceback (most recent call last):
File “/usr/src/homeassistant/homeassistant/helpers/template.py”, line 353, in async_render
render_result = compiled.render(kwargs)
File “/usr/local/lib/python3.8/site-packages/jinja2/environment.py”, line 1090, in render
self.environment.handle_exception()
File “/usr/local/lib/python3.8/site-packages/jinja2/environment.py”, line 832, in handle_exception
reraise(*rewrite_traceback_stack(source=source))
File “/usr/local/lib/python3.8/site-packages/jinja2/_compat.py”, line 28, in reraise
raise value.with_traceback(tb)
File “”, line 1, in top-level template code
TypeError: unsupported operand type(s) for -: ‘float’ and ‘NoneType’

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File “/usr/src/homeassistant/homeassistant/helpers/template.py”, line 462, in async_render_to_info
render_info._result = self.async_render(variables, **kwargs)
File “/usr/src/homeassistant/homeassistant/helpers/template.py”, line 355, in async_render
raise TemplateError(err) from err
homeassistant.exceptions.TemplateError: TypeError: unsupported operand type(s) for -: ‘float’ and ‘NoneType’

Logger: homeassistant.helpers.condition
Source: helpers/condition.py:458
First occurred: 7:55:00 AM (2 occurrences)
Last logged: 7:56:00 AM

Error during template condition: TypeError: unsupported operand type(s) for -: ‘float’ and ‘NoneType’

I really appreciate this blueprint, was working on some automations myself, saved me a lot of time! Question: how can I disable the manual alarm time? I use the alarm from my (Android) phone with the sensor from the companion app. When I don’t set any alarm (which is often the case now with corona lockdown) I don’t want any sunrise effect on whatever time. Maybe the manual alarm time can be optional? For example when no time is entered, the wake-up light will not start.

When no alarm is set on the phone, the sensor becomes unavailable. So I could make an automation 'when sensor unavailable disable the wake-up light, or something like that. Would be nice to be able to do it within the blueprint.

Manual alarm time should only be used if you put ‘none’ in the sensor entity input. So as long as you have put your alarm sensor in there you should be fine.

Ah, some misinterpretation of the documentation on my side. I thought the manual time would be used when the value of a selected sensor is empty. I will test it anyway to be sure, don’t want to be rudely awakened on a free morning :wink:

I’ve made a mod to this blue print that may be able to be handled by the timestamp_sensor. It may or may not be of value, but it allows for the creation of different alarms depending on the day of the week. These could be input_booleans set in the UI.

Addition to input:

  input:
    sunday_alarm:
      name: Set alarm for Sunday (Optional)
      description: Choose on for to turn alarm on for Sunday
      default: false
      selector:
        boolean: {}
    monday_alarm:
      name: Set alarm for Monday (Optional)
      description: Choose on for to turn alarm on for Monday
      default: false
      selector:
        boolean: {}
    tuesday_alarm:
      name: Set alarm for Tuesday (Optional)
      description: Choose on for to turn alarm on for Tuesday
      default: false
      selector:
        boolean: {}
    wednesday_alarm:
      name: Set alarm for Wednesday (Optional)
      description: Choose on for to turn alarm on for Wednesday
      default: false
      selector:
        boolean: {}
    thursday_alarm:
      name: Set alarm for Thursday (Optional)
      description: Choose on for to turn alarm on for Thursday
      default: false
      selector:
        boolean: {}
    friday_alarm:
      name: Set alarm for Friday (Optional)
      description: Choose on for to turn alarm on for Friday
      default: false
      selector:
        boolean: {}
    saturday_alarm:
      name: Set alarm for Saturday (Optional)
      description: Choose on for to turn alarm on for Saturday
      default: false
      selector:
        boolean: {}

additions to variables:

variables:
  sunday_alarm: !input 'sunday_alarm'
  monday_alarm: !input 'monday_alarm'
  tuesday_alarm: !input 'tuesday_alarm'
  wednesday_alarm: !input 'wednesday_alarm'
  thursday_alarm: !input 'thursday_alarm'
  friday_alarm: !input 'friday_alarm'
  saturday_alarm: !input 'saturday_alarm'

additions to condition:

condition:
  - condition: or
    conditions:
      - condition: and
        conditions:
          - condition: template
            value_template: '{{ states[sunday_alarm].state == ''on'' }}'
          - condition: time
            weekday:
              - sun
      - condition: and
        conditions:
          - condition: template
            value_template: '{{ states[monday_alarm].state == ''on'' }}'
          - condition: time
            weekday:
              - mon
      - condition: and
        conditions:
          - condition: template
            value_template: '{{ states[tuesday_alarm].state == ''on'' }}'
          - condition: time
            weekday:
              - tue
      - condition: and
        conditions:
          - condition: template
            value_template: '{{ states[wednesday_alarm].state == ''on'' }}'
          - condition: time
            weekday:
              - wed
      - condition: and
        conditions:
          - condition: template
            value_template: '{{ states[thursday_alarm].state == ''on'' }}'
          - condition: time
            weekday:
              - thu
      - condition: and
        conditions:
          - condition: template
            value_template: '{{ states[friday_alarm].state == ''on'' }}'
          - condition: time
            weekday:
              - fri
      - condition: and
        conditions:
          - condition: template
            value_template: '{{ states[saturday_alarm].state == ''on'' }}'
          - condition: time
            weekday:
              - sat
2 Likes

I’m trying to amend this to add a “after” duration as well as “before”. I’ve got part way, but I’m struggling to get my head around the logic in the repeat section. What I think it needs is to repeat for longer (not just for the number of seconds as before, but for the number of seconds before and after the alarm), and to adjust the brightness accordingly.

Any pointers?

blueprint:
  name: Wake-up light alarm with sunrise effect - WITH END TIME
  description: 'A wake-up light alarm with a brightness and color temperature sunrise
    effect. Note: Requires date_time_iso sensor in configuration, not manually executable!'
  domain: automation
  input:
    light_entity:
      name: Wake-up light entity
      description: The light to control. Turning it off during the sunrise will keep
        it off. Color temperature range is auto-detected.
      selector:
        entity:
          domain: light
    timestamp_sensor:
      name: Alarm timestamp sensor
      description: 'Sensor with timestamp of next alarm with device_class: timestamp
        (set to ''none'' for manual alarm time)'
      default: none
      selector:
        entity:
          device_class: timestamp
    manual_time:
      name: Manual alarm time
      description: Time to trigger alarm every day if timestamp sensor is not set.
        Settings at or shortly after midnight will not work as expected!
      default: '7:00:00'
      selector:
        time: {}
    check_entity:
      name: Additional entity to check before sunrise is triggered
      description: If set, checks if entity is 'on' or 'home' before triggering. Use
        e.g. a (workday) sensor, device_tracker or person entity.
      default: none
      selector:
        entity: {}
    sunrise_duration:
      name: Sunrise duration
      description: The sunrise will start the configured number of minutes before
        the timestamp.
      default: 5
      selector:
        number:
          min: 1.0
          max: 60.0
          step: 1.0
          unit_of_measurement: min
          mode: slider
    sunrise_finish:
      name: Sunrise finish
      description: The number of minutes after the alarm to continue
        the timestamp.
      default: 5
      selector:
        number:
          min: 1.0
          max: 60.0
          step: 1.0
          unit_of_measurement: min
          mode: slider
    start_brightness:
      name: Minimum brightness
      description: The brightness to start with. Some lights ignore very low values
        and may turn on with full brightness instead!
      default: 1
      selector:
        number:
          min: 1.0
          max: 255.0
          step: 1.0
          mode: slider
    end_brightness:
      name: Maximum brightness
      description: The brightness will be transitioned from the minimum to the configured
        value.
      default: 255
      selector:
        number:
          min: 5.0
          max: 255.0
          step: 1.0
          mode: slider
    min_mired:
      name: Minimum color temperature
      description: 'The minimum color temperature to use. (0: lowest supported)'
      default: 0
      selector:
        number:
          min: 0.0
          max: 500.0
          step: 5.0
          mode: slider
          unit_of_measurement: mired
    pre_sunrise_actions:
      name: Pre-sunrise actions
      description: Optional actions to run before sunrise starts.
      default: []
      selector:
        action: {}
    post_sunrise_actions:
      name: Post-sunrise actions
      description: Optional actions to run after sunrise ends (around the alarm time).
      default: []
      selector:
        action: {}
  source_url: https://gist.github.com/sbyx/96c43b13b90ae1c35b872313ba1d2d2d
variables:
  light_entity: !input 'light_entity'
  sensor: !input 'timestamp_sensor'
  sunrise_duration: !input 'sunrise_duration'
  sunrise_finish: !input 'sunrise_finish'
  start_brightness: !input 'start_brightness'
  end_brightness: !input 'end_brightness'
  range_brightness: '{{float(end_brightness)-float(start_brightness)}}'
  manual_time: !input 'manual_time'
  seconds: '{{float(sunrise_duration) * 60}}'
  duration: '{{ ( float(sunrise_duration) + float(sunrise_finish) ) * 60}}'
  min_mired: !input 'min_mired'
  start_mired: '{{state_attr(light_entity, ''max_mireds'')}}'
  end_mired: '{{[state_attr(light_entity, ''min_mireds'')|int, min_mired|int]|max}}'
  tick_time: '{{float(duration) / float(range_brightness)}}'
  check_entity: !input 'check_entity'
trigger:
- platform: time_pattern
  minutes: '*'
condition: []
action:
- wait_template: '{{sensor == ''none'' or as_timestamp(states(sensor)) != None}}'
- wait_template: '{{0 < as_timestamp(states(sensor) if sensor != ''none'' else states(''sensor.date'')
    ~ '' '' ~ manual_time) - as_timestamp(states(''sensor.date_time_iso'')) <= float(seconds)
    and states(check_entity) in [''unknown'', ''on'', ''home'']}}'
- choose: []
  default: !input 'pre_sunrise_actions'
- condition: template
  value_template: '{{sensor == ''none'' or as_timestamp(states(sensor)) != None}}'
- condition: template
  value_template: '{{0 < as_timestamp(states(sensor) if sensor != ''none'' else states(''sensor.date'')
    ~ '' '' ~ manual_time) - as_timestamp(now()) <= float(seconds) and states(check_entity)
    in [''unknown'', ''on'', ''home'']}}'
- choose:
  - conditions:
    - '{{state_attr(light_entity, ''min_mireds'') != None}}'
    sequence:
    - service: light.turn_on
      data:
        brightness: '{{start_brightness}}'
        color_temp: '{{start_mired}}'
      entity_id: !input 'light_entity'
  default:
  - service: light.turn_on
    data:
      brightness: '{{start_brightness}}'
    entity_id: !input 'light_entity'
- repeat:
    while:
    - '{{sensor == ''none'' or as_timestamp(states(sensor)) != None}}'
    - '{{0 < as_timestamp(states(sensor) if sensor != ''none'' else
        states(''sensor.date'') ~ '' '' ~ manual_time) - as_timestamp(now()) <= float(duration)}}'
    sequence:
    - delay: '{{tick_time}}'
    - choose:
      - conditions:
        - '{{0 < state_attr(light_entity, ''brightness'') | int < end_brightness | int}}'
        - '{{sensor == ''none'' or as_timestamp(states(sensor)) != None}}'
        - '{{0 < as_timestamp(states(sensor) if sensor != ''none'' else
          states(''sensor.date'') ~ '' '' ~ manual_time) - as_timestamp(now()) <= float(duration)}}'
        sequence:
        - choose:
          - conditions:
            - '{{state_attr(light_entity, ''min_mireds'') != None}}'
            sequence:
            - service: light.turn_on
              data:
                brightness: '{{(float(end_brightness) - (float(range_brightness) *
                  (as_timestamp(states(sensor) if sensor != ''none'' else states(''sensor.date'')
                  ~ '' '' ~ manual_time) - as_timestamp(now())) / float(duration))) | int}}'
                color_temp: '{{(float(end_mired) + (float(start_mired) - float(end_mired))
                  * ((as_timestamp(states(sensor) if sensor != ''none'' else states(''sensor.date'')
                  ~ '' '' ~ manual_time) - as_timestamp(now())) / float(duration))) | int}}'
              entity_id: !input 'light_entity'
          default:
          - service: light.turn_on
            data:
              brightness: '{{(float(end_brightness) - (float(range_brightness) * (as_timestamp(states(sensor)
                if sensor != ''none'' else states(''sensor.date'') ~ '' '' ~ manual_time)
                - as_timestamp(now())) / float(duration))) | int}}'
            entity_id: !input 'light_entity'
- choose: []
  default: !input 'post_sunrise_actions'
mode: single
max_exceeded: silent

EDIT: It seems that the Adaptive/Circadian lighting HACS integration was preventing the lights to start at minimum brightness. The key was to turn it off before sunrise alarm and turn it back on after.

Is anyone having issues with Philips Hue lights? I am testing it out with a single hue light and it seems to just turn on at full brightness and do nothing after that?

Mine went full brightness and then blinked every so often…

Got the same problem but with other lights (LIDL Smart lights). Thought my lights did not support the small steps in increase of brightness / color temp. But now I see your post it seems that the lamps are not the problem. Can anybody help? Or is this a known problem? @Sbyx do you recognize this problem?

alias: Wake-up light alarm with sunrise effect
description: ''
use_blueprint:
  path: sbyx/wake-up-light-alarm-with-sunrise-effect.yaml
  input:
    light_entity: light.extended_color_light_3
    end_brightness: '254'
    manual_time: '10:02:00'
    start_brightness: '1'
    min_mired: '140'
    sunrise_duration: '30'

@Sbyx @sgobat

Found my own stupid mistake which made the lights go from lowest brightness / color temp to highest brightness / color temp very fast… I set the transition time to be half an hour but then to test it i set the alarm only 1 / 2 minutes in the future. This made the automation execute the light transition in that 1 / 2 minutes.

Just started automating my home haha :smiley: At least I could laugh at my own dumb mistake

I don’t know if it would be possible to add that the input_datetime or manual time at least has to be the current time + transition time.

Seems like @wolfer4004 also has the same issue

1 Like

I’m just curious but will this work with rolling days?

Say that you want the alarm to start at 00:10:00 (just after midnight) with a duration of 25 minutes.
This wait_template implies that it will not work.

0 < as_timestamp(states(sensor) if sensor != ''none'' else states(''sensor.date'')
    ~ '' '' ~ manual_time) - as_timestamp(states(''sensor.date_time_iso'')) <= float(seconds)

Test:

{%- set manual_time = '00:10:00' %}
{%- set seconds = 25*60 %}
{%- set date =  "2021-01-22" %}
{%- set nnow =  strptime("2021-01-22T23:55", "%Y-%m-%dT%H:%M")%}
{{ as_timestamp(date ~ ' ' ~ manual_time) - as_timestamp(nnow) }}
{{ 0 < as_timestamp(date ~ ' ' ~ manual_time) - as_timestamp(nnow) <= float(seconds) }}

Returns False.

This is a suggestion on how to fix it:


{% set date =  "2021-01-22" %}
{% set seconds = 25*60 -%}
Seconds to consider: {{ seconds }}
{% for manual_time in ['23:56:00', '00:10:00'] %}
{%- for iso_date in ["2021-01-22T23:55", "2021-01-22T22:55", ] %}
{%- set nnow =  strptime(iso_date, "%Y-%m-%dT%H:%M")%}
{% set time_diff = (as_timestamp(date ~ ' ' ~ manual_time) - as_timestamp(nnow) ) -%}
Alarm time: '{{manual_time}}', now: {{nnow}}:
Original: {{ 0 < as_timestamp(date ~ ' ' ~ manual_time) - as_timestamp(nnow) <= float(seconds) }},  0 > {{as_timestamp(date ~ ' ' ~ manual_time) - as_timestamp(nnow) }} <= {{ seconds }}
New: {{ (0 < time_diff <= seconds) or  ((24*60*60)-seconds < time_diff*-1 < (24*60*60))
}}, {{ 0 }} < {{time_diff}} <= {{seconds}} or {{(24*60*60)-seconds }} < {{ time_diff*-1}} < {{(24*60*60) }}
{%- endfor %}
{%- endfor %}

Which outputs this:

Seconds to consider: 1500

Alarm time: '23:56:00', now: 2021-01-22 23:55:00:
Original: True,  0 > 60.0 <= 1500
New: True, 0 < 60.0 <= 1500 or 84900 < -60.0 < 86400
Alarm time: '23:56:00', now: 2021-01-22 22:55:00:
Original: False,  0 > 3660.0 <= 1500
New: False, 0 < 3660.0 <= 1500 or 84900 < -3660.0 < 86400
Alarm time: '00:10:00', now: 2021-01-22 23:55:00:
Original: False,  0 > -85500.0 <= 1500
New: True, 0 < -85500.0 <= 1500 or 84900 < 85500.0 < 86400
Alarm time: '00:10:00', now: 2021-01-22 22:55:00:
Original: False,  0 > -81900.0 <= 1500
New: False, 0 < -81900.0 <= 1500 or 84900 < 81900.0 < 86400

Suggestion for change:

- wait_template: '{{0 < as_timestamp(states(sensor) if sensor != ''none'' else states(''sensor.date'')
    ~ '' '' ~ manual_time) - as_timestamp(states(''sensor.date_time_iso'')) <= float(seconds)
    and states(check_entity) in [''unknown'', ''on'', ''home'']}}'
#TO
- wait_template: >-
    {% set time_diff = as_timestamp(states(sensor) if sensor != 'none' else 
    states('sensor.date') ~ ' ' ~ manual_time) - as_timestamp(states('sensor.date_time_iso')-%}
    {{(0 < time_diff <= float(seconds) or (86400 - float(seconds) < time_diff|abs < 86400) and 
    states(check_entity) in ['unknown', 'on', 'home']}}