„Das Auto lädt erst mit mindestens 6A ab damit erst ab 1200 Watt!“ – so hieß es häufig in diversen Foren.
Gerade für den, der nur eine etwas kleinere PV-Anlage am Dach hat und damit Überschussladen machen möchte, etwas ärgerlich.
Wie in meinem ursprünglichen Artikel dazu auch beschrieben (siehe „Mini-PV“ mit Überschussladen) verschenkt man entweder Strom ins Netz oder man beginnt eher Strom aus dem Netz zu beziehen, wenn man das Auto laden möchte.
Durch Zufall bin ich nun auf eine Lösung gekommen, wie man beim Kia e-Niro doch noch besser auch mit kleinen PV-Anlagen Überschussladen kann.
Die EV-Einstellungen des e-Niro nutzen…
Kia bietet hier im EV-Menü die Option an , nicht immer maximal, sondern reduziert oder minimal zu laden. Einmal für den „Ladeziegel“ / das Notladegerät, einmal für die Wallbox. Dies kann ganz sinnvoll sein, wenn die Leitung nicht zu sehr belastet werden soll oder wenn einfach langsamer geladen werden soll:
Wie ich – erst glaubte ich schon an einen Defekt der Wallbox – feststellen durfte verhält es sich nun wie folgt: Ist der Ladestrom AC tragbar auf minimal oder reduziert gestellt und lädt man nur einphasig (ich nutze hierzu ein separates Kabel), dann kommt es darauf an, mit welcher Ladestärke der Ladevorgang gestartet wird:
- Beginnt man mit wenig Ladeleistung (6A), wird die Ladeeinheit als „Ladeziegel“ / Notladegerät interpretiert (=> „AC tragbar“)
- Beginnt man mit viel Ladeleistung (16A), denkt der KIA, er sei an einer normalen Wallbox („AC stationär“).
Bei der Einstellung „AC Stationär“ => maximal und „AC tragbar“ => reduziert oder minimal lässt sich nun ein „maximales Laden“ oder ein „reduziertes Laden“ von außen steuern, ohne dass im Auto etwas umgestellt werden muss.
Wen die Ladestärken bei den jeweiligen Ampere-Stufen interessieren, ich habe mir diese einmal mitprotokolliert, damit wir den Lademodus erkennen können und im Überschussladen später umschalten können und wir wissen ja seitens der Wallbox erst einmal nicht, ob der Niro reduziert, minimal oder maximal Laden konfiguriert hat.
Lademodus rechnerisch für openHAB ermitteln
Anhand der Durchschnittswerte der jeweiligen Stufen (einphasig wie dreiphasig) schauen wir nun, an welchen Werten die tatsächliche Ladeleistung näher dran liegt und erstellen uns so ein neues Item, welches den Lademodus (sofern geladen wird) enthält.
Dazu braucht es die entsprechende Rule:
var boolean log = false
rule "Lademodus Kia eNiro ermitteln"
when Item GoeCharger_Power_All changed
then
var String eniroMode
if ((GoeCharger_Phases.state as Number).intValue > 0) {
var Number percentMinimal
var Number percentReduced
var Number percentMaximal
if ((GoeCharger_Phases.state as Number).intValue == 1) {
// Werte für einphasiges Laden
percentMinimal = 0.45
percentReduced = 0.68
percentMaximal = 0.95
} else {
// Werte für dreiphasiges Laden
percentMinimal = 0.51
percentReduced = 0.82
percentMaximal = 0.92
}
val Number uDefault = 217
var Number pMax = (GoeCharger_Phases.state as Number).intValue * uDefault * (GoeCharger_Maximum_Current.state as Number).intValue
var Number diffMinimal = Math::abs(((percentMinimal * pMax) as Number - GoeCharger_Power_All.state as Number).intValue)
var Number diffReduced = Math::abs(((percentReduced * pMax) as Number - GoeCharger_Power_All.state as Number).intValue)
var Number diffMaximal = Math::abs(((percentMaximal * pMax) as Number - GoeCharger_Power_All.state as Number).intValue)
// Lademodus feststellen
if (diffMinimal <= diffReduced && diffMinimal <= diffMaximal) {
eniroMode = 'minimal'
} else if (diffReduced <= diffMinimal && diffReduced <= diffMaximal) {
eniroMode = 'reduziert'
} else {
eniroMode = 'maximal'
}
if (log) logInfo('eNiro', 'Ladestaerke=' + GoeCharger_Maximum_Current.state.toString + ', pMax=' + pMax.toString + ', diffMinimal=' + diffMinimal.toString + ', diffReduced=' + diffReduced.toString + ', diffMaximal=' + diffMaximal.toString + ', eniroMode=' + eniroMode)
} else {
if (log) logInfo('eNiro', 'Phasen = 0 - kein Kabel angeschlossen?')
eniroMode = 'kein Laden'
}
// Lademodus ins entsprechende Item setzen
if (eNiroLademodus.state != eniroMode) eNiroLademodus.sendCommand(eniroMode)
end
Lademodus im Überschussladen berücksichtigen
Im Überschussladen genügt es nun, den Lademodus zu berücksichtigen, damit man weiß, um wieviel Ampere man für die Differenz vorhandener Strom – verbrauchter Strom nach oben / unten korrigieren müsste. Zudem, wenn man deutlich mehr als 16A rechnerisch bräuchte, um den Strom zu nutzen, schalten wir den Lademodus auf maximal um.
Rule für das Überschussladen:
Der relevante Teil ist der fettgedruckte, da ich inzwischen meine Rules schon wieder etwas abgeändert habe im Vergleich zu meinem früheren Artikel habe ich sie komplett angefügt.
var boolean log = false
val logPrefix = 'rule_ueberschussladen_ladevorgang'
var Integer ampereAlt
var Integer ampereNeu
var Integer ladeSprung
var boolean starteLaden
var boolean stoppeLaden
var Number durchschnittsleistungPV
var Number durchschnittsverbrauchSaldierendAnOhneWallbox
var Number tempStromOhneWallbox
rule "Durchschnittswert PV ermitteln und Wallbox aktiv steuern"
when
Time cron "0/10 * * * * * *"
or Item ueberschussladen_aktiv changed
then
if (log) {
logInfo(logPrefix, '>>')
logInfo(logPrefix, '>> start')
}
// Default-Werte, falls nicht initialisiert
if (config_pv_laden_untergrenze.state == NULL) config_pv_laden_untergrenze.sendCommand(300) // Default-Wert setzen
if (config_pv_laden_puffer.state == NULL) config_pv_laden_puffer.sendCommand(0) // Default-Wert setzen
if ((GoeCharger_Cable_Encoding.state == NULL) || (GoeCharger_Cable_Encoding.state == UNDEF)) {
if (log) logInfo(logPrefix, '!!! Wallbox (temporär) offline? Abbruch!')
} else if (GoeCharger_PWM_signal_status.state == 'READY_NO_CAR') {
if (log) logInfo(logPrefix, '!!! Kein Auto angeschlossen, Abbruch!')
} else if (ueberschussladen_aktiv.state != ON) {
if (log) logInfo(logPrefix, '+++ Überschussladen nicht aktiv - keine automatische Steuerung. ueberschussladen_aktiv.state=' + ueberschussladen_aktiv.state.toString)
} else if (ueberschussladen_aktiv.state == ON) { // Rule nur relevant, wenn automatisches Überschussladen aktiv
// Relevante Code-Anteile ab hier. Überschussladen ist aktiviert; richtiges Kabel ist eingesteckt.
durchschnittsleistungPV = shellypro3empv_Power.averageSince(now.minusMinutes(1))
durchschnittsverbrauchSaldierendAnOhneWallbox = strom_saldierend_ohne_wallbox.averageSince(now.minusMinutes(1))
// check, ob Laden abgebrochen werden muss. Wir schauen uns hier die durchschnittsverbräuche der letzten 10 Minuten an - ist einer passend, laden wir erst einmal weiter
// wichtig
stoppeLaden = true
if (log) logInfo(logPrefix, '+++ Ermittle Wert Boolean stoppeLaden:')
(1..4).forEach[i|
tempStromOhneWallbox = (strom_saldierend_ohne_wallbox.averageSince(now.minusMinutes(i)) as Number)
if (tempStromOhneWallbox.intValue < (-1 * (config_pv_laden_untergrenze.state as Number).intValue)) {
stoppeLaden = false
if (log) logInfo(logPrefix,'> Durchlauf prüfen Stopp NEGATIV: ' + i.toString + '/5, config_pv_laden_untergrenze=' + config_pv_laden_untergrenze.state.toString + ' < tempStromOhneWallbox=' + (-1 * tempStromOhneWallbox).toString + ' W')
} else {
if (log) logInfo(logPrefix,'> Durchlauf prüfen Stopp POSITIV: ' + i.toString + '/5, config_pv_laden_untergrenze=' + config_pv_laden_untergrenze.state.toString + ' < tempStromOhneWallbox=' + (-1 * tempStromOhneWallbox).toString + ' W')
}
]
if (log) logInfo(logPrefix, '+++ Ermittle Wert Boolean starteLaden:')
starteLaden = ( // Bedingungen für Starten von Laden (sofern Überschussladen aktiv)
((durchschnittsleistungPV).intValue < -700) // Mindestens 700 Watt per PV im Durchscnitt letzte 1 Minute
&& ((shellypro3empv_Power.state as Number).intValue < -700) // ... sowie aktuell
&& ((durchschnittsverbrauchSaldierendAnOhneWallbox).intValue < (-1 * (config_pv_laden_untergrenze.state as Number +150).intValue)) //150 Watt Puffer um schnelles Ein- und Ausschalten zu verhindern; Damit Hürde Start immer schwerer als Hürde Stopp
)
if (log) {
logInfo(logPrefix, '------------------------------------------------------------------------')
logInfo(logPrefix, '+++ Aktuell saldierender Strom mit Auto: ' + strom_saldierend.state.toString)
logInfo(logPrefix, '+++ Aktuell saldierender Strom ohne Auto: ' + strom_saldierend_ohne_wallbox.state.toString)
logInfo(logPrefix, '+++ Durchschn. saldierend AN ohne Auto: ' + durchschnittsverbrauchSaldierendAnOhneWallbox.toString)
logInfo(logPrefix, '+++ Aktuelle Leistung PV: ' + shellypro3empv_Power.state.toString)
logInfo(logPrefix, '+++ Durchschnittsleistung PV 1 Min.: ' + durchschnittsleistungPV.toString)
logInfo(logPrefix, '+++ config_pv_laden_untergrenze ' + config_pv_laden_untergrenze.state.toString)
logInfo(logPrefix, '+++ Variable starteLaden: ' + starteLaden.toString)
logInfo(logPrefix, '+++ Variable stoppeLaden: ' + stoppeLaden.toString)
logInfo(logPrefix, '------------------------------------------------------------------------')
}
// Abbruch, wenn Ladevorgang gestoppt werden soll; Stoppen aber nur, wenn starteLaden auch negativ ist!
if (stoppeLaden && !starteLaden && GoeCharger_PWM_signal_status.state == 'CHARGING') {
GoeCharger_Maximum_Current_Temporary.sendCommand(6)
GoeCharger_Allow_Charging.sendCommand(OFF)
if (log) logInfo(logPrefix, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Überschussladen abgebrochen! XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
}
// Laden, wenn Ladevorgang gestartet werden soll.
if (!stoppeLaden && starteLaden && GoeCharger_PWM_signal_status.state != 'CHARGING') {
GoeCharger_Maximum_Current.sendCommand(6) // auf kleinste Leistung setzen - Hochgesetzt wird dann automatisch im nächsten Durchlauf
GoeCharger_Allow_Charging.sendCommand(ON)
if (log) {
logInfo(logPrefix, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Überschussladen freigegeben XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
}
}
// Anpassung Stromstärke, falls gerade geladen wird.
if (GoeCharger_PWM_signal_status.state == 'CHARGING') { // es wird aktuell geladen und Überschussladen ist an (zuvor geprüft) - Anpassen Ladeleistung?
// Saldierender Strom negativ - Überschuss vorhanden? Überschuss modulo ladeSprung in Watt erhöhen, max 16 A
// Saldierender Strom positiv - Netzbezug vorhanden? Überschuss modulo ladeSprung in Watt verringern, max auf 6A
if ((GoeCharger_Phases.state as Number).intValue == 1) { // einphasig - 100, 150 bzw. 205 Watt als "Ladesprung"
if (eNiroLademodus.state.toString == 'minimal') ladeSprung = 100
else if (eNiroLademodus.state.toString == 'reduziert') ladeSprung = 150
else ladeSprung = 205
} else { // dreiphasig - 110, 180 bzw. 200 Watt als "Ladesprung"
if (eNiroLademodus.state.toString == 'minimal') ladeSprung = 110
else if (eNiroLademodus.state.toString == 'reduziert') ladeSprung = 180
else ladeSprung = 200
}
// Ladestärke errechnen aus Differenz Stromverbrauch Saldierend (inkl PV!) + Ladepuffer (ggf.) ganzzahlig durch Ladesprung geteilt.
ampereAlt = ((GoeCharger_Maximum_Current.state as Number).intValue)
ampereNeu = ampereAlt.intValue - (( (strom_saldierend.state as Number) + (config_pv_laden_puffer.state as Number) ).intValue / ladeSprung).intValue
// wenn ampereNeu > 18 und ladestärke nicht maximal ist, dann Umschalten auf "normales Laden" beim eNiro.
if (ampereNeu >= 18 && eNiroLademodus.state != 'maximal') {
logInfo(logPrefix, '########### ÄNDERUNG DES LADEMODUS AUF MAXIMAL!')
GoeCharger_Allow_Charging.sendCommand(OFF)
GoeCharger_Maximum_Current_Temporary.sendCommand(16)
GoeCharger_Maximum_Current.sendCommand(16)
Thread::sleep(1000)
GoeCharger_Allow_Charging.sendCommand(ON)
}
// Nun regulär weiter und ggf. auf 16 ampere kappen
if (ampereNeu > 16) ampereNeu = 16 // max. 16 A bei 11 kW Wallbox
else if (ampereNeu < 6 ) ampereNeu = 6 // minimale Ladeleistung 6 A
if (ampereAlt != ampereNeu) {
if (log) logInfo(logPrefix, '<<<<<<<<>>>>>>>>>> Anpassung Wallbox Ladestärke von : ' + ampereAlt.toString + ' A zu ' + ampereNeu.toString + 'A')
GoeCharger_Maximum_Current_Temporary.sendCommand(ampereNeu)
GoeCharger_Maximum_Current.sendCommand(ampereNeu)
} else {
if (log) logInfo(logPrefix, '<<<<<<<<>>>>>>>>>> keine Anpassung Ladestärke nötig, bleibt bei ' + ampereAlt.toString + ' A')
}
}
}
if (log) {
logInfo(logPrefix, '>> ende')
logInfo(logPrefix, '>>')
}
end
Rule für Konfiguration des Überschussladens
Der Vollständigkeit halber noch die Rule für die Konfiguration des Überschussladens anbei
var boolean log = false
val logPrefix = 'rule_ueberschussladen_konfiguration'
// Item ueberschussladen_aktiv ist auf ON wenn Überschussladen konfiguriert und auch richtiges Kabel eingesteckt ist (1pahsig 20A)!
rule "Anschluss Wallbox überwachen, um Überschuss-Lademodus abhängig davon anzusteuern"
when
Item GoeCharger_Cable_Encoding changed
or Item config_pv_laden_aktivieren changed
then
// 20A-einphasiges kabel? => Wenn Überschussladen konfiguriert, dann nur Überschussladen, ansonsten immer laden.
if (GoeCharger_Cable_Encoding.state == NULL) {
logInfo(logPrefix, 'Wallbox aktuell nicht erreichbar, daher keine Änderung Überschusslademodus')
} else {
// Ist config_pv_laden_aktivieren AN sowie das richtige Kabel eingesteckt ist der Überschusslade-Modus aktiviert
if (((GoeCharger_Cable_Encoding.state as Number).intValue == 20) && (config_pv_laden_aktivieren.state == ON)) {
if (log) logInfo(logPrefix, 'Änderung Wallboxanschluss erkannt: Automatisches Laden DEAKTIVIERT - 6A Default Stromstärke setzen')
// Laden per se verbieten - das Laden wird dann separat über die Cron-getriggerte Rule gestartet
//GoeCharger_Allow_Charging.sendCommand(OFF)
// Eventueller Ladevorgang wird automatisch in Überschusslade-Rule beendet, wenn zu wenig Überschuss vorhanden
GoeCharger_Maximum_Current_Temporary.sendCommand(6)
GoeCharger_Maximum_Current.sendCommand(6)
if (ueberschussladen_aktiv.state != ON) ueberschussladen_aktiv.sendCommand(ON)
} else {
if (log) logInfo(logPrefix, 'Änderung Wallboxanschluss erkannt: Automatisches Laden AKTIVIERT - 16A Default Stromstärke setzen')
// Laden per se erlauben - es wird nicht oder mit mehrphasigem Kabel geladen, ist ein auto angeschlossen wird mit Laden begonnen
GoeCharger_Maximum_Current_Temporary.sendCommand(16)
GoeCharger_Maximum_Current.sendCommand(16)
GoeCharger_Allow_Charging.sendCommand(ON)
if (ueberschussladen_aktiv.state != OFF) ueberschussladen_aktiv.sendCommand(OFF)
}
}
end
Das Ergebnis
Im Ergebnis bekommt man so eine saubere Nutzung des Stromüberschusses hin. im Beispiel hatte ich „reduziert“ eingestellt, so dass er mit ~ 800W begonnen hat, zu laden.
Die gelbe Chartlinie stellt den saldierenden Stromverbrauch dar, die rote Linie den Verbrauch der Wallbox. Grün ist der Ertrag (negativ, Einspeisung) der PV-Anlage.