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

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Entwicklung
  4. [Neuer Adapter] Senec Home Adapter

NEWS

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

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

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

[Neuer Adapter] Senec Home Adapter

Geplant Angeheftet Gesperrt Verschoben Entwicklung
photovoltaiksenecadapter
386 Beiträge 70 Kommentatoren 92.4k Aufrufe 67 Watching
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • D dispo112

    @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 Online
    O Online
    oxident
    schrieb am zuletzt editiert von
    #353

    @dispo112 Mega! ... und: Bescheid :grin:

    1 Antwort Letzte Antwort
    0
    • D dispo112

      @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

      S Offline
      S Offline
      Semmy
      schrieb am zuletzt editiert von
      #354

      @dispo112 Ich auch bitte: Bescheid:blush:

      1 Antwort Letzte Antwort
      0
      • icebearI Offline
        icebearI Offline
        icebear
        schrieb am zuletzt editiert von icebear
        #355

        Ich auch Bescheid, bitte 😊

        D 1 Antwort Letzte Antwort
        0
        • icebearI icebear

          Ich auch Bescheid, bitte 😊

          D Offline
          D Offline
          dispo112
          schrieb am zuletzt editiert von
          #356

          @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.');
          
          

          icebearI 1 Antwort Letzte Antwort
          1
          • D dispo112

            @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.');
            
            

            icebearI Offline
            icebearI Offline
            icebear
            schrieb am zuletzt editiert von
            #357

            @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 Antwort Letzte Antwort
            0
            • icebearI icebear

              @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 Offline
              S Offline
              Semmy
              schrieb am zuletzt editiert von
              #358

              @icebear Ich bekomme den gleichen Fehler.

              D 1 Antwort Letzte Antwort
              0
              • S Semmy

                @icebear Ich bekomme den gleichen Fehler.

                D Offline
                D Offline
                dispo112
                schrieb am zuletzt editiert von
                #359

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

                icebearI S 2 Antworten Letzte Antwort
                0
                • D dispo112

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

                  icebearI Offline
                  icebearI Offline
                  icebear
                  schrieb am zuletzt editiert von
                  #360

                  @dispo112

                  Der Fehler kommt auch nach einem erneuten Start des Script.

                  1 Antwort Letzte Antwort
                  0
                  • D dispo112

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

                    S Offline
                    S Offline
                    Semmy
                    schrieb am zuletzt editiert von
                    #361

                    @dispo112 Der Fehler kommt immer wieder.

                    D 1 Antwort Letzte Antwort
                    0
                    • S Semmy

                      @dispo112 Der Fehler kommt immer wieder.

                      D Offline
                      D Offline
                      dispo112
                      schrieb am zuletzt editiert von
                      #362

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

                      Schaue ich mir nachher an!

                      icebearI 1 Antwort Letzte Antwort
                      0
                      • D dispo112

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

                        Schaue ich mir nachher an!

                        icebearI Offline
                        icebearI Offline
                        icebear
                        schrieb am zuletzt editiert von
                        #363

                        @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 Antwort Letzte Antwort
                        0
                        • S Offline
                          S Offline
                          Semmy
                          schrieb am zuletzt editiert von
                          #364

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

                          Viele Grüße
                          Semmy

                          icebearI 1 Antwort Letzte Antwort
                          0
                          • S Semmy

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

                            Viele Grüße
                            Semmy

                            icebearI Offline
                            icebearI Offline
                            icebear
                            schrieb am zuletzt editiert von
                            #365

                            @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 Antwort Letzte Antwort
                            0
                            • icebearI Offline
                              icebearI Offline
                              icebear
                              schrieb am zuletzt editiert von icebear
                              #366

                              @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.

                              M R 3 Antworten Letzte Antwort
                              2
                              • S Offline
                                S Offline
                                Semmy
                                schrieb am zuletzt editiert von
                                #367

                                Hallo
                                Sieht gut aus bis jetzt. Ist es möglich, für diese Datenpunkte jährliche Datenpunkte zu integrieren?

                                Viele Grüße
                                Semmy

                                1 Antwort Letzte Antwort
                                0
                                • icebearI 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.

                                  M Offline
                                  M Offline
                                  musicnrw
                                  schrieb am zuletzt editiert von
                                  #368

                                  @icebear, ich bin was iobroker und Scripte angeht absoluter Anfänger. Kannst Du mir bitte möglichst detailiert beschreiben, was ich an welcher Stelle tun muss? Also, wie und wo richte ich Deine Scripte in meiner Konfiguration ein, damit ich die Werte aus der SENEC-Anlage in meine InfluxDB bekomme. Vielen Dank im Voraus!

                                  1 Antwort Letzte Antwort
                                  0
                                  • icebearI Offline
                                    icebearI Offline
                                    icebear
                                    schrieb am zuletzt editiert von
                                    #369

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

                                    Also, wie und wo richte ich Deine Scripte in meiner Konfiguration ein,

                                    Scripte von oben kopieren und dann auf 'Skripte'

                                    Senec_1.png

                                    Dann legst 1. Einen neuen Ordner (im Root-Verzeichnis an), dann 2. den Ordner anklicken (das er 'blau' markiert ist) und dann oben auf 3. das '+' für neues Script.

                                    Senec_2.png

                                    Dann JS auswählen

                                    Senec_3.png

                                    Dann einen Namen vergeben und das kopierte Script einfügen.

                                    Senec_4.png

                                    Auf den 'roten Pfeil' Script starten.

                                    Unter > 0_userdata.0.Energie.Senec sollten dann die DP erstellt und mit den Werten befüllt werden.

                                    M 1 Antwort Letzte Antwort
                                    2
                                    • icebearI 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.

                                      R Offline
                                      R Offline
                                      RicoStriese
                                      schrieb am zuletzt editiert von
                                      #370

                                      @icebear Danke für die Arbeit, habe alles übernommen. Es funktioniert super. Nochmals besten Danke für die Mühe.:clap: :clap:

                                      1 Antwort Letzte Antwort
                                      0
                                      • icebearI 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.

                                        R Offline
                                        R Offline
                                        RicoStriese
                                        schrieb am zuletzt editiert von
                                        #371

                                        @icebear Danke für die Arbeit, habe alles übernommen. Es funktioniert super. Nochmals besten Danke für die Mühe.:clap: :clap:

                                        1 Antwort Letzte Antwort
                                        0
                                        • icebearI icebear

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

                                          Also, wie und wo richte ich Deine Scripte in meiner Konfiguration ein,

                                          Scripte von oben kopieren und dann auf 'Skripte'

                                          Senec_1.png

                                          Dann legst 1. Einen neuen Ordner (im Root-Verzeichnis an), dann 2. den Ordner anklicken (das er 'blau' markiert ist) und dann oben auf 3. das '+' für neues Script.

                                          Senec_2.png

                                          Dann JS auswählen

                                          Senec_3.png

                                          Dann einen Namen vergeben und das kopierte Script einfügen.

                                          Senec_4.png

                                          Auf den 'roten Pfeil' Script starten.

                                          Unter > 0_userdata.0.Energie.Senec sollten dann die DP erstellt und mit den Werten befüllt werden.

                                          M Offline
                                          M Offline
                                          musicnrw
                                          schrieb am zuletzt editiert von
                                          #372

                                          @icebear, super. Vielen Dank für Deine Arbeit. Ich werde es am Wochenende umsetzen.

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


                                          Support us

                                          ioBroker
                                          Community Adapters
                                          Donate

                                          542

                                          Online

                                          32.4k

                                          Benutzer

                                          81.5k

                                          Themen

                                          1.3m

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

                                          • Du hast noch kein Konto? Registrieren

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