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:
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”.
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
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
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.
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 }}'
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:
You can find the holistic integration with circadian lights below:
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.
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
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.
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:
template from @mama_mia I can’t get to work
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…