
EVCC-Grundgerüst: Das Setup, bevor irgendein Assistent mitredet
EVCC-Grundgerüst: Das Setup, bevor irgendein Assistent mitredet
Über die alte go-e-Wallbox und ihre Wiederbelebung hab ich ja schon ausführlicher geschrieben. Was in der Geschichte damals eher am Rand vorkam, war das eigentliche Fundament darunter: EVCC selbst, und wie die Config aussieht, die aus einem Wechselrichter, einem Zähler und einem Auto ein funktionierendes Ladesystem macht. Genau das ist der Ausgangspunkt für diese neue Serie - und die Serie hat einen zweiten Zweck: Sie dokumentiert nicht nur, was konfiguriert wurde, sondern wie - erst ganz klassisch von Hand, später mit einem KI-Assistenten im Boot. Aber eins nach dem anderen.
Was EVCC überhaupt macht
EVCC ist eine Open-Source-„Solar-Ladesteuerung“. Es sitzt zwischen Wechselrichter, Netzzähler, Wallbox und optional dem Auto selbst, und entscheidet in Echtzeit, wie viel Strom gerade ans Auto geht - abgestimmt auf den tatsächlichen PV-Überschuss statt einfach stur Netzstrom zu ziehen, sobald ein Kabel steckt. Technisch: ein einzelnes Go-Binary bzw. Docker-Image, eine YAML-Config, ein schlankes Web-UI für den Alltag.
Dieser Post beschreibt den Stand, wie er existierte, bevor irgendein KI-Assistent überhaupt involviert war - die reine, von Hand konfigurierte Basis, auf der die späteren Teile aufbauen.
Wo es läuft
EVCC läuft als einzelner Docker-Container auf dem Homelab-Server, der ohnehin schon eine Handvoll anderer selbstgehosteter Dienste trägt:
# docker-compose.yml (Struktur, nicht die echte Datei)
services:
evcc:
image: evcc/evcc:0.312.1
volumes:
- ./evcc.yaml:/etc/evcc.yaml:ro # read-only Bind-Mount
- ./data:/data # beschreibbar: SQLite-DB, Cache
ports:
- "7070:7070"
restart: unless-stopped
Zwei Details, die später in der Serie wieder auftauchen:
- Die Config-Datei ist read-only gemountet. EVCC kann seine eigene Config von innen nicht umschreiben - jede Änderung heißt: Datei auf dem Host bearbeiten, Container neu starten. Das ist eine bewusste Design-Entscheidung, keine Einschränkung von EVCC selbst.
- Die SQLite-Datenbank liegt in einem eigenen, beschreibbaren Volume, nicht am Standardpfad im Container - sonst würde sie im Home-Verzeichnis des Containers landen und bei jedem Rebuild verschwinden.
Erreichbar ist die Instanz intern über <EVCC_HOSTNAME>:7070.
Die Config, Stück für Stück
Netzwerk und Basics
network:
schema: http
host: <EVCC_HOSTNAME>
port: 7070
interval: 30s # wie oft Zähler/Wallbox abgefragt und neu bewertet werden
database:
type: sqlite
dsn: /data/evcc.db
log: info
Sponsorship
sponsortoken: <SPONSOR_TOKEN>
EVCC ist frei und offen, aber manche Gerätetreiber - in diesem Fall der go-e-Treiber - setzen einen aktiven Sponsor-Token voraus. Das GitHub-Sponsoring des Projekts liefert einen: ein langlebiges JWT, das direkt in die Config wandert.
Zähler - Netz und PV, über Modbus/SunSpec
Der Wechselrichter ist ein Fronius Verto Plus 15 kW. EVCC spricht ihn über Modbus TCP nach SunSpec-Standard an - ein herstellerübergreifendes Protokoll, das die meisten ernsthaften Solar-Wechselrichter unterstützen, statt einer proprietären Hersteller-API:
meters:
- name: netz
type: template
template: fronius-vertoplus
usage: grid
host: <INVERTER_IP>
port: 502
id: 200 # Modbus-Geräte-ID für die Netzzähler-Funktion
- name: pv_dach
type: template
template: fronius-vertoplus
usage: pv
host: <INVERTER_IP>
port: 502
maxacpower: 15000
Beide Einträge zeigen auf dasselbe physische Gerät und dieselbe TCP-Verbindung - der Verto Plus stellt mehrere logische SunSpec-„Modelle“ über eine einzige Modbus-Verbindung bereit, und usage: grid vs. usage: pv wählt einfach aus, welches Modell EVCC ausliest. Die Netzzähler-Funktion nutzt eine eigene Modbus-ID (200), die PV-Funktion (Wechselrichter selbst) die Standard-ID (1, hier implizit). Diese Trennung - eine physische Verbindung, mehrere logische Ansichten über usage: und teils über die Geräte-ID - wird später in der Serie noch wichtig, sobald ein Speicher dazukommt.

Wallbox
chargers:
- name: goe_carport
type: go-e
uri: http://<CHARGER_IP>
Die go-e-Wallbox (Hardware V2, „CM-02“) wird über ihre lokale HTTP-API gesteuert - kein Cloud-Umweg für die Ladesteuerung nötig.

Fahrzeug - nur Lesezugriff auf den Akkustand via Tesla Fleet API
vehicles:
- name: tesla_model3
type: template
template: tesla
title: <VEHICLE_TITLE>
clientId: <TESLA_CLIENT_ID>
accessToken: <TESLA_ACCESS_TOKEN>
refreshToken: <TESLA_REFRESH_TOKEN>
vin: <VEHICLE_VIN>
capacity: 79
cache: 15m
Dieser Eintrag ist bewusst schmal gehalten: Er liest ausschließlich den Akkustand des Autos über die Tesla Fleet API - schickt aber keine Start/Stop- oder Stromlimit-Befehle ans Auto. Die eigentliche Ladesteuerung läuft komplett über die go-e-Box oben. Zwei Gründe dafür:
- Die go-e-Wallbox erledigt die Ladesteuerung auf Hardware-Ebene bereits zuverlässig und lokal - ein Umweg über Teslas Cloud-API bringt hier nichts.
- Teslas Fleet API verlangt eine eigene, registrierte Developer-App mit genehmigter OAuth-Redirect/Origin. Eine generische Drittanbieter-App passt da nicht rein, also wurde eine eigene App extra dafür registriert - deren Client-ID steht oben unter
clientId.

Site und Loadpoint
site:
title: <SITE_NAME>
meters:
grid: netz
pv:
- pv_dach
loadpoints:
- title: Carport
charger: goe_carport
vehicle: tesla_model3
mode: "pv"
Ein Loadpoint („Carport“), eine Wallbox, ein Fahrzeug, im PV-Überschussmodus - geladen wird mit überschüssigem Solarstrom statt nach festem Zeitplan, dreiphasig mit rund 6-16 A, je nachdem wie viel die Sonne gerade hergibt.

Stand am Ende dieses Posts
- EVCC läuft, fragt Netz und PV alle 30 Sekunden über SunSpec/Modbus ab.
- Eine Wallbox, lokal per HTTP gesteuert.
- Ein Fahrzeug, nur Akkustand, über eine eigens registrierte Tesla-Fleet-API-App.
- Ein Loadpoint, der PV-Überschuss lädt.
- Noch kein Speicher - der kommt erst später in der Serie dazu, und zwar auf einem ganz anderen Weg als alles hier oben.
Im nächsten Teil geht’s darum, wie diese Bausteine tatsächlich entstanden sind - ganz klassisch, mit Texteditor und docker restart, bevor überhaupt ein Assistent im Spiel war.