Skip to content
  • Recent
  • Tags
  • 0 Unread 0
  • Categories
  • Unreplied
  • Popular
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Logo
  1. ioBroker Community Home
  2. Deutsch
  3. Skripten / Logik
  4. JavaScript
  5. ecoflow-connector-Script zur dynamischen Leistungsanpassung

NEWS

  • Wartung am 15.11. – Forum ab 22:00 Uhr nicht erreichbar
    BluefoxB
    Bluefox
    11
    2
    209

  • UPDATE 31.10.: Amazon Alexa - ioBroker Skill läuft aus ?
    apollon77A
    apollon77
    48
    3
    7.9k

  • Monatsrückblick – September 2025
    BluefoxB
    Bluefox
    13
    1
    1.7k

ecoflow-connector-Script zur dynamischen Leistungsanpassung

ecoflow-connector-Script zur dynamischen Leistungsanpassung

Scheduled Pinned Locked Moved JavaScript
1.6k Posts 127 Posters 741.2k Views 127 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    resilient
    wrote on last edited by
    #566

    Gestern Abend ist mir was aufgefallen, das eventuell noch ein Bug sein könnte. Der erste PS mit Speicher war leer und der 2. hatte noch 60% aber das Script wollte/konnte
    dem 2. PS die angeforderte Leistung nicht zuweisen er wollte immer den ersten bei dem die Batterie bereits leer war. Half nur das script zu stoppen und es manuell über die app zu machen.
    Aber ansonsten läuft die Regelung ziemlich gut auch bei Echtzeit-Regelung.

    1 Reply Last reply
    0
    • P Ponti92

      @kaiausbrieselang ja das geht auch über

      *.data.InverterHeartbeat.batSoc
      
      K Offline
      K Offline
      kaiausBrieselang
      wrote on last edited by
      #567

      @ponti92
      wieder was gelernt 🙂
      Danke dir!!

      1 Reply Last reply
      0
      • S Offline
        S Offline
        sirdir
        wrote on last edited by sirdir
        #568

        Hm, das neue Script funktioniert für mich nicht. Es regelt überhaupt nichts. Der Debug Modus gibt leider auch keine sinnvollen Meldungen mehr aus sondern im Prinzip nur MQTT geschnatter. Disregard, beim cut&paste ist bei der Smartmeter ID was schief gegangen.

        1 Reply Last reply
        0
        • umeleU Offline
          umeleU Offline
          umele
          wrote on last edited by
          #569

          Hallo zusammen,

          Ich habe mal für mich selber zusätzlich zum Script mit Blockly was entworfen, was mir erlaubt, den täglichen Strombezug vom Netz zu monitoren.
          blockly Strombezug.png

          Die dafür nötigen Objekte habe ich manuell erstellt:
          neue Objekte.png

          Falls das interessant erscheint - vielleicht mag ja jemand das ins Script integrieren?

          1 Reply Last reply
          0
          • umeleU Offline
            umeleU Offline
            umele
            wrote on last edited by umele
            #570

            Hallo zusammen,

            Das Script läuft bei mir inzwischen reibungslos - vielen Dank @Waly_de für die super Arbeit!

            Ich möchte "lowBatLimitPozOn" von der Wettervorhersage abhängig machen.
            Wenn der kommende Tag sonnig wird, dann soll lowBatLimitPozOn = 10 sein, sonst lowBatLimitPozOn = 30 (möchte genügend Reserve für Stromausfälle behalten).
            Die Wettervorhersage bekomme ich vom Adapter "DasWetter". Über die Objekte

            • daswetter.0.NextDays.Location_1.Day_1.Wetter_Symbol_id

            und

            • daswetter.0.NextDays.Location_1.Day_1.Wetter_Symbol_id2

            kommt die Info, ob Vormittag, bzw. Nachmittag sonnig werden.

            Darauf basierend habe ich ein Objekt ("AkkuReserve") erstellt, das den gewünschten Wert für lowBatLimitPozOn enthält.

            "AkkuReserve" soll an lowBatLimitPozOn übergeben werden.

            Leider kann ich wirklich kein JavaScript...
            Kann mir bitte jemand dabei helfen?
            7535bac0-4d05-422e-a372-1de59c654df7-image.png

            Vielen Dank!

            W 1 Reply Last reply
            0
            • umeleU umele

              Hallo zusammen,

              Das Script läuft bei mir inzwischen reibungslos - vielen Dank @Waly_de für die super Arbeit!

              Ich möchte "lowBatLimitPozOn" von der Wettervorhersage abhängig machen.
              Wenn der kommende Tag sonnig wird, dann soll lowBatLimitPozOn = 10 sein, sonst lowBatLimitPozOn = 30 (möchte genügend Reserve für Stromausfälle behalten).
              Die Wettervorhersage bekomme ich vom Adapter "DasWetter". Über die Objekte

              • daswetter.0.NextDays.Location_1.Day_1.Wetter_Symbol_id

              und

              • daswetter.0.NextDays.Location_1.Day_1.Wetter_Symbol_id2

              kommt die Info, ob Vormittag, bzw. Nachmittag sonnig werden.

              Darauf basierend habe ich ein Objekt ("AkkuReserve") erstellt, das den gewünschten Wert für lowBatLimitPozOn enthält.

              "AkkuReserve" soll an lowBatLimitPozOn übergeben werden.

              Leider kann ich wirklich kein JavaScript...
              Kann mir bitte jemand dabei helfen?
              7535bac0-4d05-422e-a372-1de59c654df7-image.png

              Vielen Dank!

              W Offline
              W Offline
              Waly_de
              wrote on last edited by
              #571

              @umele hehe das ist eine tolle Idee 👍😊

              Vorschlag: wenn du schon ein Objekt selbst anlegst, dann scheib doch da den gewünschten wert für dein Limit rein, und wir ersetzen die entsprechende Variable im Script mit diesem Object…

              umeleU 1 Reply Last reply
              0
              • W Waly_de

                @umele hehe das ist eine tolle Idee 👍😊

                Vorschlag: wenn du schon ein Objekt selbst anlegst, dann scheib doch da den gewünschten wert für dein Limit rein, und wir ersetzen die entsprechende Variable im Script mit diesem Object…

                umeleU Offline
                umeleU Offline
                umele
                wrote on last edited by
                #572

                @waly_de - bist ein Schatz 🙂

                Ich habe es für mich jetzt erst mal so probiert - hoffe, damit zerschiesse ich mir das Script nicht:

                59c8603e-858d-41b1-a3bf-417a2e9e9b7f-image.png

                W 1 Reply Last reply
                0
                • umeleU umele

                  @waly_de - bist ein Schatz 🙂

                  Ich habe es für mich jetzt erst mal so probiert - hoffe, damit zerschiesse ich mir das Script nicht:

                  59c8603e-858d-41b1-a3bf-417a2e9e9b7f-image.png

                  W Offline
                  W Offline
                  Waly_de
                  wrote on last edited by
                  #573

                  @umele das könnte gehen, allerdings greift das nur beim starten des Scripts und nicht während der Laufzeit.

                  Ich hab mir dazu was flexibles überlegt, das ich auch in die nächste Version fest einbaue.
                  Damit kann man das easy für jeden Punkt der Config machen und es ist auch während der Laufzeit alles änderbar:

                  Füge das hier unmittelbar nach der "ConfigData" definition ein:

                  //  EXTERNE STATES zum Manipulieren von Configurationsvariablen 
                  var externConfig = [
                      //############# Diesen Abschnitt für jeden einzelne Wert anlegen ################
                      {
                          VarName: "seriennummern[0].lowBatLimitPozOn",       //Variabelname aus "ConfigData" bei Aufzählungen [0...X] in der Reigenfolge der Angaben 
                          id: "0_userdata.0.ecoflow.ExStateTest"              //Das Objekt (State) das den Wert für diese variable enthalten soll 
                      },
                      //#######################################################################
                  ];
                  //#######################################################################
                  
                  // Funktion zum Setzen einer verschachtelten Eigenschaft in einem Objekt
                  function setNestedProperty(obj, path, value) {
                      let keys = path.split('.');
                      let lastKey = keys.pop();
                      let tempObj = obj;
                  
                      keys.forEach(key => {
                          if (key.match(/\[\d+\]/)) {
                              let index = parseInt(key.match(/\[(\d+)\]/)[1]);
                              key = key.split('[')[0];
                              tempObj = tempObj[key][index];
                          } else {
                              tempObj = tempObj[key];
                          }
                      });
                  
                      tempObj[lastKey] = value;
                  }
                  
                  function setConfigValueFromId(VarName, id) {
                      if (isState2(id)) {
                          let value = getState(id).val;  // Wert von ioBroker abrufen
                          setNestedProperty(ConfigData, VarName, value);  // Wert in ConfigData setzen
                      }
                  }
                  
                  // Initialisierung bei Programmstart
                  externConfig.forEach(config => {
                      setConfigValueFromId(config.VarName, config.id);
                  });
                  
                  // Änderungen während der Laufzeit überwachen
                  externConfig.forEach(config => {
                      if (isState2(config.id)) {
                          on(config.id, function (obj) {
                              setConfigValueFromId(config.VarName, obj.id);
                              //log("ExternesEvent:" + obj.id + " : " + config.VarName + ":" + obj.state.val)
                          });
                      }
                  });
                  //#######################################################################
                  
                  

                  solle sich selbst erklären 😉

                  umeleU 2 Replies Last reply
                  0
                  • W Waly_de

                    @umele das könnte gehen, allerdings greift das nur beim starten des Scripts und nicht während der Laufzeit.

                    Ich hab mir dazu was flexibles überlegt, das ich auch in die nächste Version fest einbaue.
                    Damit kann man das easy für jeden Punkt der Config machen und es ist auch während der Laufzeit alles änderbar:

                    Füge das hier unmittelbar nach der "ConfigData" definition ein:

                    //  EXTERNE STATES zum Manipulieren von Configurationsvariablen 
                    var externConfig = [
                        //############# Diesen Abschnitt für jeden einzelne Wert anlegen ################
                        {
                            VarName: "seriennummern[0].lowBatLimitPozOn",       //Variabelname aus "ConfigData" bei Aufzählungen [0...X] in der Reigenfolge der Angaben 
                            id: "0_userdata.0.ecoflow.ExStateTest"              //Das Objekt (State) das den Wert für diese variable enthalten soll 
                        },
                        //#######################################################################
                    ];
                    //#######################################################################
                    
                    // Funktion zum Setzen einer verschachtelten Eigenschaft in einem Objekt
                    function setNestedProperty(obj, path, value) {
                        let keys = path.split('.');
                        let lastKey = keys.pop();
                        let tempObj = obj;
                    
                        keys.forEach(key => {
                            if (key.match(/\[\d+\]/)) {
                                let index = parseInt(key.match(/\[(\d+)\]/)[1]);
                                key = key.split('[')[0];
                                tempObj = tempObj[key][index];
                            } else {
                                tempObj = tempObj[key];
                            }
                        });
                    
                        tempObj[lastKey] = value;
                    }
                    
                    function setConfigValueFromId(VarName, id) {
                        if (isState2(id)) {
                            let value = getState(id).val;  // Wert von ioBroker abrufen
                            setNestedProperty(ConfigData, VarName, value);  // Wert in ConfigData setzen
                        }
                    }
                    
                    // Initialisierung bei Programmstart
                    externConfig.forEach(config => {
                        setConfigValueFromId(config.VarName, config.id);
                    });
                    
                    // Änderungen während der Laufzeit überwachen
                    externConfig.forEach(config => {
                        if (isState2(config.id)) {
                            on(config.id, function (obj) {
                                setConfigValueFromId(config.VarName, obj.id);
                                //log("ExternesEvent:" + obj.id + " : " + config.VarName + ":" + obj.state.val)
                            });
                        }
                    });
                    //#######################################################################
                    
                    

                    solle sich selbst erklären 😉

                    umeleU Offline
                    umeleU Offline
                    umele
                    wrote on last edited by
                    #574

                    @waly_de - super Danke!! 😊 😊 👍 👍

                    1 Reply Last reply
                    0
                    • W Waly_de

                      @umele das könnte gehen, allerdings greift das nur beim starten des Scripts und nicht während der Laufzeit.

                      Ich hab mir dazu was flexibles überlegt, das ich auch in die nächste Version fest einbaue.
                      Damit kann man das easy für jeden Punkt der Config machen und es ist auch während der Laufzeit alles änderbar:

                      Füge das hier unmittelbar nach der "ConfigData" definition ein:

                      //  EXTERNE STATES zum Manipulieren von Configurationsvariablen 
                      var externConfig = [
                          //############# Diesen Abschnitt für jeden einzelne Wert anlegen ################
                          {
                              VarName: "seriennummern[0].lowBatLimitPozOn",       //Variabelname aus "ConfigData" bei Aufzählungen [0...X] in der Reigenfolge der Angaben 
                              id: "0_userdata.0.ecoflow.ExStateTest"              //Das Objekt (State) das den Wert für diese variable enthalten soll 
                          },
                          //#######################################################################
                      ];
                      //#######################################################################
                      
                      // Funktion zum Setzen einer verschachtelten Eigenschaft in einem Objekt
                      function setNestedProperty(obj, path, value) {
                          let keys = path.split('.');
                          let lastKey = keys.pop();
                          let tempObj = obj;
                      
                          keys.forEach(key => {
                              if (key.match(/\[\d+\]/)) {
                                  let index = parseInt(key.match(/\[(\d+)\]/)[1]);
                                  key = key.split('[')[0];
                                  tempObj = tempObj[key][index];
                              } else {
                                  tempObj = tempObj[key];
                              }
                          });
                      
                          tempObj[lastKey] = value;
                      }
                      
                      function setConfigValueFromId(VarName, id) {
                          if (isState2(id)) {
                              let value = getState(id).val;  // Wert von ioBroker abrufen
                              setNestedProperty(ConfigData, VarName, value);  // Wert in ConfigData setzen
                          }
                      }
                      
                      // Initialisierung bei Programmstart
                      externConfig.forEach(config => {
                          setConfigValueFromId(config.VarName, config.id);
                      });
                      
                      // Änderungen während der Laufzeit überwachen
                      externConfig.forEach(config => {
                          if (isState2(config.id)) {
                              on(config.id, function (obj) {
                                  setConfigValueFromId(config.VarName, obj.id);
                                  //log("ExternesEvent:" + obj.id + " : " + config.VarName + ":" + obj.state.val)
                              });
                          }
                      });
                      //#######################################################################
                      
                      

                      solle sich selbst erklären 😉

                      umeleU Offline
                      umeleU Offline
                      umele
                      wrote on last edited by umele
                      #575

                      @waly_de - gerade getestet. Bekomme diese Fehler:
                      95c9f581-6368-4ac9-90e4-032f6a02e043-image.png

                      Weil mein Objekt eine andere ID hat, habe ich die für den Test im Script angepasst:
                      9faaa1f3-0ceb-48b1-a25e-b535b86054b4-image.png

                      In Zeile 282 und 283 steht das hier:
                      6b4ad1f8-ddef-45a0-ac6f-a44a841c8838-image.png

                      Zeile 2513 gibt es gar nicht:
                      7e532ff0-f540-4923-9762-ada27f1fcfdd-image.png

                      W 1 Reply Last reply
                      0
                      • umeleU umele

                        @waly_de - gerade getestet. Bekomme diese Fehler:
                        95c9f581-6368-4ac9-90e4-032f6a02e043-image.png

                        Weil mein Objekt eine andere ID hat, habe ich die für den Test im Script angepasst:
                        9faaa1f3-0ceb-48b1-a25e-b535b86054b4-image.png

                        In Zeile 282 und 283 steht das hier:
                        6b4ad1f8-ddef-45a0-ac6f-a44a841c8838-image.png

                        Zeile 2513 gibt es gar nicht:
                        7e532ff0-f540-4923-9762-ada27f1fcfdd-image.png

                        W Offline
                        W Offline
                        Waly_de
                        wrote on last edited by
                        #576

                        @umele hmmm guck noch mal, ob du es an der richtigen Stelle eingefügt hast. Es muss hinter der. Letzten }; der ConfigData Definition eingesetzt werden

                        umeleU 1 Reply Last reply
                        0
                        • W Waly_de

                          @umele hmmm guck noch mal, ob du es an der richtigen Stelle eingefügt hast. Es muss hinter der. Letzten }; der ConfigData Definition eingesetzt werden

                          umeleU Offline
                          umeleU Offline
                          umele
                          wrote on last edited by umele
                          #577

                          Hab ich - hier ist der Code bis zum Ende des neuen Codes von config-date bis zum Ende des neuen Codes:

                          var ConfigData = {
                              email: "xxxxxx@gmail.com",                             // Die App-Zugangsdaten von ecoFlow
                              passwort: "yyyyyyyyyy",
                              SmartmeterID: "sonoff.0.Stromzaehler.SENSOR.E320.Power_in",     // State, der den aktuellen Gesamtverbrauch in Watt anzeigt
                              seriennummern: [
                                  //############# Diesen Abschnitt für jedes einzelne Gerät anlegen ################
                                  {
                                      seriennummer: "HWxxxxxxxxxx",              // Die Seriennummer des Gerätes
                                      name: "PowerStream",                        // beliebiger Namen
                                      MaxPower: 600,                              // Der höchstmögliche Wert in Watt für die Einspeiseleistung
                                      subscribe: true,                            // "true": Alle Daten für dieses Gerät werden angefragt. "false": Es werden keine Statusdaten abgefragt
                                      typ: "PS",                                  // Welches Gerät ist es: Powerstrem:"PS"; DeltaMax:"DM"; Delta2: "D2" ; Delta2 Max: "D2M"; SmartPlug: "SM"; Andere: "NA" 
                                      // Parameter an hier nur für PowerStream.     
                                      regulation: true,                           // "true": Dieser PowerStream soll vom Script reguliert werden
                                      RegulationOffPower: -1,                     // Wird die Regulation per State abgestellt, wird die Einspeiseleistung des ersten Powerstreams auf diesen Wert gesetzt (-1 = keine Änderung, -2 = Batterie Priomodus)
                                      hasBat: true,                               // "true": Eine Batterie ist angeschlossen. Nur für PowerStream relevant.
                                      battPozOn: 99, battPozOff: 96,              // Wenn die Batterie bei battPozOn ist, Einspeisung auf MaxPower. Bei BattPozOff Normalbetrieb
                                      battOnSwitchPrio: true,                    // "true": Bei battPozOn wird in den Batterie-Prioritätsmodus gewechselt
                                      prioOffOnDemand: 30,                        // Wattwert des Bedarfs, bei dem zurück in den Strom-Priomodus gechaltet wird. 0 für kein Rückschalten.   
                                      lowBatLimitPozOn: 30, lowBatLimitPozOff: 35,// Bei Unterschreiten der Batterieladung von "lowBatLimitPozOn" % ist die maximale Einspeiseleistung auf 
                                      lowBatLimit: 0,                           // "lowBatLimit" limitiert, bis der Ladezustand wieder bei "lowBatLimitPozOff" ist
                                  },
                                  //#######################################################################
                                  {
                                      seriennummer: "DCExxxxx",
                                      name: "DELTA Pro",
                                      typ: "NA",
                                      subscribe: false,                            // "true": Alle Daten für dieses Gerät werden angefragt. "false": Es werden keine Statusdaten abgefragt
                                  },
                                  //#######################################################################
                                  {
                                      seriennummer: "XXXXXXXXXXXXX",
                                      name: "SmartPlug 1",
                                      typ: "SM",
                                      subscribe: true,                            // "true": Alle Daten für dieses Gerät werden angefragt. "false": Es werden keine Statusdaten abgefragt
                                  },
                                  //#######################################################################
                              ],
                              AdditionalPower: [                                     // Wenn es weitere Wechselrichter gibt, die in IOBroker erfasst werden, können diese hier Angelegt werden
                                  //############# Diesen Abschnitt für jedes einzelne Gerät anlegen ################
                                  {
                                      name: "Hoymiles2000",                       // Beliebiger Name
                                      id: "mqtt.0.solar.1234567890.0.power"       // Der Objektpfad zu dem Leistungswert in Watt (W)
                                  },
                                  //#######################################################################
                              ],
                              //****************************************
                              // Erweiterte Einstellungen:
                              //****************************************
                              SmartmeterTimeoutMin: 4,                            // Wenn der letzte Wert vom Smartmeter älter als "SmartmeterTimeoutMin" ist, wird das Script mit...
                              SmartmeterFallbackPower: 150,                       // SmartmeterFallbackPower als aktuellem Realpowerwert weiter arbeiten, bis wieder aktuelle Daten geliefert werden. 
                              Regulation: true,                                   // 'false' stellt das Setzen der Einspeiseleistung ab 
                              RegulationState: "Regulate",                        // Wenn angegeben, kann mit diesem State die Regulation ein- und ausgeschaltet werden (Wird automatisch unter 0_userdata.0.ecoflow angelegt)
                              RegulationMultiPsMode: 0,                           // Wenn mehrere PS reguliert werden sollen. "balance" = 0 oder "serial" = 1
                              BasePowerOffset: 20,                                // Wird vom aktuellen Verbrauch abgezogen, um die Einspeiseleistung zu berechnen 
                              Zusatzpower_Offset: 10,                             // Zusatzpower startet ab einer Batterieladeleistung von MaxPower - Zusatzpower_Offset
                              MinValueMin: 1,                                     // Der Zeitraum in Minuten, aus dem der niedrigste Gesamtverbrauchswert geholt werden soll. 0 für Echtzeitwert
                              MinValueAg: 0,                                      // Art der Ermittlung des kleinsten Wertes: 0 = Minimalwert, 1 = Durchschnittswert
                              ReconnectMin: 30,                                   // Zeit in Minuten, nach der die Anwendung neu gestartet wird, wenn keine neuen Daten eintreffen
                              statesPrefix: "0_userdata.0.ecoflow",               // Hier werden die ecoFlow States angelegt
                              latitude: latitude,                                 // Breitengrad des Standortes (wird automatisch eingesetzt)
                              longitude: longitude,                               // Längengrad des Standortes (wird automatisch eingesetzt)
                              //****************************************
                              // Überschuss Ladung:
                              //****************************************
                              ExcessCharge: false,                                //
                              ExcessChargePowerID: "0_userdata.0.ecoflow.app_xxxxxxxxxxxxxxxxxxxx_DAxxxxxxxxxxxxxxxxxx_thing_property_set.writeables.slowChgPower",
                              ExcessChargeSwitchID: "hm-rpc.3.xxxxxxxxxxxxxxxxxx.3.STATE",
                              ExcessChargeSwitchOn: true,
                              ExcessChargeSwitchOff: false,
                              ExcessChargeSwitchMin: 10,
                              ExcessChargeMaxPower: 1500,
                              ExcessChargeStartPower: 50,
                              ExcessChargeStartPowerDurationMin: 5,
                              //****************************************
                              Debug: false,
                              PlotCmdID: 99999,
                          };
                          
                          
                          //  EXTERNE STATES zum Manipulieren von Configurationsvariablen 
                          var externConfig = [
                              //############# Diesen Abschnitt für jeden einzelne Wert anlegen ################
                              {
                                  VarName: "seriennummern[0].lowBatLimitPozOn",       //Variabelname aus "ConfigData" bei Aufzählungen [0...X] in der Reigenfolge der Angaben 
                                  id: "0_userdata.0.eigene_Berechnungen.AkkuReserve"              //Das Objekt (State) das den Wert für diese variable enthalten soll 
                              },
                              //#######################################################################
                          ];
                          //#######################################################################
                           
                          // Funktion zum Setzen einer verschachtelten Eigenschaft in einem Objekt
                          function setNestedProperty(obj, path, value) {
                              let keys = path.split('.');
                              let lastKey = keys.pop();
                              let tempObj = obj;
                           
                              keys.forEach(key => {
                                  if (key.match(/[\d+]/)) {
                                      let index = parseInt(key.match(/[(\d+)]/)[1]);
                                      key = key.split('[')[0];
                                      tempObj = tempObj[key][index];
                                  } else {
                                      tempObj = tempObj[key];
                                  }
                              });
                           
                              tempObj[lastKey] = value;
                          }
                           
                          function setConfigValueFromId(VarName, id) {
                              if (isState2(id)) {
                                  let value = getState(id).val;  // Wert von ioBroker abrufen
                                  setNestedProperty(ConfigData, VarName, value);  // Wert in ConfigData setzen
                              }
                          }
                           
                          // Initialisierung bei Programmstart
                          externConfig.forEach(config => {
                              setConfigValueFromId(config.VarName, config.id);
                          });
                           
                          // Änderungen während der Laufzeit überwachen
                          externConfig.forEach(config => {
                              if (isState2(config.id)) {
                                  on(config.id, function (obj) {
                                      setConfigValueFromId(config.VarName, obj.id);
                                      //log("ExternesEvent:" + obj.id + " : " + config.VarName + ":" + obj.state.val)
                                  });
                              }
                          });
                          //#######################################################################
                          
                          W 1 Reply Last reply
                          0
                          • umeleU umele

                            Hab ich - hier ist der Code bis zum Ende des neuen Codes von config-date bis zum Ende des neuen Codes:

                            var ConfigData = {
                                email: "xxxxxx@gmail.com",                             // Die App-Zugangsdaten von ecoFlow
                                passwort: "yyyyyyyyyy",
                                SmartmeterID: "sonoff.0.Stromzaehler.SENSOR.E320.Power_in",     // State, der den aktuellen Gesamtverbrauch in Watt anzeigt
                                seriennummern: [
                                    //############# Diesen Abschnitt für jedes einzelne Gerät anlegen ################
                                    {
                                        seriennummer: "HWxxxxxxxxxx",              // Die Seriennummer des Gerätes
                                        name: "PowerStream",                        // beliebiger Namen
                                        MaxPower: 600,                              // Der höchstmögliche Wert in Watt für die Einspeiseleistung
                                        subscribe: true,                            // "true": Alle Daten für dieses Gerät werden angefragt. "false": Es werden keine Statusdaten abgefragt
                                        typ: "PS",                                  // Welches Gerät ist es: Powerstrem:"PS"; DeltaMax:"DM"; Delta2: "D2" ; Delta2 Max: "D2M"; SmartPlug: "SM"; Andere: "NA" 
                                        // Parameter an hier nur für PowerStream.     
                                        regulation: true,                           // "true": Dieser PowerStream soll vom Script reguliert werden
                                        RegulationOffPower: -1,                     // Wird die Regulation per State abgestellt, wird die Einspeiseleistung des ersten Powerstreams auf diesen Wert gesetzt (-1 = keine Änderung, -2 = Batterie Priomodus)
                                        hasBat: true,                               // "true": Eine Batterie ist angeschlossen. Nur für PowerStream relevant.
                                        battPozOn: 99, battPozOff: 96,              // Wenn die Batterie bei battPozOn ist, Einspeisung auf MaxPower. Bei BattPozOff Normalbetrieb
                                        battOnSwitchPrio: true,                    // "true": Bei battPozOn wird in den Batterie-Prioritätsmodus gewechselt
                                        prioOffOnDemand: 30,                        // Wattwert des Bedarfs, bei dem zurück in den Strom-Priomodus gechaltet wird. 0 für kein Rückschalten.   
                                        lowBatLimitPozOn: 30, lowBatLimitPozOff: 35,// Bei Unterschreiten der Batterieladung von "lowBatLimitPozOn" % ist die maximale Einspeiseleistung auf 
                                        lowBatLimit: 0,                           // "lowBatLimit" limitiert, bis der Ladezustand wieder bei "lowBatLimitPozOff" ist
                                    },
                                    //#######################################################################
                                    {
                                        seriennummer: "DCExxxxx",
                                        name: "DELTA Pro",
                                        typ: "NA",
                                        subscribe: false,                            // "true": Alle Daten für dieses Gerät werden angefragt. "false": Es werden keine Statusdaten abgefragt
                                    },
                                    //#######################################################################
                                    {
                                        seriennummer: "XXXXXXXXXXXXX",
                                        name: "SmartPlug 1",
                                        typ: "SM",
                                        subscribe: true,                            // "true": Alle Daten für dieses Gerät werden angefragt. "false": Es werden keine Statusdaten abgefragt
                                    },
                                    //#######################################################################
                                ],
                                AdditionalPower: [                                     // Wenn es weitere Wechselrichter gibt, die in IOBroker erfasst werden, können diese hier Angelegt werden
                                    //############# Diesen Abschnitt für jedes einzelne Gerät anlegen ################
                                    {
                                        name: "Hoymiles2000",                       // Beliebiger Name
                                        id: "mqtt.0.solar.1234567890.0.power"       // Der Objektpfad zu dem Leistungswert in Watt (W)
                                    },
                                    //#######################################################################
                                ],
                                //****************************************
                                // Erweiterte Einstellungen:
                                //****************************************
                                SmartmeterTimeoutMin: 4,                            // Wenn der letzte Wert vom Smartmeter älter als "SmartmeterTimeoutMin" ist, wird das Script mit...
                                SmartmeterFallbackPower: 150,                       // SmartmeterFallbackPower als aktuellem Realpowerwert weiter arbeiten, bis wieder aktuelle Daten geliefert werden. 
                                Regulation: true,                                   // 'false' stellt das Setzen der Einspeiseleistung ab 
                                RegulationState: "Regulate",                        // Wenn angegeben, kann mit diesem State die Regulation ein- und ausgeschaltet werden (Wird automatisch unter 0_userdata.0.ecoflow angelegt)
                                RegulationMultiPsMode: 0,                           // Wenn mehrere PS reguliert werden sollen. "balance" = 0 oder "serial" = 1
                                BasePowerOffset: 20,                                // Wird vom aktuellen Verbrauch abgezogen, um die Einspeiseleistung zu berechnen 
                                Zusatzpower_Offset: 10,                             // Zusatzpower startet ab einer Batterieladeleistung von MaxPower - Zusatzpower_Offset
                                MinValueMin: 1,                                     // Der Zeitraum in Minuten, aus dem der niedrigste Gesamtverbrauchswert geholt werden soll. 0 für Echtzeitwert
                                MinValueAg: 0,                                      // Art der Ermittlung des kleinsten Wertes: 0 = Minimalwert, 1 = Durchschnittswert
                                ReconnectMin: 30,                                   // Zeit in Minuten, nach der die Anwendung neu gestartet wird, wenn keine neuen Daten eintreffen
                                statesPrefix: "0_userdata.0.ecoflow",               // Hier werden die ecoFlow States angelegt
                                latitude: latitude,                                 // Breitengrad des Standortes (wird automatisch eingesetzt)
                                longitude: longitude,                               // Längengrad des Standortes (wird automatisch eingesetzt)
                                //****************************************
                                // Überschuss Ladung:
                                //****************************************
                                ExcessCharge: false,                                //
                                ExcessChargePowerID: "0_userdata.0.ecoflow.app_xxxxxxxxxxxxxxxxxxxx_DAxxxxxxxxxxxxxxxxxx_thing_property_set.writeables.slowChgPower",
                                ExcessChargeSwitchID: "hm-rpc.3.xxxxxxxxxxxxxxxxxx.3.STATE",
                                ExcessChargeSwitchOn: true,
                                ExcessChargeSwitchOff: false,
                                ExcessChargeSwitchMin: 10,
                                ExcessChargeMaxPower: 1500,
                                ExcessChargeStartPower: 50,
                                ExcessChargeStartPowerDurationMin: 5,
                                //****************************************
                                Debug: false,
                                PlotCmdID: 99999,
                            };
                            
                            
                            //  EXTERNE STATES zum Manipulieren von Configurationsvariablen 
                            var externConfig = [
                                //############# Diesen Abschnitt für jeden einzelne Wert anlegen ################
                                {
                                    VarName: "seriennummern[0].lowBatLimitPozOn",       //Variabelname aus "ConfigData" bei Aufzählungen [0...X] in der Reigenfolge der Angaben 
                                    id: "0_userdata.0.eigene_Berechnungen.AkkuReserve"              //Das Objekt (State) das den Wert für diese variable enthalten soll 
                                },
                                //#######################################################################
                            ];
                            //#######################################################################
                             
                            // Funktion zum Setzen einer verschachtelten Eigenschaft in einem Objekt
                            function setNestedProperty(obj, path, value) {
                                let keys = path.split('.');
                                let lastKey = keys.pop();
                                let tempObj = obj;
                             
                                keys.forEach(key => {
                                    if (key.match(/[\d+]/)) {
                                        let index = parseInt(key.match(/[(\d+)]/)[1]);
                                        key = key.split('[')[0];
                                        tempObj = tempObj[key][index];
                                    } else {
                                        tempObj = tempObj[key];
                                    }
                                });
                             
                                tempObj[lastKey] = value;
                            }
                             
                            function setConfigValueFromId(VarName, id) {
                                if (isState2(id)) {
                                    let value = getState(id).val;  // Wert von ioBroker abrufen
                                    setNestedProperty(ConfigData, VarName, value);  // Wert in ConfigData setzen
                                }
                            }
                             
                            // Initialisierung bei Programmstart
                            externConfig.forEach(config => {
                                setConfigValueFromId(config.VarName, config.id);
                            });
                             
                            // Änderungen während der Laufzeit überwachen
                            externConfig.forEach(config => {
                                if (isState2(config.id)) {
                                    on(config.id, function (obj) {
                                        setConfigValueFromId(config.VarName, obj.id);
                                        //log("ExternesEvent:" + obj.id + " : " + config.VarName + ":" + obj.state.val)
                                    });
                                }
                            });
                            //#######################################################################
                            
                            W Offline
                            W Offline
                            Waly_de
                            wrote on last edited by Waly_de
                            #578

                            @umele sagte in ecoflow-connector-Script zur dynamischen Leistungsanpassung:

                            Hab ich - hier ist der Code bis zum Ende des neuen Codes von config-date bis zum Ende des neuen Codes:

                            da muss irgendwo anders im Script was kaputt sein.
                            Hier das komplette neue Script mit der eingebauten Änderung. Versuch das bitte noch mal:

                            ecoflow-connector_v115.txt

                            umeleU 1 Reply Last reply
                            0
                            • W Waly_de

                              @umele sagte in ecoflow-connector-Script zur dynamischen Leistungsanpassung:

                              Hab ich - hier ist der Code bis zum Ende des neuen Codes von config-date bis zum Ende des neuen Codes:

                              da muss irgendwo anders im Script was kaputt sein.
                              Hier das komplette neue Script mit der eingebauten Änderung. Versuch das bitte noch mal:

                              ecoflow-connector_v115.txt

                              umeleU Offline
                              umeleU Offline
                              umele
                              wrote on last edited by umele
                              #579

                              @waly_de - super - läuft 👍 👍
                              Vielen Dank!

                              Hier ist noch mein mini blockly-Script für die Ermittlung der Wettervorhersage für das Setzen der Akkureserve:

                              <block xmlns="https://developers.google.com/blockly/xml" type="schedule" id="(GE`TYRwgdq64gu:ev3X" x="-1412.7252672983375" y="-312.29998779296875">
                                <field name="SCHEDULE">17 0 * * *</field>
                                <statement name="STATEMENT">
                                  <block type="controls_if" id="ZvDhkV_4w)f-:`W}*PD7">
                                    <mutation else="1"></mutation>
                                    <value name="IF0">
                                      <block type="logic_operation" id=")i8lCy/Y9qP.tfH3AbbA">
                                        <field name="OP">AND</field>
                                        <value name="A">
                                          <block type="logic_compare" id="XFoiqi)4IC{nioM%}N$V">
                                            <field name="OP">LTE</field>
                                            <value name="A">
                                              <block type="get_value" id="^cq7Kj`t!a5C-K@V5Cy5">
                                                <field name="ATTR">val</field>
                                                <field name="OID">daswetter.0.NextDays.Location_1.Day_1.Wetter_Symbol_id</field>
                                              </block>
                                            </value>
                                            <value name="B">
                                              <block type="math_number" id="[C5p_$e+hZj:45Jj`X8b">
                                                <field name="NUM">2</field>
                                              </block>
                                            </value>
                                          </block>
                                        </value>
                                        <value name="B">
                                          <block type="logic_compare" id="Y3Ss0!70G}oW:jZ;RE8N">
                                            <field name="OP">LTE</field>
                                            <value name="A">
                                              <block type="get_value" id="O?o^MK%1hqw`K8L?_6Ba">
                                                <field name="ATTR">val</field>
                                                <field name="OID">daswetter.0.NextDays.Location_1.Day_1.Wetter_Symbol_id2</field>
                                              </block>
                                            </value>
                                            <value name="B">
                                              <block type="math_number" id="2!2?c9]7:2RXsT7ARsin">
                                                <field name="NUM">2</field>
                                              </block>
                                            </value>
                                          </block>
                                        </value>
                                      </block>
                                    </value>
                                    <statement name="DO0">
                                      <block type="control" id="1:AV6/J(fY[Zz*1*X[6*">
                                        <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                                        <field name="OID">0_userdata.0.eigene_Berechnungen.AkkuReserve</field>
                                        <field name="WITH_DELAY">FALSE</field>
                                        <value name="VALUE">
                                          <block type="math_number" id="Lj/0p64,RRVn/[21U`U(">
                                            <field name="NUM">10</field>
                                          </block>
                                        </value>
                                        <next>
                                          <block type="debug" id="^#I:RE;C?.+/QDp/q540">
                                            <field name="Severity">log</field>
                                            <value name="TEXT">
                                              <shadow type="text" id="V0Et@Z_=RE]`1r`CjF``">
                                                <field name="TEXT">Der Tag wird sonnig - Reserve runter auf 10.</field>
                                              </shadow>
                                            </value>
                                          </block>
                                        </next>
                                      </block>
                                    </statement>
                                    <statement name="ELSE">
                                      <block type="control" id="XKy/aY~l#z4bg4uF*iJd">
                                        <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                                        <field name="OID">0_userdata.0.eigene_Berechnungen.AkkuReserve</field>
                                        <field name="WITH_DELAY">FALSE</field>
                                        <value name="VALUE">
                                          <block type="math_number" id="HVMt*OIb?!;7_QG9LQ#D">
                                            <field name="NUM">30</field>
                                          </block>
                                        </value>
                                        <next>
                                          <block type="debug" id="!HTqeR|~wD?~*g(SzZ=.">
                                            <field name="Severity">log</field>
                                            <value name="TEXT">
                                              <shadow type="text" id="E-Eho[?yh+g;iD0_J:7x">
                                                <field name="TEXT">Nicht genug Sonne - Reserve auf 30.</field>
                                              </shadow>
                                            </value>
                                          </block>
                                        </next>
                                      </block>
                                    </statement>
                                  </block>
                                </statement>
                              </block>
                              

                              1543fc32-6edf-48f9-8b14-613fb52dfdf7-image.png

                              Die Instanz für "Das Wetter" ist so konfiguriert, dass jede Nacht um 00:07 die Vorhersage aktualisiert wird.
                              Das blockly greift dann die Objekte ab, die anzeigen, ob es am kommenden Vormittag und Nachmittag sonnig genug wird.

                              1dca5a1d-a54a-4275-9181-c5e66e827598-image.png

                              39e64e02-b148-487a-995a-fef7f250f266-image.png

                              1 Reply Last reply
                              1
                              • R Offline
                                R Offline
                                resilient
                                wrote on last edited by
                                #580

                                Welche größe sollte man eigentlich nehmen um zu tracken was wirklich eingespeist wurde (bei 2 PS)
                                jeweils die Werte addieren: ...data.InverterHeartbeat.invOutputWatts ?

                                W 1 Reply Last reply
                                0
                                • R resilient

                                  Welche größe sollte man eigentlich nehmen um zu tracken was wirklich eingespeist wurde (bei 2 PS)
                                  jeweils die Werte addieren: ...data.InverterHeartbeat.invOutputWatts ?

                                  W Offline
                                  W Offline
                                  Waly_de
                                  wrote on last edited by
                                  #581

                                  @resilient sagte in ecoflow-connector-Script zur dynamischen Leistungsanpassung:

                                  jeweils die Werte addieren: ...data.InverterHeartbeat.invOutputWatts ?

                                  Ja, das macht am meisten Sinn.

                                  Es könnte auch sein, dass in den Daten unter:
                                  0_userdata.0.ecoflow.app_device_property_HWXXXXXXXXXXX.data.PowerPack... irgendwie die Daten aus der App versteckt sind.. Ich hatte noch keine Geduld dass zu untersuchen. Auf den ersten Blick finde ich da aber keine Übereinstimmungen.

                                  D 1 Reply Last reply
                                  0
                                  • S Offline
                                    S Offline
                                    sirdir
                                    wrote on last edited by
                                    #582

                                    Hm, die Version vom Juli die ich angepasst hatte auf meine Bedürfnisse funktionierte eigentlich problemlos, die neueren Versionen hören alle irgendwann auf zu regeln (finde nicht heraus warum, debug ist dann jeweils nicht an und wenn ich das script neu starte geht’s wieder). Gibt’s eigentlich ne einfache möglichkeit im ionroker ein script regelmässig neu starten zu lassen automatisch?

                                    W 1 Reply Last reply
                                    0
                                    • S sirdir

                                      Hm, die Version vom Juli die ich angepasst hatte auf meine Bedürfnisse funktionierte eigentlich problemlos, die neueren Versionen hören alle irgendwann auf zu regeln (finde nicht heraus warum, debug ist dann jeweils nicht an und wenn ich das script neu starte geht’s wieder). Gibt’s eigentlich ne einfache möglichkeit im ionroker ein script regelmässig neu starten zu lassen automatisch?

                                      W Offline
                                      W Offline
                                      Waly_de
                                      wrote on last edited by Waly_de
                                      #583

                                      @sirdir schwer zu sagen was das problem ist. Steht denn das Script komplett, oder wird nur nicht mehr gesendet? Steht nichts im Log wie z.B. das es zu viele SetStates gab...

                                      Neustarten geht z.b. aus einem anderen Script mit einem Cron

                                      bei mir ist der zugehörige Pfad: "javascript.0.scriptEnabled.ecoflow-connector_dev"
                                      Neustart sollte dann so gehen:

                                      // Pfad zum 'enabled'-State des Scripts
                                      var scriptEnabledStatePath = 'javascript.0.scriptEnabled.ecoflow-connector_dev'; 
                                      
                                      // Script deaktivieren
                                      setState(scriptEnabledStatePath, false, true, function() {
                                          // Kurze Pause, dann Script wieder aktivieren
                                          setTimeout(function() {
                                              setState(scriptEnabledStatePath, true, true);
                                          }, 1000);  // Wartezeit in Millisekunden, kann angepasst werden
                                      });
                                      
                                      S 2 Replies Last reply
                                      0
                                      • W Waly_de

                                        @resilient sagte in ecoflow-connector-Script zur dynamischen Leistungsanpassung:

                                        jeweils die Werte addieren: ...data.InverterHeartbeat.invOutputWatts ?

                                        Ja, das macht am meisten Sinn.

                                        Es könnte auch sein, dass in den Daten unter:
                                        0_userdata.0.ecoflow.app_device_property_HWXXXXXXXXXXX.data.PowerPack... irgendwie die Daten aus der App versteckt sind.. Ich hatte noch keine Geduld dass zu untersuchen. Auf den ersten Blick finde ich da aber keine Übereinstimmungen.

                                        D Offline
                                        D Offline
                                        Dreffi
                                        wrote on last edited by
                                        #584

                                        @waly_de
                                        Folgender Bug:
                                        (Version: 1.1.4.2)

                                        Der erste Powerstream schaltet wegen BatPoz auf Prio Speicher. Normal müsste Powerstream 2 nur noch einspeisen, was zu Deckung des Bedarfs fehlt.
                                        Dieser speist aber mehr ein, wodurch ins Netz zurückgespeist wird. Nein, Akku von Powerstream 2 ist nicht voll und die Ladeleistung liegt deutlich unter 600 W.

                                        Es scheint als würde die Last für Powerstream 2 nicht mit der tatsächlichen Einspeiseleistung von Powerstream 1, sondern mit der eingestellten AC Last von Powerstream 1 berechnet werden.

                                        Die Rückspeisung ins Netz ist ungefähr so groß, wie die aktuelle PV-Leistung von Powerstream 1 abzüglich der eingestellten AC Last von Powerstream 1.
                                        Die durch Prio Speicher höher ausfallende AC Leistung wird nicht berücksichtigt.

                                        W 1 Reply Last reply
                                        0
                                        • D Dreffi

                                          @waly_de
                                          Folgender Bug:
                                          (Version: 1.1.4.2)

                                          Der erste Powerstream schaltet wegen BatPoz auf Prio Speicher. Normal müsste Powerstream 2 nur noch einspeisen, was zu Deckung des Bedarfs fehlt.
                                          Dieser speist aber mehr ein, wodurch ins Netz zurückgespeist wird. Nein, Akku von Powerstream 2 ist nicht voll und die Ladeleistung liegt deutlich unter 600 W.

                                          Es scheint als würde die Last für Powerstream 2 nicht mit der tatsächlichen Einspeiseleistung von Powerstream 1, sondern mit der eingestellten AC Last von Powerstream 1 berechnet werden.

                                          Die Rückspeisung ins Netz ist ungefähr so groß, wie die aktuelle PV-Leistung von Powerstream 1 abzüglich der eingestellten AC Last von Powerstream 1.
                                          Die durch Prio Speicher höher ausfallende AC Leistung wird nicht berücksichtigt.

                                          W Offline
                                          W Offline
                                          Waly_de
                                          wrote on last edited by
                                          #585

                                          @dreffi bitte teste mal die 1.1.5. genau an diesen Dingen hab ich noch mal gearbeitet...

                                          1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          Support us

                                          ioBroker
                                          Community Adapters
                                          Donate

                                          96

                                          Online

                                          32.4k

                                          Users

                                          81.3k

                                          Topics

                                          1.3m

                                          Posts
                                          Community
                                          Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                                          ioBroker Community 2014-2025
                                          logo
                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Recent
                                          • Tags
                                          • Unread 0
                                          • Categories
                                          • Unreplied
                                          • Popular
                                          • GitHub
                                          • Docu
                                          • Hilfe