xztraz
(Xztraz)
October 13, 2025, 7:43pm
47
sounds weird.
i did some small updates to the graph scripts today but mostly just some titles that where wrong. and a update to the template script some days ago where tomorrow gets data at minutes: 10 (i saw that pulling data to two templates at once from nordpool was giving some errors so did a little bit of delay for the tomorrows data and that seem to work)
the nordpool integration usually takes in new data within an hour after release. and tomorrows data template updates every hour. so might take up to two hours after nordpool releases new prices. you can change the update interval for tomorrows template.
also. the apex chart sometimes missbehaves and you need to reload the page to see tomorrows data. also try in another browser. if that doesn’t work. check logs if something misbehaves regarding the template. also check the state of tomorrows data under envelopment tools. to see if there is data from the template or if it gets stuck before that somehow
1 Like
xztraz
(Xztraz)
October 13, 2025, 9:07pm
48
also update your ha to latest core. some nordpool bugs are fixed in that
1 Like
viperhansa
(Hans Åström)
October 14, 2025, 6:34pm
49
Well, started over and redid the apex chart…
Now it seems to be working.
Is it possible to have the chart on auto scale?
~12 set and the price is low i tgives a lot of overhead and empty space…
And THANK YOU for the support and time you put into this!
regards
// Hans
viperhansa
(Hans Åström)
October 14, 2025, 7:03pm
50
Spoke to early… It work perfectly in web browser on pc.
And in HA app on android… BUT only in portrait view… Horizontal it’s just the date line and the header values that are visible.
Any ideas?
//Hans
xztraz
(Xztraz)
October 15, 2025, 6:42am
51
its the reactive part that you might want to look into. its a bit buggy in apexchart and i’ve only adjusted it to my usercase. since it’s dependent on screen resolution you might want to do another graph for small devices
viperhansa
(Hans Åström)
October 15, 2025, 5:58pm
52
the reactive part? never heard about it.
Any pointers?
Edit: problem solved… didn’t really know how but changed PX values in the begining of the chart code…
Again, thank you for the support and your work!
//Hans
Saukko
(Saukko)
October 29, 2025, 8:47am
54
Thank You guys! Now I get it The “key” was remove/uninstall the nordpool from HASC. Then install that Nordpool from the “devices”.
Sven.2410
(Sven.2410)
October 29, 2025, 10:48am
55
I have no Area. You have Sweden 1,2,3 and 4. I live in The Netherlands what do i need to put after area:
xztraz
(Xztraz)
October 30, 2025, 6:44am
56
have you tried with NL as country and area?. since you already configure that in the nordpool integration. the data should be from the right place and in the template i just tried to mimic the hacs version data output. its not used by the graph so should be fine with whatever you put there.
MrGlad8
(Andree)
November 1, 2025, 10:44am
57
Heya, I’m a bit lost. I just tried the new official Nordpool integration after using the HACS version for years. Now I’m left with seven sensors, but no daily prices or tomorrow’s prices. I understand that the new integration requires creating extra sensors via templates, but the documentation only shows an example for tomorrow’s prices. How do I create a sensor that shows today’s prices?
And I guess I now need to add VAT also via a template sensor?
xztraz
(Xztraz)
November 3, 2025, 8:10am
58
@MrGlad8
have you read this thread with the examples? you get today and tomorrow. helpers for vat and such.
MrGlad8
(Andree)
November 10, 2025, 4:35pm
59
Should I just copy your code from the #5 post? Didnt get it tot work, will try again!
xztraz
(Xztraz)
November 21, 2025, 4:03pm
60
start from post 3. guide is sectioned.
the sensor doesn’t show date/time with the data
while for the next day
it does. is this the problem?
MattiW
November 28, 2025, 8:43am
62
I have a strange behavior word the Core nordpool integration. At the start of the day (from 00:00 to 13:05), the template (code below) collects the data from yesterday as the today_price, and i don’t know why.
If i use a template action in the developer tools the collected data is fine, what am i missing?
- trigger:
- trigger: time_pattern
minutes: /15
- trigger: homeassistant
event: start
action:
- action: nordpool.get_prices_for_date
data:
config_entry: 01KB4QNAERVA78WH3Z93BYE47R
date: "{{ now().date() + timedelta(days=1) }}"
areas: BE
currency: EUR
response_variable: tomorrow_price
- action: nordpool.get_prices_for_date
data:
config_entry: 01KB4QNAERVA78WH3Z93BYE47R
date: "{{ now().date()}}"
areas: BE
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['BE'] %}
{% set data.prices = data.prices + [(state.price/1000) | 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['BE'] %}
{% set data.prices = data.prices + [{'start':state.start, 'end':state.end, 'price': (state.price/1000) | 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['BE'] %}
{% set data.prices = data.prices + [(state.price/1000) | 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['BE'] %}
{% set data.prices = data.prices + [{'start':state.start, 'end':state.end, 'price': (state.price/1000) | 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['BE'] %}
{% set data.prices = data.prices + [(state.price/1000) | 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['BE'] %}
{% set data.prices = data.prices + [{'start':state.start, 'end':state.end, 'price': (state.price/1000) | round(3, default=0)}] %}
{% endfor %}
{{data.prices}}
{% else %}
[]
{% endif %}
Change the code a bit, now its working:
- trigger:
- trigger: time_pattern
minutes: /15
- trigger: homeassistant
event: start
action:
- variables:
area: NL
currency: EUR
config_entry: <your own config_ID>
price_now: sensor.nord_pool_nl_current_price
price_low: sensor.nord_pool_nl_lowest_price
price_high: sensor.nord_pool_nl_highest_price
- action: nordpool.get_price_indices_for_date
data:
config_entry: "{{ config_entry }}"
date: "{{ now().date() }}"
areas: "{{ area }}"
currency: "{{ currency }}"
resolution: "15"
response_variable: today_price
- action: nordpool.get_price_indices_for_date
data:
config_entry: "{{ config_entry }}"
date: "{{ now().date() + timedelta(days=1) }}"
areas: "{{ area }}"
currency: "{{ currency }}"
resolution: "15"
response_variable: tomorrow_price
sensor:
- name: Electricity prices
unique_id: nl_electricity_prices
unit_of_measurement: "cent/kWh"
icon: mdi:cash
state: > # returns the current price
{% set electricity_tax = states('input_number.electricity_tax') | float(0) %}
{% set purchase_costs = states('input_number.electricity_purchase_costs') | float(0) %}
{% set vat = states('input_number.VAT') | float(0) %}
{% set current_price = ((states(price_now) | float(0) + electricity_tax + purchase_costs) * (100 + vat)) | round(1) %}
{{ current_price }}
attributes:
tomorrow_valid: >
{{ tomorrow_price["NL"] | count > 0 }}
average: >
{% 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) %}
{% set vat = states('input_number.VAT') | float(0) %}
{% if today_price["NL"] | count > 0 %}
{% for state in today_price["NL"] %}
{% set corrected_start = as_datetime(state.start).astimezone().isoformat() %}
{% set corrected_end = as_datetime(state.end).astimezone().isoformat() %}
{% set data.prices = data.prices + [{'start':corrected_start, 'end':corrected_end, 'value': ((state.price/1000) * (100 + vat) + (purchase_costs+ electricity_tax)*100) | round(1)}] %}
{% endfor %}
{% endif %}
{% if tomorrow_price["NL"] | count > 0 %}
{% for state in tomorrow_price["NL"] %}
{% set corrected_start = as_datetime(state.start).astimezone().isoformat() %}
{% set corrected_end = as_datetime(state.end).astimezone().isoformat() %}
{% set data.prices = data.prices + [{'start':corrected_start, 'end':corrected_end, 'value': ((state.price/1000) * (100 + vat) + (purchase_costs+ electricity_tax)*100) | round(1)}] %}
{% endfor %}
{% endif %}
{{data.prices}}
{% else %}
[]
{% endif %}
type: custom:apexcharts-card
experimental:
color_threshold: true
graph_span: 36h
header:
title: Elektriciteitsprijs (cent/kWh)
show: true
show_states: true
colorize_states: false
span:
start: hour
offset: "-8h"
yaxis:
- id: €cent
apex_config:
tickAmount: 10
forceNiceScale: true
now:
show: true
label: Nu
series:
- entity: sensor.electricity_prices
yaxis_id: €cent
name: Bar
type: column
stroke_width: 0.1
show:
extremas: true
in_header: true
in_chart: true
legend_value: false
float_precision: 1
color_threshold:
- value: 0
color: "#8be9fd"
- value: 10
color: "#50fa7b"
- value: 15
color: "#8be978"
- value: 20
color: "#f8f872"
- value: 25
color: "#ffb86c"
- value: 30
color: "#ff9859"
- value: 35
color: "#ff7846"
- value: 40
color: "#ff5555"
- value: 50
color: "#ff0000"
data_generator: |
return entity.attributes.average.map((record, index) => {
return [record.start, record.value];
});
- entity: sensor.electricity_prices
yaxis_id: €cent
name: line
curve: stepline
stroke_width: 0.5
show:
extremas: false
in_header: false
legend_value: false
data_generator: |
return entity.attributes.average.map((record, index) => {
return [record.start, record.value];
});
xztraz
(Xztraz)
December 13, 2025, 8:48am
65
looks allright with my code.
I have a question about AIO. I thought it would highlight the 8 cheapest hours by the config made by @xztraz But as you can see in the pictures there’s highlighted on some low hours, but not the lowest. Is this right, or have I accidentally changed something? Also thanks to @xztraz for making this super easy to set up.
xztraz
(Xztraz)
January 13, 2026, 7:41am
67
it looks for the cheapest hours between
first_hour: 19
last_hour: 18
it will look better when next days data shows up.
xztraz
(Xztraz)
January 13, 2026, 7:52am
68
Here is a bit of extended code for aio energy management with cheap and expensive hours. There are some input helpers to be able to fine tune values that need to be created for this to work.
i found the expensive setting to be usefull if you don’t want to turn something off if the price is low enought the whole day.
aio_energy_management:
cheapest_hours:
- nordpool_official_config_entry: 01K6AEXZV4HDRNYVJQEJB2R5GT
unique_id: my_cheapest_hours
name: My Cheapest Hours
mtu: 15
first_hour: 19
last_hour: 18
price_limit: input_number.electricity_cheap_price_calc
starting_today: true
number_of_hours: input_number.cheap_hours_setting
sequential: false
failsafe_starting_hour: 21
calendar: false
- nordpool_official_config_entry: 01K6AEXZV4HDRNYVJQEJB2R5GT
unique_id: my_expensive_hours
name: My Expensive Hours
mtu: 15
first_hour: 24
last_hour: 23
inversed: true
price_limit: input_number.expensive_price_calc
starting_today: true
number_of_hours: input_number.expensive_hours_setting
sequential: false
calendar: false
And graphs for that (and alot of extra stuff)
type: custom:apexcharts-card
experimental:
color_threshold: true
apex_config:
responsive:
- breakpoint: 500
options:
chart:
height: 300px
- breakpoint: 1200
options:
chart:
height: 640px
- breakpoint: 3000
options:
chart:
height: 800px
legend:
show: false
title:
floating: false
align: center
style:
fontSize: 20px
fontWeight: bold
xaxis:
labels:
datetimeFormatter:
hour: HH
plotOptions:
bar:
columnWidth: 80%
barGap: 3
graph_span: 2d
show:
last_updated: true
header:
title: Energy Price
show: true
show_states: true
colorize_states: true
span:
start: day
now:
show: true
label: Now
series:
- entity: binary_sensor.my_cheapest_hours
name: Cheapest
type: area
curve: stepline
yaxis_id: CHEAP
opacity: 0.6
stroke_width: 0
color: "#008"
show:
extremas: false
in_header: false
data_generator: |
let data = [];
let periods = entity.attributes.list || [];
periods.forEach((p) => {
let s = new Date(p.start).getTime();
let e = new Date(p.end).getTime();
data.push([s, 1]); // jump up at start
data.push([e, 1]); // stay high until end
data.push([e, 0]); // drop straight down
});
return data;
- entity: binary_sensor.my_cheapest_hours
yaxis_id: CHEAP
name: Cheap Chart
transform: "return x === 'on' ? 1 : 0;"
curve: stepline
type: area
opacity: 0.2
stroke_width: 2
extend_to: false
group_by:
func: avg
duration: 15m
color: "#00f"
show:
extremas: false
in_header: false
- entity: binary_sensor.my_expensive_hours
name: Expensive
type: area
curve: stepline
yaxis_id: CHEAP
opacity: 0.6
stroke_width: 0
color: "#800"
show:
extremas: false
in_header: false
data_generator: |
let data = [];
let periods = entity.attributes.list || [];
periods.forEach((p) => {
let s = new Date(p.start).getTime();
let e = new Date(p.end).getTime();
data.push([s, 1]); // jump up at start
data.push([e, 1]); // stay high until end
data.push([e, 0]); // drop straight down
});
return data;
- entity: binary_sensor.my_expensive_hours
yaxis_id: CHEAP
name: Expensive Chart
transform: "return x === 'on' ? 1 : 0;"
curve: stepline
type: area
opacity: 0.2
stroke_width: 2
extend_to: false
group_by:
func: avg
duration: 15m
color: "#f00"
show:
extremas: false
in_header: false
- entity: sensor.electricity_prices_today
yaxis_id: SEK
type: column
show:
extremas: true
in_header: false
float_precision: 2
color: green
color_threshold:
- value: 0
color: "#00ffaa"
- value: 0.25
color: "#00ff55"
- value: 0.5
color: "#00ff00"
- value: 0.75
color: "#55ff00"
- value: 1
color: "#aaff00"
- value: 1.5
color: "#ffff00"
- value: 2
color: "#ffaa00"
- value: 2.5
color: "#ff5500"
- value: 3
color: "#ff0000"
- value: 4
color: "#ff0055"
- value: 5
color: "#ff00aa"
- value: 6
color: "#ff00ff"
- value: 7
color: "#ff34ff"
- value: 9
color: "#ff65ff"
- value: 11
color: "#ff98ff"
- value: 13
color: "#ffccff"
- value: 15
color: "#ffffff"
data_generator: |
return entity.attributes.data.map((start, index) => {
return [new Date(start["start"]).getTime() + 450000, entity.attributes.data[index]["value"]];
});
- entity: sensor.electricity_prices_tomorrow
yaxis_id: SEK
type: column
show:
extremas: true
in_header: false
float_precision: 2
color: green
color_threshold:
- value: 0
color: "#00ffaa"
- value: 0.25
color: "#00ff55"
- value: 0.5
color: "#00ff00"
- value: 0.75
color: "#55ff00"
- value: 1
color: "#aaff00"
- value: 1.5
color: "#ffff00"
- value: 2
color: "#ffaa00"
- value: 2.5
color: "#ff5500"
- value: 3
color: "#ff0000"
- value: 4
color: "#ff0055"
- value: 5
color: "#ff00aa"
- value: 6
color: "#ff00ff"
- value: 7
color: "#ff34ff"
- value: 9
color: "#ff65ff"
- value: 11
color: "#ff98ff"
- value: 13
color: "#ffccff"
- value: 15
color: "#ffffff"
data_generator: |
return entity.attributes.data.map((start, index) => {
return [new Date(start["start"]).getTime() + 450000, entity.attributes.data[index]["value"]];
});
- entity: sensor.electricity_prices_today
name: Current Price
yaxis_id: SEK
float_precision: 2
show:
in_header: true
in_chart: false
unit: Kr/kWh
color: orange
- entity: sensor.total_power
yaxis_id: kW
name: Power Usage Chart
color: white
opacity: 0.8
float_precision: 2
show:
extremas: false
in_header: true
type: line
curve: stepline
stroke_width: 2
extend_to: false
unit: kW
transform: return x /1000;
group_by:
func: avg
duration: 15m
- entity: sensor.total_real_time_energy_cost
name: Cost Now Chart
yaxis_id: SEK
float_precision: 2
show:
extremas: false
in_header: true
unit: Kr/h
type: line
curve: stepline
stroke_width: 3
color: purple
opacity: 0.8
extend_to: false
group_by:
func: avg
duration: 15min
- entity: sensor.electricity_prices_today
attribute: min
name: Min Today
yaxis_id: SEK
float_precision: 2
show:
in_header: true
in_chart: false
unit: Kr/kWh
color: green
- entity: sensor.electricity_prices_today
attribute: mean
name: Average Today
yaxis_id: SEK
float_precision: 2
show:
in_header: true
in_chart: false
unit: Kr/kWh
color: yellow
- entity: sensor.electricity_prices_today
attribute: max
name: Max Today
yaxis_id: SEK
float_precision: 2
show:
in_header: true
in_chart: false
unit: Kr/kWh
color: red
- entity: sensor.electricity_prices_tomorrow
attribute: min
name: Min Tomorrow
yaxis_id: SEK
float_precision: 2
show:
in_header: true
in_chart: false
unit: Kr/kWh
color: darkgreen
- entity: sensor.electricity_prices_tomorrow
attribute: mean
name: Average Tomorrow
yaxis_id: SEK
float_precision: 2
show:
in_header: true
in_chart: false
unit: Kr/kWh
color: brown
- entity: sensor.electricity_prices_tomorrow
attribute: max
name: Max Tomorrow
yaxis_id: SEK
float_precision: 2
show:
in_header: true
in_chart: false
unit: Kr/kWh
color: darkred
- entity: binary_sensor.my_cheapest_hours
yaxis_id: CHEAP
name: Cheap Now
transform: "return x === 'on' ? 1 : 0;"
color: "#00f"
show:
in_header: true
in_chart: false
- entity: binary_sensor.my_expensive_hours
yaxis_id: CHEAP
name: Expensive Now
transform: "return x === 'on' ? 1 : 0;"
color: "#f00"
show:
in_header: true
in_chart: false
yaxis:
- id: SEK
min: 0
max: ~12
apex_config:
tickAmount: 6
forceNiceScale: true
title:
text: SEK
- id: kW
min: 0
max: ~6
decimals: 0
apex_config:
tickAmount: 6
forceNiceScale: true
opposite: true
title:
text: kW
- id: CHEAP
min: 0
max: 1
show: false
apex_config:
tickAmount: 6
forceNiceScale: true
1 Like