Nordpool today's prices value

I want to create an entity that shows a value 1-24 depending on Nordpool today’s prices.
1 is cheapest
2 second cheapest

24 most expensive

It then becomes easy to activate an automation through “below” 3, for example

You can make sorted entities from low to high for each prices if you use this pyscript from a norwegian user in another forum:

Another way is to use a template like this which first sort the prices and then make a binary sensor for the four cheapest hours.

template:
  - binary_sensor:
      - name: "Billigste 4 timer"
        state: >-
          {% set l=state_attr( 'sensor.nordpool', 'raw_today')|sort(attribute='value') %}
          {{ (now() >= l[0].start and now() <= l[0].end)
            or (now() >= l[1].start and now() <= l[1].end)
            or (now() >= l[2].start and now() <= l[2].end)
            or (now() >= l[3].start and now() <= l[3].end) }}

If you want the four expensive hours you must change the index to 20, 21, 22, 23 like this:

template:
  - binary_sensor:
      - name: "Dyreste 4 timer"
        state: >-
          {% set l=state_attr( 'sensor.nordpool', 'raw_today')|sort(attribute='value') %}
          {{ (now() >= l[20].start and now() <= l[20].end)
            or (now() >= l[21].start and now() <= l[21].end)
            or (now() >= l[22].start and now() <= l[22].end)
            or (now() >= l[23].start and now() <= l[23].end) }}

The orginal post in norwegian is here: Finne de billigste strømtimene i Home Assistant - Strømsparing og strøm-overvåkning - Hjemmeautomasjon

This is one way of doing it:

sensor:
   - name: "Nordpool Current Price Rank"
     state: >-
     {% set rt = state_attr('sensor.nordpool','raw_today')|sort(attribute='value') %}
     {% set ns = namespace(mark=0) %}
     {% for i in range(0, 24) %}
     {% if ( now() >= rt[i].start and now() < rt[i].end ) %}
     {% set ns.mark = i %}
     {% endif %}
     {% endfor %}
     {{ ns.mark }}

And yet another way of finding 3 cheapest hours:

{% set tod=state_attr('sensor.nordpool','raw_today') %}
{% set ns = namespace(value=0, amount=1000, index=0) %}
{% for i in range(0, 22) %}
{% set ns.value = tod[i].value + tod[i+1].value + tod[i+2].value %}
{% if (ns.value < ns.amount) %}
{% set ns.index = i %}
{% set ns.amount = ns.value %}
{% endif %}
{% endfor %}
{{ tod[ns.index].start.strftime("%H:%M") }} - {{ tod[ns.index+2].end.strftime("%H:%M") }}

This method can of course also be used on tomorrows prices (when available).

1 Like

Thanks, this was what I was looking for.
Is it possible to make a small adjustment?
Today, 0.13, 0.13, 0.13, 0.13, 0.13, 0.14, 0.13, 0.16, 2.64, 2.89, 4.63, 4.63, 7.46, 6.31, 6.46, 5.62, 5.15, 7.16, 8.65, 8.77, 5.03, 6.41, 3.46, 0.13
Now at 23:00 the entity shows “6” is it possible to make it show “0 or 1” as it is the lowest price of the day even though there were 6 hours with the same price earlier in the day?

Hmm I’m not sure. I’ve only recently started to play around with this stuff and probably doing it all wrong. I have a sneaking feeling I need to learn more about select_attr and filters in Jinja2.

Anyway…Maybe if you sort it a second time by start time?

{% set rt = state_attr('sensor.nordpool','raw_today')|sort(attribute='value')|sort(attribute='start') %}

Maybe in reverse? Try it out :slight_smile:

{% set rt = state_attr('sensor.nordpool','raw_today')|sort(attribute='value')|sort(attribute='start',reverse=true) %}

Btw. The Template Tool under Developers Tool are really helpful when you’re trying to figure out this stuff :slight_smile:

I “solved” it another way.
I changed to 3 decimals in the Nordpool integration, then there is minimal risk of being the same price per hour.

Great! Nice work-around :slight_smile:

You might be really unlucky though and still get two or more of the same prices one day. Maybe if you checked for the current price instead of the time, in the loop, you would always get the first match and thus lowest ranking with two or more of the same spot prices.

I havent checked it a lot, but the following seems to give correct results (on first glance anyway):

     {% set rt = state_attr('sensor.nordpool_kwh_dk2_dkk_4_095_025','raw_today')|sort(attribute='value') %}
     {% set cp = state_attr('sensor.nordpool_kwh_dk2_dkk_4_095_025', 'current_price') %}
     {% set ns = namespace(mark=-1) %}
     {% for i in range(0, 24) %}
     {% if ( cp == rt[i].value ) %}
     {% set ns.mark = i %}
     {% endif %}
     {% endfor %}
     {{ ns.mark }}

Edit: On second thought… maybe the earlier method just needs a way of not counting duplicates when ranking. Anyway my HA is broken and needs mending, so I need to get back to that :slight_smile:

This was what I am looking for I think. I want to easily see in text when the 3 cheapest hours are! And I guess this one does it?
I would also want the same but for the 3 most expensive hours. Do I then just change the (0, 22) to (22, 0) ?

It depends on whether you want 3 consecutive hours or just the 3 cheapest/expensive hours during the day.

The following should give you the 3 cheapest consecutive hours (you can set the number of hours).

{% set rt = state_attr('sensor.nordpool_kwh_dk2_dkk_4_095_025','raw_today') %}
{% set ns = namespace(hours=3, start=0, sum=0, mark=0) %}
{% for i in range(0, 24 - ns.hours + 1 ) %}
{% set ns.sum = 0 %}
{% for j in range(0, ns.hours) %}  
{% set ns.sum = ns.sum + rt[i+j].value %}
{% endfor %}
{% if ( ns.mark > ns.sum or ns.mark == 0 ) %}
{% set ns.start = i %}
{% set ns.mark = ns.sum %}
{% endif %}
{% endfor %}
{{ ns.start }}:00 - {{ns.start + ns.hours }}:00

To get the most expensive hours, you just change the greater-than (>) to less-than (<).

{% set rt = state_attr('sensor.nordpool_kwh_dk2_dkk_4_095_025','raw_today') %}
{% set ns = namespace(hours=3, start=0, sum=0, mark=0) %}
{% for i in range(0, 24 - ns.hours + 1 ) %}
{% set ns.sum = 0 %}
{% for j in range(0, ns.hours) %}  
{% set ns.sum = ns.sum + rt[i+j].value %}
{% endfor %}
{% if ( ns.mark < ns.sum or ns.mark == 0 ) %}
{% set ns.start = i %}
{% set ns.mark = ns.sum %}
{% endif %}
{% endfor %}
{{ ns.start }}:00 - {{ns.start + ns.hours }}:00
1 Like

Thanks. but it doesnt give me the correct hours when I compare it to the actually price over the day!

You’re right. I was able to test it today and it doesn’t work. Seems I forgot to reset the ns.sum var at each iteration. I’ve edited the above post to reflect this. Let me know if it works for you now :slight_smile:

Hmm I think they work now, but they are mixed right. The top one shows the 3 most expensive, and the lower one shows the 3 most cheapest hours, right?
And it says “8:00-11:00” so thats hour 8,9,10 then right?

Yeah, it’s the same routine just with less-than (<) and greater-than (>) swapped. I forgot to update the text when editing the post. It’s corrected now.

8:00-11:00 means from 8 o’clock until 11 o’clock.

You can easily change it though. For example:

{{ ns.start }}:00 - {{ns.start + ns.hours - 1}}:59

Will give you 8:00 - 10:59 - if you prefer that.

1 Like

Cool, what if I just want the starting hour?

Is it possible to also include tomorrows price (if it’s available) and only find a hour-block that is in the future?

It’s possible, but I don’t have the time nor use nord pool custom component anymore.

I suggest the following search:

https://www.google.com/search?q=nord+pool+custom+component+find+cheapest+hours