Automations with dusk, dawn, night and day period

Hi Rich!

You can set a positive (forward pointing) offset, for example through a delay in your automation. You unfortunately cannot set backward pointing offsets with this sensor, because the ‘period of the day’ calculates dynamically and it is unknown to homeassistant as to when the value changes.

-Markus

Hi, this doesn’t work «universally». I live in the arctic region, so we wont see the sun above the horizon until 21st of january and this is current data:

next_rising: 2021-01-14T10:47:56+00:00
next_setting: 2021-01-14T10:58:25+00:00

This code will keep the sensor as «dusk» until 14th og January.

This is a sensor that works based on elevation. It’s worked out together with an employee of The Norwegian Meteorological Institute (met.no and yr.no)

sensor:
  - platform: template
    sensors:
      period_of_day:
        friendly_name: 'Period of the day'
        value_template: >-
          {% set elevation = state_attr('sun.sun', 'elevation') %}
          {% set rising = state_attr('sun.sun', 'rising') %}
          {%- if elevation <= -12 -%}
            night
          {%- elif -12 < elevation <= -6 -%}
            {{ 'dawn' if rising else 'dusk' }}
          {%- else -%}
            day
          {%- endif -%}light
        icon_template: >-
          {% set elevation = state_attr('sun.sun', 'elevation') %}
          {% set rising = state_attr('sun.sun', 'rising') %}
          {%- if elevation <= -12 -%}
            mdi:weather-night
          {%- elif -12 < elevation <= -6 -%}
            mdi:weather-sunset-{{ 'up' if rising else 'down' }}
          {% else %}
            mdi:weather-sunny
          {% endif %}

Between -12 and -6 is nautical dusk/dawn, and between -6 and 0 is «normal dusk/dawn». They consider everything between -6 and greater as «daylight», and I’m using this mostly in automation, so I’ve choosen this range (-12 to -6 as dusk/dawn). But you can tweak it for your linking. :slight_smile:

EDIT: Updated the code. Forgot to alter the icon_template.

14/12/2020: Updated the code.

7 Likes

Hello Joachim!

You demonstrate the true power of this forum: Exchange good - better - best ideas. Quite frankly, your sensor is literally “universal”, since it uses the sun’s elevation as basic criteria. Don’t know why I didn’t come up with the idea when I wrote my sensor, I believe that the sun attributes were not yet available in hass at that point of time.

Thumbs up, good work!

Cheers,
Markus

Anyone got it working for their region? I have tried to tweak the numbers, but it does not show dusklight or dawnlight. Just daylight or nightlight.

The original updated code works. For my region (japan), dawn is about 06:09 and dusk is about 16:30.

 - 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 %}

Hi, I don’t recognize the code you’ve pasted as the version in my post. However, I found a bug in the code and have updated it.

Which version of HA are you running? From masterkarkush’s post, the elevation values is probably available in newer versions of HA.

Which version of HA are you running?
Ah, that may explains it. I am running 0.117

I don’t recognize the code you’ve pasted as the version in my post.
The code is from the OP, 3rd post from top.

Ah, you had posted as a reply to my post, so got confused. But the reason why I rewrote the code, was simply because the solution you’re using didn’t work in my region either.

Have a look at this. Automations with dusk, dawn, night and day period

There’s a bug in your logic comparison, in order to compare a range you need to chain two boolean expressions with a binary and.
The a > b < c expression valid in math isn’t normally in programming languages; therefore the ‘<= -6’ condition is never checked and ‘day’ condition is never trigged.
I guess since it’s pretty far away for you, it’d have taken you a while to notice it :smile:.

       period_of_day:
        friendly_name: 'Period of the day'
        value_template: >-
          {% set elevation = state_attr('sun.sun', 'elevation') %}
          {% set rising = state_attr('sun.sun', 'rising') %}
          {%- if elevation <= -12 -%}
            night
          {%- elif elevation > -12 and elevation <= -6 -%}
            {{ 'dawn' if rising else 'dusk' }}
          {%- else -%}
            day
          {%- endif -%}light
        icon_template: >-
          {% set elevation = state_attr('sun.sun', 'elevation') %}
          {% set rising = state_attr('sun.sun', 'rising') %}
          {%- if elevation <= -12 -%}
            mdi:weather-night
          {%- elif elevation > -12 and elevation <= -6 -%}
            mdi:weather-sunset-{{ 'up' if rising else 'down' }}
          {% else %}
            mdi:weather-sunny
          {% endif %}

Hi, this high > this < low is a valid comparison. However, you’re quoting the old code - with the bug (which had this < high < low). The code was updated 2 days ago- and yes Compound Boolean Expressions is valid.

1 Like

I really like this solution, but at least for Germany the values aren’t quite right. Dawn was between 3:53 and 4:42am tonight, so when the sensor switched to “day”, it was still pitch black outside. Where are the elevation values -12 and -6 coming from?

@ dantist
Seems like Germany and Japan share the same day periods. Can you post your codes?

Hi,

My code only respect “Nautical dusk/dawn” from -12 to -6 degree angle of the sun towards the earth.

If you want to include civil dusk/dawn too, change -6 to 0. Let me know if you also want to separate between civil and nautical, and I’ll write an updated code for you.

The meteorologists that I worked this out with said they considered the civil dusk/dawn as part of the daylight.

I mostly use this for light automation outdoor and I don’t see the need of keeping the light on until it’s fully bright. The light can be quite dim before turned on/off.

But got to admit that it’s strange that it switched when it was pitch black :flushed:

Hi Joachim, I’m using the sensor to define the brightness of indoor lighting. When you switch on the lights during daytime, they are set to 100%. During dusk/dawn to 70% and at night to 10%. I’m afraid I don’t know the difference between civil and nautical dusk/dawn, but my goal is to define the times where there’s still a little bit of daylight outside, but already/still dark enough that you need to use indoor lighting.

@mastermarkush awesome job! Thanks for sharing! :grinning:

1 Like

Works fine for me:

- 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') == 'above_horizon' %}
          day
        {% else %}
          night
        {% 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') == 'above_horizon' %}
          mdi:weather-sunny
        {% else %}
          mdi:weather-night
        {% endif %}
1 Like

Little update on that:

    - name: Period of the day
      unique_id: period_of_day
      state: >
        {% if (as_timestamp(state_attr('sun.sun','next_dusk'))) - (as_timestamp(state_attr('sun.sun','next_setting'))) < 0 %}
          dusk
        {% elif (as_timestamp(state_attr('sun.sun','next_rising'))) - (as_timestamp(state_attr('sun.sun','next_dawn'))) < 0 %}
          dawn
        {% elif is_state('sun.sun','above_horizon') %}
          day
        {% else %}
          night
        {% endif %}
      icon: >
        {% if (as_timestamp(state_attr('sun.sun','next_dusk'))) - (as_timestamp(state_attr('sun.sun','next_setting'))) < 0 %}
          mdi:weather-sunset-down
        {% elif (as_timestamp(state_attr('sun.sun','next_rising'))) - (as_timestamp(state_attr('sun.sun','next_dawn'))) < 0 %}
          mdi:weather-sunset-up
        {% elif is_state('sun.sun','above_horizon') %}
          mdi:weather-sunny
        {% else %}
          mdi:weather-night
        {% endif %}
3 Likes

With this latest code, I have sometimes 2 minutes of night between dawn and day

    period_of_day:
      friendly_name: 'Period of the day'
      value_template: >-
        {% if (as_timestamp(states.sun.sun.attributes.next_dusk)) - (as_timestamp(now())) < 3600 %}
          dusk
        {% elif (as_timestamp(now)) - (as_timestamp(states.sun.sun.attributes.next_rising)) < 3600 %}
          dawn
        {% elif states('sun.sun') == 'above_horizon' %}
          day
        {% else %}
          night
        {% endif %}

Can someone with greater knowledge than me check the logic of this please, would it trigger ‘dusk’ as an hour before next_dusk and dawn for an hour after next rising?

hope that makes sense

It’s a bit sad, to see people still referring to the code of the original post, while the code from @joachimmg is a bit more stable. Only relying on the elevation instead of comparing future events is easier to understand and more stable.
Maybe @mastermarkush you could add a reference in your original post? I know you already selected Joachim’s Post as a solution but obviously that’s not enough.

For other people stumbling upon this I recommend to read at least the beginning of the Wikipedia article for nautical and civil dusk and dawn. Then you understand the meaning of -12, -6 and -3 degree elevation.

For turning OFF lights and opening shades in the morning I recommend to use civil dusk, but I’m still looking for a good way to also dynamically include some weather conditions to wait a bit longer if it’s foggy or very cloudy outside or if it’s very cold to benefit a bit longer from the additional isolation of my shades…

Once you go into automation you notice how you treat this differently in summer, winter, spring and autumn, clear sky, foggy,…

2 Likes