Code für Ladung und Abrechnung von E-Fahrzeugen

Begonnen von Prof. Dr. Peter Henning, 21 Oktober 2026, 10:00:06

Vorheriges Thema - Nächstes Thema

Prof. Dr. Peter Henning

Ich habe jetzt in meinem FHEM-System drei E-Fahrzeuge von zwei verschiedenen Herstellern. Für alle drei gilt: Sie werden meistens an ihrem Heimatstandort an einer von zwei Wallboxen geladen, ab und zu auch extern. Eine der Wallboxen hat einen festen Stromtarif und lädt zwei unterschiedliche Fahrzeuge, auch mit solarem Anteil. Die andere hat einen dynamischen Tibber-Tarif.

Für die drei Fahrzeuge logge ich nicht nur gefahrene Kilometer und Verbrauch (Monat, Jahr, Lifetime), sondern auch die Kosten.
Natürlich geht das insbesondere bei externen Ladungen nicht so einfach - wenn man unterwegs ist, eventuell bei verschiedenen Anbietern lädt.

Ich habe das so gelöst, dass ich zu beliebigen späteren Zeiten, also auch Tage nach einer externen Ladung, eine solche Ladung in meine Logs einfügen kann. Ein Perl-Befehl
{ BEV_chargeext('{"car":"ID7","date":"3.10.","cost":13.20,"energy":28.4}') }fügt diese Ladung rückwirkend in alle Logs ein, d.h. sie werden nachträglich ab dem 3. Oktober korrigiert.

Während eines lokalen Ladevorgangs werden die Kosten auch ermittelt und hinzugefügt.

Bevor ich Code dazu poste, würde ich gerne wissen, ob jemand an diesen Lösungen interessiert ist.

LG

pah

rabehd

Ich habe nur ein Auto und logge bisher nur Ladung zuhause (Menge gesamt und heute), sowie Batterielevel und Kilometerstand.
Fester Stromtarif mit Balkonsolaranlage.
Externe Ladungen wären schon interessant, Thema ist noch auf der Liste.
Auch funktionierende Lösungen kann man hinterfragen.

Prof. Dr. Peter Henning

Gut, dann suchen wir doch erstmal eine Basis für das Logging.

Bei mir sieht das so aus, dass jeden Abend um 23:59:55 für jedes Fahrzeug ein Reading charge_athome gesetzt wird. Ein FileLog-Device achtet auf die entsprechenden Events und baut das Monatslog auf, z.B.
Zitat2026-10-02_23:59:55 Spring charge_athome: W-d 0.000 W-ds 0.0 W-m 0.000 W-ms 0.0 W-total 46.925 odo-d 11 odo-m 11 odo-total 382 soc 77
2026-10-03_23:59:55 Spring charge_athome: W-d 6.734 W-ds 0.0 W-m 6.734 W-ms 0.0 W-total 53.659 odo-d 0 odo-m 11 odo-total 382 soc 100
2026-10-04_23:59:55 Spring charge_athome: W-d 0.000 W-ds 0.0 W-m 6.734 W-ms 0.0 W-total 53.659 odo-d 173 odo-m 184 odo-total 555 soc 18
(ja, die Kiste gehört meiner Tochter und ist wirklich brandneu). Darin ist
  • W-d die am heutigen Tag erhaltene Ladung aus der eigenen Wallbox, W-ds der solare Anteil daran (Null, weil noch keine PV-Anlage);
  • W-m insgesamt in diesem Monat erhaltene Ladung aus der eigenen Wallbox, W-ms der solare Anteil daran;
  • W-total die über die Lebensdauer aus der Wallbox bezogene Ladung;
  • odo-d die am heutigen Tag zurückgelegte Kilometerzahl, odo-m die des gegenwärtigen Monats;
  • odo-total der Gesamtkilometerstand des Fahrzeugs.
  • soc der Ladezustand
Wenn ich mit dem unten beschriebenen Befehl eine externe Ladung für den gegenwärtigen Monat einlese, wird diese in einem Reading als Teil eines JSON-arrays abgelegt, z.B. für eine Ladung am 4.10.2026, 5.9 kWh für 3.28 €:
chargeext_month [["2026-10-04",3.28,5.9]]Dieses Array wird über den ganzen Monat hinweg gehalten, am Monatsende in ein Jahresreading überführt.

Damit ist das monatliche und jährliche Log immer wieder aus diesen Readings rekonstruierbar. Der Rekonstruktionsbefehl fügt in die Logdatei hinter jede charge_athome-Zeile eine charge_abroad-Zeile ein:
Zitat2026-10-02_23:59:55 Spring charge_athome: W-d 0.000 W-ds 0.0 W-m 0.000 W-ms 0.0 W-total 46.925 odo-d 11 odo-m 11 odo-total 382 soc 77
2026-10-02_23:59:56 Spring charge_abroad: X-d 0.000 X-m 0.000 S-d 0.000 S-m 0.000
2026-10-03_23:59:55 Spring charge_athome: W-d 6.734 W-ds 0.0 W-m 6.734 W-ms 0.0 W-total 53.659 odo-d 0 odo-m 11 odo-total 382 soc 100
2026-10-03_23:59:56 Spring charge_abroad: X-d 0.000 X-m 0.000 S-d 6.734 S-m 6.734
2026-10-04_23:59:55 Spring charge_athome: W-d 0.000 W-ds 0.0 W-m 6.734 W-ms 0.0 W-total 53.659 odo-d 173 odo-m 184 odo-total 555 soc 18
2026-10-04_23:59:56 Spring charge_abroad: X-d 5.900 X-m 5.900 S-d 5.900 S-m 12.634
Darin sind X-d und X-m die an dem Tag/in dem Monat akkumulierten externen Ladungen, und S-d bzw. S-m die Summe aus interner und externer Ladung.
Die X- und S-Werte werden immer nachträglich aktualisiert, ich könnte also auch jetzt noch eine andere externe Ladung für Oktober eintragen.

Die Daten stammen natürlich aus den Fahrzeug-Readings
energy_grid_month, energy_solar_month, energy_ext_month bzw. energy_grid_year, energy_solar_year, energy_ext_year.
Die Daten vorhergehender Jahre sind nur noch als Gesamtsumme sichtbar:
energy_grid_year_start, energy_solar_year_start, energy_ext_year_start.

Damit gilt beispielsweise: Die Energie, die bis zum vorigen Abend in der Lebensdauer des Fahrzeugs aus der Solaranlage bezogen wurde, ist

energy_solar = energy_solar_year_start + energy_solar_year + energy_solar_month

Oder z.B. die in diesem Jahr bis zum vorigen Abend aus der eigenen Wallbox bezogene Energie ist

energy_grid_year + energy_grid_month + energy_solar_year + energy_solar_month

Es gibt also eine Vielzahl von Konsistenzbedingungen, mit denen man die Validität der Daten überprüfen kann. Und das Prinzip ist immer:

- Der Wert des heutigen Tages ist bis kurz vor Mitternacht nicht im Monatswert enthalten.
- Der Wert des gegenwärtigen Monats ist bis kurz vor Mitternacht des letzten Tages im Monat nicht im Jahreswert enthalten
- Der Wert des gegenwärtigen Jahres ist bis kurz vor Mitternacht des letzten Tages im Jahr nicht in dem year_start-Wert enthalten.

Aus dieser monatlichen Log-Datei kann man wunderbar einen Plot erzeugen, siehe Anlage

So, das erst einmal als Einstieg - mit der Bitte um Kommentare.

LG

pah