I’ve been driving an electric car for over two years now and I absolutely love it. The driving experience is great, charging at home is convenient, and combining it with solar power makes it even better.
When I got my first EV, I immediately installed a home charger. I also have a dynamic energy contract, but I mostly charged at work or during the night when electricity prices were low.
Recently, we decided to replace our second ICE car with another EV. At the same time, changes in Dutch regulations, such as the introduction of ERE certificates and the expected phase-out of the Salderingsregeling, made me rethink our charging strategy. With two EVs, solar panels, and dynamic pricing, I wanted to optimize charging as much as possible.
Being an IT and automation enthusiast, this was the perfect weekend project. Enter evcc.
The Goal
My requirements were straightforward:
- Prioritize solar: Use maximum PV surplus for charging.
- Smart pricing: Factor in dynamic hourly energy rates.
- Reliability: Ensure both cars are ready for the morning commute.
- Safety: Prevent blowing the main fuse through load management.
Installation & Environment
evcc is incredibly flexible — it supports Docker, Home Assistant add-ons, and bare metal. I chose to run it in an LXC container on Proxmox for better resource management. The installation itself is outside the scope of this post, but the official documentation is excellent.
Once the service was up, the real fun began: the configuration.
Configuration
The Charger – Alfen Single Line Pro
To allow evcc to control my Alfen Single Line Pro, I enabled Modbus communication via the MyEve app:
Advanced→Smart Charging→Active Load Balancing: Set Protocol to Energy Management System.Advanced→Smart Charging→Energy Management: Set Mode to Socket and ValidityTime to 300s.
Using a different charger? Check the evcc charger documentation.
In the evcc GUI, I applied the following key settings:
Default Mode: Solar
I only want to charge using solar power by default. If I need a certain State of Charge (SOC) in the morning, the planner takes care of it.
Solar Mode: Custom (not Maximum)
My solar panels don’t always produce enough power for stable charging. Since single-phase charging requires about 1.4 kW to start, I configured:
- Enable grid power at: -750 W
- Disable grid power at: 750 W
This means charging starts when at least 750 W of solar surplus is available, and evcc may supplement with a small amount of grid power to maintain the minimum charging level.
Vehicle Detection: Automatic
Vehicle information is only updated while charging, so there’s no need to poll when the car is disconnected.
Circuit configuration is handled later under load management.
Vehicles
I have a Kia EV6 and a Hyundai Inster. Setting them up in the GUI is straightforward: just select the brand and model. I configured the actual battery capacities and enabled three-phase charging for both vehicles to ensure they can take full advantage of high-power charging windows.
Vehicle documentation: https://docs.evcc.io/en/docs/devices/vehicles
Solar Panels
My GoodWe inverter does not integrate directly with evcc. Since it was already integrated into Home Assistant, I simply pointed evcc to the Home Assistant pv_power sensor.
Using a different inverter? Check: https://docs.evcc.io/en/docs/devices/meters
Grid Meter
For accurate load balancing you need real-time grid data. I used DSMR-Reader and connected evcc directly to its API. This provides clean three-phase data (import/export and current per phase), which is essential for keeping the household within the 3x25A limit.
power:
source: calc
add:
- source: http
uri: http://<>:7777/api/v2/consumption/electricity-live
method: GET # default HTTP method
headers:
- content-type: application/json
- X-AUTHKEY: YOUR_KEY
insecure: true # set to true to trust self-signed certificates
jq: .|{currently_delivered}| join(" ")
scale: 1
timeout: 10s
- source: http
uri: http://<>:7777/api/v2/consumption/electricity-live
method: GET # default HTTP method
headers:
- content-type: application/json
- X-AUTHKEY: YOUR_KEY
insecure: true # set to true to trust self-signed certificates
jq: .|{currently_returned}| join(" ")
scale: -1
timeout: 10s
energy:
source: calc
add:
- source: http
uri: http://<>:7777/api/v2/consumption/today
method: GET # default HTTP method
headers:
- content-type: application/json
- X-AUTHKEY: YOUR_KEY
insecure: true # set to true to trust self-signed certificates
jq: .|{electricity_merged}| join(" ")
scale: 1
timeout: 10s
- source: http
uri: http://<>:7777/api/v2/consumption/today
method: GET # default HTTP method
headers:
- content-type: application/json
- X-AUTHKEY: YOUR_KEY
insecure: true # set to true to trust self-signed certificates
jq: .|{electricity_returned_merged}| join(" ")
scale: -1
timeout: 10s
currents:
- source: http
uri: http://<>:7777/api/v2/datalogger/dsmrreading?limit=1&ordering=-timestamp
method: GET # default HTTP method
headers:
- content-type: application/json
- X-AUTHKEY: YOUR_KEY
insecure: true # set to true to trust self-signed certificates
jq: .results[]|{phase_power_current_l1}| join(" ")
scale: 1
timeout: 10s
- source: http
uri: http://<>:7777/api/v2/datalogger/dsmrreading?limit=1&ordering=-timestamp
method: GET # default HTTP method
headers:
- content-type: application/json
- X-AUTHKEY: YOUR_KEY
insecure: true # set to true to trust self-signed certificates
jq: .results[]|{phase_power_current_l2}| join(" ")
scale: 1
timeout: 10s
- source: http
uri: http://<>:7777/api/v2/datalogger/dsmrreading?limit=1&ordering=-timestamp
method: GET # default HTTP method
headers:
- content-type: application/json
- X-AUTHKEY: YOUR_KEY
insecure: true # set to true to trust self-signed certificates
jq: .results[]|{phase_power_current_l3}| join(" ")
scale: 1
timeout: 10s
Tariffs (Dynamic Pricing + Forecasting)
This is where evcc outshines standard smart chargers. By using the epexprijzen.nl API, evcc knows the hourly prices for the next 24 hours. I configured the following:
- Grid price and feed-in forecasts: To know when it’s cheaper to charge than to sell back to the grid.
- Solar forecast: Using
forecast-solarto predict how much free energy is coming tomorrow.
With this data, evcc doesn’t just react, it plans. It knows whether to wait for a sunny afternoon or a cheap 3:00 AM window.
currency: EUR
grid:
type: custom
forecast:
source: http
uri: https://epexprijzen.nl/api/v1/prices/zonneplan/hourly
jq: '.today + .tomorrow | map({"start": (.t | strptime("%Y-%m-%dT%H:%M:%S%z") | strftime("%Y-%m-%dT%H:%M:%SZ")), "end": (.t | strptime("%Y-%m-%dT%H:%M:%S%z") | mktime + 3600 | strftime("%Y-%m-%dT%H:%M:%SZ")), "value": .price}) | tostring'
feedin:
type: custom
forecast:
source: http
uri: https://epexprijzen.nl/api/v1/prices/zonneplan/hourly
jq: '.today + .tomorrow | map({"start": (.t | strptime("%Y-%m-%dT%H:%M:%S%z") | strftime("%Y-%m-%dT%H:%M:%SZ")), "end": (.t | strptime("%Y-%m-%dT%H:%M:%S%z") | mktime + 3600 | strftime("%Y-%m-%dT%H:%M:%SZ")), "value": .price}) | tostring'
co2:
type: template
template: ned
apiKey: YOUR_API_KEY
solar:
type: template
template: forecast-solar
lat: YOUR_LAT
lon: YOUR_LONG
az: 184
dec: 25
kwp: 2.16Tariff documentation: https://docs.evcc.io/en/docs/tariffs
Load Management
In the Netherlands, a standard residential connection is 3x25A. If you’re charging an EV at 11 kW while the heat pump and oven are running, you might blow the main fuse. evcc handles this through a Circuit configuration. I defined my main circuit with a maxCurrent: 25.
- name: main
title: Hoofdcircuit
maxCurrent: 25
meter: db:8If the house consumption spikes, evcc throttles the chargers within seconds. This active load balancing is the only practical way to safely run a multi-EV household on a standard Dutch grid connection.
Charging Plan
This is where the “Smart” in Smart Charging actually happens. While the default mode is Solar, I have hard requirements for the next morning. I created a repeating plan for 100% State of Charge (SOC) by 06:30 AM. evcc’s algorithm then looks at:
- Required energy: How many kWh are needed to reach the target?
- Solar forecast: Is there a burst of sun expected before the deadline?
- Dynamic prices: When are the cheapest hours (or negative price windows) between now and 06:30 AM?
It then schedules charging into those specific cheapest slots, which means it can stop and start in between. If you’d prefer one uninterrupted block, set it to continuous and evcc will plan a full charge window rather than spreading across the cheapest moments. If you have multiple vehicles, configure a separate plan per vehicle.
Charging When Prices Are Low
In the evcc interface you can set a price limit that triggers aggressive charging. Whenever the electricity price drops below this threshold, evcc charges at maximum speed. This is especially useful during periods of very low or negative electricity prices.
Conclusion
The results have been fantastic. The setup has a high WAF (Wife Acceptance Factor): my wife just plugs in the car, and the system handles the rest.
We’ve maximized our solar investment, kept costs low under a dynamic contract, and have two cars ready every morning without thinking about it. If you’re into smart homes and energy management, evcc is the missing piece.