Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. dispo112

    NEWS

    • Wir empfehlen: Node.js 22.x

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker goes Matter ... Matter Adapter in Stable

    D
    • Profile
    • Following 0
    • Followers 0
    • Topics 4
    • Posts 36
    • Best 4
    • Groups 1

    dispo112

    @dispo112

    Starter

    4
    Reputation
    11
    Profile views
    36
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    dispo112 Follow
    Starter

    Best posts made by dispo112

    • RE: [Neuer Adapter] Senec Home Adapter

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

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

      koreolis845 created this issue in solectrus/senec-collector

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

      posted in Entwicklung
      D
      dispo112
    • RE: Verständnisfrage Schleife

      @paul53 danke.
      Ich setze das grad mal um. Wo finde ich den "und" Baustein?

      posted in Blockly
      D
      dispo112
    • RE: [Neuer Adapter] Senec Home Adapter

      @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

      posted in Entwicklung
      D
      dispo112
    • RE: [Neuer Adapter] Senec Home Adapter

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

      posted in Entwicklung
      D
      dispo112

    Latest posts made by dispo112

    • RE: [Neuer Adapter] Senec Home Adapter

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

      Schaue ich mir nachher an!

      posted in Entwicklung
      D
      dispo112
    • RE: [Neuer Adapter] Senec Home Adapter

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

      posted in Entwicklung
      D
      dispo112
    • RE: [Neuer Adapter] Senec Home Adapter

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

      posted in Entwicklung
      D
      dispo112
    • RE: [Neuer Adapter] Senec Home Adapter

      @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

      posted in Entwicklung
      D
      dispo112
    • RE: [Neuer Adapter] Senec Home Adapter

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

      posted in Entwicklung
      D
      dispo112
    • RE: [Neuer Adapter] Senec Home Adapter

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

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

      koreolis845 created this issue in solectrus/senec-collector

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

      posted in Entwicklung
      D
      dispo112
    • RE: [Neuer Adapter] Senec Home Adapter

      @oxident
      Ich habe mir überlegt, die PV-Tagesproduktion lokal zu berechnen, indem ich alle 10 Sekunden die Leistung in Watt in Wh umrechne (Leistung × 10s ÷ 3600) und aufsummiere. Zusätzlich berücksichtige ich Speicher-SOC-Änderungen sowie Netzbezug und Einspeisung, um die Energieflüsse besser abzubilden und eine genaue Tagesbilanz zu erhalten. Reset erfolgt um Mitternacht.

      Mal sehen was dabei rauskommt.

      posted in Entwicklung
      D
      dispo112
    • RE: Der "ultimative" ioBroker Lovelace Leitfaden/Dokumentation

      @chrisham stehe vor dem gleichen Problem. Nur die card-mod.js hochladen klappt nicht.
      Wo ist der Fehler?

      posted in ioBroker Allgemein
      D
      dispo112
    • RE: Test lovelace 4.x

      @raducanu
      ich bekomme die Fehlermeldung

      Custom element doesn't exist: power-flow-card.

      Habe die .js Datei aber wie alle anderen auch im Instanzbereich hineinkopiert.
      Hast du eine Idee?

      posted in Tester
      D
      dispo112
    • RE: Test lovelace 4.x

      @garfonso ich habe mich heute mal an das Update auf 3.x gewagt.
      Lovelace lässt sich jetzt nicht mehr aufrufen. Der Adapter läuft...

      Wenn ich eine neue Instanz hinzufüge, klappt es. Nur dann wäre vermutlich eine Woche Arbeit futsch..... Irgendeine Idee?

      posted in Tester
      D
      dispo112
    Community
    Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
    The ioBroker Community 2014-2023
    logo