NEWS
FlexCharts am Beispiel einer Viessmann Wärmepumpen
-
Noch in Bearbeitung!
Vorhaben
Da mittlerweile der FlexCharts Adapter von @jrbwh (weitgehend) ausgereift ist, wird hier aufgezeigt, wie man ihn zur Darstellung von COP Werten und Energien (elektrisch, Wärme) bei einer Vitocal Wärmepumpe einsetzen kann. Folgende Diagramme werden für den jeweils aktuellen Monat erstellt ..
- COP-Werte für Warmwasser, Heizung und gesamt
- Energieumsätze (elektrischer Energie und erzeugter Wärme) für Warmwasser, Heizen und deren Gesamtwerte.
vorab
Wer die hier vorgestellten Beispiele bearbeiten bzw. verwenden will, sollte das Skript in ioBroker im Javascript-Adapter erstellen und die Konfiguration des Charts als JSON in einem Datenpunkt im Objektbaum eintragen.
Strategie
Der Adapter erwartet die Daten (Werte und Konfigurationsparameter) für ein Diagramm (Chart) entweder per Datenpunkt (JSON) oder einer Callback Funktion. Hier wird zunächst nur das erste Vorgehen beschrieben.
Beim hier vorgestellten Vorgehen muss das Chart bereits komplett in einem Datenpunkt im JSON-Format vorliegen. Das Chart wird via JSON.parse als Objekt im RAM allokiert. Hierdurch kann auf jedes Element des Charts direkt zugegriffen und dieses wunschgemäß verändert werden. Sind alle Änderungen erfolgt, so wird das Objekt wieder mittels stringify als JSON zurück in den Datenpunkt im Objektbaum geschrieben. Die Darstellung des Charts wird mittels eines http-Aufruf generiert.
In dem hier vorgestellten Skript wird eine strickte Trennung von Daten und Konfiguration gepflegt. Dies ermöglicht Optionen zur Darstellung des Diagramms (später) über die Visualisierung zu steuern, während die Daten etwa via History Adapter archiviert werden können.
Hinweise ..
Die Darstellung des auf diese Weise aufbereiteten Charts erfolgt vorzugsweise in einem iFrame-Widget. In diesem wird nachfolgender http-Aufruf verwendet:
http://<localhost>:8082/flexcharts/echarts.html?source=state&id=<Adresse des Datenpunktes im Objektbaum von ioBroker>&darkmode
Alle Positions- und Größenangaben sollte man in Prozentwerten - anstelle einer festen Pixelanzahl - angeben. Auf diese Weise fügt sich das Chart - etwa in einem Widget (iFrame) - recht problemlos an.
Der Darkmode lässt sich nicht über einen API-Eintrag im JSON realisieren, es muss der Parameter darkmode im http Aufruf angeben werden.
Energie Chart
Das JavaScript, welche die Aufbereitung des JSON vornimmt, ist hier aufgelistet ..
let timerID let chartJSON = "0_userdata.0.FlexCharts.EnergienPrimärErzeugt" let chart = JSON.parse(getState(chartJSON).val) chart.title.text = "Energien für Warmwasser & Heizung im " + getMonthByName() //Anzahl der Tage im laufenden Monat bestimmen let heute = new Date() let numberOfDays = getDaysInMonth(heute.getFullYear(),heute.getMonth()) //x-Achse mit den Tagen des laufenden Monats füllen chart.xAxis[0].data = new Array(numberOfDays).fill(0) for (let j=0; j<numberOfDays; j++) { chart.xAxis[0].data[j] = j+1 } //Listen der Energiewerte auf 0 setzen for (let j=0; j < 6; j++) { chart.series[j].data = new Array(numberOfDays).fill(0) } //Liefert die Anzahl der Tage eines Monats function getDaysInMonth(year, month) { return new Date(year, month + 1, 0).getDate(); } //Liefert den Name des Monats function getMonthByName() { let Monate = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "Oktober", "November", "Dezember"] let Datum = new Date() return Monate[Datum.getMonth()-1] } function UpdateEnergies(chart) { //Quellobjektadresse (Basiswerte) let srcWP0 = "e3oncan.0.Vitocal.tree.1311_EnergyConsumptionDomesticHotWaterMonthMatrix.CurrentMonth." let srcWG0 = "e3oncan.0.Vitocal.tree.1392_GeneratedDomesticHotWaterOutputMonthMatrix.CurrentMonth." let srcHP0 = "e3oncan.0.Vitocal.tree.1294_EnergyConsumptionCentralHeatingMonthMatrix.CurrentMonth." let srcHG0 = "e3oncan.0.Vitocal.tree.1315_GeneratedCentralHeatingOutputMonthMatrix.CurrentMonth." for (let i=0; i<numberOfDays; i++) { let d = '0' + String(i+1) d = d.slice(-2) chart.series[0].data[i] = getState(srcWP0 + d).val //Warmwasser primär chart.series[1].data[i] = getState(srcWG0 + d).val //Warmwasser erzeugt chart.series[2].data[i] = getState(srcHP0 + d).val //Heizung primär chart.series[3].data[i] = getState(srcHG0 + d).val //Heizung erzeugt chart.series[4].data[i] = 1*getState(srcHP0 + d).val + 1*getState(srcWP0 + d).val //Gesamtenergie primär chart.series[5].data[i] = 1*getState(srcHG0 + d).val + 1*getState(srcWG0 + d).val //Gesamtenergie primär } setState(chartJSON,JSON.stringify(chart),true) } timerID = setInterval(UpdateEnergies,60000, chart) UpdateEnergies(chart) //clearTimeout(timerID);
Das Skript gliedert sich in die Teile allgemeine Einstellungen (Zeilen 1 - 30) und Aktualisierung der Daten (Zeile 32 - 70) sowie einer Steuerung (Zeile 72).
allgemeine Einstellungen
In den Zeilen 21 - 31 werden hilfreiche Funktionen definiert: getDaysInMonth liefert die Anzahl der Tage des laufenden Monats (z.B. Feb. 2024 -> 90 Tage); getMonthByName ermittelt den Monatsnamen. In Zeile 1 wird das Chart aus dem Datenpunkt in ioBroker als JSON ausgelesen und im RAM als Objekt allokiert; der Diagrammtitel wird in Zeile 6 konfiguriert; in 8 - 15 wird die Anzahl der Tage des laufenden Monats als Beschriftung der x-Achse konfiguriert; als Letztes werden die sechs Datenreihen mit 0 initialisiert.
Aktualisierung der Daten
Zum Darstellung der Energiewerte wird die Funktion UpdateEnergies verwendet, welche in Zeile 33 - 55 die Daten in die Datenreihen einträgt, in Zeile 54 wird das Chart als JSON zurück in den Datenpunkt von ioBroker geschrieben.
Steuerung
In Zeile 57 wird eine Intervall-Timer definiert, der alle 60s die Datenreihen aktualisiert und das Diagramm mittels der Funktion UpdateEnergies aktuell hält. Mittels der timerID ließe sich der Timer stoppen.
fertiges Diagramm
Der Datenpunkt zu dem nachfolgenden Diagramm ..
{ "backgroundColor": "#333333", "darkMode": true, "dataZoom": [ { "show": true, "start": 0, "end": 100, "height": "7%", "bottom": "3%" } ], "grid": { "left": "8%", "right": "6%", "top": "20%", "bottom": "15%" }, "legend": { "top": "6%" }, "title": { "text": "Energien für Warmwasser & Heizung im November", "left": "center", "textStyle": { "fontSize": 20, "color": "#ffffff" } }, "tooltip": { "trigger": "axis", "axisPointer": { "type": "shadow" } }, "xAxis": [ { "axisLabel": { "fontSize": 12, "color": "#ffffff" }, "name": "Tag", "nameLocation": "end", "nameTextStyle": { "color": "#ffffff", "fontSize": 10 }, "type": "category", "data": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 ] } ], "yAxis": [ { "name": "Energie", "nameLocation": "end", "nameTextStyle": { "color": "#ffffff", "fontSize": 15 }, "type": "value", "axisLabel": { "formatter": "{value} KWh", "fontSize": 16, "color": "#ffffff" } } ], "series": [ { "name": "Wasser (primär)", "type": "bar", "barGap": "30%", "color": "#0000ff", "stack": "primär", "data": [ 1.1, 1.2, 1.6, 1.3, 1.6, 1.1, 1.6, 1.2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] }, { "name": "Wasser (erzeugt)", "type": "bar", "barGap": "30%", "color": "#7f7fff", "stack": "erzeugt", "data": [ 3.7, 4.1, 5.6, 4.6, 5.3, 3.8, 4.6, 3.6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] }, { "name": "Heizung (primär)", "type": "bar", "barGap": "30%", "color": "#ff0000", "stack": "primär", "data": [ 6.2, 4.6, 8.9, 9.1, 9.7, 8.2, 10.1, 11.2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] }, { "name": "Heizung (erzeugt)", "type": "bar", "barGap": "30%", "color": "#ff7f7f", "stack": "erzeugt", "data": [ 38.8, 31.5, 49.6, 45, 45.6, 43.9, 51.6, 53.9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] }, { "name": "Gesamt (primär)", "type": "bar", "barGap": "30%", "color": "#007f00", "stack": "gesamt0", "data": [ 7.300000000000001, 5.8, 10.5, 10.4, 11.299999999999999, 9.299999999999999, 11.7, 12.399999999999999, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] }, { "name": "Gesamt (erzeugt)", "type": "bar", "barGap": "30%", "color": "#5faf5f", "stack": "gesamt1", "data": [ 42.5, 35.6, 55.2, 49.6, 50.9, 47.699999999999996, 56.2, 57.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] } ] }
Die Anzeige der Daten kann durch (de)selektieren der einzelnen Werte in der Legende dynamisch verändert werden (die Schaltflächen der ausgeblendeten Daten erscheinen in der Legende weiß). Mittels der Zoom-Option können Ausschnitte ausgewählt und angezeigt werden.
======================== COP-Diagramm ========================
Analog zu dem geschilderten Vorgehen wird im Folgenden ein Vorschlag zur Visualisierung der COP-Werte angegeben.
Script des Charts
//Anzahl der Tage im laufenden Monat bestimmen let heute = new Date() let numberOfDays = getDaysInMonth(heute.getFullYear(),heute.getMonth()) //Liefert die Anzahl der Tage eines Monats function getDaysInMonth(year, month) { return new Date(year, month + 1, 0).getDate(); } //Liefert den Name des Monats function getMonthByName() { let Monate = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "Oktober", "November", "Dezember"] let Datum = new Date() return Monate[Datum.getMonth()-1] } let timerID let Chart = JSON.parse(getState("0_userdata.0.FlexCharts.COPs").val) Chart.title.text = 'COP-Werte im ' + getMonthByName() //x-Achse mit den Tagen des laufenden Monats füllen Chart.xAxis[0].data = new Array(numberOfDays).fill(0) for (let j=0; j<numberOfDays; j++) { Chart.xAxis[0].data[j] = j+1 } //Listen der COP-Werte auf 0 setzen for (let j=0; j < 3; j++) { Chart.series[j].data = new Array(numberOfDays).fill(0) } function SetChart(Chart) { //********************* Warmwasser ********************* let srcWP0 = "e3oncan.0.Vitocal.tree.1311_EnergyConsumptionDomesticHotWaterMonthMatrix.CurrentMonth." //elektrische Primärenergie let srcWG0 = "e3oncan.0.Vitocal.tree.1392_GeneratedDomesticHotWaterOutputMonthMatrix.CurrentMonth." //Erzeugte Wärmeenergie //*********************** Heizung *********************** let srcHP0 = "e3oncan.0.Vitocal.tree.1294_EnergyConsumptionCentralHeatingMonthMatrix.CurrentMonth." //elektrische Primärenergie let srcHG0 = "e3oncan.0.Vitocal.tree.1315_GeneratedCentralHeatingOutputMonthMatrix.CurrentMonth." //erzeugte Wärmeenergie let Nenner let NennerGesamt let ZaehlerGesamt let Ergebnis for (let i=0; i<numberOfDays-1; i++) { let d = '0' + String(i+1) d = d.slice(-2) Nenner = getState(srcWP0 + d).val NennerGesamt = Nenner if (Nenner > 0) { Ergebnis = getState(srcWG0 + d).val / Nenner Chart.series[0].data[i] = Ergebnis.toFixed(1) } Nenner = getState(srcHP0 + d).val NennerGesamt = NennerGesamt + Nenner if (Nenner > 0) { Ergebnis = getState(srcHG0 + d).val / Nenner Chart.series[1].data[i] = Ergebnis.toFixed(1) } if (NennerGesamt > 0) { Ergebnis = (getState(srcHG0 + d).val + getState(srcWG0 + d).val) / NennerGesamt Chart.series[2].data[i] = Ergebnis.toFixed(1) } } setState("0_userdata.0.FlexCharts.COPs",JSON.stringify(Chart),true) } SetChart(Chart) timerID = setInterval(SetChart, 120000, Chart)
JSON des Charts
{ "backgroundColor": "#333333", "dataZoom": [ { "show": true, "start": 0, "end": 100, "bottom": "3%", "height": "7%" } ], "grid": { "left": "8%", "right": "6%", "top": "20%", "bottom": "15%" }, "legend": { "show": true, "top": "8%", "textStyle": { "fontSize": 10, "color": "#ffffff" } }, "title": { "text": "COP-Werte im November", "left": "center", "textStyle": { "fontSize": 19, "color": "#ffffff" } }, "tooltip": { "trigger": "axis", "axisPointer": { "type": "shadow" } }, "xAxis": [ { "axisLabel": { "fontSize": 12, "color": "#ffffff" }, "name": "Tag", "nameLocation": "end", "nameTextStyle": { "color": "#ffffff", "fontSize": 10 }, "type": "category", "data": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 ] } ], "yAxis": [ { "name": "COP", "nameLocation": "end", "nameTextStyle": { "color": "#ffffff", "fontSize": 16 }, "type": "value", "axisLabel": { "formatter": "{value}", "fontSize": 16, "color": "#ffffff" } } ], "series": [ { "name": "Warmwasser", "type": "bar", "barGap": "30%", "color": "#0000ff", "data": [ "3.4", "3.4", "3.5", "3.5", "3.3", "3.5", "2.9", "3.0", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] }, { "name": "Heizung", "type": "bar", "barGap": "30%", "color": "#ff0000", "data": [ "6.3", "6.8", "5.6", "4.9", "4.7", "5.4", "5.1", "4.8", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] }, { "name": "Gesamt", "type": "bar", "barGap": "30%", "color": "#ff00ff", "data": [ "5.8", "6.1", "5.3", "4.8", "4.5", "5.1", "4.8", "4.6", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] } ] } ```/Users/leandergroben/Pictures/Photos Library.photoslibrary/resources/renders/3/3D4AB953-2557-4DFA-9988-BAF3D7859E19_1_201_a.jpeg**Fettschrift**