Tomorrows price unavailable with Nordpool core integration

I’m in the process of moving from the custom component for Nordpool to the new core integration. Besides having issues displaying today and tomorrow’s price on a chart (see here), I’m also trying to follow the examples form the official doc.
When testing “tomorrow’s lowest price” in the template editor, I get

‘tomorrow_price’ is undefined

I used the exact same code as the Example, just changed my config_entry and SE3 to SE4.

template:
  - trigger:
      - trigger: time_pattern
        minutes: /10
      - trigger: homeassistant
        event: start
    action:
      - action: nordpool.get_prices_for_date
        data:
          config_entry: 01JHZHJ9EMYV8JA28490CH5GEE
          date: "{{ now().date() + timedelta(days=1) }}"
          areas: SE4
          currency: SEK
        response_variable: tomorrow_price
    sensor:
      - name: Tomorrow lowest price
        unique_id: se4_tomorrow_low_price
        state: >
          {% if not tomorrow_price %}
            unavailable
          {% else %}
            {% set data = namespace(prices=[]) %}
            {% for state in tomorrow_price['SE4'] %}
              {% set data.prices = data.prices + [(state.price / 1000)] %}
            {% endfor %}
            {{min(data.prices)}}
          {% endif %}
        attributes:
          data: >
            {% if not tomorrow_price %}
              []
            {% else %}
              {% set data = namespace(prices=[]) %}
              {% for state in tomorrow_price['SE4'] %}
                {% set data.prices = data.prices + [{'start':state.start, 'end':state.end, 'price': state.price/1000}] %}
              {% endfor %}
              {{data.prices}}
            {% endif %}

Anything I do wrong? Or is this a bug with the integration?

I didn’t find any information on the actions available with the integration (e.g. get_prices_for_date), where are these documented?

1 Like

Is tomorrows prices available then?
Can you look at the entity and see if there are any prices tomorrow?

They should be.
If I got to Developper tools > Actions I can get them:

But under entity states, I can’t see anything:

1 Like

Check the state by searching for Tomorrow lowest price

Nope, there is nothing about tomorrow’s price anywhere.

However, the Action works when I perform it from the Actions menu:

I tried changing the response_variable to service_result but that doesn’t change anything. It shouldn’t actually matter as the name of the variable is decided in the action of the template.

Anyone who managed to get the dcumentation’s example working?
https://www.home-assistant.io/integrations/nordpool/#tomorrows-lowest-price

1 Like

Here is a working example

 - trigger:
      - trigger: time_pattern
        minutes: /10
      - trigger: homeassistant
        event: start
    action:
      - action: nordpool.get_prices_for_date
        data:
          config_entry: 01JKBP83VGA8S6TH1C3041Y189
          date: "{{ now().date() + timedelta(days=1) }}"
          areas: SE3
          currency: SEK
        response_variable: tomorrow_price
    sensor:
      - name: Nord Pool Tomorrow Lowest price
        unique_id: se3_tomorrow_low_price
        state: >
          {% if not tomorrow_price %}
            unavailable
          {% else %}
            {% set data = namespace(prices=[]) %}
            {% for state in tomorrow_price['SE3'] %}
              {% set data.prices = data.prices + [(state.price / 1000)] %}
            {% endfor %}
            {{min(data.prices)}}
          {% endif %}
        attributes:
          data: >
            {% if not tomorrow_price %}
              []
            {% else %}
              {% set data = namespace(prices=[]) %}
              {% for state in tomorrow_price['SE3'] %}
                {% set corrected_start = as_datetime(state.start).astimezone().strftime('%Y-%m-%d %H:%M:%S') %}
                {% set corrected_end = as_datetime(state.end).astimezone().strftime('%Y-%m-%d %H:%M:%S') %}
                {% set data.prices = data.prices + [{'start':corrected_start, 'end':corrected_end, 'price': state.price/1000}] %}
              {% endfor %}
              {{data.prices}}
            {% endif %}

For my scenario i converted timestamps to be in my timezone
In states i can find it by filtering on this


BTW i found that i need to refresh the states page after a modification

I switched to core version as well and see the same problem, why did they drop those hourly prices - today and tomorrow? Makes no sense.

If there is no solution, I’m forced to move back to HACS-version.

Update: So i did,

  • took a git clone to custom_components,
  • checkout tag 0.0.16
  • restart whole system
    and everything is back in normal. Wasted good working hours, sigh.

Could you please update the topic, it’s not only tomorrows price, it’s whole hourly prices from today and tomorrow that is missing. This prevents all kind of charts and dynamic optimizers from working. Current topic ‘tomorrow’s price’ is a bit misleading.

Home-assistant official nordpool integration · Issue #451 · custom-components/nordpool · GitHub

gjohansson-STon Dec 18, 2024

Lastly, as the native one is new there will be some iterations
before it’s complete. As example in 2025.1 there will be an
action call to get all prices for a date etc. There is no preference
for which one to use more than your own preference and use-
case.

Here is how I got the Nordpool core integration and Apexcharts working with todays and tomorrows prices.

First I found a chart example that works for the custom nordpool integration here: https://gathering.tweakers.net/forum/list_message/73974776#73974776

The issue for me and others is/was that there is no attribute raw_today or row_tomorrow in the core integration.

Like @iculda I already had a working trigger template based on the example in: Nord Pool - Home Assistant

My trigger template looks like this:

template:
  - trigger:
      - trigger: time_pattern
        minutes: /10
      - trigger: homeassistant
        event: start
    action:
      - action: nordpool.get_prices_for_date
        data:
          config_entry: REPLACE_WITH_YOUR_OWN_CONFIG_ENTRY
          date: "{{ now().date() + timedelta(days=1) }}"
          areas: NL
          currency: EUR
        response_variable: tomorrow_price
      - action: nordpool.get_prices_for_date
        data:
          config_entry: REPLACE_WITH_YOUR_OWN_CONFIG_ENTRY
          date: "{{ now().date() }}"
          areas: NL
          currency: EUR
        response_variable: today_price
    sensor:
      - name: Tomorrow lowest price
        unique_id: nl_tomorrow_low_price
        unit_of_measurement: "EUR/kWh"
        icon: mdi:cash
        state: >
          {% if tomorrow_price is mapping %}
            {% set data = namespace(prices=[]) %}
            {% set electricity_tax = states('input_number.electricity_tax') | float(0) %}
            {% set purchase_costs = states('input_number.electricity_purchase_costs') | float(0) %}
            {% for state in tomorrow_price['NL'] %}
              {% set data.prices = data.prices + [((state.price/1000 + electricity_tax + purchase_costs) * 1.21) | round(3, default=0)] %}
            {% endfor %}
            {{min(data.prices)}}
          {% else %}
            unavailable
          {% endif %}
        attributes:
          data: >
            {% if tomorrow_price is mapping %}
            {% set electricity_tax = states('input_number.electricity_tax') | float(0) %}
            {% set purchase_costs = states('input_number.electricity_purchase_costs') | float(0) %}
            {% set data = namespace(prices=[]) %}
              {% for state in tomorrow_price['NL'] %}
                {% set data.prices = data.prices + [{'start':state.start, 'end':state.end, 'price': ((state.price/1000 + electricity_tax + purchase_costs) * 1.21) | round(3, default=0)}] %}
              {% endfor %}
              {{data.prices}}
            {% else %}
              []
            {% endif %}
      - name: Tomorrow highest price
        unique_id: nl_tomorrow_high_price
        unit_of_measurement: "EUR/kWh"
        icon: mdi:cash
        state: >
          {% if tomorrow_price is mapping %}
            {% set data = namespace(prices=[]) %}
            {% set electricity_tax = states('input_number.electricity_tax') | float(0) %}
            {% set purchase_costs = states('input_number.electricity_purchase_costs') | float(0) %}
            {% for state in tomorrow_price['NL'] %}
              {% set data.prices = data.prices + [((state.price/1000 + electricity_tax + purchase_costs) * 1.21) | round(3, default=0)] %}
            {% endfor %}
            {{max(data.prices)}}
          {% else %}
            unavailable
          {% endif %}
        attributes:
          data: >
            {% if tomorrow_price is mapping %}
            {% set electricity_tax = states('input_number.electricity_tax') | float(0) %}
            {% set purchase_costs = states('input_number.electricity_purchase_costs') | float(0) %}
            {% set data = namespace(prices=[]) %}
              {% for state in tomorrow_price['NL'] %}
                {% set data.prices = data.prices + [{'start':state.start, 'end':state.end, 'price': ((state.price/1000 + electricity_tax + purchase_costs) * 1.21) | round(3, default=0)}] %}
              {% endfor %}
              {{data.prices}}
            {% else %}
              []
            {% endif %}
      - name: Today prices
        unique_id: nl_today_prices
        unit_of_measurement: "EUR/kWh"
        icon: mdi:cash
        state: >
          {% if today_price is mapping %}
            {% set data = namespace(prices=[]) %}
            {% set electricity_tax = states('input_number.electricity_tax') | float(0) %}
            {% set purchase_costs = states('input_number.electricity_purchase_costs') | float(0) %}
            {% for state in today_price['NL'] %}
              {% set data.prices = data.prices + [((state.price/1000 + electricity_tax + purchase_costs) * 1.21) | round(3, default=0)] %}
            {% endfor %}
            {{min(data.prices)}}
          {% else %}
            unavailable
          {% endif %}
        attributes:
          data: >
            {% if today_price is mapping %}
            {% set electricity_tax = states('input_number.electricity_tax') | float(0) %}
            {% set purchase_costs = states('input_number.electricity_purchase_costs') | float(0) %}
            {% set data = namespace(prices=[]) %}
              {% for state in today_price['NL'] %}
                {% set data.prices = data.prices + [{'start':state.start, 'end':state.end, 'price': ((state.price/1000 + electricity_tax + purchase_costs) * 1.21) | round(3, default=0)}] %}
              {% endfor %}
              {{data.prices}}
            {% else %}
              []
            {% endif %}

As you can see I have some sensors for the lowest price tomorrow and the highest price tomorrow. That already have an attribute called data with as contents something like this:

start: <date>, end: <date>, price: <in EUR/kWh including taxes, VAT and purchase costs>

So at first I changed the span, entity and data_generator part of the ApexChart definition to:

span:
  start: day
  offset: +1d
series:
  - entity: sensor.tomorrow_lowest_price
    data_generator: |
      return entity.attributes.data.map((start, index) => {
        return [new Date(start["start"]).getTime() + 1800000, entity.attributes.data[index]["price"]];
      });

Which resulted in this:

type: custom:apexcharts-card
experimental:
  color_threshold: true
graph_span: 23h
header:
  title: Electricity Prices Tomorrow
  show: true
span:
  start: day
  offset: +1d
series:
  - entity: sensor.tomorrow_lowest_price
    type: column
    show:
      extremas: true
    float_precision: 3
    data_generator: |
      return entity.attributes.data.map((start, index) => {
        return [new Date(start["start"]).getTime() + 1800000, entity.attributes.data[index]["price"]];
      });
    color_threshold:
      - value: 0
        color: "#186ddc"
      - value: 0.155
        color: "#04822e"
      - value: 0.2
        color: "#12A141"
      - value: 0.25
        color: "#79B92C"
      - value: 0.3
        color: "#C4D81D"
      - value: 0.35
        color: "#F3DC0C"
      - value: 0.4
        color: "#EFA51E"
      - value: 0.45
        color: "#E76821"
      - value: 0.5
        color: "#DC182F"
yaxis:
  - id: "1"
    align_to: 0.1
    decimals: 2
    apex_config:
      title:
        text: €/kWh
      tickAmount: 4
apex_config:
  xaxis:
    type: datetime
    tooltip:
      enabled: false
  tooltip:
    enabled: true
    x:
      show: true
    fixed:
      enabled: true
      position: topLeft
  chart:
    height: 320px
  grid:
    show: true
    borderColor: rgba(255,255,255,0.1)

And that gave me the correct prices for tomorrow. Then I still was missing the today_prices so I added the following sensor to my template trigger:

      - name: Today prices
        unique_id: nl_today_prices

With the chart definition like this gave me the graph I wanted:

type: custom:apexcharts-card
experimental:
  color_threshold: true
graph_span: 23h
header:
  title: Electricity Prices Today
  show: true
span:
  start: day
now:
  show: true
  label: Now
series:
  - entity: sensor.today_prices
    type: column
    show:
      extremas: true
    float_precision: 3
    data_generator: |
      return entity.attributes.data.map((start, index) => {
        return [new Date(start["start"]).getTime() + 1800000, entity.attributes.data[index]["price"]];
      });
    color_threshold:
      - value: 0
        color: "#186ddc"
      - value: 0.155
        color: "#04822e"
      - value: 0.2
        color: "#12A141"
      - value: 0.25
        color: "#79B92C"
      - value: 0.3
        color: "#C4D81D"
      - value: 0.35
        color: "#F3DC0C"
      - value: 0.4
        color: "#EFA51E"
      - value: 0.45
        color: "#E76821"
      - value: 0.5
        color: "#DC182F"
yaxis:
  - id: "1"
    align_to: 0.1
    decimals: 2
    apex_config:
      title:
        text: €/kWh
      tickAmount: 4
apex_config:
  xaxis:
    type: datetime
    tooltip:
      enabled: false
  tooltip:
    enabled: true
    x:
      show: true
    fixed:
      enabled: true
      position: topLeft
  chart:
    height: 320px
  grid:
    show: true
    borderColor: rgba(255,255,255,0.1)

See this picture:

The only thing that do not quite understand is why fetching the data in developer tools works immediately and with the template trigger it didn’t return data until the data for tomorrow was available. Restarting HA Core didn’t update the sensor today_prices (nor just reloading template entitities: Developer Tools–> Yaml → YAML configuration reloading → TEMPLATE ENTITIES).

My guess is that the action part of the template trigger wasn’t able to ge the prices for tomorrow and thus didn’t do to the next action as well. But I am not sure. At 12:50 today the prices for tomorrow were there and my sensor for today_prices was also populated.

When working on the high and low sensors a few weeks ago I got the impression that some data is cached thus not executing the api for nordpool every 10 minutes like the trigger suggests. But I am not sure of this.

Hopefully this helps others trying to get these nice graphs with the core integration working as well.

4 Likes

Any idea when core Nordpool will get fixes for us mortals to add hourly graph for next day? Im looking at above code hell, and I dont understand it… =)

OK, so I have been playing around with this and come up with something that suits my needs. Maybe helpful to someone else…
The following is based on the above code from @pcroozen (Thanks).

  1. I was not able to figure out how to use the GUI for creating the trigger, actions and sensor. Is this possible as the actions return a ‘response_variable’.
    So I finally went with the terminal/CLI. As I don’t want to clutter the configuration.yaml, I created a new file 'templates.yaml" and reference it from config:
    template: !include templates.yaml

  2. I don’t want two graphs, one for today and one for tomorrow, just one graph for both days as Nord Pool updates with prices for today and tomorrrow at 12:00 CET.

  3. I’m not sure I’m a fan of using HACS as these repos seem to be dependent on the availablility and interest of the creators. But in this case I didn’t find any option to using apex-chartcards. Installation was easy with a click. When adding a card to the dashboard, it shows up at the bottom of the list.

  4. Finding the actions/config_entry:
    Go to Developer tools → Actions (GUI mode)
    Action: “Nord Pool: Get prices for date”
    Integration: “Nord Pool”
    Date: select todays date
    Click “Perform Action” and then “Go to yaml mode”

  5. templates.yaml:
    The code for state should probably be changed for something useful…
    Currently I am only interested in the base Nord Pool price so I am not using the tax or purchase options (not even sure of how input_number works).

- triggers:                                                                                                                                                                                                                                                                                                                   
    - trigger: time_pattern
      minutes: /10
    - trigger: homeassistant
      event: start
  actions:
    - action: nordpool.get_prices_for_date
      data:
        config_entry: <Add YOUR config_entry here>
        date: "{{ now().date() }}"
        areas: SE3
        currency: SEK
      response_variable: today_price
    - action: nordpool.get_prices_for_date
      data:
        config_entry: <Add YOUR config_entry here>
        date: "{{ now().date() + timedelta(days=1) }}"
        areas: SE3
        currency: SEK
      response_variable: tomorrow_price
  sensor:
    - name: Electricity prices
      unique_id: se3_electricity_prices
      unit_of_measurement: "SEK/kWh"
      icon: mdi:cash
      state: >
        {% if (today_price is mapping) and (tomorrow_price is mapping) %}
          {% set data = namespace(prices=[]) %}
          {% set electricity_tax = states('input_number.electricity_tax') | float(0) %}
          {% set purchase_costs = states('input_number.electricity_purchase_costs') | float(0) %}
          {% for state in today_price['SE3'] %}
            {% set data.prices = data.prices + [((state.price/1000 + electricity_tax + purchase_costs) * 1.0) | round(3, default=0)] %}
          {% endfor %}
          {% for state in tomorrow_price['SE3'] %}
            {% set data.prices = data.prices + [((state.price/1000 + electricity_tax + purchase_costs) * 1.0) | round(3, default=0)] %}
          {% endfor %}
          {{min(data.prices)}}
        {% else %}
          unavailable
        {% endif %}
      attributes:
        data: >
          {% if (today_price is mapping) and (tomorrow_price is mapping) %}
          {% set electricity_tax = states('input_number.electricity_tax') | float(0) %}
          {% set purchase_costs = states('input_number.electricity_purchase_costs') | float(0) %}
          {% set data = namespace(prices=[]) %}
            {% for state in today_price['SE3'] %}
              {% set corrected_start = as_datetime(state.start).astimezone().strftime('%Y-%m-%d %H:%M:%S') %}
              {% set corrected_end = as_datetime(state.end).astimezone().strftime('%Y-%m-%d %H:%M:%S') %}
              {% set data.prices = data.prices + [{'start':corrected_start, 'end':corrected_end, 'price': ((state.price/1000 + electricity_tax + purchase_costs) * 1.0) | round(3, default=0)}] %}
            {% endfor %}
            {% for state in tomorrow_price['SE3'] %}
              {% set corrected_start = as_datetime(state.start).astimezone().strftime('%Y-%m-%d %H:%M:%S') %}
              {% set corrected_end = as_datetime(state.end).astimezone().strftime('%Y-%m-%d %H:%M:%S') %}
              {% set data.prices = data.prices + [{'start':corrected_start, 'end':corrected_end, 'price': ((state.price/1000 + electricity_tax + purchase_costs) * 1.0) | round(3, default=0)}] %}
            {% endfor %}
            {{data.prices}}
          {% else %}
            []
          {% endif %}
  1. apex-chartcard:
    The documentation is available from HACS. Click your downloaded “apecxcharts-card”. Links don’t work (for me) and it is a bit unstructured.
type: custom:apexcharts-card
experimental:
  color_threshold: true
header:
  show: true
  title: NordPool electricity prices (today/tomorrow)
  show_states: true
  colorize_states: true
graph_span: 48h
span:
  end: day
  offset: +1d
now:
  show: true
  label: Now
series:
  - entity: sensor.electricity_prices
    type: column
    show:
      extremas: true
      in_header: before_now
    float_precision: 3
    data_generator: |
      return entity.attributes.data.map((start, index) => {
        return [new Date(start["start"]).getTime() + 1800000, entity.attributes.data[index]["price"]];
      });
    color_threshold:
      - value: 0
        color: "#186ddc"
      - value: 0.15
        color: "#04822e"
      - value: 0.2
        color: "#12A141"
      - value: 0.25
        color: "#79B92C"
      - value: 0.3
        color: "#C4D81D"
      - value: 0.35
        color: "#F3DC0C"
      - value: 0.4
        color: "#EFA51E"
      - value: 0.45
        color: "#E76821"
      - value: 0.5
        color: "#DC182F"

This is what I get:


You can compare your results with what Nord Pool provdes:
Nord Pool | Data Portal
Of course you have to select your country/region…

NOTE:
The “+ 1800000” is (as I understand it) to get the price indication at the middle of the hour - xx:30.
As per details on Nord Pool page:

When SDAC 15-minute goes live, estimated for 11 June 2025, official Day-Ahead prices will be provided in 15-minute resolution. This update is mandated externally and is not within our control.

So the code above may have to be updated soon…

3 Likes

I took out the 1800000 in the code examples above to be prepared for the quarterly prices. The input_numbers are helpers I use to calculate the actual costs. I can update the energy tax, VAT or the purchase costs when they change without having to change the template trigger/sensor.

In NL we have a complex system, and I wanted to know when the prices including all costs and taxes are negative. When that happens I switch off our SolarEdge inverter with a HACS modbus integration. Because I do not want to pay for supplying energy to the grid. The SolarEdge app has a function to do that, but cannot handle the complex Dutch situation. It switches off the inverter too soon.

I also created a third graph to show the prices for today before the today’s auction time. (Based on yesterday’s prices for tomorrow. If you can still follow me :thinking:)

I think I found a bug. I had one trigger with two actions. One for the prices of today (the second action) and one for the prices of tomorrow. That fails of course when those prices are not known yet. Thus leaving me with an empty graph for today and tomorrow. Created a trigger for each action and I suspect that would fix the issue for why I thought I needed a third graph.

I like the import of the template file @teebar and used that as well.

Besides this I created an input datetime helper that I can use to select a date between the last two months and tomorrow. Along with a template trigger that gets triggered by changing the date and then uses that to get the prices for that day.

Only ApexCharts will not auto adjust graph_span. For now I use a span of 22days to get the highlights of that day.

1 Like

So its not possible to make just one apexcard, without custom config to templates.yaml?

That is correct. If you want to use the nordpool core integration that lacks the raw_today and raw_tomorrow attributes you need to use a trigger template.
That you can put in a separate file.

If you want to use the ApexCharts you need to install HACS and with that ApexCharts. If you can do that, then I do not see the big issue with editing the config.

I use the Visual Studio Code add-on for that.

Just make sure you know how to create and restore a backup in HA, and test (via Developer Tools ->YAML → Check and restart → Check configuration) if your HA will still startup after you make some changes and before you actually do the restart.

But if you use HACS you can probably also use the Nordpool integration from there. That has the attributes I mentioned before. But I have no experience with that. I am not sure whether you do not need any template helpers there.

Hope this helps.
Patrick

1 Like

[quote=“teebar, post:12, topic:838167”]
Hi, I got a error in a templates.yaml, how to fix it ?
actions: Property actions is not allowed.

Thanks a mil! This works right away! :white_check_mark:
After recently spending a whole evening only trying to get the price sensors to appear.

Hi, what is config_entry…the API?
Can i get an API without being customer of Nord Pool ?

Thanks! Tomes

Hi @Tomes ,

config_entry is a generated / assigned unique number (as it seems to me).

@ Developer Tools / Actions, just run
nordpool.get_price_indices_for_date

Next, tap “Goto YAML mode”, and you’ll see your config_entry.

There’s no need for an API, just add the Nord Pool integration (NOT the hacs version).
No need to be a customer.

1 Like

Thanks Peter, first i installed nordpool Planner from dala318, there i saw only some prefabed entities but No “today” and “tomorrow” . So i thought i would need an API . Then i installed nordpool from hellowlol , there i got only one entity, but i made template Sensors to read out what i want.

So now i’m nearly Happy for the beginning.

Two Things Annoy me, First that the Apex Chart Card does Not Show the current price with 3 decimals, it rounds to only one.

Second hast also to do with apex Card.
I want to see the raw-today and raw-tomorrow prices, they seem to load, i have Here also the Same decimals Problem as described but further the whole Grafik only goes to the actual time but Not Till end of tomorrow.

Any idea Here?

Thanks again for your Help!

1 Like