Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Hardware
    4. Sungrow WR SGH10RT MODBUS ioSkripte

    NEWS

    • [erledigt] 15. 05. Wartungsarbeiten am ioBroker Forum

    • ioBroker goes Matter ... Matter Adapter in Stable

    • Monatsrückblick - April 2025

    Sungrow WR SGH10RT MODBUS ioSkripte

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

      Hallo zusammen,

      ich dachte mir als Folgethema für:
      "Sungrow WR SGH10RT erfolgreich mit MODBUS eingebunden" von @Atlantis
      könnten Skripte interessant sein, die sich in ioBroker mit Sungrow Hardware nutzen lassen.

      Also für alle die einen Sungrow WR und evtl. Akku und ioBroker ihr Eigen nennen.

      Wichtig wäre nur, dass ein paar Rahmenparameter angegeben werden (gerne ergänzen):

      Sungrow WR: SH10RT
      Akku: SBR160
      Beschreibung: Gibt in der Einheit Watt im Datenpunkt
      "0_userdata.0.PV_Datenpunkte.Berechnung_Batterieentladung_negativ" aus, ob Batterie be- oder entladen wird.
      Testen: read only Datenpunkt modbus.0.inputRegisters.13007_Load_power_ ohne Bestätigung verändern.

      e7a849b9-1c7a-41d0-b264-4fcf17f25c22-image.png

      Sungrow Leistung positiv negativ.xml

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

        Sungrow WR: SH10RT
        Akku: SBR160
        Beschreibung: Gibt in Datenpunk 0_userdata.0.PV_Datenpunkte.Überschussstrom
        eine 0 oder 1 aus, wenn Akku bei 97% ist und 150 Watt PV Leistung anliegen, Werte können angepasst werden. Hab damit ne VIS Visualisierung gesteuert, damit ich sehe, wann Überschuss da ist.
        Testen: Bedingungen in Blockly vorübergehend verändern, z.B. auf Bedingung Akku kleiner 100% und PV Leistung auf aktuelle Leistung einstellen, damit Bedingungen erfüllt sind.

        017dadd1-1ffd-40dc-b288-adb97d8f623f-image.png

        Ueberschuss ja oder nein.xml

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

          Hoffe das ich hier keine Daten meines Telegram Accounst teile, sonst wär ich für Info dankbar.
          Bin nicht sehr fit in Blockly, muss ich sagen...

          Sungrow WR: SH10RT
          Akku: SBR160
          Beschreibung: Dieses Skript verlangt eine Telegram Instanz. Es prüft alle zwei Monate die Akkuqualität und sendet eine Nachricht auf mein Handy, sollte sich die Qualität des Akkus irgendwann verschlechtern und auf unter X% rutschen.

          Testen: Den Datenpunkt modbus.0.inputRegisters.13023_Battery_state_of_health der read only ist auf niedrigen Wert setzen. Er springt direkt zurück, aber löst das Skript aus.

          c7e4ee6e-bc91-42f5-9fc1-1786848ba79a-image.png

          Warnung Telegram bei schlechtem Akku.xml

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

            Das hier nutze ich sehr gerne, war tricky die Gerätevariable hinzubekommen.

            Funktioniert nicht perfekt, manchmal reagiert der Alexa Adapter zu langsam mit dem Update der history, dann kommt die Sprache auf dem vorher verwendeten Gerät raus... Dann kann man "Alexa Test" sagen und den Vorgang wiederholen, dann sollte history aktualisiert sein.

            Sungrow WR: SH10RT
            Akku: SBR160
            Beschreibung: Der Trigger ist ein Datenpunkt als Schalter (true, false). Ich habe ihn über den iot Adapter in Alexa eingebunden, dann eine Routine erstellt. Sage ich "Photovoltaik" dann schaltet Alexa den Schalter.
            Alexa gibt auf dem Gerät zu dem ich spreche (Smartphone App geht nicht) den aktuellen Ertrag in Watt, Tagesertrag in kW und Batteriefüllstand in Prozent aus.
            Testen: Veränderung des Trigger-Datenpunktes

            8e0d8258-62c7-4ac8-9bf5-110a8fa2ed64-image.png

            Alexa nennt PV Werte.xml

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

              @mraiobroker sagte in Sungrow WR SGH10RT MODBUS ioSkripte:

              Sungrow Leistung positiv negativ.xml

              Habe den Hinweis von @GombersIOB umgesetzt und Code gegen Screenshots und XML files ersetzt, für mehr Übersichtlichkeit.
              Da ich seit ein paar Tagen der Herausforderung als Windows user wegen auf einen Mac umgestiegen bin, hoffe ich, dass das alles so passt. Gebt mir nen kurzen ping, wenn das jemand erfolgreich importieren konnte.

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

                Ganz schön still hier, hatte auf etwas mehr Beteiligung gehofft, wenn ich ehrlich bin 😊

                G 1 Reply Last reply Reply Quote 0
                • G
                  GombersIOB @MRaioBroker last edited by GombersIOB

                  @mraiobroker

                  Ganz schön still hier

                  Das Problem ist, dass man das hier irgendwie nicht findet. Ich habe mir ein Lesezeichen dafür gesetzt. Atlantis hat ja auch eine Thread zum steuern der Batterie gesetzt, da ist auch tote Hose. Die Idee für eine Programmsammlung ist ja sehr gut - aber das Forum bietet für so was irgendwie nicht das geeignete Format.
                  Ich habe auch kein Gefühl dafür, ob das was ich mache, für irgendwen relevant ist. Ein paar Bilder habe ich ja gepastet. Das scheint ja für jeden offensichtlich oder uninteressant zu sein - wie ich aufgrund der fehlenden Nachfragen annehmen muss. Von daher fürchte ich fast, dass dieser Thread nicht sehr gut besucht sein wird.

                  G M 2 Replies Last reply Reply Quote 0
                  • G
                    GombersIOB @GombersIOB last edited by GombersIOB

                    @gombersiob

                    Hier mein erster Beitrag

                    Idee: Ich möchte gerne mal sehen, wie die Spitzen meiner neuen PV-Anlage aussehen. Dafür habe ich mir eine Blockly geschrieben (TS ist mir eigentlich lieber). Es macht folgendes:

                    • Schreibt den höchsten je gefundenen Leistungswert der Stromgenerierung weg - zusammen mit der Uhrzeit, wann es auftrat.
                    • Zählt für bestimmte Schwellwerte, wie oft sie überschritten wurden. Ich habe eine 8,5kWp-Anlage, habe deshalb die Schwellwerte 7500, 8000, 8500 und 8700 gewählt.

                    Das Layout der Datapoints dafür sieht so aus:
                    1ff2f74e-0e49-4943-9d63-643df698f0a3-grafik.png

                    /* Setup Datapoints for Maxima blockly script */
                    let prefix:string = '0_userdata.0.Sungrow.Maxima.';
                    let zero:number = 0;
                    let today:string = new Date().toString();
                    createState(prefix+'Bigger7500', zero, {
                    	name: "Anzahl PV-Leistungen über 7500 Watt",
                    	type: 'number',
                    	role: 'value'
                    });
                    createState(prefix+'Bigger8000', zero, {
                    	name: "Anzahl PV-Leistungen über 8000 Watt",
                    	type: 'number',
                    	role: 'value'
                    });
                    createState(prefix+'Bigger8500', zero, {
                    	name: "Anzahl PV-Leistungen über 8500 Watt",
                    	type: 'number',
                    	role: 'value'
                    });
                    createState(prefix+'Bigger8700', zero, {
                    	name: "Anzahl PV-Leistungen über 8700 Watt",
                    	type: 'number',
                    	role: 'value'
                    });
                    createState(prefix+'MaximumPowerGeneration', zero, {
                    	name: "Größte erzeugte Leistung an den Modulen",
                    	type: 'number',
                    	role: 'value'
                    });
                    createState(prefix+'MaximumPowerGenerationTime', zero, {
                    	name: "Uhrzeit der größten erzeugten Leistung",
                    	type: 'string',
                    	role: 'value'
                    });
                    


                    In der Variablen "prefix" lege ich den gewünschten Pfad fest. Verzeichnisse, die noch nicht existieren, werden autmatisch angelegt. Der Punkt am Ende, als Trennung zwischen Verzeichnis und Datenpunkt ist wichtig.
                    Das Script kann mehrfach laufen, zum Beispiel um weitere Datenpunkte zuzufügen - Datenpunkte, die einmal angelegt sind werfen einen Fehler aus, mehr passiert nicht.

                    Das hier ist jetzt das Blockly-Script als Bild:
                    31796591-aadb-4ee8-8393-68038f6fd3ac-grafik.png

                    Und als importierbarer Text:
                    MaximumPowerGeneration.xml

                    M M G 3 Replies Last reply Reply Quote 0
                    • M
                      MRaioBroker @GombersIOB last edited by

                      @gombersiob
                      sehr cool, danke für den Beitrag.
                      Mein Solarteur hat mir einen 10kW WR und eine 16er Anlage verbaut, erst heute weiß ich was das bedeutet und wie das Verhältnis sein sollte...

                      Hab dann ECharts genutzt und es grafisch gelöst. Werde wohl den halben Sommer über den 10kW des WR liegen

                      Mir war es eh wichtiger im Winter viel Strom zu haben, daher das ganze Dach voll gemacht, im Sommer nicht alles nutzen zu können.... ist dann halt so - gibt ja eh kaum Geld dafür.
                      Trotzdem wichtig das zu überwachen, finde ich.

                      Carsten Sauermann 1 Reply Last reply Reply Quote 0
                      • M
                        MRaioBroker @GombersIOB last edited by

                        @gombersiob sagte in Sungrow WR SGH10RT MODBUS ioSkripte:

                        as Problem ist, dass man das hier irgendwie nicht findet.

                        Hab jetzt einfach mal noch viele tags eingefügt. Vielleicht bringt´s ja Besucher

                        1 Reply Last reply Reply Quote 0
                        • N
                          newbie_near_cologne last edited by

                          Hallo zusammen, meine Eltern nutzen auch einen Sungrow SH10RT und ich habe zur Überwachung/Visualisierung den ioBroker auf einem Raspberry im Einsatz. Gute Idee mit der Skriptsammlung. Kann aber aktuell nichts an Skripten zum Thread beitragen.

                          1 Reply Last reply Reply Quote 0
                          • M
                            mpl1338 @GombersIOB last edited by mpl1338

                            @gombersiob

                            das script zum anlegen funktioniert nicht

                            Screenshot 2023-03-04 213153.png

                            1
                            PID
                            Zeit
                            error
                            Nachricht
                            
                            javascript.0
                            3497131	2023-03-04 21:23:23.371	error	at processImmediate (node:internal/timers:468:21)
                            
                            javascript.0
                            3497131	2023-03-04 21:23:23.371	error	at Immediate._onImmediate (/opt/iobroker/node_modules/iobroker.javascript/main.js:1587:17)
                            
                            javascript.0
                            3497131	2023-03-04 21:23:23.371	error	at /opt/iobroker/node_modules/iobroker.javascript/main.js:2113:17
                            
                            javascript.0
                            3497131	2023-03-04 21:23:23.371	error	at prepareScript (/opt/iobroker/node_modules/iobroker.javascript/main.js:2015:37)
                            
                            javascript.0
                            3497131	2023-03-04 21:23:23.371	error	at createVM (/opt/iobroker/node_modules/iobroker.javascript/main.js:1762:21)
                            
                            javascript.0
                            3497131	2023-03-04 21:23:23.371	error	at new Script (node:vm:100:7)
                            
                            javascript.0
                            3497131	2023-03-04 21:23:23.371	error	SyntaxError: Unexpected token ':'
                            
                            javascript.0
                            3497131	2023-03-04 21:23:23.371	error	^
                            
                            javascript.0
                            3497131	2023-03-04 21:23:23.370	error	let prefix:string = '0_userdata.0.Sungrow.Maxima.';
                            
                            javascript.0
                            3497131	2023-03-04 21:23:23.370	error	script.js.PV.Skript_1 compile failed: at script.js.PV.Skript_1:2
                            
                            G 1 Reply Last reply Reply Quote 0
                            • G
                              GombersIOB @mpl1338 last edited by

                              @mpl1338 said in Sungrow WR SGH10RT MODBUS ioSkripte:

                              das script zum anlegen funktioniert nicht

                              Das Script ist vom Typ "TypeScript". JavaScript hat keine Typensicherheit.

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

                                das habe ich überlesen 😵

                                1 Reply Last reply Reply Quote 0
                                • G
                                  GombersIOB @GombersIOB last edited by GombersIOB

                                  @gombersiob
                                  Zum Darstellen der Erträge mache ich mir Auswertungen "pro Tag", "pro Monat" und "pro Jahr". Hier will ich mal die Auswertung "pro Tag" darstellen, die anderen kann man ja davon ableiten

                                  • 13.3.2023 - Tippfehler im DaySwitch korrigiert
                                  • 12.3.2023 - Habe meine eigenen DataPoint und Variablennamen überarbeitet. Deshalb alle Scripte ausgetauscht
                                  • 11.3.2023 - Rechnung der Verluste aus Batterie Charge/Discharge

                                  Idee: Über VIS will ich sehen, wie sich der tägliche Verbrauch gestaltet. Ich stelle dabei den heutigen Tag, dem gestrigen "gegenüber". "Gegenüber" in Anführungszeichen, weil ich sie untereinander darstelle. Denn ich will dasselbe Bild auf Computer, IPad und Handy darstellen. Nebeneinander müsste ich auf dem Handy hin und her scrollen.
                                  So sieht derzeit das Gesamtbild aus:
                                  37e04f9d-78cb-41b6-92ab-07e06afa6c27-grafik.png

                                  Die Datenpunkte sehen so aus:
                                  67c7bf33-7198-49b1-9ec8-acaa41041ed1-grafik.png
                                  Es sind Datenpunkte dabei, die ich anderswo oder auch nicht mehr verwende. Da muss ich mal aufräumen!

                                  Setup der Datenpunkte mache ich wieder mit einem TypeScript-Programm. Das ist recht nützlich. Ich habe schon ein paarmal alles platt gemacht und neu angefangen. Jeden Datenpunkt einzeln zu definieren ist nervig.

                                  /**
                                  * Yesterday
                                  */
                                  let today = new Date();
                                  let milliSeconds = today.getTime();
                                  let milliSecondsOfADay = 24*60*60*1000;
                                  let yesterday = new Date(milliSeconds-milliSecondsOfADay);
                                  let prevDate:string = yesterday.toLocaleDateString('de-DE');
                                  let prevEnergyConsumed:number = 11.1832;
                                  let prevEnergyImported:number=0.3;
                                  let prevEnergyOwnConsumed:number=10.1;
                                  let prevEnergyDirectPvConsumed:number=3.3;
                                  let prevEnergyBatteryConsumed:number=6.8;
                                  let prevEnergyGenerated:number = 21.3;
                                  let prevEnergyExported:number = 8.9;
                                  let prevEnergyBatteryLoss:number = 0.7832;
                                  let prevBatteryChargeFromGrid:number = 0.1;
                                  let prevBatteryDischargeToGrid:number = 0;
                                  let prevEOD_BatteryLevel:number = 48.4;
                                  
                                  let prevPercentConsumedFromImported:number = 0;
                                  let prevPercentConsumedFromOwn:number = 0;
                                  let prevPercentConsumedFromDirectPv:number = 0;
                                  let prevPercentConsumedFromBattery:number = 0;
                                  let prevPercentEnergyBatteryLoss:number = 0;
                                  
                                  if (prevEnergyConsumed > 0) {
                                  
                                  	prevPercentConsumedFromImported = prevEnergyImported * 100 / prevEnergyConsumed;
                                  	prevPercentConsumedFromOwn = prevEnergyOwnConsumed * 100 / prevEnergyConsumed;
                                  	prevPercentConsumedFromDirectPv = prevEnergyDirectPvConsumed * 100 / prevEnergyConsumed;
                                  	prevPercentConsumedFromBattery = prevEnergyBatteryConsumed * 100 / prevEnergyConsumed;
                                  	prevEnergyBatteryLoss = prevEnergyBatteryLoss * 100 / prevEnergyConsumed;
                                  }
                                  let prevPercentEnergyExported:number = 0;
                                  if (prevEnergyGenerated > 0) {
                                  
                                  	prevPercentEnergyExported = prevEnergyExported * 100 / prevEnergyGenerated;
                                  }
                                  let prefix:string = '0_userdata.0.Sungrow.EarningsPerDay.Yesterday.';
                                  doCreateStateString(prefix, "Date", "Yesterday", prevDate);
                                  doCreateStateNumber(prefix, "EnergyConsumed", "Yesterday", prevEnergyConsumed);
                                  doCreateStateNumber(prefix, "EnergyImported", "Yesterday", prevEnergyImported);
                                  doCreateStateNumber(prefix, "EnergyOwnConsumed", "Yesterday", prevEnergyOwnConsumed);
                                  doCreateStateNumber(prefix, "EnergyDirectPvConsumed", "Yesterday", prevEnergyDirectPvConsumed);
                                  doCreateStateNumber(prefix, "EnergyBatteryConsumed", "Yesterday", prevEnergyBatteryConsumed);
                                  doCreateStateNumber(prefix, "EnergyBatteryLoss", "Yesterday", prevEnergyBatteryLoss);
                                  doCreateStateNumber(prefix, "EnergyGenerated", "Yesterday", prevEnergyGenerated);
                                  doCreateStateNumber(prefix, "EnergyExported", "Yesterday", prevEnergyExported);
                                  doCreateStateNumber(prefix, "EOD-BatteryLevel", "Yesterday", prevEOD_BatteryLevel, 1);
                                  doCreateStateNumber(prefix, "BatteryChargeFromGrid", "Yesterday", prevBatteryChargeFromGrid);
                                  doCreateStateNumber(prefix, "BatteryDischargeToGrid", "Yesterday", prevBatteryDischargeToGrid);
                                  doCreateStateNumber(prefix, "PercentConsumedFromImported", "Yesterday", prevPercentConsumedFromImported);
                                  doCreateStateNumber(prefix, "PercentConsumedFromOwn", "Yesterday", prevPercentConsumedFromOwn);
                                  doCreateStateNumber(prefix, "PercentConsumedFromDirectPv", "Yesterday", prevPercentConsumedFromDirectPv);
                                  doCreateStateNumber(prefix, "PercentConsumedFromBattery", "Yesterday", prevPercentConsumedFromBattery);
                                  doCreateStateNumber(prefix, "PercentEnergyBatteryLoss", "Yesterday", prevPercentEnergyBatteryLoss);
                                  doCreateStateNumber(prefix, "PercentEnergyExported", "Yesterday", prevPercentEnergyExported);
                                  
                                  /**
                                  * Today
                                  */
                                  let nowDate:string = new Date().toLocaleDateString('de-DE');
                                  let nowEnergyBatteryLevelStart:number = 48.4;
                                  
                                  let nowEnergyConsumed:number = 0;
                                  let nowEnergyImported:number=0;
                                  let nowEnergyOwnConsumed:number=0;
                                  let nowEnergyDirectPvConsumed:number=0;
                                  let nowEnergyBatteryConsumed:number=0;
                                  let nowEnergyGenerated:number = 0;
                                  let nowEnergyExported:number = 0;
                                  let nowEnergyBatteryLoss:number = 0;
                                  let nowBatteryChargeFromGrid:number = 0;
                                  let nowBatteryDischargeToGrid:number = 0;
                                  let nowPercentConsumedFromImported:number = 0;
                                  let nowPercentConsumedFromOwn:number = 0;
                                  let nowPercentConsumedFromDirectPv:number = 0;
                                  let nowPercentConsumedFromBattery:number = 0;
                                  let nowPercentEnergyBatteryLoss:number = 0;
                                  if (nowEnergyConsumed > 0) {
                                  
                                  	nowPercentConsumedFromImported = nowEnergyImported * 100 / nowEnergyConsumed;
                                  	nowPercentConsumedFromOwn = nowEnergyOwnConsumed * 100 / nowEnergyConsumed;
                                  	nowPercentConsumedFromDirectPv = nowEnergyDirectPvConsumed * 100 / nowEnergyConsumed;
                                  	nowPercentConsumedFromBattery = nowEnergyBatteryConsumed * 100 / nowEnergyConsumed;
                                  	nowEnergyBatteryLoss = nowEnergyBatteryLoss * 100 / nowEnergyConsumed;
                                  }
                                  let nowPercentEnergyExported:number = 0;
                                  if (nowEnergyGenerated > 0) {
                                  
                                  	nowPercentEnergyExported = nowEnergyExported * 100 / nowEnergyGenerated;
                                  }
                                  prefix = '0_userdata.0.Sungrow.EarningsPerDay.Today.';
                                  doCreateStateString(prefix, "Date", "Today", nowDate);
                                  
                                  doCreateStateNumber(prefix, "EnergyBatteryLevelStart", "Today", nowEnergyBatteryLevelStart, 1);
                                  
                                  doCreateStateNumber(prefix, "EnergyConsumed", "Today", nowEnergyConsumed);
                                  doCreateStateNumber(prefix, "EnergyImported", "Today", nowEnergyImported);
                                  doCreateStateNumber(prefix, "EnergyOwnConsumed", "Today", nowEnergyOwnConsumed);
                                  doCreateStateNumber(prefix, "EnergyDirectPvConsumed", "Today", nowEnergyDirectPvConsumed);
                                  doCreateStateNumber(prefix, "EnergyBatteryConsumed", "Today", nowEnergyBatteryConsumed);
                                  doCreateStateNumber(prefix, "EnergyBatteryLoss", "Today", nowEnergyBatteryLoss);
                                  doCreateStateNumber(prefix, "EnergyGenerated", "Today", nowEnergyGenerated);
                                  doCreateStateNumber(prefix, "EnergyExported", "Today", nowEnergyExported);
                                  doCreateStateNumber(prefix, "BatteryChargeFromGrid", "Today", nowBatteryChargeFromGrid);
                                  doCreateStateNumber(prefix, "BatteryDischargeToGrid", "Today", nowBatteryDischargeToGrid);
                                  doCreateStateNumber(prefix, "PercentConsumedFromImported", "Today", nowPercentConsumedFromImported);
                                  doCreateStateNumber(prefix, "PercentConsumedFromOwn", "Today", nowPercentConsumedFromOwn);
                                  doCreateStateNumber(prefix, "PercentConsumedFromDirectPv", "Today", nowPercentConsumedFromDirectPv);
                                  doCreateStateNumber(prefix, "PercentConsumedFromBattery", "Today", nowPercentConsumedFromBattery);
                                  doCreateStateNumber(prefix, "PercentEnergyBatteryLoss", "Today", nowPercentEnergyBatteryLoss);
                                  doCreateStateNumber(prefix, "PercentEnergyExported", "Today", nowPercentEnergyExported);
                                  
                                  
                                  function doCreateStateNumber(prefix:string, datapoint:string, nameSuffix:string, value:number, decimals:number=0) {
                                  
                                  	createState(prefix + datapoint, iobGlbl_roundToDecimals(value, decimals) , {
                                  
                                  		name: datapoint+nameSuffix,
                                  		type: 'number',
                                  		role: 'value'
                                  
                                  	})
                                  });
                                  function doCreateStateString(prefix:string, datapoint:string, nameSuffix:string, value:string) {
                                  
                                  	createState(prefix + datapoint, value, {
                                  
                                  		name: datapoint+nameSuffix,
                                  		type: 'string',
                                  		role: 'value'
                                  
                                  	})
                                  });
                                  

                                  Dann habe ich noch ein Blockly für den Tageswechsel (läuft täglich, wie man sehen kann, um 23:59 Uhr):
                                  c9286e6f-f51c-492f-8386-31fd805df7b0-grafik.png
                                  Hier das XML-Unload des Blockly: DaySwitch.blockly
                                  Und natürlich ein Script, dass unter Tage die Sicht auf den laufenden Tag aktuell hält. Auch das ist wieder ein TypeScript. Ich finde dafür Blockly doch zu unhandlich.

                                  
                                  // Daily energy consumption distributed to the sources
                                  // by absolute values and percentages
                                  schedule("* * * * *", async function () {
                                  
                                  	let prefix = '0_userdata.0.Sungrow.EarningsPerDay.Today.';
                                  	// Get start values
                                  	let energyBatteryLevelStart = Number(getState(prefix+"EnergyBatteryLevelStart").val);
                                  	// Get current registers
                                  	prefix = 'modbus.0.inputRegisters.';
                                  	let totalModBusDataAsJson =
                                  	{
                                  
                                  		"energyImport": Number(getState(prefix+"13035_Daily_Import_Energy").val),
                                  		"directPvConsumption": Number(getState(prefix+"13016_Daily_Direct_Energy_Consumption").val),
                                  		"energyGeneration": Number(getState(prefix+"13001_Daily_PV_Generation").val),
                                  		"energyExport": Number(getState(prefix+"13044_Daily_Export_Energy").val),
                                  		"energyExportFromPv": Number(getState(prefix+"13004_Daily_Export_Energy_from_PV").val),
                                  		"energyBatteryCharge": Number(getState(prefix+"13039_Daily_Charge_Energy").val),
                                  		"energyBatteryChargeFromPV": Number(getState(prefix+"13011_Daily_Battery_Charge_Energy_from_PV").val),
                                  		"energyBatteryDischarge": Number(getState(prefix+"13025_Daily_Battery_Discharge_Energy").val),
                                  		"energyBatteryCapacity": Number(getState(prefix+"13038_Battery_Capacity").val),
                                  		"energyBatteryLevel": Number(getState(prefix+"13022_Battery_Level_").val),
                                  		"energyBatteryLevelStart": energyBatteryLevelStart,
                                  
                                  	};
                                  
                                  	let result = ioGlobl_calculateTheEarnings(JSON.stringify(totalModBusDataAsJson));
                                  	let resultJson = JSON.parse(result);
                                  	// Persist calculated values
                                  	prefix = '0_userdata.0.Sungrow.EarningsPerDay.Today.';
                                  	setState(prefix+'EnergyConsumed', iobGlbl_roundToDecimals(resultJson.energyConsumption, 1), true);
                                  	setState(prefix+'EnergyImported', iobGlbl_roundToDecimals(resultJson.energyImport, 1), true);
                                  	setState(prefix+'EnergyOwnConsumed', iobGlbl_roundToDecimals(resultJson.energyOwnConsumption, 1), true);
                                  	setState(prefix+'EnergyDirectPvConsumed', iobGlbl_roundToDecimals(resultJson.energyPvConsumption, 1), true);
                                  	setState(prefix+'EnergyBatteryConsumed', iobGlbl_roundToDecimals(resultJson.energyBatteryConsumption, 1), true);
                                  	setState(prefix+"EnergyBatteryLoss", iobGlbl_roundToDecimals(resultJson.energyBatteryLoss,1));
                                  	setState(prefix+'EnergyGenerated', iobGlbl_roundToDecimals(resultJson.energyGeneration, 1), true);
                                  	setState(prefix+'EnergyExported', iobGlbl_roundToDecimals(resultJson.energyExport, 1), true);
                                  	setState(prefix+'BatteryChargeFromGrid', iobGlbl_roundToDecimals(resultJson.batteryChargeFromGrid, 1), true);
                                  	setState(prefix+'BatteryDischargeToGrid', iobGlbl_roundToDecimals(resultJson.batteryDischargeToGrid, 1), true);
                                  	setState(prefix+'PercentConsumedFromImported', iobGlbl_roundToDecimals(resultJson.percentImport, 0), true);
                                  	setState(prefix+'PercentConsumedFromOwn', iobGlbl_roundToDecimals(resultJson.percentOwnConsumption, 0), true);
                                  	setState(prefix+'PercentConsumedFromDirectPv', iobGlbl_roundToDecimals(resultJson.percentPvConsumption, 0), true);
                                  	setState(prefix+'PercentConsumedFromBattery', iobGlbl_roundToDecimals(resultJson.percentBatteryConsumption, 0), true);
                                  	setState(prefix+"PercentEnergyBatteryLoss", iobGlbl_roundToDecimals(resultJson.percentBatteryLoss,0));
                                   	setState(prefix+'PercentEnergyExported', iobGlbl_roundToDecimals(resultJson.percentExport, 0), true);
                                  });
                                  
                                  /**
                                   * We are called with derived modbus data and we will caclulate sum sums and percentages
                                   */
                                  function ioGlobl_calculateTheEarnings(modBusData) {
                                  
                                  	let modBusJson = JSON.parse(modBusData);
                                  	/* calculate */
                                  	let batteryChargeFromGrid = modBusJson.energyBatteryCharge - modBusJson.energyBatteryChargeFromPV;
                                  	let batteryDischargeToGrid = modBusJson.energyExport-modBusJson.energyExportFromPv;
                                  	let energyBatteryConsumption = modBusJson.energyBatteryDischarge - batteryDischargeToGrid;
                                  	
                                  	let energyOwnConsumption = energyBatteryConsumption + modBusJson.directPvConsumption;
                                  	let energyBatteryContentStart = modBusJson.energyBatteryCapacity * modBusJson.energyBatteryLevelStart / 100;
                                  	let energyBatteryContentNow = modBusJson.energyBatteryCapacity * modBusJson.energyBatteryLevel / 100;
                                  	let energyBatteryContentExpected = energyBatteryContentStart + modBusJson.energyBatteryCharge - modBusJson.energyBatteryDischarge;
                                  	let energyBatteryLoss = energyBatteryContentExpected - energyBatteryContentNow;
                                  //	console.log("Contt: " +  modBusJson.energyBatteryCapacity + " * " + modBusJson.energyBatteryLevelStart + " / 100 " +  " = " + energyBatteryContentStart);
                                  //	console.log("Expct: " + energyBatteryContentStart + " + " + modBusJson.energyBatteryCharge + " - " + modBusJson.energyBatteryDischarge + " = " + energyBatteryContentExpected);
                                  //	console.log("Loss: " + energyBatteryContentExpected + " - " + energyBatteryContentNow + " = " + energyBatteryLoss);
                                  	if (energyBatteryLoss < 0) {
                                  		energyBatteryLoss = 0;
                                  	}
                                  
                                  	let energyConsumption = modBusJson.energyImport + energyOwnConsumption + energyBatteryLoss;
                                  // console.log("Cons: " + modBusJson.energyImport + " + " + energyOwnConsumption + " + " + energyBatteryLoss + " = " + energyConsumption);
                                  	let percentImport = 0;
                                  	let percentOwnConsumption = 0;
                                  	let percentPvConsumption = 0;
                                  	let percentBatteryConsumption = 0;
                                  	let percentBatteryLoss = 0;
                                  	let percentExport = 0;
                                  
                                  	if (energyConsumption > 0) {
                                  		percentImport = modBusJson.energyImport * 100 / energyConsumption;
                                  		percentOwnConsumption = energyOwnConsumption * 100 / energyConsumption;
                                  		percentPvConsumption = modBusJson.directPvConsumption * 100 / energyConsumption;
                                  		percentBatteryConsumption = energyBatteryConsumption * 100 / energyConsumption;
                                  		percentBatteryLoss = energyBatteryLoss * 100 / energyConsumption;
                                  
                                  	}
                                  	if ( modBusJson.energyGeneration > 0) {
                                  
                                  		percentExport = modBusJson.energyExport * 100 / modBusJson.energyGeneration;
                                  
                                  	}
                                  	let result = {
                                  
                                  		"energyConsumption": energyConsumption,
                                  		"energyImport": modBusJson.energyImport,
                                  		"energyOwnConsumption": energyOwnConsumption,
                                  		"energyPvConsumption": modBusJson.directPvConsumption,
                                  		"energyBatteryConsumption": energyBatteryConsumption,
                                  		"energyBatteryLoss": energyBatteryLoss,
                                  		"energyGeneration": modBusJson.energyGeneration,
                                  		"energyExport": modBusJson.energyExport,
                                  		"percentImport":percentImport,
                                  		"percentOwnConsumption": percentOwnConsumption,
                                  		"percentPvConsumption":  percentPvConsumption,
                                  		"percentBatteryConsumption": percentBatteryConsumption,
                                  		"percentBatteryLoss": percentBatteryLoss,
                                  		"percentExport": percentExport,
                                          "batteryChargeFromGrid": batteryChargeFromGrid,
                                          "batteryDischargeToGrid": batteryDischargeToGrid,
                                  
                                  	};
                                  
                                  	return JSON.stringify(result);
                                  }
                                  
                                  
                                  


                                  • 9.3.2023 - 20:00: Berechnung "energyOwnConsumption" korrigiert

                                  Dieses Script ruft eine Function auf ("ioGlbl_roundToDecimals") mit der die errechnete Zahl auf die gewünschte Anzahl Nachkommastellen gerundet wird. Ich habe die bei mir als "Globale Funktion" definiert (d.h. in den Ordner "global"). Man kann Sie aber auch einfach direkt an das EarningsPerDay-Script oben anhängen.
                                  Die Kalkulationen habe ich jetzt auch in eine "Function" ausgelagert. Damit kann ich sie bei den EarningsPerMonth und EarningsPerYear einfach wiederverwenden - getreu dem Motto DRY (Don't repeat yourself).
                                  /*
                                  * Provide numbers with requested number of decimals
                                  */
                                  function iobGlbl_roundToDecimals(num = 0, decimals = 2) {
                                      var base = 1, i=decimals;
                                  	while (i > 0) {
                                  		base = base*10;
                                  		i--;
                                  	}
                                  	return +(Math.round(num*base))/base;
                                  }
                                  

                                  Bei mir läuft das Script minütlich. Das muss eigentlich nicht sein. Alle halbe Stunde würde auch reichen. Aber derzeit ist mein RaspBerry noch ganz entspannt - ich habe da keinen Druck.

                                  G 1 Reply Last reply Reply Quote 0
                                  • G
                                    GombersIOB @GombersIOB last edited by

                                    @gombersiob

                                    An anderer Stelle habe ich es schon erwähnt. Ich lese die ModBus-Daten (ohne IOBroker!) mit einem eigenen Java-Programm regelmäßig (alle 15 Minuten) und schreibe sie als XML-File weg. Dazu habe ich mir auf meinem RaspBerry eine JAVA-Runtime installiert und lasse es via crontab, wie gesagt viertelstündlich, laufen.

                                    Wenn Interesse an sowas besteht würde ich das Programm anpassen, damit es über Parameter personalisierbar wird. Derzeit mache ich alle Einstellungen direkt im Code.

                                    Ich füge hier mal die XML von heute ein, damit man sich ein Bild darüber machen kann.
                                    Der lese ich nur die Input-Register aus. Die Vorbereitung für die Holding-Register ist da, aber da sie mich nicht interessieren sammele ich sie auch (noch) nicht.

                                    2023_03-MARCH_12-data.xml

                                    K 1 Reply Last reply Reply Quote 0
                                    • K
                                      kklaus @GombersIOB last edited by

                                      Ich bin noch Anfänger und versuche gerade meine vielen Daten sinnvoll zu nutzen.
                                      Die Running States des SH10RT lese ich erfolgreich aus und einzelne Verbraucher (Heizstab Warmwasser, Kliaanlage zum heizen und kühlen, Wärmepumpe Pool, Fahrzeug Laden) schalten geht auch, wenn meist händisch. Das irgendwie zu automatisieren wäre mein Ziel.

                                      Hat hier Jemand die Daten ähnlich der ISolarCloud abgebildet und kann mir helfen das nachzubauen.

                                      M 1 Reply Last reply Reply Quote 0
                                      • M
                                        MRaioBroker @kklaus last edited by

                                        @kklaus

                                        das ist ne recht offene Frage. Wenn Du auf der Suche nach Skripts zur Automatisierung bist kann Dir hier evtl. geholfen werden.

                                        Zur Automatisierung: Ich selbst nutze ein paar Skripts z.B. um meine Wärmepumpe in den Smart Grid Modus zu schalten,
                                        teilen bringt aber nicht viel, weil recht spezifisch. Ich schalte z.B. einen Datenpunkt wenn ich Überschuss hab und mit dem schalte ich
                                        dann andere Dinge wie z.B. einen Shelly der meine Brauchwasser-Wärmepumpe aktiviert...
                                        (aber das auch. nur wenn ich am Vortag Strom zugekauft hab, wenn der Speicher noch voll ist bringts nicht ne Wärmepumpe mit PV Strom direkt zu steuern)

                                        Wichtiger als die Schaltung selbst ist die Intelligenz dahinter, damit man PV Strom auch wirklich sinnvoll nutzt.
                                        Bei Balkonkraftwerk recht einfach, da musst Du nur den Strom sinnvoll investieren
                                        Bei PV Anlage mit Speicher schon schwieriger, da musst Du verhindern, dass Du einspeist und nachkaufst.

                                        Vielleicht hilft das
                                        c42b1f8d-c6ac-4571-800a-4e94e3ab19d9-image.png

                                        App:
                                        Die Daten der App nachzustellen wäre evtl. ein anderes Thema hier im Forum z.B. https://forum.iobroker.net/post/972129
                                        Die App ist extrem umfangreich.

                                        Ich habe nur Teile die mich interessieren nachgebildet, die Visualisierung der App in IoBroker VIS mit dem Energieflussadapter andere Dinge in einer VIS
                                        die mich interessieren z.B. so

                                        240076bd-5b5f-402f-8866-128ed144967a-image.png
                                        30fdfda9-5038-481c-99a2-a1891f937808-image.png

                                        K R 2 Replies Last reply Reply Quote 0
                                        • K
                                          kklaus @MRaioBroker last edited by

                                          @mraiobroker Danke, ich stehe noch sehr am Anfang und habe nun erstmal alle Systeme eingebunden so dass sie Daten liefern.
                                          Den Energieflussadapter habe ich auch installiert, er läuft aber noch nicht mit den richtigen Daten und meine bisherigen Versuche zur Visualisierung und Steuerung sind noch sehr "rudimentär"!
                                          Welche Datenpunkte setzt Du im Energieflussadapter ein?

                                          PXL_20230427_081754195.jpg

                                          M 1 Reply Last reply Reply Quote 0
                                          • M
                                            MRaioBroker @kklaus last edited by

                                            @kklaus
                                            Du musst berechnen, ob die Batterie be oder entladen wird, dass kann Modbus so nicht

                                            7772425f-d675-42e6-8f32-a544ae2402c2-image.png

                                            Datenpunkt berechnen Skript
                                            a95f6b6b-e693-4a25-a2d0-eaf7aaf1bbef-image.png

                                            <xml xmlns="https://developers.google.com/blockly/xml">
                                              <variables>
                                                <variable id="(ocA``hXb:ASln87_[5i">PV Akku Be- oder Entladung</variable>
                                              </variables>
                                              <block type="on_ext" id="ehBZF8`0,PKLSMKg__PB" x="-2012" y="-487">
                                                <mutation xmlns="http://www.w3.org/1999/xhtml" items="1"></mutation>
                                                <field name="CONDITION">ne</field>
                                                <field name="ACK_CONDITION"></field>
                                                <value name="OID0">
                                                  <shadow type="field_oid" id="0m^saRA]WjVCQ`9A%2n8">
                                                    <field name="oid">modbus.0.inputRegisters.13007_Load_power_</field>
                                                  </shadow>
                                                </value>
                                                <statement name="STATEMENT">
                                                  <block type="variables_set" id="F`@4}oyq-b-2|/kYbR$U">
                                                    <field name="VAR" id="(ocA``hXb:ASln87_[5i">PV Akku Be- oder Entladung</field>
                                                    <value name="VALUE">
                                                      <block type="math_arithmetic" id="1Zv4~dL0,_aGpt}7[_kP">
                                                        <field name="OP">MINUS</field>
                                                        <value name="A">
                                                          <shadow type="math_number" id="d[QgpJU-{V|[)Y8g,,:@">
                                                            <field name="NUM">1</field>
                                                          </shadow>
                                                          <block type="math_arithmetic" id="5||kb1lHC-qwY!85c3KH">
                                                            <field name="OP">MINUS</field>
                                                            <value name="A">
                                                              <shadow type="math_number" id="lWjzQ^1^A)~nyY4K}k/%">
                                                                <field name="NUM">1</field>
                                                              </shadow>
                                                              <block type="get_value" id="v|oqCDrxh=7lS_fPh~*[">
                                                                <field name="ATTR">val</field>
                                                                <field name="OID">modbus.0.inputRegisters.5016_Total_DC_Power</field>
                                                              </block>
                                                            </value>
                                                            <value name="B">
                                                              <shadow type="math_number" id="hMTHE%-|Fip{Z1M$2d7y">
                                                                <field name="NUM">1</field>
                                                              </shadow>
                                                              <block type="get_value" id="pQL:D)uc#*C|yW94;;1U">
                                                                <field name="ATTR">val</field>
                                                                <field name="OID">modbus.0.inputRegisters.13007_Load_power_</field>
                                                              </block>
                                                            </value>
                                                          </block>
                                                        </value>
                                                        <value name="B">
                                                          <shadow type="math_number" id="LWB:(CTORxv:`-#$RF=q">
                                                            <field name="NUM">1</field>
                                                          </shadow>
                                                          <block type="get_value" id="E}0?u4:S)mn)6}@G9fd]">
                                                            <field name="ATTR">val</field>
                                                            <field name="OID">modbus.0.inputRegisters.13009_Export_power</field>
                                                          </block>
                                                        </value>
                                                      </block>
                                                    </value>
                                                    <next>
                                                      <block type="update" id="(TMX3NmoY?k,I8B2]p?C">
                                                        <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                                                        <field name="OID">0_userdata.0.PV_Datenpunkte.Berechnung_Batterieentladung_negativ</field>
                                                        <field name="WITH_DELAY">FALSE</field>
                                                        <value name="VALUE">
                                                          <block type="variables_get" id="p$a.=$hGsH%AenyyxPI!">
                                                            <field name="VAR" id="(ocA``hXb:ASln87_[5i">PV Akku Be- oder Entladung</field>
                                                          </block>
                                                        </value>
                                                      </block>
                                                    </next>
                                                  </block>
                                                </statement>
                                              </block>
                                            </xml>
                                            
                                            K C 2 Replies Last reply Reply Quote 1
                                            • First post
                                              Last post

                                            Support us

                                            ioBroker
                                            Community Adapters
                                            Donate

                                            758
                                            Online

                                            31.6k
                                            Users

                                            79.5k
                                            Topics

                                            1.3m
                                            Posts

                                            akku automatisierung batteriespeicher blockly javaskript photovoltaik skript smarthome sungrow wechselrichter
                                            10
                                            52
                                            5223
                                            Loading More Posts
                                            • Oldest to Newest
                                            • Newest to Oldest
                                            • Most Votes
                                            Reply
                                            • Reply as topic
                                            Log in to reply
                                            Community
                                            Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                                            The ioBroker Community 2014-2023
                                            logo