Next_dawn next_dusk in automation

I think I found out by myself and I can just use dusk and dawn instead of sunrise and sunset.
This wasn’t well documented and I was wondering why in the examples is just sunrise and sunset mentioned, but the attributes for this time value called next_rising and next_setting. I will test dusk and dawn now.

Please report back if this works and what you used

I am using a sun angle below 10 degrees (or something like that) to compensate for different light levels for different times of year - but dusk and dawn might work better

It depends if HA defines twilight by angle (6°) or time (24minutes). Time after sunset or before sunrise will not give you seasonal adjustments. Angle below the horizon will (and should be used). Even though the sun appears to move at a constant rate of 15° an hour the angle of the ecliptic will cause seasonal variations in twilight length as measured by time. See my awesome illustration skill here:

2 Likes

Thanks for your explanation. But I think your are wrong with your point of longer twilight in winter. I live in the northern hemisphere and used this page for calculate the civil twilight http://jekophoto.eu/tools/twilight-calculator-blue-hour-golden-hour/index.php
And this show me for March and my geo positions a civil twilight of 34 minutes and for June I’ve got 46 minutes. Which shows me a longer twilight in summer.
I tested with the event “dusk” and “dawn” but this are no events that are fired. Even at the restart of homeassistant I’ve got a message about a broken automations configuration.
It wouldb be more easy to use if “dusk” and “dawn” where events like “sunset” and “sunrise”.

1 Like

Use the sun elevation attribute, which you can then tweak to suit yourself. For instance here I use -5.

Civil dusk is defined as -6 degrees, so if you’re after dusk/dawn then the elevation is exactly what you’re after :wink:

1 Like

Thanks, I set this now up with the elevation.

- alias: "Housedoorlight on"
  trigger:
    - platform: numeric_state
      entity_id: sun.sun
      value_template: '{{ state.attributes.elevation }}'
      below: -5.9
  action:
    service: homeassistant.turn_on
    entity_id: switch.house_door_light

- alias: "Housedoorlight off"
  trigger:
    - platform: numeric_state
      entity_id: sun.sun
      value_template: '{{ state.attributes.elevation }}'
      above: -5.9
  action:
    service: homeassistant.turn_on
    entity_id: switch.house_door_light
4 Likes

Geez I hate being wrong, but you are absolutely correct. Twilight is shortest at the exinoxes and longest in summer. My mistake was the same as this blokes: https://astronomy.stackexchange.com/questions/2408/why-is-twilight-longer-in-summer-than-winter-and-shortest-at-the-equinox

The angle of the ecliptic and horizon doesn’t actually change with time of year, just latitude.

You would still be accounting for this if using the angle of the sun below the horizon (6 deg) for calculating the time to switch, rather than a fixed time offset.

1 Like

If you need to do more with that elevation you can also use intermediate binary sensors. Create a template sensor or threshold sensor.

So I like this and set it to come on below 25° however I think I need another condition so it doesn’t come on in the mornings?

So I want my lounge room lights to come on when the sun is lower than 25° and I manually turn them off when I go to bed at 10pm and I don’t want them to come on again until tomorrow at 25° again…

Will this work?

- action:
  - data:
      brightness_pct: 75
      entity_id: light.lounge
      kelvin: 3100
    service: light.turn_on
  alias: Turn Lounge Light On elevation below 25 degrees
  condition:
  - after: '12:00:00'
    before: '22:00:00'
    condition: time
  id: '1505977024304'
  trigger:
  - below: '25'
    entity_id: sun.sun
    platform: numeric_state
    value_template: '{{ state.attributes.elevation }}'
1 Like

Hi,
I think this will just work for turning on the Lounge Light, for turning off you need an extra action. But the trigger looks fine for me.

Yes it does seem to work.
I don’t need it to turn off on an automation - I just tell Google to turn lights off when I go to bed.

With regards to next_dusk and next_dawn in action please see my example within the circadian lights automation. This relies on a sensor that dynamically calculates the period of day which I’m in (of course this is independent from local time, any time zones or the ever-changing day length).

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.

I do the same for ‘next_dawn’ and this is how the sensor looks like:

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

This is what’s shown in the GUI:
image

You can find the holistic integration with circadian lights below:

4 Likes

I made some changes to @mastermarkush’s sensor and it’s now working nice regardless the zone you live:


  - platform: template
    sensors:
      altura_do_dia:
        friendly_name: 'Altura do dia'
        value_template: >-
          {% set rising = (as_timestamp(states.sun.sun.attributes.next_rising)) < (as_timestamp(states.sun.sun.attributes.next_dawn)) %}
          {% set setting = (as_timestamp(states.sun.sun.attributes.next_dusk)) < (as_timestamp(states.sun.sun.attributes.next_setting)) %}
          {%- if is_state('sun.sun', 'above_horizon') %}
            Dia
          {%- elif is_state('sensor.altura_do_dia', 'Dia') and setting %}
            Anoitecer
          {%- elif is_state('sensor.altura_do_dia', 'Anoitecer') and not setting %}
            Noite
          {%- elif is_state('sensor.altura_do_dia', 'unavailable') and is_state('sun.sun', 'below_horizon') %}
            Noite
          {%- elif is_state('sensor.altura_do_dia', 'Noite') and rising %}
            Amanhecer
          {%- else %}
            {{ states('sensor.altura_do_dia') }}
          {%- endif %}
        icon_template: >-
          {%- if is_state('sensor.altura_do_dia', 'Dia') %}
            mdi:weather-sunny
          {%- elif is_state('sensor.altura_do_dia', 'Anoitecer') %}
            mdi:weather-sunset-down
          {%- elif is_state('sensor.altura_do_dia', 'Noite') %}
            mdi:weather-night
          {%- elif is_state('sensor.altura_do_dia', 'Amanhecer') %}
            mdi:weather-sunset-up
          {%- else %}
            mdi:alert-circle
          {%- endif %}

Result:

The difference is that I’m just changing the value once, and then keep the value until the next change. This prevents it from boucing when changing from dawn to day.

1 Like

Hi Gerald,

Did you manage to turn on your lights at dusk in automation?

For anyone interested.

Here is how got my dusk automation working

1 Like

This reads like the awesome template that I’d love to use. However, if I try this in the developer tools the value I get back is “unknown”:

It won’t work on that menu because the sensor reads its own value to set the next value.
As you didn’t create the sensor yet, you get the ‘unknown’.

For it to work you need to add it to your yaml configuration.

1 Like

Isn’t it all there then?

- sensor:
    - name: "Alturo do Dia"
      unique_id: sensor.altura_do_dia
      state: >-
        {% set rising = (as_timestamp(states.sun.sun.attributes.next_rising)) < (as_timestamp(states.sun.sun.attributes.next_dawn)) %}
        {% set setting = (as_timestamp(states.sun.sun.attributes.next_dusk)) < (as_timestamp(states.sun.sun.attributes.next_setting)) %}
        {%- if is_state('sun.sun', 'above_horizon') %}
          Dia
        {%- elif is_state('sensor.altura_do_dia', 'Dia') and setting %}
          Anoitecer
        {%- elif is_state('sensor.altura_do_dia', 'Anoitecer') and not setting %}
          Noite
        {%- elif is_state('sensor.altura_do_dia', 'unavailable') and is_state('sun.sun', 'below_horizon') %}
          Noite
        {%- elif is_state('sensor.altura_do_dia', 'Noite') and rising %}
          Amanhecer
        {%- else %}
          {{ states('sensor.altura_do_dia') }}
        {%- endif %}
      icon: >-
        {%- if is_state('sensor.altura_do_dia', 'Dia') %}
          mdi:weather-sunny
        {%- elif is_state('sensor.altura_do_dia', 'Anoitecer') %}
          mdi:weather-sunset-down
        {%- elif is_state('sensor.altura_do_dia', 'Noite') %}
          mdi:weather-night
        {%- elif is_state('sensor.altura_do_dia', 'Amanhecer') %}
          mdi:weather-sunset-up
        {%- else %}
          mdi:alert-circle
        {%- endif %}

Hi all,

did someone got this working? I configured this code in template.yaml but still got the state “unknown”. Can someone please help?

sensor:
- name: daytime
  unique_id: daytime
  state: >-
    {% set rising = (as_timestamp(states.sun.sun.attributes.next_rising)) < (as_timestamp(states.sun.sun.attributes.next_dawn)) %}
    {% set setting = (as_timestamp(states.sun.sun.attributes.next_dusk)) < (as_timestamp(states.sun.sun.attributes.next_setting)) %}
    {%- if is_state('sun.sun', 'above_horizon') %}
      day
    {%- elif is_state('sensor.daytime', 'day') and setting %}
      dusk
    {%- elif is_state('sensor.daytime', 'dusk') and not setting %}
      night
    {%- elif is_state('sensor.daytime', 'unavailable') and is_state('sun.sun', 'below_horizon') %}
      night
    {%- elif is_state('sensor.daytime', 'night') and rising %}
      dawn
    {%- else %}
      {{ states('sensor.daytime') }}
    {%- endif %}
  icon: >-
    {%- if is_state('sensor.daytime', 'day') %}
      mdi:weather-sunny
    {%- elif is_state('sensor.daytime', 'dusk') %}
      mdi:weather-sunset-down
    {%- elif is_state('sensor.daytime', 'night') %}
      mdi:weather-night
    {%- elif is_state('sensor.daytime', 'dawn') %}
      mdi:weather-sunset-up
    {%- else %}
      mdi:alert-circle
    {%- endif %}

I have created 2 sensors in yaml with both templates:

- 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('sensor.period_of_day', 'day') %}
          mdi:weather-sunny
        {%- elif is_state('sensor.period_of_day', 'dawn') %}
          mdi:weather-sunset-down
        {%- elif is_state('sensor.period_of_day', 'night') %}
          mdi:weather-night
        {%- elif is_state('sensor.period_of_day', 'dusk') %}
          mdi:weather-sunset-up
        {%- else %}
          mdi:alert-circle
        {%- endif %}

- platform: template
  sensors:
    period_of_day2:
      friendly_name: 'period of the day 2'
      value_template: >-
        {% set rising = (as_timestamp(states.sun.sun.attributes.next_rising)) < (as_timestamp(states.sun.sun.attributes.next_dawn)) %}
        {% set setting = (as_timestamp(states.sun.sun.attributes.next_dusk)) < (as_timestamp(states.sun.sun.attributes.next_setting)) %}
        {%- if is_state('sun.sun', 'above_horizon') %}
          day
        {%- elif is_state('sensor.period_of_day2', 'day') and setting %}
          dawn
        {%- elif is_state('sensor.period_of_day2', 'dawn') and not setting %}
          night
        {%- elif is_state('sensor.period_of_day2', 'unavailable') and is_state('sun.sun', 'below_horizon') %}
          night
        {%- elif is_state('sensor.period_of_day2', 'night') and rising %}
          dusk
        {%- else %}
          {{ states('sensor.period_of_day2') }}
        {%- endif %}
      icon_template: >-
        {% if is_state('sensor.period_of_day2', 'day') %}
          mdi:weather-sunny
        {%- elif is_state('sensor.period_of_day2', 'dawn') %}
          mdi:weather-sunset-down
        {%- elif is_state('sensor.period_of_day2', 'night') %}
          mdi:weather-night
        {%- elif is_state('sensor.period_of_day2', 'dusk') %}
          mdi:weather-sunset-up
        {%- else %}
          mdi:alert-circle
        {%- endif %}

template from @mastermarkush works great:
image

template from @mama_mia I can’t get to work
image

run in template tab:

There is something missing here.

Also, I don’t understand why the template from @mastermarkush would be a problem
???

Thanks anyway…