NEWS
Test Adapter flexcharts - Stapeldiagramme und mehr
-
Motivation
Habt ihr auch schon mal die Möglichkeit vermisst, "richtige" Stapeldiagramme zu erzeugen? Oder andere spezielle Diagramme, die momentan mit ioBroker nicht möglich sind? Mit dem Adapter flexcharts ist das möglich. Ein Stapeldiagramm sieht dann z.B. so aus:
Der ECharts-Adapter ist klasse, hat aber durch das UI-Konzept Einschränkungen bzgl. der möglichen Diagramm-Typen.
Konzept
Mit dem flexcharts-Adapter ist es möglich, alle Diagrammtypen zu erzeugen, die Apache eCharts anbietet. Dazu übergibt man dem Adapter die komplette Definition des Charts (den Inhalt von
options
in den Beispielen als JSON-Objekt). Man kann das Chart also nicht per UI zusammen klicken (es gibt keine UI), sondern muss es per Javascript oder Blockly erstellen.Der Adapter arbeitet als Web-Extension, benötigt also den Web-Adapter und ist per Default auf Port 8082 erreichbar. Das Verhalten steuert man über Parameter im http-Aufruf. Beispiel:
- Definition und Daten des Charts hat man im State
0_userdata.0.echarts.chart1
gespeichert - Dann erzeugt der Aufruf
http://localhost:8082/flexcharts/echarts.html?source=state&id=0_userdata.0.echarts.chart1
das entsprechende eChart. Diese Adresse kann man als iFrame z.B. in der vis oder in jarvis eintragen. Oder direkt in einem Browser-Tab. Stattlocalhost
ggf. die Adresse der ioBroker-Rechners verwenden. - Statt die Chart-Daten in einem State zu speichern, kann man sie direkt per Skript erzeugen und mit callback() an den Adapter übergeben.
- Ein Demo-Chart ist im Adapter hinterlegt, das ruft man auf mit
http://localhost:8082/flexcharts/echarts.html?source=state&id=flexcharts.0.info.chart1
Details zu Installation und Verwendung sind im README beschrieben:
https://github.com/MyHomeMyData/ioBroker.flexchartsBitte ausprobieren
Adapter ist im Beta-Repo verfügbar. Link zum npm-Paket.
Ich freue mich auf eure Rückmeldungen!Hinweis zu Versionen kleiner als 0.1.4
Falls jemand eine Version vor 0.1.4 installiert hat: Bitte einmal den Adapter (nicht nur die Instanz) komplett deinstallieren und neu installieren. Dadurch wird das Zusammenspiel mit dem Admin-Adapter aufgeräumt. Da der Adapter keine eigene Konfigurationsparameter hat, kann dabei nichts verloren gehen.
- Definition und Daten des Charts hat man im State
-
Ich hab jetzt endlich mal die Zeit gefunden deinen Adapter kurz anzuschauen (ein 12 Wochen altes Baby verschiebt dann halt berechtigterweise doch die Prioritäten )
Daumen Hoch - das ist mal ne sehr mächtige und flexible Implementiering von Charts. Jetzt muss ich nur noch die Zeit finden aus meinen teils einmal am Tag ebenfalls via Skript befüllten DPs das passende JSON via Skript für das Chart zu erstellen.
In der Readme schreibst du, "I'm working on a more elaborated javascript template to simplify usage of the adapter. Stay tuned.", d.h. du arbeitest an einer generischen Lösung?
-
@darkiop Danke für das positive Feedback. Für eine recht spezifische Anwendung für Nutzer der Viessmann Wärmepumpe Vitocal habe ich eine konkrete Umsetzung geschrieben - das nutze ich auch selbst. Die Anleitung findest Du hier.
Das funktioniert natürlich nur mit dem spezifischen Datenformat, das die Wärmepumpe liefert. Das sieht für die monatlichen Werte so aus:
{"CurrentMonth":{"10":9,"11":4.6,"12":10.1,"13":4.5,"14":5.5,"15":5.3,"16":5.6,"17":10,"18":4.2,"19":10.4,"20":9.2,"21":4.9,"22":10.2,"23":9.2,"24":8.4,"25":4.6,"26":10.5,"27":4.6,"28":9.9,"29":4.7,"30":6.4,"31":0,"01":4.5,"02":5.9,"03":6,"04":9.9,"05":4.7,"06":10.7,"07":4.9,"08":5.6,"09":10.3},"LastMonth":{"10":9.4,"11":5.3,"12":9.6,"13":8.9,"14":9.7,"15":9.2,"16":9.4,"17":9.6,"18":9.4,"19":4.6,"20":9.4,"21":5.2,"22":9.5,"23":4.4,"24":10,"25":4.5,"26":9.8,"27":4.6,"28":10.3,"29":4.8,"30":5.6,"31":10,"01":0,"02":0,"03":0,"04":9.8,"05":11.4,"06":9,"07":10.1,"08":9.6,"09":9.2}}
An einem Skript für z.B. täglich gespeicherte Daten bin ich dran. Wie sieht denn Dein Datenformat konkret aus?
Gruß, Jürgen
P.S.: Glückwunsch zum Baby. Die Zeiten liegen bei mir schon lange zurück, ich kann mich aber noch lebhaft daran erinnern Wir durften uns vor 2 Wochen über die Geburt unseres ersten Enkelkindes freuen
-
@darkiop Habe jetzt ein erstes Javascript-Template erstellt. Damit können kombinierte Stapel-/Linien-Diagramme erstellt werden, wenn die Daten als Tages-, Monats- oder Jahres-Werte im History-Adapter vorliegen. Das Template liegt hier.
Wichtig: Die History-Daten müssen "sauber" sein, d.h. in jeder Datenreihe muss zu jedem Tag/Monat/Jahr genau ein Wert vorhanden sein. Sowohl mehrfach vorhandene, als auch fehlende Werte führen meist zu seltsamen Effekten in den Charts.
Um das Template zu benutzen, müssen einige Werte im Skript angepasst werden. das ist alles in den Kommentaren im Skript beschrieben. Wenn alles klappt, sieht ein typisches Ergebnis dann so aus:
-
@jrbwh Super. Vorab schonmal danke dafür. Ich werde morgen mal versuchen es mir anzuschauen und dir dann auch mal ein Beispiel für meinen ersten usecase geben.
-
@jrbwh "sondern muss es per Javascript oder Blockly erstellen."
sorry, das ist für mich kein adapter. -
@da_woody Danke für Deine Rückmeldung. Aus meiner Sicht stellt dieser Ansatz Funktionalität für ioBroker bereit, die bisher nicht verfügbar ist. Es wird das volle Potenzial von Apache ECharts erschlossen.
Z.B. ist es mir bisher nicht gelungen, Stapeldiagramme in ioBroker zu erzeugen. Auch im Forum konnte mir niemand eine Lösung zeigen. Mit Grafana mag das gehen, aber das funktioniert weitgehend außerhalb ioBroker und ich wollte bei ECharts bleiben.
Mit flexcharts ist das nun innerhalb von ioBroker möglich. Und sehr viele weitere Arten von Darstellungen sind ebenfalls nutzbar, ECharts hat da ja eine große Bandbreite.
Die Schnittstelle von flexcharts ist zwar etwas ungewöhnlich, eröffnet aber auch sehr viele Möglichkeiten. Deshalb sehe ich das schon als Adapter.
Wenn Du eine einfachere Möglichkeit siehst, das volle Potenzial von Apache ECharts für ioBroker verfügbar zur machen, bin ich daran sehr interessiert.
-
@da_woody sagte in Test Adapter flexcharts 0.0.1 - Stapeldiagramme und mehr:
@jrbwh "sondern muss es per Javascript oder Blockly erstellen."
sorry, das ist für mich kein adapter.Sehe ich auch so. Blicke da nicht durch.
Gibt es ein Blockly Beispiel? Wie bekomme ich die History Daten da rein? -
@sigi234 Danke für Deine Rückmeldung.
Leider arbeite ich selbst nicht mit Blockly, deshalb gibt es da noch kein Beispiel.Grundsätzlich geht es so:
- Darzustellende Daten beschaffen, z.B. aus der History lesen
- Ein Objekt erstellen, das eine für ECharts passende Struktur hat. Beispiel für ein einfaches Balkendiagramm s.u. Deine einzelnen Datenreihen musst Du jeweils im Key "data" speichern.
- Das Objekt im JSON-Format in einem State speichern, z.B. unter der ID
0_userdata.0.flexcharts.chart1
- In einem Browser-Tab oder in einem iFrame die ID des States an flexcharts übergeben. Also mit
http://localhost:8200/echarts.html?source=state&id=0_userdata.0.flexcharts.chart1
Mir ist schon klar, dass das ein bisschen kompliziert ist und sich nicht direkt erschließt. Das ist für Fälle gedacht, wenn man mit den GUI-basierten Ansätzen nicht weiter kommt und man bereit ist, mehr Zeit in das Thema zu investieren.
Template für ein einfaches Balkendiagramm mit einer Datenreihe:
{"tooltip":{"trigger":"axis","axisPointer":{"type":"shadow"}}, "legend":{}, "xAxis":[{"type":"category","data":["Mon","Tue","Wed","Thu","Fri","Sat","Sun"]}], "yAxis":[{"type":"value"}], "dataZoom":[{"show":true,"start":0,"end":100}], "series":[ {"name":"Meine Datenreihe 1","type":"bar","color":"#a30000","data":[8,19,21,50,26,1,36]} ]}
-
@jrbwh
Kannst du einen Fehler bzgl. Port abfangen? In meinem Fall ist es dercameras
-Adapter, der nutzt auch 8200.
Oder evtl. direkt einen anderen Port verwenden?
error: flexcharts.0 (458177) Exception-Code: EADDRINUSE: listen EADDRINUSE: address already in use :::8200
-
@mcu Danke für den Hinweis. Nein, habe ich nicht abgefangen. Werde ich einbauen.
Den Default ändere ich dann auch gleich. Gibt es eine Liste der bereits verwendeten Ports?
-
-
@mcu Super. Danke!
-
@mcu Habe den Default-Port jetzt auf 3100 geändert. Da grafana auf 3000 liegt, scheint mir das passend.
Mein Versuch, einen Port-Konflikt abzufangen, funktioniert aber bisher nicht. Ich habe den Start des http-Servers in ein try-catch gepackt, trotzdem stürzt der Adapter im Konfliktfall ab und meldet für die Zeile vonthis.webServer.listen
diesen Fehler:uncaught exception: listen EADDRINUSE: address already in use
. Der Code sieht so aus:try { this.webServer.listen({port: this.config.port}, () => { this.log.info(`Server started on localhost:${this.config.port}`); this.setState('info.connection', true, true); }); } catch (e) { this.log.error(`Start of http server failed on localhost:${this.config.port} - err=${e.message}`); this.setState('info.connection', false, true); }
Verstehe ich nicht. Wie hast Du das gelöst?
-
@jrbwh Nimm die Funktion.
const check_port = await this.getPortAsync(this.config.port);
Ist der Prot belegt gibt check_port den nächsten freien wieder.
Gruß//Lucky
-
@lucky_esa Wow, kaum macht man es richtig, funktioniert's.
Vielen Dank für die super schnelle Hilfe!
-
@jrbwh sagte in Test Adapter flexcharts 0.0.1 - Stapeldiagramme und mehr:
An einem Skript für z.B. täglich gespeicherte Daten bin ich dran. Wie sieht denn Dein Datenformat konkret aus?
Ich bin leider immer noch nicht dazugekommen mich damit zu beschäftigen ... Aber der Winter ist ja lange
Hier mal ein einfaches Beispiel wofür ich deine Charts verwenden würde:
Die 3 Werte werden täglich um 23:59 ermittelt und in eine MariaDB mit dem SQL-Adapter geschrieben. Für das Chart stelle ich mir ein Balkendiagram mit den 3 Werten pro Tag und vielleicht 7 Tage zurück vor. In etwa so, nur eben xAxis.data ausgehende vom heutigen Tag -7d.
option = { xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] }, yAxis: { type: 'value' }, series: [ { data: [120, 200, 150, 80, 70, 110, 130], type: 'bar' }, { data: [120, 200, 150, 80, 70, 110, 130], type: 'bar' }, { data: [120, 200, 150, 80, 70, 110, 130], type: 'bar' } ] };
-
@darkiop Das sollte mit dem Skript-Template direkt möglich sein, wie in meinem Post vom 31. Aug. 2024, 11:54 beschrieben. Folgendes musst Du anpassen:
"instanceHistory": Deine History-Instanz eintragen
"yAxis": Die 2te y-Achse entfernen
"mySeries.daily": Für die ersten 3 Zeilen Deine Datenpunkte eintragen, alles "stack_a" zuordnen (sofern es ein Stapeldiagramm mit einem Balken werden soll). Die restlichen Zeilen löschen.
"mySeries.monthly" und "mySeries.yearly": Alle Zeilen löschen, also nur [] übrig lassen
Aufrufen mit " ...params={"period":"daily", "start":7} -
-
@legro Danke für den Hinweis. Habe den Link in der Beschreibung ergänzt.