ArnoD15 / iobroker_E3DC

Laderegelung E3DC Hauskraftwerk mit Wetterprognose
https://forum.iobroker.net/topic/32976/e3dc-hauskraftwerk-steuern
GNU General Public License v3.0
20 stars 13 forks source link

Skript "mypv Heizstab.js" berücksichtigt keine Ladeschwelle und nutzt nur den manuellen Mode von ChargeControl #10

Open jansios opened 1 month ago

jansios commented 1 month ago

Hi,

wenn die in den verschiedenen Modi definierte Ladeschwelle noch nicht erreicht ist, soll lt. ChargeControl erstmal alles an PV-Energie in den Akku fließen, was ja auch Sinn macht. Das Heizstab-Skript beachtet die Ladeschwelle jedoch nicht, so dass stattdessen der Heizstab befeuert wird.

Kann man das noch einbauen?

Außerdem wird das Ladeende2 nur von Ladeende2_0 ausgelesen - das ist der manuell gesetzte Wert. ChargeControl nutzt auf Basis der Wetterprognosen jedoch die Werte Ladeende2_1 bis Ladenende2_5.

Ich habe in meinem Skript alle Modi ausgelsen sowie, welcher Modus gerade aktiv ist: const sID_EinstellungAnwahl = '0_userdata.0.Charge_Control.Allgemein.EinstellungAnwahl'; // aktuelle Einstellung Chargecontrol const sID_Ladeende2_0 = '0_userdata.0.Charge_Control.Parameter.Ladeende2_0' // Landeende 2 bei Modus Manuell const sID_Ladeende2_1 = '0_userdata.0.Charge_Control.Parameter.Ladeende2_1' // Landeende 2 bei Modus Alles Laden const sID_Ladeende2_2 = '0_userdata.0.Charge_Control.Parameter.Ladeende2_2' // Landeende 2 bei Modus Sonne const sID_Ladeende2_3 = '0_userdata.0.Charge_Control.Parameter.Ladeende2_3' // Landeende 2 bei Modus 12-18 Bewölkt const sID_Ladeende2_4 = '0_userdata.0.Charge_Control.Parameter.Ladeende2_4' // Landeende 2 bei Modus 12-15 Bewölkt const sID_Ladeende2_5 = '0_userdata.0.Charge_Control.Parameter.Ladeende2_5' // Landeende 2 bei Modus 15-18 Bewölkt

let EinstellungAnwahl = (await getStateAsync(sID_EinstellungAnwahl)).val; let Ladeende2_0 = (await getStateAsync(sID_Ladeende2_0)).val; let Ladeende2_1 = (await getStateAsync(sID_Ladeende2_1)).val; let Ladeende2_2 = (await getStateAsync(sID_Ladeende2_2)).val; let Ladeende2_3 = (await getStateAsync(sID_Ladeende2_3)).val; let Ladeende2_4 = (await getStateAsync(sID_Ladeende2_4)).val; let Ladeende2_5 = (await getStateAsync(sID_Ladeende2_5)).val;

Im späteren Verlauf habe ich dann per

if (EinstellungAnwahl == 0) {Ladeende2 = Ladeende2_0}; if (EinstellungAnwahl == 1) {Ladeende2 = Ladeende2_1}; if (EinstellungAnwahl == 2) {Ladeende2 = Ladeende2_2}; if (EinstellungAnwahl == 3) {Ladeende2 = Ladeende2_3}; if (EinstellungAnwahl == 4) {Ladeende2 = Ladeende2_4}; if (EinstellungAnwahl == 5) {Ladeende2 = Ladeende2_5};

die für das Skript genutzten Werg Ladeende2 generiert und verwendet.

Was haltet Ihr davon?

jansios commented 1 month ago

Das mit dem Code klappt ja prima in der Anzeige :( Hier nochmal ohne den Flag die relevanten Parts:

const sID_EinstellungAnwahl = '0_userdata.0.Charge_Control.Allgemein.EinstellungAnwahl'; // aktuelle Einstellung Chargecontrol const sID_Ladeende2_0 = '0_userdata.0.Charge_Control.Parameter.Ladeende2_0' // Landeende 2 bei Modus Manuell const sID_Ladeende2_1 = '0_userdata.0.Charge_Control.Parameter.Ladeende2_1' // Landeende 2 bei Modus Alles Laden const sID_Ladeende2_2 = '0_userdata.0.Charge_Control.Parameter.Ladeende2_2' // Landeende 2 bei Modus Sonne const sID_Ladeende2_3 = '0_userdata.0.Charge_Control.Parameter.Ladeende2_3' // Landeende 2 bei Modus 12-18 Bewölkt const sID_Ladeende2_4 = '0_userdata.0.Charge_Control.Parameter.Ladeende2_4' // Landeende 2 bei Modus 12-15 Bewölkt const sID_Ladeende2_5 = '0_userdata.0.Charge_Control.Parameter.Ladeende2_5' // Landeende 2 bei Modus 15-18 Bewölkt

let EinstellungAnwahl = (await getStateAsync(sID_EinstellungAnwahl)).val;
let Ladeende2_0 = (await getStateAsync(sID_Ladeende2_0)).val;
let Ladeende2_1 = (await getStateAsync(sID_Ladeende2_1)).val;
let Ladeende2_2 = (await getStateAsync(sID_Ladeende2_2)).val;
let Ladeende2_3 = (await getStateAsync(sID_Ladeende2_3)).val;
let Ladeende2_4 = (await getStateAsync(sID_Ladeende2_4)).val;
let Ladeende2_5 = (await getStateAsync(sID_Ladeende2_5)).val;

if (EinstellungAnwahl == 0) {Ladeende2 = Ladeende2_0};
if (EinstellungAnwahl == 1) {Ladeende2 = Ladeende2_1};
if (EinstellungAnwahl == 2) {Ladeende2 = Ladeende2_2};
if (EinstellungAnwahl == 3) {Ladeende2 = Ladeende2_3};
if (EinstellungAnwahl == 4) {Ladeende2 = Ladeende2_4};
if (EinstellungAnwahl == 5) {Ladeende2 = Ladeende2_5};
ArnoD15 commented 1 month ago

Man müsste erstmal generell die Prioritäten festlegen. Wenn immer die Batterie Vorrang vor dem Heitzstab hat, könnte man es so machen.

jansios commented 1 month ago

Fairer Punkt - ich selbst sehe tatsächlich die Versorgung meines Hauses und Einhalten einer Notstrom-Reserve und damit die Dinge, die ChargeControl verfolgt, als Prio 1. Was dann "über" ist, kann gerne in den Heizstab, damit ist das Heizstab-Skript quasi eine nachgelagerte Prio für mich.

ORuessel commented 1 month ago

Hallo @ArnoD15 das Skript sollte auf Basis der aktuellen Implementierung als Slave von charge Control agieren, da ich die Versorgung des Hauses als 2 Ranging sehe, da bei mir eine Gastherme im Winter den Hauptbetrieb übernimmt. Unter dem Gesichtspunkt wollte ich das Skript so bauen.

Sollen da noch weitere Definitionen rein ?

ArnoD15 commented 1 month ago

Ich würde dann eine Objekt ID e3dc-rscp.0.Charge_Control.Allgemein.FreigabeHeizstab bei mir einbauen und diese immer auf "false" setzen, wenn Charge-Control Vorrang hat. Das wäre dann bei:

Habe ich was vergessen :-)

ArnoD15 commented 1 month ago

Ich habe das jetzt mal im Branch Issue-#10 umgesetzt. @ORuessel @jansios könnt ihr das mal testen, ob es so funktioniert.

ORuessel commented 1 month ago

@ArnoD15 @jansios Kurze Anmerkung die Ladeschwelle ist nur in Kombination mit Power_Mode=2 hinterlegt, da je nach PV Leistung der Schwellenwert von ChargeControl <500W die Regelgung des E3DCs an ihn wieder zurück übergibt und dann der Heizstab nicht aktiv sein soll.

            //Prüfen ob berechnete Ladeleistung M_Power zu Netzbezug führt nur wenn LadenStoppen = false ist
            if(M_Power >= 0 && !bLadenEntladenStoppen){   
                let PowerGrid = PV_Leistung_Summe_W -(Power_Home_W + M_Power)
                if(PowerGrid < 500 && M_Power != maximumLadeleistung_W){// Führt zu Netzbezug, Steuerung ausschalten
                    M_Power = maximumLadeleistung_W
                    if(LogAusgabeRegelung){log(`${Logparser1} -==== Laderegelung wird gestoppt ====- ${Logparser2}`);}
                }   

theoretisch brauchen wir die FreigabeHeizstab ObjektID nicht da der Heizstab nur auf Basis der verfügbaren PV Energie den Überschuss berechnet. Es wird immer der Wert von ChargeControl aus der Berechnung M_Power_W ( Ladeleistung definiert aus Charge_Control ) herangezogen, somit ist Charge_Control der Master für den Heizstab.


// Verfügbaren Überschuss berechnen
        let verfuegbarerUeberschuss_W = **PV_Leistung_W - Hausverbrauch_W - M_Power_W - sicherheitspuffer**; // Verfügbarer Überschuss unter Berücksichtigung von PV-Leistung, Hausverbrauch, Soll-Ladeleistung und Sicherheitspuffer
        verfuegbarerUeberschuss_W = Math.max(verfuegbarerUeberschuss_W, 0); // Stellen Sie sicher, dass der Wert nicht negativ wird
ArnoD15 commented 1 month ago

Gebe zu das ich mir dein Skript noch nicht genauer angesehen habe, da ich es ohne Heizstab auch schlecht testen kann. Ich verwende EMS.SET_POWER_MODE (0= keine externe Regelung 1= Idle 2=Entladen 3=Laden) In deinem Script verwendest du EMS.MODE, wo ich nicht sicher bin, ob das entsprechend aktualisiert wird. Ich habe mir in meiner Liste bei der Objekt ID MODE einen Merker eingetragen, diese nicht zu verwenden, da die Rückmeldung zu spät und teilweise auch falsch gesetzt wird. Ich weiß jetzt nur nicht, ob das noch der Fall ist oder es bereits mit den letzten Updates behoben wurde.

Werde mir das am Sonntag, in ruhe mal ansehen.

ArnoD15 commented 4 weeks ago

EMS.MODE scheint zu funktionieren. Wenn ich es jetzt richtig verstanden habe, wird das Laden vom Heizstab unterbunden, wenn EMS.MODE =2 (Laden) ist und Ladeende2_0 nicht erreicht ist. Ansonsten wird der Überschuss berechnet, indem von der PV-Leistung der Hausverbrauch ohne Heizstab und die benötigte Ladeleistung aus Charge-Control abgezogen wird. Dazu ein paar Anmerkungen:

ORuessel commented 4 weeks ago

@ArnoD15 ja hast du korrekt verstanden, da ich wollte, wenn der E3DC die Ladesteuerung übernimmt ich keine Einwirkung auf das Ladeverhalten provozieren möchte, sondern die Batterie die höchste Priorität für mich hat.

zu deinen angemerkten Punkten, die nehme ich gerne auf.

ArnoD15 commented 4 weeks ago

Im Inselbetrieb gibt es einen entscheidenden Nachteil, wenn die PV-Leistung stark schwankt z. B. weil es bewölkt ist, kann nicht einfach aus dem Netz bezogen werden. Je nach Ausstattung ist die WR Leistung in so einem Fall begrenzt und wenn ich ein Heizstab hätte, würde ich nicht wollen, dass wegen des Heizstabes meine Leistung nicht ausreicht, um wichtigere Dinge zu versorgen. Ich habe aber zu wenig Erfahrung mit dem Inselbetrieb und weiß somit nicht wie E3DC reagiert, wenn ich 4000 W verbrauch habe, aber der WR nur 1500 W aus der Batterie liefern kann wie z.B. beim S10 MINI.

ArnoD15 commented 4 weeks ago

Ich habe jetzt das Script Charge-Control angepasst, sodass Akt_Berechnete_Ladeleistung_W die aktuell eingestellte Leistung enthält. Die Berechnung vom reinen Hausverbrauch habe ich jetzt in Charge-Control übernommen und wird in die Objekt-ID userdata.0.Charge_Control.Allgemein.Hausverbrauch eingetragen. Damit sollte sich dann auch Issues #3 erledigt haben. @ORuessel wenn du Zeit hast, könntest du dein Script anpassen und mal Branch Issue-#10 testen.

ArnoD15 commented 3 weeks ago

Ich habe die Funktion zur Berechnung der reinen Hausverbrauchsleistung noch mal optimiert.

jansios commented 3 weeks ago

Hallo Ihr beiden!

prima, wie Ihr da dran seid! Ich bin aktuell für 3 Wochen im Urlaub und kann daher nicht testen, mache es aber gerne nach dem Urlaub!

Viele Grüße, Jan