Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. JavaScript
    5. Zendure SolarFlow2400 AC (EVCC, Tibber und PV-Forecast)

    NEWS

    • UPDATE 31.10.: Amazon Alexa - ioBroker Skill läuft aus ?

    • Monatsrückblick – September 2025

    • Neues Video "KI im Smart Home" - ioBroker plus n8n

    Zendure SolarFlow2400 AC (EVCC, Tibber und PV-Forecast)

    This topic has been deleted. Only users with topic management privileges can see it.
    • S
      Schimi last edited by Schimi

      HI,

      da ich inzwischen öfters suchende nach einen Skript sehe und selber auch nichts "für mich passendes" gefunden habe...
      Habe ich mich vor einer Woche (mit Hilfe der Ki) an die Arbeit gemacht und heute glaube ich ist der tag wo man es veröffentlichen kann 🙂

      Um das script zu nutzen müsst Ihr mit eueren Solarflow, eine MQTT Verbindung zum iobroker aufbauen (ich gehe davon aus, das es jeder selber hinbekommt)

      Nutzung von Tibber, EVCC und dem PV-Forecast kann deaktiviert werden

      Von euch auszufüllen wäre die: "1. Konfiguration" und "2. Datenpunkte"

      //-------------------------------------------------------------------------------------
      // ### ioBroker Skript: Batteriesteuerung (Zendure) mit PI-Regler ###
      //
      // v2.0 - 02.11.2025
      // - ANPASSUNG: Die Steuerung von Tibber, EVCC und PV-Forecast erfolgt nun 
      //   ausschließlich über die internen "CONFIG" Variablen (ENABLE_TIBBER, etc.).
      // - ENTFERNT: Es werden keine externen Datenpunkte mehr zur Aktivierung/Deaktivierung
      //   der Module benötigt oder abgefragt.
      // - Check: Timer-basierte Regelung (V1.9) bleibt erhalten.
      //-------------------------------------------------------------------------------------
      
      // --- 1. KONFIGURATION ---
      
      const CONFIG = {
          // --- Globale Schalter ---
          // Steuern Sie hier, welche Module aktiv sein sollen.
          // Es werden keine externen Datenpunkte mehr hierfür verwendet.
          ENABLE_TIBBER: true,                 
          ENABLE_EVCC: true,                   
          ENABLE_PV_FORECAST: true,            // (Nur wirksam, wenn ENABLE_TIBBER auch true ist)
      
          DEBUG: false,                    // FALSE: Detaillierte Logs unterdrücken; TRUE: Logs ausgeben
      
          // --- Batterie & PV ---
          BATTERY_CAPACITY_KWH: 8.64,        // Akkugröße in kWh (Nennkapazität)
          PV_FORECAST_SAFETY_FACTOR: 2.0,    
      
          MAX_CHARGE_W: 2400,                // Maximale Ladeleistung der Batterie
          MAX_DISCHARGE_W: 2400,             // Maximale Entladeleistung der Batterie
      
          // --- PI-Regler Parameter ---
          KP: 0.7,                           
          KI: 0.08,                          
          DEADBAND_W: 15,                    
          TARGET_W: 0,                       
          
          // Anti-Windup Limits
          INTEGRAL_MAX: 30000,               
          INTEGRAL_MIN: -30000,              
      
          // --- Zeit-Parameter ---
          REGEL_INTERVALL_MS: 2000,          // Intervall für die PI-Regelung (dt = 2.0)
          AC_MODE_COOLDOWN_MS: 5000,         
      };
      
      // --- 2. DATENPUNKTE (IDs) ---
      
      const IDs = {
          // --- Netz (Trigger) ---
          netz: "shelly.0.SHEM-3#8CAAB5619A05#1.Total.InstantPower", // Nur noch für Abfrage
      
          // --- Batterie (Zendure) ---
          acMode: "mqtt.2.Zendure.select.HOA1NPN3N210791.acMode",
          acModeSet: "mqtt.2.Zendure.select.HOA1NPN3N210791.acMode.set",
          currentInput: "mqtt.2.Zendure.number.HOA1NPN3N210791.inputLimit",
          inputSet: "mqtt.2.Zendure.number.HOA1NPN3N210791.inputLimit.set",
          currentOutput: "mqtt.2.Zendure.number.HOA1NPN3N210791.outputLimit",
          outputSet: "mqtt.2.Zendure.number.HOA1NPN3N210791.outputLimit.set",
          soc: "mqtt.2.Zendure.sensor.HOA1NPN3N210791.electricLevel",
      
          // --- Externe Steuerung ---
          evccModus: "0_userdata.0.zendure.EVCC_Modus",
          tibberLaden: "0_userdata.0.Tibber.01_Automatisierungs-Kanaele.Batterie_laden",
          
          // PV Prognose Restenergie des Tages
          pvForecastRest: "pvforecast.0.summary.energy.nowUntilEndOfDay"
      };
      
      const AC_MODES = {
          INPUT: "Input mode",
          OUTPUT: "Output mode"
      };
      
      // --- 3. GLOBALE VARIABLEN (Status) ---
      
      let integral = 0.0;                   
      let lastAcModeSwitch = 0;             
      
      // --- 4. HILFSFUNKTIONEN FÜR LOGGING ---
      
      function logInfo(message) {
          log(`[Info] ${message}`, 'info');
      }
      
      function logDebug(message) {
          if (CONFIG.DEBUG) {
              log(`[Debug] ${message}`, 'info');
          }
      }
      
      // --- 5. INITIALISIERUNG & TIMER ---
      
      function initialize() {
          logInfo("--- Batteriesteuerung Skript gestartet (v2.0) ---");
          logInfo(`Module: Tibber=${CONFIG.ENABLE_TIBBER}, EVCC=${CONFIG.ENABLE_EVCC}, PV-Forecast=${CONFIG.ENABLE_PV_FORECAST}`);
      
          integral = 0;
          lastAcModeSwitch = new Date().getTime(); 
      
          // Startet den PI-Regler-Loop im festgelegten Intervall
          setInterval(mainControlLoop, CONFIG.REGEL_INTERVALL_MS); 
          
          logInfo(`PI-Regelung läuft jetzt Timer-basiert alle ${CONFIG.REGEL_INTERVALL_MS}ms.`);
      
          // Führt initialen Check aus, falls Overrides schon aktiv sind
          checkOverridesAndAct(); 
      }
      
      // --- 6. TRIGGER & OVERRIDES ---
      
      // KEIN Trigger auf IDs.netz mehr.
      
      // Trigger werden nur registriert, wenn das Modul in der CONFIG aktiviert ist.
      if (CONFIG.ENABLE_EVCC) {
          on({ id: IDs.evccModus, change: "any" }, (obj) => {
              logInfo(`EVCC Modus geändert auf: ${obj.state.val}. Prüfe Override.`);
              checkOverridesAndAct();
          });
      }
      
      if (CONFIG.ENABLE_TIBBER) {
          on({ id: IDs.tibberLaden, change: "any" }, (obj) => {
              logInfo(`Tibber Modus geändert auf: ${obj.state.val}. Prüfe Override.`);
              checkOverridesAndAct();
          });
      }
      
      if (CONFIG.ENABLE_TIBBER && CONFIG.ENABLE_PV_FORECAST) {
          on({ id: IDs.pvForecastRest, change: "any" }, (obj) => {
              logDebug(`PV Prognose (Rest) geändert auf: ${obj.state.val} Wh. Prüfe Tibber-Logik.`);
              checkOverridesAndAct();
          });
      }
      
      /**
       * Überprüft alle Overrides (Tibber, EVCC). Führt bei Aktivität sofort eine 
       * Modusänderung durch und gibt 'true' zurück, wenn ein Override aktiv war.
       * @returns {boolean} - true, wenn ein Override aktiv war, sonst false.
       */
      function checkOverridesAndAct() {
          // --- 6.1. Externe Overrides prüfen (Tibber) ---
          if (CONFIG.ENABLE_TIBBER && getState(IDs.tibberLaden).val === true) {
              
              let chargeAllowed = false;
              
              if (isNight()) {
                  logInfo("Tibber-Laden aktiv (Nacht). Laden ERLAUBT.");
                  chargeAllowed = true;
              } else {
                  // PV-Forecast wird nur geprüft, wenn BEIDE Module aktiviert sind
                  if (CONFIG.ENABLE_PV_FORECAST) {
                      if (checkPvForecastAllowsDayChargeV1_4()) {
                          logInfo("PV-Restenergie UNZUREICHEND. Tibber-Laden am Tag ERLAUBT.");
                          chargeAllowed = true;
                      } else {
                          logInfo("PV-Restenergie AUSREICHEND. Laden am Tag BLOCKIERT (PV hat Priorität).");
                      }
                  } else {
                      // Falls PV-Forecast deaktiviert ist, gilt die Standardregel: Tibber am Tag blockiert.
                      logInfo("Tibber am Tag blockiert (PV-Forecast-Modul ist deaktiviert).");
                  }
              }
              
              if (chargeAllowed) {
                  forcePower(AC_MODES.INPUT, CONFIG.MAX_CHARGE_W);
                  integral = CONFIG.INTEGRAL_MIN; 
                  return true; // Override war aktiv
              }
          } 
      
          // --- 6.2. Externe Overrides prüfen (EVCC) ---
          if (CONFIG.ENABLE_EVCC) {
              const evccMode = getState(IDs.evccModus).val;
              if (evccMode === 2) {
                  logInfo("EVCC Modus 2: Entladen blockiert.");
                  forcePower(AC_MODES.OUTPUT, 0); 
                  integral = CONFIG.INTEGRAL_MAX; 
                  return true; // Override war aktiv
              } else if (evccMode === 3) {
                  logInfo("EVCC Modus 3: Laden erzwungen.");
                  forcePower(AC_MODES.INPUT, CONFIG.MAX_CHARGE_W);
                  integral = CONFIG.INTEGRAL_MIN; 
                  return true; // Override war aktiv
              }
          }
      
          return false; // Kein Override war aktiv
      }
      
      
      // --- 7. HAUPTREGELUNGSLOOP (Durch Timer getriggert) ---
      
      function mainControlLoop() {
          
          // Prüfen, ob ein Override aktiv ist.
          const overrideActive = checkOverridesAndAct(); 
          
          // Wenn ein Override aktiv war, bricht die Regelung hier ab.
          if (overrideActive) {
              return; 
          }
      
          // --- PI-REGELUNG (Nur wenn kein Override aktiv ist) ---
      
          // Feste Zeitschritt-Basis (dt = 2.0 Sekunden)
          const dt = CONFIG.REGEL_INTERVALL_MS / 1000.0; 
      
          const gridPower = getState(IDs.netz).val; 
          let error = CONFIG.TARGET_W - gridPower;
      
          // --- 7.1. Deadband ---
          if (Math.abs(gridPower) <= CONFIG.DEADBAND_W) {
              error = 0.0;
              logDebug(`Netzleistung [${gridPower.toFixed(0)}W] in Deadband. Fehler auf 0 gesetzt.`);
          }
      
          // --- 7.2. PI-Berechnung ---
          integral = integral + error * dt;
          // Anti-Windup
          integral = Math.max(CONFIG.INTEGRAL_MIN, Math.min(CONFIG.INTEGRAL_MAX, integral));
      
          const proportional = CONFIG.KP * error;
          const integralAnteil = CONFIG.KI * integral;
      
          let outputPower = proportional + integralAnteil;
      
          logDebug(`Regel-Loop: Netz=${gridPower.toFixed(0)}W | Fehler=${error.toFixed(0)} | P=${proportional.toFixed(1)} | I=${integralAnteil.toFixed(1)} | Integral=${integral.toFixed(1)} | Out(raw)=${outputPower.toFixed(0)}W`);
      
          
          // --- 7.3. Stellgröße auf Limits begrenzen (Clamping) ---
          if (outputPower > 0) { 
              outputPower = Math.min(outputPower, CONFIG.MAX_CHARGE_W);
          } else if (outputPower < 0) { 
              outputPower = Math.max(outputPower, -CONFIG.MAX_DISCHARGE_W);
          }
      
          // --- 7.4. Stellgröße an Batterie senden ---
          setBatteryPower(outputPower);
      }
      
      
      // --- 8. ZUSÄTZLICHE HELPER-FUNKTIONEN (Unverändert) ---
      
      function checkPvForecastAllowsDayChargeV1_4() {
          try {
              const socPercent = getState(IDs.soc).val; 
              const forecastRestWh = getState(IDs.pvForecastRest).val; 
              
              const missingCapacityKWh = CONFIG.BATTERY_CAPACITY_KWH * (100 - socPercent) / 100.0;
              const forecastRestKWh = forecastRestWh / 1000.0;
      
              const thresholdKWh = missingCapacityKWh * CONFIG.PV_FORECAST_SAFETY_FACTOR;
      
              logDebug(`PV-Check (Tag/Tibber): SOC=${socPercent}% | Ladebedarf=${missingCapacityKWh.toFixed(2)} kWh | PV-Rest=${forecastRestKWh.toFixed(2)} kWh | Schwelle=${thresholdKWh.toFixed(2)} kWh`);
      
              if (forecastRestKWh < thresholdKWh) {
                  return true;
              } else {
                  return false;
              }
      
          } catch (e) {
              logInfo("Fehler beim Lesen des SOC oder PV-Forecast-Datenpunkts. Tibber-Laden am Tag wird sicherheitshalber blockiert (PV-Priorität).");
              return false;
          }
      }
      
      function setBatteryPower(power) {
          power = Math.round(power); 
      
          const currentAcMode = getState(IDs.acMode).val;
          let targetAcMode = AC_MODES.OUTPUT; 
          let targetPowerValue = Math.abs(power);
      
          if (power > 0) { 
              targetAcMode = AC_MODES.INPUT;
              targetPowerValue = power;
          }
      
          if (currentAcMode !== targetAcMode) {
              const now = new Date().getTime();
              if (now - lastAcModeSwitch < CONFIG.AC_MODE_COOLDOWN_MS) {
                  // V1.8 BUGFIX: Modus-Wechsel blockiert -> Setze aktuellen Modus auf 0W (sicherer Stillstand)
                  if (currentAcMode === AC_MODES.INPUT) {
                      setState(IDs.inputSet, "0", false); 
                  } else { // AC_MODES.OUTPUT
                      setState(IDs.outputSet, "0", false); 
                  }
                  logDebug(`AC-Modus-Wechsel zu [${targetAcMode}] blockiert (Cooldown). Leistung des aktuellen Modus auf 0W gesetzt.`);
                  return; 
              }
      
              // --- Wechsel wird durchgeführt ---
              logInfo(`=== AC-Modus-Wechsel: [${currentAcMode}] -> [${targetAcMode}] ===`);
              lastAcModeSwitch = now;
      
              setState(IDs.acModeSet, targetAcMode, false);
      
              if (targetAcMode === AC_MODES.INPUT) {
                  setState(IDs.outputSet, "0", false); 
                  setState(IDs.inputSet, String(targetPowerValue), false); 
                  logDebug(`Setze Input: ${targetPowerValue}W, Output: 0W`);
              } else { // AC_MODES.OUTPUT
                  setState(IDs.inputSet, "0", false); 
                  setState(IDs.outputSet, String(targetPowerValue), false); 
                  logDebug(`Setze Input: 0W, Output: ${targetPowerValue}W`);
              }
          } else {
              // --- Modus ist korrekt, nur Leistung aktualisieren ---
              if (targetAcMode === AC_MODES.INPUT) {
                  if (getState(IDs.currentInput).val !== targetPowerValue) {
                      setState(IDs.inputSet, String(targetPowerValue), false);
                      logDebug(`Update Input: ${targetPowerValue}W`);
                  }
              } else { // AC_MODES.OUTPUT
                  if (getState(IDs.currentOutput).val !== targetPowerValue) {
                      setState(IDs.outputSet, String(targetPowerValue), false);
                      logDebug(`Update Output: ${targetPowerValue}W`);
                  }
              }
          }
      }
      
      function forcePower(mode, power) {
          power = Math.round(power);
          const powerStr = String(power);
          
          logDebug(`Force Mode: [${mode}]`);
          setState(IDs.acModeSet, mode, false);
          lastAcModeSwitch = new Date().getTime(); 
      
          if (mode === AC_MODES.INPUT) {
              setState(IDs.outputSet, "0", false);
              setState(IDs.inputSet, powerStr, false);
              logDebug(`Force Set Input: ${powerStr}W, Output: 0W`);
          } else { // AC_MODES.OUTPUT
              setState(IDs.inputSet, "0", false);
              setState(IDs.outputSet, powerStr, false);
              logDebug(`Force Set Input: 0W, Output: ${powerStr}W`);
          }
      }
      
      function isNight() {
          try {
              const now = new Date();
              const sunrise = getAstroDate('sunrise');
              const sunset = getAstroDate('sunset');
      
              if (!sunrise || !sunset) {
                   logInfo("Astro-Daten (sunrise/sunset) nicht verfügbar. Prüfen Sie die Javascript-Instanz-Einstellungen.");
                   return false; 
              }
      
              if (now > sunset || now < sunrise) {
                  return true; 
              }
              return false; 
          } catch (e) {
              logInfo("Astro-Funktion 'getAstroDate' nicht verfügbar. Prüfen Sie die Javascript-Instanz-Einstellungen.");
              return false; 
          }
      }
      
      // --- Skriptstart ---
      initialize();
      

      Ich hoffe es hilft den einem oder anderen weiter...
      Lässt sich auch gut mit dem Skript von @maxclaudi kombinieren (um Sicherheit wegen Smartmode zu haben)
      https://forum.iobroker.net/topic/82263/zendure-smartmode-1-solarflow2400-ac-solarflow800-u-pro/150

      falls ich noch was optimiere oder Bugs finde, werde ich das hier im ersten Post, ändern

      L 1 Reply Last reply Reply Quote 1
      • L
        lesiflo Most Active @Schimi last edited by

        @Schimi: Du solltest bei Entladen aus dem Akku noch mit berücksichtigen, ob du viel mit PV oder Netz geladen hast. Wenn viel mit Netz sollte der Entladepreis mindestens 20% über deinem Ladepreis liegen. Soweit ich das sehe hast du das noch nicht mit drin. Oder wie wird das Entladen geregelt?

        S 1 Reply Last reply Reply Quote 1
        • S
          Schimi @lesiflo last edited by

          @lesiflo das stimmt, das wird über Tibber berücksichtigt und man kann es dort direkt konfigurieren... (bei mir z.b. muss sogar 25% Differenz sein)...

          der Hintergedanke war, das die meisten die einen flexiblen Stromtarif haben, irgendwie sowas selber berechnen (kann der tibberlink Adapter direkt).
          Will das Script nicht übertrieben aufblähen...

          Danke für deinen einwand 👍🏼

          1 Reply Last reply Reply Quote 0
          • S
            Schimi last edited by Schimi

            update

            // v1.9 - 01.11.2025
            // - OPTIMIERUNG: PI-Regelung ist nun Timer-basiert (alle 2000ms), um eine fixe
            // Integrationszeit (dt) und damit eine höhere Stabilität zu gewährleisten.
            // - VERBESSERUNG: Trennung der Log-Funktionen in logInfo (wichtig, immer an)
            // und logDebug (detailliert, ausschaltbar).
            // - NEU: Trigger auf Netzleistung entfernt. Die Regelung erfolgt nur noch über den Timer.*

            1 Reply Last reply Reply Quote 0
            • S
              Schimi last edited by

              // v2.0 - 02.11.2025
              // - ANPASSUNG: Die Steuerung von Tibber, EVCC und PV-Forecast erfolgt nun
              // ausschließlich über die internen "CONFIG" Variablen (ENABLE_TIBBER, etc.).
              // - ENTFERNT: Es werden keine externen Datenpunkte mehr zur Aktivierung/Deaktivierung
              // der Module benötigt oder abgefragt.
              // - Check: Timer-basierte Regelung (V1.9) bleibt erhalten.
              //------------------------------------------------------------

              1 Reply Last reply Reply Quote 0
              • M
                Mabbi last edited by Mabbi

                Hi,

                cooles java script, danke fürs bauen

                Ich habe mal angefangen, Dein Javascript für Nerds wie mich in Blockly zu bauen:
                bb0a3dd6-18cb-4f6e-ba61-fc94a2e9d4cc-grafik.png

                Allerdings werde ich in meiner Version EVCC und Tibber weglassen, dafür wird Sie mit 2x Zendure AC2400 im Wechseltakt arbeiten. Entweder regel ich dann hoffentlich insgesamt schneller oder schone die Hardware etwas...wir werden sehen.

                1 Reply Last reply Reply Quote 1
                • M
                  Mabbi last edited by Mabbi

                  Habe fertig...alles nun schön in Funktionen gepackt (bis auf die Presets der Konstanten/Globals):

                  29a817e2-c3fc-4d46-b636-664fb9e805e6-grafik.png

                  Ein bisschen stolz bin ich auf das hier:

                  d2452022-d588-4892-9580-745ae3ea0a22-grafik.png

                  im Zusammenspiel mit dem hier (Beispiel):

                  2e7ebbdc-485c-4d56-8c09-6aebe6ad0882-grafik.png

                  Volle Flexibilität bei den Datenpunkten (werden aus Bausteinen je nach Akku_Nr zusammengebaut und um die Object-Subfolder, Zielobjekte und evtl '.SET' (je nachdem ob man liest oder schreibt) erstellt.

                  So ist da hinzufügen eines weiteren Akkus einfach nur die Seriennummer und die MQTT.X Nummer in die Variable einzutragen und schon funzt es(hoffentlich).

                  Ist noch ein bisschen rough, muss noch 'sonst falls' bei der Akku-Ansteuerung bekommen, die Variaben für den 3. Akku fehlen noch und die Object_ID Funktion werde ich noch mit einem Rückgabewert versehen, aber das Prinzip wird glaube ich schon ersichtlich.

                  Heute leider keine Zeit mehr zum Testen... 😞

                  1 Reply Last reply Reply Quote 1
                  • S
                    Schimi last edited by Schimi

                    cool!!

                    Ich könnte (wenn bedarf besteht) das JavaScript auch auf "mehrere Geräte" umbauen...
                    Das müsste aber einer testen oder mir min. ein Gerät spenden 😉

                    edit
                    Ich glaube interessant wäre es auch wenn du das als Code zum importieren anbietest

                    M 1 Reply Last reply Reply Quote 0
                    • M
                      Mabbi @Schimi last edited by Mabbi

                      Kleine aber sinnvolle Fortschritte:

                      @Schimi:
                      Ich habe mich von Deinem Integral getrennt 😞

                      Was aktuell im Blockly funktioniert:
                      Beide Zendure AC2400 takten und steuern im Wechsel
                      Hat mir viel Kopfzerbrechen gemacht die beiden Regelungen sinnvoll vom Aufschauckeln abzuhalten
                      76d8e8c5-0a3f-4f06-bf3a-175ef9df7e4a-grafik.png
                      bis hin zu einer lädt und der andere speist ein...
                      a37167b5-a751-4bf5-ba43-d89896f13d39-grafik.png

                      Das ist beides gelöst und ich habe nun ein sinnvolles Leistungs-Synchronisation (Loadbalancing) zwischen den beiden:
                      68a3a5d0-d042-47eb-b146-c6dc9be8c6e9-grafik.png

                      Sieht doch schon besser aus 🙂

                      • Es gibt nun einen Nachtmodus (Sonnenuntergang bis Sonnenaufgang) der beide Zendure strikt im Output-Modus festhält, ich nutze ja kein Tibber o.ä.

                      • SOC Balancing zwischen den beiden Akkus
                        Erstaunlicherweise Laden und Entladen die beiden nicht wirklich parallel (beide Akkus liefen da noch synchron in der Ansteuerung ohne Wechseltaktung):
                        4b1f3b41-15cb-47ac-911c-ca597a6a01c9-grafik.png

                      Vielleicht ist SOC gar nicht so wichtig bei diesem Akkutyp, der blaue und der lila Graph sind die SOC-Werte.
                      Vielleicht laden und entladen die auch unterschiedlich, weil der eine aktuell im Technikraum und der andere bei mir im Büro steht... ergo unterschiedliche Temperaturn in der Nacht (wir reden hier von gerade mal 20° zu 16° Grad Unterschied) ?

                      Aktuell steure ich die Akkus beim einem SOC Unterschied von mehr als 5% gezielter an um das auszugleichen.
                      Bin aber nicht sicher, ob ich den Part behalten werde.

                      • Eine indirekte Unterstützung für meine Wallbox ist integriert.
                        Es gibt ein prozentuales Prio-System, bei gleicher Priorität zwischen Haus-Akku und EV 'sieht' die WB einen Teil der Akku-Ladeleistung als zus. virtuellen PV-Überschuss. Damit wird die WB früher motiviert das EV zu laden.
                        Über einem bestimmten SOC halten die Akkus die Wallbox virtuell (ja. hier kann es zu kurzem geringen Netzbezug kommen weil die Akkus nicht schnell genug schalten auf Entladen) am Leben. Funktioniert noch nicht ganz optimal, aktuell steuert meine go-E nur alle 90 Sekunden per Adapter. Und für genau den Adapter erzeuge ich eine teilweise gefakete PV-Einspeisungs-Leistungswerte.
                        Funktioniert aber schon ganz gut, hier war der Haus-Akku etwas höher in der Prio und hat der WB immer mehr Leistung geklaut, als der Akku fast voll war, bekam die WB wieder mehr Leistung freigeschaltet:
                        41525309-a0e2-4953-838d-2471ad154309-grafik.png
                        Lila oben ist die WB, grün unten die Ladeleistung beider Akkus kombiniert, man kann sogar die kurzen Einspeisungpeaks sehen, als die WB von 1- auf 3-phaisg geschaltet hat und ca. 20 Minuten später wieder zurück wegen insgesamt sinkendem Solarertag.

                      Und auch wenn die roten Netzbezugs-Peaks (ich nutze da MAX-Werte) im oberen Diagramm wild aussehen, das Haus hat heute insgesamt laut Smartmeter gerade mal 560 Wh verbraucht. Und das obwohl ich von 29,3 KWh Produktion nur 3,39KWh eingespeist habe, alles andere ist in Wärme, Haus-Akku für die Nacht und EV geflossen.

                      Langsam bekommt es Hand und Fuß.
                      Ich muss noch etwas an den scripten feilen und testen, dann würde ich die hier auch zu Verfügung stellen, solange @Schimi damit grün ist.

                      Und nun der Wehrmutstropfen am Schluss:
                      Wenn ich die ZendureAC2400 einzeln schneller als 14 Sekunden in der Ansteuerung takte, dann sieht man zwar die mqtt Änderung in den SELECT/xxx-Limit Werten wie diese vom SET übernommen werden im ca. 1 Sekundentakt, die Werte im Sensor/ gridinput/homeoutput power frieren aber ein und mein Smartmeter bestätigt das auch.

                      Ich komme einfach nicht dahinter, warum beide Zendure AC2400 sich bei mir so verhalten... 😞

                      1 Reply Last reply Reply Quote 0
                      • First post
                        Last post

                      Support us

                      ioBroker
                      Community Adapters
                      Donate

                      996
                      Online

                      32.4k
                      Users

                      81.2k
                      Topics

                      1.3m
                      Posts

                      3
                      9
                      125
                      Loading More Posts
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes
                      Reply
                      • Reply as topic
                      Log in to reply
                      Community
                      Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                      The ioBroker Community 2014-2023
                      logo