Automations with dusk, dawn, night and day period

I’d like to share a way of integrating particular periods of a day into automations. Likewise you can avoid relying on local time as condition for automations to trigger, because - depending on the season - days can be longer (summer) or shorter (winter) and therefore a static time might lead to frustrations.

The issue with the sun component is that the dusk and dawn values are always directed towards future: Once you have gone beyond e.g. the current next_dusk mark, it immediately switches to the next day’s mark. Therefore I used a trick in order to calculate the dusk and dawn zones. As soon as the result of next_dusk minus next_setting becomes negative, I know that I have entered the dusk-period. Once I pass the next_setting mark, this value turns positive, so I know that I just left the dusk-period.

Here’s the sensor component which updates automatically:

  - platform: template
    sensors:
      period_of_day:
        friendly_name: 'period of the day'
        value_template: >-
          {% if (as_timestamp(states.sun.sun.attributes.next_dusk)) - (as_timestamp(states.sun.sun.attributes.next_setting)) < 0 %}
            dusk
          {% elif (as_timestamp(states.sun.sun.attributes.next_rising)) - (as_timestamp(states.sun.sun.attributes.next_dawn)) < 0 %}
            dawn
          {% elif (states.sun.sun.attributes.elevation) < 0 %}
            night
          {% else %}
            day
          {% endif %}
        icon_template: >-
          {% if is_state('sun.sun', 'above_horizon') %}
            mdi:weather-sunny
          {% else %}
            mdi:weather-night
          {% endif %}

The GUI shows this sensor like this, whilst every day period is being displayed in another color:
image
You consume the information provided by the sensor through a value_template as shown in this example:

  - alias: 'turn on light in entry hall when main door opens'
    trigger:
      platform: state
      entity_id: sensor.main_entrance_door
      to: "open"
    condition:
      - condition: template
        value_template: "{{ states.sensor.period_of_day.state != 'day' }}"
    action:
      - service: homeassistant.turn_on
        entity_id: switch.aeotec_zw075_smart_switch_gen5_switch
23 Likes

awesome work! can’t wait to try this out!

update July 2018: I reworked the sensor and made it more precise. The prior version had some glitches when transitioning from dawn to day and from day to dawn (the sensor switched to “night” for a couple of minutes). This new version resolves this problem since it put’s the “day” status to the exit/else condition. Attention: The negative value of the solar angle (-4 in my case) could vary according to your latitude, so you might need to change it to another value.

image

For those of you who like nice icons in the GUI, I added an icon template. Kudos to @Mariusthvdb who brought up this idea.

 - platform: template
   sensors:
     period_of_day:
       friendly_name: 'period of the day'
       value_template: >-
         {% if (as_timestamp(states.sun.sun.attributes.next_dusk)) - (as_timestamp(states.sun.sun.attributes.next_setting)) < 0 %}
           dusk
         {% elif (as_timestamp(states.sun.sun.attributes.next_rising)) - (as_timestamp(states.sun.sun.attributes.next_dawn)) < 0 %}
           dawn
         {% elif (states.sun.sun.attributes.elevation) < -4 %}
           night
         {% else %}
           day
         {% endif %}
       icon_template: >-
         {% if (as_timestamp(states.sun.sun.attributes.next_dusk)) - (as_timestamp(states.sun.sun.attributes.next_setting)) < 0 %}
           mdi:weather-sunset-down
         {% elif (as_timestamp(states.sun.sun.attributes.next_rising)) - (as_timestamp(states.sun.sun.attributes.next_dawn)) < 0 %}
           mdi:weather-sunset-up
         {% elif (states.sun.sun.attributes.elevation) < -4 %}
           mdi:weather-night
         {% else %}
           mdi:weather-sunny
         {% endif %}
17 Likes

Awesome contribution. Many thanks! :slight_smile:

Hello,

Where did you put this code to? I tried in configuration.yaml also separate files and i got syntax errors like: mapping values are not allowed …

I have checked yaml validation, it looks ok.
Sorry if its a dumb question i am pretty new to home assistante.

You should use it in sensor.yaml

nope. still extra keys not allowed @ data[‘sensor’]

Difficult to help you remotely, but let’s give it a try. Be sure that you have the “sun” component activated, so that my sensor can pull values from this component. please follow the instructions for a split config, if this is what you intend to do:

Normally it should work, at least in my config this sensor is still up and running…

Very interesting, exactly what I was looking for, thanks!

This is an excellent utility.

If I want to know when it’s NOT day, is the following valid:

condition: state
entity_id: sensor.period_of_day
state: 'dawn', 'dusk', 'night'

Or do I need three separate conditions to test for NOT day?

Hi Ashscott! This example can be found above:

value_template: "{{ states.sensor.period_of_day.state != 'day' }}"

The “!=” means “not equal to”.

Brilliant. Thank you.

Hi, can anyone tell me how I figure out what value I put for the ‘solar angle’ in this Please ?

I think it is the Elevation attribute from the sun sensor you are looking for?

It was this text in the comments above that made me think I would need to change the solar angle for where I lived…

…‘The negative value of the solar angle (-4 in my case) could vary according to your latitude, so you might need to change it to another value.’

I think it’s a kind of margin he built in for properly transitioning to and from the night state. My suggestion would be to just try as is. If night state seems to start or end at the wrong time, adjust -4 higher or lower.

Hi I really like this component! I was wondering if there was a way to do math in the template or something to create an offset for when the state transitions into dusk? There’s got to be a way to subtract 30 minutes from the next_dusk attribute right?

Hi Derek! So you want to understand when the day-period transitions into dusk? You’re right, it’s usually 30 minutes before night falls. However, a template (at least mine) is not forward-looking, and cannot take into consideration elements which have either not yet happened or not calculated (such as the next_rising value for instance).

How about working with a trigger in an automation, like this:

trigger:
  - platform: state
    entity_id: sensor.period_of_day
    from: 'day'
    to: 'dusk'

If you describe your use case better, we might help better as well :smiley:

Thanks for the reply @mastermarkush and thanks again for making this component with comprehensive instructions.

I’m using your component to trigger my sunset actions by triggering when the state moves away from “day”. However, I feel like that’s a little later than I’d like. I was really hoping I could find a way to subtract 30 minutes from the next_dusk time and have “day” transition into “dusk” at that time.

Thanks

This is a really good sensor thanks, do you know if it is possible to add an offset as this would be great for automation

Cheers

Rich