This component adds electricity prices from stock exchange EPEX Spot to Home Assistant. EPEX Spot does not provide free access to the data, so this component uses different ways to retrieve the data.
You can choose between multiple sources:
-
Awattar
Awattar provides a free of charge service for their customers. Market price data is available for Germany and Austria. So far no user identifiation is required.
-
EPEX Spot Web Scraper
This source uses web scraping technologies to retrieve publicly available data from its website.
If you like this component, please give it a star on github.
-
Ensure that HACS is installed.
-
Install EPEX Spot integration via HACS:
-
Add EPEX Spot integration to Home Assistant:
In case you would like to install manually:
-
Copy the folder
custom_components/epex_spot
tocustom_components
in your Home Assistantconfig
folder. -
Add EPEX Spot integration to Home Assistant:
This integration provides the following sensors:
- Current market price
- Average market price during the day
- Lowest market price during the day
- Highest market price during the day
- Current market price quantile during the day
- Rank of the current market price during the day
The EPEX Spot Web Scraper provides some additional sensors:
- Buy Volume
- Sell Volume
- Volume
The sensor value reports the current market price which will be updated every hour.
The sensor attributes contains a list of all available market prices (today and tomorrow if available):
data:
- start_time: '2022-12-15T23:00:00+00:00'
end_time: '2022-12-16T00:00:00+00:00'
price_eur_per_mwh: 296.3
- start_time: '2022-12-16T00:00:00+00:00'
end_time: '2022-12-16T01:00:00+00:00'
price_eur_per_mwh: 288.12
- start_time: '2022-12-16T01:00:00+00:00'
end_time: '2022-12-16T02:00:00+00:00'
price_eur_per_mwh: 280.19
The sensor value reports the average market price during the day.
The sensor value reports the lowest market price during the day.
The sensor attributes contains the start and endtime of the lowest market price timeframe.
start_time: '2023-02-15T22:00:00+00:00'
end_time: '2023-02-15T23:00:00+00:00'
The sensor value reports the highest market price during the day.
The sensor attributes contains the start and endtime of the highest market price timeframe.
start_time: '2023-02-15T22:00:00+00:00'
end_time: '2023-02-15T23:00:00+00:00'
The sensor value reports the quantile between the lowest market price and the highest market price during the day in the range between 0 .. 1.
Examples:
- The sensor reports 0 if the current market price is the lowest during the day.
- The sensor reports 1 if the current market price is the highest during the day.
- If the sensor reports e.g., 0.25, then the current market price is 25% of the range between the lowest and the highest market price.
The sensor value reports the rank of the current market price during the day. Or in other words: The number of hours in which the price is lower than the current price.
Examples:
- The sensor reports 0 if the current market price is the lowest during the day. There is no lower market price during the day.
- The sensor reports 23 if the current market price is the highest during the day (if the market price will be updated hourly). There are 23 hours which are cheaper than the current hour market price.
- The sensor reports 1 if the current market price is the 2nd cheapest during the day. There is 1 one which is cheaper than the current hour market price.
Add a template sensor like this:
template:
- sensor:
- name: epex_spot_price_ct_per_kWh
unit_of_measurement: "ct/kWh"
availability: '{{ states("sensor.epex_spot_de_price") != "unavailable" }}'
state: '{{ states("sensor.epex_spot_de_price") | float / 10 }}'
Don't forget to replace de
epex_spot_de_price if necessary!
With ApexCharts, you can easily show a chart like this:
You just have to install ApexCharts (via HACS) and enter the following data in the card configuration:
type: custom:apexcharts-card
header:
show: true
title: Electricity Prices
graph_span: 48h
span:
start: day
now:
show: true
label: Now
series:
- entity: sensor.epex_spot_de_price
name: Electricity Price
type: column
extend_to: end
data_generator: >
return entity.attributes.data.map((entry, index) => { return [new
Date(entry.start_time).getTime(), entry.price_eur_per_mwh]; });
It might be an interesting use case to know what the hours with lowest consecutive prices during the day are. This might be of value when looking for the most optimum time to start your washing machine, dishwasher, dryer, etc.
The template below determines when the 3 hours with lowest consecutive prices start, between 06:00 and 22:00.
You can change these hours in the template below, if you want hours before 06:00 and after 22:00 also to be considered.
Remove {%- set ns.combo = ns.combo[6:22] %}
do disable this filtering completely.
template:
- sensor:
- name: start_low_period
state: >-
{% set ns = namespace(attr_dict=[]) %}
{% for item in (state_attr('sensor.epex_spot_be_price', 'data'))[0:24] %}
{%- set ns.attr_dict = ns.attr_dict + [(loop.index-1,item["price_eur_per_mwh"])] %}
{% endfor %}
{%- set price_map = dict(ns.attr_dict) %}
{%- set price_sort = price_map.values()|list %}
{%- set keys_list = price_map.keys()|list %}
{%- set ns = namespace(combo=[]) %}
{%- for p in keys_list %}
{%- set p = p|int %}
{%- if p < 22 %}
{%- set ns.combo = ns.combo + [(p, ((price_sort)[p] + (price_sort)[p+1] + (price_sort)[p+2])|round(2))] %}
{%- endif %}
{%- endfor %}
{%- set ns.combo = ns.combo[6:22] %}
{%- set mapper = dict(ns.combo) %}
{%- set key = mapper.keys()|list %}
{%- set val = mapper.values()|list %}
{%- set val_min = mapper.values()|min %}
{{ key[val.index(val_min)]|string + ":00" }}
Here's an other ApexCharts example.
It shows the price for the current day, the next day and the min/max
value for each day.
Furthermore, it also fills the hours during which prices are lowest (see 3.)
type: custom:apexcharts-card
header:
show: false
graph_span: 48h
span:
start: day
now:
show: true
label: Now
color_list:
- var(--primary-color)
series:
- entity: sensor.epex_spot_be_price
yaxis_id: uurprijs
float_precision: 2
type: line
curve: stepline
extend_to: false
show:
extremas: true
data_generator: >
return entity.attributes.data.map((entry, index) => { return [new
Date(entry.start_time).getTime(), entry.price_eur_per_mwh; }).slice(0,24);
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: red
- value: 0.5
color: magenta
- entity: sensor.epex_spot_be_price
yaxis_id: uurprijs
float_precision: 2
type: line
curve: stepline
extend_to: end
show:
extremas: true
data_generator: >
return entity.attributes.data.map((entry, index) => { return [new
Date(entry.start_time).getTime(), entry.price_eur_per_mwh]; }).slice(23,47);
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: red
- value: 0.5
color: magenta
- entity: sensor.epex_spot_be_price
yaxis_id: uurprijs
color: green
float_precision: 2
type: area
curve: stepline
extend_to: false
data_generator: >
return entity.attributes.data.map((entry, index) => { return [new
Date(entry.start_time).getTime(), entry.price_eur_per_mwh];}).slice(parseInt(hass.states['sensor.start_low_period'].state.substring(0,2)),parseInt(hass.states['sensor.start_low_period'].state.substring(0,2))+4);
experimental:
color_threshold: true
yaxis:
- id: uurprijs
min: 0.1
max: 0.5
decimals: 2
apex_config:
title:
text: €/MWh
tickAmount: 4
apex_config:
legend:
show: false
tooltip:
x:
show: true
format: HH:00 - HH:59