Plot von monatlichen Werten als Balkendiagramm

Begonnen von plinepa, 11 August 2020, 17:39:06

Vorheriges Thema - Nächstes Thema

plinepa

Hallo!

Ich würde gerne meinen monatlichen Gasverbrauch als Balkendiagramm plotten.

Ich speichere die Werte an jedem ersten des Monats in einem Dummy D_GASCNTAT1STDAYOFMONTH.
Vorgegangen bin ich da nach https://wiki.fhem.de/wiki/Heizleistung_und_Gasverbrauch

Im Plot mit fixedrange = 2years bekomme ich also als preprocessed input einen Wert pro Monat:
get logdb HISTORY INT 2019-01-01_00:00:00 2020-12-31_23:59:59 D_GASCNTAT1STDAYOFMONTH:gasabsolut

2019-01-01_00:01:00 5154.58
2019-02-01_00:01:00 5537.51
2019-03-01_00:01:00 5861.94
2019-04-01_00:01:00 6108.21
2019-05-01_00:01:00 6254.78
2019-06-01_00:01:00 6389.67
2019-07-01_00:01:00 6439.64
2019-08-01_00:01:00 6479.96
2019-09-01_00:01:00 6519.16
2019-10-01_00:01:00 6608.88
2019-11-01_00:01:00 6755.94
2019-12-01_00:01:00 7004.87
2020-01-01_00:01:00 7327.94
2020-02-01_00:01:00 7697.52
2020-03-01_00:01:00 8003.45
2020-04-01_00:01:00 8286.01
2020-05-01_00:01:00 8447.48
2020-06-01_00:01:00 8558.79
2020-07-01_00:01:00 8625.89
2020-08-01_00:01:00 8675.63
#D_GASCNTAT1STDAYOFMONTH:gasabsolut:::


Als Plot bekomme ich dann halt die entsprechende Line wie im angehängten Bild.

Doch wie kann ich jetzt das Delta entsprechend aufbereiten und plotten.
Die beiden bekannten delta-h und delta-d sind hier ja nicht so passend.

Hier noch meine gplot-Datei:
# Created by FHEM/98_SVG.pm, 2020-08-11 17:28:39
set terminal png transparent size <SIZE> crop
set output '<OUT>.png'
set xdata time
set timefmt "%Y-%m-%d_%H:%M:%S"
set xlabel " "
set title '<L1>'
set ytics
set y2tics
set grid y2tics
set ylabel ""
set y2label "Gasverbrauch"

#logdb D_GASCNTAT1STDAYOFMONTH:gasabsolut

plot "<IN>" using 1:2 axes x1y2 title 'Line 1' ls l0 lw 1 with lines


Vielen Dank für Eure Hilfe
Gruß
plinepa

Nobbynews

#1
Nachträglich wird das nur von Hand gehen. Bei den paar Werten lohnt es sich imho nicht hier etwas in z.b. myUtils zu erstellen.
Ansonsten würde ich das über Readings erschlagen und jeden Monatsanfang über ein at befüllen und damit die Daten erzeugen.
Z.b. so:

Folgende Readings im device anlegen: Differenz, Vormonat
Dabei das reading "Vormonat" mit dem entsprechenden Wert aus der vorhandenen Log-Datei setzen.
Für den nächsten Monatswechsel als z.B.
setreading <device> Vormonat 8675.63

Das reading "Verbrauch aktueller Monat" existiert ja schon als
D_GASCNTAT1STDAYOFMONTH:gasabsolut

Und im at dann folgende Berechnung durchführen (in unreine geschrieben):

my $tmp = ReadingsVal("D_GASCNTAT1STDAYOFMONTH","gasabsolut",0);
my $Differenz = $tmp - ReadingsVal("<device>", "Vormonat",0);
fhem ("setreading <device> Differenz $Differenz");
fhem ("setreading <device> Vormonat $tmp);


Und dann noch für reading Differenz in eine Log-Datei erzeugen.

Zum Testen kannst Du das über das at auch mal täglich machen lassen.

Icinger

Für die zuküntigen Daten schau dir doch das statistics-Modul an.
Verwende deine Zeit nicht mit Erklärungen. Die Menschen hören (lesen) nur, was sie hören (lesen) wollen. (c) Paulo Coelho

Nobbynews

Zitat von: Icinger am 16 August 2020, 09:08:50
Für die zuküntigen Daten schau dir doch das statistics-Modul an.
Das ist mit Sicherheit auch eine Möglichkeit, ist aber mMn für die gestellte Aufgabe wie mit Kanonen auf Spatzen zu schießen.

plinepa

Zitat von: Nobbynews am 16 August 2020, 07:34:48
Nachträglich wird das nur von Hand gehen. Bei den paar Werten lohnt es sich imho nicht hier etwas in z.b. myUtils zu erstellen.
Ansonsten würde ich das über Readings erschlagen und jeden Monatsanfang über ein at befüllen und damit die Daten erzeugen.
Z.b. so:

Folgende Readings im device anlegen: Differenz, Vormonat
Dabei das reading "Vormonat" mit dem entsprechenden Wert aus der vorhandenen Log-Datei setzen.
Für den nächsten Monatswechsel als z.B.
setreading <device> Vormonat 8675.63

Das reading "Verbrauch aktueller Monat" existiert ja schon als
D_GASCNTAT1STDAYOFMONTH:gasabsolut

Und im at dann folgende Berechnung durchführen (in unreine geschrieben):

my $tmp = ReadingsVal("D_GASCNTAT1STDAYOFMONTH","gasabsolut",0);
my $Differenz = $tmp - ReadingsVal("<device>", "Vormonat",0);
fhem ("setreading <device> Differenz $Differenz");
fhem ("setreading <device> Vormonat $tmp);


Und dann noch für reading Differenz in eine Log-Datei erzeugen.

Zum Testen kannst Du das über das at auch mal täglich machen lassen.

So hatte ich das auch schon mal probiert, aber dann wird der Verbrauch für z.B. Juli 2020 ja am 01.08.2020 in das Device geschrieben.
(Bei setreading kann ich ja keinen TIMESTAMP von z.B. 31.07.2020 angeben)
Dann hatte ich in der Folge da das Problem dass der Plot ja dann den Juli-Verbrauch im August angezeigt hat.
Mit fixedoffset habe ich auch schon "rumgespielt", bin aber zu keinem Ergebnis gekommen.

Daher bin ich im Moment dabei das Ganze mittels einem externen Python-Skript zu berechnen und die Verbräuche direkt in die fhem.history zu INSERTen.
Da kann ich dann beim INSERT ja meinen TIMESTAMP gezielt setzen.




Nobbynews

#5
Zitat von: plinepa am 16 August 2020, 13:14:45
So hatte ich das auch schon mal probiert, aber dann wird der Verbrauch für z.B. Juli 2020 ja am 01.08.2020 in das Device geschrieben.
Was erwartest Du als Ergebnis??
Es wird ein Reading gesetzt! Kein Device.
Am 1. August den Monatsverbrauch für Juli dargestellt zu bekommen, ist doch korrekt.
Ich verstehe nicht, was Dein Ziel ist.
Was ist fhem.history??
Soetwas kann ich bei meiner Installation nicht finden.

DS_Starter

@plinepa, ich glaube du benutzt eine Datenbank für das Logging.
Dann kannst du die Möglichkeiten von DbRep nutzen und deine Daten wie benötigt selektieren/aggregieren, in die DB zurück schreiben und plotten.
Ein Beispiel ist im DbRep-Wiki beschrieben. Externe Skripte brauchst dafür nicht entwerfen.
Proxmox+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

plinepa

Zitat von: Nobbynews am 16 August 2020, 14:19:53
Was erwartest Du als Ergebnis??
Es wird ein Reading gesetzt! Kein Device.
Am 1. August den Monatsverbrauch für Juli dargestellt zu bekommen, ist doch korrekt.
Ich verstehe nicht, was Dein Ziel ist.
Ich möchte den Juli-Verbrauch auch als Balken über dem Monat Juli angezeigt bekommen.
Bei mir wurde aber der Juli-Verbrauch im August angezeigt, also einen Monat versetzt.
Diesen Versatz konnte ich nicht beheben.

Zitat von: Nobbynews am 16 August 2020, 14:19:53
Was ist fhem.history??
Soetwas kann ich bei meiner Installation nicht finden.
Bei mir läuft FHEM mit MySQL und die Readings stehen alle in der Tabelle history der Datenbank fhem.

plinepa

Zitat von: DS_Starter am 16 August 2020, 15:01:04
@plinepa, ich glaube du benutzt eine Datenbank für das Logging.
Dann kannst du die Möglichkeiten von DbRep nutzen und deine Daten wie benötigt selektieren/aggregieren, in die DB zurück schreiben und plotten.
Ein Beispiel ist im DbRep-Wiki beschrieben. Externe Skripte brauchst dafür nicht entwerfen.
Ja, ich benutze MySQL.
Auch das Modul DbRep benutze ich soweit schon für das Löschen der alten Readings und das Backup.

Dann werde ich den Wiki-Artikel mal versuchen zu verstehen  ;)

Icinger

Den Versatz um ein Monat kannst du mit LogProxy realisieren.
Verwende deine Zeit nicht mit Erklärungen. Die Menschen hören (lesen) nur, was sie hören (lesen) wollen. (c) Paulo Coelho

Nobbynews

#10
Jetzt verstehe ich, was Dein Problem ist.
Den Timestamp musst Du nicht verbiegen.
Es reicht doch völlig aus, den Monatsverbrauch nicht am 1. Tag des Monats, sondern am LETZTEN Tag des Monats zu erzeugen. Dann passt der Timestamp für den Monat automatisch.
Das geht mit einem at wir hier beschrieben https://forum.fhem.de/index.php/topic,49461.msg1030850.html#msg1030850

Zitat von: DeeSPe am 10 März 2020, 12:44:09
define at_EnergyCostMonth2359 at *23:59:00 {fhem "setreading Gaszaehler EnergyCostMonth2359 [Gaszaehler:ESPEasy_ESP_Easy1_reedkontakt_Total_EnergyCostMonth]" if ((strftime "%d",localtime time+86400) eq "01")}