Blog/Web engineering
Charging on EPEX Austria prices: what my Home Assistant app saves
A year of hourly EPEX prices for Austria, replayed for a Tesla and a water boiler: cheapest-hour charging costs 6.5 instead of 18.9 ct/kWh, close to €590 a year, without blowing a 20 A fuse.
Balázs Csorba··9 min read
- Home Assistant
- EPEX Spot
- Energy prices
- Tesla
- Energy management

Key takeaways
- EPEX Austria, Oct 2025 to Sep 2026: 14.3 ct/kWh average incl. VAT, 15.9 ct between a day's cheapest and dearest hour, 253 negative hours.
- Charging a car that needs 2,500 kWh a year in the cheapest hours costs 6.5 instead of 18.9 ct/kWh, about €311 a year.
- A 6 kWh/day boiler saves about €278 a year against evening heating and €191 against a night slot.
- The midday solar dip is where most of the saving is; charging only overnight saves €145.
- A balcony battery saves about 8 ct per kWh it moves from a cheap hour into the evening.
- Putting every load in the same cheap hour needs a per-phase guard; the app keeps each phase under 20 A.
I buy electricity on a spot tariff, so every hour costs what the EPEX day-ahead auction for Austria says. Over the last twelve months the same kilowatt-hour cost anything from −59.6 to 71.1 ct (spot price plus VAT). On an average day the cheapest and the most expensive hour were 15.9 ct apart. That gap is the whole business case: if the big loads can wait for the cheap hours, the bill shrinks without using a single kilowatt-hour less.
My house has three loads that can wait: a Tesla, an electric water boiler and a balcony battery (an EET SolMate 3 that I extended to about 16 kWh). So I built a Home Assistant app that moves them into the cheapest hours, and keeps every phase of the 20 A connection under its limit while doing it. This post is about what that is worth, measured on a full year of EPEX Austria prices, and how the app gets there.
A year of EPEX Austria prices
I pulled every hourly day-ahead price for Austria from 29 September 2025 to 28 September 2026, 8,760 hours in total. The yearly average was 14.3 ct/kWh including VAT. The table shows how the day is shaped month by month: the average, the mean of each day's three cheapest hours, the evening peak from 18:00 to 21:00 and the average gap between the cheapest and the most expensive hour of a day.
| Month | Daily average | Cheapest 3 h | Evening 18–21 | Daily spread |
|---|---|---|---|---|
| Oct 2025 | 13.1 | 8.4 | 18.2 | 13.3 |
| Nov 2025 | 13.9 | 10.0 | 16.2 | 9.5 |
| Dec 2025 | 13.7 | 10.9 | 15.3 | 6.6 |
| Jan 2026 | 17.0 | 12.1 | 19.6 | 11.0 |
| Feb 2026 | 13.1 | 9.8 | 15.6 | 7.4 |
| Mar 2026 | 13.6 | 4.3 | 20.2 | 18.4 |
| Apr 2026 | 10.4 | −0.3 | 16.4 | 19.3 |
| May 2026 | 12.0 | 0.7 | 19.0 | 21.9 |
| Jun 2026 | 12.8 | 3.8 | 19.7 | 22.4 |
| Jul 2026 | 14.1 | 5.1 | 19.7 | 17.4 |
| Aug 2026 | 17.8 | 8.8 | 25.3 | 18.5 |
| Sep 2026 | 20.9 | 10.2 | 30.9 | 24.7 |
Two patterns stand out. From March to September, solar power pushes midday prices down, often below zero: the year had 253 hours with a negative price (2.9 %), and the lowest, −59.6 ct, was at 13:00 on 1 May, a public holiday. In the evening, when everyone comes home and the sun is gone, prices climb, and in September the evening average was three times the cheapest hours. In winter the day is flatter, so there is less to gain, but even then the cheapest hours are a few cents below the evening.
What shifting the loads saves
To turn prices into euros I replayed the year hour by hour for two loads. The car needs 2,500 kWh a year from the grid (about 15,000 km), 6.8 kWh a day on average, and charges at 12.4 kWh per hour at 20 A on three phases. The boiler needs 6 kWh a day at 2 kW. Each gets the same energy every day; only the hours change.
| Load | When it runs | ct/kWh | Per year |
|---|---|---|---|
| Car, 2,500 kWh/yr | at once when plugged in at 18:00 | 18.9 | €472 |
| Car | cheapest hours 18:00–07:00 | 13.1 | €327 |
| Car | cheapest hours of the day | 6.5 | €161 |
| Boiler, 6 kWh/day | heats from 18:00 | 19.7 | €431 |
| Boiler | classic night slot from 22:00 | 15.7 | €344 |
| Boiler | cheapest hours of the day | 7.0 | €153 |
Charging the car in the cheapest hours instead of right after work cuts its energy cost from 18.9 to 6.5 ct/kWh, about €311 a year. The boiler saves about €278 a year against heating in the evening, and still €191 against a classic night slot. Together that is close to €590 a year on the energy part of the bill alone.
The biggest gains come from the midday dip, so they depend on the car being at home and plugged in when the sun is up. If it only charges overnight, the saving drops to €145 a year, because the night is cheaper than the evening but rarely as cheap as a sunny noon. That is why the plan looks at today and tomorrow together instead of forcing a full battery by the morning.
For the balcony battery the question is different: it moves energy from a cheap hour to an expensive one. Charged in the day's cheapest hours it paid 8.2 ct/kWh on average, while the evening from 17:00 to 23:00 averaged 18.5 ct. After a 90 % round trip, every kilowatt-hour it shifts saves about 8 ct, as long as the house actually uses that energy in the evening.
A SolMate on its own stores far too little to move a whole evening. So I wired an extra pack directly in parallel to its internal battery: 16 LiFePO4 cells of 314 Ah, about 16 kWh, managed by a JK BMS V19 with an active balancer. The SolMate doesn't know the pack is there, so the app is configured with the real capacity when it works out how many cheap hours a full charge takes at 2.5 kW. This is a DIY change the manufacturer doesn't support; I did it at my own risk.
How the app picks the hours
Every day around 13:00 the next day's prices are published. The plan starts from the energy the car needs, the gap between its battery level and its charge limit, and sorts all of today's remaining hours plus all of tomorrow's by price. It takes the cheapest until the energy is covered. There is no deadline: if tomorrow's noon is cheaper, the car waits. An optional price ceiling removes the hours above it, and an unplugged car gets no hours today, so a car in the street doesn't block the boiler for nothing.
needed_kwh = max(0.0, (target_pct - soc_pct) / 100.0 * battery_kwh)
per_hour_kwh = max_amps * voltage * 3.0 / 1000.0 * EFFICIENCY # 20 A → ~12.4 kWh
candidates = []
if needed_kwh > NEEDED_MIN_KWH:
if plugged_in: # an unplugged car gets no hours today
candidates += priced_hours(prices_today, range(now_hour, 24), "today")
candidates += priced_hours(prices_tomorrow, range(0, 24), "tomorrow")
candidates.sort(key=lambda c: c[1]) # cheapest first
if max_price_ct is not None:
candidates = [c for c in candidates if c[1] <= max_price_ct]
# take cheapest hours until the energy is coveredThe boiler follows its own daily window of cheap hours, and the balcony battery charges from the grid in the cheapest hours at or below its own ceiling (25 ct by default), planned from its live battery level at 2.5 kW. While the car or the boiler run on cheap power, the battery is not asked to discharge; it keeps its energy for the expensive evening.
Cheap hours without blowing the fuse
The catch with cheap hours is that every load wants the same ones. The car at 20 A, the boiler and the battery together are more than a 20 A phase can carry. So the app measures instead of guessing: the house meter sees everything, the wallbox included, and because the car loads all three phases equally, what the quietest phase carries above its house baseline is the car. Tesla's own cloud data lags by minutes, up to an hour while the car sleeps, so it is only a fallback.
An amp guard sets the largest charge current that keeps every phase under 20 A. The car has priority in its plan hours: the boiler doesn't start next to it, and if a phase still goes over, loads are dropped one at a time, 30 seconds apart.
| Order | Load | What happens |
|---|---|---|
| 1 | Boiler | switched off, back after 5 min once there is room |
| 2 | Balcony battery | charging turned down, then off until midnight |
| 3 | Car | current stepped down, stopped below 6 A |
Seeing the prices
- Prices and plan. Today's and tomorrow's prices as bars from green to red, with a car or boiler icon above every planned hour.
- Price ceilings. One for the car and one for the battery; hours above them are never used.
- Solar what-if. What a PV system with a battery would have earned on this house, from the meter's real hourly history, the recorded prices and historical irradiance from Open-Meteo.
The app is a Vue 3 dashboard on top of plain Python logic, deployed to Home Assistant with a single script. Most of it was written together with a coding agent, in the way I describe in my coding agent workflow.
What I learned
- The daily spread is the money. With about 16 ct between the cheapest and the dearest hour on an average day, a flexible load earns more than any tariff comparison.
- Midday beats the night. From spring to autumn the cheapest hours are at noon, so plugging the car in during the day matters more than a night timer.
- Cheap hours need a fuse guard. Moving every load into the same hour only works if something measures the phases and sets priorities.
- Measure, don't ask. A local meter beats any cloud API for decisions that protect a fuse.
Sources
Frequently asked questions
How much can you save by charging an EV on EPEX spot prices in Austria?
On the prices from October 2025 to September 2026, a car that needs 2,500 kWh a year paid 6.5 ct/kWh (spot plus VAT) in the day's cheapest hours, against 18.9 ct when charging right after being plugged in at 18:00. That is about €311 a year on the energy component; grid fees and levies are the same either way.
When are electricity prices cheapest in Austria?
From spring to autumn usually around midday, when solar power floods the market; in 2025-26 there were 253 hours with a negative price. In winter the cheapest hours are mostly at night, and the evening from 18:00 is the most expensive time all year.
Is a night timer enough to get cheap power?
It helps, but not much. Overnight charging paid 13.1 ct/kWh on average, against 6.5 ct in the cheapest hours of the whole day. Planning with today's and tomorrow's published prices catches the midday dips a fixed timer misses.