bedarf für plots ausser wert über zeit?

Begonnen von justme1968, 17 November 2014, 22:59:02

Vorheriges Thema - Nächstes Thema

rudolfkoenig

Ich habe nichts dagegen, wenn ich es nicht oder nicht sofort machen muss.
Es kollidiert vmtl. mit meinem "genialen" komprimier Algorithmus, der einzelne Kurven als Cookie ablegt fuer copy&paste.

Johannes

#16
Hallo zusammen,

Ich klinke mich auch mal ein, da ich mit dem Chartfrontend inzwischen einige Erfahrung sammeln konnte, was das Rendern auf der Clientseite angeht, sprich im Webbrowser.

Zitat von: Dr. Boris Neubert am 18 November 2014, 22:01:47
Das Rendern auf einem Raspi dauert so lange, dass ich unangenehme Darstellungspausen habe. Ich hatte Rudi so verstanden, dass bei einer Verlegung des Renderings mittels clientseitigen Javascript, also in den Browser, Updates ganz schnell gehen, weil der Browser den über longpoll kommunizierten neuen Datenpunkt einfach in den Chart dazuschreibt.
Das ist beim Forstschreiben eines bereits gerenderten Charts korrekt, da dort die Datenmenge und die Grafik einfach ergänzt wird. Trotzdem ist der erste Schritt immer, den Plot zunächst zu rendern mit seinen x Datensätzen, bevor er dynamisch erweitert wird um weitere Werte. Die Performance des initialen Renderns des Charts ist schwer abhängig vom eingesetzten Client und kann auch dort, je nach Datenmenge, lange dauern!

Zitat von: justme1968 am 18 November 2014, 23:34:14
das browserseitige rendern bringt glaube ich am meisten bei der interaktion mit dem plot. d.h. zoomen und scrollen. da hier dann nicht mehr neu gerendert werden muss.
Ich würde eher sagen, dass nicht mehr neu "angefordert" werden muss, was die Daten anbelangt. Bei einem Zoom wird natürlich neu gerendert, da einzelne SVG-Elemente versteckt / gezeigt und verschoben werden

Zitat von: klausw am 19 November 2014, 12:37:25
Im Tread Neues Charting / Plotting - GUI Redesign? scheint schon einiges in diese Reichtung zu lauben. Aber wenn ich das richtig verstehe ist das ein eigenes Frontend, das sich nicht in die klassische FHEM Oberfläche enbinden lässt  :-\
Vielleicht lässt sich aber ein Teil des codes für diese Zwecke nutzen.
Ich stelle meine Erfahrung und Code gerne zur Verfügung und bin auch an einer "näheren" Integration in FHEM interessiert. Das verpacken des Chartings in eine etwas aufwändigere Oberfläche war ein Versuch, gleich mehrere Dinge umzugestalten. Es spricht nichts dagegen, den GUI-Overhead wegzulassen und sich auf das Charting selbst zu konzentrieren. Ein Schritt in die Richtung ist übrigens mein letzter Commit in dem Projekt, mit dem sich zuvor angelegte Charts ohne das gesamten Frontend in einer abgespeckten Form als IFrame in FHEM einbinden lassen
. Das ist sicherlich nicht der Weisheit letzter Schluss, aber geht in die Richtung...

Insgesamt bringt das Rendern der Charts im Client Vor- und Nachteile. Konkret:

Vorteile:
  * Ist der Client und Webbrowser performant, läuft die Darstellung sehr zügig, wenn die Datenmenge einen gewissen Schwellenwert nicht überschreitet
  * Häufig ist es tatsächlich so, dass der betrachtende Client mehr "Rechenpower" mit bringt (z.B. herkömmlicher Desktop PC) als der hier häufig genutzte "Server" Raspberry Pi
  * Charts gerendert im Client bringen interaktivität (Mouse-Over, direktes Zoomen, Nachladen von Daten über AJAX, gleichzeitiges Darstellen und Highlighten von Messwerten im Chart und in einer tabellarischen Auflistung etc.)

Nachteile:
  * Ist der Client eher weniger performant (Tablet PCs, Smartphones) ist es in der Regel genauso mit dem Rendering-Verhalten der Charts. Hat man also einen flotten Server aber lahmen Cient, verliert man eher als das man gewinnt, wenn rein die Performance betrachtet wird.
  * Es ist zusätzliche Zeit einzuplanen, da die Daten vom Server zum Client transportiert werden müssen. Mit JSON und gzip-Komprimierung ist man da aber schon sehr flott
  * Beim Überschreiten von Grenzen (Anzahl der Datensätze, die gerendert werden) bremst oder blockiert man den Browser stark aus, gerade auf Tablets / Smartphones

Zitat von: justme1968 am 19 November 2014, 12:56:27
diese charing libs sind eventuell später eine alternative/option. die meisten punkte aus der liste oben und auch auf dem logProxy modul setzen aber eine ebene tiefer an. d.h. beim beschaffen der daten.
das charting frontend kenne ich. es ist aber einen ein komplett neues frontend das sehr direkt auf die db aufsetzt und zur zeit weder mit FileLog noch mit logProxy funktioniert.
mir ist es (wie immer) lieber wenn es so integriert ist das es auch mit anderen fhem komponenten/modulen funktionieren.
Stimmt so nicht, da sowohl Filelog als auch DbLog unterstützt werden. Auch wenn das parsen generell unterschiedlich ausfällt, landen beide nachher in der selben schlichten Syntax, die dann im Chart zum Rendern genutzt werden.

Hier noch zwei Links zu aktuellen JS-Charting Libs, wo es auch schöne Beispiele gibt und mit denen ich gute Erfahrung gemacht habe (erstere wird im Frontend verwendet):
http://dev.sencha.com/extjs/5.0.1/examples/charts-kitchensink/#basic-column
http://www.highcharts.com/demo


justme1968

@johannes: auf jeden fall schon mal danke für dein angebot. so viel im fronten zu tun war (noch) gar nicht meine absicht. zumindest die punkte ganz oben haben (noch) garnicht darauf abgezielt.

das mit den renderzeiten hatte ich auch so gemeint. wenn die datenmenge größer wird nützt weder ein schneller server bei langsamem client noch ein schneller client bei langsamen server. das verhältnis zur datenmenge muss stimmen. vielleicht ist für bestimmte fälle noch etwas luft und ich wollte auch danach schauen aber das war nicht das primäre ziel.

natürlich unterstützt dein modul DbLog (von FileLog wusste ich es noch nicht) aber so viel ich weiß eben auf einer recht tiefen ebene. d.h. es ist zumindest nicht automatisch etwas wie logProxy dazwischenschaltbar. umgekehrt natürlich für einiges auch garnicht nötig.

das ziel das ich mit den punkten ganz oben habe ist primär mit wenigen kleinen änderungen features im plot ausgabe format nachzurüsten die es ermöglichen neue arten von plots zu erstellen wie z.b. den screenshot ganz oben. dazu sind auf SVG seite nur minimale änderungen nötig.

der zweite schritt ist es diese neuen features dann zu nutzen. das zielt nicht primär auf enduser sondern eher auf die modul ebene.

logProxy sehe ich als verbindung dieser beiden ebenen die es auch jemandem der nicht ganz tief einsteigen will erlaubt direkt bei den daten und nicht nur bei reiner konfiguration einzugreifen. eine eigene plot routine ist vielleicht nichts für einen anfäner aber auch der kann sich die sonnenauf- und -untergangszeiten als routine kopieren und einbinden. oder das hinzufügen von aktuellen werten zu historischen daten oder anderes das hoffentlich noch kommt. ich habe schon ideen für windrichtung gesehen und die darstellung der abhängigkeit zweier messgrößen.

die dritte stufe wäre dann ein modul das diese in eins und zwei gesammelten und aufbereiteten daten darstellt. das ist zur zeit das SVG modul. rudi hat ja auch schon ideen angekündigt hier auf client seite mehr machen zu wollen.

einiges von dem feedback oben zielt schon in diese richtung. es scheint also bedarf zu geben. ich könnte mir vorstellen das es irgendwann ein neues SVG modul gibt das zum backend hin kompatibel zum aktuellen ist aber interaktivität und eventuell server entlastung ermöglicht in dem es mehr ins frontend verlagert so wie es mit deinem modul möglich ist. aber eben nicht als komplettes fronten sondern genau so wie man einen aktuellen SVG plot einbetten kann.

ich weiß nicht wie viel vorarbeiten rudi hier schon im kopf und in der tasche hat und das ganze wäre nicht in kurzer zeit gemacht. die umstellung auf 'echte' koordinaten und verwenden von transform ist aber vielleicht schon ein kleiner schritt. das mit den koordinaten brauche ich auf jeden fall. x-werte immer in ein fake datum umzurechnen ist sicher nicht der optimale weg.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

justme1968

@rudi: mir ist gerade noch etwas aufgefallen. du hast schon die optimierung eingebaut das ein neuer punkt nur dann an die polyline angehängt wird wenn er sich in x und y unterscheidet. das nützt aber fast nichts wenn man z.b. einen temperatur plot hat der alle 5 minuten etwas zappelt will dann zwar der x wert gleich ist, der y wert nicht. bei einem temperatur plot den ich hier habe kommen so viele werte zusammen das ein sehr schneller mac nur noch in zeitlupe in der lage ist die SVG kurven beim klick aus und wieder ein zu blenden.

hast du mal probiert pro x wert alle y werte ausser dem größten und kleinsten rauszufiltern? das müsste für diese fälle eigentlich sehr viel bringen.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

rudolfkoenig

Zitatdu hast schon die optimierung eingebaut das ein neuer punkt nur dann an die polyline angehängt wird wenn er sich in x und y unterscheidet

Waere schlau, nicht? :) Leider stimmt es nicht ganz (wenn ich es richtig sehe), und es wird angehaengt wenn x _ODER_ y sich unterscheidet, sonst haettest du das Problem nicht. Man koennte es aber so umbauen, dass bei gleichen x von den vielen y nur min,max und last gemerkt wird. Und man darf dann ueberlegen, wie man das fuer die verschiedenen Linientypen umsetzt.
Und eigentlich kann man das auch fuer ungleiche x durchfuehren, solange delta-x kleiner als ein Punkt auf dem Bildschirm ist.

justme1968

#20
Zitatdu hast schon die optimierung eingebaut das ein neuer punkt nur dann an die polyline angehängt wird wenn er sich in x und y unterscheidet
es war natürlich x oder y gemeint...
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

oniT

Hi,

also wenn man schon dabei ist, hätte ich einen Wunsch in diese Richtung. Oder Vielleicht ist es ja auch schon bereits möglich, ich habe halt nur noch keine Lösung bisher gefunden. Wie im Anhang dargestellt suche ich eine Möglichkeit das ein Balkendiagramm mit jedem neuen Werteintrag im Logfile weiter wächst. Oder anders, es soll somit immer nur der aktuellste Wert aus dem Logfile angezeigt werden. Das ganze dann natürlich eben nicht auf die Uhrzeit, sondern immer auf den gesamten Monat bzw. könnte dies auch zusätzlich noch wöchentlich und jährlich dargestellt werden. Und dann noch als Zusatz, nicht nur ein Balkendiagramm sondern 2 oder 3 nebeneinander.

Ist dies möglich?

Danke
Tino
BBB - debian weezy - FHEM 5.7
HMLAN - HM-LC-Bl1-FM, HM-ES-PMSw1-PI, HM-LC-Sw1-FM, HM-TC-IT-WM-W-EU, HM-WDS40-TH-I, HM-Sen-Wa-Od, HM-Sec-RHS
Dimplex Wärmepumpe / Dimplex ZL 300 - Modbus TCP
SDM630M - Modbus TCP
SolarLog 200 / SMA SonnyBoy 1.5/2.5 - Modbus TCP

justme1968

@rudi: ich habe noch mal genauer nachgeschaut:

beim pushen der koordinaten in die beiden arrays werden nur punkte hinzugefügt wenn sie sich in datum oder wert vom vorherigen unterscheit. d.h. wenn beides gleich ist wird ein punkt übersprungen.

beim zusammenbau der polyline wird ein punkt übersprungen wenn er in x und y gleich dem vorherigen ist. das kann aber eigentlich gar nicht mehr passieren.

das erste sollte doch eigentlich nicht wirklich nötig sein? wie kann es passieren das mehrfach das gleiche datum mit dem gleichen wert im log landet?

bei letztem habe ich bald probehalber eingebaut das bei mehreren werten an der gleichen x position nur ein ymax und min verbunden wird. das ist für den client sehr entlastend. das ein und ausblenden auf monats und jahres stufe funktioniert bei meinem plot damit wieder vernünftig. das könnte etwa so aussehen:--- 98_SVG.pm   2014-11-21 13:34:01.000000000 +0100
+++ 98_SVG.pm.neu       2014-11-21 13:37:04.000000000 +0100
@@ -1545,13 +1545,29 @@
        }

     } else {                            # lines and everything else
+      my ($ymin, $ymax) = (99999999, -99999999);
       foreach my $i (0..int(@{$dxp})-1) {
         my ($x1, $y1) = (int($x+$dxp->[$i]),
                          int($y+$h-($dyp->[$i]-$min)*$hmul));
-        next if($x1 == $lx && $y1 == $ly);
+        if( $x1 == $lx ) { # calc ymin/ymax for points with the same x coordinates
+
+          $ymin = $y1 if( $y1 < $ymin ); 
+          $ymax = $y1 if( $y1 > $ymax ); 
+          $ly = $y1;                     
+          next;                           
+        }     
+
         $ret .=  sprintf(" %d,%d", $x1, $y+$h) if($i == 0 && $isFill);
-        $lx = $x1; $ly = $y1;
+
+        if( $ymin != 99999999 ) { # plot ymin/ymax range for points with the same x coordinates
+          $ret .=  sprintf(" %d,%d", $lx, $ymin);
+          $ret .=  sprintf(" %d,%d", $lx, $ymax);
+          $ret .=  sprintf(" %d,%d", $lx, $ly);
+          ($ymin, $ymax) = (99999999, -99999999);
+        }     
+
         $ret .=  sprintf(" %d,%d", $x1, $y1);
+        $lx = $x1;
       }
       #-- insert last point for filled line
       $ret .=  sprintf(" %d,%d", $lx, $y+$h) if($isFill && $lx > -1);


@oniT: ich glaube ich verstehe nicht was du meinst...
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

rudolfkoenig

Zitatwie kann es passieren das mehrfach das gleiche datum mit dem gleichen wert im log landet?
Weil ein Modul zweimal das gleiche Event in der gleichen  Sekunden generiert?
Ist aber irrelevant, da hier x & y nicht  Originalwerte, sondern bereits skalierte sind, und damit kann das erst recht vorkommen. Ich weiss nicht, was polyline mit "5,3, 5,3" macht (insb. bei gefuellten Flaechen), aber mAn sollte es vermieden werden. Bisher wurde aus "5,3 5,3" ein "5,3". Mit dem Patch wird daraus ein "5,3 5,3 5,3 5,3", und das passt mir nicht so recht. :)

justme1968

polyline macht nichts schlimmes. auch beim füllen nicht.

dein beispiel kann man vermeiden in dem man die zeilenext if($x1 == $lx && $y1 == $ly); mit drin lässt.

es macht wie gesagt auf monats level auf einem schnellen client den unterschied von zu nicht benutzbar zu damit lässt sich noch arbeiten aus.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

rudolfkoenig

#25
Zitatdein beispiel kann man vermeiden in dem man die zeile... mit drin laesst.
Und $ly muss noch gespeichert werden.

Zitates macht wie gesagt auf monats level auf einem schnellen client den unterschied von zu nicht benutzbar zu damit lässt sich noch arbeiten aus.

Und ich dachte, ich beherrsche diese Sprache. Kannst Du das bitte anders formulieren?

Nachtrag: Habe gedanklich an verschiedenen Stellen Pausen eingefuegt, und damit verstanden.

oniT

Hallo justme,

also ich meine es so wie im vorherigen Anhang dargestellt. Beispiel, es werden in einem Logfile Laufzeiten gespeichert. Viele haben hier zum Beispiel eine Brennerlaufzeit über HourCounter oder so etwas. Bei jeder Änderung des Wertes steigt dieser im Logfile an. Im Moment ist es ja so, dass dieser Anstieg des Wertes über die Zeit dargestellt wird. Auf den Tag gesehen als Treppe, oder wie auch immer man das nennen mag.

Jetzt soll daraus allerdings ein Balkendiagramm erzeugt werden. Der Balken in dem Diagramm soll aber nicht erst zum Ende des Tages oder Monats angezeigt werden, sondern ständig mit Zunahme des Werte ansteigen. Bis eben zum Beispiel ein Tageswechsel oder Monatswechsel erfolgt.

Ich hoffe ich konnte es jetzt etwas verständlicher erklären.

Danke

Gruß,
Tino
BBB - debian weezy - FHEM 5.7
HMLAN - HM-LC-Bl1-FM, HM-ES-PMSw1-PI, HM-LC-Sw1-FM, HM-TC-IT-WM-W-EU, HM-WDS40-TH-I, HM-Sen-Wa-Od, HM-Sec-RHS
Dimplex Wärmepumpe / Dimplex ZL 300 - Modbus TCP
SDM630M - Modbus TCP
SolarLog 200 / SMA SonnyBoy 1.5/2.5 - Modbus TCP

justme1968

dazu ist es sicher einfacher wenn du dir zusätzlich wochen- und monatswerte loggst.

das hinterher allgemein im plot zu machen ist glaube ich nicht vernünftig zu konfigurieren.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

justme1968

@Boris: ich habe eben eine neue option scale2reading für logProxy eingecheckt. damit lässt sich der name des readings abhängig vom aktuellen zoomfaktor ändern. wenn man z.b. auf jahres und monats stufe anstelle von temperature auf temperature_avg_day aus dem average modul umschaltet beschleunigt sich der aufbau das plots deutlich.

durch das ändern des reading namens sind in der ganzen pipeline von der abfrage des log device bis hin zum fertigen plots deutlichen weniger daten und diese werde nicht erst irgendwo in der pipeline aufändig reduziert.

die zeile im plotfle würde dann so aussehen:#logProxy DbLog:dbLog,scale2reading={year=>'temperature_avg_day',month=>'temperature_avg_day'}:s300ht_1:temperature::

im wiki steht etwas mehr dazu.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968