SMA Wallbox automatisiert über FHEM steuern

In einem früheren Arikel hatte ich bereits beschrieben, wie ich meine FHEM-Haussteuerung mit der PV-Anlage verbunden habe. In einem weiteren Artikel habe ich beschrieben, welche Daten ich u.a. für mein FHEM Daschboard nutze und über welche Geräte ich diese auslese.

In meinem heutigen Artikel möchte ich euch einmal genauer erläutern, wie ich die Wallbox von SMA – den EVCharger 22 – in FHEM integriert habe und wie ich damit eine automatisierte Ladesteuerung umgesetzt habe.

Die Integration der SMA Wallbox in FHEM

Da es bei FHEM noch kein Modul für die SMA Wallbox gab, habe ich erstmals selbst ein solches Modul realisiert. Aktuell ist dieses Modul nicht direkt in FHEM integriert und muß daher manuell installiert werden. Den Forums-Beitrag mit der entsprechenden Erläuterung findet ihr hier.

Das Modul bildet dabei im Prinzip die Abfrage der Daten und die Steuerungsoptionen an, die man auch über die Weboberfläche der Wallbox erreichen kann. Über dieses Modul hat man dann auch die Möglichkeit, einen Ladevorgang zu starten, die Stromstärke einzustellen sowie Lademenge bzw. Ladedauer zu steuern.

Damit wollte ich unter anderem die SMA App ablösen, mit der man einen Ladevorgang starten kann und diesen dann möglichst auch noch automatisieren. Das Ziel war es, dass ich das E-Auto einfach anstecke und FHEM dann ermittelt, ob und mit welchen Parametern der Ladevorgang durchzuführen ist.

Damit die Automatisierung funktioniert, benötigt man natürlich mindestens noch den aktuellen Ladestand des E-Autos. Da die Wallbox in erster Linie für unseren Kia e-Niro genutzt wird, musste also eine Funktion her, die den Ladestand abfragen und in FHEM nutzbar machen kann. Hierzu habe ich ein Python-Modul auf Github gefunden, welches ich auf meinem Rasperry abgelegt habe und mittels FHEM Funktion regelmäßig starte.

Wallboxsteuerung im FHEM Ftui Dachboard

Den Ladezustand (SoC) des E-Autos abfragen

Wie oben beschrieben nutze ich zur Abfrage unseres Kia den Perl-Code von Hacksore. Leider ist es nicht immer so einfach, einen funktionierenden Code zu finden, da die Hersteller nicht so offen sind und ihre Schnittstellen immer wieder anpassen oder gegen Zugriffe abschotten. Ansonsten findet man auch im Code der OpenWB-Umsetzung oft interessante Ansätze, die man nutzen kann.

Abruf der Kia Daten über Python Script und Übermittlung an FHEM

Damit die Daten aus dem Python-Modul in FHEM landen, habe ich zunächst eine recht einfache Lösung eingebaut. Die ermittelten Werte werden quasi in einer kleinen Json-Struktur zusammengefasst und mittels FHEM-Set Befehl über den Aufruf einer URL in einem DOIF-Konstrukt gespeichert.

Im Python-Modul sieht das, vereinfacht dargestellt, in etwa wie folgt aus:

myStatus = {'returnCode' : 'OK', 'returnText' : 'Statusabruf','doorLock' : str(doorLock), 'trunkOpen' : str(trunkOpen), 'airCtrlOn' : str(airCtrlOn), 'airCtrlTemp' : str(airCtrlTemp), 'evBatteryCharge' : str(charging), 'battery12soc' : str(batsoc),'battery12state' : str(batstate), 'evBatterySoc' : str(evBatterySoc), 'evBatteryPlugin' : str(batteryPlugin), 'chargeTimeFast' : str(chargeTimeFast), 'chargeTimeNormal' : str(chargeTimeNormal), 'chargeTimeWallbox' : str(chargeTimeWallbox), 'evRange' : str(evRange), 'hoodOpen' : str(hoodOpen), 'targetSOCAC' : str(targetSOCAC), 'targetSOCDC' : str(targetSOCDC), 'targetRangeAC' : str(targetRangeAC), 'targetRangeDC' : str(targetRangeDC), 'kilometer' : str(kilometer), 'gpslatitude' : str(gpslatitude), 'gpslongitude' : str(gpslongitude), 'gpshead' : str(gpshead), 'gpsspeed' : str(gpsspeed)}

return 0, myStatus

------------
def main()
ret = get_status()

returnJson = json.dumps(ret[1])
url = 'http://raspberrypi4fhem:8083/fhem?cmd.diKiaStatus=setreading%20diKiaStatus%20KiaAPI%20'+returnJson
requests.post(url,'')
Dummy Device für alle Infos zum Kia e-Niro

Verarbeitung der E-Auto Daten in FHEM

Innerhalb FHEM habe ich für die E-Autos jeweils ein Dummy-Device angelegt. Hier speichere ich die Daten, die für eine automatisierte Ladesteuerung benötigt werden oder zur Anzeige in meiner FHEM FTUI-Oberfläche.

Damit die entsprechenden Readings aus dem Python-Script übertragen werden, verwende ich einerseits ein DOIF (siehe nächster Abschnitt), in dem ich auf die Änderung des Readings „KiaStatus“ abfrage und eine kleine FHEM-Funktion aufrufe. In dieser Funktion wird dann das Ergebnis aus dem Python-Script in die entsprechenden Readings des Dummy-Device geschrieben.

Der Code aus 99_myUtils.pm sieht dann wie folgt aus:

sub KiaStatusSetzen()
{
   my $status = ReadingsVal("diKiaStatus", "KiaAPI", "unbekannt");
   my $json = decode_json( $status );
   
   if ($json->{returnCode} eq "OK" and $json->{returnText} eq "Statusabruf")
   {
      my $doorLock = $json->{doorLock};
   
      fhem("setreading duKia doorLock $doorLock");
      fhem("setreading duKia trunkOpen $json->{trunkOpen}");
      fhem("setreading duKia airCtrlOn $json->{airCtrlOn}");
      fhem("setreading duKia airCtrlTemp $json->{airCtrlTemp}");
      fhem("set duKia evBatteryCharge $json->{evBatteryCharge}");
      fhem("set duKia evBatteryPlugin $json->{evBatteryPlugin}");
      fhem("setreading duKia chargeTimeFast $json->{chargeTimeFast}");
      fhem("setreading duKia chargeTimeNormal $json->{chargeTimeNormal}");
      fhem("setreading duKia chargeTimeWallbox $json->{chargeTimeWallbox}");
      fhem("setreading duKia evRange $json->{evRange}");
      fhem("setreading duKia hoodOpen $json->{hoodOpen}");
      fhem("setreading duKia battery12soc $json->{battery12soc}");
      fhem("setreading duKia battery12state $json->{battery12state}");
   
      #manchmal verliert er wohl die TargetSOC Einstellung?
      if ($json->{targetSOCAC} > 0)
      {
         fhem("setreading duKia targetSOCAC $json->{targetSOCAC}");
         fhem("setreading duKia targetSOCDC $json->{targetSOCDC}");
      }
      fhem("setreading duKia targetRangeAC $json->{targetRangeAC}");
      fhem("setreading duKia targetRangeDC $json->{targetRangeDC}");
   
      #letzten Kilometerstand und evSOC merken
      my $kilometer = ReadingsVal("duKia","kilometer",0);
      my $evSOC = ReadingsVal("duKia","evBatterySOC",0);
      fhem("setreading duKia kilometer_last $kilometer");
      fhem("setreading duKia evBatterySOC_last $evSOC");
      fhem("setreading duKia kilometer $json->{kilometer}");
   
      # manchmal liefert die API nicht den richtigen SOC
      if($json->{evBatterySoc} ne "0")
      {
         fhem("setreading duKia evBatterySoc $json->{evBatterySoc}");
      }
   
      fhem("setreading duKia gpslatitude $json->{gpslatitude}");
      fhem("setreading duKia gpslongitude $json->{gpslongitude}");
      fhem("setreading duKia gpshead $json->{gpshead}");
      fhem("setreading duKia gpsspeed $json->{gpsspeed}");
      fhem("set duKia "."Letzter Status:".strftime('%d.%m. %H:%M', localtime));
   }
   else
   {
      Log3 undef, 3, $status;
   }
}

Regelmäßiger Abruf der E-Auto Daten

Für den regelmäßigen Abruf der Daten verwende ich ein DOIF, in dem dann auch der JSON-String aus dem Python-Script landet. Im Prinzip rufe ich die Daten einmal pro Stunde ab und auch nur tagsüber. Kleinere Intervalle können kritisch sein, da die Schnittstelle von Kia bei zuvielen Aufrufen nicht mehr funktioniert. Hier ist wohl eine Obergrenze definiert.

Während des Ladevorgangs rufe ich die Daten dann alle 20 Minuten ab, um regelmäßig den aktuellen Akkuladestand (SoC) zu ermitteln. Dies geschieht auch immer dann, wenn das E-Auto an die Wallbox angeschlossen wird. So bekomme ich die notwendigen Werte für die automatisierte Steuerung.

Schließlich ist in dem DOIF noch der Aufruf für die Übertragung der Daten aus dem Python-Script in FHEM.

Das DOIF sieht wie folgt aus:

## Status vom Kia
## Falls an der Wallbox mal ein anderes Auto hängt, wird der Kia Status unnötigerweise aufgerufen.
## Ist aber eher die Ausnahme
##

## Falls ein Ladevorgang aktiv ist, alle 20 Minuten abfragen, um den SOC zu ermitteln
([+00:20] and ([duKia:evBatteryPlugin] eq "2" or [myWallbox:Status_Ladevorgang] ne "nicht verbunden") and ([duKia:evBatteryCharge] eq "True" or [myWallbox:Status_Ladevorgang] eq "Ladevorgang aktiv") )
   ({system("python3 ./mykia/mykia.py &")})

## turnusmäßiger Abruf 1mal pro Stunde
DOELSEIF ([06:00-20:00,+1:00] and [duKia:evBatteryCharge] eq "False" and [duUrlaub] eq "nein")
   ({system("python3 ./mykia/mykia.py &")})
## Sobald die Wallbox angesteckt wird, den Status abfragen, für den aktuellen SOC
DOELSEIF ([myWallbox:Startzeit_Verbindung] ne "nicht verbunden")
   ({system("python3 ./mykia/mykia.py &")})

## bei erfolgreicher Statusabfrage duKia-Werte setzen
DOELSEIF ([$SELF:KiaAPI] =~ m/"returnCode": "OK"/)
   ({KiaStatusSetzen()})

Bei den Attributen habe ich „do always“ gesetzt, weil ich hier schon mal ein paar Hänger hatte, wenn das Python-Script nicht richtig funktionierte bzw. keine Daten von Kia abgerufen werden konnten. Weiterhin habe ich noch ein Userreading definiert, welches dazu dient, in der FTUI-Oberfläche die Zeiten für den nächsten Statusabruf darzustellen.

nextKiaUpdate {(ReadingsVal("duKia","evBatteryCharge","False") eq "False") ? ReadingsVal("diKiaStatus","timer_04_c02","06:00") : ReadingsVal("diKiaStatus","timer_01_c01","06:00")},

Damit sind die Rahmenbedingungen für die automatisierte Ladesteuerung geschaffen.

Statusdarstellung des E-Auto im FHEM FTUI Dashboard

Automatisierte Ladesteuerung des E-Autos über FHEM

An der Wallbox von SMA befindet sich ein Drehschalter, der auf den Modus „Direktladung“ oder „intelligentes Laden“ eingestellt werden kann. Normalerweise steht dieser Schalter bei mir immer auf „intelligentes Laden“, damit über das Sunny-Portal von SMA eine automatisierte Überschußladung realisiert werden kann. In dieser Einstellung wird dann auf Basis von Wetterprognosen, Verhalten anderer Verbraucher und der aktuellen PV-Erzeugung sowie weiterer Vorgaben die Stromstärke der Wallbox gesteuert. Im Sunny-Portal gebe ich dazu nur an, wieviel Sonnenenergie für das Laden des E-Autos verwendet werden soll. Im Sommer steht der Wert bei mir immer auf 100%. In den Wintermonaten reduziere ich den Wert dann schrittweise, da eine progosebasierte Beladung sonst kaum noch funktionieren würde.

In diesem Zustand wird ein angeschlossenen E-Auto also immer dann geladen, wenn genug Überschuß an Sonnenenergie vorhanden ist. Nun muß das Auto auch unabhängig von der Sonneneinstrahlung geladen werden, weil man einen bestimmten Akkustand für die nächste Fahrt benötigt. In diesem Fall nutzt man normalerweise die App von SMA. Hier kann man einstellen, wieviel kWh man laden möchte und bis zu welcher Uhrzeit diese Lademenge ans Auto übertragen werden muß. Auch jetzt versucht die intelligente Steuerung die Ladung so zu planen, dass möglichst viel Sonnenenergie genutzt wird.

Unsere Wallbox in der Garage

Meine Anforderungen an die automatisierte Ladesteuerung

Für die Ladesteuerung der SMA Wallbox nutzt man normalerweise die entsprechende App. Hier hat mich gestört, dass ich mir immer überlegen bzw. ausrechnen muß, wieviel ich für einen bestimmten Ladestand nachladen muß und dass es nicht eine Möglichkeit gibt, den Prozess ein wenig zu automatisieren. Daher habe ich nun versucht, meine persönlichen Anforderungen mit den FHEM-Mitteln umzusetzen.

Meine Idee war, dass automatisiert berechnet wird, wieviel Energie ins Elektro-Auto geladen werden sollte. Weiterhin kenne ich ja meine regelmäßigen Abfahrtzeiten zur Arbeit. Also sollte geprüft werden, ob ein bestimmter Mindestladestand unterschritten wird und dann eine Aufladung bis zu einem definierten Ladestand erfolgen. Dieser Ladestand soll dann spätestens zur Abfahrtzeit zur Verfügung stehen.

Somit würde also regelmäßig quasi die Funktion der App nachgebildet werden. Die eigentliche Ladeplanung wird ja weiterhin vom Sunny-Portal bzw. der Wallbox umgesetzt.

Mit der nachfolgenden Lösung kann ich nun für jeden Tag eine Abfahrtzeit definieren und angeben, bei welchem Ladestand spätestens eine Ladung erfolgen soll. In Verbindung mit der Angabe einer oberen Ladegrenze wird dann unter Berücksichtigung von Ladeverlusten die Lademenge ermittelt und diese Informationen an die Wallbox weiter gegeben.

Einstellung der Parameter über die FTUI Oberfläche von FHEM

In meiner FHEM FTUI Oberfläche habe ich beide Elektroautos bzw. die Lademöglichkeiten über die Wallbox und meine selbstgebaute „Ladestation“ (220V Ladung) eingebunden. Hier können die täglichen Abfahrtzeiten eingestellt werden. Gibt es an einem Tag keine regelmäßigen Abfahrtzeiten, wird einfach 0:00 Uhr eingetragen. Schließlich kann noch die Unter- und die Obergrenze für den Akkustand eingetragen werden. Zusätzlich werden dann alle Lade-Infos angezeigt, die während des Ladevorgangs über die Wallbox ermittelt werden.

Die Speicherung der Informationen erfolgt dann über ein DOIF in dem ich einige Readings angelegt habe. Das DOIF wird nachfolgend erläutert, da es auch zur eigentlichen Steuerung des Ladevorgangs eingesetzt wird.

Darstellung eines Ladevorgangs in der SMA App

Ladesteuerung mittels FHEM DOIF

Mit einem DOIF habe ich die eigentliche Ladesteuerung umgesetzt. Hierbei wird auf die Ereignisse beim Ändern der Parameter über die FTUI Oberfäche reagiert bzw. auf den aktuellen Ladezustand des Akkus.

## Schaltzeiten werden geschaltet, wenn Ladung_Aktiv == on - damit kann also die gesamte Automatik deaktiviert werden
## Für jeden Tag muß eine Abfahrtzeit eingetragen werden (ToDo: Feiertage berücksichtigen?)
## Wenn für einen Tag keine Abfahrtzeit definiert werden soll - also keine Zielzeit für eine Ladung definiert wird - dann die Zeit 00:00 eintragen
## Sobald der ermittelte SOC aus duKia unterhalb von SOC_Untergrenze liegt, wird ein Befehl an die Wallbox gesendet
##
## Wenn die Automatik aktiv ist und der Akku unterhalb der Untergrenze liegt, Ladung aktivieren
([?$SELF:Ladung_Aktiv, "off"] eq "on"
and [myWallbox:Status_Ladevorgang] eq "verbunden"
and ([myWallbox:Param_Betriebsart_Ladevorgang] eq "Optimiertes_Laden" or [myWallbox:Param_Betriebsart_Ladevorgang] eq "Ladestopp" or [$SELF:Naechste_Abfahrt])
and (([duKia:evBatterySoc] <= [$SELF:SOC_Untergrenze] and [duKia:evBatterySoc] != 0)))
   ({WallboxAutomatik("$SELF","myWallbox")})
## Änderungen, die über das Tablet vorgenommen werden in den Readings speichern
DOELSEIF([$SELF:Tablet_Ok] eq "save")
	(set $SELF [$SELF:Tablet_Wochentag] [$SELF:Tablet_Uhrzeit])
## Bei Änderung der Lade-Obergrenze oder der Abfahrtzeit müssen ggf. die Ladeparameter angepasst werden
DOELSEIF([?myWallbox:Param_Betriebsart_Ladevorgang] eq "Laden_mit_Vorgabe" and ([$SELF:SOC_Obergrenze] or [$SELF:Naechste_Abfahrt_Num]))
   ({system("python3 ./mykia/mykia.py &")};{WallboxAutomatik("$SELF","myWallbox")})
## Nachdem über das Tablet der Speicher-Button gedrückt wurde, wird der Status im Reading wieder geändert, damit das Triggern richtig funktioniert   
DOELSEIF([$SELF:Tablet_Wochentag] or [$SELF:Tablet_Uhrzeit])
   (setreading $SELF Tablet_Ok changed)

Die Hauptfunktion ist im ersten Zweig des DOIF zu finden. Hier wird zunächst geprüft, ob die Automatik aktiviert ist und das Auto mit dem Wallbox verbunden ist. Dann wird geprüft, ob der Status der Wallbox auf „optimiertes Laden“ oder „Ladestopp“ steht und es eine Abfahrtzeit gibt bzw. diese geändert wurde. Wenn diese Eigenschaften zutreffen wird dann geprüft, ob der aktuelle Ladestand des Akkus unter dem unteren Grenzwert liegt. Die Abfrage „!=0“ musste ich einbauen, da der SoC manchmal fehlerhaft mit 0 vom Auto zurück gegeben wird.

Treffen die Bedingungen zu, wird die Funktion „WallboxAutomatik“ aufgerufen, die dann die notwendigen Ladeparameter ermittelt.

Die Zweige Nummer 2 und 4 dienen der Übergabe der Parameter aus dem Tablet und deren Speicherung in den Readings des DOIF.

In Zweig 3 wird geprüft, ob wir uns in einer Ladung mit Vorgabe befinden. Ob die Ladung mit vordefinierten Werten aufgerufen wurde. Ist das der Fall dann wird dieser Zweig immer dann getriggert, wenn sich die Obergrenze oder die Abfahrtzeit während des bereits gestarteten Ladevorgangs verändert haben. Hierzu wird dann nochmals der aktuell Akkuladestand abgerufen und dann zeitversetzt (mittels wait) die Funktion „Wallbox Automatik“ aufgerufen.

Nach Beendigung des Ladevorgangs wechselt die Wallbox dann wieder selbstständig in den Modus „optimiertes Laden“.

Die Funktion „Wallbox Automatik“ sieht wie folgt aus:

# setzt eine Ladezeit und eine Lademenge zur Ladung der jeweiligen E-Autos
# bei den Abfahrtzeiten in den Wochentagen wird 00:00 als besondere Zeit für "an diesem Tag keine Abfahrtzeit" definiert
# 
# Übergabeparameter: 
#   1: Device-Name des DOIF in dem die Zeiten definiert sind
#   2: Device-Name der Wallbox
#
# Im DOIF-Device notwendige Readings
#   Ladeverlust
#   SOC_Obergrenze
#   SOC_Untergrenze
#   Max_Kapazitaet 
#	Namen für jeden Wochentag (Montag, Dienstag,...)
#
sub WallboxAutomatik($$)
{
   my ($Timer, $Wallbox) = @_;
	
   my @wochentage = ("Sonntag","Montag", "Dienstag", "Mittwoch", "Donnerstag","Freitag","Samstag");
   my ($sec,$min,$hour,$mday,$mon,$year,$heute,$yday,$isdst) = localtime();
   my $ladedauer = 0;
   my $lademenge = ReadingsVal("$Timer","Lademenge", "0");
	
   # nächste Abfahrtzeit ermitteln, beginnend beim aktuellen Wochentag
   for ( my $wtag = $heute; $wtag <= 13 and $ladedauer <= 0 and $lademenge > 0; $wtag++ )
   {
	my $akttag = $wtag > 6 ? $wtag - 7 : $wtag;
	my $uhrzeit = ReadingsVal("$Timer",$wochentage[$akttag], "00:00");
	my ($stunde, $minute) = split(":", $uhrzeit);
		
	if ($uhrzeit ne "00:00")
	{
	   # ladedauer ist heute + anzahltage in zukunft * 24 - differenz aus abfahrt und aktueller Uhrzeit
 	   $ladedauer = (86400 * ($wtag - $heute) + (($stunde * 60 + $minute) - ($hour * 60 + $min)) * 60) / 60;
	}
   }
	
   # falls keine Abfahrtzeit definiert ist, wird 12 Stunden als Default angenommen
   if($ladedauer == 0)
   {
      $ladedauer = 12 * 60;
   }
   
   # 
   if($lademenge > 0)
   {
	fhem ("set $Wallbox Param_Dauer_Ladevorgang $ladedauer");
	fhem ("set $Wallbox Param_Energiemenge_Ladevorgang $lademenge");

   }
}

Im Prinzip erfolgt hier nur die Berechnung der Ladedauer auf Basis der nächsten Abfahrtzeit, die der Wallbox mitgegeben werden muß. Die Lademenge wird bereits in dem DOIF mit einem Userreading ermittelt. Das hätte ich natürlich auch hier noch einbauen können.

Im DOIF gibt es also noch zwei bzw. drei Userreadings für die Ermittlung der nächsten Abfahrtzeit sowie der Lademenge. Die nächste Abfahrtzeit wird in erster Linie auch für die Anzeige in der Oberfläche ermittelt. Die Userreadings sehen wie folgt aus:

Lademenge {(ReadingsNum("myWallbox","Energie_Ladevorgang",0)/1000) + ((ReadingsVal("diKiaLadung","SOC_Obergrenze", "80") - ReadingsVal("duKia","evBatterySoc", "20")) 
					* ReadingsVal("diKiaLadung","Max_Kapazitaet", "64") / 100 
					* (1 + ReadingsVal("diKiaLadung","Ladeverlust", "10") / 100))},
Naechste_Abfahrt_Num {naechsteAbfahrt("diKiaLadung")},
Naechste_Abfahrt {FmtDateTime(ReadingsNum("diKiaLadung", "Naechste_Abfahrt_Num", time()))}

Schließlich noch die Funktion zur Ermittlung der nächsten Abfahrtzeit:

# nächste Abfahrtzeit des jeweiligen E-Autos ermitteln für eine mögliche automatische Ladung
sub naechsteAbfahrt($)
{
	my ($device) = @_;
	my @wt = qw(Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag); 
	my $heute = strftime('%w', localtime); 
	my $stunde = strftime('%H', localtime);
	my $minute = strftime('%M', localtime);
	my $next = $heute;
	
	my $abfahrt = ReadingsVal("$device", "$wt[$next]", "00:00");
	my ($abfahrt_stunde, $abfahrt_minute) = split(/:/,$abfahrt);
	
	if ( ($stunde * 60 + $minute) > ($abfahrt_stunde * 60 + $abfahrt_minute) )
	{
		$next = $heute + ($heute < 6 ? 1 : -6);
		$abfahrt = ReadingsVal("$device", "$wt[$next]", '00:00');
	}
	
	while( $abfahrt eq "00:00" and $next != $heute )  
	{
		$next += ($next < 6 ? 1 : -6);
		$abfahrt = ReadingsVal("$device", "$wt[$next]", '00:00');
	}
	
	if ($abfahrt eq "00:00")
	{
		return "Keine Abfahrtzeit definiert"
	}
	else
	{

		my $t = localtime(); 
		$t =~ s/\d\d:\d\d:\d\d/$abfahrt:00/;
		my $dif = $heute <= $next ? $next - $heute : $next - $heute + 7;
		my $abfahrt_num = str2time($t) + ($dif * 24 * 60 * 60);
		
		return $abfahrt_num;
	}
}

Zusammenfassung

Mit meiner Umsetzung muß ich mich eigentlich kaum noch darum kümmern, ob das E-Auto für die regelmäßigen Fahrten ausreichend geladen ist. Sobald ich davon abweichende Beladungen benötige, stelle ich einfach nur die entsprechende Zeit und die gewünschte Obergrenze des Ladestands an. Damit die Ladung dann auch wirklich startet, muß ggf. noch die Untergrenze oberhalb des aktuellen Ladestands eingestellt werden. Ab dann läuft alles automatisch und wird mit möglichst viel Sonnenenergie durch die SMA Geräte versorgt.

5 comments

  1. Hallo Jürgen,

    super, dass du auch auf dieses Thema nochmal eingegangen bist!

    Die automatisierte & manuelle Ladeplanung hatte ich zwar vorher schon implementiert – hatte es aber mit meinen openWBs auch deutlich einfacher, weil ich mit denen bereits vieles per MQTT lesen und schreiben kann.
    Womit ich noch keine Erfahrung hab, sind diese Skripte die sich mit den Kia- oder VW-Servern verbinden. Dass z.B. das Fahrzeug nicht verriegelt ist, finde ich eine interessante Info, die mir noch fehlt. Da wird mir dein Artikel sicher weiter helfen.

    Was mir noch ganz schmerzlich fehlt, ist die Möglichkeit über FHEM vorzuklimatisieren. Die VW-App ist ja leider extrem langsam und vor allem für meine Frau keine gute Option.
    So wie ich das sehe liest bisher auch „nur“ den Status der Klimatisierung aus, kannst noch nicht von FHEM aus steuern, oder?

  2. Aktuell lese ich tatsächlich in erster Linie die Werte von den Autos aus. Die Statusinfos zu Türen, Kofferaum usw. habe ich aber tatsächlich immer noch nicht umgesetzt. Für den Kia hatte ich mir mal eine Temperatursteuerung über FHEM und Alexa gebaut. Allerdings steht der in der Garage und wird tatsächlich nie vorklimatisiert. Mit dem eUp sollte das eigentlich auch gehen. Hier nutze ich ja die NativeAPI.py von trocotronic (githab). Ich habe es gerade nochmal im Script getestet. Die Klima lässt sich damit einfach einschalten. Man könnte also einerseits die Temperatur über FHEM einstellen und die Klima starten/stoppen.

    Eigentlich mal eine gute Idee, meinen Ansatz mit Alexa zu beschreiben. Dann wäre die Bedienung noch einfacher. Hierzu habe ich einen Dummy-Schalter angelegt, über den ich eine Temperatur steuern kann.

  3. Danke für deine schnelle und hilfreiche Antwort!
    Ich hab das Skript von trocotronic gestern gleich mal ausprobiert. War mein erster Versuch Python-Skripte aufzurufen, ich musste mich da erst etwas einarbeiten, aber hat ganz gut geklappt. Toll wie viele Daten man da abrufen kann. Etwas hinderlich ist nur, dass man den VW-Server wahrscheinlich nicht zu oft abfragen sollte, damit sie dem nicht irgendwann einen Riegel vorschieben. Auch die Klima-Einstellungen kann man nur paar mal ändern, bevor das Auto meldet: „The command was rejected because of energy concerns“ (zumindest hoffe ich, dass die Meldung vorübergehend ist und wieder verschwindet sobald man zwischendrin mal die Zündung an hatte)
    Da kann ich jetzt wieder viel Zeit in die Perfektionierung von Logik und Visualisierung versenken 😉

    Falls es jemand interessiert, so sieht meine erste Version aus (die sicher nicht so bleiben wird)…

    ————–
    DOIF
    ————–
    define di_ClimateGolf DOIF ([„$SELF:ClimatisationActive: on“])\
    ({system(‚python3 /opt/fhem/mytools/weconnect/climate.py WVWZZZXYZ on ‚.ReadingsVal(„$SELF“, „TargetTemp“, „20“).‘ &‘)})\
    (setreading $SELF ClimatisationActive_UI on )\
    (setreading $SELF ClimatisationActive_UI off)\
    DOELSEIF ([„$SELF:ClimatisationActive: off“]) (\
    {system(‚python3 /opt/fhem/mytools/weconnect/climate.py WVWZZZXYZ off &‘)},\
    setreading $SELF ClimatisationActive_UI off\
    )
    attr di_ClimateGolf do always
    attr di_ClimateGolf readingList TargetTemp ClimatisationActive
    attr di_ClimateGolf room Auto
    attr di_ClimateGolf setList TargetTemp:slider,16,1,24 ClimatisationActive:on,off
    attr di_ClimateGolf wait 0,0,600:0

    Um nicht ständig über den VW-Server fragen zu müssen ob die Klimatisierung noch läuft, schalte ich den Switch im UI nach 10 Minuten automatisch wieder aus (über das wait im DOIF), da das Auto anscheinend immer nur 10 Minuten klimatisiert.

    ————–
    climate.py
    ————–
    import sys
    from NativeAPI import WeConnect

    if __name__ == „__main__“:
    vwc = WeConnect()
    vwc.login()

    vin = sys.argv[1]
    action = sys.argv[2]

    if action.lower() == ‚on‘:
    temp = int(sys.argv[3])
    vwc.climatisation_temperature(vin,temp)

    vwc.climatisation(vin,action)

    ————–
    TabletUI
    ————–

  4. Schade, Einrückungen sind leider verloren gegangen und TabletUI-Sektion abgeschnitten.

    TabletUI
    ————

  5. Ok, war ne dumme Idee HTML-Content in einen Kommentar zu packen 😉
    Egal.

    Zum Thema Zielladen:
    Das hab ich etwas anders gelöst. Im TabletUI kann ich für jeden Wochentag einstellen:
    – Zielladen aktiv (on/off)
    – Uhrzeit (in 15-Minuten-Schritten)
    – Target-SoC (in 10%-Schritten)
    Ich hab also für jeden Wochentag eine Uhrzeit und einen Target-SoC. Meist sind das z.B. 50% um 9 Uhr. Vor längeren Reisen stelle ich ihn auf 100% zur tatsächlichen Abfahrtszeit.

    In userreadings ermittle ich für jeden Wochentag die Ladedauer, um, bei maximaler Ladeleistung, vom aktuellen SoC auf den Target-SoC zu kommen. Per DOIF triggere ich dann die Sofort-Ladung zum Zeitpunkt „Abfahrtszeit abzgl. Ladedauer“.

    Ziel des Ganzen ist, dass das Auto täglich einen gewissen Mindest-SoC hat, aber so lange wie möglich versucht wird mit der Überschuss-Ladung hinzukommen. Erst wenn der Target-SoC nur noch mit maximaler Ladeleistung zu erreichen ist, wechsle ich in den Modus Sofort-Laden.

    Eine Kombination aus unseren beiden Lösungswegen wäre eigentlich ganz cool. Täglich auf einen Mindest-SoC hochladen, wenn PV-Überschuss nicht gereicht hat. Und zusätzlich Termine aus’m Google-Kalender lesen zu denen auf 100% geladen wird 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *

*

x

Check Also

Batteriediagnose unseres neuen Kia EV6

Eigentlich wollte ich die Batterie unseres neuen Kia EV6 schon längst mit dem Aviloo Premium ...