Sun elevation based on percentage of day


I am trying to create a template sensor which calculates the percent of daylight that has elapsed.
i have some coding skills but this seems to be a bit out of my league.

I’m trying to create a sun elevation card (with picture elements).
To account for the daily change of the amount of daytime i thought a percentage would work to define picture elements for the different sun elevations


I found some code snippets here and there and put them together in the template editor… but it doesnt seem to work…

- platform: template
      friendly_name: "Percentage of day"
      value_template: >-
        {% set total_daylight = states('sensor.daylight_hours')  %}
        {% set daylight_remaining = as_timestamp(state_attr('sun.sun','next_setting') | float - now().timestamp() | int  ) | timestamp_custom('%H:%M', false)  %}

        {{ (daylight_remaining/total_daylight)*100 }}

Can anyone help me?

Check this

1 Like

You were close, but brackets in the wrong place and more type conversions than you needed. Try this line:

{% set daylight_remaining = (state_attr('sun.sun','next_setting')|as_timestamp - now()|as_timestamp)|timestamp_custom('%H:%M', false)  %}

That’s a string, though (like you asked for with timestamp_custom) and your final line then makes no sense. What does {{ states('sensor.daylight_hours') }} return?

you should have a look at GitHub - pnbruckner/ha-sun2: Home Assistant Sun2 Sensor which provides several sensors out of the box that you could use.

I use some of them to build templates like:

        friendly_name: Daylight remaining minutes
        value_template: >
          {% set nw = now() %}
          {% set sr = state_attr('sensor.astral_sunrise','today') %}
          {% set ss = state_attr('sensor.astral_sunset','today') %}
          {% if nw < sr %}
            {{((ss - sr).total_seconds()/60)|int}}
          {% elif nw < ss %}
            {{((ss - nw).total_seconds()/60)|int}}
          {% else %}
          {% endif %}
#          {{((as_timestamp(state_attr('sun.sun','next_setting')) - now().timestamp())/60)|int}}
        unit_of_measurement: min

        friendly_name: 'Daylight remaining hh:mm'
        value_template: >
          {% set nw = now().replace(microsecond=0) %}
          {% set sr = state_attr('sensor.astral_sunrise', 'today') %}
          {% set ss = state_attr('sensor.astral_sunset', 'today') %}
          {% if nw < sr %}
            {{ ss - sr }}
          {% elif nw < ss %}
            {{ ss - nw }}
          {% else %}
          {% endif %}

creating a percentage sensor should not be too difficult

1 Like

It returns the total amount of daylight time.
I’ll give it a try this afternoon and get back to you!
The final line is where the template editor started giving me the error:
TypeError: unsupported operand type(s) for /: ‘str’ and ‘str’

I’m trying to make a percentage… and that is how far I got with the calculations :upside_down_face:

I’ve used the final line before in a different sensor that works…
It might be that i cant do these calculations with time?

example of the working sensor:

- platform: template
      friendly_name: "Inzidenz Change"
      value_template: >-
        {% set n = states('sensor.sk_koln_newcases') | float %}
        {% set r = states('sensor.sk_koln_newrecovered') | float %}
        {% set d = states('sensor.sk_koln_newdeaths') | float %}
        {{ (n - (r+d)) | round(0) }}

Thanks for the help

Thanks. Ill look into that!

Not with strings like “03:34”, no. You should read and get familiar with this:

Sensors’ states are always strings, even if they look like numbers. You need to turn them into numbers using |int or |float before doing any arithmetic on them.

You’ll probably find it easier to convert all the times you’re working with into UNIX timestamps (seconds since 1970; all documented at the link above), so you end up with seconds of daylight and seconds until sunset.

I’ve been searching for this exact type of card and is basically what I’m trying to achieve with the calculations. Thanks!

1 Like