Question: Lowest Price Hour Sensor Template Issue

Hi,
I’m trying to create a sensor that calculates the hour with the lowest energy price in the next 8 hours using data from the sensor.nordpool_energyprices. My template processes the times and prices attributes, compares them to the current time and an 8-hour cutoff, and is supposed to return the time of the lowest price as HH:MM. If no data is found, it defaults to N/A.

Here’s my code:

yaml

Copy code

- sensor:
    - name: "Lowest Price Hour Next 8h"
      unique_id: ad701199-7f86-46ab-a6c2-a8cdf573e497
      icon: mdi:currency-eur
      unit_of_measurement: "€"
      state: >-
        {% set times = state_attr('sensor.nordpool_energyprices', 'times') %}
        {% set prices = state_attr('sensor.nordpool_energyprices', 'prices') %}
        {% if times is not none and prices is not none %}
          {% set cutoff = now() + timedelta(hours=8) %}
          {% set result = namespace(lowest_time=None, lowest_price=None) %}

          {% for i in range(times | length) %}
            {% set t = as_datetime(times[i]) %}
            {% if t is not none and t >= now() and t < cutoff %}
              {% set p = prices[i] %}
              {% if result.lowest_price is none or p < result.lowest_price %}
                {% set result.lowest_price = p %}
                {% set result.lowest_time = t %}
              {% endif %}
            {% endif %}
          {% endfor %}

          {% if result.lowest_time %}
            {{ result.lowest_time.strftime('%H:%M') }}
          {% else %}
            N/A
          {% endif %}
        {% else %}
          N/A
        {% endif %}

This is the output of my sensor.nordpool_energyprices:

unit_of_measurement: €
icon: mdi:currency-eur
friendly_name: NordPool Energyprices
times:

  • “2024-12-13 00:00:00”
  • “2024-12-13 01:00:00”
  • “2024-12-13 02:00:00”
  • “2024-12-13 03:00:00”
  • “2024-12-13 04:00:00”
  • “2024-12-13 05:00:00”
  • “2024-12-13 06:00:00”
  • “2024-12-13 07:00:00”
  • “2024-12-13 08:00:00”
  • “2024-12-13 09:00:00”
  • “2024-12-13 10:00:00”
  • “2024-12-13 11:00:00”
  • “2024-12-13 12:00:00”
  • “2024-12-13 13:00:00”
  • “2024-12-13 14:00:00”
  • “2024-12-13 15:00:00”
  • “2024-12-13 16:00:00”
  • “2024-12-13 17:00:00”
  • “2024-12-13 18:00:00”
  • “2024-12-13 19:00:00”
  • “2024-12-13 20:00:00”
  • “2024-12-13 21:00:00”
  • “2024-12-13 22:00:00”
  • “2024-12-13 23:00:00”
    prices:
  • 0.119
  • 0.102
  • 0.102
  • 0.102
  • 0.102
  • 0.121
  • 0.145
  • 0.23
  • 0.3
  • 0.363
  • 0.331
  • 0.25
  • 0.242
  • 0.199
  • 0.198
  • 0.198
  • 0.271
  • 0.242
  • 0.149
  • 0.142
  • 0.102
  • 0.102
  • 0.064
  • 0.061

However, the sensor doesn’t seem to work as expected. It either doesn’t update, returns N/A, or errors out. Could someone help me identify what might be wrong or what I’m missing?

Thanks in advance!

This is my code for my e-paper display that formats differently for highest and lowest price during the day.
Perhaps this can be useful for you?

    {% set ns = namespace( text_list = [], line =0) %} 
    {% set nordpool ="sensor.nordpool_kwh_se4_sek_3_10_025" %} 
    {% set cheapest = 5 %} 
    {% set expensivest = 5 %} 
    {% set decimal = "," %} {## decimal separator in currency ##} 
    {% set currency = "kr" %} {## include space if needed/wanted ##} 
    {% set position = "trailing" %} {## trailing or leading ##} 
    {% set decimal_places = 2 %}

    {% for day in ["today", "tomorrow"] %}
      {% for s in state_attr(nordpool,'raw_' ~ day)-%}
        {% if s.end > now() -%}
          {%- set ns.text_list = ns.text_list +  

           [{ "type": "rectangle",  
             "x_start": 1,
             "x_end": 127,
             "y_start": 1 + (25*ns.line), 
             "y_end": 25 + (25*ns.line),
             "width": 4 if s.value in (state_attr(nordpool, day) | sort(reverse = false))[0:cheapest] else 2,
             "fill": "white",
             "outline": "red" if s.value in (state_attr(nordpool, day) | sort(reverse = false))[0:cheapest] else "black"}] +

          [{ "type": "text",  
             "value": ("0" ~ s.start.hour)[-2:3] ~ ":00", 
             "font": "ppb.ttf",
             "x": 5,
             "y":  7 + (25*ns.line), 
             "size": 16,
             "color": "red" if s.value in (state_attr(nordpool, day) | sort(reverse = true))[0:expensivest] else "black"} ] +
             
          [{ "type": "text",  
             "value": (currency if position == "leading") ~ (((s.value | round(decimal_places) ~ "00000")[0:decimal_places+(s.value|string).split(".")[0]|length +1]) |string).replace(".", decimal) ~ (currency if position == "trailing"),
             "font": "ppb.ttf",
             "x": 58,
             "y":  7 + (25*ns.line), 
             "size": 16,
             "color": "red" if s.value in (state_attr(nordpool, day) | sort(reverse = true))[0:expensivest] else "black"} ] -%}
        
          {% set ns.line = ns.line + 1 %} 
        {% endif %}
      {%- endfor -%}
    {%- endfor -%}


    {{ ns.text_list }}

Or have a look at:

Cheapest Energy Hours - Jinja macro for dynamic energy prices - Share your Projects! - Home Assistant Community

2 Likes