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 (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. While the installation is outside the scope of this post, 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.
If you use a different charger, check the EVCC charger documentation: https://docs.evcc.io/en/docs/devices/chargers
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.
- evcc may supplement with grid power if needed to reach the minimum charging level.
Vehicle Detection: Automatic
Vehicle information is only updated while charging; 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 GW2000-NS inverter does not integrate directly with evcc. However, since it was already integrated into Home Assistant, I simply pointed evcc to the Home Assistant pv_power sensor.
If you use 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).
This data is essential for load management and ensures the household stays within the 3×25A 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 & Feed-in Forecasts:To know when it’s cheaper to charge than to sell.Solar Forecast:Usingforecast-solarto predict how much “free” energy is coming tomorrow.
With this data, evcc doesn’t just react; it plans. It knows if it should 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 are 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 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:
- Your 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 sessions into those specific “cheapest” slots. It means that it can stop and start charging in between. If you prefer to charge a full bock, make sure to set it to continuous so it plans a full block rather than cheapest moments.
If you have multiple vehicles, configure a plan per vehicle.
Charging When Prices Are Low
In the evcc interface, you can configure a price limit that determines when the system should switch to aggressive charging. Whenever the electricity price falls below this threshold, evcc automatically charges at maximum speed. This feature is especially useful during periods of very low or even negative electricity prices, allowing you to take full advantage of favorable market conditions.
Conclusion
The results have been fantastic. The setup provides a high WAF (Wife Acceptance Factor): my wife just plugs in the car, and the system handles the complexity.
We’ve achieved maximum automation, optimized our costs under a dynamic contract, and made the most of our solar investment. If you’re into smart homes and energy management, evcc is the missing link.