Any good ideas are welcome. Nordpool Energy Price per hour

Without state of “switch.boilers” the problem still remains.

In this case, it is not correct to use the maximum price of three cheepest hours, because the nordpool exchange price does not include additional costs (night, day, weekends transfer fees, etc).

Therefore, I wanted to create the automation based on the principle that the boiler is turned on if the binary sensor is “true” at the relevant moment.

I don’t understand why the state of the binary sensor is not changed even though the result is “true”. Could it be that this created binary sensor is not processed (eg every minute, as is the case with templete)?

Hi all,

I would like to create a sensor with 3 states (green, yellow, red) based on the average price for the next 3 hours being below X, between X and Y, or above Y. In this way it should be possible to show my wife (and myself) in an easy way if it is OK to start appliances that takes 2-3 hours to run.

Does anybody have ideas to how that can be accomplished?

1 Like

Skærmbillede 2022-09-19 kl. 13.42.28

Assuming you’re using Nordpool.
Setup your Nordpool integration
Install Apexcharts using HACS
Todays prices:

type: custom:apexcharts-card
graph_span: 24h
apex_config:
  chart:
    height: 170px
show:
  last_updated: true
experimental:
  color_threshold: true
header:
  title: Strømpriser i dag
  show: true
  show_states: true
  colorize_states: true
span:
  start: day
now:
  show: true
  label: Nu
series:
  - entity: sensor.nordpool_kwh_dk2_dkk_2_10_025
    show:
      extremas: true
      in_header: raw
      header_color_threshold: true
    type: column
    data_generator: |
      return entity.attributes.raw_today.map((start, index) => {
        return [new Date(start["start"]).getTime(), entity.attributes.raw_today[index]["value"]];
      });
    color_threshold:
      - value: 1
        color: darkgreen
        opacity: 1
      - value: 1
        color: goldenrod
      - value: 3
        color: darkred

Tomorrows prices:

type: custom:apexcharts-card
graph_span: 1d
experimental:
  color_threshold: true
apex_config:
  chart:
    height: 170px
header:
  title: Strømpriser i morgen (kr/kWh)
  show: true
span:
  start: day
  offset: +1d
series:
  - entity: sensor.nordpool_kwh_dk2_dkk_2_10_025
    type: column
    data_generator: |
      return entity.attributes.raw_tomorrow.map((start, index) => {
        return [new Date(start["start"]).getTime(), entity.attributes.raw_tomorrow[index]["value"]];
      });
    color_threshold:
      - value: 1
        color: darkgreen
        opacity: 1
      - value: 1
        color: goldenrod
      - value: 3
        color: darkred

Skærmbillede 2022-09-19 kl. 13.42.28

7 Likes

Hi Christian,

Yes I have installed the Nordpool integration.

The Charts looks nice. But I would like to be able to visualize in a simple way, with a kind of traffic-light on the wall showing how the prices will behave in the next 3 hours.

Ah, I see - I don’t have a solution like that :frowning:

In hopes of someone having a similar need, or similar solution out there - I’ll describe what I’m looking for atm.

I’ve got a geothermal heatpump (but the principal goes for any type), with mainly underfloor heating.
Ultimately, I’m looking for a script, that will help me determine the most expensive 3 hour windows, throughout the day, so that I may automate the shutdown.

Heatpumps aren’t fond of being shut off and turned on a lot, but needs longer periods to generate the heat - a minimum of 6 hours at a time.

The concept I look for, ideally, would be able to first determine the most expensive consecutive 3 hours, in the day and afterwards, look 6 hours apart, for another 3 hour window.

Atleast in Denmark, the prices rise in the morning, before usual work time and in the evening, after work. That gives the windows 6-9 and 17-20, that are expensive, historically.

With the current fluctuations, a static rule wont mix - and there is no reason to shutdown the heatpump, if a cheap wave of electricity is soaring the market.

So ideally, the script would in a “normal day” identify the 2 timeslots and confirm that they are more than 6 hours apart, and then report a true / false value.
Even better would it be, if the timeslot were available to query, so that the apexcharts, that I posted above, could show the timeslots, as a color or with a graphical component.

That way, the dashboard would show prices and the timeslots in which the heating element would shut off.

I’ve tried most the code in this thread, but none match this functionality.
My hope is to actively cut off the normal high times of the price-waves, and take advantage of lower prices, to generate more heat instead.

3 Likes

If I want to save the highest price ever like an all time high with time stamp. What would the best way be?

This is similar to what I’m looking to do also. Your idea might be better. Someone suggested the Node Red nod Power Saver which might do what you want to do. I would prefer to do this in YAML or similarly have an entity gives the (using Tibbers definition of Price_Level) the price_level over the next 1, 3, or 6 hours. This way I could write automation that will increase the setpoint when the temperature will remain low over the next several hours (or increase after several hours).

I’m also interested in your idea and made a tiny start to the project. My code below reads the Nordpool sensor from HACS (Finland area in this example), sums the prices of three consecutive hours, appends them to a new list and finds the index of the maximum value on the list.
This could be extended to cover the next day prices if available.

{% set nordpoolSensor = "sensor.nordpool_kwh_fi_eur_3_05_0" %}
{% set priceData = namespace(numbers=[]) %}
{% for i in state_attr(nordpoolSensor,'raw_today') %}
  {% set priceData.numbers = priceData.numbers + [i.value] %}
{% endfor %}

{% set three_consecutive_hours = namespace(numbers=[]) %}
{% for n in range(0,22) %}
    {% set three_hour_sum = (priceData.numbers[n]+priceData.numbers[n+1]+priceData.numbers[n+2])|round(2) %}
    {% set three_consecutive_hours.numbers = three_consecutive_hours.numbers + [three_hour_sum] %}
{% endfor %}
{% set max_three_hour = max(three_consecutive_hours.numbers) %}
{% set most_expensive_hours = three_consecutive_hours.numbers.index(max_three_hour) %}
Sum of three consecutive hours:
{{three_consecutive_hours.numbers}}

Most expensive 3 hours are from {{ most_expensive_hours }} to {{ most_expensive_hours+3 }} o'clock
5 Likes

This seems to work fine! Thank you for sharing! :grinning:

Thank you for your interest!

That code is a very good starting point, and it nails the 3 consecutive hour time slot straight on.

Thank you for sharing it!

I do think it would be a good idea to have it factor tomorrows prices, when available, and adjust the calculations, but I guess it’s just a matter of copy paste and adjust for tomorrow, instead

The toughest part is still getting that 2nd timeslot locked down.
I’m kind of a novice in python, so I’ve spent the better part of the morning searching on how to go about filtering the array, or doing a for if loop that checks the time of the highest values, until it hits something that is three_consecutive_hours.numbers.index(max_three_hour) - 8 or + 8
I imagine something like a for loop for all values, check if the value time is either +8 or -8 from the most_expensive_hours and if so, check if it’s higher than 2nd_timeslot, and if so, set it to that value.

But for the life of me, I can’t get it from my head, into code :sweat_smile:

Good work. This could be a good starting point to do what i want :
1 check if grid power price is among the upcoming 24hrs lowest rate?
2 check solar forecast for my production, is it more than battery capacity?
3 check battery state, is it empty?

if ( 1 and 3 and not 2 ) fill battery from grid
if ( 2 and not 1 ) do not fill battery from grid
and so on

with add-on (if electricity price > some_value) empty battery to grid and do not fill battery.
:slight_smile:

This binary sensor was awesome! Thanks a lot! To make the automation even better, I would like to add the tariff the grid supplier charges to the prices to get the sorting to take this into account. During Nov-Mar there is an additional 58 öre during workdays 6-22. Is there any way to do this? Cheers

That can be added directly into the nordpool sensor.

Under additional costs you can play with this to suit your needs:

# Tariff example
'{% set s = {
    "hourly_fixed_cost": 0.5352,
    "winter_night": 0.265,
    "winter_day": 0.465,
    "summer_day": 0.284,
    "summer_night": 0.246,
    "cert": 0.01
}
%}
{% if now().month >= 5 and now().month <11 %}
    {% if now().hour >=6 and now().hour <23 %}
        {{s.summer_day+s.hourly_fixed_cost+s.cert|float}}
    {% else %}
        {{s.summer_night+s.hourly_fixed_cost+s.cert|float}}
    {% endif %}
{% else %}
    {% if now().hour >=6 and now().hour <23 %}
        {{s.winter_day+s.hourly_fixed_cost+s.cert|float}}
    {%else%}
        {{s.winter_night+s.hourly_fixed_cost+s.cert|float}}
    {% endif %}
{% endif %}'

Thanks for your quick reply! I have seen this, but being a n00b, I can’t wrap my head around how it is done. It does not seem to be as simple as replacing “{{0.0|float}}” with the code you pasted from the documentation. The documentation says: “This option allows the usage of a template to add a tariff.” but I am not sure how this is done. Any pointers are greatly appreciated!

And where exactly should this tariff example be added? Maybe it is possible to show a full example?

Many great ideas and contributions here!

I need help with a sensor. I would like to know the cheapest hour between 08.00 and 20.00.

The reason is that I would like to produce hot water twice every 24 hours, in the middle of the night but also during the day. So I would like to list the hours between 08 and 20 from cheapest to most expensive, similar to the examples in this thread (but obviously not for the whole 24 hrs :slight_smile: )

Anyone that could help me in the right direction to achieve this?

you can use this as condition in a automation (this is the cheapest 2 hours between 8-16)

   {{ ([(state_attr('sensor.nordpool_kwh_dk1_dkk_3_10_025','today')[8]
              |
                              float(default=0)),
                              (state_attr('sensor.nordpool_kwh_dk1_dkk_3_10_025','today')[9] |
                              float(default=0)),
                              (state_attr('sensor.nordpool_kwh_dk1_dkk_3_10_025','today')[10] |
                              float(default=0)),
                              (state_attr('sensor.nordpool_kwh_dk1_dkk_3_10_025','today')[11] |
                              float(default=0)),
                              (state_attr('sensor.nordpool_kwh_dk1_dkk_3_10_025','today')[12] |
                              float(default=0)),
                              (state_attr('sensor.nordpool_kwh_dk1_dkk_3_10_025','today')[13] |
                              float(default=0)),
                              (state_attr('sensor.nordpool_kwh_dk1_dkk_3_10_025','today')[14] |
                              float(default=0)),
                              (state_attr('sensor.nordpool_kwh_dk1_dkk_3_10_025','today')[15] |
                              float(default=0)),
                              (state_attr('sensor.nordpool_kwh_dk1_dkk_3_10_025','today')[16] |
                              float(default=0))] | sort)[2] >=
                              state_attr('sensor.nordpool_kwh_dk1_dkk_3_10_025','current_price') | float }}
1 Like

Try this oneliner:

{{ (state_attr('sensor.nordpool_kwh_dk1_dkk_3_10_025', 'today')[8:16] | sort(false))[1] | float(default=0) }}

This takes elements from 8 to 16 (ie 8:00 - 16:00 included), sorts them to ascending order and gives you the second (index 1) lowest price. In automation you should compare that current price is less or equal with this one.

5 Likes

As an noob on HA, how do i include this as condition in an automation?
Just used to java programming if( something) then { }
:slight_smile:
I guess i need to compare it to this:
state_attr(‘sensor.nordpool_kwh_dk1_dkk_3_10_025’,‘current_price’) | float

?