Skip to content
  • Home
  • 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

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Skripten / Logik
  4. JavaScript
  5. [Vorlage] Hoymiles Wechselrichter Begrenzung mit openDTU

NEWS

  • Jahresrückblick 2025 – unser neuer Blogbeitrag ist online! ✨
    BluefoxB
    Bluefox
    17
    1
    2.2k

  • Neuer Blogbeitrag: Monatsrückblick - Dezember 2025 🎄
    BluefoxB
    Bluefox
    13
    1
    945

  • Weihnachtsangebot 2025! 🎄
    BluefoxB
    Bluefox
    25
    1
    2.2k

[Vorlage] Hoymiles Wechselrichter Begrenzung mit openDTU

Geplant Angeheftet Gesperrt Verschoben JavaScript
12 Beiträge 3 Kommentatoren 1.8k Aufrufe 2 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.
  • SchmakusS Schmakus

    Hi,

    ich montiere aktuell eine PV mit 3x Hoymiles HMS-1600 Wechselrichtern.
    Um diese zu begrenzen habe ich ein Script zusammengeschustert.
    Ich habe es jetzt nur mal manuell getestet, habe aber keine Erfahrungen, wie es sich mit den WR verhält.

    Der Gedanke: Es wird bei jeder Änderung der Wechselrichterleistung geprüft, ob alle Wechselrichter gemeinsam nicht mehr als die vorgegebene Begrenzung einspeisen. Bei Änderung wird proportional die Begrenzung der WR geändert.

    Vielleicht kann dieses Script schon mal jemand testen und gerne Kritik äußern!

    Des Weiteren werde ich das Script step-by-step erweitern wollen. Gerade mit dem Thema der Nulleinspeisung, um die maximale Auslastung zu erreichen.
    Hierzu wären Tipps und Erfahrungen von Euch wünschenswert.
    z.B.: Erst wenn die Einspeisung größer 600/800W beträgt, werden die Wechselrichter begrenzt und/oder werden weitere Verbraucher hinzugeschalten, usw.

    Die Anzahl der Wechselrichter kann beliebig erweitert oder bis auf einen verkürzt werden.
    Ebenfalls ist eine Berechnung für eine Batterieladung integriert.

    https://github.com/Schmakus/ioBroker-Scripte/blob/main/hoymiles-begrenzung.js

    /*
      * Script zur Begrenzung von Hoymiles Wechselrichter in Verbindung mit openDTU
      * v0.0.3 2023/12/12 by Schmakus
      * http://www.github.com/Schmakus/ioBroker-Scripte/
      *
      * Es werden folgende eigene Datenpunkte erstellt:
      *    BegrenzungSoll:          Vorgabe der Gesamtbegrenzung
      *    BegrenzungIst:           Aktuelle Begrenzung in Watt über alle Wechselrichter
      *    BegrenzungIstInProzent:  Aktuelle Begrenzung in Prozent über alle Wechselrichter
      *
      * Info: Die Objekt-IDs im Wechselrichter Objekt sind nur zum Test und müssen mit den richtigen Datenpunkten der Wechselrichter, usw. ersetzt werden!
     */
    
    //Wo sollen die eigenen Datenpunkte angelegt werden?
    const path = "0_userdata.0.PV";
    
    //** Angaben zu den Wechselrichtern */
    const wechselrichter = {
      1: {
        name: "Wechselrichter 1",
        maxLeistung: 1600,
        objLeistung: "0_userdata.0.PV.LeistungWR1", // Datenpunkt des Wechselrichters der aktuellen Leistung in Watt
        objBegrenzung: "0_userdata.0.PV.BegrenzungWR1", // Beispiel: opendtu.0.xxxxxx.power_control.limit_persistent_absolute)
        aktuelleLeistung: 0, // Nichts ändern!
        begrenzteLeistung: 0, // Nichts ändern!
      },
      2: {
        name: "Wechselrichter 2",
        maxLeistung: 1600,
        objLeistung: "0_userdata.0.PV.LeistungWR2", // Datenpunkt des Wechselrichters der aktuellen Leistung in Watt
        objBegrenzung: "0_userdata.0.PV.BegrenzungWR2", // Beispiel: opendtu.0.xxxxxx.power_control.limit_persistent_absolute)
        aktuelleLeistung: 0, // Nichts ändern!
        begrenzteLeistung: 0, // Nichts ändern!
      },
      3: {
        name: "Wechselrichter 3",
        maxLeistung: 1600,
        objLeistung: "0_userdata.0.PV.LeistungWR3", // Datenpunkt des Wechselrichters der aktuellen Leistung in Watt
        objBegrenzung: "0_userdata.0.PV.BegrenzungWR3", // Beispiel: opendtu.0.xxxxxx.power_control.limit_persistent_absolute)
        aktuelleLeistung: 0, // Nichts ändern!
        begrenzteLeistung: 0, // Nichts ändern!
      },
    };
    
    //Objekt-ID aktuelle Leistungsaufnahme des Hauses
    const objLeistungHaus = "0_userdata.0.PV.LeistungHaus"; // Hier den Datenpunkt zum Smartmeter angeben (Shelly, IR-Lesekopf, etc...)
    
    //Entscheidung ob Batterie geladen werden soll?
    const batterie = {
        laden: true, // true = laden, false = nicht laden
        maxLadeleistung: 600, //maximale Ladeleistung in Watt,
        unit: "volt", // "volt", "watt" or "percent"
        objLadungWatt: "0_userdata.0.PV.LadeleistungBatterie", // Hier den Datenpunkt zum Ladegerät angeben
        objLadungProzent: "0_userdata.0.PV.LadeleistungBatterieInProzent", // Hier den Datenpunkt zum Ladegerät angeben
        objLadungVolt: "0_userdata.0.PV.LadeleistungBatterieInVolt" // Hier den Datenpunkt zum Ladegerät angeben
    }
    
    //**************************** */
    // AB HIER NICHTS MEHR ÄNDERN! //
    //**************************** */
    
    //Variablen
    let wechselrichterLeistungen = [];
    let maximaleLeistungen = [];
    let entpreller = null;
    let maxGesamtLeistung = 0;
    let objBegrenzung = "";
    let objBegrenzungIst = "";
    let objBegrenzungIstProzent = "";
    
    /**
     * Diese Funktion wird aufgerufen, wenn das System bereit ist.
     */
    async function onReady() {
        await setStates();
        await getWechselrichterLeistungen();
    
        for (const wr of Object.values(wechselrichter)) {
            on({ id: wr.objLeistung, change: "ne" }, async (obj) => {
            wr.aktuelleLeistung = obj.state.val;
            console.log(`Aktuelle Leistung eines Wechselrichters aktualisiert. Wechselrichter: ${wr.name}, aktuelle Leistung: ${wr.aktuelleLeistung}`);
            await setWechselrichterLeistungen();
            });
        }
    
        const updateMaxGesamtLeistung = async (obj) => {
                maxGesamtLeistung = (await getStateAsync(objBegrenzung)).val || 800;
                await setStateAsync(objBegrenzung, { val: maxGesamtLeistung, ack: true });
                console.log(`Aktuelle Begrenzung Soll: ${maxGesamtLeistung}`);
                await setWechselrichterLeistungen();
         };
        
        on({ id: [objLeistungHaus, objBegrenzung], change: "ne" }, updateMaxGesamtLeistung);
    }
    
    /**
     * Diese Funktion erstellt und initialisiert die eigenen Datenpunkte.
     */
    async function setStates() {
        // Maximal zulässige Gesamtleistung
        await createStateAsync(`${path}.BegrenzungSoll`, 800, { read: true, write: true, name: 'Begrenzung Wechselrichter in Summe', type: "number", role: "state", unit: "W", def: 800 });
        await createStateAsync(`${path}.BegrenzungIst`, 0, { read: true, write: false, name: 'Ist-Begrenzung Wechselrichter in Summe [Watt]', type: "number", role: "value", unit: "W", def: 0 });
        await createStateAsync(`${path}.BegrenzungIstInProzent`, 0, { read: true, write: false, name: 'Ist-Begrenzung Wechselrichter in Summe [Prozent]', type: "number", role: "value", unit: "%", def: 0 });
        objBegrenzung = `${path}.BegrenzungSoll`;
        objBegrenzungIst = `${path}.BegrenzungIst`;
        objBegrenzungIstProzent = `${path}.BegrenzungIstInProzent`;
        maxGesamtLeistung = getState(objBegrenzung).val ?? 800;
    }
    
    /**
     * Diese Funktion ruft die aktuellen Leistungen aller Wechselrichter ab.
     */
    async function getWechselrichterLeistungen() {
        for (const wr of Object.values(wechselrichter)) {
            try {
                const leistung = await getStateAsync(wr.objLeistung);
                if (leistung) {
                    wr.aktuelleLeistung = leistung.val;
                } else {
                    console.error(
                    `Could not retrieve state for ${wr.objLeistung}`
                    );
                    wr.aktuelleLeistung = 0; // Use 0 as a default value
                }
            } catch (error) {
                console.error(
                    `Error retrieving state for ${wr.objLeistung}: ${error}`
                );
                wr.aktuelleLeistung = 0; // Use 0 as a default value
            }
        }    
    }
    
    /**
     * Diese Funktion gibt ein Array der maximalen Leistungen aller Wechselrichter zurück.
     */
    async function getMaximaleLeistungen() {
      return Object.values(wechselrichter).map(
        (wechselrichter) => wechselrichter.maxLeistung
      );
    }
    
    /**
     * Berechnet die Summe aller aktuellen Leistungen der Wechselrichter.
     */
    async function getAktuelleLeistungSumme() {
      let summe = 0;
      // Iteriere durch jedes Wechselrichter-Objekt
      for (const wr of Object.values(wechselrichter)) {
          summe = summe + wr.aktuelleLeistung;
      }
      return summe;
    };
    
    /**
     * Berechnet die Summe aller maxLeistung-Werte im Wechselrichter-Objekt.
     */
    async function getMaxLeistungSumme() {
      let summe = 0;
      // Iteriere durch jedes Wechselrichter-Objekt
      for (const wr of Object.values(wechselrichter)) {
          summe = summe + wr.maxLeistung;
      }
      return summe;
    };
    
    /**
     * Berechnet die Summe aller begrenzteLeistung-Werte im Wechselrichter-Objekt.
     */
    async function getMaxBegrenzungSumme() {
      let summe = 0;
      // Iteriere durch jedes Wechselrichter-Objekt
      for (const wr of Object.values(wechselrichter)) {
          summe = summe + wr.begrenzteLeistung;
      }
      return summe;
    };
    
    /**
     * Berechnet die maximale Leistung und setzt die Begrenzung der Wechselrichter.
     */
    async function setWechselrichterLeistungen() {
        const aktuelleLeistungen = await getAktuelleLeistungSumme();
        console.log(`Aktuelle Gesamtleistung der Wechselrichter: ${aktuelleLeistungen}`);
    
        const faktor = maxGesamtLeistung / aktuelleLeistungen;
        console.log(`Reduktionsfaktor der Wechselrichter: ${faktor}`);
    
        await Promise.all(
            Object.values(wechselrichter).map(async (wr) => {
                let begrenzung = Math.floor(wr.aktuelleLeistung * faktor);
                
                // Begrenze die einzelnen Wechselrichter auf mindestens 50W
                begrenzung = Math.max(begrenzung, 50);
                
                // Begrenze die einzelnen Wechselrichter auf maxGesamtLeistung
                begrenzung = Math.min(begrenzung, maxGesamtLeistung);
                
                wr.begrenzteLeistung = begrenzung;
                
                await setStateAsync(wr.objBegrenzung, { val: wr.begrenzteLeistung, ack: false });
    
                const prozentualeLeistung = (wr.begrenzteLeistung / wr.maxLeistung) * 100;
                console.log(`${wr.name}: ${wr.begrenzteLeistung}W (${prozentualeLeistung.toFixed(2)}%)`);
            })
        );
    
        const begrenzteLeistungIst = await getMaxBegrenzungSumme();
        const begrenzteLeistungIstInProzent = Math.round((begrenzteLeistungIst / await getMaxLeistungSumme()) * 10000) / 100; // Runden auf 2 Nachkommastellen
        await Promise.all([
          setStateAsync(objBegrenzungIst, { val: begrenzteLeistungIst, ack: true }),
          setStateAsync(objBegrenzungIstProzent, { val: begrenzteLeistungIstInProzent, ack: true })
        ]);
        console.log(`Gesamtbegrenzung nach Anpassung: ${begrenzteLeistungIst}W, ${begrenzteLeistungIstInProzent}%, maxLeistungWR: ${maxGesamtLeistung}W`);
        
        //Batterieladung
        await loadBattery(aktuelleLeistungen);
    }
    
    async function loadBattery(aktuelleLeistungen) {
       if (batterie.laden) {
          const leistungHaus = (await getStateAsync(objLeistungHaus)).val;
          const ueberschuss = Math.max(aktuelleLeistungen - leistungHaus, 0);
          const ladeLeistung = Math.min(ueberschuss, batterie.maxLadeleistung);
      
          const ladeLeistungProzent = Math.round((ueberschuss / batterie.maxLadeleistung) * 10000) / 100; // Runden auf 2 Nachkommastellen
          const ladeLeistungVolt = Math.round(10 * (ladeLeistungProzent / 100) * 100) / 100; // Runden auf 2 Nachkommastellen
      
          switch (batterie.unit) {
            case "watt":
              await setStateAsync(batterie.objLadungWatt, { val: ladeLeistung, ack: false });
              break;
            case "percent":
              await setStateAsync(batterie.objLadungProzent, { val: ladeLeistungProzent, ack: false });
              break;
            case "volt":
              await setStateAsync(batterie.objLadungVolt, { val: ladeLeistungVolt, ack: false });
              break;
            default:
              console.warn(`Keine Einheit für die Batterieladung angegeben oder Einheit entspricht nicht 'watt', 'volt' oder 'percent'!`);
            
          };
          console.log(`Aktueller Überschuss: ${ueberschuss}, Ladeleistung: ${ladeLeistung}W, ${ladeLeistungProzent}%, ${ladeLeistungVolt}`);
        }
    }
    
    onReady();
    

    Edit 13.12.2023: Code Update

    CodierknechtC Offline
    CodierknechtC Offline
    Codierknecht
    Developer Most Active
    schrieb am zuletzt editiert von
    #2

    @schmakus
    Was mir sofort auffällt, ohne tief in das Script eingestiegen zu sein:
    Du definierst path, aber die einzelnen DP werden trotzdem absolut definiert.
    Könnte man beispielhaft auch so machen:

    const objLeistungHaus = `$(path).LeistungHaus`;
    

    Dann auch gleich oben definieren und konsequent verwenden.
    Dann muss man nur diese eine Konstante ändern, wenn man die DP woanders ablegen möchte.

    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand." (Martin Fowler, "Refactoring")

    Proxmox 9.1.1 LXC|8 GB|Core i7-6700
    HmIP|ZigBee|Tasmota|Unifi
    Zabbix Certified Specialist
    Konnte ich Dir helfen? Dann benutze bitte das Voting unten rechts im Beitrag

    SchmakusS 1 Antwort Letzte Antwort
    0
    • SchmakusS Schmakus

      Hi,

      ich montiere aktuell eine PV mit 3x Hoymiles HMS-1600 Wechselrichtern.
      Um diese zu begrenzen habe ich ein Script zusammengeschustert.
      Ich habe es jetzt nur mal manuell getestet, habe aber keine Erfahrungen, wie es sich mit den WR verhält.

      Der Gedanke: Es wird bei jeder Änderung der Wechselrichterleistung geprüft, ob alle Wechselrichter gemeinsam nicht mehr als die vorgegebene Begrenzung einspeisen. Bei Änderung wird proportional die Begrenzung der WR geändert.

      Vielleicht kann dieses Script schon mal jemand testen und gerne Kritik äußern!

      Des Weiteren werde ich das Script step-by-step erweitern wollen. Gerade mit dem Thema der Nulleinspeisung, um die maximale Auslastung zu erreichen.
      Hierzu wären Tipps und Erfahrungen von Euch wünschenswert.
      z.B.: Erst wenn die Einspeisung größer 600/800W beträgt, werden die Wechselrichter begrenzt und/oder werden weitere Verbraucher hinzugeschalten, usw.

      Die Anzahl der Wechselrichter kann beliebig erweitert oder bis auf einen verkürzt werden.
      Ebenfalls ist eine Berechnung für eine Batterieladung integriert.

      https://github.com/Schmakus/ioBroker-Scripte/blob/main/hoymiles-begrenzung.js

      /*
        * Script zur Begrenzung von Hoymiles Wechselrichter in Verbindung mit openDTU
        * v0.0.3 2023/12/12 by Schmakus
        * http://www.github.com/Schmakus/ioBroker-Scripte/
        *
        * Es werden folgende eigene Datenpunkte erstellt:
        *    BegrenzungSoll:          Vorgabe der Gesamtbegrenzung
        *    BegrenzungIst:           Aktuelle Begrenzung in Watt über alle Wechselrichter
        *    BegrenzungIstInProzent:  Aktuelle Begrenzung in Prozent über alle Wechselrichter
        *
        * Info: Die Objekt-IDs im Wechselrichter Objekt sind nur zum Test und müssen mit den richtigen Datenpunkten der Wechselrichter, usw. ersetzt werden!
       */
      
      //Wo sollen die eigenen Datenpunkte angelegt werden?
      const path = "0_userdata.0.PV";
      
      //** Angaben zu den Wechselrichtern */
      const wechselrichter = {
        1: {
          name: "Wechselrichter 1",
          maxLeistung: 1600,
          objLeistung: "0_userdata.0.PV.LeistungWR1", // Datenpunkt des Wechselrichters der aktuellen Leistung in Watt
          objBegrenzung: "0_userdata.0.PV.BegrenzungWR1", // Beispiel: opendtu.0.xxxxxx.power_control.limit_persistent_absolute)
          aktuelleLeistung: 0, // Nichts ändern!
          begrenzteLeistung: 0, // Nichts ändern!
        },
        2: {
          name: "Wechselrichter 2",
          maxLeistung: 1600,
          objLeistung: "0_userdata.0.PV.LeistungWR2", // Datenpunkt des Wechselrichters der aktuellen Leistung in Watt
          objBegrenzung: "0_userdata.0.PV.BegrenzungWR2", // Beispiel: opendtu.0.xxxxxx.power_control.limit_persistent_absolute)
          aktuelleLeistung: 0, // Nichts ändern!
          begrenzteLeistung: 0, // Nichts ändern!
        },
        3: {
          name: "Wechselrichter 3",
          maxLeistung: 1600,
          objLeistung: "0_userdata.0.PV.LeistungWR3", // Datenpunkt des Wechselrichters der aktuellen Leistung in Watt
          objBegrenzung: "0_userdata.0.PV.BegrenzungWR3", // Beispiel: opendtu.0.xxxxxx.power_control.limit_persistent_absolute)
          aktuelleLeistung: 0, // Nichts ändern!
          begrenzteLeistung: 0, // Nichts ändern!
        },
      };
      
      //Objekt-ID aktuelle Leistungsaufnahme des Hauses
      const objLeistungHaus = "0_userdata.0.PV.LeistungHaus"; // Hier den Datenpunkt zum Smartmeter angeben (Shelly, IR-Lesekopf, etc...)
      
      //Entscheidung ob Batterie geladen werden soll?
      const batterie = {
          laden: true, // true = laden, false = nicht laden
          maxLadeleistung: 600, //maximale Ladeleistung in Watt,
          unit: "volt", // "volt", "watt" or "percent"
          objLadungWatt: "0_userdata.0.PV.LadeleistungBatterie", // Hier den Datenpunkt zum Ladegerät angeben
          objLadungProzent: "0_userdata.0.PV.LadeleistungBatterieInProzent", // Hier den Datenpunkt zum Ladegerät angeben
          objLadungVolt: "0_userdata.0.PV.LadeleistungBatterieInVolt" // Hier den Datenpunkt zum Ladegerät angeben
      }
      
      //**************************** */
      // AB HIER NICHTS MEHR ÄNDERN! //
      //**************************** */
      
      //Variablen
      let wechselrichterLeistungen = [];
      let maximaleLeistungen = [];
      let entpreller = null;
      let maxGesamtLeistung = 0;
      let objBegrenzung = "";
      let objBegrenzungIst = "";
      let objBegrenzungIstProzent = "";
      
      /**
       * Diese Funktion wird aufgerufen, wenn das System bereit ist.
       */
      async function onReady() {
          await setStates();
          await getWechselrichterLeistungen();
      
          for (const wr of Object.values(wechselrichter)) {
              on({ id: wr.objLeistung, change: "ne" }, async (obj) => {
              wr.aktuelleLeistung = obj.state.val;
              console.log(`Aktuelle Leistung eines Wechselrichters aktualisiert. Wechselrichter: ${wr.name}, aktuelle Leistung: ${wr.aktuelleLeistung}`);
              await setWechselrichterLeistungen();
              });
          }
      
          const updateMaxGesamtLeistung = async (obj) => {
                  maxGesamtLeistung = (await getStateAsync(objBegrenzung)).val || 800;
                  await setStateAsync(objBegrenzung, { val: maxGesamtLeistung, ack: true });
                  console.log(`Aktuelle Begrenzung Soll: ${maxGesamtLeistung}`);
                  await setWechselrichterLeistungen();
           };
          
          on({ id: [objLeistungHaus, objBegrenzung], change: "ne" }, updateMaxGesamtLeistung);
      }
      
      /**
       * Diese Funktion erstellt und initialisiert die eigenen Datenpunkte.
       */
      async function setStates() {
          // Maximal zulässige Gesamtleistung
          await createStateAsync(`${path}.BegrenzungSoll`, 800, { read: true, write: true, name: 'Begrenzung Wechselrichter in Summe', type: "number", role: "state", unit: "W", def: 800 });
          await createStateAsync(`${path}.BegrenzungIst`, 0, { read: true, write: false, name: 'Ist-Begrenzung Wechselrichter in Summe [Watt]', type: "number", role: "value", unit: "W", def: 0 });
          await createStateAsync(`${path}.BegrenzungIstInProzent`, 0, { read: true, write: false, name: 'Ist-Begrenzung Wechselrichter in Summe [Prozent]', type: "number", role: "value", unit: "%", def: 0 });
          objBegrenzung = `${path}.BegrenzungSoll`;
          objBegrenzungIst = `${path}.BegrenzungIst`;
          objBegrenzungIstProzent = `${path}.BegrenzungIstInProzent`;
          maxGesamtLeistung = getState(objBegrenzung).val ?? 800;
      }
      
      /**
       * Diese Funktion ruft die aktuellen Leistungen aller Wechselrichter ab.
       */
      async function getWechselrichterLeistungen() {
          for (const wr of Object.values(wechselrichter)) {
              try {
                  const leistung = await getStateAsync(wr.objLeistung);
                  if (leistung) {
                      wr.aktuelleLeistung = leistung.val;
                  } else {
                      console.error(
                      `Could not retrieve state for ${wr.objLeistung}`
                      );
                      wr.aktuelleLeistung = 0; // Use 0 as a default value
                  }
              } catch (error) {
                  console.error(
                      `Error retrieving state for ${wr.objLeistung}: ${error}`
                  );
                  wr.aktuelleLeistung = 0; // Use 0 as a default value
              }
          }    
      }
      
      /**
       * Diese Funktion gibt ein Array der maximalen Leistungen aller Wechselrichter zurück.
       */
      async function getMaximaleLeistungen() {
        return Object.values(wechselrichter).map(
          (wechselrichter) => wechselrichter.maxLeistung
        );
      }
      
      /**
       * Berechnet die Summe aller aktuellen Leistungen der Wechselrichter.
       */
      async function getAktuelleLeistungSumme() {
        let summe = 0;
        // Iteriere durch jedes Wechselrichter-Objekt
        for (const wr of Object.values(wechselrichter)) {
            summe = summe + wr.aktuelleLeistung;
        }
        return summe;
      };
      
      /**
       * Berechnet die Summe aller maxLeistung-Werte im Wechselrichter-Objekt.
       */
      async function getMaxLeistungSumme() {
        let summe = 0;
        // Iteriere durch jedes Wechselrichter-Objekt
        for (const wr of Object.values(wechselrichter)) {
            summe = summe + wr.maxLeistung;
        }
        return summe;
      };
      
      /**
       * Berechnet die Summe aller begrenzteLeistung-Werte im Wechselrichter-Objekt.
       */
      async function getMaxBegrenzungSumme() {
        let summe = 0;
        // Iteriere durch jedes Wechselrichter-Objekt
        for (const wr of Object.values(wechselrichter)) {
            summe = summe + wr.begrenzteLeistung;
        }
        return summe;
      };
      
      /**
       * Berechnet die maximale Leistung und setzt die Begrenzung der Wechselrichter.
       */
      async function setWechselrichterLeistungen() {
          const aktuelleLeistungen = await getAktuelleLeistungSumme();
          console.log(`Aktuelle Gesamtleistung der Wechselrichter: ${aktuelleLeistungen}`);
      
          const faktor = maxGesamtLeistung / aktuelleLeistungen;
          console.log(`Reduktionsfaktor der Wechselrichter: ${faktor}`);
      
          await Promise.all(
              Object.values(wechselrichter).map(async (wr) => {
                  let begrenzung = Math.floor(wr.aktuelleLeistung * faktor);
                  
                  // Begrenze die einzelnen Wechselrichter auf mindestens 50W
                  begrenzung = Math.max(begrenzung, 50);
                  
                  // Begrenze die einzelnen Wechselrichter auf maxGesamtLeistung
                  begrenzung = Math.min(begrenzung, maxGesamtLeistung);
                  
                  wr.begrenzteLeistung = begrenzung;
                  
                  await setStateAsync(wr.objBegrenzung, { val: wr.begrenzteLeistung, ack: false });
      
                  const prozentualeLeistung = (wr.begrenzteLeistung / wr.maxLeistung) * 100;
                  console.log(`${wr.name}: ${wr.begrenzteLeistung}W (${prozentualeLeistung.toFixed(2)}%)`);
              })
          );
      
          const begrenzteLeistungIst = await getMaxBegrenzungSumme();
          const begrenzteLeistungIstInProzent = Math.round((begrenzteLeistungIst / await getMaxLeistungSumme()) * 10000) / 100; // Runden auf 2 Nachkommastellen
          await Promise.all([
            setStateAsync(objBegrenzungIst, { val: begrenzteLeistungIst, ack: true }),
            setStateAsync(objBegrenzungIstProzent, { val: begrenzteLeistungIstInProzent, ack: true })
          ]);
          console.log(`Gesamtbegrenzung nach Anpassung: ${begrenzteLeistungIst}W, ${begrenzteLeistungIstInProzent}%, maxLeistungWR: ${maxGesamtLeistung}W`);
          
          //Batterieladung
          await loadBattery(aktuelleLeistungen);
      }
      
      async function loadBattery(aktuelleLeistungen) {
         if (batterie.laden) {
            const leistungHaus = (await getStateAsync(objLeistungHaus)).val;
            const ueberschuss = Math.max(aktuelleLeistungen - leistungHaus, 0);
            const ladeLeistung = Math.min(ueberschuss, batterie.maxLadeleistung);
        
            const ladeLeistungProzent = Math.round((ueberschuss / batterie.maxLadeleistung) * 10000) / 100; // Runden auf 2 Nachkommastellen
            const ladeLeistungVolt = Math.round(10 * (ladeLeistungProzent / 100) * 100) / 100; // Runden auf 2 Nachkommastellen
        
            switch (batterie.unit) {
              case "watt":
                await setStateAsync(batterie.objLadungWatt, { val: ladeLeistung, ack: false });
                break;
              case "percent":
                await setStateAsync(batterie.objLadungProzent, { val: ladeLeistungProzent, ack: false });
                break;
              case "volt":
                await setStateAsync(batterie.objLadungVolt, { val: ladeLeistungVolt, ack: false });
                break;
              default:
                console.warn(`Keine Einheit für die Batterieladung angegeben oder Einheit entspricht nicht 'watt', 'volt' oder 'percent'!`);
              
            };
            console.log(`Aktueller Überschuss: ${ueberschuss}, Ladeleistung: ${ladeLeistung}W, ${ladeLeistungProzent}%, ${ladeLeistungVolt}`);
          }
      }
      
      onReady();
      

      Edit 13.12.2023: Code Update

      Ralla66R Offline
      Ralla66R Offline
      Ralla66
      Most Active
      schrieb am zuletzt editiert von
      #3

      @schmakus

      würde den Wirkungsgrad der WR mit einfließen lassen.

      SchmakusS 1 Antwort Letzte Antwort
      0
      • CodierknechtC Codierknecht

        @schmakus
        Was mir sofort auffällt, ohne tief in das Script eingestiegen zu sein:
        Du definierst path, aber die einzelnen DP werden trotzdem absolut definiert.
        Könnte man beispielhaft auch so machen:

        const objLeistungHaus = `$(path).LeistungHaus`;
        

        Dann auch gleich oben definieren und konsequent verwenden.
        Dann muss man nur diese eine Konstante ändern, wenn man die DP woanders ablegen möchte.

        SchmakusS Offline
        SchmakusS Offline
        Schmakus
        Developer
        schrieb am zuletzt editiert von
        #4

        @codierknecht sagte in [Vorlage] Hoymiles Wechselrichter Begrenzung mit openDTU:

        @schmakus
        Was mir sofort auffällt, ohne tief in das Script eingestiegen zu sein:
        Du definierst path, aber die einzelnen DP werden trotzdem absolut definiert.
        Könnte man beispielhaft auch so machen:

        const objLeistungHaus = `$(path).LeistungHaus`;
        

        Dann auch gleich oben definieren und konsequent verwenden.
        Dann muss man nur diese eine Konstante ändern, wenn man die DP woanders ablegen möchte.

        Hi, schon geändert. Hat jedoch nur einen Datenpunkt betroffen. Die anderen DPs sind meine Test-Datenpunkte und müssen durch die richtigen Datenpunkte der Wechselrichter, usw. ersetzt werden.

        Dev of LightControl Adapter, Contributor of HUE and DoorBird Adapter

        1 Antwort Letzte Antwort
        0
        • Ralla66R Ralla66

          @schmakus

          würde den Wirkungsgrad der WR mit einfließen lassen.

          SchmakusS Offline
          SchmakusS Offline
          Schmakus
          Developer
          schrieb am zuletzt editiert von
          #5

          @ralla66 sagte in [Vorlage] Hoymiles Wechselrichter Begrenzung mit openDTU:

          @schmakus

          würde den Wirkungsgrad der WR mit einfließen lassen.

          Kannst du mir das näher erklären?

          Dev of LightControl Adapter, Contributor of HUE and DoorBird Adapter

          Ralla66R 1 Antwort Letzte Antwort
          0
          • SchmakusS Schmakus

            @ralla66 sagte in [Vorlage] Hoymiles Wechselrichter Begrenzung mit openDTU:

            @schmakus

            würde den Wirkungsgrad der WR mit einfließen lassen.

            Kannst du mir das näher erklären?

            Ralla66R Offline
            Ralla66R Offline
            Ralla66
            Most Active
            schrieb am zuletzt editiert von Ralla66
            #6

            @schmakus

            Beispiel: du hast 2 WR a 1600 Watt
            Begrenzung ist 1500 Watt.
            Fahrweise 1 -> 2 WR a 750 Watt betreiben, schlechter Wirkungsgrad
            oder
            Fahrweise 2 -> 1 WR aus, der andere wird mit 1500 Watt betrieben.

            SchmakusS 1 Antwort Letzte Antwort
            0
            • Ralla66R Ralla66

              @schmakus

              Beispiel: du hast 2 WR a 1600 Watt
              Begrenzung ist 1500 Watt.
              Fahrweise 1 -> 2 WR a 750 Watt betreiben, schlechter Wirkungsgrad
              oder
              Fahrweise 2 -> 1 WR aus, der andere wird mit 1500 Watt betrieben.

              SchmakusS Offline
              SchmakusS Offline
              Schmakus
              Developer
              schrieb am zuletzt editiert von
              #7

              @ralla66 Hi, verstehe ich nicht. Liegt aber vermutlich an meinen noch nicht existierenden Knowhow. :see_no_evil:
              Welche Rolle spielt es, wenn in Summe die Leistung kommt, welche benötigt wird, bzw auf die begrenzt wird?

              Dev of LightControl Adapter, Contributor of HUE and DoorBird Adapter

              Ralla66R 1 Antwort Letzte Antwort
              0
              • SchmakusS Schmakus

                @ralla66 Hi, verstehe ich nicht. Liegt aber vermutlich an meinen noch nicht existierenden Knowhow. :see_no_evil:
                Welche Rolle spielt es, wenn in Summe die Leistung kommt, welche benötigt wird, bzw auf die begrenzt wird?

                Ralla66R Offline
                Ralla66R Offline
                Ralla66
                Most Active
                schrieb am zuletzt editiert von Ralla66
                #8

                @schmakus sagte in [Vorlage] Hoymiles Wechselrichter Begrenzung mit openDTU:

                wenn in Summe die Leistung kommt

                bezogen auf die eingespeiste Strom Menge aber weniger.
                100 Watt -> 92 % Wirkungsgrad macht 92 Watt zum Verbrauch
                100 Watt -> 70 % Wirkungsgrad macht 72 Watt zum Verbrauch

                SchmakusS 1 Antwort Letzte Antwort
                0
                • Ralla66R Ralla66

                  @schmakus sagte in [Vorlage] Hoymiles Wechselrichter Begrenzung mit openDTU:

                  wenn in Summe die Leistung kommt

                  bezogen auf die eingespeiste Strom Menge aber weniger.
                  100 Watt -> 92 % Wirkungsgrad macht 92 Watt zum Verbrauch
                  100 Watt -> 70 % Wirkungsgrad macht 72 Watt zum Verbrauch

                  SchmakusS Offline
                  SchmakusS Offline
                  Schmakus
                  Developer
                  schrieb am zuletzt editiert von
                  #9

                  @ralla66 sagte in [Vorlage] Hoymiles Wechselrichter Begrenzung mit openDTU:

                  @schmakus sagte in [Vorlage] Hoymiles Wechselrichter Begrenzung mit openDTU:

                  wenn in Summe die Leistung kommt

                  bezogen auf die eingespeiste Strom Menge aber weniger.
                  100 Watt -> 92 % Wirkungsgrad macht 92 Watt zum Verbrauch
                  100 Watt -> 70 % Wirkungsgrad macht 72 Watt zum Verbrauch

                  Ok, stehe immer noch etwas auf dem Schlauch.
                  Bedeutet das, die Begrenzung der WR bezieht sich nicht auf die AC-Leistung, sondern DC-Leistung?

                  Dev of LightControl Adapter, Contributor of HUE and DoorBird Adapter

                  Ralla66R 1 Antwort Letzte Antwort
                  0
                  • SchmakusS Schmakus

                    @ralla66 sagte in [Vorlage] Hoymiles Wechselrichter Begrenzung mit openDTU:

                    @schmakus sagte in [Vorlage] Hoymiles Wechselrichter Begrenzung mit openDTU:

                    wenn in Summe die Leistung kommt

                    bezogen auf die eingespeiste Strom Menge aber weniger.
                    100 Watt -> 92 % Wirkungsgrad macht 92 Watt zum Verbrauch
                    100 Watt -> 70 % Wirkungsgrad macht 72 Watt zum Verbrauch

                    Ok, stehe immer noch etwas auf dem Schlauch.
                    Bedeutet das, die Begrenzung der WR bezieht sich nicht auf die AC-Leistung, sondern DC-Leistung?

                    Ralla66R Offline
                    Ralla66R Offline
                    Ralla66
                    Most Active
                    schrieb am zuletzt editiert von
                    #10

                    @schmakus

                    das hat nichts mit der Begrenzung zu tun, sondern mit reingesteckter Energie zu gewandelter nutzbarer Energie.
                    Verluste die der WR beim Wandeln selbst verbraucht.

                    SchmakusS 1 Antwort Letzte Antwort
                    0
                    • Ralla66R Ralla66

                      @schmakus

                      das hat nichts mit der Begrenzung zu tun, sondern mit reingesteckter Energie zu gewandelter nutzbarer Energie.
                      Verluste die der WR beim Wandeln selbst verbraucht.

                      SchmakusS Offline
                      SchmakusS Offline
                      Schmakus
                      Developer
                      schrieb am zuletzt editiert von
                      #11

                      @ralla66 sagte in [Vorlage] Hoymiles Wechselrichter Begrenzung mit openDTU:

                      @schmakus

                      das hat nichts mit der Begrenzung zu tun, sondern mit reingesteckter Energie zu gewandelter nutzbarer Energie.
                      Verluste die der WR beim Wandeln selbst verbraucht.

                      Verstehe. Es wäre jedoch eh besser, auf die tatsächliche Einspeisung zu begrenzen.

                      Dev of LightControl Adapter, Contributor of HUE and DoorBird Adapter

                      Ralla66R 1 Antwort Letzte Antwort
                      0
                      • SchmakusS Schmakus

                        @ralla66 sagte in [Vorlage] Hoymiles Wechselrichter Begrenzung mit openDTU:

                        @schmakus

                        das hat nichts mit der Begrenzung zu tun, sondern mit reingesteckter Energie zu gewandelter nutzbarer Energie.
                        Verluste die der WR beim Wandeln selbst verbraucht.

                        Verstehe. Es wäre jedoch eh besser, auf die tatsächliche Einspeisung zu begrenzen.

                        Ralla66R Offline
                        Ralla66R Offline
                        Ralla66
                        Most Active
                        schrieb am zuletzt editiert von
                        #12

                        @schmakus

                        Genau, begrenzen auf den aktuellen Verbrauch, Rest in den Speicher. :-)

                        1 Antwort Letzte Antwort
                        0
                        Antworten
                        • In einem neuen Thema antworten
                        Anmelden zum Antworten
                        • Älteste zuerst
                        • Neuste zuerst
                        • Meiste Stimmen


                        Support us

                        ioBroker
                        Community Adapters
                        Donate

                        682

                        Online

                        32.6k

                        Benutzer

                        82.2k

                        Themen

                        1.3m

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

                        • Du hast noch kein Konto? Registrieren

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