Any good ideas are welcome. Nordpool Energy Price per hour

will your code check the cheapest hour ex. from 21.00 to the next day at 21.00 ? so it uses today and tomorrow prices?

This looks for cheapest sequential hours? It would be even better if i somehow could charge ev at absolutely cheapest hours. For example charging 4 hours could be at 22-23, 01-03 and 04-05.

1 Like

‘’’
Hi,

It is actually not my code…so no credits, nor questions, to me :wink:
You will have to analyse the code yourself.

greetz,

Jan
‘’’

"
Hi,

It is actually not my code…so no credits, nor questions, to me :wink:
You will have to analyse the code yourself.

greetz,

Jan

"

Hi! I have moved to mariadb and lost all the history, that’s not too bad but I was wondering, is there a way to get a 30 day history of the nordpool price in a graph? As of now it started from today but like to get 29 previous days in the graph also.

You can use a markdown card for that.
Just change the nordpool sensor and the time.

(cheapest hour today)

{% set priceList = state_attr('sensor.nordpool_kwh_fi_eur_3_10_024', 'today')[8:22] %}
{% set dateList = state_attr('sensor.nordpool_kwh_fi_eur_3_10_024', 'raw_today')[8:22] %}
{% set minPrice = min(priceList) %}
{% set minIndex = priceList.index(minPrice) %}
{% set minDateTimeStr= dateList[minIndex].start | string %}
{% set minDateTime= strptime(minDateTimeStr[0:19], '%Y-%m-%d %H:%M:%S') %}

Billigaste priset idag mellan 07-22 och är {{ minPrice }} EUR/kWh och startar kl {{ minDateTime.hour }}:00

(cheapest hour tomorrow)



{% set priceList = state_attr('sensor.nordpool_kwh_fi_eur_3_10_024', 'tomorrow')[8:22] %}
{% set dateList = state_attr('sensor.nordpool_kwh_fi_eur_3_10_024', 'raw_tomorrow')[8:22] %}
{% set minPrice = min(priceList) %}
{% set minIndex = priceList.index(minPrice) %}
{% set minDateTimeStr= dateList[minIndex].start | string %}
{% set minDateTime= strptime(minDateTimeStr[0:19], '%Y-%m-%d %H:%M:%S') %}

Billigaste priset mellan 07-22 imorgon är {{ minPrice }} EUR/kWh och startar kl {{ minDateTime.hour }}:00

image

And here is for tomorrow cheapest 2 hours from 00:00-24:00
Just change {% set num_hours = 2 | int %} to whatever you want.

      {% set iterativesum = namespace(iter=[]) %}

      {% set lowestiter = namespace(kr=2) %}

      {% set timelowest = namespace(hr=2) %}

      {% set highestiter = namespace(kr=0) %}

      {% set timehighest = namespace(hr=0) %}

      {% set num_hours = 2 | int %}

      {% set nordpoolentity = 'sensor.nordpool_kwh_fi_eur_3_10_024' %}

      {% set timemapper = {

      0: '00:00',

      1 : '01:00',

      2 : '02:00',

      3 : '03:00',

      4 : '04:00',

      5 : '05:00',

      6 : '06:00',

      7 : '07:00',

      8 : '08:00',

      9 : '09:00',

      10 : '10:00',

      11 : '11:00',

      12 : '12:00',

      13 : '13:00',

      14 : '14:00',

      15 : '15:00',

      16 : '16:00',

      17 : '17:00',

      18 : '18:00',

      19 : '19:00',

      20 : '20:00',

      21 : '21:00',

      22 : '22:00',

      23 : '23:00',

      24: '00:00',

      25 : '01:00',

      26 : '02:00',

      27 : '03:00',

      28 : '04:00',

      29 : '05:00',

      30 : '06:00',

      31 : '07:00',

      32 : '08:00',

      33 : '09:00',

      34 : '10:00',
      35 : '11:00',

      36 : '12:00',

      37 : '13:00',

      38 : '14:00',

      39 : '15:00',

      40 : '16:00',

      41 : '17:00',

      42 : '18:00',

      43 : '19:00',

      44 : '20:00',

      45 : '21:00',

      46 : '22:00',

      47 : '23:00',

      48 : '0:00',

      } %}

      {% set prices = namespace(price=[]) %}

      {% set prices.price = prices.price + state_attr(nordpoolentity, 'today')
      %}
      {%- if state_attr(nordpoolentity,'tomorrow') | length == 1 -%}
      Morgondagens priser ej släppta

      {% else %}

      {% set prices.price = prices.price + state_attr(nordpoolentity,
      'tomorrow') %}

      {% endif %}

      {%- for n in range(prices.price|length -num_hours +1) -%}

      {%- set tempsum= namespace(temp=0) -%}

      {%- for i in range(num_hours) -%}

      {%- set tempsum.temp = tempsum.temp + prices.price[n+i] -%}

      {% endfor -%}

      {% set iterativesum.iter = iterativesum.iter + [tempsum.temp] -%}

      {% endfor -%}

      {% for iter in iterativesum.iter -%}

      {%- if loop.index > now().hour -%}

      {%- if iter < lowestiter.kr | float -%}

      {%- set lowestiter.kr = iter | float -%}

      {%- set timelowest.hr = loop.index -1 -%}

      {%- endif -%}
      {%- if iter > highestiter.kr | float -%}

      {%- set highestiter.kr = iter | float -%}

      {%- set timehighest.hr = loop.index -1 -%}

      {%- endif -%}

      {%- endif -%}

      {% endfor -%}
      De billigaste {{num_hours}}-timmarna startar {% if (timelowest.hr < 24)
      %}idag{% else %}imorgon{% endif %} kl {{timemapper[timelowest.hr]}}, då
      snittpriset är {{"%.2f"|format(lowestiter.kr/num_hours)}} cent/kWh
      De dyraste {{num_hours}}-timmarna startar {% if (timehighest.hr < 24)
      %}idag{% else %}imorgon{% endif %} kl {{timemapper[timehighest.hr]}}, då
      snittpriset är {{"%.2f"|format(highestiter.kr/num_hours)}} cent/kWh

2 Likes

I have mungled in template editor for hours and got this. Have not yet tested irl, as i am not really experienced with home assistant. Is this ok, or have i gone horribly wrong somewhere?

{% if now().hour < 7 %}
{% set prices = (state_attr('sensor.nordpool_kwh_fi_eur_3_10_024', 'today')[now().hour:7]| sort(false)) %}
{%- else -%}
{% set prices = ((state_attr('sensor.nordpool_kwh_fi_eur_3_10_024', 'today')[now().hour:24]|list + state_attr('sensor.nordpool_kwh_fi_eur_3_10_024', 'tomorrow')[0:7]|list)| sort(false)) %}
{%- endif %}
{{ state_attr('sensor.nordpool_kwh_fi_eur_3_10_024', 'current_price') <= (prices[((states("sensor.kona_target_capacity_of_charge_ac")|float - states("sensor.kona_ev_battery")|float)/10)|round(0,"floor")]) }}

It calculates charging time from ev target charge - ev battery, 10%/hour. For example target is 80%, battery is at 54% → 2.6 hours (rounded up to 3).

This gives out True if now is one of 3 cheapest hour between now and tomorrow 7:00. This i think could be used to turn charger on and off.

1 Like

Do your top Numbers - max, min average - match the graph? Are you using any template for additionel costs?

Have made mine based on yours and i have som issue with the top and graph I cant wrap my head around

Hello.
I have used the code, for calculating cheapest sequencial hours, for morning, afternoon and evening. To turn on/off my air to air heating pump.
And its works for morning and afternoon. But the calculation for the evening, cheapeste hour, is wrong. It’s not chosing the 3 cheapest hours, that i won it to. Its a longer period it choosing. For example 7pm to 7 am, next morning.

image

This is the code i’am using

#Nordpool billigste timer aften

  • platform: template
    sensors:
    cheapest_hours_energy_tomorrow_third:
    device_class: timestamp
    friendly_name: Cheapest sequential electricity hours third
    value_template: >
    {%- set numberOfSequentialHours = 3 -%}
    {%- set lastHour = 23 -%}
    {%- set firstHour = 16 -%}
    {%- if state_attr(‘sensor.nordpool_kwh_dk2_dkk_3_10_025’, ‘tomorrow_valid’) == true -%}
    {%- set ns = namespace(counter=0, list=[], cheapestHour=today_at(“00:00”) + timedelta( hours = (24)), cheapestPrice=999.00) -%}
    {%- for i in range(firstHour + numberOfSequentialHours, lastHour+1) -%}
    {%- set ns.counter = 0.0 -%}
    {%- for j in range(i-numberOfSequentialHours, i) -%}
    {%- set ns.counter = ns.counter + state_attr(‘sensor.nordpool_kwh_dk2_dkk_3_10_025’, ‘tomorrow’)[j] -%}
    {%- endfor -%}
    {%- set ns.list = ns.list + [ns.counter] -%}
    {%- if ns.counter < ns.cheapestPrice -%}
    {%- set ns.cheapestPrice = ns.counter -%}
    {%- set ns.cheapestHour = today_at(“00:00”) + timedelta( hours = (24 + i - numberOfSequentialHours)) -%}
    {%- endif -%}
    {%- endfor -%}
    {{ ns.cheapestHour }}
    {%- set ns.cheapestPrice = ns.cheapestPrice / numberOfSequentialHours -%}
    {%- endif -%}
This is the automation for fetching the nordpool data.

#automation:

  • id: ‘1663398489324’
    alias: ‘Set device/end start time third’
    description: ‘’
    trigger:
    • platform: time
      at: ‘23:15:00’
      condition:
    • condition: not
      conditions:
      • condition: state
        entity_id: sensor.cheapest_hours_energy_tomorrow_third
        state: unknown
        action:
    • service: input_datetime.set_datetime
      data:
      time: ‘{{ as_timestamp(states(’‘sensor.cheapest_hours_energy_tomorrow_third’’)) | timestamp_custom(’’%H:%M’’) }}’
      target:
      entity_id: input_datetime.device_start_time_third
    • service: input_datetime.set_datetime
      data:

      CHANGE-ME: 3 (3600*3) is the number of sequential cheapest hours we are looking for

      time: ‘{{ ((as_timestamp(states(’‘sensor.cheapest_hours_energy_tomorrow’’)) + (3600*3)) | timestamp_custom(’’%H:%M’’)) }}’
      target:
      entity_id: input_datetime.device_end_time_third
      mode: single
Hope that any of you, are able to spot my mistake.

Thanks

Can I sneak in a question there? I added the additional costs to the sensor, but accidentally wrote the value Swedish Öre instead of SEK, so it got a measurement 100 times as large as expected and that one has now polluted my data so I have a huge spike in the graph. I found the “state” row in the database and removed that one, but the spike is still there. Where does apexcharts get the datapoints for this sensor from?

How to get new Finnish 10% VAT to the sensor?

you can go edit sensor.py
You can find it → /config/custom_components/nordpool
I think you can figure out the rest :wink:
but your sensor name will change. Atleast mine did.

1 Like

Hi,

I’ve been now figuring things out for a while, and this thread has been my lifesaver.
Now I’m in some kind of halt, because after thorough googling, I cant figure out how can i resolve this problem:
I would like to use a slider (input.number) to select x many cheapest hours. Currently I’m picking cheapest hours by:

value_template: >-
      {% set l=state_attr('sensor.nordpool_kwh_fi_eur_3_10_01', 'raw_today')|sort(attribute='value') %}
      {{ (now() >= l[0].start and now() <= l[0].end) }}

So I had in mind to make this thing through multiple automations, that will go on or off depending input number, but there has to be a better way to do this?
Hopefully I was clear enough to be understood.

FYI, this is to make a dumb EV and dumber EV charger a little bit more intelligent.

Thanks @rapu123

So I changed Finlands 0.24 to 0.10 here in sensor.py
The new sensor name is sensor.nordpool_kwh_fi_eur_3_10_01

    "DK1": ["DKK", "Denmark", 0.25],

    "DK2": ["DKK", "Denmark", 0.25],

    "FI": ["EUR", "Finland", 0.10],

    "EE": ["EUR", "Estonia", 0.20],

    "LT": ["EUR", "Lithuania", 0.21],

    "LV": ["EUR", "Latvia", 0.21],

    "Oslo": ["NOK", "Norway", 0.25],

    "Kr.sand": ["NOK", "Norway", 0.25],

    "Bergen": ["NOK", "Norway", 0.25],

    "Molde": ["NOK", "Norway", 0.25],

    "Tr.heim": ["NOK", "Norway", 0.25],

    "Tromsø": ["NOK", "Norway", 0.25],

    "SE1": ["SEK", "Sweden", 0.25],

    "SE2": ["SEK", "Sweden", 0.25],

    "SE3": ["SEK", "Sweden", 0.25],

    "SE4": ["SEK", "Sweden", 0.25],

    # What zone is this?

    "SYS": ["EUR", "System zone", 0.25],

    "FR": ["EUR", "France", 0.055],

    "NL": ["EUR", "Netherlands", 0.09],

    "BE": ["EUR", "Belgium", 0.21],

    "AT": ["EUR", "Austria", 0.20],

    # Tax is disabled for now, i need to split the areas

    # to handle the tax.

    "DE-LU": ["EUR", "Germany and Luxembourg", 0],

2 Likes

Hi,

I am having issues not getting updates for energy prices tomorrow. This than throws off the cheapest energy calculation (from ha_nordpool_cheapest_hours/nordpool_cheapest_hours.yaml at 8a8e78612e29634cd370cadcfe3ef0a926e8913c · kotope/ha_nordpool_cheapest_hours · GitHub) giving

sensor.cheapest_hours_energy_tomorrow rendered invalid timestamp

Any ideas?

There are also these related issues:

Logger: homeassistant.helpers.template_entity
Source: helpers/template_entity.py:356
First occurred: 1:08:16 PM (2 occurrences)
Last logged: 1:08:16 PM

TemplateError('ValueError: Template error: float got invalid input 'unknown' when rendering template '{{ states('sensor.transmission_down_speed')|float * 1024 }}' but no default was specified') while processing template 'Template("{{ states('sensor.transmission_down_speed')|float * 1024 }}")' for attribute '_attr_native_value' in entity 'sensor.transmission_down_speed'
TemplateError('ValueError: Template error: float got invalid input 'unknown' when rendering template '{{ states('sensor.transmission_up_speed')|float * 1024 }}' but no default was specified') while processing template 'Template("{{ states('sensor.transmission_up_speed')|float * 1024 }}")' for attribute '_attr_native_value' in entity 'sensor.transmission_up_speed'

and

Logger: homeassistant.helpers.event
Source: helpers/template.py:425
First occurred: 1:08:16 PM (2 occurrences)
Last logged: 1:08:16 PM

Error while processing template: Template("{{ states('sensor.transmission_down_speed')|float * 1024 }}")
Error while processing template: Template("{{ states('sensor.transmission_up_speed')|float * 1024 }}")
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 1710, in forgiving_float_filter
    return float(value)
ValueError: could not convert string to float: 'unknown'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 423, in async_render
    render_result = _render_with_context(self.template, compiled, **kwargs)
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 1942, in _render_with_context
    return template.render(**kwargs)
  File "/usr/local/lib/python3.10/site-packages/jinja2/environment.py", line 1301, in render
    self.environment.handle_exception()
  File "/usr/local/lib/python3.10/site-packages/jinja2/environment.py", line 936, in handle_exception
    raise rewrite_traceback_stack(source=source)
  File "<template>", line 1, in top-level template code
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 1713, in forgiving_float_filter
    raise_no_default("float", value)
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 1411, in raise_no_default
    raise ValueError(
ValueError: Template error: float got invalid input 'unknown' when rendering template '{{ states('sensor.transmission_down_speed')|float * 1024 }}' but no default was specified

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 540, in async_render_to_info
    render_info._result = self.async_render(variables, strict=strict, **kwargs)
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 425, in async_render
    raise TemplateError(err) from err
homeassistant.exceptions.TemplateError: ValueError: Template error: float got invalid input 'unknown' when rendering template '{{ states('sensor.transmission_down_speed')|float * 1024 }}' but no default was specified

If tomorrow’s hours show, there is no issue with the “kotope” code. So I suppose the issue is more with the Nordpool integration.

Hi!
I feel like a totally newbie and a nutjob, since I tried to add the additional costs to the sensor, even after reading the Nordpool documentation, but with no luck. I just can’t spin my head around this - if I must create a script and save or if it´s enough to paste a bunch of text when configuring the integration. I’m completly lost here. I live in Sweden (SE3) and have 0,7 SEK as additional costs. Can someone please explain it to me as I am a five year old or something, or just paste an example or PM me. Thanks!
/Fanan

Hej!
Put the following under the sensor section in you configuration file.

  - platform: nordpool

    # Should the prices include vat? Default True
    VAT: True

    # What currency the api fetches the prices in
    # this is only need if you want a sensor in a non local currecy
    #currency: "SEK"

    # Helper so you can set your "low" price
    # low_price = hour_price < average * low_price_cutoff
    low_price_cutoff: 0.95

    # What power regions your are interested in.
    # Possible values: "DK1", "DK2", "FI", "LT", "LV", "Oslo", "Kr.sand", "Bergen", "Molde", "Tr.heim", "Tromsø", "SE1", "SE2", "SE3","SE4", "SYS", "EE"
    region: "SE3"

    # How many decimals to use in the display of the price
    precision: 3

    # What the price should be displayed in default
    # Possible values: MWh, kWh and Wh
    # default: kWh
    price_type: kWh

    # This option allows the usage of a template to add a tariff.
    # now() always refers start of the hour of that price.
    # this way we can calculate the correct costs add that to graphs etc.
    # The price result of the additional_costs template expects this additional cost to be in kWh and not cents as a float
    additional_costs: "{{0.7|float}}"
1 Like

Hi, trying to get additional_costs to work. Getting

Error loading /config/configuration.yaml: while scanning for the next token found character ‘%’ that cannot start any token in “/config/sensors/sähkö.yaml”, line 54, column 22

with code below, line 54 being the first one. sähkö.yaml is included in configuration.yaml

  additional_costs: '{% set s = {
    "hourly_fixed_cost": 0.0049,
    "day": 0.0288,
    "night": 0.0154
    }
    %}
    {% if now().hour >=7 and now().hour <22 %}
      {{s.day+s.hourly_fixed_cost|float}}
    {% else %}
      {{s.night+s.hourly_fixed_cost|float}}
    {% endif %}'

Pretty new with home assistant, have tried to look for examples for additional costs and documentation for nordpool but can’t get it to work. Any help would be welcome.

You need to format your code differently. See this documentation: https://yaml-multiline.info/

My sensor looks like this:

  additional_costs: >
    {%
      set s = {
          "night": 0.3685,
          "day": 0.4310,
          "cert": 0.01
      }
    %}
    {%  if states('binary_sensor.workday') and (now().hour >=6 and now().hour <22) %}
      {{s.day+s.cert|float}}
    {%else%}
        {{s.night+s.cert|float}}
    {% endif %}

Thanks, got it to work. Formatting isn’t my strong suit, especially with jinja.