FTUI Neue Version chart_widget

Begonnen von eki, 31 Januar 2016, 00:17:26

Vorheriges Thema - Nächstes Thema

eki

Es gibt in seit kürzerem die Möglichkeit über $eval beliebige Jave Script Funktionen beim Erzeugen der Header Infos zu verwenden. Beispiel für Rundung (einmal auf eine Nachkommastelle und dann noch auf 2 Nachkommastellen gerundet):

data-title="Klima Wohnzimmer Average: $eval(parseInt($data{avg1}*10)/10)°C / Max: $eval(parseInt($data{max1}*100)/100)°C"

netwalk

Funktioniert perfekt.
Vielen Dank!
live long and prosper
netwalk
_______________________________________________
INTEL NUC7CJYH, Homematic mit 3x HMLGW, JEELINK mit 18x TX29-DTH-IT, DUOFERNSTICK, FB7590 mit FBDECT, NETATMO, Philips HUE, RFXtrx433, Ubiquiti G3 PRO/FLEX/DOME/MICRO

dadoc

Grüß Dich Eki,
Endlich hatte ich mal wieder Anlass, zu einem Gerät schöne Charts zu erstellen - nämlich zum Owl-Energieverbrauchsmesser.
Was ich da u.a. machen will ist eine Chart, in der immer die Verbrauchswerte der letzten und der vorletzten 24 h als Kurven übereinander liegen. So kann man schön die reglmäßigen Verbraucher von den punktuellen unterscheiden. Soweit ich das sehe, geht das mit Bordmitteln des Chart Widget (days_ago...) nicht.
Sollte ich da versuchen, eine zweite Logfile (um 24 h versetzt) zu erzeugen oder gint es andere Tricks?
Grüße
Martin
Standort 1: FS20 mit CUL und FHEM auf Raspi. HM-Komponenten (Heizung, Rollladen, Schalter). HM IP über Raspimatic (testweise)
Standort 2: Homematic (Wired) über CCU2 und PocketHome HD
3 x Raspi3 mit piCorePlayer/Kodi für Multiroom Audio (+ Tablets/iPeng/iPods

eki

#303
Was Du bräuchtest, um das direkt im Chart Widget zu machen, wäre eine zweite X-Achse. Das gibt es bisher im Chart nicht und wäre auch ein großer Aufwand und würde außerdem zu recht viel Konfusion führen, daher möchte ich das lieber nicht einbauen.
Was Du aber machen könntest, wäre das Statistik Modul zu verwenden. Dort können Deltas eines Readings zu zeitlich vorherigen Readingwerten als neue Readings angelegt werden. Mal angenommen Dein Device heißt OWL und das reading heißt power, dann könntest Du mit folgender statistics Definition dafür sorgen, dass bei jeder Änderung des Readings der Unterschied zum Vortag in ein neues Reading mit Namen statPowerDay eingetragen wird:


define stat statistics OWL
attr stat ignoreDefaultAssignments 1
attr stat deltaReadings power
attr stat singularReadings OWL:power:Delta:Day


Wenn Du dieses Reading mit ins Logfile oder Deine LogDB packst, dann kannst Du es entweder direkt als Unterschied darstellen, oder Du kannst es per "stacking" auf den Wert vom aktuellen Tag oben drauf legen und hast dann die Darstellung, die Du haben möchtest. Gib mal Bescheid, ob das klappt und wie das Ergebnis aussieht, interessiert mich auch für meine Verbrauchsmessung.

dadoc

Danke Eki, das werde ich mal versuchen.
War gerade noch am überlegen, ob die Readings nicht vielleicht schon direkt aus der OWL bzw. aus dem OWL-Modul ableitbar sind oder zumindest direkt im Modul 60_CM160.pm erzeugt werden könnten.
Es gibt da ja schon eine Menge "historischer" Daten:
Standort 1: FS20 mit CUL und FHEM auf Raspi. HM-Komponenten (Heizung, Rollladen, Schalter). HM IP über Raspimatic (testweise)
Standort 2: Homematic (Wired) über CCU2 und PocketHome HD
3 x Raspi3 mit piCorePlayer/Kodi für Multiroom Audio (+ Tablets/iPeng/iPods

eki

So wie das aussieht, hast Du ja schon ein statistic Modul am Laufen (siehe stat... Readings). Das könntest Du ja nutzten (also nur das Attribut singularReadings entsprechend setzen).

dadoc

da bin ich mir nicht ganz sicher, ob die stat-Readings nicht direkt aus der OWL ausgelesen werden. Das fhem Owl-Modul jedenfalls scheint nach meinem laienhaften Verständnis nicht das statistic-Modul zu nutzen, und im Modul selbst werden sie anscheinend auch nicht erzeugt/berechnet. Die Owl hat ja auch selbst interne Statistic-Funktionen zur Anzeige auf dem LCD - vermute mal, dass die daher komen.
Standort 1: FS20 mit CUL und FHEM auf Raspi. HM-Komponenten (Heizung, Rollladen, Schalter). HM IP über Raspimatic (testweise)
Standort 2: Homematic (Wired) über CCU2 und PocketHome HD
3 x Raspi3 mit piCorePlayer/Kodi für Multiroom Audio (+ Tablets/iPeng/iPods

eki

Das musst Du wissen, das Format sieht mir aber sehr nach readings vom Statistic Modul aus. Gib einfach mal "list TYPE=statistics" im Kommandofenster von FHEM ein, wenn da was angezeigt wird, hast Du ein statistics Modul am laufen.

dadoc

Zitat von: eki am 19 Februar 2018, 13:37:01
list TYPE=statistics
ergibt nichts, läuft also nicht, damit kann es m.E. nur direkt aus der Owl-Hardware über USB in fhem kommen.
Vielleicht frage ich mal den letzten Bearbeiter des Owl-Moduls.
Standort 1: FS20 mit CUL und FHEM auf Raspi. HM-Komponenten (Heizung, Rollladen, Schalter). HM IP über Raspimatic (testweise)
Standort 2: Homematic (Wired) über CCU2 und PocketHome HD
3 x Raspi3 mit piCorePlayer/Kodi für Multiroom Audio (+ Tablets/iPeng/iPods

dadoc

Zitat von: eki am 19 Februar 2018, 10:25:51
könntest Du mit folgender statistics Definition dafür sorgen, dass bei jeder Änderung des Readings der Unterschied zum Vortag in ein neues Reading mit Namen statPowerDay eingetragen wird:
Ich habe mich nun mal ein bissl in das Statistik-Thema eingelesen (und im Owl-Modul den Code auf Log3 umgestellt...).
Name des Device: CM160
Name des Readings: W
Beispielzeilen aus dem Log:

2018-02-19_19:52:04 CM160 W: 302.40 W
2018-02-19_19:52:25 CM160 W: 302.40 W
2018-02-19_19:53:04 CM160 W: 302.40 W
2018-02-19_20:54:25 CM160 W: 369.60 W
2018-02-19_20:55:04 CM160 W: 369.60 W


Statistics-Definition:

define powerstats statistics CM160
attr powerstats deltaReadings W
attr powerstats ignoreDefaultAssignments 1
attr powerstats room Energie
attr powerstats singularReadings CM160:W:Delta:Day

Log-Definition:
/opt/fhem/log/CM160.log CM160.W:.*|powerstats:statWDay:.*
Das Problem ist, dass ich beim Statistik-Device überhaupt keine Power-Readings sehe (oder kommen die erst nach dem ersten Tag?). Als Readings gibt es:

monitoredDevicesCM160    CM160                              2018-02-19 20:54:26
nextPeriodChangeCalc       2018-02-19 21:59:55         2018-02-19 20:59:55
state                                Updated stats for: CM160   2018-02-19 21:11:26

Wo habe ich da noch einen Fehler drin?
Danke & Grüße
Martin
Standort 1: FS20 mit CUL und FHEM auf Raspi. HM-Komponenten (Heizung, Rollladen, Schalter). HM IP über Raspimatic (testweise)
Standort 2: Homematic (Wired) über CCU2 und PocketHome HD
3 x Raspi3 mit piCorePlayer/Kodi für Multiroom Audio (+ Tablets/iPeng/iPods

dadoc

ok, habs kapiert - die neuen Readings erscheinen beim Owl-Device...
Standort 1: FS20 mit CUL und FHEM auf Raspi. HM-Komponenten (Heizung, Rollladen, Schalter). HM IP über Raspimatic (testweise)
Standort 2: Homematic (Wired) über CCU2 und PocketHome HD
3 x Raspi3 mit piCorePlayer/Kodi für Multiroom Audio (+ Tablets/iPeng/iPods

dadoc

So, das läuft ganz gut mit Deinem Tipp, vielen Dank! Ich muss jetzt noch mal bis morgen warten, bis das Log entsprechend rückwirkend befüllt ist.

Das Problem ist, dass das Owl-Modul das Log überflüssigerweise zuballert, auch wenn es keine Veränderung in den Readings gab. Ungünstig für die Plot-Generierung. Leider unterstützt es nicht event-on-change-reading etc. Wenn ich das richtig verstanden habe, müsste dafür das Aktualisieren der readings im Modul mit readingsBeginUpdate - readingsBulkUpdate bzw. readingsBulkUpdateIfChanged - usw. gemacht werden. Ob ich das aber hinbekomme, wage ich zu bezweifeln, vielleicht habt Ihr ja einen Tipp? Ich denke, die Stelle im Modul wo das einzige (relevante) Reading W gesetzt wird ist:
#read last reading W, if already defined
my $lastva = '0.00 W';
if (defined($hash->{READINGS}{'W'}{VAL})) {
$lastva = $hash->{READINGS}{'W'}{VAL};
}

my %readings = (
'W' => sprintf('%.2f %s', $va, 'W'),
'lastW' => sprintf('%s', $lastva)
);

my $state = sprintf(
'W: %s',
$readings{W}
);

my $log = sprintf(
'%s: %04d.%02d.%02d %02d:%02d - ', $name, $year, $month, $day, $hour, $min
) . $state;

Grüße
Martin
Standort 1: FS20 mit CUL und FHEM auf Raspi. HM-Komponenten (Heizung, Rollladen, Schalter). HM IP über Raspimatic (testweise)
Standort 2: Homematic (Wired) über CCU2 und PocketHome HD
3 x Raspi3 mit piCorePlayer/Kodi für Multiroom Audio (+ Tablets/iPeng/iPods

dadoc

Grüß dich Exi,
Zitat von: eki am 19 Februar 2018, 10:25:51
oder Du kannst es per "stacking" auf den Wert vom aktuellen Tag oben drauf legen und hast dann die Darstellung, die Du haben möchtest. Gib mal Bescheid, ob das klappt und wie das Ergebnis aussieht, interessiert mich auch für meine Verbrauchsmessung.
Ich habe jetzt mal zwei volle Tage Log zur Verfügung. Zwei Fragen hätte ich noch:
1. Die Berechnung des Delta scheint nicht immer zutreffend, Bsp.:
2018-02-20_05:52:04 CM160 W: 369.60 W
2018-02-20_05:52:04 CM160 mstatWDay: 0.00

und
2018-02-21_05:52:04 CM160 W: 1696.80 W
2018-02-21_05:52:04 CM160 mstatWDay: 1394.40

Am 21.2. müsste mstatWDay m.E. 1327 betragen, nicht 1394,40.
Bei anderen Stichproben dagegen stimmt bis hinters Komma:
2018-02-20_07:29:04 CM160 W: 302.40 W
2018-02-20_07:29:04 CM160 mstatWDay: -67.20

und
2018-02-21_07:29:04 CM160 W: 537.60 W
2018-02-21_07:29:04 CM160 mstatWDay: 235.20


Und wenn negative Deltawerte auftauchen, verstehe ich nichts mehr:
2018-02-20_13:49:04 CM160 W: 268.80 W
2018-02-20_13:49:04 CM160 mstatWDay: -100.80

und
2018-02-21_13:49:06 CM160 W: 268.80 W
2018-02-21_13:49:06 CM160 mstatWDay: -33.60


Ich konnte der commandref nicht entnehmen, was DeltaDay genau zugrunde legt - wirklich eine Momentaufnahme zur identischen Zeit des Vortags? Und wenn das Reading des Vortags nicht sekundengenau mit dem des aktuellen Tags korrespondiert?

Zum anderen noch eine Frage zur Darstellung. Du schlägst Stacking vor, aber das würde mir ja den aktuellen Verbrauchswert und den vor 24 h addieren,was wohl nur eine korrekte Darstellung ergäbe, wenn negative Deltawerte korrekt berechnet würden (?). In meinem Verständnis müsste man einfach die aktuelle Verbrauchskurve und die um 24 h versetzte übereinanderlegen. Oder halt den mstatWDay - so er sich mal als vertrauenswürdig erweisen sollte - je nach Vorzeichen entweder addieren oder subtrahieren - oder würden beim Stacking negative Werte von aktuellen Wert auch in der Grafik abgezogen?

Viele Grüße
Martin
Standort 1: FS20 mit CUL und FHEM auf Raspi. HM-Komponenten (Heizung, Rollladen, Schalter). HM IP über Raspimatic (testweise)
Standort 2: Homematic (Wired) über CCU2 und PocketHome HD
3 x Raspi3 mit piCorePlayer/Kodi für Multiroom Audio (+ Tablets/iPeng/iPods

eki

Sorry, habe das erst jetzt gesehen. Leider kann ich zum Statistik Modul nicht so viel sagen, da ich hier auch nur Anwender bin. Vielleicht fragst Du mal in Richtung des Erstellers des Modls.

eki

#314
Es gibt jetzt mal wieder eine neue Version. Da ich für das Feature "beliebig viele Y-Achsen" ziemlich viel im Code ändern musste, stelle ich das jetzt mal hier rein und bitte Freiwillige um ausgiebige Tests. Sollte es soweit funktionieren würde ich das dann in ein paar Tagen "freigeben" und setstate bitten es in das Downloadpaket einzufügen.
Was hat sich geändert:
- Es werden jetzt mehrere Y-Achsen auf der linken und der rechten Seite unterstützt. Dazu muss bei data-uaxis statt eines Strings ('primary') ein Array mit 2 Werten angegeben werden. Der erste Wert ist der normale String für 'primary' bzw. 'secondary' der zweite Wert ist eine Zahl, die die Nummer der Achse angibt (mit 0 beginnend). Um die Parameter für diese Achsen festlegen zu können, müssen die entsprechenden data-... Werte auch als Arrays angegeben werden. Die Achsennummer ist dann der Index im Array.
Beispiel: data-uaxis='[["secondary","0"],["secondary","1"]]' würde 2 sekundäre Y-Achsen rechts festlegen. data-ytext_sec='["Temperatur °C","Temperatur °F"]' würde festlegen, dass die erste sekundäre Y-Achse mit "Temperatur °C" und die zweite mit "Temperatur °F" beschriftet werden (man müsste natürlich dann auch data-minvalue und data-maxvalue als Arrays angeben und auch Plotwerte in den entsprechenden Graphen mit den jeweiligen Skalierungen haben).
Die Achsen werden nebeneinander dargestellt, und machen natürlich den Bereich für das eigentlichen Chart kleiner. Im ersten Ansatz wird immer vom kleinsten zum größten Index aufgefüllt. Ein Klick auf eine der Achsen schiebt die jeweilige Achse dann direkt neben das Chart und die restlichen entsprechend vom Chart weg. Die Grid Linien werden immer passend zu der Achse die dem Chart am nächsten ist dargestellt.
- Unterstützung von HTML Formattierung für Überschriften, Achsenbeschriftungen etc.
  Beispiel: data-title="<b><i>Average:</i></b>\t avg0" würde "Average:" in fett und kursiv schreiben, ein TAB und den Mittelwert dazufügen (\n würde einen festen Zeilenumbruch machen).
- Verbesserungen bei der automatischen X-Achsen Beschriftung
- Bei der X-Achse werden, wenn sich durch auto-Formattierung z.B. Tages- und Stundenangaben mischen, die großen Werte fett gemacht.
- Über data-margin kann ein Abstand zwischen den Buttons oben und dem Chart selbst vogegeben werden.
- Fehlerbeseitigung bei den selbst definierten Gradienten im data-style.
- Fehlerbeseitigung bei Stacking mit Logarithmischen Achsen.
- Fehlerbeseitigung beim Clipping in Safari.

Unten sind die js und css Dateien angehängt, viel Spass beim Testen und bitte melden, wenn Ihr was findet, was nicht funktioniert. Ich habe zwar "Regressionstests" gemacht und darauf geachtet, dass das Ganze "Rückwärtskompatibel" bleibt, aber es gibt so viele Möglchkeiten und Kombinationen dass ich sicher nicht alles prüfen konnte. Außerdem habe ich ein paar Beispiele für die zusätzlichen Achsen und die neuen Formattierungen angehängt.