Skip to content
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • 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

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo
  1. ioBroker Community Home
  2. Deutsch
  3. Skripten / Logik
  4. JavaScript
  5. ecoflow-connector-Script zur dynamischen Leistungsanpassung

NEWS

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

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

  • Neues Video "KI im Smart Home" - ioBroker plus n8n
    BluefoxB
    Bluefox
    15
    1
    2.1k

ecoflow-connector-Script zur dynamischen Leistungsanpassung

Geplant Angeheftet Gesperrt Verschoben JavaScript
1.6k Beiträge 127 Kommentatoren 741.7k Aufrufe 127 Watching
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • K kaiausBrieselang

    Hallo,
    ich habe mal eine Verständnisfrage:
    wozu benötige ich die Parameter:
    lowBatLimitPozOn: 30,
    lowBatLimitPozOff:40,
    lowBatLimit: 150,

    Bei mir wird der Akku bis zum letzten % "leer" gezogen. Ich hätte erwartet, dass zumindest ab 30% "nur" noch auf 150W reduziert wird. Das klappt bei mir gar nicht.
    Aber ich verstehe auch den Hintergrund nicht so ganz. Warum sollte ich "kurz vor Leer" die Ausgabeleistung "nur" auf 150W (oder einen beliebigen Wert) reduzieren. Entweder ich möchte die volle benötigte Leistung bis zur definierten Restladung haben oder nicht, aber was bringt eine reduzierte Abgabe?
    Vielleicht verstehe ich das auch nicht richtig.

    Dann habe ich noch eine weitere Frage.
    Der Ladestand der Batterie wird ja hier angezeigt:
    0_userdata.0.ecoflow.app_device_property_R351xxxxD2Mxxx.data.params.bms_bmsStatus.f32ShowSoc
    0_userdata.0.ecoflow.app_device_property_R351xxxxD2Mxxx.data.params.bms_bmsStatus.soc
    0_userdata.0.ecoflow.app_device_property_R351xxxxD2Mxxx.data.params.bms_emsStatus.f32LcdShowSoc
    0_userdata.0.ecoflow.app_device_property_R351xxxxD2Mxxx.data.params.bms_emsStatus.lcdShowSoc

    Aber um an die Werte heran zu kommen muss ich ja den D2M abfragen. Das wiederum erzeugt ja viel Datenstrom.
    In den Einstellungen des PS in der APP wird ja auch der Batteriestand angezeigt.
    Finde ich vielleicht den Wert irgendwo versteckt in den "userdaten" wieder ohne de D2M abzufragen?

    vielen Lieben Dank für eure Hilfe.
    Und vor allen für das tolle Script.

    gruß Kai

    P Offline
    P Offline
    Ponti92
    schrieb am zuletzt editiert von
    #564

    @kaiausbrieselang ja das geht auch über

    *.data.InverterHeartbeat.batSoc
    
    K 1 Antwort Letzte Antwort
    0
    • P Offline
      P Offline
      pasch
      schrieb am zuletzt editiert von
      #565

      Läuft super bisher. 🙂

      Mir ist aufgefallen, dass "Other Loads" bei mir oft um 1-3 Watt schwankt. Gibt es die Möglichkeit zu sagen, nur bei Änderungen größer X den neuen Wert setzten? In den Einstellungen habe ich nichts gefunden.

      Grüße
      Patrick

      1 Antwort Letzte Antwort
      0
      • R Offline
        R Offline
        resilient
        schrieb am zuletzt editiert von
        #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 Antwort Letzte Antwort
        0
        • P Ponti92

          @kaiausbrieselang ja das geht auch über

          *.data.InverterHeartbeat.batSoc
          
          K Offline
          K Offline
          kaiausBrieselang
          schrieb am zuletzt editiert von
          #567

          @ponti92
          wieder was gelernt 🙂
          Danke dir!!

          1 Antwort Letzte Antwort
          0
          • S Offline
            S Offline
            sirdir
            schrieb am zuletzt editiert von 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 Antwort Letzte Antwort
            0
            • umeleU Offline
              umeleU Offline
              umele
              schrieb am zuletzt editiert von
              #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 Antwort Letzte Antwort
              0
              • umeleU Offline
                umeleU Offline
                umele
                schrieb am zuletzt editiert von 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 Antwort Letzte Antwort
                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
                  schrieb am zuletzt editiert von
                  #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 Antwort Letzte Antwort
                  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
                    schrieb am zuletzt editiert von
                    #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 Antwort Letzte Antwort
                    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
                      schrieb am zuletzt editiert von
                      #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 Antworten Letzte Antwort
                      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
                        schrieb am zuletzt editiert von
                        #574

                        @waly_de - super Danke!! 😊 😊 👍 👍

                        1 Antwort Letzte Antwort
                        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
                          schrieb am zuletzt editiert von 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 Antwort Letzte Antwort
                          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
                            schrieb am zuletzt editiert von
                            #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 Antwort Letzte Antwort
                            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
                              schrieb am zuletzt editiert von 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 Antwort Letzte Antwort
                              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
                                schrieb am zuletzt editiert von 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 Antwort Letzte Antwort
                                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
                                  schrieb am zuletzt editiert von 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 Antwort Letzte Antwort
                                  1
                                  • R Offline
                                    R Offline
                                    resilient
                                    schrieb am zuletzt editiert von
                                    #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 Antwort Letzte Antwort
                                    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
                                      schrieb am zuletzt editiert von
                                      #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 Antwort Letzte Antwort
                                      0
                                      • S Offline
                                        S Offline
                                        sirdir
                                        schrieb am zuletzt editiert von
                                        #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 Antwort Letzte Antwort
                                        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
                                          schrieb am zuletzt editiert von 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 Antworten Letzte Antwort
                                          0
                                          Antworten
                                          • In einem neuen Thema antworten
                                          Anmelden zum Antworten
                                          • Älteste zuerst
                                          • Neuste zuerst
                                          • Meiste Stimmen


                                          Support us

                                          ioBroker
                                          Community Adapters
                                          Donate

                                          722

                                          Online

                                          32.4k

                                          Benutzer

                                          81.4k

                                          Themen

                                          1.3m

                                          Beiträge
                                          Community
                                          Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                                          ioBroker Community 2014-2025
                                          logo
                                          • Anmelden

                                          • Du hast noch kein Konto? Registrieren

                                          • Anmelden oder registrieren, um zu suchen
                                          • Erster Beitrag
                                            Letzter Beitrag
                                          0
                                          • Aktuell
                                          • Tags
                                          • Ungelesen 0
                                          • Kategorien
                                          • Unreplied
                                          • Beliebt
                                          • GitHub
                                          • Docu
                                          • Hilfe