Sunrise Range Template

Is there a more elegant way to do this?

Basically I have a sunrise range template for when I want to trigger my blinds

  • If sunrise is before 5:30 then open at 5:30
  • If sunrise is after 5:30 but before 7:30 then open at sunrise
  • If sunrise is after 7:30 then open at 7:30

This provides a time which then feeds into another automation to determine time of day

I also would not mind having a full datetime stamp rather than time only

This is what I have and it works well enough, just assumed there might be a better way

        {% set sunrise = state_attr('sun.sun', 'next_rising') | as_datetime | as_local %}
        {% set sunrise_range = sunrise.time() %}
        {% set sunrise_range_start = today_at('5:30').time() %}
        {% set sunrise_range_end = today_at('7:30').time() %}
        {% if sunrise_range <= sunrise_range_start < sunrise_range_end %} {{ sunrise_range_start }}
        {% elif sunrise_range_start <= sunrise_range < sunrise_range_end %} {{ sunrise_range.strftime("%H:%M:%S") }}
        {% elif sunrise_range_end <= sunrise_range %} {{ sunrise_range_end }}
        {% else %} Unknown
        {% endif %}

There’s always a more elegant way. However, if it’s working right for you, then lock it in. Whether it’s 5 lines or 2 lines it’s going to use about the same amount of CPU.

What like is you are breaking it out into its own template. I find that to be a best practice as it’s easy to observe and makes the resulting automations much simpler to make correct. You can then chain this into making a different decision if its sunny vs cloudy, etc.

I’d change the default from “unknown” to some time, so that even if the sun integration fails, something reasonable happens.

1 Like

I should then alternatively ask how can I set today + a fixed time to provide a datetime stamp. The reason I want this is I’m having issues with the downstream automations when all I have is time.

The following provides me a time of 5:30, but how to get today + 5:30 so that the resulting output is ‘2023-02-09T05:30:00+10:00’

{% set sunrise_range_start = today_at('5:30').time() %}

If I understood your template correctly, it’s limiting the value to fall within a range. There’s a simple technique for doing that and it’s explained here:

Limit a value to fall within a range - Share your Projects! - Home Assistant Community (home-assistant.io)

The technique is to simply define a list containing three items:

  • Range’s starting value
  • Range’s ending value
  • Your value

Then sort the list and report its second item.

{% set rise = (state_attr('sun.sun', 'next_rising') | as_datetime | as_local).time()  %}
{% set start = today_at('5:30').time() %}
{% set end =  today_at('7:30').time() %}
{{ ([start, rise, end] | sort)[1].strftime("%H:%M:%S") }}

Or a bit more concisely:

{% set rise = (state_attr('sun.sun', 'next_rising') | as_datetime | as_local).time() %}
{{ ([today_at('5:30').time(), rise, today_at('7:30').time()] | sort)[1].strftime("%H:%M:%S") }}

If you’re unconvinced that the technique works, copy-paste the following version into the Template Editor and change the hours value to add/subtract time from sunrise to see how the template behaves.

{% set rise = (state_attr('sun.sun', 'next_rising') | as_datetime | as_local - timedelta(hours=2)).time() %}
{% set start = today_at('5:30').time() %}
{% set end =  today_at('7:30').time() %}
{{ ([start, rise, end] | sort)[1].strftime("%H:%M:%S") }}

@123 this is very cool, many thanks

1 Like