Custom Component: ENTSO-e Day Ahead Energy Prices

You should use the “prices” attribute instead of “prices_today” & “prices_tomorrow”. The “prices” attribute doesn’t change at midnight and is easier to use.

1 Like

I am making some progress, but still can’t manage to get entso-e to show the price with VAT and the 13cent fees added. Can someone please explain how to work with the added cost Template?

I had assumed {{current_price *0.19 + 0.13|float(0)}} like with Nordpool, but that does nothing…

Hi!
It seems like nordpool and entso prices are not correct, nordpool are correct but why is entso showing incorrect values, only thing that is correct is “today highest” and “current”

I think the integration needs quite a few Updates before it is ready for everyday use…

Hi. Is there a version of this (or similar) which presents data for UK? (damn Brexit!!!). Thanks.

Yeah it is a good start but at the moment it is not accurate.
High today is correct, same with current price, but lowest today is way off, same with average.

1 Like

I don’t notice any options to use cents? Am i missing something?

@jeveli did you double check your “rotation” / “sliding” / “publish” on configuration screen of the integration? If you use sliding, the values are calculated from today AND tomorrow values making it seem inaccurate. Same goes for publish as values are updated when next day values are published. I changed this to rotation and now it gives accurate values day-to-day basis.

I liked this example. As JInja etcetera is new to me, I struggled a bit, but I managed to make a slightly different version for the Entsoe integration. It gives me the cheapest 4 hours in period now -next day 08:00 (if available). My use case was switching on my dishwasser after dinner and wanting it to run in the cheapest hours during the night.
I do not know the good formatting rules/syntax else I would have copied the template as well in this reply.

@molsHOOP, I am also running the ENTSOE-e integration and liked this example. I would love to see your adaptation as I am also setting up this use case at home.

Maybe this FAQ page could help to understand the formatting and posting of code? How to help us help you - or How to ask a good question
Thanks anyway.

@RT1080 and @molsHOOP: There is more documentation and code for a similar use case: Home Assistant: Nord Pool Spot prices and how to automate devices for cheapest hours – Creating Smart Home

I signed up for ANWB in December and my contract will (finally) start in a few days. I have 3 basic use cases:

  1. Machines that have a delayed start feature but no remote auto start (Dryer and a dishwasher)
  2. Machines that can auto start at a specific time (I have a newish Washing machine that supports this)
  3. Electric Floor heating that can be switched ON/OFF remotely (simply based on current price)

For 1&2 I created some templates that help to automate/visualize this. I’m not interested in 9AM when it is 10AM so ‘next lowest price time’ updates automatically.

Calculations use a weight - so for 3 hours you can set 50,25,25 or 33,33,34. Code has some comments to explain. Rationale: My dishwasher runs for ~3 hours - but the first hour (warming up water) and third hour (warming up to dry) consumes more so I use 50,20,30.

Hopefully useful for others here as well.


  - platform: template
    sensors:
      next_low_prices:
        friendly_name: "Next hours of lowest energy prices"
        unit_of_measurement: ''
        value_template: >
          {# use prices for today and tomorrow or prices_today for only today ( tomorrow is updated ~1PM) #}
          {% set p = state_attr('sensor.entsoe_average_electricity_price_today','prices') %}
          {% set r = namespace(v=p[0], i=0, j=0) %}
          {% set x = namespace(v1={"price": 99}, v2={"price": 99}, v3={"price": 99}, v4={"price": 99}) %}
          {% set t = as_timestamp(now()) - 3600  %}
          {% for f in p %}
            {# Only inspect times that are later than now (including current hour)#}
            {% if ( as_timestamp(f.time) - t > 0) %}
              
              {# Next 1 hour at the lowest price: charge small appliance #}
              {# This can be achieved without a loop but kept it for consistency #}
              {% if loop.index0 < (loop.length) %}
                {% set r.i = loop.index0 %}
                {% set r.j = 0 %}
                {% for l in [100] %} {% set r.j = r.j + (p[r.i+loop.index0].price * l/100) %}  {% endfor %}
                {% if r.j < x.v1.price %}
                   {% set x.v1 = {"time":f.time, "price": r.j|round(4)} %}
                {% endif %}
              {% endif %}

              {# Next 2 hours at the lowest price: run dishwasher #}
              {% if loop.index0 < (loop.length - 1) %}
                {% set r.i = loop.index0 %}
                {% set r.j = 0 %}
                {# first hour at 60% as it heats up #}
                {% for l in [60,40] %} {% set r.j = r.j + (p[r.i+loop.index0].price * l/100) %}  {% endfor %}
                {% if r.j < x.v2.price %}
                   {% set x.v2 = {"time":f.time, "price": r.j|round(4)} %}
                {% endif %}
              {% endif %}

              {# Next 3 hours at the lowest price: run washingmachine #}
              {% if loop.index0 < (loop.length - 2) %}
                {% set r.i = loop.index0 %}
                {% set r.j = 0 %}
                {# weigh first and last hour more for heat  / spin #}
                {% for l in [50,20,30] %} {% set r.j = r.j + (p[r.i+loop.index0].price * l/100) %}  {% endfor %}
                {% if r.j < x.v3.price %}
                   {% set x.v3 = {"time":f.time, "price": r.j|round(4)} %}
                {% endif %}
              {% endif %}

              {# Next 4 hours at the lowest price: charge large appliance #}
              {% if loop.index0 < (loop.length - 3) %}
                {% set r.i = loop.index0 %}
                {% set r.j = 0 %}
                {% for l in [25,25,25,25] %} {% set r.j = r.j + (p[r.i+loop.index0].price * l/100) %}  {% endfor %}
                {% if r.j < x.v4.price %}
                   {% set x.v4 = {"time":f.time, "price": r.j|round(4)} %}
                {% endif %}
              {% endif %}
            {% endif %}
          {% endfor %}
          {# Concatenate the results #}
          {{ ( {"h1": x.v1 , "h2": x.v2 , "h3": x.v3 , "h4": x.v4})|to_json}}
          
  - platform: template
    sensors:
      next_low_prices_h1_price:
        friendly_name: "Price next 1 hour"
        value_template: >
          {{(states('sensor.next_low_prices')|from_json)['h1']['price'] * 100}}
  - platform: template
    sensors:
      next_low_prices_h2_price:
        friendly_name: "Price next 2 hours"
        value_template: >
          {{(states('sensor.next_low_prices')|from_json)['h2']['price'] * 100}}
  - platform: template
    sensors:
      next_low_prices_h3_price:
        friendly_name: "Price next 3 hours"
        value_template: >
          {{(states('sensor.next_low_prices')|from_json)['h3']['price'] * 100}}
  - platform: template
    sensors:
      next_low_prices_h4_price:
        friendly_name: "Price next 4 hours"
        value_template: >
          {{(states('sensor.next_low_prices')|from_json)['h4']['price'] * 100}}

  - platform: template
    sensors:
      display_current_hour_market_price:
        friendly_name: "Entsoe Price current hour"
        value_template: >
          {{(states('sensor.entsoe_current_electricity_market_price') | round(5) * 100)}}
  - platform: template
    sensors:
      display_next_hour_market_price:
        friendly_name: "Entsoe Price next hour"
        value_template: >
          {{(states('sensor.entsoe_next_hour_electricity_market_price') | round(5) * 100)}}          
  - platform: template
    sensors:
      display_diff_hour_market_price:
        friendly_name: "Entsoe Price diff hour"
        value_template: >
             {% set c = states('sensor.entsoe_current_electricity_market_price') | round(5) * 100 %}
             {% set n = states('sensor.entsoe_next_hour_electricity_market_price') | round(5) * 100 %}
             {{ (n - c) | round (5) }} 
     
  - platform: template
    sensors:
      next_low_prices_h1_time:
        friendly_name: "Time next 1 hour"
        value_template: >
          {% set s = (states('sensor.next_low_prices')|from_json)['h1']['time']|as_datetime %}
          {% if now().day == s.day %}
          TODAY {{ s.strftime('%H:%M') }}
          {% else %}
          TOMORROW {{ s.strftime('%H:%M') }}
          {% endif %}
  - platform: template
    sensors:
      next_low_prices_h2_time:
        friendly_name: "Time next 2 hours"
        value_template: >
          {% set s = (states('sensor.next_low_prices')|from_json)['h2']['time']|as_datetime %}
          {% if now().day == s.day %}
          TODAY {{ s.strftime('%H:%M') }}
          {% else %}
          TOMORROW {{ s.strftime('%H:%M') }}
          {% endif %}
  - platform: template
    sensors:
      next_low_prices_h3_time:
        friendly_name: "Time next 3 hours"
        value_template: >
          {% set s = (states('sensor.next_low_prices')|from_json)['h3']['time']|as_datetime %}
          {% if now().day == s.day %}
          TODAY {{ s.strftime('%H:%M') }}
          {% else %}
          TOMORROW {{ s.strftime('%H:%M') }}
          {% endif %}
  - platform: template
    sensors:
      next_low_prices_h4_time:
        friendly_name: "Time next 4 hours"
        value_template: >
          {% set s = (states('sensor.next_low_prices')|from_json)['h4']['time']|as_datetime %}
          {% if now().day == s.day %}
          TODAY {{ s.strftime('%H:%M') }}
          {% else %}
          TOMORROW {{ s.strftime('%H:%M') }}
          {% endif %}

And to visualize this on a page - I use the following:

type: vertical-stack
cards:
  - square: false
    columns: 4
    type: grid
    cards:
      - type: gauge
        name: 1 hour
        entity: sensor.next_low_prices_h1_price
        severity:
          green: 0
          yellow: 20
          red: 40
        min: 0
        max: 80
        needle: false
      - type: gauge
        name: 2 hours
        entity: sensor.next_low_prices_h2_price
        severity:
          green: 0
          yellow: 20
          red: 40
        min: 0
        max: 80
      - type: gauge
        name: 3 hours
        entity: sensor.next_low_prices_h3_price
        severity:
          green: 0
          yellow: 20
          red: 40
        min: 0
        max: 80
      - type: gauge
        name: 4 hours
        entity: sensor.next_low_prices_h4_price
        severity:
          green: 0
          yellow: 20
          red: 40
        min: 0
        max: 80
  - square: false
    columns: 4
    type: grid
    cards:
      - show_name: false
        show_icon: false
        type: button
        tap_action:
          action: toggle
        entity: sensor.next_low_prices_h1_time
        show_state: true
      - show_name: false
        show_icon: false
        type: button
        tap_action:
          action: toggle
        entity: sensor.next_low_prices_h2_time
        show_state: true
      - show_name: false
        show_icon: false
        type: button
        tap_action:
          action: toggle
        entity: sensor.next_low_prices_h3_time
        show_state: true
      - show_name: false
        show_icon: false
        type: button
        tap_action:
          action: toggle
        entity: sensor.next_low_prices_h4_time
        show_state: true

3 Likes

Team,

When you configure VAT in the plugin config with the value: “0.21”

When is this 21% VAT applied? After the “Price Modifier Template” or before?

I have the quoted sensor for nordpool, but can’t get it to work if I replace the nordpool sensor with entsoe average…price_today. Any hints?

The date time convention used as well as the attribute names are different. You would need to adjust the template sensor to cater for this.

The Nordpool integration is just too flaky nowadays. Hardly ever updates in the afternoon without HA restart.

I need help with the attribute and date time conversion. I’d like to just make a template sensor that i could point all my existing code to. I.e just use the entso-e data (i have the integration up and running) but have an entity with the same exact data, format and attributes as the nordpool data has now. Has anyone managed to accomplish this?

I’m just too deep already and cant start reformatting all the code.

1 Like

I would also like to move away from Nordpool, but I am jot seeing much progress with entso-e and it’s still a nightmare to get it to calculate the actual price with taxes and fees included…

My graphs stopped working after a reinstall from backup of HA. My graphs are empty except for the ‘Now’ marking.
image
The data form Entso seems to be coming through just fine: image
Also when looking at the ‘State’ of the entity the price data is showing up just fine:


My card configuration looks like this:

type: custom:apexcharts-card
experimental:
  color_threshold: true
graph_span: 24h
span:
  start: day
now:
  show: true
  label: Nu
header:
  show: true
  title: Stroomprijs vandaag (€/kWh)
series:
  - entity: sensor.dynamische_prijzen_average_electricity_price_today
    stroke_width: 2
    float_precision: 3
    type: column
    opacity: 1
    color: ''
    data_generator: |
      return entity.attributes.prices.map((record, index) => {
        return [record.time, record.price];
      });
yaxis:
  - id: Prijs
    decimals: 2
    min: 0

Anybody that has seen this problem before or knows how to fix it?

I had the same issue with Nordpool update 0.0.14. Turned back to 0.0.13. There is more info on github/nordpool. Look at #issues

Hi I had the same issue a few days ago. Remove the current integration and reinstall it under a different name. This works but you have to update your charts and templates which still use the old entity names etc. Not sure what is going on but something with cache perhaps? Is there a way to clean the cache from HA? Perhaps someone has some insight into this?