SmartVISU + fronthem - Plotübergabe (gelöst)

Begonnen von blitz94, 10 Februar 2021, 17:22:22

Vorheriges Thema - Nächstes Thema

blitz94

Hallo zusammen,

arbeite aktuell an der Visualisierung von Graphen (Plots) mit SmartVISU über FHEM.
Habe dazu die Anleitung in folgendem Threat durchgearbeitet:
https://forum.fhem.de/index.php/topic,86584.0.html

Nach erfolgreichem Update der benannten Dateien war es nun möglich, in den GADs auch Plots zu bearbeiten.
Leider bekomme ich es nicht her, dass die Daten im Logfile auch tatsächlich ausgelsen und in SmartVISU angezeigt werden. Ich habe mittlerweile dutzende Kombinationen erfolglos versucht miteinander zu verbinden.

Mein Wunsch wäre es, das in FHEM definierte Element "WZ_Istwert", welches ins Logfile schreibt "FileLog_WZ_Heizung".

Ich habe im Anhang Screenshots der GAD Konfiguration und einen Logfileauszug angehängt. Ich wäre sehr für eure Ideen dankbar.

Zudem habe ich noch eine Fehlermeldung im Logfile finden können, mit der ich leider nicht viel anfangen kann.
2021.02.10 17:06:20 1: Devices: error doing $result = fronthem::Plotfile($param); Undefined subroutine &main::timelocal called at ./FHEM/99_fronthemUtils.pm line 38.

GammaTwin

Grüße,

Deine Einstellung im Screenshot sollte funktionieren. Wie viele Einträge hat den der Logfile? Kopiere mal die Datei, kürze diese mal drastisch auf den letzten Tag und probiere es dann mal mit der gekürzten Version.

blitz94

Hallo, vielen Dank für deine Antwort.

Ich habe für diesen Zweck extra ein Versuchslogfile angelegt, das aktuell ca. 300 Einträge umfasst. Auch nach dem Löschen und Befüllen mit ca. 10 Werten kommt leider keine Grafik zustande.

Was mich etwas stuzig macht sind zwei Dinge
- Wenn ich den Browser mit SmartVisu offen habe, werden die aktuellsten Datensätze übergeben und in der Grafik dargestellt. Diese scheinen aber nur temporär zu sein, da sie nach einem Refreh der Seite wieder verschwinden.
- Die Fehlermeldung in der FHEM Log.
"Devices: error doing $result = fronthem::Plotfile($param); Undefined subroutine &main::timelocal called at ./FHEM/99_fronthemUtils.pm line 38."

GammaTwin

Hänge hier mal die Bsp-Datei an. Ich versuche das mal nachzustellen.

blitz94

Vielen Dank, das wäre sehr nett :)
Ich habe dir im Anhang die LogDatei angehängt, wie sie in FHEM generiert wird. Kann dir bei bedarf gerne noch weitere Dateien zukommen lassen.

GammaTwin

Grüße,

ich habe die Datei in mein Log-Verzeichnis gelegt und folgendes FileLog-Device angelgt.
defmod FileLog_WZ_Sollwert FileLog ./log/autocreate/WZ_Sollwert-%Y.log test

Meine fronthem-Einstellungen: Diese entsprechen Deinen Einstellungen aus dem ersten Post, angepasst auf Sollwert und anderen Dateinamen
"type" : "plot",
"reading" : "getG1",
"converter" : "Plotfile FileLog_WZ_Sollwert",
"device" : "WZ_Sollwert",


Und dann erhalte ich auch eine Grafik in smartVISU. Ich erhalte auch keinen Fehler im Log.

:-\ Also, die Einstellungen stimmen, es sollte funktionieren. Der Fehler liegt also wo anders.

blitz94

Vielen Dank für deine Hilfe! Habe mir - da wir die Konfiguration ausschließen konnten - nochmal die Fehlermeldung " &main::timelocal" genauer angesehen und bin irgendwo im Forum auf einen ähnlichen Fehler gestoßen.

Kurzum: Falls so etwas bei jemandem auftreten sollte, ist die Lösung eine der obersten Zeilen "use Time::HiRes qw(gettimeofday);"  im File "99_fronthemUtils.pm" durch folgende zu ersetzen:
use Time::Local;

Jetzt kommen die Daten in SmartVISU an.

Danke nochmal und lg

Boe3eh

Hallo,
ich habe das Problem, dass meine Logfiles zu groß werden (ich logge jede Stunde einen Wert, also 24*365=8760 pro Jahres-File), irgendwann sind um die 3000 Werte in dem File und dann bekomme ich in der SmartVISU den Plot nicht mehr angezeigt. Reduziere ich die Einträge in dem File ist der Plot wider da.
Hat jemand eine Idee, wo ich anpassen muss, dass ich das Jahresfile mit den 8760 Zeilen in SmartVisu als Plot dargestellt bekomme.
Hier mein Plot in Smartvisu:
{{ plot.period('AT',
         'AT',
         'avg',
         '1y',
         'now',
         '-25',
         '45',
         '100',
         ['Außentemperatur Süd'],
         ['#0000FF'],
         ['line'],
         '',
         'advanced',
         '',
         '',
         '',
         '',
         ['°'],
         { yAxis: [ { tickInterval: 1} ], legend: { verticalAlign: 'bottom', y: -5 }, rangeSelector: {selected: '2'}})
         }}



wvhn

Der Aufruf des Plot-Widgets ist in Ordnung. Die eckigen Klammern brauchst Du nur, wenn Du mehrere Datenreihen oder y-Achsen hast und dafür Parameter als Arrays angeben musst. Sie schaden aber nicht.

Die Anzahl der Datenpunkte im Plot könntest Du von 100 auf 365 stellen, um für jeden Tag einen Temperaturwert  zu halbwegs konstanten Uhrzeiten zu bekommen. So wie Du es jetzt eingestellt hast, bekommst Du alle 87-88 Stunden einen Wert, also Werte, die von ganz unterschiedlichen Uhrzeiten stammen.

Das Problem der fehlenden Daten liegt vermutlich  auf der fronthem-Seite, dort wo das Logfile aufbereitet wird. Da kann ich Dir nicht weiter helfen. Wenn Du im Treiber (./driver/io.fhem.js) den Loglevel auf 2 stellst, wird beim Aufrufen der betreffenden Seite der Datenverkehr zwischen smartVISU und fronthem auf der Entwicklerkonsole des Browsers ausgegeben. Poste mal das Ergebnis. Vielleicht gibt das weiteren Aufschluss.

Gruß
Wolfram

Boe3eh

Hallo,
prinzipiell wird ja der Plot angezeigt. Jedoch scheint es an der Anzahl der Einträge im File zu liegen, dass der dann nicht mehr dargestellt werden kann?
GammaTwin hatte in diesem Post am 11 Februar 2021, 09:30:00 geziehlt nach der Anzahl der Einträge gefragt, daher meine Hoffnung das dazu die Lösung schon bekannt ist?!
Ich schau dann aber mal, ob über das Log wie du beschrieben hast was zu sehen ist...

GammaTwin

Grüße,

das Problem mit der Anzahl ist noch vorhanden. Ob es aber das gleiche Problem ist, weiß ich nicht. Ich beschreibe meine Auffälligkeit.
Ich nutze als Quelle allerdings eine SQL-DB und nicht den Logfile.

##############Einstellung "raw"

Ich habe ein Diagramm, welches meinen Strombezug bzw. -lieferung darstellt. Es werde alle 5 Sekunden beide Werte geliefert.
Ich stelle die letzten 11 Minuten mit der Einstellung "raw" dar, neue Werte werden schön hinzugefügt - sieht toll aus, wenn man sich einen Kaffee rauslässt und die dazugehörige Stromspitze sieht :D
{{ plot.period('pAktLiefBezugFein', ['Strom.aktLieferung.plot', 'Strom.aktBezug.plot'], 'raw', '11i', 'now', '', '', '', ['Lieferung', 'Bezug'], ['#aa0', '#ce7f2b'], ['area', 'area'], '', '') }}

Erhöhe ich die Zeit von 11i passiert folgendes:
- 5h: es kommen keine Werte
- 4h: Es erscheinen Werte
- 240i (entspricht 4h in Minuten): es kommen keine Werte
- 99i ist die Grenze, da werden Werte angezeigt

Vereinfacht: Für "raw" scheinen folgende Grenzen zu gelten:
Stunden: 4h
Minuten: 99i

Was übrigens immer klappt: Es werden neue Werte hinzugefügt.

##############Einstellung "avg"

In Deinem angehängten Beispiel hast Du ja "avg" verwendet und ein Jahr "1y" als Zeitraum gewählt.

Ich habe das gleiche Diagramm noch als "Langzeit-Chart": 72h
{{ plot.period('pAktLiefBezugGrob', ['Strom.aktLieferung.plot', 'Strom.aktBezug.plot'], 'avg', '72h', 'now', '', '', '', ['Lieferung', 'Bezug'], ['#aa0', '#ce7f2b'], ['area', 'area'], '', '1h') }}

Wenn ich da auf "1y" stelle, bleibt mein FHEM ca. eine Minute stehen und dann wird das Chart angezeigt. Es werden dafür so grob 21.000.000 Werte genutzt (2 Daten * 365 Tage * 24 Stunden * 60 Minuten * 20 Sekunden (alle 5 Sek kommt ein Wert)). Es werden 12 Schritte (Monate) auf der x-Achse dargestellt.

Für mich heißt das aber, dass für die Einstellung "avg" keine Grenze für die Darstellung der Werte gibt.

Wie am Anfang gesagt, es könnte auch ein völlig anderes Phänomen für Einstellung "raw" sein.

wvhn

Das smartVISU Widget Plot.period macht nichts anderes, als die Daten beim Backend anzufordern und 1:1 an Highcharts weiter zu leiten. Highcharts kann Hunderttausende von Punkten darstellen und sollte in Euren Fällen keine Begrenzung darstellen. Die Aufbereitung der Daten (Zeitbereich, Anzahl, Wertearten 'raw', 'avg' usw.) ist Aufgabe des Backends. Zur Lösung des Problems wäre es deshalb wichtig, zu sehen, welche Daten das Backend bei der Anfrage liefert. Dazu brauche ich die Logs von der Konsole.

Gruß
Wolfram

wvhn

#12
Leider sind wir hier noch nicht weiter gekommen und die benötigten Konsolenausgaben zum Eingrenzen des Fehlers habe ich bisher nicht gesehen.

Ich habe deshalb nochmal den Code des fhem-Treibers untersucht und es bestätigt sich meine obige Aussage, dass die Aufbereitung der Plot-Daten komplett im fhem/fronthem gemacht wird.

Innerhalb von smartVISU wird ein Plot-Item wie folgt benannt:

hcs.data.OilLevelPlot.avg.5y 6m.0.100 -- count
|-------------------||--||----||-|
        item           \    \    \ end
                        \    \ start
                         \ mode

Mit diesem Namen ist das item im Objekt "widget.buffer" abgelegt, aus dem sich die smartVISU-Widgets bedienen. Das Objekt kann man sich auf der Entwicklerkonsole des Browsers ausgeben lassen. 
Der Treiber io.fhem.js zerlegt diesen String anhand der Punkte und schickt die Einzelteile in json-Format an fronthem. Im Beispiel sieht das so aus:

{"cmd": "plot", "items":{
                "item": "hcs.data.OilLevelPlot",
                "mode": "avg",
                "start": "5y 6m",
                "end": "now",                        // 0 wird durch "now" ersetzt
                "count": "100"
                "interval": "OnChange",
                "minzoom": "irgendwas"        // der im Widget unter 'data-zoom' festgelegte Wert
                "updatemode": "additional"
              }
      }

Das heißt die durations für Start und Ende werden unverändert an fronthem übertragen und müssen dort korrekt weiterverarbeitet werden. Wenn bei Euch mit den durations 240i und 4h unterschiedliche Ergebnisse herauskommen, dann liegt die Ursache in fhem/fronthem im Parser, der die durations in das Zeitformat der Datenbank wandelt.

Nach Erhalt der Log-Daten im nächsten Post kann ich den folgenden Absatz nicht mehr voll bestätigen. ich lasse ihn zu Dokuzwecken aber als Zitat stehen. Richtig ist, dass die mit dem Kommando ,,plot" bei fronthem angefragten Daten mit einer vollständigen Series-ID zurück geliefert und so auch eindeutig zugeordnet werden. Es gibt im Treiber jedoch noch eine Routine für Daten, die mit dem Kommando ,,series" zurück kommen. Ob dies aus dem addon-Treiber kommt, oder eine Leiche im Treiber ist, kann ich aktuell nicht beurteilen. Für diese Daten gilt das nachfolgend gesagte. 
ZitatWenn smartVISU von fronthem die angeforderten Daten erhält, fehlen leider die Angaben für mode, start, end und count in der Rückmeldung, d.h. Der Name des Plot-items ist unvollständig. Der Treiber sucht dann in allen geladenen Seiten nach Plot-Widgets, die das item abonniert haben (ohne Berücksichtigung der fehlenden Angaben) und versorgt diese mit den Daten. Da smartVISU seit v2.8 auf jQuery mobile basiert, das die einmal geladenen Seiten im Speicher behält (Multipage Document), kann es hier zu Konflikten kommen, wenn dasselbe item in einem weiteren Plot mit anderen modi, durations oder counts abonniert ist. Wünschenswerte Abhilfe wäre eine Rückübermittlung der fehlenden Daten, so dass der item-Name mit allen Angaben komplett vorliegt. Und natürlich müsste fhem/fronthem die Anfragen mit unterschiedlichen Parametern auch wie separate Anfragen behandeln.

In smarthomeNG haben wir die Funktion ,,seriesCancel" eingeführt, mit der Abonnements von Serien beendet werden können. SmartVISU ruft diese bei jedem Seitenwechsel auf. Das machen wir aus Performancegründen, aber für fhem wäre dies IMHO wichtig, um Klarheit in die abonnierten Plots zu bekommen. Im fhem-Treiber ist die zugehörige Funktion io.stopseries() zwar vorhanden, aber noch leer. Ich wäre bereit, diese zu realisieren, wenn jemand den Part auf der Seite von fhem/fronthem übernimmt.

Gruß
Wolfram

Johann.S

#13
Hallo,

ich habe leider das gleiche Problem!

2 Systeme:

  • fhem auf RPI 3,
    WEB/Datenbankserver Debian Buster Apache2 php8 smartVISU und nextcloud
  • RPI 3 mit fhem Apache2 php7.3 smartvisu
    lesender Datenbankzugriff auf die gleiche Datenbank wie 1

Bei beiden Systemen das gleiche Ergebnis.

smartVISU:
/**
* -----------------------------------------------------------------------------
* @package     smartVISU
* @author      Johann Schierl
* @copyright   2019
* @license     GPL [http://www.gnu.de]
* -----------------------------------------------------------------------------
*/

{% extends "base.html" %}

{% block content %}

{{ plot.period('', 'ws.windspeed.plot', 'raw', '47h', now, 0, 20, 100, 'Windgeschwindigkeit', '#a00', 'spline', ['raw 47h', 'Geschwindigkeit in km/h']) }}

{{ plot.period('', 'ws.windspeed.plot', 'raw', '48h', now, 0, 20, 100, 'Windgeschwindigkeit', '#a00', 'spline', ['raw 48h', 'Geschwindigkeit in km/h']) }}

{% endblock %}


Webausgabe siehe Bild.

Log aus fhem siehe Datei.

Firefox-Konsolenausgabe siehe Datei.

Die Namensänderung des Items im 2. Plot bringt auch keine Besserung.

Wen noch weiter Daten benötigt werden stehe ich gerne zur Verfügung!

Gruß

Johann

PS: musste noch mal schreiben weil zu viele Zeichen!
Raspi 3, Sduino 433MHz und 868MHz beide CC1101, Wetterstation TFA Dostmann 35.1119 (WH1080), intertechno PAR1000/PA1500
NOBILY Standard-Minifunkrolladenmotor PR4 13/147-40 ID-98, Homematic CCU3 (homematic-raspi), HmIP-eTRV-2, HmIP-SWDO, HmIP-STH, HmIP-WTH-2, Eigenbau sonoff für Gartenbewässerung

wvhn

Vielen Dank für die gute Auswertung!

Aus dem fhem Log ist zu erkennen, dass beide Serien angefragt und zunächst aus der Datenbank geliefert werden.  Danach geht aber in der Übermittlung etwas schief:
fronthem erhält die Anweisung für den 47h-Plot
{"log":{"text":"ws send to client{"cmd":"plot", "items":[{"updatemode":"additional", "plotdata":[[1639152698000,1.1], ... ,[1639321759000,8.6]], "item":"ws.windspeed.plot.raw.47h.now.100"}]}", "cmd":"log", "level":4}}
und führt dies anschließend aus. Im smartVISU-Log sieht man, dass die Daten ankommen.
Als nächstes erhält fronthem die Anweisung für den 48h-Plot:
{"log":{"level":4,"cmd":"log","text":"ws send to client{"items":[{"item":"ws.windspeed.plot.raw.48h.now.100","updatemode":"additional", "plotdata":[[1639149147000,1.1], ... , [1639321808000,6.1]]}], "cmd": "plot"}"}}
Auch dies scheint laut fhem Log ausgeführt zu werden, aber in smartVISU kommen die Daten nicht an. Auffällig ist, dass die Inhalte beider Messages gleich sind, aber die Reihenfolge der einzelnen Elemente in der Message unterschiedlich ist. Kann es sein, dass die Daten innerhalb von fronthem noch abgefangen werden - evtl. wegen der veränderten Struktur? Dass smartVISU die Daten nicht erhält, ist ziemlich eindeutig. Erste Aktion des fhem-Treibers beim Empfang von Daten ist deren Ausgabe auf die Konsole, bevor die Daten weiter verarbeitet werden.

Ein weiterer Fehler ist, dass die Anzahl der angefragten Datensätze ignoriert wird. Das passiert offenbar schon bei der Datenbankabfrage. Die Datenbank sendet einfach alle Werte im angefragten Zeitraum.

Auffällig sind noch die folgenden items. Dort fehlt der Modus (z.B. "avg"). Vermutlich bleiben sie deshalb leer.
{"items":[{"item":"ws.windguest.plot..10d.now.100","updatemode":"point","plotdata":[]}],"cmd":"plot"}
{"items":[{"updatemode":"point","plotdata":[],"item":"WZ_th.temp.plot..3m.now.100"}],"cmd":"plot"}
{"cmd":"plot","items":[{"updatemode":"point","plotdata":[],"item":"WZ_th.humidity.plot..3m.now.100"}]}
{"cmd":"plot","items":[{"item":"ws.windguest.plot..10d.now.100","plotdata":[],"updatemode":"point"}]}

Wie werden die Plots für diese items in Deinen Seiten aufgerufen? Normalerweise ersetzt das Plotwidget von smartVISU fehlende mode-Angaben im Aufruf durch "avg".

Gruß
Wolfram

Johann.S

Wenn du die smartVISU Seiten meinst, die stehen im Post ganz am Anfang.
{{ plot.period('', 'ws.windspeed.plot', 'raw', '47h', now, 0, 20, 100, 'Windgeschwindigkeit', '#a00', 'spline', ['raw 47h', 'Geschwindigkeit in km/h']) }}
{{ plot.period('', 'ws.windspeed.plot', 'raw', '48h', now, 0, 20, 100, 'Windgeschwindigkeit', '#a00', 'spline', ['raw 48h', 'Geschwindigkeit in km/h']) }}
Der Modus ist bei beiden gesetzt, einziger unterschied ist die Zeitspanne!
Wie du schon festgestellt hast, werden die Anzahl der Datensätze ignorriert!
Ich habe mit 100,200,1000,10000 und 100000 getestet, macht aber keinen Unterschied.

Noch etwas das vielleicht wichtig ist, ich habe mit 56h und 57h begonnen und
musste dann mit fortlaufender Zeit immer mehr verringern.
Mal so ein Gedanke, kann man die Daten in kleineren Pakten verschicken?
Wenn ich das log richtig lese, werden beide Aufrufe in zwei Pakten verschickt, sollten es beim zweiten nicht eher drei Pakete werden?

Gruß
Johann
Raspi 3, Sduino 433MHz und 868MHz beide CC1101, Wetterstation TFA Dostmann 35.1119 (WH1080), intertechno PAR1000/PA1500
NOBILY Standard-Minifunkrolladenmotor PR4 13/147-40 ID-98, Homematic CCU3 (homematic-raspi), HmIP-eTRV-2, HmIP-SWDO, HmIP-STH, HmIP-WTH-2, Eigenbau sonoff für Gartenbewässerung

wvhn

Ich meine die drei Plots für windgust, WZ_th.temp und WZ_th.humidity, die im smartVISU Log erscheinen. Dort fehlen die Modi und die Datensätze sind leer.

Das Senden in kleinen Paketen ist nicht vorgesehen. Lediglich die nachträglichen Updates kommen in kleinen Einheiten.

Wenn Du schreibst, Du hättest die Zeitspanne immer weiter verkürzen müssen: geht die Dauer 1:1 mit der Zeit? Das würde ja bedeuten, dass es ein Problem mit einer bestimmten Startzeit der Serie gibt.

Johann.S

Ich hatte im Firefox einen anderern Tab mit der Hauptversion offen, anscheinend sind die Daten von dort~~~

Nicht die Startzeit, es sind Echtzeitwinddaten und die verändern sich, bei mir geht ständig der Wind :)
Jetzt Teste ich mit 33h und 34h um den Effekt zu bekommen, in einer Stunde wieder mit anderen!

Währe es möglich das versenden auf Pakete umzustellen? Ich denke es wird hier irgendwo ein Buffer/Cach überlaufen!

Ich habe es jetzt mit nur einem smartVISU-Tab noch einmal durch geführt!
Um eine bessere Übersicht zu haben, habe ich beim zweiten Plot eine neue Variable verwendet.
Die sind aber im fronthem absolut gleich defieniert!

HTML:
/**
* -----------------------------------------------------------------------------
* @package     smartVISU
* @author      Johann Schierl
* @copyright   2019
* @license     GPL [http://www.gnu.de]
* -----------------------------------------------------------------------------
*/

{% extends "base.html" %}

{% block content %}

{{ plot.period('', 'ws.windspeed.plot', 'raw', '33h', now, 0, 20, 100, 'Windgeschwindigkeit', '#a00', 'spline', ['raw 33h', 'Geschwindigkeit in km/h']) }}

{{ plot.period('', 'ws.windkmh.plot', 'raw', '34h', now, 0, 20, 100, 'Windgeschwindigkeit', '#a00', 'spline', ['raw 34h', 'Geschwindigkeit in km/h']) }}

{% endblock %}


Bilder und Log's wieder als Anhang.

Mir ist aber etwas aufgefallen im fhem-log, der Datenbankaufruf erfolgt zweimal mit ws.windspeed.plot.
Müsste es nicht einmal 'ws.windspeed.plot und einmal ws.windkmh.plot sein?



Raspi 3, Sduino 433MHz und 868MHz beide CC1101, Wetterstation TFA Dostmann 35.1119 (WH1080), intertechno PAR1000/PA1500
NOBILY Standard-Minifunkrolladenmotor PR4 13/147-40 ID-98, Homematic CCU3 (homematic-raspi), HmIP-eTRV-2, HmIP-SWDO, HmIP-STH, HmIP-WTH-2, Eigenbau sonoff für Gartenbewässerung

wvhn

#18
Das Verhalten ist das Gleiche wie vorher. smartVISU erhält nur eine der Serien, obwohl innerhalb von fronthem beide Serien korrekt vorbereitet werden. Es fällt auf, dass bei beiden Versuchen die ankommenden Messages unter 64 kB groß sind, während die nicht ankommenden Messages mehr als 64kB haben (um genau zu sein: mehr als 65.536 ASCII-Zeichen). Deine Vermutung, dass ein Puffer überläuft, scheint damit richtig. Das muss der Sendepuffer des Websockets sein.

Anschließend werden die Updates der neu hinzugekommenden Datenpunkte für beide Serien korrekt gesendet.

Der neue Name der Plot-Serie in fronthem wird auch richtig angegeben. Im fhem Log wird der Name des Readings verwendet und der ist natürlich für beide Serien gleich.

Ich denke wir kommen hier ohne die Hilfe von fronthem-Profis nicht weiter. Aktuell gibt es keinen Hinweis, dass das Problem in smartVISU zu suchen ist - was meine Baustelle wäre.

Gruß
Wolfram

Johann.S

Hallo Wolfram,

ich habe gesehen, das du ein Issues bei herrmannj eingetragen hast,
der dürfte die Entwicklung aber anscheinend eingestellt haben!

Die Erweiterung für Plot stammt, so weit ich das sehe, von raman und das ist auch schon einige Zeit her!
Es gibt anscheinend auf GitHub keine Version die der von raman entspricht, vielleicht sollte man ihn per PM kontaktieren!
Währe schade wenn fronthem nicht mehr weiter Entwickelt wird.

Gruß
Johann
Raspi 3, Sduino 433MHz und 868MHz beide CC1101, Wetterstation TFA Dostmann 35.1119 (WH1080), intertechno PAR1000/PA1500
NOBILY Standard-Minifunkrolladenmotor PR4 13/147-40 ID-98, Homematic CCU3 (homematic-raspi), HmIP-eTRV-2, HmIP-SWDO, HmIP-STH, HmIP-WTH-2, Eigenbau sonoff für Gartenbewässerung

herrmannj

Ich hab die Einträge gesehen, vielen Dank. Die Plots kommen tatsächlich nicht von mir aber das hat erstmal nichts zu sagen. Problem ist eher das fronthem ein poc war, man müsste eigentlich einige Sachen grundlegend neu machen. So richtig dringend wars nie, dafür läuft fronthem zu gut. Grundsätzlich habe ich vor das anzugehen. Ich schaue Mal was geht

Johann.S

Hallo,

hat sich vielleicht etwas getan in diesem Fall?
Würde gerne meine Daten, die ich seit 2017 gesammelt habe, Anzeigen und Vergleichen!

@herrmannj: habe in der Zwischenzeit ernsthaft vesucht Perl, die Programmierung von fhem und die Kommunikation zwischen fhem und smartvisu zu lernen! Ist mir echt zu hoch!

Gruß
Johann
Raspi 3, Sduino 433MHz und 868MHz beide CC1101, Wetterstation TFA Dostmann 35.1119 (WH1080), intertechno PAR1000/PA1500
NOBILY Standard-Minifunkrolladenmotor PR4 13/147-40 ID-98, Homematic CCU3 (homematic-raspi), HmIP-eTRV-2, HmIP-SWDO, HmIP-STH, HmIP-WTH-2, Eigenbau sonoff für Gartenbewässerung

wvhn

#22
Hallo Johann,

Mit ramans Hilfe haben wir ein Repository https://github.com/wvhn/fronthem aufgemacht, in dem ich mit meinen ebenfalls nicht vorhandenen Perl-und fronthem-Kenntnissen den bisherigen Stand von fronthem mit allen wichtigen Erweiterungen aus dem Forum zusammen getragen habe (master branch). Raman hat dann ein paar Weiterentwicklungen integriert und u.a. das Problem mit dem Websocket-Puffer gelöst (develop branch). Beides ist rudimentär getestet, aber außer einem Versuch von Funsailor mit den neuen UZSU-Funktionen gab es kein Feedback aus der Community. Und bisher auch keine Unterstützung bei der Analyse / Lösung des UZSU-Problems.

Du könntest Dich also als Tester engagieren und erstmal den master branch testen. Wenn sich damit alles so verhält wie bisher,  kannst Du entweder den ganzen develop branch ziehen und testen, oder Du spielst nur die Änderung im Websocket-Modul ein. Das müsste durch Austausch der 01_fronthem.pm und der fhewbsocket.pm klappen. Man kann dann Port und Puffergröße des Websockets in fronthem parametrieren. Raman hat seine Änderungen ab hier kurz beschrieben: https://forum.fhem.de/index.php/topic,127432.msg1234015.html#msg1234015.

Gruß Wolfram

P.S. wenn Du ein Backup Deiner bisherigen fronthem-Dateien machen und mir mal privat zukommen lassen würdest, dann wäre das für die Analyse von Problemen echt hilfreich.

alkazaa

Moin!

Ich habe die develop Version eingespielt und das neue Attribut maxSendSize ausprobiert. Ich habe es probehalber auf große Werte (128000) und kleine Werte (0) gesetzt, aber keine Auswirkungen festgestellt, d.h. Plot- und sonstige Daten wurden wie gewohnt in Smartvisu angezeigt. Smartvisu- und Browser-Cache waren jeweils gelöscht worden.

-Franz

wvhn

#24
Moin Franz,

Bei Änderung der maxSendSize muss fhem neu gestartet werden. @JohannS hat dies ausführlich getestet und er konnte deutlich größere Plots darstellen, wenn er den Wert erhöhte. Das könntest Du nochmal verifizieren.

Wir haben aber noch ein anderes Problem entdeckt: bei der Auswertung der durations in der Subroutine ,,fronthem_Time" wird nur ein Term mit 2 Ziffern und einer Einheit zugelassen, also z.B. ,,99d" für 99 Tage. 100 Tage gehen dann schon nicht mehr.  ( klar könnte man "15w" schreiben, aber das sind dann halt 105 Tage). SmartVISU sieht eigentlich vor, die duration aus mehreren Termen zusammenzusetzen: ,,1y 3m 10d". Um das in fronthem verfügbar zu machen, müsste man den Ausdruck in der Subroutine an den Leerzeichen splitten, die Terme einzeln auswerten und deren Ergebnisse summieren. Da ich Perl nicht beherrsche, bin ich auf Mithilfe angewiesen. Bis dahin werde ich als Zwischenlösung die Begrenzung auf 4 Ziffern erweitern. Das hat Johann auch schon getestet.
Hierzu muss man das Regex in fronthem_Time und fronthem_Duration ändern in
if ($period =~ /^(\d{1,4})(s|i|h|d|w|m|y)/)
und
if ($duration =~ /^(\d{1,4})(s|i|h|d|w|m|y)/)

Weitere Ergebnisse folgen.

Gruß
Wolfram

P.S.: die Änderung in der 99_fronthemUtils.pm mit Kommentaren zum "to do" habe ich soeben in den develop branch gepusht. Wenn das ausreichend getestet ist, ziehe ich das im Master nach. Rückmeldungen sind willkommen.

alkazaa

#25
Moin Wolfram, danke für die schnelle Rückmeldung.
Neustart hat in der Tat geholfen, ich hatte vorher nur mit "reload xxxx.pm" die entsprechenden Module aktualisiert.

Das (unabhängige) Problem mit '99' und '100' hatte ich auch schon gesehen und wollte es noch fürs Forum dokumentieren, ist aber nun ja nicht mehr nötig, Dank auch dafür.
Ich spiel mal weiter...

Gruß
Franz

Nachtrag
OK, hier das erste Ergebnis meines weiteren Spielens:
Du schriebst:
ZitatSmartVISU sieht eigentlich vor, die duration aus mehreren Termen zusammenzusetzen: ,,1y 3m 10d". Um das in fronthem verfügbar zu machen, müsste man den Ausdruck in der Subroutine an den Leerzeichen splitten, die Terme einzeln auswerten und deren Ergebnisse summieren. Da ich Perl nicht beherrsche, bin ich auf Mithilfe angewiesen.

Ich habe mal versucht, das splitten eines Ausdrucks á la ,,1y 3m 10d" in der der Routine fronthem_Time zu implementieren; es scheint zu funktionieren. Die andere Routine (fronthem_Duration) muss ich erst noch verstehen, dann probier ich das auch mal.

So sieht die Routine jetzt aus, meine 2 Einfügungen habe ich markiert:
sub
fronthem_Time($$)
{
my ($time, $period) = @_;
#### Anfang 1. Einfügung
my @periods = split(' ', $period);
foreach my $period (@periods)
{
#### Ende 1. Einfügung
if ($period =~ /^(\d{1,4})(s|i|h|d|w|m|y)/)
{
my $newTime = 0;
#main::Debug('$2: '.$2);
if ($2 eq "s")
{
$newTime = $1;
}
elsif ($2 eq "i")
{
$newTime = $1 * 60;
}
elsif ($2 eq "h")
{
$newTime = $1 * 3600;
}
elsif ($2 eq "d")
{
$newTime = $1 * 3600 * 24;
}
elsif ($2 eq "w")
{
$newTime = $1 * 3600 * 24 * 7;
}
elsif ($2 eq "m")
{
$newTime = $1 * 3600 * 24 * 30;
}
elsif ($2 eq "y")
{
$newTime = $1 * 3600 * 24 * 365;
}
$time = $time - $newTime;
}
#### Anfang 2. Einfügung
}
#### Ende 2. Einfügung
return $time;
}

alkazaa

Moin!
Ich habe nun auch die Routine fronthem_Duration geändert. Diese Routine berechnet den Mittelungsmodus für den Fall, dass in SV der plot.period Parameter 'mode' ungleich 'raw' ist. Wenn ich das richtig verstanden habe, wurde in der vorhandenen Implementierung von fronthem_Duration dafür nur der SV-Parameter 'tmin' ausgewertet. Für den Fall, dass das [tmin,tmax] Intervall relativ kurz und weiter in der Vergangenheit liegt, ergaben sich damit unsinnig lange Mittelungszeiten.

Die neue Implementierung wertet jetzt  die Intervalllänge tmax-tmin aus. Der Code von fronthem_Duration lautet nun
sub
fronthem_Duration($)     # duration of interval (tmax - tmin) in seconds
{
my ($duration) = @_;
if ($duration > 2*365*24*3600)
{
return 'yearstats';
}
elsif ($duration > 2*30*24*3600)
{
return 'monthsstats';
}
elsif ($duration > 2*7*24*3600)
{
return 'weekstats';
}
elsif ($duration > 2*24*3600)
{
return 'daystats';
}
elsif ($duration > 2*3600)
{
return 'hourstats';
}
return 'timerange';
}


In der eigentlichen Plotroutine Plot() ist dann noch folgende Anpassung wichtig:
if ($mode ne "raw") {
my $duration_seconds = main::fronthem_Time(0, $end) - main::fronthem_Time(0, $start);
$duration = main::99_fronthemUtils.pm($duration_seconds);
}
# if ($mode ne "raw") {
# $duration = main::fronthem_Duration($start);
# }


Die Datei 99_fronthemUtils.pm mit den neuen Routinen fronthem_Time und fronthem_Duration hänge ich hier an (der alte fronthem_Duration code ist zum Vergleich noch drin, aber auskommentiert).

Rückmeldungen vom code-reviewing und Testen gern auch per PN.

Beste Grüße
Franz

wvhn

#27
Moin Franz,

das sieht super aus. Vielen Dank!
Nach einem kurzen "Code Review" habe ich die Änderungen gleich in den develop branch gepusht.

Die Idee, die Intervalllänge als Basis für die Mittelungsmethoden zu nehmen, ist ein großer Schritt in die richtige Richtung. Meines Erachtens könnte man nochmal probieren, ob dies nicht am "Abtastintervall" orientiert werden muss, also an (tmax-tmin)/count. Ich könnte mir vorstellen, dass dies die Genauigkeit der Darstellung erhöht. Habe allerdings keine Ahnung, wie die Datenbankabfrage realisiert ist. 

Gruß
Wolfram

alkazaa

Moin Wolfram,
Du schriebst:
Zitat von: wvhn am 18 November 2022, 18:20:02
Die Idee, die Intervalllänge als Basis für die Mittelungsmethoden zu nehmen, ist ein großer Schritt in die richtige Richtung. Meines Erachtens könnte man nochmal probieren, ob dies nicht am "Abtastintervall" orientiert werden muss, also an (tmax-tmin)/count. Ich könnte mir vorstellen, dass dies die Genauigkeit der Darstellung erhöht. Habe allerdings keine Ahnung, wie die Datenbankabfrage realisiert ist. 
Da wird sich (ohne sehr großen Aufwand) nicht viel machen lassen. Die Datenbankabfrage ist in dem Modul 93_DbLog.pm realisiert (Doku siehe https://fhem.de/commandref_DE.html#DbLog) und liefert mit den Modi hourstats, yearstats etc. Statistikdaten (min, max, avg...) über den jeweiligen Zeitraum, unabhängig von der Zahl der in dem Zeitfenster gesampelten Daten.

Beste Grüße
Franz

wvhn

Moin Franz,

Danke für die Einschätzung. Das kann man tatsächlich nicht so einfach umbiegen. Ich habe auch jetzt erst gesehen, dass der "count"-Parameter aus der Anfrage von smartVISU nicht an fhem weitergegeben wird. Somit ist die Idee erstmal vom Tisch. IMHO macht smarthomeNG das besser, indem es mit dem count-Parameter Daten pro Abtastintervall gruppiert und darauf die Methoden (min, max, avg) anwendet. So kann man die gewünschte  Genauigkeit durch Vorgabe der Anzahl von Punkten selbst wählen.

Gruß
Wolfram

P.S.: in Zeile 100 habe ich noch einen Typo gefunden ("monthsstats" statt "monthstats") und im develop korrigiert.

alkazaa

#30
Moin Wolfram,

ich möchte meine Einschätzung "großer Aufwand" korrigieren.
Sie basierte darauf, dass man für die Funktionalität 'avg, min, max, ...' die bereits in 93_DbLog.pm implementierten Funktionen nutzt.

Man hat aber natürlich in der Plot() Routine in 99_fronthemUtils.pm die raw-Daten zur Verfügung und kann dort das averaging etc. durchführen.

Ich habe das mal für ein averaging über count Messpunkte realisiert.

Dazu habe ich die foreach-Schleife in sub Plot()

foreach my $data (@response) {
my $i = 0;
foreach my $row (@{$data->{data}}) {
if ($mode eq "raw") { # [TIMESTAMP,VALUE]
push(@{$data[0]->{plotdata}[$i]}, main::fronthem_TimeStamp($row->{TIMESTAMP}));
push(@{$data[0]->{plotdata}[$i]}, sprintf("%#.4f", $row->{VALUE}) * 1);
}
elsif ($mode eq "avg") { # [TIMESTAMP,AVG]
push(@{$data[0]->{plotdata}[$i]}, main::fronthem_TimeStamp($row->{TIMESTAMP}));
push(@{$data[0]->{plotdata}[$i]}, $duration eq "timerange" ? sprintf("%#.4f", $row->{VALUE}) * 1 : sprintf("%#.4f", $row->{AVG}) * 1);
}
elsif ($mode eq "sum") { # [TIMESTAMP,SUM]
push(@{$data[0]->{plotdata}[$i]}, main::fronthem_TimeStamp($row->{TIMESTAMP}));
push(@{$data[0]->{plotdata}[$i]}, $duration eq "timerange" ? sprintf("%#.4f", $row->{VALUE}) * 1 : sprintf("%#.4f", $row->{SUM}) * 1);
}
elsif ($mode eq "min") { # [TIMESTAMP,MIN]
push(@{$data[0]->{plotdata}[$i]}, main::fronthem_TimeStamp($row->{TIMESTAMP}));
push(@{$data[0]->{plotdata}[$i]}, $duration eq "timerange" ? sprintf("%#.4f", $row->{VALUE}) * 1 : sprintf("%#.4f", $row->{MIN}) * 1);
}
elsif ($mode eq "max") {  # [TIMESTAMP,MAX]
push(@{$data[0]->{plotdata}[$i]}, main::fronthem_TimeStamp($row->{TIMESTAMP}));
push(@{$data[0]->{plotdata}[$i]}, $duration eq "timerange" ? sprintf("%#.4f", $row->{VALUE}) * 1 : sprintf("%#.4f", $row->{MAX}) * 1);
}
$i++;
}
}

         
ersetzt durch:

foreach my $data (@response) {
my $i = 0;
my $avgval = 0;
my $timestampvalue = 0;
my $avgcount = 0;
my $jmax = scalar(@{$data->{data}});
my $j = 0;
foreach my $row (@{$data->{data}}) {
if ($mode eq "raw") { # [TIMESTAMP,VALUE]
$avgcount++;
$avgval += $row->{VALUE};
$timestampvalue += main::fronthem_TimeStamp($row->{TIMESTAMP});
$j++;
if (($count < 0) && ($avgcount == -$count || $j == $jmax))
{
push(@{$data[0]->{plotdata}[$i]}, $timestampvalue/$avgcount);
push(@{$data[0]->{plotdata}[$i]}, sprintf("%#.4f", $avgval/$avgcount) * 1);
$avgcount = 0;
$avgval = 0;
$timestampvalue = 0;
$i++;
}
elsif ($count >= 0)
{
push(@{$data[0]->{plotdata}[$i]}, main::fronthem_TimeStamp($row->{TIMESTAMP}));
push(@{$data[0]->{plotdata}[$i]}, sprintf("%#.4f", $row->{VALUE}) * 1);
$i++;
}
}
elsif ($mode eq "avg") { # [TIMESTAMP,AVG]
push(@{$data[0]->{plotdata}[$i]}, main::fronthem_TimeStamp($row->{TIMESTAMP}));
push(@{$data[0]->{plotdata}[$i]}, $duration eq "timerange" ? sprintf("%#.4f", $row->{VALUE}) * 1 : sprintf("%#.4f", $row->{AVG}) * 1);
$i++;
}
elsif ($mode eq "sum") { # [TIMESTAMP,SUM]
push(@{$data[0]->{plotdata}[$i]}, main::fronthem_TimeStamp($row->{TIMESTAMP}));
push(@{$data[0]->{plotdata}[$i]}, $duration eq "timerange" ? sprintf("%#.4f", $row->{VALUE}) * 1 : sprintf("%#.4f", $row->{SUM}) * 1);
$i++;
}
elsif ($mode eq "min") { # [TIMESTAMP,MIN]
push(@{$data[0]->{plotdata}[$i]}, main::fronthem_TimeStamp($row->{TIMESTAMP}));
push(@{$data[0]->{plotdata}[$i]}, $duration eq "timerange" ? sprintf("%#.4f", $row->{VALUE}) * 1 : sprintf("%#.4f", $row->{MIN}) * 1);
$i++;
}
elsif ($mode eq "max") {  # [TIMESTAMP,MAX]
push(@{$data[0]->{plotdata}[$i]}, main::fronthem_TimeStamp($row->{TIMESTAMP}));
push(@{$data[0]->{plotdata}[$i]}, $duration eq "timerange" ? sprintf("%#.4f", $row->{VALUE}) * 1 : sprintf("%#.4f", $row->{MAX}) * 1);
$i++;
}
#$i++;
}
main::Debug('imax: '.$i.'; jmax: '.$jmax);
}

         
(Das Debug-statement am Schluß schreibt imax und jmax in die FHEM-Logdatei)

Zum Testen:
Man muss einen negativen (!) count Parameter in SV angeben und den 'raw' Modus nutzen.

Außerdem geht die Mittelung davon aus, dass die Messwerte äquidistant in der Zeit sind, was in FHEM (und zumindest bei mir ist es oft so) auch anders sein kann. So eine gewichtete Mittelwertbildung zu implementieren erfordert dann noch etwas mehr Mühe. Mal schaun, ob's interessiert.

Beste Grüße
Franz

wvhn

Klasse!

Es wäre toll, wenn ein paar Plot-Intensivnutzer dies testen und bewerten könnten, ob die Darstellung - abhängig von der Anzahl angeforderter Punkte - besser wird, als mit der Standard-Statistik. Wenn das bestätigt ist, lohnt sich eine Weiterentwicklung. Zur ganz korrekten Mittelung muss übrigens jeder einzelne Wert im Abtastintervall mit seiner Dauer multipliziert werden und die Summe dieser Werte durch die gesamte Dauer des Abtastintervalls geteilt werden.

Gibt es übrigens eine Möglichkeit, das Abonnement eines Plot-items zu stoppen? Nach den Tests von @JohannS scheinen die "Geister"-Telegramme auf dem Websocket daher zu kommen, dass fhem Update-Events für nicht mehr benötigte Plots triggert und diese in fronthem nicht abgefangen werden. Ich kann von smartVISU aus bei jedem Seitenwechsel einen Befehl z.B. "series_cancel" über den Websocket schicken, der dieselben Parameter wie "series" hat und jedem Plot einzeln abbestellt. Das ist in Verbindung mit smarthomeNG schon standardmäßig umgesetzt.

Gruß
Wolfram

Johann.S

Hallo Wolfram und Franz!

Wegen den "Geister" Telegrammen möchte ich noch was erklähren!

So wie in dem Screenshot sieht bei mir z.B. ein Heizkörper in smartVISU aus.
Die Einstellungen in fronthem sind im nächsten Bild.
Links in jedem Bild sieht man ob das Item aktiv ist oder nicht!
Bei den Plots wird das nicht gemacht!
Sobald sich in einem Plot etwas ändert, egal ob aktiv oder nicht, wird die Information an smartVISU gesendet!
Vielleicht hilft das bei der Suche!

Ich habe mir auch die avg Änderung angesehen!
Meine Testeinstellungen in smartVISU sehen so aus:
{{ plot.period('', 'ws.windspeed.plot', 'raw', '1m', '1h', '', '', -100, 'Windgeschwindigkeit', '#a00', 'spline', ['raw 1m 1h', 'Geschwindigkeit in km/h']) }}
{{ plot.period('', 'ws.windspeed.plot', 'raw', '1m', '1h', '', '', '-100', 'Windgeschwindigkeit', '#a00', 'spline', ['raw 1m 1h', 'Geschwindigkeit in km/h']) }}
{{ plot.period('', 'ws.windspeed.plot', 'raw', '1m', '1h', '', '', '!100', 'Windgeschwindigkeit', '#a00', 'spline', ['raw 1m 1h', 'Geschwindigkeit in km/h']) }}
Da ich mir in der Schreibweise nicht sicher bin!
Getestet habe ich mit 100,200,300 und 1000 wobei sich die Datenlänge (~190.500) nur minimal geändert hat!
Zur Sicherheit habe ich alle Dateien aus dem Developer und die 99_fronthemUtils.pm aus dem Anhang noch mal übertrage und geteste.
Leider kein Unterschied!

Gruß
Johann
Raspi 3, Sduino 433MHz und 868MHz beide CC1101, Wetterstation TFA Dostmann 35.1119 (WH1080), intertechno PAR1000/PA1500
NOBILY Standard-Minifunkrolladenmotor PR4 13/147-40 ID-98, Homematic CCU3 (homematic-raspi), HmIP-eTRV-2, HmIP-SWDO, HmIP-STH, HmIP-WTH-2, Eigenbau sonoff für Gartenbewässerung

alkazaa

#33
Moin Johann,
Dank fürs Testen.

Solch große Datensätze wie Du hatte ich nicht zum Testen. Ich hänge hier mal 4 Bilder an, in denen jeweils ca. 2500 Daten mit 500, 50, 10 Punkten und gar nicht gemittelt wurden.

Der SmartVISU code sowie die ins FHEM-Log geschriebene Debug Information sah dabei so aus:
SV-Definition: {{ plot.period('', 'ESP1_rFplot', 'raw', '5d','1h','','','-500','T-WZ','#060','',['Zeit'],'',[2],[1,0])}}
FHEM-Log-Zeile: 2022.11.22 17:06:20 1: DEBUG>imax: 6; jmax: 2501

SV-Definition: {{ plot.period('', 'ESP1_rFplot', 'raw', '5d','1h','','','-50','T-WZ','#060','',['Zeit'],'',[2],[1,0])}}
FHEM-Log-Zeile: 2022.11.22 17:11:35 1: DEBUG>imax: 51; jmax: 2501

SV-Definition: {{ plot.period('', 'ESP1_rFplot', 'raw', '5d','1h','','','-10','T-WZ','#060','',['Zeit'],'',[2],[1,0])}}
FHEM-Log-Zeile: 2022.11.22 17:12:47 1: DEBUG>imax: 250; jmax: 2500

SV-Definition: {{ plot.period('', 'ESP1_rFplot', 'raw', '5d','1h','','','10','T-WZ','#060','',['Zeit'],'',[2],[1,0])}}
FHEM-Log-Zeile: 2022.11.22 17:14:12 1: DEBUG>imax: 2501; jmax: 2501


Was standen denn bei Dir in der Log-Datei für Werte von imax und jmax?

Die jeweils erhaltenen SmartVISU Plots sind in den anghängten Dateien.
Gruß
Franz

alkazaa


Ich habe das averaging jetzt auch mal mit einem größeren Datensatz getestet, und es läuft bei mir im Prinzip korrekt.
'Im Prinzip' heißt dabei, dass der große Datensatz (ca. 320000 Daten) korrekt dargestellt und gemittelt wird. Allerdings dauert das ganze etwa 85 sec, und in meiner FHEM-Logdatei tauchen dabei merkwürdige Fehlermeldungen von verschiedenen anderen devices auf (der MQTT2-Server meckert besonders häufig). Ich vermute, dass die Plot() Routine in 99_fronthemUtils.pm im blocking-mode läuft und damit das FHEM-System kräftig durcheinander bringt.

Die benutzte Hardware: aktuelles FHEM auf Raspi 3B+, MariaDB Server auf einer Synology DS216j, beide im LAN verbunden. SmartVISU 3.2.0

Ich hatte übrigens die averaging Routine auf gewichtete Mittelwertbildung erweitert, war gar nicht so schwer. (Siehe Datei im Anhang.)

Mein Zwischenfazit wäre: das averaging in 99_fronthemUtils.pm zu machen ist nur für kürzere Datensätze sinnvoll. Wo genau die Grenze zwischen kürzer und länger liegt, hängt vielleicht von der verwendeten Hardware ab.

Wünschenswert wäre es, die statistischen Auswertungen (avg, min, max etc.) wie bisher vom db-Server machen zu lassen, aber mit besserer Kontrolle des Auswerteintervalls.

Und den Trick wie das geht verrate ich vielleicht demnächst  ;) 
Muss noch bisschen testen...

-Franz

wvhn

Hallo Franz,

das hört sich ja vielversprechend an. Wichtig wäre mal ein Vergleich der Ergebnisse mit der heutigen Standard-Abfrage und der neuen Mittelung. Lohnt sich der Aufwand?

Insbesondere die Idee, die Auswertung gleich in der Datenbank richtig zu machen, finde ich gut. Dazu zwei Hinweise:

"count" ist in smartVISU die Anzahl der Punkte im Plot (je höher count, desto feiner die Auflösung). In Deiner ersten Mittelungsmethode hast Du count als Anzahl der Punkte interpretiert, über die gemittelt wird (je höher count, desto gröber die Auflösung). Ich plädiere dafür, den Standard aus smartVISU zu verwenden, wie dies andere Backends auch machen.

Ein gutes Beispiel für die Datenbankabfrage ist das Python-Skript für das database-Plugin von smarthomeNG: https://github.com/smarthomeNG/plugins/blob/master/database/__init__.py
Ab Zeile 813 wird die Abfrage zusammengebaut. Dabei werden die Daten jeweils in Gruppen der Breite step = (tmax-tmin)/count gruppiert:
GROUP BY ROUND(time / :step)
und dann entsprechend dem "mode"-Parameter der Serie weiter verarbeitet. Die Selektionskriterien für die durations werden ab Zeile 896 zusammengestellt.

Gruß
Wolfram

alkazaa


Hallo Wolfram,

Zitat
das hört sich ja vielversprechend an. Wichtig wäre mal ein Vergleich der Ergebnisse mit der heutigen Standard-Abfrage und der neuen Mittelung. Lohnt sich der Aufwand?
Vermutlich lohnt sich der Aufwand nicht, da die Zahl der SV-Plot-FHEM user im niedrigen einstelligen Bereich liegen dürfte...
Andrerseits: als nicht mehr berufstätiger Mensch gehe ich das ganze eher sportlich an, als Zeitvertreib ähnlich wie Kreuzworträtsel lösen. Von Perl, SQL etc. habe ich close-to-zero Ahnung, aber das machts gerade spannend.

Ich möchte dennoch jetzt gern mal eine Zusammenfassung dessen schreiben, was ich hier gelernt habe. Und das Thema damit zumindest für mich abschließen, da ich für das was evtl. noch zu tun wäre nicht mehr beitragen kann.

Zunächst einmal der Vergleich dreier Testszenarien. Ich habe einen drei Monate langen Datensatz mit ca. 47000 Daten dargestellt, und zwar einmal im 'raw' Modus ohne jede Mittelung, dann mit 'avg' und nicht-gewichteter Mittelung über jeweils 1 Woche, und zum Schluß eine gewichtete Mittelung mit dem von mir implementierten Algorithmus (so dass aus den 30 Monaten 13 Mittelwerte entstanden). Zum Messen des Timings habe ich mit einigen Debug-Befehlen Informationen in die FHEM-Logdatei geschrieben.

Szenario 1 (46785 raw Daten):

{{ plot.period('', ['E_Verbrauch'], ['raw'], '0w 3m','','','',['14'],['A'],['#060','#d00','#880'],'',['Zeit', '°C', '%'],'',[2,1,1],[1,0])}}

2022.11.25 11:29:02 1: DEBUG>QUERY
2022.11.25 11:29:02 1: DEBUG>sql: SELECT TIMESTAMP, VALUE FROM history WHERE READING = 'power' AND DEVICE = 'E_Zaehler' AND TIMESTAMP Between '2022-08-27 12:29:02' AND '2022-11-25 11:29:02' ORDER BY TIMESTAMP;
2022.11.25 11:29:08 1: DEBUG>START averagig  duration: timerange
2022.11.25 11:29:08 1: DEBUG>imax: 46785
2022.11.25 11:29:14 1: DEBUG>DONE

Die erste Zeile ist die SV Definiton, dann kommt markiert mit 'QUERY' der Start der SQL Abfrage, dann mit 'START averaging ...' das Übertragen der Daten zu SmartVISU

Szenario 2 (46785 raw Daten, schon mit der SQL-Abfrage wochenweise gemittelt):

{{ plot.period('', ['E_Verbrauch'], ['avg'], '0w 3m','','','',['14'],['A'],['#060','#d00','#880'],'',['Zeit', '°C', '%'],'',[2,1,1],[1,0])}}

2022.11.25 11:29:44 1: DEBUG>QUERY
2022.11.25 11:29:44 1: DEBUG>sql: SELECT date_format(timestamp, '%Y-%m-%d 00:00:00') AS TIMESTAMP, SUM(CAST(VALUE AS DECIMAL(12,4))) AS SUM, AVG(CAST(VALUE AS DECIMAL(12,4))) AS AVG, MIN(CAST(VALUE AS DECIMAL(12,4))) AS MIN, MAX(CAST(VALUE AS DECIMAL(12,4))) AS MAX, COUNT(VALUE) AS COUNT FROM history WHERE READING = 'power' AND DEVICE = 'E_Zaehler' AND TIMESTAMP Between '2022-08-27 12:29:44' AND '2022-11-25 11:29:44' GROUP BY date_format(timestamp, '%Y-%u 00:00:00') ORDER BY 1;
2022.11.25 11:29:48 1: DEBUG>START averagig  duration: weekstats
2022.11.25 11:29:48 1: DEBUG>imax: 14 noofavgs: 0
2022.11.25 11:29:48 1: DEBUG>DONE


Szenario 3 (46785 raw Daten, in 99_fronthemUtils.pm gewichtet gemittelt zu 13 Datenpunkten):

{{ plot.period('', ['E_Verbrauch'], ['raw'], '0w 3m','','','',['-14'],['A'],['#060','#d00','#880'],'',['Zeit', '°C', '%'],'',[2,1,1],[1,0])}}

2022.11.25 11:30:50 1: DEBUG>QUERY
2022.11.25 11:30:50 1: DEBUG>sql: SELECT TIMESTAMP, VALUE FROM history WHERE READING = 'power' AND DEVICE = 'E_Zaehler' AND TIMESTAMP Between '2022-08-27 12:30:50' AND '2022-11-25 11:30:50' ORDER BY TIMESTAMP;
2022.11.25 11:30:55 1: DEBUG>START averagig  duration: timerange
2022.11.25 11:30:55 1: DEBUG>imax: 46784 noofavgs: 3341
2022.11.25 11:31:01 1: DEBUG>number of data: 46784; number of averaged data: 13
2022.11.25 11:31:01 1: DEBUG>DONE


Man sieht, dass die SQL Abfrage in allen 3 Fällen ca. 5 sec braucht. In Szenario 1 (wo gar nicht gemittelt wird) die sub Plot() in 99_fronthemUtils.pm dann nochmal ca. 6 sec! ABER: der SQL-Vorgang in 93_DbLog.pm wird non-blocking ausgeführt (und stört den FHEM Prozess nicht), der Vorgang in der sub Plot() dagegen ist blocking. Und das Umstellen auf non-blocking überfordert mich klar.

In Szenario 2 wieder die ca. 5 sec für SQL, aber dann quasi instantan die bereits auf 14 Punkte eingedampften Daten nach SV.

In Szenario 3 wieder 5 sec die SQL, und 6 sec in sub Plot().

Im Anhang sind die Ergebnisse gezeigt.

Zitat
"count" ist in smartVISU die Anzahl der Punkte im Plot (je höher count, desto feiner die Auflösung). In Deiner ersten Mittelungsmethode hast Du count als Anzahl der Punkte interpretiert, über die gemittelt wird (je höher count, desto gröber die Auflösung).
Das habe ich korrigiert.

ZitatEin gutes Beispiel für die Datenbankabfrage ist das Python-Skript für das database-Plugin von smarthomeNG: https://github.com/smarthomeNG/plugins/blob/master/database/__init__.py
Schau ich mir bei Gelegenheit an (Python kann ich auch nicht...)

Und hier zum Trick, wie man im SV plot.period statement angibt, welche Mittelungsperiode anzuwenden ist: Da in 99_fronthemUtils.pn für die Festlegung des Mittelungsintervalls der Anfang des SV-Parameters 'start' ausgewertet wird, und da mit einer der kürzlichen Änderungen auch strings wie '2w 3d 4h' als start-Parameter richtig gelesen werden, kann man z.B. mit '0d 2w' eine Tageweise Mittelung erreichen, oder mit '0m 2y' die Mittelwerte der Monate im 2 Jahreszeitraum berechnen lassen, oder wie im obigen Beispiel mit '0w 3m' die wochenweise-Mittelung für den 3-Monatszeitraum.

So, das war's erstmal von meiner Seite.

(Die angehängte 99_fronthemUtils.pm enthält noch die Debug statements. Das Debug in 93_DbLog.pm müsste man selber einfügen (Zeile 6599)

Beste Grüße
Franz




wvhn

#37
Hallo Franz,

das hast Du super dokumentiert. Vielen Dank.

Die bisherige Version der fronthem Plots hat nur einen Term für die durations zugelassen. Die Filterung konnte man über diesen Term mit beeinflussen. Bei einer duration von ,,3m" bekam man nur 3 Werte. Gab man für die gleiche Zeitspanne ,,13w" ein, waren es 13 Werte und ,,90d" ergab 90 Werte für den gleichen Zeitraum. Bei der Erweiterung auf mehrere zulässige Terme haben wir das übersehen. Die Idee, die Filterung nur von der Gesamtdauer der Zeitspanne abhängig zu machen, war nicht so gut. Das hast Du ja wieder rückgängig gemacht, indem Du die Subroutine fronthem_duration wieder auf den alten Stand geändert hast.

Aus Kompatibilitätsgründen sollten wir das so lassen und den ,,Trick" gut dokumentieren. D.h. der Filter, den man verwenden will, muss immer im ersten Term stehen. Also z.B. ,,0h 3w", wenn man pro Stunde einen Wert bekommen will. ,,2184h" geht alternativ auch, nachdem wir die Beschränkung auf 2 Ziffern aufgehoben haben. Zusätzlich könnte man den Parameter count auswerten, um den Filter auszuwählen. Das schaue ich mir nochmal an.

Die Filter sind übrigens so realisiert, dass die Datumseinträge bei der SQL-Abfrage an entsprechender Stelle abgeschnitten und mit Nullen aufgefüllt werden. Dadurch entstehen z.B. beim Filter ,,daystats" innerhalb eines Tages viele Werte mit Zeitstempel ,,<Tagesdatum> 00:00:00", über die dann gemittelt wird. Das Ergebnis ist dann jeweils ein Punkt am Tagesdatum um 0:00 Uhr. Man muss sich also bewusst sein, dass bei Verwendung von avg, min und max eine duration, die feiner auflöst als der eingestellte Filter, keine Auswirkungen hat. Sprich: Terme mit Werten unter "120i" oder "7200s" machen nur im raw-Modus Sinn, da der feinste Filter die Werte auf Stundenbasis zusammenfasst.

Gruß
Wolfram

wvhn

Die Rückänderung auf die alte Version von "fronthem_duration" ist jetzt im develop branch. Auf mittlere Sicht werde ich dies in den Master übernehmen, wenn hier noch ein paar Teseter grünes Licht geben.
Dabei ist zu beachten, dass die Auswahl der Statistikfunktion aus Gründen der Rückwärtskompatibilität etwas hakelig ist. Mann kann zwar im ersten Term mit z.B. "0d" die Tagesstatistik (pro Tag ein Wert) auswählen, "1d" führt aber wie bisher zur Auswahl der Stundenstatistik (24 Werte pro Tag).  "0d 2y 6m" ergibt also über die letzten 2 1/2 Jahre pro Tag einen Wert, "1d 2y 6m" erhöht den Zeitraum um einen Tag und stellt die Statistik auf Stundenwerte um.

Wer die lokale Mittelung aus den raw-Daten testen will, muss sich weiter die letzte Version von alkazaa aus seinem letzten Post laden.

Gruß
Wolfram

Johann.S

#39
Hallo Franz und Wolfram!

Ich bin mal davon ausgegangen, dass die zwei Plots
{{ plot.period('', 'ws.windspeed.plot', 'avg', '0d 1y', '', '', '', '14', 'Windgeschwindigkeit', '#a00', 'spline', ['avg 0d 1y / 14', 'Geschwindigkeit in km/h']) }}
{{ plot.period('', 'ws.windspeed.plot', 'raw', '0d 1y', '', '', '', '-14', 'Windgeschwindigkeit', '#a00', 'spline', ['raw 0d 1y / -14', 'Geschwindigkeit in km/h']) }} abgesehen von der Geschwindigkeit, das gleiche Ergebnis sein sollten!

Bei mir sehen sie aus wie im Screenshot 1!

Mache/Verstehe ich was falsch?

Gruß
Johann

Nachtrag: Developerversion und 99_fronthemUtils.pm von Franz!
Raspi 3, Sduino 433MHz und 868MHz beide CC1101, Wetterstation TFA Dostmann 35.1119 (WH1080), intertechno PAR1000/PA1500
NOBILY Standard-Minifunkrolladenmotor PR4 13/147-40 ID-98, Homematic CCU3 (homematic-raspi), HmIP-eTRV-2, HmIP-SWDO, HmIP-STH, HmIP-WTH-2, Eigenbau sonoff für Gartenbewässerung

alkazaa

#40
Hallo Johann,
Danke fürs Weitertesten!

In meiner letzten fronthemUtils Version hatte ich (nach Hinweis von Wolfram) den SV-Parameter count so interpretiert, wie es in der SV Doku beschrieben ist, als Zahl der Daten pro Plot. (Vorher hatte ich es als Zahl der Daten pro Mittelung genommen).
Die 14 Werte scheinen also zu passen (lass den Spline weg, dann müsste man es auszählen können). Setz mal den count auf -365.

Im ersten Plot sind es auf den ersten Blick 365 Punkte, wie es dem '0d' entspricht.

Weitere Details:
ich bin beim Mitteln davon ausgegangen, dass in den Originaldaten zu den Zeitpunkten t0, t1, t2, ... die Werte y0, y1, y2, ... gemessen wurden. Für den Beispielfall einer Mittelung über nur 2 Punkte habe ich dann <y0> = (y0*(t1-t0) + y1*(t2-t1))(t2-t0) gerechnet.

Und diesen Mittelwert habe ich dann dem Zeitpunkt t0 zugeordnet. Dahinter stand die Überlegung, dass man mangels besseren Wissens davon ausgehen müsste, dass während des ganzen Zeitraums t0 bis t1 der Wert y0 vorliegt usw. Und somit wäre es konsistent, den Wert <y0> dem Zeitpunkt t0 zuzuordnen, und <y1> dem Zeitpunkt t2 usw.

Man könnte <y0> auch dem Zeitpunkt (t2-t0)/2 zuordnen, aber ich fand meine Wahl konsistenter. Was am sinnvollsten ist, müsste man diskutieren.

Jedenfalls  führt dieses Detail dazu, dass die 14 Werte des 2. Plots schon Mitte September enden.


Gruss
Franz

Johann.S

Hallo Franz,

ok, ich hatte es so vertstanden, dass er den Mittelwert aus 14 Punkten nimmt!
{{ plot.period('', 'ws.windspeed.plot', 'avg', '0d 1y', '', '', '', '365', 'Windgeschwindigkeit', '#a00', '', ['avg 0d 1y / 365', 'Geschwindigkeit in km/h']) }}
{{ plot.period('', 'ws.windspeed.plot', 'raw', '0d 1y', '', '', '', '-365', 'Windgeschwindigkeit', '#a00', '', ['raw 0d 1y / -365', 'Geschwindigkeit in km/h']) }}

Sieht gleich besser aus!
Der Zeitunterschied ist aber gewaltig!
Ich werde noch einige Test machen, Hut ab vor der Leistung!

Kann man deine Auswertung irgendwie aktivieren, ich find die Super!

Gruß
Johann
Raspi 3, Sduino 433MHz und 868MHz beide CC1101, Wetterstation TFA Dostmann 35.1119 (WH1080), intertechno PAR1000/PA1500
NOBILY Standard-Minifunkrolladenmotor PR4 13/147-40 ID-98, Homematic CCU3 (homematic-raspi), HmIP-eTRV-2, HmIP-SWDO, HmIP-STH, HmIP-WTH-2, Eigenbau sonoff für Gartenbewässerung

alkazaa

#42
Hallo Johann,
Du schriebst:
Zitat von: Johann.S am 28 November 2022, 18:26:55
Kann man deine Auswertung irgendwie aktivieren, ich find die Super!

Ich bin ncht sicher, was Du mit 'aktivieren' meinst. Aber ich würde von meiner Art des Mittelns abraten, und zwar wegen der Blockierung des FHEM Prozesses. Wobei: es ist nicht der Mittelungsalgorithmus, der die Zeitprobleme macht, die treten auch beim 'raw' ohne einen negativen count-Parameter auf. Es ist einfach die große Zahl der raw Daten die an SV weitergereiht werden.

Wie ich schon in einem der vorigen Beiträge sagte, ist die beste Mittelung die, die bereits beim SQL-Query vom DB-Server erledigt wird. Und da ist das benutzte FHEM Modul 93_DbLog.pm (ein ganz tolles Modul, nebenbei) für den Einsatz im fronthemUtils vielleicht nicht mal das beste. Es gibt nämlich noch das Modul DbRep (vom gleichen Entwickler glaub ich), dass laut Doku (https://fhem.de/commandref_DE.html#DbRepattr ) noch mehr Möglichkeiten bietet, z.B. auch gemittelte Averages.
Aber wie ich auch schon sagte: ich bin mangels Kenntnissen da raus, das in fronthemUtils einzubauen.

-Franz

Johann.S

Hallo Franz,

ja schon aber bei deiner Routine kann man auch auf Stunden oder 4 Werte pro Tag usw... einstellen.
Bei DbLog und DbRep geht das nur auf Tag oder Woche!
Den Unterschied siehst du im Screenshot!
So in der Art möchte ich das hinbekommen und ein Wert pro Tag ist einfach zuwenig!

Ich versuche gerade einen SQL-Query auf zu bauen der mehr kann!
Wenn ich fertig bin versuche ich in fhem beizubringen so das er mit DbLog oder DbRep funtkioniert!
Wobei DbLog währe mir lieber, den das muss auf jeden Fall vorhanden sein!

Ich melde mich wenn ich mehr weiss oder bei den Tests was auftritt!

-Johann


Raspi 3, Sduino 433MHz und 868MHz beide CC1101, Wetterstation TFA Dostmann 35.1119 (WH1080), intertechno PAR1000/PA1500
NOBILY Standard-Minifunkrolladenmotor PR4 13/147-40 ID-98, Homematic CCU3 (homematic-raspi), HmIP-eTRV-2, HmIP-SWDO, HmIP-STH, HmIP-WTH-2, Eigenbau sonoff für Gartenbewässerung

alkazaa

Hallo Johann,

ich hab's nicht ausprobiert, aber bei DbRep kann man anscheinend auch 'minute' auswählen.

Und ne alternative Idee: die Daten schon vor dem Speichern in die DB reduzieren (d.h. in FHEM)?

-Franz

alkazaa

#45
So, mein Spieltrieb hat mir nun doch keine Ruhe gelassen und ich habe meine in diesem Beitrag vorgestellte Berechnung gewichteter Mittelwerte als SQL Query formuliert, sodass die Berechnung nun vom SQL-Server gemacht wird.

Beschrieben habe ich das Query in einem anderen Thread.

Für eine Nutzung in 99_fronthemUtils.pm kann man allerdings nicht mehr den fhem-Befehl "get ... Webchart" nutzen, sondern man braucht zusätzlich zum DbLog-device auch ein DbRep-device in fhem: das stellt den Befehl ' get ... sqlCmdBlocking' zur Verfügung, mit dem beliebige SQL-Queries ausgeführt werden können. (Anmerkung: auch das 'get ... Webchart' arbeitet wohl blockierend, im Gegensatz zu dem was ich in einem vorigen Beitrag sagte).

Um meine angehängte 99_fronthemUtils.pm zu testen, braucht man ein DbRep-device, das mit dem DbLog-device verknüpft ist. Wenn das DbLog device z.B. mylogdb heißt, wird dafür in 99_fronthemUtils ein DbRep erzeugt mit dem Befehl "defmod -silent mylogdbReport DbRep mylogdb".

Zum Aktivieren der Mittelung in SV im Modus 'avg' einen negativen Wert für 'count' angeben.

Gruß,
Franz

Johann.S

#46
Hallo Franz,

chapeau!
Testsystem RaspBerry pi mit aktuellem fhem, fronthem aus dem Deloper, 99_fronthemUtils.pm aus dem Anhang und kein maxSendeSize!
Ich komme bei 1 Jahr auf 3.074 Datenpunkte also 8,42 Punkte pro Tag!
Die Geschwindigkeit ist sensationel.

Du und Wolfram habt mich vom avg überzeugt!
Ich habe mein Testsystem schon komplett umgebaut und kann bisher keine Fehler feststellen.
Daten zu vergleichen ist jetzt ein Kinderspiel.
IMHO kann man die Änderungen in den Master übernehmen!
Edit: mehrere Werte in einer Tabelle ärgert noch! Melde mich!

Gruß
Johann
Raspi 3, Sduino 433MHz und 868MHz beide CC1101, Wetterstation TFA Dostmann 35.1119 (WH1080), intertechno PAR1000/PA1500
NOBILY Standard-Minifunkrolladenmotor PR4 13/147-40 ID-98, Homematic CCU3 (homematic-raspi), HmIP-eTRV-2, HmIP-SWDO, HmIP-STH, HmIP-WTH-2, Eigenbau sonoff für Gartenbewässerung

Johann.S

Hallo Franz,

ich konnte nur einen "Fehler" finden!
Bei der Berechnung für 1 Jahr (1y) fehlen 9 Tage bei 2 Jahren (2y) 18 Tage usw.,
bei Eingabe der Tage funktioniert es (siehe Anhang)!
Ansonsten keine Auffälligkeiten noch mal chapeau!

Ich habe bis 4 Werte in einem Chart getestet und wie gesagt es funktioniert!
Allso ich denke der Master-Brunch und fhem ruft!

Was mir jetzt doch noch einfällt, ich habe tmax nicht getestet, wird nachgereicht!

Gruß
Johann
Raspi 3, Sduino 433MHz und 868MHz beide CC1101, Wetterstation TFA Dostmann 35.1119 (WH1080), intertechno PAR1000/PA1500
NOBILY Standard-Minifunkrolladenmotor PR4 13/147-40 ID-98, Homematic CCU3 (homematic-raspi), HmIP-eTRV-2, HmIP-SWDO, HmIP-STH, HmIP-WTH-2, Eigenbau sonoff für Gartenbewässerung

alkazaa

#48
Hallo Johann,

Zitat von: Johann.S am 13 Dezember 2022, 11:53:23
Bei der Berechnung für 1 Jahr (1y) fehlen 9 Tage bei 2 Jahren (2y) 18 Tage usw.,
Wenn man eine Anzahl N von Daten im vollen Datensatz hat und diesen in count Intervalle zerlegt, kämen (bei einigermaßen gleich über der Zeit verteilten Messpunkten) N/count Daten in ein Teilintervall. Der gemittelte Werte für ein Teilintervall wird (habe ich irgendwo vorher erwähnt) dem Anfangszeitpunkt des Teilintervalls zugeordnet.

Das führt dazu, dass beim Plot N/count Daten zu fehlen scheinen. Wenn N doppelt so groß wird (2 Jahre vs. 1 Jahr), aber count gleich bleibt, scheinen doppelt so viele zu fehlen. Geht man von den konkreten Zahlen in Deinem letzten Beitrag aus, müsste Dein Originaldatensatz etwa (9 Tage) * (8,42 Punkte/Tag) * 3074 = ca. 233000 Messpunkte haben. Passt das in etwa?

Wenn man die Zuordnung des gemittelten Wertes nicht zum Zeitanfang des Intervalls macht, sondern zur Intervallmitte, würden am Anfang 9/2 Tage 'fehlen' und am Ende ebenfalls. Und bei 2 Jahren das Doppelte.

Zitat von: Johann.S am 13 Dezember 2022, 11:53:23
bei Eingabe der Tage funktioniert es (siehe Anhang)!
Ich verstehe nicht, was Du mit 'Eingabe der Tage' meinst.

Könntest Du mal die plot.period Definition aus SV posten? Und die Zahl der Originaldaten nennen?

Besten Gruß und Dank fürs Testen

Franz


Ach ja, noch etwas:
Wenn Daten gemittelt werden wie Temperatur, Luftfeuchte etc., die typischerweise tagesperiodisch sind, sollte immer über Tage oder Vielfache davon gemittelt werden, sonst erhält man irreführende Datendarstellungen. Die ursprüngliche averaging Methode (die auf einem Aufruf von 'get ... webchart...' in 99-fronthemUtils beruht) leistet aus gutem Grund genau das. Sie macht halt kein gewichtetes Mitteln, was bei zeitlich ungleich verteilten Werten auch wieder irreführend sein kann. Ein gewichtetes Mitteln mit stunden-, tage-, oder wochenweise begenzten Intervallen wäre am besten.
Nachdem ich mich nun interessehalber in diese ganze Thematik eingewühlt habe, sehe ich durchaus Möglichkeiten, das umzusetzen. Mal sehen...

Johann.S

Hallo Franz,

öhm, ich kanns nicht mehr nachstellen (schäm).
Jetzt funkt es so wie es soll!

{{ plot.period('', 'ws.windspeed.plot', 'avg', '1y', '', '', '', '-1460', 'Windgeschwindigkeit', '#a00', '', ['avg 1y / -1460', 'Geschwindigkeit in km/h'], 'advanced', '', '', '', '', '', { rangeSelector: {selected: '2'}}) }}
{{ plot.period('', 'ws.windspeed.plot', 'avg', '365d', '', '', '', '-1460', 'Windgeschwindigkeit', '#a00', '', ['avg 365d / -1460', 'Geschwindigkeit in km/h'], 'advanced', '', '', '', '', '', { rangeSelector: {selected: '2'}}) }}

Der einzige Unterschied bei den Kurven war '1y' und '365d'!
Wie schon gesagt, jetzt sind beide gleich!
Das beim Mitteln mal ein Tag weniger rauskommt war mir schon klar aber tmin mit '1y' und '365d' müssen die gleichen Kurven haben, was sie ja auch tun!

tmax habe ich auch schon getestet und konnte nichts negatives entdecken!
Schön währe halt, wenn man auch ein fixes Datum einstellen könnte und/oder
zweimal die gleiche Kurve mit z.B. 1 Jahr Unterschied!
z.B.
{{ plot.period('', ['ws.windspeed.plot','ws.windspeed.plot'], 'avg', ['1y','1y'], ['', '1y'], '', '', ['-365','-365'], 'Windgeschwindigkeit', '#a00', '', ['avg tmin 1y,1y/ tmax "",1y / -1460', 'Geschwindigkeit in km/h'], ['#a00', '#00a'], ['areaspline', 'spline']) }}

Wobei ich in der Doku gerade gelesen habe, das auch Zeitwerte möglich sind, halt nur im internen Format!
Werde ich mir auch noch ansehen!

Bezüglich der Datenanzahl sehe ich nur minimale Unterschiede, 2.841 und 2.842 Werte, was meines Erachtens vernachlässigbar ist!

Bin weiter am Testen und Berichten.
Gruß

Johann

Raspi 3, Sduino 433MHz und 868MHz beide CC1101, Wetterstation TFA Dostmann 35.1119 (WH1080), intertechno PAR1000/PA1500
NOBILY Standard-Minifunkrolladenmotor PR4 13/147-40 ID-98, Homematic CCU3 (homematic-raspi), HmIP-eTRV-2, HmIP-SWDO, HmIP-STH, HmIP-WTH-2, Eigenbau sonoff für Gartenbewässerung

alkazaa

#50
Ich habe jetzt das zeit-gewichtete Mitteln auch für die Strategie implementiert, bei der die Gesamtzeit eines Plots nicht einfach in 'count' Intervalle zerteilt wird, sondern jeweils über Stunden (oder Tage, Wochen, ...)  gewichtet gemittelt wird.
Im angehängten Bild habe ich für einen 18 h Zeitraum die Ergebnisse des gewichteten Mittelns (18 Intervalle), eines gewichteten Mittelns über Stunden-Intervalle und eines nicht-gewichteten Mittelns über Stunden-Intervalle verglichen. Man beachtet, dass beim Stunden-Mitteln die Intervall-Grenzen immer auf vollen Stunden liegen (bei Tagen auf Tagen, usw.)


Im Moment habe ich nur die stundenweise gewichtete Mittelung ins 99_fronthemUtils eingebaut. Die anderen Zeitintervalle einzubauen ist jetzt nur noch Schreibarbeit.

Wichtig für die Nutzung: wie wählt man im SV-code die Mittelungsmethode aus?
Mein Vorschlag:

       
  • Beim Modus 'raw' wird unabhängig vom Parameter 'count' alles dargestellt.
  • Beim Modus 'avg' bestimmt der 1. Term der 'tmin' Angabe das Mittelungs-Intervall, z.B. '0h' für Stunden.
    Mit einem Parameter 'count' = 1 wird dabei die alte, ungewichtete Mittelung benutzt.
  • Bei 'avg' mit 'count' > 1 wird gewichtet gemittelt, die Intervalllänge wird über den 1. tmin-Term festgelegt
  • Bei 'avg' mit 'count' < 0 wird gewichtet gemittelt, wobei die Gesamtlänge in |count| Intervalle geteilt wird
Wäre das so akzeptabel? Andere Vorschläge?
Und noch eine Frage an Wolfram: wie gibt man in SV feste absolute Zeiten für tmin,tmax an? Eine Zahl wie z.B. 1629109298731 aus der Doku ist ja nicht sehr nutzerfreundlich?


-Franz

Im Vergleichsplot sind dargestellt:

       
  • Rohdaten (raw) eines 18-h Intervalls und gewichtete Mittelung in 18 Teilen (w-avg 18)
  • Rohdaten und stundenweise gewichtetes (w-avg h) und ungewichtetes Mittel (avg h)
  • Die drei Mittelungen in einem Plot
Zwischen 5:00 und 6:00 erkennt man z.B. einen signifikanten Unterschied zwischen gewichtet und ungewichtet.

wvhn

Super Arbeit!

Das Vorgeben fester Zeitpunkte geht derzeit tatsächlich nur über die Zeitstempel. Das ist sicher nicht optimal, aber aus meiner Sicht zumutbar. Da die Zeiten ja fest in die Visu-Seiten eingetragen werden müssen, wird man sie sicherlich nicht so häufig ändern. Dann ist der Mehraufwand, auf einer der einschlägigen Websites ein Datum in einen Unix-Zeitstempel (in Millisekunden) umzurechnen, überschaubar.

Gruß
Wolfram

Johann.S

@Woflram: Bei einem Auswertungsfenster wird sehr wohl unterschiedliches Datum eingegeben.
                  Der Unterschied ist nur, dass jetzt jeder eine zusätzliche Routine erstellen muss!
                  Wenn man hingegen Date-Time Werte angibt wird das im Plot erledigt!
                  Für Laien (wie mich) wurde ich zweiteres bevorzugen ;)

@Franz:    Ich sehe da Konstellationen die nicht mehr möglich sind z.B. 30 Stunden auf Stunden gemittelt.
                 Das ist zwar lösbar in dem ich auf Minuten oder Tage gehe aber ich denke da sollte man velleicht
                 die Parameter erweitern und z.B. die Mittelung in Klammer angeben '30h (h)' oder so.
                 Angepasst an deine Vorschlag würde es dann so aussehen:


  •     Beim Modus 'raw' wird unabhängig vom Parameter 'count' alles dargestellt.

  •     Beim Modus 'avg' bestimmt in der 'tmin' Angabe '(h)' das Mittelungs-Intervall für Stunden,
       'd' für Tage usw..

  •     Bei 'avg' mit 'tmin' = '()' wird gewichtet gemittelt, wobei die Gesamtlänge in |count| Intervalle geteilt wird

  •     Mit  'tmin' <> '()' oder '(h)' wird dabei die alte, ungewichtete Mittelung benutzt.
                 und 'count' wird belassen wie in der Docu beschrieben!
                 Hat meines Erachtens den Vorteil, die Mittelung kann irgendwo im 'tmin' stehen
                 und die Einstellung erfolgt nur über einen Paramter!

                 Ist nur so ein Gedanke!

Gruß
Johann
Raspi 3, Sduino 433MHz und 868MHz beide CC1101, Wetterstation TFA Dostmann 35.1119 (WH1080), intertechno PAR1000/PA1500
NOBILY Standard-Minifunkrolladenmotor PR4 13/147-40 ID-98, Homematic CCU3 (homematic-raspi), HmIP-eTRV-2, HmIP-SWDO, HmIP-STH, HmIP-WTH-2, Eigenbau sonoff für Gartenbewässerung

alkazaa

#53
Moin Johann,
Zitat
Ich sehe da Konstellationen die nicht mehr möglich sind z.B. 30 Stunden auf Stunden gemittelt.
Doch, das geht problemlos, siehe die drei Beispiele in meinem letzten Beitrag. Die relevanten Teile der plot.period Definitionen dazu sind:
1. Plot: mode = ['raw','avg'],       tmin = '0h 18h', tmax = '', count = ['1','-18'],     label = ['raw','w-avg 18']
2. Plot: mode = ['raw','avg','avg'], tmin = '0h 18h', tmax = '', count = ['1','2','1'],   label = ['raw','w-avg h','avg h']
3. Plot: mode = ['avg','avg','avg'], tmin = '0h 18h', tmax = '', count = ['-18','2','1'], label = ['w-avg 18','w-avg h','avg h']


Des weiteren schriebst Du:
Zitat

       
  •     Beim Modus 'raw' wird unabhängig vom Parameter 'count' alles dargestellt.
  •     Beim Modus 'avg' bestimmt in der 'tmin' Angabe '(h)' das Mittelungs-Intervall für Stunden,
       'd' für Tage usw..
  •     Bei 'avg' mit 'tmin' = '()' wird gewichtet gemittelt, wobei die Gesamtlänge in |count| Intervalle geteilt wird
  •     Mit  'tmin' <> '()' oder '(h)' wird dabei die alte, ungewichtete Mittelung benutzt.
aber wo bleibt da die gewichtete Mittelung mit Stunden? Ich muss ja das Mittelungsintervall irgendwo in tmin unterbringen, und irgendwo anders muss ich sagen, ob ich gewichtete oder ungewichtete Mittelung will.


Was ich noch einbauen möchte (teilweise schon habe):

       
  • Zeitangaben der Form '1629109298731' (und zwar bei tmin auch als z.B. '0h 1629109298731'  für Mittelungen)
  • absolute Zeitangaben der Form '2022-12-16 14:00:00', bzw.  '0h 2022-12-16 14:00:00'
Dank für die Rückmeldungen
und beste Grüße
Franz

Johann.S

#54
Hallo Franz,

Zitattmin = '0h 18h'
Ok, mir war nicht bewusst, dass man 0h und 18h gleichzeitig verwenden kann!
Ist für mich nicht logisch.

ZitatBeim Modus 'raw' wird unabhängig vom Parameter 'count' alles dargestellt.
    Beim Modus 'avg' bestimmt der 1. Term der 'tmin' Angabe das Mittelungs-Intervall, z.B. '0h' für Stunden.
    Mit einem Parameter 'count' = 1 wird dabei die alte, ungewichtete Mittelung benutzt.
    Bei 'avg' mit 'count' > 1 wird gewichtet gemittelt, die Intervalllänge wird über den 1. tmin-Term festgelegt
    Bei 'avg' mit 'count' < 0 wird gewichtet gemittelt, wobei die Gesamtlänge in |count| Intervalle geteilt wird
Wie machst du eine Mittlung mit der alten Methode und 'count' > 1?
Wenn man 'count' nicht angiebt ist er automatisch 100 also Variante 3?
Würde bedeuten das ich bei 'tmin' = '10d' 100 Werte gemittelt auf Tage bekomme, währen dann also nur 10 Werte oder?

Gruß
Johann

Nachtrag:
Zitataber wo bleibt da die gewichtete Mittelung mit Stunden? Ich muss ja das Mittelungsintervall irgendwo in tmin unterbringen, und irgendwo anders muss ich sagen, ob ich gewichtete oder ungewichtete Mittelung will.
Das währe in meiner Variation der Punkt 2 und bei deiner der Punkt 3.
Raspi 3, Sduino 433MHz und 868MHz beide CC1101, Wetterstation TFA Dostmann 35.1119 (WH1080), intertechno PAR1000/PA1500
NOBILY Standard-Minifunkrolladenmotor PR4 13/147-40 ID-98, Homematic CCU3 (homematic-raspi), HmIP-eTRV-2, HmIP-SWDO, HmIP-STH, HmIP-WTH-2, Eigenbau sonoff für Gartenbewässerung

alkazaa

#55
Hallo Johann!

Ok, ich versuch jetzt mal, die Entwicklung dieses Mittelungsverfahrens aus diesem thread nachzuvollziehen:
Zunächst gab es nur das ungewichtete Mitteln, das sich nach tmin richtete, und zwar so, dass
- bei tmin < 2h gar nicht
- bei 2h <= tmin < 2d stundenweise
- bei 2d <= tmin < 2w tageweise
- bei 2w <= tmin < 2m wochenweise
- bei 2m <= tmin < 2y monatsweise
- bei 2y <= tmin jahresweise gemittelt wurde.
tmin hatte immer nur einen Term, count spielte keine Rolle.

Dann wurde implementiert, dass tmin auch mehrere Terme haben durfte (im Einklang mit dem von Wolfram erwähnten SV-Möglichkeiten, z.B. '2m 3d 12h'), wobei der Buchstabe (h|d|w|m|y) des 1. Terms genutzt wurde, das Mittelungsintervall festzulegen.
Das hatte den Nebeneffekt, das man unabhängig von der Gesamtzeit das Mittelungsintervall festlegen konnte. War z.B. sinnvoll, wenn man mit tmin='1y 2w', tmax='1y' einen 2-Wochen-Zeitraum vor einem Jahr mit tageweiser Mittelung anschauen wollte: dann konnte man einfach tmin='0d 1y 2w' angeben, da die Terme in tmin einfach aufaddiert wurden. Ging vorher gar nicht. (Das war der Trick, den ich früher mal erwähnte.)

Ich gebe zu, dass das nicht intuitiv und logisch aussieht, aber man könnte ja auch, wie von Dir vorgeschlagen, mit vorangestelltem oder folgendem (h), (d), ... den gleichen Effekt erzielen. Würde ich aber nicht machen, da es dann bei jemand, der die alte 1-Term-für-tmin-Angabe benutzt, nicht funktioniert.

Nun gibt es aber zusätzlich das gewichtete Mitteln, und man muss jetzt irgendwo unterbringen, welche der beiden Methoden genommen werden soll. Da habe ich mich entschieden, das mit dem Parameter count zu machen (den ich ja schon beim gewichteten Mitteln mit 'brutaler' Einteilung der Gesamtzeit in |count| Intervalle missbraucht hatte.)

Mit Modus 'avg' und count>1 das gewichtete Mitteln auszuwählen ist vernünftig, da das ungewichtete Mitteln bei ungleichen Zeitabständen der Messwerte nicht sinnvoll ist. (Und bei gleichen Zeitabständen liefern beide Methoden das gleiche Ergebnis. Wer es trotzdem ungewichtet möchte, kann es mit count=1 immer noch erzwingen. Muss natürlich alles gut dokumentiert werden).

Wenn mit Deiner Variante 2 das gewichtete Mitteln gewählt wird, verstehe ich nicht, wie bei Deiner Variante 4 das Mittelungsintervall angegeben wird.

Ich hoffe, wir reden nicht zu sehr aneinander vorbei...

Gruß
Franz

wvhn

Hallo zusammen,

super Zusammenfassung, @alkazaa. Das bringt gut Transparenz in die Sache.
Ein neues Format für die Angabe der Mittelung anzugeben - z.B. "(h)" - ist wegen Kompatibilität zu bisherigen Visu-Seiten der Anwender und auch hinsichtlich der anderen Backend-Systeme ungünstig. Darauf würde ich gerne verzichten. Schon die negative Angabe für count ist eine Krücke, aber vermutlich das Beste, was einem einfallen kann um die gewichtete Mittelung ohne negative Begleiteffekte für bestehende Visu-Seiten einzuführen.

Das Beispiel "0h 18h" ist etwas ungünstig, weil zweimal die gleiche Einheit verwendet wird. Das funktioniert zwar, aber das "0h" ist überflüssig, weil bereits "18h" als erster Termin die Mittelung über Stunden bewirkt. Nimmt man "0h 18d" wird es vielleicht klarer: mit vorangestelltem "0h" wird stundenweise gemittelt, anderenfalls tageweise.

@JohannS, ich kenne das "Auswertungsfenster" nicht. Kannst Du den Zweck und die Funktionsweise beschreiben?

Gruß
Wolfram

Johann.S

Hallo Wolfram,

am Auswertungsfenster bastle ich gerade herum!
Sinn und Zweck ist es in diesem Fenster die Werte Plotname, tmin, tmax, count usw. einzugeben/auszuwählen!
Anschliesend wird ein unabhängiges Fenster göffnet mit dem Plot!
Bei der nächsten Eingabe kommt wieder ein unabhängige Fenster usw..
Somit kann man mehrer Plots in unabhängigen Fenster anzeigen und vergleichen!
So ähnlich wie hier im Forum die angehängten Bilder!

Damit muss ich nicht alle Vergleiche im vorhinein wissen/erstellen und kann Kraut und Rüben mit einander vergleichen!

Ich hoffe die Erklährung war verständlich?

Wegen der Parameter bin ich mit allem Einverstanden, ich bin ja froh das es endlich funktioniert!
Ein Jahr warten hat sich ausgezahlt!

Ohne Franz währen wir nie so weit gekommen!

Danke noch mal!

Gruß
Johann
Raspi 3, Sduino 433MHz und 868MHz beide CC1101, Wetterstation TFA Dostmann 35.1119 (WH1080), intertechno PAR1000/PA1500
NOBILY Standard-Minifunkrolladenmotor PR4 13/147-40 ID-98, Homematic CCU3 (homematic-raspi), HmIP-eTRV-2, HmIP-SWDO, HmIP-STH, HmIP-WTH-2, Eigenbau sonoff für Gartenbewässerung

alkazaa

#58
Moin Johann, Wolfram,

danke für das fette Lob (rot-werd). Ich will das dann mal (vorerst) abschließen mit der 99_fronthemUtils.pm im Anhang.

Ich habe noch paar Anmerkungen dazu:

A) Parameterübergabe aus plot.period:

       
  • mode 'raw' liefert immer alle Werte im angegebenen Zeitfenster tmin,tmax
    (Also keine Änderung gegenüber vorher)
  • mode 'avg' und count > 2 liefert gewichtete Mittelwerte in count Intervallen
    (Das ist neu, und es vermeidet einen negativen count-Wert. Es ist auch der einzige Fall
    wo der Wert von count die Zahl der Intervalle angibt)
  • mode 'avg' und count = 2 liefert gewichtete Mittelwerte in Intervallen, die durch den ersten
    Buchstaben (h|d|w|m|y) in den tmin-Angaben festgelegt sind. tmin kann mehrere Werte haben,
    die aufaddiert werden, z.B. ergibt '1y 3m 2d' eine Dauer von 1 Jahr, 3 Monaten und 2 Tagen.
    In der SV-Dokumentation ist das als 'duration-format' bezeichnet. Ein vorangestelltes '0h' oder
    '0d' etc. trägt ( wegen der 0) nicht zur Gesamtdauer bei, aber legt Stunden (h) (oder Tage etc.)
    als Mittelungsintervall fest.
  • mode 'avg' und count = 1: wie vor, aber ungewichtetes Mitteln
  • bei den Modi 'min', 'max', 'sum' ist alles wie vorher (der count-Wert ist irrelevant, die Intervalldauer
    wird durch den ersten Term in tmin festgelegt
B) weitere Features:

       
  • In tmin und tmax können timestamps der Form 1670259921000 angegeben werden. Ein führender
    Term '0h', '0d', etc. wird in tmin akzeptiert und wirkt sich aus wie oben beschrieben
  • Außer Jahr (y), Monat (m), Woche (w), Tag (d) und Stunde (h) habe ich auch Viertel-Tage (also 6h-Zeiträume)
    und Viertelstunden implementiert. Allerdings: die entsprechenden Kürzel (q und v habe ich gewählt)
    werden von SV nicht übergeben. Kann man das in SV ändern?
  • Ebenso kann SV keine 'human-readable' Absolutzeiten der Form "2022-11-11 11:11:00" verdauen:
    Sie werden zwar an fronthemUtils übergeben (und dort auch richtig verarbeitet), aber im Browser tauchen
    merkwürdige x-Achsen auf, sodass keine Daten zu sehen sind.
C) Besonderheiten/Einschränkungen:

       
  • für die Nutzung der o.g. features wird in FHEM automatisch ein DbRep-device angelegt, dessen Name dem des DbLog-device mit angehängtem 'Report' entspricht
  • die implementierten SQL-Queries sind z.Zt. nur für MySql verfügbar. PostGreSQL und sqlite kann ich nicht testen
  • in Plotfile() sind keine der Änderungen aktiv
  • ausführliches Testen als Sahnehäubchen fehlt noch (obwohl ich den Eindruck habe, dass annähernd 100%
    derjenigen, die FHEM-SV-Plot nutzen schon getestet haben  ;) )
Einen schönen 4. Advent noch!
Franz

Nachtrag
In DbRep ist zwar bereits ein gewichtetes Mitteln implementiert. Die Punkte eines Mittelungsintervalls werden dort aber mit separaten SQL-Queries eingelesen (und dann im Perl-code weiterverarbeitet). Dadurch fällt immer der jeweils letzte Datenpunkt eines Intervalls "unter den Tisch", da sein Zeitabstand zum nächsten Punkt außerhalb des Intervalls nicht bekannt ist. Fällt zwar nur auf, wenn nur wenige Datenpunkte pro Intervall vorliegen, aber trotzdem...

Mit der reinen SQL-Berechnung. die ich gewählt habe, kann man das vermeiden. Ich habe das so implementiert, dass der Wert, der durch einen Datenpunkt am Ende eines Intervalls repräsentiert wird, korrekt auf dieses und das folgende Intervall verteilt wird.  Der zugehörige SQL-Code sieht allerdings gelinde gesagt abschreckend aus, wenn man die Lust verspürt, ihn im sourcecode anzuschauen. In der beiliegenden ZIP Datei habe ich ihn daher in etwas leichter lesbarer formatierter Form zusätzlich beigefügt (am besten mit notepad++ o.ä. anschauen).

Johann.S

Hallo Franz, Wolfram,

danke noch mal für die spitzen Leistung, ich fülle mich wie Weihnachten, ach ja ist ja Weihnachten  ;D

Also von meiner Seite kann man das jetzt in fhem einfliessen lassen (oder wie immer man das nennt)!
Für meine Verhältnisse ist es mehr als ich mir gewünscht habe!

Ich werde es heute in meine Hauptversion installieren!

Schöne Feiertage!
Johann
Raspi 3, Sduino 433MHz und 868MHz beide CC1101, Wetterstation TFA Dostmann 35.1119 (WH1080), intertechno PAR1000/PA1500
NOBILY Standard-Minifunkrolladenmotor PR4 13/147-40 ID-98, Homematic CCU3 (homematic-raspi), HmIP-eTRV-2, HmIP-SWDO, HmIP-STH, HmIP-WTH-2, Eigenbau sonoff für Gartenbewässerung

alkazaa

Ich habe meine Routinen zur Mittelwertbildung nochmal überarbeitet, damit Werte an Grenzen eines Mittelungsintervalls korrekt verarbeit (und nicht weggeworfen) werden.
Siehe dazu den Nachtrag und den Anhang in diesem Topic.

Falls Wolfram hier noch mitliest:
Ich denke, man könnte das ganze jetzt in den master branch einfügen. Da ich nicht mehr sicher bin, von welcher Version ich ausgegangen bin, müsste ich eine Version mit den aktuellen UZSU Routinen haben, um meine Änderungen dazu zu mergen. Welche wäre das?

Beste Grüße
und einen guten Rutsch

Franz



wvhn

Moin Franz,

Klar lese ich noch mit und habe das Thema auch noch auf meiner to-do List. Ich schau mir das in den nächsten Tagen mal an, welche Erweiterung ich guten Gewissens in welchem branch zur Verfügung stellen kann.

Unentschlossen bin ich noch mit den Erweiterungen der Zeiteinheiten ('q', 'v'), weil das von smartVISU nicht unterstützt wird und dort an mehreren Stellen abgefangen werden müsste. Vielleicht fällt uns da noch eine andere Lösung ein.

Gruß
Wolfram

wvhn

Hallo zusammen,

wie schon vor einiger Zeit versprochen habe ich die Versionen in den beiden branches überarbeitet.


  • der master branch enthält jetzt die bisherige Version, erweitert um die an den smartVISU-Standard angepassten Zeitangaben: durations mit mehreren Termen, Unix-Zeitstempel und "now". Wie oben beschrieben wird die Berechnungsmethode (hourstats, daystats, weekstats, monthstats) für die Auswertungsmodi aus dem ersten Term der duration entnommen.
  • der develop branch enthält die letzte von Franz bereitgestellte Version mit neuen Auswertungsmöglichkeiten für die Plots (https://forum.fhem.de/index.php/topic,118668.msg1252219.html#msg1252219), sowie die neuen UZSU-Routinen von raman.

Aus meiner Sicht ist dies die beste Lösung, um sowohl eine breit getestete und bewährte Version, als auch eine noch experimentelle Version mit neuen Features zur Verfügung zu stellen.

Gruß
Wolfram

alkazaa

#63
Moin Wolfram,

im KNX-smartvisu Forum hatte ich die "sub fronthem_Time($$)" für negative duration-format Angaben wie z.B. '-2h' so erweitert:
sub
fronthem_Time($$)
{
my ($time, $period) = @_;
my $temp;

if ($period =~ /^(.*?)\s*(\d{13})/) { # alkazaa
return int($2/1000 + 0.5);
}
if ($period eq "now") {
return $time;
}

# alkazaa
# the next 'if' is meant to parse a tmin or tmax parameter of the form "0w 2022-12-01 12:34:56"
# It converts correctly for further processing, however, it is not working with SmartVISU, since
# within the SV plot.period widget such a tmin statement does not produce the correct x-axis
if ($period =~ /^(.*?)\s*(\d{4})-(\d{2})-(\d{2})\s(\d{2}):(\d{2}):(\d{2})/) {
return timelocal($7,$6,$5,$4,$3-1,$2);
}

my @periods = split(' ', $period);  # alkazaa: split composed time specifications like "1y 3m 5d 10h"
foreach my $period (@periods)     # into an array like ("1y","3m","5d","10h") and loop over array elements
{
if ($period =~ /^([-+]?\d{1,4})(s|i|h|d|w|m|y)/)
{
my $newTime = 0;
if ($3 eq "s")
{
$newTime = $2;
}
elsif ($3 eq "i")
{
$newTime = $2 * 60;
}
elsif ($3 eq "h")
{
$newTime = $2 * 3600;
}
elsif ($3 eq "d")
{
$newTime = $2 * 3600 * 24;
}
elsif ($3 eq "w")
{
$newTime = $2 * 3600 * 24 * 7;
}
elsif ($3 eq "m")
{
$newTime = $2 * 3600 * 24 * 30;
}
elsif ($3 eq "y")
{
$newTime = $2 * 3600 * 24 * 365;
}
$time -= $newTime;
}

}
return $time;
}

Ich schlage vor, das in den develop branch zu übernehmen. Die Einführung der $sign Variablen scheint mir hinreichend betriebssicher implementiert, sie auch gleich in den master branch zu bringen.

Beste Grüße
Franz

wvhn

Moin Franz,

vielen Dank. Ich übernehme das bei nächster Gelegenheit.

Gruß
Wolfram

alkazaa

ZitatIch übernehme das bei nächster Gelegenheit.
Danke, Wolfram! (aber aufpassen: Ich habe das Vorzeichenhandling im code snippet von Beitrag #63 nochmal editiert, ist jetzt kompakter geschrieben)

-Franz

wvhn

Hallo Franz,

kannst Du mir mal helfen, das Regex if ($period =~ /^([-+]?\d{1,4})(s|i|h|d|w|m|y)/) zu verstehen?
Mit den beiden Klammern gibt es zwei Auswertegruppen, deren Ergebnisse nach $1 und $2 geschrieben werden müssten. Du verwendest aber im Folgenden $2 und $3.

Da ich den Code nicht selbst testen kann, möchte ich ihn zumindest verstehen, bevor ich ihn im Repository veröffentliche.

Denke und Gruß
Wolfram

alkazaa

Wolfram,
danke fürs Aufpassen. Du hast natürlich recht, es muss $1 und $2 heißen.

Die Änderung gegenüber der 1. Version im Beitrag #63 lag darin, das Vorzeichen der Zahl gleich in der 1. capture group mitzunehmen.

Das kommt davon wenn man zu schnell etwas 'kompakter' schreiben will...

Sorry, Franz

wvhn

Die Änderung ist jetzt im master branch und im develop branch. Negative durations ermöglichen es, ein Diagramm auch in die Zukunft hinein zu skalieren - z.B. zur Darstellung von Prognosedaten.

Gruß
Wolfram