Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Entwicklung
    4. [Neuer Adapter] Senec Home Adapter

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    [Neuer Adapter] Senec Home Adapter

    This topic has been deleted. Only users with topic management privileges can see it.
    • O
      oxident @dispo112 last edited by

      @dispo112 Ja, das wäre auf jeden Fall ein Anfang. Ich meine aber, dass SourceAnalytix das auch kann und dann halt bei jeder Änderung des Datenpunkts berechnet. Dürfte aber so oder so ungenau sein.

      Sieht mir auch leider danach aus, dass es wohl länger dauert, bis wir wieder an die offiziellen Daten kommen.

      D 1 Reply Last reply Reply Quote 0
      • icebear
        icebear last edited by

        @dispo112
        @oxident

        Für diejenigen, die nebenbei auch noch HA nutzen und den Senec auch in HA integriert haben, wäre vielleicht auch noch interessant, das es für HA eine Integration gibt, die die Werte umrechnet .

        Siehe Riemann Integral.

        D 1 Reply Last reply Reply Quote 0
        • D
          dispo112 @oxident last edited by

          @oxident
          auf der Github Solectrus Seite ist ja faktisch schon ein Lösungsweg aufgeführt...
          https://github.com/solectrus/senec-collector/issues/639

          Denke das bekommt man auch mittels Iobroker hin, bin jedenfalls dabei mir den gleichen Workaround nachzubauen.

          koreolis845 created this issue in solectrus/senec-collector

          open Verwendung der App-API nicht mehr möglich #639

          1 Reply Last reply Reply Quote 1
          • D
            dispo112 @icebear last edited by

            @icebear danke für den Hinweis. Aber zunächst versuche ich den Solectrus Workaround im Iobroker nachzubauen.

            icebear 1 Reply Last reply Reply Quote 0
            • icebear
              icebear @dispo112 last edited by icebear

              @dispo112 said in [Neuer Adapter] Senec Home Adapter:

              Aber zunächst versuche ich den Solectrus Workaround im Iobroker nachzubauen.

              Ah, ich sehe du liest auch quer wie es da weitergeht, wäre super wenn du uns auf dem laufenden halten könntest wie man das in IOB nachbauen kann. (evtl auch mir Node-Red)

              Leider fehlt mir hier das programmiertechnische Know-How.

              D 1 Reply Last reply Reply Quote 0
              • D
                dispo112 @icebear last edited by

                @icebear @oxident
                Das mache ich auf jeden Fall.
                Was schon mal sehr erfreulich ist:
                Mein Skript, das die 10-Sekunden-Erzeugungswerte im ioBroker aufsummiert, läuft ziemlich genau – trotz der teils sehr unregelmäßigen PV Erzeugungskurve.
                Ich beobachte das jetzt ein paar Tage weiter.
                Wenn jemand Interesse an dem Skript hat: einfach kurz Bescheid sagen, dann stelle ich es hier gerne zur Verfügung.

                Screenshot_20250724-222850.png Screenshot_20250724-222828.png

                O S 2 Replies Last reply Reply Quote 1
                • O
                  oxident @dispo112 last edited by

                  @dispo112 Mega! ... und: Bescheid 😁

                  1 Reply Last reply Reply Quote 0
                  • S
                    Semmy @dispo112 last edited by

                    @dispo112 Ich auch bitte: Bescheid😊

                    1 Reply Last reply Reply Quote 0
                    • icebear
                      icebear last edited by icebear

                      Ich auch Bescheid, bitte 😊

                      D 1 Reply Last reply Reply Quote 0
                      • D
                        dispo112 @icebear last edited by

                        @icebear @oxident @Semmy
                        So, bitte schön. Die Ordnerpfade sind alle standard. Theoretisch könnt ihr das Skript importieren und starten, fertig. Alle neuen Datenpunkte werden im Userdata erzeugt und können dann via Lovelace / VIS abgegriffen werden.

                        /**
                        * Skript: PV-Tagesproduktion aus Senec-Datenpunkten
                        * Erstellt und summiert Wh- und kWh-Werte aus Live-Daten.
                        * Berücksichtigt PV-Leistung, Netzbezug/-einspeisung und Batterie-Laden/Entladen.
                        * 
                        * Erstellt nötige Datenpunkte automatisch, um Messwerte persistent zu speichern.
                        * 
                        * Letzte Anpassung: 23.07.2025
                        */
                        
                        // --- Konfiguration ---
                        
                        // Basis-Pfad für eigene Datenpunkte
                        const BASE_DP_PATH = '0_userdata.0.energy';
                        
                        // Datenpunkte vom Senec Adapter
                        const SENEC_PV_POWER = 'senec.0.ENERGY.GUI_INVERTER_POWER';       // Aktuelle PV-Leistung in Watt (alle 10s)
                        const SENEC_BAT_POWER = 'senec.0.ENERGY.GUI_BAT_DATA_POWER';       // Batterie Lade-/Entladeleistung in Watt (alle 10s), positiv = Laden, negativ = Entladen
                        const SENEC_GRID_POWER = 'senec.0.ENERGY.GUI_GRID_POW';            // Netzleistung in Watt (alle 10s), positiv = Netzbezug, negativ = Einspeisung
                        
                        // Datenpunkte zur Speicherung
                        const DP_PV_WH = `${BASE_DP_PATH}.pv_wh`;          // Tages-Wh PV
                        const DP_BAT_WH = `${BASE_DP_PATH}.bat_wh`;        // Tages-Wh Batterie (Netto Laden)
                        const DP_GRID_WH = `${BASE_DP_PATH}.netz_wh`;      // Tages-Wh Netzbezug
                        const DP_EINSPEISUNG_WH = `${BASE_DP_PATH}.einspeisung_wh`;  // Tages-Wh Einspeisung
                        
                        const DP_PV_KWH = `${BASE_DP_PATH}.pv_kwh`;        // Tages-kWh PV
                        const DP_BILANZ_KWH = `${BASE_DP_PATH}.bilanz_kwh`; // Bilanz kWh (PV - Netzbezug)
                        
                        // --- Variablen ---
                        let lastTimestamp = null;   // Timestamp letzte Messung
                        let lastPVPower = 0;        // Letzte gemessene PV-Leistung in Watt
                        let lastBatPower = 0;       // Letzte gemessene Batterieleistung in Watt
                        let lastGridPower = 0;      // Letzte gemessene Netzleistung in Watt
                        
                        // --- Hilfsfunktion: Sicherer State-Lesezugriff ---
                        function getStateSafe(id, defaultValue = 0) {
                           const state = getState(id);
                           if (state && state.val !== null && state.val !== undefined) {
                               return state.val;
                           }
                           return defaultValue;
                        }
                        
                        // --- Ordner (Channel) anlegen, falls nicht vorhanden ---
                        if (!existsObject(BASE_DP_PATH)) {
                           createChannel(BASE_DP_PATH, 'Ordner für Energie-Datenpunkte', (err) => {
                               if (err) {
                                   log(`Fehler beim Erstellen des Ordners ${BASE_DP_PATH}: ${err}`, 'error');
                               } else {
                                   log(`Ordner ${BASE_DP_PATH} erfolgreich erstellt`, 'info');
                               }
                           });
                        }
                        
                        // --- Datenpunkte anlegen, falls nicht vorhanden ---
                        function createStateIfNotExists(id, common, initialValue = 0) {
                           if (!existsState(id)) {
                               createState(id, initialValue, common, (err) => {
                                   if (err) {
                                       log(`Fehler beim Erstellen des Datenpunkts ${id}: ${err}`, 'error');
                                   } else {
                                       log(`Datenpunkt ${id} erstellt mit Initialwert ${initialValue}`, 'info');
                                   }
                               });
                           }
                        }
                        
                        // Definieren der Common-Objekte (Typ, Rolle usw.)
                        const commonWH = { name: 'Tageswert in Wattstunden (Wh)', type: 'number', role: 'value.power', unit: 'Wh', read: true, write: false };
                        const commonKWH = { name: 'Tageswert in Kilowattstunden (kWh)', type: 'number', role: 'value.power', unit: 'kWh', read: true, write: false };
                        
                        // Erstellen aller nötigen Datenpunkte
                        createStateIfNotExists(DP_PV_WH, commonWH);
                        createStateIfNotExists(DP_BAT_WH, commonWH);
                        createStateIfNotExists(DP_GRID_WH, commonWH);
                        createStateIfNotExists(DP_EINSPEISUNG_WH, commonWH);
                        createStateIfNotExists(DP_PV_KWH, commonKWH);
                        createStateIfNotExists(DP_BILANZ_KWH, commonKWH);
                        
                        // --- Hauptlogik: Verarbeitung der Messwerte und Integration in Wh ---
                        
                        // Funktion zum Verarbeiten neuer Messwerte
                        function processNewData(pvPower, batPower, gridPower) {
                           const jetzt = Date.now();
                        
                           if (lastTimestamp !== null) {
                               const deltaT = (jetzt - lastTimestamp) / 1000; // Zeitdifferenz in Sekunden
                        
                               // Energie (Wh) = Leistung (W) * Zeit (h)
                               // deltaWh = W * (s / 3600)
                               const deltaWhPV = lastPVPower * (deltaT / 3600);
                               const deltaWhBat = lastBatPower * (deltaT / 3600);
                               const deltaWhGrid = lastGridPower * (deltaT / 3600);
                        
                               // Update der Tageswerte
                               let pvWh = getStateSafe(DP_PV_WH);
                               let batWh = getStateSafe(DP_BAT_WH);
                               let gridWh = getStateSafe(DP_GRID_WH);
                               let einspeisungWh = getStateSafe(DP_EINSPEISUNG_WH);
                        
                               pvWh += deltaWhPV;
                        
                               // Batterie: Nur Netto-Ladung (positive Leistung)
                               if (deltaWhBat > 0) {
                                   batWh += deltaWhBat;
                               } else {
                                   // Entladen wird nicht addiert, könnte separat behandelt werden
                               }
                        
                               // Netzbezug vs Einspeisung trennen:
                               if (deltaWhGrid > 0) {
                                   gridWh += deltaWhGrid; // Netzbezug
                               } else {
                                   einspeisungWh += Math.abs(deltaWhGrid); // Einspeisung
                               }
                        
                               // Datenpunkte aktualisieren
                               setState(DP_PV_WH, pvWh, true);
                               setState(DP_BAT_WH, batWh, true);
                               setState(DP_GRID_WH, gridWh, true);
                               setState(DP_EINSPEISUNG_WH, einspeisungWh, true);
                        
                               // kWh berechnen und speichern
                               setState(DP_PV_KWH, +(pvWh / 1000).toFixed(3), true);
                        
                               // Bilanz: PV-Produktion minus Netzbezug (kWh)
                               const bilanzKWh = (pvWh - gridWh) / 1000;
                               setState(DP_BILANZ_KWH, +bilanzKWh.toFixed(3), true);
                           }
                        
                           // Update letzte Werte und Timestamp für nächste Berechnung
                           lastPVPower = pvPower;
                           lastBatPower = batPower;
                           lastGridPower = gridPower;
                           lastTimestamp = jetzt;
                        }
                        
                        // --- Event-Listener: Trigger bei Änderung eines relevanten Datenpunkts ---
                        
                        // Abonnieren aller 3 relevanten Datenpunkte, um schnell reagieren zu können
                        on({ id: [SENEC_PV_POWER, SENEC_BAT_POWER, SENEC_GRID_POWER], change: 'ne' }, () => {
                           const pvPower = getStateSafe(SENEC_PV_POWER);
                           const batPower = getStateSafe(SENEC_BAT_POWER);
                           const gridPower = getStateSafe(SENEC_GRID_POWER);
                        
                           processNewData(pvPower, batPower, gridPower);
                        });
                        
                        // --- Täglicher Reset der Tageswerte um Mitternacht ---
                        schedule('0 0 * * *', () => {
                           log('Tagesreset: Tageswerte auf 0 setzen.');
                           setState(DP_PV_WH, 0, true);
                           setState(DP_BAT_WH, 0, true);
                           setState(DP_GRID_WH, 0, true);
                           setState(DP_EINSPEISUNG_WH, 0, true);
                           setState(DP_PV_KWH, 0, true);
                           setState(DP_BILANZ_KWH, 0, true);
                        
                           // Reset lokale Variablen ebenfalls
                           lastTimestamp = null;
                           lastPVPower = 0;
                           lastBatPower = 0;
                           lastGridPower = 0;
                        });
                        
                        // --- Skriptstart ---
                        log('PV-Tagesproduktion mit Senec Datenpunkten gestartet.');
                        
                        

                        icebear 1 Reply Last reply Reply Quote 1
                        • icebear
                          icebear @dispo112 last edited by

                          @dispo112

                          Erst einmal vielen Dank für das Script.

                          Leider bekomme ich einen Fehler beim Starten vom Script.

                          javascript.0	08:39:18.506	info	
                          Start JavaScript script.js.Energie_Strom.Senec.senec_tageswerte (Javascript/js)
                          javascript.0	08:39:18.543	error	
                          ReferenceError: createChannel is not defined
                          javascript.0	08:39:18.543	error	
                              at script.js.Energie_Strom.Senec.senec_tageswerte:48:4
                          javascript.0	08:39:18.544	error	
                              at script.js.Energie_Strom.Senec.senec_tageswerte:174:3
                          
                          S 1 Reply Last reply Reply Quote 0
                          • S
                            Semmy @icebear last edited by

                            @icebear Ich bekomme den gleichen Fehler.

                            D 1 Reply Last reply Reply Quote 0
                            • D
                              dispo112 @Semmy last edited by

                              @oxident
                              Wenn ihr das Skript nochmal startet - taucht der Fehler dann wieder auf? Oder nur beim Initial Start?

                              icebear S 2 Replies Last reply Reply Quote 0
                              • icebear
                                icebear @dispo112 last edited by

                                @dispo112

                                Der Fehler kommt auch nach einem erneuten Start des Script.

                                1 Reply Last reply Reply Quote 0
                                • S
                                  Semmy @dispo112 last edited by

                                  @dispo112 Der Fehler kommt immer wieder.

                                  D 1 Reply Last reply Reply Quote 0
                                  • D
                                    dispo112 @Semmy last edited by

                                    @semmy Seltsam, hatte alle Fehler behoben und es jetzt 1:1 bei mir herauskopiert. 🤔

                                    Schaue ich mir nachher an!

                                    icebear 1 Reply Last reply Reply Quote 0
                                    • icebear
                                      icebear @dispo112 last edited by

                                      @dispo112

                                      Ich glaub es reicht wenn du 'createChannel' durch 'createState' ersetzt.

                                      // --- Ordner (Channel) anlegen, falls nicht vorhanden ---
                                      if (!existsObject(BASE_DP_PATH)) {
                                         createState(BASE_DP_PATH, 'Ordner für Energie-Datenpunkte', (err) => {
                                             if (err) {
                                                 log(`Fehler beim Erstellen des Ordners ${BASE_DP_PATH}: ${err}`, 'error');
                                             } else {
                                                 log(`Ordner ${BASE_DP_PATH} erfolgreich erstellt`, 'info');
                                             }
                                         });
                                      }
                                      
                                      1 Reply Last reply Reply Quote 0
                                      • S
                                        Semmy last edited by

                                        Ok, funktioniert jetzt. Wie bekommt man die Datenpunkte in Home Assistant?

                                        Viele Grüße
                                        Semmy

                                        icebear 1 Reply Last reply Reply Quote 0
                                        • icebear
                                          icebear @Semmy last edited by

                                          @semmy said in [Neuer Adapter] Senec Home Adapter:

                                          Wie bekommt man die Datenpunkte in Home Assistant?

                                          Also ich mach das bei einem anderen Projekt mit MQTT.

                                          1 Reply Last reply Reply Quote 0
                                          • icebear
                                            icebear last edited by icebear

                                            @dispo112 said in [Neuer Adapter] Senec Home Adapter:

                                            So, bitte schön. Die Ordnerpfade sind alle standard. Theoretisch könnt ihr das Skript importieren und starten, fertig. Alle neuen Datenpunkte werden im Userdata erzeugt und können dann via Lovelace / VIS abgegriffen werden.

                                            Nochmal vielen Dank für deine Arbeit. Läuft bei mir seit gestern und die Werte sind soweit völlig O.K.

                                            Ich hab mich jetzt auch entschieden, nicht mehr darauf zu Warten ob irgendeiner etwas bereitstellt das die API oder die Werte über mein-senec abgegriffen werden. Die Klimzüge über HA sind mir zu aufwendig und keiner weiß wie lange das dann funktioniert bevor Senec da wieder den Riegel vorschiebt.
                                            Solange wie der Adapter mir die Live-Daten zur Verfügung stellt reicht mir das.

                                            Ich hab deshalb zusätzlich zu dem Script von @dispo112 noch drei weitere Scripte bei mir implementiert, die laufen seit gestern und liefern meines Erachtens ausreichend genaue Werte, so das sich eine gewisse Statistik aufrechterhalten lässt.

                                            Hier die drei Scripte die ich zusätzlich noch implementiert hab:

                                            1. Hausverbrauch (schreibt die Werte in zwei DP's , einmal Wh und einmal kWh und wird täglich um 00:00 Uhr auf '0' gesetzt)
                                            // ====== Konfiguration START ======
                                            
                                            // ID des Datenpunkts, der den aktuellen Hausverbrauch in Watt (W) liefert.
                                            // Diesen Wert MUSST du an deine ioBroker-Installation anpassen!
                                            // Beispiel: 'shelly.0.shellypower.power' oder 'modbus.0.holdingRegisters.power_total'
                                            const currentHouseConsumptionPowerId = "senec.0.ENERGY.GUI_HOUSE_POW";
                                            
                                            // ID des Datenpunkts für den täglichen Hausverbrauch in Wh (wird erstellt, falls nicht vorhanden)
                                            const dailyHouseConsumptionWhId = "0_userdata.0.Energie.Senec.Tages_Hausverbrauch_Wh";
                                            // ID des Datenpunkts für den täglichen Hausverbrauch in kWh (wird erstellt, falls nicht vorhanden)
                                            const dailyHouseConsumptionKWhId = "0_userdata.0.Energie.Senec.Tages_Hausverbrauch_kWh";
                                            
                                            // ====== Konfiguration ENDE ======
                                            
                                            
                                            // Globale Variablen für die Berechnung
                                            let lastPowerValue = 0; // Letzter bekannter Leistungswert
                                            let lastUpdateTime = new Date().getTime(); // Zeitpunkt der letzten Aktualisierung in Millisekunden
                                            
                                            // --- Hilfsfunktionen ---
                                            
                                            // Funktion zum Erstellen der notwendigen Datenpunkte (States)
                                            function createMyStates() {
                                                createState(dailyHouseConsumptionWhId, 0, {
                                                    name: 'Täglicher Hausverbrauch (Wh)',
                                                    type: 'number',
                                                    read: true,
                                                    write: false,
                                                    role: 'value.power.consumption',
                                                    unit: 'Wh',
                                                    desc: 'Summierter Hausverbrauch für den aktuellen Tag in Wattstunden'
                                                });
                                                createState(dailyHouseConsumptionKWhId, 0, {
                                                    name: 'Täglicher Hausverbrauch (kWh)',
                                                    type: 'number',
                                                    read: true,
                                                    write: false,
                                                    role: 'value.power.consumption',
                                                    unit: 'kWh',
                                                    desc: 'Summierter Hausverbrauch für den aktuellen Tag in Kilowattstunden'
                                                });
                                                log("Datenpunkte für den Hausverbrauch überprüft/erstellt.");
                                            }
                                            
                                            // Funktion, um den initialen Wert aus dem Datenpunkt zu lesen und zu loggen
                                            async function initializeConsumptionValues() {
                                                const state = await getStateAsync(dailyHouseConsumptionWhId);
                                                if (state && state.val !== null) {
                                                    log(`Initialer Wert für täglichen Hausverbrauch Wh: ${state.val} Wh`);
                                                } else {
                                                    setState(dailyHouseConsumptionWhId, 0, true);
                                                    setState(dailyHouseConsumptionKWhId, 0, true);
                                                    log(`Datenpunkte ${dailyHouseConsumptionWhId} und ${dailyHouseConsumptionKWhId} auf 0 gesetzt.`);
                                                }
                                            }
                                            
                                            // --- Hauptlogik ---
                                            
                                            // 1. Beim Start des Skripts: Datenpunkte erstellen und initialisieren
                                            createMyStates();
                                            initializeConsumptionValues();
                                            
                                            // 2. Trigger bei Änderung des Hausverbrauchs-Datenpunkts
                                            on({ id: currentHouseConsumptionPowerId, change: 'ne' }, async function (obj) {
                                                const currentPower = parseFloat(obj.state.val); // Aktueller Leistungswert in Watt
                                            
                                                // Prüfen, ob der Wert gültig ist
                                                if (isNaN(currentPower)) {
                                                    log(`Ungültiger Leistungswert erhalten: ${obj.state.val}. Berechnung übersprungen.`, 'warn');
                                                    return;
                                                }
                                            
                                                const currentTime = new Date().getTime(); // Aktueller Zeitstempel in Millisekunden
                                            
                                                // Initialisierung von lastPowerValue und lastUpdateTime beim ersten Trigger
                                                if (lastPowerValue === 0 && lastUpdateTime === new Date().getTime()) {
                                                    const powerState = getState(currentHouseConsumptionPowerId);
                                                    if (powerState && powerState.val !== null) {
                                                        lastPowerValue = parseFloat(powerState.val);
                                                    } else {
                                                        lastPowerValue = 0; // Fallback
                                                    }
                                                    lastUpdateTime = currentTime;
                                                    log("Initialisierung der Leistungswerte beim ersten Trigger.");
                                                    return;
                                                }
                                            
                                                const timeDiffSeconds = (currentTime - lastUpdateTime) / 1000; // Zeitdifferenz in Sekunden
                                            
                                                // Falls keine Zeit vergangen ist (z.B. zu schnelle Updates oder gleicher Zeitstempel)
                                                if (timeDiffSeconds <= 0) {
                                                    // log("Zeitdifferenz ist 0 oder negativ, Überspringe Berechnung.", 'debug'); // Kann viele Logs verursachen
                                                    return;
                                                }
                                            
                                                // Berechnung der Energie: Leistung (W) * Zeit (s) = Wattsekunden (Ws)
                                                const energyWs = currentPower * timeDiffSeconds;
                                                // Umrechnung von Wattsekunden in Wattstunden (Ws / 3600 = Wh)
                                                const energyWh = energyWs / 3600;
                                            
                                                log(`Aktuelle Leistung: ${currentPower.toFixed(2)} W, Zeitdiff: ${timeDiffSeconds.toFixed(2)} s, Berechnete Energie: ${energyWh.toFixed(2)} Wh`);
                                            
                                                // Aktuellen summierten Verbrauch von ioBroker lesen und sicherstellen, dass es eine Zahl ist
                                                let currentDailyConsumptionWh = parseFloat((await getStateAsync(dailyHouseConsumptionWhId)).val) || 0;
                                            
                                                // Energie zum Tagesverbrauch addieren
                                                currentDailyConsumptionWh += energyWh;
                                            
                                                // Werte in die Datenpunkte schreiben
                                                setState(dailyHouseConsumptionWhId, currentDailyConsumptionWh.toFixed(2), true); // Wh auf 2 Nachkommastellen
                                                setState(dailyHouseConsumptionKWhId, (currentDailyConsumptionWh / 1000).toFixed(3), true); // kWh auf 3 Nachkommastellen
                                            
                                                log(`Hausverbrauch addiert. Neue Summe: ${currentDailyConsumptionWh.toFixed(2)} Wh (${(currentDailyConsumptionWh / 1000).toFixed(3)} kWh)`);
                                            
                                                // Werte für die nächste Iteration speichern
                                                lastPowerValue = currentPower;
                                                lastUpdateTime = currentTime;
                                            });
                                            
                                            // 3. Reset der Tagessummen um Mitternacht
                                            schedule('0 0 * * *', async function () {
                                                log("Mitternacht erreicht, setze täglichen Hausverbrauch zurück.");
                                                setState(dailyHouseConsumptionWhId, 0, true);
                                                setState(dailyHouseConsumptionKWhId, 0, true);
                                            
                                                // Wichtig: lastUpdateTime muss auch zurückgesetzt werden für korrekte delta-t Berechnung am neuen Tag
                                                // und lastPowerValue für den ersten Wert des neuen Tages
                                                lastUpdateTime = new Date().getTime();
                                                lastPowerValue = parseFloat((await getStateAsync(currentHouseConsumptionPowerId)).val) || 0; // Aktuellen Power-Wert erneut holen
                                            
                                                log("Täglicher Hausverbrauch wurde zurückgesetzt.");
                                            });
                                            
                                            // Optional: Info-Log beim Start des Skripts
                                            log("Skript zum Überwachen des täglichen Hausverbrauchs gestartet.");
                                            
                                            1. Akku Be-und Entladung (schreibt die Werte (batIn und batOut) in DP's , einmal Wh und einmal kWh und wird täglich um 00:00 Uhr auf '0' gesetzt)
                                            // ====== Konfiguration START ======
                                            // Datenpunkt-ID, die die aktuelle Leistung in Watt liefert.
                                            // Negativ für BatOut, Positiv für BatIn.
                                            // Diesen Wert musst du an deine ioBroker-Installation anpassen!
                                            const powerStateId = "senec.0.ENERGY.GUI_BAT_DATA_POWER"; // Beispiel: smartmeter.0.0_1_123_456_789.power_total_current
                                            
                                            // Datenpunkt-ID für die tägliche BatOut in Wh (wird erstellt, falls nicht vorhanden)
                                            const dailyBatOutWhStateId = "0_userdata.0.Energie.Senec.Bat_Out_Wh";
                                            // Datenpunkt-ID für die tägliche BatOut in kWh
                                            const dailyBatOutKWhStateId = "0_userdata.0.Energie.Senec.Bat_Out_kWh";
                                            
                                            // Datenpunkt-ID für den täglichen BatIn in Wh (wird erstellt, falls nicht vorhanden)
                                            const dailyBatInWhStateId = "0_userdata.0.Energie.Senec.Bat_In_Wh";
                                            // Datenpunkt-ID für den täglichen BatIn in kWh
                                            const dailyBatInKWhStateId = "0_userdata.0.Energie.Senec.Bat_In_kWh";
                                            
                                            // ====== Konfiguration ENDE ======
                                            
                                            
                                            // Globale Variablen für die Berechnung der Tagessummen
                                            let lastPowerValue = 0; // Letzter bekannter Leistungswert
                                            let lastUpdateTime = new Date().getTime(); // Zeitpunkt der letzten Aktualisierung in Millisekunden
                                            
                                            // Funktion zum Initialisieren der Datenpunkte (falls nicht vorhanden)
                                            function createStates() {
                                                createState(dailyBatOutWhStateId, 0, {
                                                    name: 'Daily BatOut (Wh)',
                                                    type: 'number',
                                                    read: true,
                                                    write: false,
                                                    role: 'value.power.consumption',
                                                    unit: 'Wh'
                                                });
                                                createState(dailyBatOutKWhStateId, 0, {
                                                    name: 'Daily BatOut (kWh)',
                                                    type: 'number',
                                                    read: true,
                                                    write: false,
                                                    role: 'value.power.consumption',
                                                    unit: 'kWh'
                                                });
                                                createState(dailyBatInWhStateId, 0, {
                                                    name: 'Daily BatIn (Wh)',
                                                    type: 'number',
                                                    read: true,
                                                    write: false,
                                                    role: 'value.power.consumption',
                                                    unit: 'Wh'
                                                });
                                                createState(dailyBatInKWhStateId, 0, {
                                                    name: 'Daily BatIn (kWh)',
                                                    type: 'number',
                                                    read: true,
                                                    write: false,
                                                    role: 'value.power.consumption',
                                                    unit: 'kWh'
                                                });
                                            }
                                            
                                            // Beim Start des Skripts Datenpunkte erstellen und initialisieren
                                            createStates();
                                            
                                            // Werte aus den Datenpunkten beim Skriptstart lesen, falls schon vorhanden
                                            // Prüfen, ob die Datenpunkte bereits einen Wert haben, ansonsten auf 0 setzen
                                            let initialBatOutState = getState(dailyBatOutWhStateId);
                                            if (initialBatOutState && initialBatOutState.val !== null) {
                                                log(`Initialer Wert für BatOut Wh: ${initialBatOutState.val}`);
                                            } else {
                                                setState(dailyBatOutWhStateId, 0);
                                                log(`Datenpunkt ${dailyBatOutWhStateId} auf 0 gesetzt.`);
                                            }
                                            
                                            let initialBatInState = getState(dailyBatInWhStateId);
                                            if (initialBatInState && initialBatInState.val !== null) {
                                                log(`Initialer Wert für BatIn Wh: ${initialBatInState.val}`);
                                            } else {
                                                setState(dailyBatInWhStateId, 0);
                                                log(`Datenpunkt ${dailyBatInWhStateId} auf 0 gesetzt.`);
                                            }
                                            
                                            // Trigger bei Änderung des Leistungsdatenpunkts
                                            on({ id: powerStateId, change: 'ne' }, async function (obj) {
                                                const currentPower = obj.state.val; // Aktueller Leistungswert in Watt
                                                const currentTime = new Date().getTime(); // Aktueller Zeitstempel in Millisekunden
                                            
                                                // Wenn der Wert zum ersten Mal kommt oder Zeitunterschied zu gering ist
                                                if (lastPowerValue === 0 && lastUpdateTime === new Date().getTime()) { // Initialisierung
                                                    lastPowerValue = currentPower;
                                                    lastUpdateTime = currentTime;
                                                    log("Initialisierung der Leistungswerte.");
                                                    return;
                                                }
                                            
                                                const timeDiffSeconds = (currentTime - lastUpdateTime) / 1000; // Zeitdifferenz in Sekunden
                                            
                                                if (timeDiffSeconds <= 0) { // Falls keine Zeit vergangen ist (z.B. zu schnelle Updates)
                                                    log("Zeitdifferenz ist 0 oder negativ, Überspringe Berechnung.");
                                                    return;
                                                }
                                            
                                                // Leistung * Zeit = Energie (Wattsekunden)
                                                const energyWs = currentPower * timeDiffSeconds;
                                                const energyWh = energyWs / 3600; // Umrechnung von Wattsekunden in Wattstunden
                                            
                                                log(`Aktuelle Leistung: ${currentPower} W, Zeitdiff: ${timeDiffSeconds.toFixed(2)} s, Berechnete Energie: ${energyWh.toFixed(2)} Wh`);
                                            
                                                // Sicherstellen, dass die gelesenen Werte Zahlen sind (durch parseFloat oder den Unary-Plus-Operator)
                                                let currentBatInWh = parseFloat((await getStateAsync(dailyBatInWhStateId)).val) || 0;
                                                let currentBatOutWh = parseFloat((await getStateAsync(dailyBatOutWhStateId)).val) || 0;
                                            
                                                if (currentPower < 0) { // BatOut
                                                    currentBatOutWh += Math.abs(energyWh); // Absolutwert, damit die Summe positiv ist
                                                    setState(dailyBatOutWhStateId, currentBatOutWh.toFixed(2), true);
                                                    setState(dailyBatOutKWhStateId, (currentBatOutWh / 1000).toFixed(3), true);
                                                    log(`BatOut addiert. Neue Summe: ${currentBatOutWh.toFixed(2)} Wh`);
                                                } else { // BatIn
                                                    currentBatInWh += energyWh;
                                                    setState(dailyBatInWhStateId, currentBatInWh.toFixed(2), true);
                                                    setState(dailyBatInKWhStateId, (currentBatInWh / 1000).toFixed(3), true);
                                                    log(`BatIn addiert. Neue Summe: ${currentBatInWh.toFixed(2)} Wh`);
                                                }
                                            
                                                // Werte für die nächste Iteration speichern
                                                lastPowerValue = currentPower;
                                                lastUpdateTime = currentTime;
                                            });
                                            
                                            
                                            // Reset der Tagessummen um Mitternacht
                                            schedule('0 0 * * *', async function () {
                                                log("Mitternacht erreicht, setze Tagessummen zurück.");
                                                setState(dailyBatOutWhStateId, 0, true);
                                                setState(dailyBatOutKWhStateId, 0, true);
                                                setState(dailyBatInWhStateId, 0, true);
                                                setState(dailyBatInKWhStateId, 0, true);
                                                // lastUpdateTime muss auch zurückgesetzt werden, um korrekte delta-t Berechnung am neuen Tag zu gewährleisten
                                                lastUpdateTime = new Date().getTime();
                                                lastPowerValue = (await getStateAsync(powerStateId)).val || 0; // Aktuellen Power-Wert erneut holen
                                            
                                                log("Tagessummen wurden zurückgesetzt.");
                                            });
                                            
                                            // Optional: Für Debugging, wenn das Skript startet
                                            log("Skript zum Überwachen von BatOut und BatIn gestartet.");
                                            
                                            1. Grid Power (schreibt die Werte in DP's (Einspeisung und Netzbezug), einmal Wh und einmal kWh und wird täglich um 00:00 Uhr auf '0' gesetzt)
                                            // ====== Konfiguration START ======
                                            // Datenpunkt-ID, die die aktuelle Leistung in Watt liefert.
                                            // Negativ für Einspeisung, Positiv für Netzbezug.
                                            // Diesen Wert musst du an deine ioBroker-Installation anpassen!
                                            const powerStateId = "senec.0.ENERGY.GUI_GRID_POW"; // Beispiel: smartmeter.0.0_1_123_456_789.power_total_current
                                            
                                            // Datenpunkt-ID für die tägliche Einspeisung in Wh (wird erstellt, falls nicht vorhanden)
                                            const dailyFeedInWhStateId = "0_userdata.0.Energie.Senec.Tages_Einspeisung_Wh";
                                            // Datenpunkt-ID für die tägliche Einspeisung in kWh
                                            const dailyFeedInKWhStateId = "0_userdata.0.Energie.Senec.Tages_Einspeisung_kWh";
                                            
                                            // Datenpunkt-ID für den täglichen Netzbezug in Wh (wird erstellt, falls nicht vorhanden)
                                            const dailyGridPurchaseWhStateId = "0_userdata.0.Energie.Senec.Tages_Netzbezug_Wh";
                                            // Datenpunkt-ID für den täglichen Netzbezug in kWh
                                            const dailyGridPurchaseKWhStateId = "0_userdata.0.Energie.Senec.Tages_Netzbezug_kWh";
                                            
                                            // ====== Konfiguration ENDE ======
                                            
                                            
                                            // Globale Variablen für die Berechnung der Tagessummen
                                            let lastPowerValue = 0; // Letzter bekannter Leistungswert
                                            let lastUpdateTime = new Date().getTime(); // Zeitpunkt der letzten Aktualisierung in Millisekunden
                                            
                                            // Funktion zum Initialisieren der Datenpunkte (falls nicht vorhanden)
                                            function createStates() {
                                                createState(dailyFeedInWhStateId, 0, {
                                                    name: 'Tägliche Einspeisung (Wh)',
                                                    type: 'number',
                                                    read: true,
                                                    write: false,
                                                    role: 'value.power.consumption',
                                                    unit: 'Wh'
                                                });
                                                createState(dailyFeedInKWhStateId, 0, {
                                                    name: 'Tägliche Einspeisung (kWh)',
                                                    type: 'number',
                                                    read: true,
                                                    write: false,
                                                    role: 'value.power.consumption',
                                                    unit: 'kWh'
                                                });
                                                createState(dailyGridPurchaseWhStateId, 0, {
                                                    name: 'Täglicher Netzbezug (Wh)',
                                                    type: 'number',
                                                    read: true,
                                                    write: false,
                                                    role: 'value.power.consumption',
                                                    unit: 'Wh'
                                                });
                                                createState(dailyGridPurchaseKWhStateId, 0, {
                                                    name: 'Täglicher Netzbezug (kWh)',
                                                    type: 'number',
                                                    read: true,
                                                    write: false,
                                                    role: 'value.power.consumption',
                                                    unit: 'kWh'
                                                });
                                            }
                                            
                                            // Beim Start des Skripts Datenpunkte erstellen und initialisieren
                                            createStates();
                                            
                                            // Werte aus den Datenpunkten beim Skriptstart lesen, falls schon vorhanden
                                            // Prüfen, ob die Datenpunkte bereits einen Wert haben, ansonsten auf 0 setzen
                                            let initialFeedInState = getState(dailyFeedInWhStateId);
                                            if (initialFeedInState && initialFeedInState.val !== null) {
                                                log(`Initialer Wert für Einspeisung Wh: ${initialFeedInState.val}`);
                                            } else {
                                                setState(dailyFeedInWhStateId, 0);
                                                log(`Datenpunkt ${dailyFeedInWhStateId} auf 0 gesetzt.`);
                                            }
                                            
                                            let initialGridPurchaseState = getState(dailyGridPurchaseWhStateId);
                                            if (initialGridPurchaseState && initialGridPurchaseState.val !== null) {
                                                log(`Initialer Wert für Netzbezug Wh: ${initialGridPurchaseState.val}`);
                                            } else {
                                                setState(dailyGridPurchaseWhStateId, 0);
                                                log(`Datenpunkt ${dailyGridPurchaseWhStateId} auf 0 gesetzt.`);
                                            }
                                            
                                            // Trigger bei Änderung des Leistungsdatenpunkts
                                            on({ id: powerStateId, change: 'ne' }, async function (obj) {
                                                const currentPower = obj.state.val; // Aktueller Leistungswert in Watt
                                                const currentTime = new Date().getTime(); // Aktueller Zeitstempel in Millisekunden
                                            
                                                // Wenn der Wert zum ersten Mal kommt oder Zeitunterschied zu gering ist
                                                // Hier ist es wichtig, dass lastPowerValue und lastUpdateTime initialisiert werden
                                                if (lastPowerValue === 0 && lastUpdateTime === new Date().getTime()) { // Initialisierung
                                                    const powerState = getState(powerStateId);
                                                    if (powerState && powerState.val !== null) {
                                                        lastPowerValue = powerState.val;
                                                    } else {
                                                        lastPowerValue = 0; // Fallback, falls kein Wert verfügbar
                                                    }
                                                    lastUpdateTime = currentTime;
                                                    log("Initialisierung der Leistungswerte beim ersten Trigger.");
                                                    return;
                                                }
                                            
                                            
                                                const timeDiffSeconds = (currentTime - lastUpdateTime) / 1000; // Zeitdifferenz in Sekunden
                                            
                                                if (timeDiffSeconds <= 0) { // Falls keine Zeit vergangen ist (z.B. zu schnelle Updates)
                                                    log("Zeitdifferenz ist 0 oder negativ, Überspringe Berechnung.");
                                                    return;
                                                }
                                            
                                                // Leistung * Zeit = Energie (Wattsekunden)
                                                const energyWs = currentPower * timeDiffSeconds;
                                                const energyWh = energyWs / 3600; // Umrechnung von Wattsekunden in Wattstunden
                                            
                                                log(`Aktuelle Leistung: ${currentPower} W, Zeitdiff: ${timeDiffSeconds.toFixed(2)} s, Berechnete Energie: ${energyWh.toFixed(2)} Wh`);
                                            
                                                // **KORRIGIERTER BEREICH START**
                                                // Sicherstellen, dass die gelesenen Werte Zahlen sind (durch parseFloat oder den Unary-Plus-Operator)
                                                let currentFeedInWh = parseFloat((await getStateAsync(dailyFeedInWhStateId)).val) || 0;
                                                let currentGridPurchaseWh = parseFloat((await getStateAsync(dailyGridPurchaseWhStateId)).val) || 0;
                                                // **KORRIGIERTER BEREICH ENDE**
                                            
                                                if (currentPower < 0) { // Einspeisung
                                                    currentFeedInWh += Math.abs(energyWh); // Absolutwert, damit die Summe positiv ist
                                                    setState(dailyFeedInWhStateId, currentFeedInWh.toFixed(2), true);
                                                    setState(dailyFeedInKWhStateId, (currentFeedInWh / 1000).toFixed(3), true);
                                                    log(`Einspeisung addiert. Neue Summe: ${currentFeedInWh.toFixed(2)} Wh`);
                                                } else { // Netzbezug
                                                    currentGridPurchaseWh += energyWh;
                                                    setState(dailyGridPurchaseWhStateId, currentGridPurchaseWh.toFixed(2), true);
                                                    setState(dailyGridPurchaseKWhStateId, (currentGridPurchaseWh / 1000).toFixed(3), true);
                                                    log(`Netzbezug addiert. Neue Summe: ${currentGridPurchaseWh.toFixed(2)} Wh`);
                                                }
                                            
                                                // Werte für die nächste Iteration speichern
                                                lastPowerValue = currentPower;
                                                lastUpdateTime = currentTime;
                                            });
                                            
                                            
                                            // Reset der Tagessummen um Mitternacht
                                            schedule('0 0 * * *', async function () {
                                                log("Mitternacht erreicht, setze Tagessummen zurück.");
                                                setState(dailyFeedInWhStateId, 0, true);
                                                setState(dailyFeedInKWhStateId, 0, true);
                                                setState(dailyGridPurchaseWhStateId, 0, true);
                                                setState(dailyGridPurchaseKWhStateId, 0, true);
                                                // lastUpdateTime muss auch zurückgesetzt werden, um korrekte delta-t Berechnung am neuen Tag zu gewährleisten
                                                lastUpdateTime = new Date().getTime();
                                                lastPowerValue = (await getStateAsync(powerStateId)).val || 0; // Aktuellen Power-Wert erneut holen
                                            
                                                log("Tagessummen wurden zurückgesetzt.");
                                            });
                                            
                                            // Optional: Für Debugging, wenn das Skript startet
                                            log("Skript zum Überwachen von Einspeisung und Netzbezug gestartet.");
                                            

                                            wer Lust hat kann ja mit testen ob das so passt.

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

                                            Support us

                                            ioBroker
                                            Community Adapters
                                            Donate

                                            415
                                            Online

                                            31.9k
                                            Users

                                            80.2k
                                            Topics

                                            1.3m
                                            Posts

                                            adapter photovoltaik senec
                                            69
                                            366
                                            70032
                                            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