Kia eNiro – Überschussladen schon ab 550 Watt (openHAB, go-e Charger

„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.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.

Durch die weitere Nutzung der Seite wird der Verwendung von Cookies und den Inhalten der Datenschutzerklärung zugestimmt. Weitere Informationen

Die Cookie-Einstellungen auf dieser Website sind auf "Cookies zulassen" eingestellt, um das beste Surferlebnis zu ermöglichen. Wenn du diese Website ohne Änderung der Cookie-Einstellungen verwendest oder auf "Akzeptieren" klickst, erklärst du sich damit einverstanden.

Schließen