Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. ioBroker Allgemein
    4. FlexCharts + Viessmann WP + COP + Energien

    NEWS

    • Monatsrückblick - April 2025

    • Minor js-controller 7.0.7 Update in latest repo

    • Save The Date: ioBroker@Smart Living Forum Solingen, 14.06.

    FlexCharts + Viessmann WP + COP + Energien

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

      in Arbeit ..

      Vorhaben

      Die Viessmann Wärmepumpen liefern Monatsübersichten für primäre und erzeugte Energien getrennt für Warmwasser und Heizung. Aus diesen Daten werden zwei Diagramme erzeugt ..

      • Energiediagramme für Warmwasser, Heizen, elektrisch (primär) und erzeugt (generiert)
      • COP-Werte für Warmwasser, Heizen und gesamt
      • Über zwei DropDown-Widgets können beliebige Jahre und Monate ausgewählt werden.

      Es ergibt sich am Ende folgende Darstellung ..

      37dd4c07-5a2c-4e80-b739-4adbc439d9ab-image.png 35e1c76c-1e87-4755-86ac-f5eb7e04d012-image.png a210ff25-e66b-402e-bef0-063fbb13f15f-image.png

      Ressourcen

      Die Monatswerte werden aus der Wärmepumpe entnommen und als JSON in den Objekt gespeichert. Die Datenpunkte genHeizen, genWasser, primHeizen, primWasser enthalten die Energiewerte für den gewählten Monat. Die auf diese Weise über die Jahre gesammelten Daten können jederzeit aufgerufen und eingesehen werden.

      d063f6d2-7f96-4028-8ca8-dfa257214e6b-image.png 3e0d5e03-d81d-4cc4-8efa-c46d802d7f2e-image.png 8437ca8c-a759-4ac9-acf4-0e63bc426b4a-image.png 75e3892f-1fb6-498d-bda3-0d597df8dc73-image.png

      Die zuletzt aufgeführten Datenpunkte sind zur Steuerung notwendig. Im Einzelnen sind dies ..

      • htmlChart : Aktualisierungszeit der iFrame-Widgets in ms.
      • listMonth : Liste aller Monate des ausgewählten Jahres
      • listYear : Liste der verfügbaren Jahre
      • selMonth : ausgewählter Monat (s. DropDown-Widget für Monate)
      • selYear : ausgewähltes Jahr (DropDown-Widget)

      Widgets

      DropDown-Widgets

      9f5fe982-9e73-42db-a8c6-db34485b8859-image.png

      Das Skript, welches zur Steuerung der Charts eingesetzt wird, besteht aus zwei Teilen: im ersten werden die Funktionen COPs (Diagramm mit COP-Werten) und Energies (Energiewerte) definiert, im zweiten die Steuerungselemente.

      1. Teil ..

      //COP-DIAGRAMM: COP-Werte berechnen und Datenreihen des Diagramms damit befüllen
      function COPs() {    
          let selYear = getState('0_userdata.0.Heizung.MonatsTabellen.selYear').val
          let selMonth = getState('0_userdata.0.Heizung.MonatsTabellen.selMonth').val
          let Chart = JSON.parse(getState('0_userdata.0.FlexCharts.Test_Chart').val)
      
          let srcWP = JSON.parse(getState(`0_userdata.0.Heizung.MonatsTabellen.${selYear}.${selMonth}.primWasser`).val);
          let srcHP = JSON.parse(getState(`0_userdata.0.Heizung.MonatsTabellen.${selYear}.${selMonth}.primHeizen`).val);
          let srcWG = JSON.parse(getState(`0_userdata.0.Heizung.MonatsTabellen.${selYear}.${selMonth}.genWasser`).val);
          let srcHG = JSON.parse(getState(`0_userdata.0.Heizung.MonatsTabellen.${selYear}.${selMonth}.genHeizen`).val);
      
          //Titelzeile des Diagramms setzen
          Chart.title.text = `COP-Werte im ${selMonth} ${selYear}`
      
          //x-Achse mit den Tagen des laufenden Monats füllen
          Chart.xAxis[0].data = []  //new Array(srcWP.length).fill(0)
          for (let j=0; j<srcWP.length; j++) {
              Chart.xAxis[0].data.push(j+1)
          }
      
          //Datenreihen des Diagramms leeren
          for (let i=0; i<3; i++) {
              Chart.series[i].data = []
          }
      
          //Datenreihen mit den Energiewerten befüllen
          for (let i=0; i<srcWP.length; i++) {
      
              //COP für Warmwasser
              if (srcWP[i] > 0) {
                  Chart.series[0].data.push((srcWG[i] / srcWP[i]).toFixed(1))
              } else {
                  Chart.series[0].data.push(0)
              }
              //COP für Heizen
              if (srcHP[i] > 0) {
                  Chart.series[1].data.push((srcHG[i] / srcHP[i]).toFixed(i))
              } else {
                  Chart.series[1].data.push(0)
              }
              //gesamter COP (Warmwasser und Heizen)
              if (srcWP[i] + srcHP[i] > 0) {c
                  Chart.series[2].data.push(((srcWG[i] + srcHG[i]) / (srcWP[i] + srcHP[i])).toFixed(1))
              } else {
                  Chart.series[2].data.push(0)
              }
          }
          //COP-Chart im Objektbaum von ioBroker ablegen
          setState('0_userdata.0.FlexCharts.Test_Chart',JSON.stringify(Chart),true)
      }
      
      //ENERGIEDIAGRAMM: Energiewerte ermitteln und Datenreihen des Diagramms damit befüllen
      function Energies() {
      
          let selYear = getState('0_userdata.0.Heizung.MonatsTabellen.selYear').val
          let selMonth = getState('0_userdata.0.Heizung.MonatsTabellen.selMonth').val
          let Chart = JSON.parse(getState('0_userdata.0.FlexCharts.Test_Chart_2').val)
      
          Chart.title.text = `Energiewerte Wasser&Heizen im ${selMonth} ${selYear}`
      
          let srcWP = JSON.parse(getState(`0_userdata.0.Heizung.MonatsTabellen.${selYear}.${selMonth}.primWasser`).val);
          let srcHP = JSON.parse(getState(`0_userdata.0.Heizung.MonatsTabellen.${selYear}.${selMonth}.primHeizen`).val);
          let srcWG = JSON.parse(getState(`0_userdata.0.Heizung.MonatsTabellen.${selYear}.${selMonth}.genWasser`).val);
          let srcHG = JSON.parse(getState(`0_userdata.0.Heizung.MonatsTabellen.${selYear}.${selMonth}.genHeizen`).val);
      
          //x-Achse mit den Tagen des laufenden Monats füllen
          //Chart.xAxis[0].data = new Array(srcWP.length).fill(0)
          Chart.xAxis[0].data = []
          for (let j=0; j<srcWP.length; j++) {
              Chart.xAxis[0].data.push(j+1)
          }
      
          Chart.series[0].data = srcWP    //Warmwasser primär
          Chart.series[1].data = srcWG    //Warmwasser erzeugt
          Chart.series[2].data = srcHP    //Heizung primär
          Chart.series[3].data = srcHG    //Heizung erzeugt
      
          for (let i=0; i<srcWP.length; i++) {
              Chart.series[5].data[i] = (srcWG[i] + srcHG[i]).toFixed(1)   //generierte Gesamtenergie
              Chart.series[4].data[i] = (srcWP[i] + srcHP[i]).toFixed(1)   //primäre Gesamtenergie
          }
      
          //Chart als JSON im Objektbaum von ioBroker ablegen
          setState('0_userdata.0.FlexCharts.Test_Chart_2',JSON.stringify(Chart),true)
      }
      

      2. Teil ..

      Zur Auswahl der Jahre bzw. Monate werden DropDown-Widgets verwendet. Hierbei werden deren Datenfelder nicht statisch eingetragen, sondern mittels Binding aus oben aufgeführten Datenpunkten entnommen. Die Werteliste für die Jahre und Monate werden per Skript aus den Objekten in ioBroker dynamisch ermittelt. Hierzu wird die function listEntries(..) verwendet, die alle Verzeichnisse im übergebenen Pfadverzeichnis (parentPath) liefert. Sie wird sowohl zum Auffinden der Jahre- als auch Monatsverzeichnisse verwendet.

      Über zwei Trigger werden bei Änderungen der DropDown-Widgets deren Listeneinträge aus dem Objektbaum von ioBroker bzw. die darzustellenden Charts aktualisiert.

      function listEntries(parentPath) {
          let Elemente = [];
          //Pfadlänge parentPath
          let maxSplit = parentPath.split('.').length + 1
      
          $(`${parentPath}.*`).each(function(id) {
              let arr = id.split('.',maxSplit+1)
              let child = id.split('.',maxSplit).join('.')
              if (!Elemente.includes(arr[maxSplit-1]) && (getObject(child).type === 'folder')) {
                  Elemente.push(arr[maxSplit-1]);
              }
          });
          return Elemente;
      }
      
      //listMonth des zugehörigen DropDown-Widgets füllen
      function listMonthYear() {
      
          let year = getState('0_userdata.0.Heizung.MonatsTabellen.selYear').val
          let parentFolder = `0_userdata.0.Heizung.MonatsTabellen.${year}`;
          let entries = listEntries(parentFolder);
      
          //Monatsnamen in die richtige Reihenfolge bringen
          let Months = ['Januar', 'Februar', 'Maerz', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember']
          let listMonth = []
          Months.forEach(function(eintrag) {
              if (entries.includes(eintrag)) {
                  listMonth.push(eintrag)
              }
          })
          //DropDown-Widget der Monate befüllen
          setState('0_userdata.0.Heizung.MonatsTabellen.listMonth',listMonth.join(';'),true)
      
      }
      
      //Beim Start des Skripts wird das DropDown-Widget für die Jahre gefüllt.
      let parentFolder = '0_userdata.0.Heizung.MonatsTabellen';
      let entries = listEntries(parentFolder);
      entries.sort
      setState('0_userdata.0.Heizung.MonatsTabellen.listYear',entries.join(';'),true)
      
      //Bei Auswahl des Jahres muss das DropDown-Widget für die Monate aktualisiert werden
      on({id: '0_userdata.0.Heizung.MonatsTabellen.selYear', change: 'any'}, function() {
          listMonthYear()
          setState('0_userdata.0.Heizung.MonatsTabellen.selMonth','')
      });
      
      //Bei Auswahl eines Monats im DropDown-Widget werden COP- und Energie-Diagramm neu aufgebaut
      on({id: '0_userdata.0.Heizung.MonatsTabellen.selMonth', change: 'any'}, function(obj) {
          COPs()
          Energies()
          setState('0_userdata.0.Heizung.MonatsTabellen.htmlChart',1000,true)
          setTimeout(() => {setState('0_userdata.0.Heizung.MonatsTabellen.htmlChart',300000,true),1000})
      });
      

      96716296-a53e-45bb-b0db-91c585e9eaed-image.png

      iFrame-Widgets

      Zur Anzeige der Monatswerte werden iFrame-Widgets verwendet.

      e023a08d-8881-4c59-84f6-7fe6f7db73b6-image.png

      • Quelle : Hier wird der für FlexCharts überliche HTML-Aufruf eingetragen, der die Referenz zu dem Datenpunkt enthält, in dem das Chart als JSON abgelegt ist.
      • Updatezeit(ms) : Diese wird nicht statisch eingetragen, sondern mittels Binding aus dem Objektbaum von ioBroker (s. oben: htmlChart) entnommen.

      Anm.: Üblicherweise sollte sich ein Widget aktualisieren, wenn seine Quelle sich ändert. Dies funktioniert offenbar bei iFrames leider nicht. Daher wird sozusagen ein Kunstgriff verwendet: Immer dann, wenn sich das DropDown-Widget für den Monat ändert, wird in den iFrames die Updatezeit neu auf den gewünschten Wert gesetzt. Hierdurch aktualisiert sich das iFrame unmittelbar neu.

      Merlin123 1 Reply Last reply Reply Quote 2
      • Merlin123
        Merlin123 @legro last edited by

        @legro Danke für den Tipp mit dem Refresh. Klappt super! 🙂

        L 1 Reply Last reply Reply Quote 0
        • L
          legro @Merlin123 last edited by legro

          @merlin123

          Es geht noch kürzer. Es reicht einfach die gewünschte Update-Zeit (htmlChart) neu zu schreiben.

          on({ id: '0_userdata.0.FlexCharts.refresh', change: 'any' }, () => {
            setState('0_userdata.0.Heizung.MonatsTabellen.htmlChart', 3000000, true);
          });
          

          Dieser Code sorgt dafür, dass das Diagramm unmittelbar neu aufgebaut werden.

          Merlin123 1 Reply Last reply Reply Quote 0
          • Merlin123
            Merlin123 @legro last edited by

            @legro Also quasi bei jeder Änderung einfach nur den DP, wo das Intervall steht, neu schreiben? Cool! Danke!

            L 1 Reply Last reply Reply Quote 0
            • L
              legro @Merlin123 last edited by

              @merlin123

              Ja, so einfach geht‘s.

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

              Support us

              ioBroker
              Community Adapters
              Donate
              FAQ Cloud / IOT
              HowTo: Node.js-Update
              HowTo: Backup/Restore
              Downloads
              BLOG

              982
              Online

              31.6k
              Users

              79.4k
              Topics

              1.3m
              Posts

              2
              5
              372
              Loading More Posts
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes
              Reply
              • Reply as topic
              Log in to reply
              Community
              Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
              The ioBroker Community 2014-2023
              logo