Ich monitore den Ölstand des Tankkessels in FHEM und berechne mir dazu täglich und wöchentlich den Verbrauch des Tages und der Woche zur Darstellung in einer Grafik.
Der Tagesverbrauch wird durch ein at um 23:50 in 99_myUtils.pm z.B. so berechnet:
# Oel Tagesverbrauch berechnen
sub
prg_Daily_Stat_Oel()
{
# Zunächst Tagesverbrauch (aktueller Wert - Wert von gestern) berechnen
# Ölstand nimmt im Gegensatz zum Stromzähler ab, deshalb Minuend und Subtrahend vertauscht!
$data{DPval} = Value("dy_OelLastDay") - ReadingsVal("CustomSensor_Oel","Oelmenge",0);
# Tagesverbrauch in OelDaily speichern
fhem ("set dy_OelDaily $data{DPval}");
# Aktuellen Wert in OelLastDay speichern (entspricht Ölstand am Tagesende)
$data{DPval} = ReadingsVal("CustomSensor_Oel","Oelmenge",0);
fhem ("set dy_OelLastDay $data{DPval}");
fhem("save");
}
Funktioniert gut. Jetzt ist es allerdings so, dass diese Rechnung am Tag einer Öllieferung nicht stimmt, da ja z.B. 2000 Liter auf den Ölstand draufkommen.
Ich suche eine Möglichkeit, die Öllieferungen in FHEM zu archivieren, durch manuelle Eingabe. Die Funktion oben könnte dann prüfen, ob an dem Tag eine Öllieferung war und den Tagesverbrauch entsprechend korrigieren - das kriege ich hin.
Was mir fehlt ist eine Idee mit welchen FHEM bzw. Perl Mitteln kann ich eine Art Array mit Öllieferung und dazugehörendem Datum anlegen, welches dann für die Berechnungen herangezogen werden kann? Ich habe 2-3 Öllieferungen pro Jahr.
Danke,
Tom
In einen dummy schreiben.
Moin Tom,
was hälst Du von einem Dummy "Oellieferung" mit einem Reading Liter, und Du per setreading "tankst".
Viele Grüße
Sunny
Upps betateilchen war schneller ;)
Danke für die schnellen Antworten.
Ist das setreading Datum des dummies implizit irgendwo im Dummy gespeichert? In einem Dummy bei mir steht z.B.
state 1279 2015-10-25 23:50:10
Wie würde ich da das setreading Datum in einer 99_myUtils Funktion extrahieren können?
Ausserdem wollte ich wie gesagt das Auftanken archivieren. Wie würdet Ihr das bei der nächsten Öllieferung machen, ein neuer dummy oder derselbe, der über ein filelog archiviert wird, geht das?
Danke,
Tom
setreading würde ich gar nicht verwenden.
Bei einem dummy kannst Du einfach per "set <dummyDevice> <readingName> <Wert>" ein Reading setzen, wenn Du dieses Reading dem dummy vorher bekannt gemacht hast. (commandref zu dummy lesen!) Und in einem dummy kannst Du beliebig viele solcher readings generieren.
Den Timestamp eines readings kannst Du über die Funktion ReadingsTimestamp() ermitteln.
Hallo betateilchen,
danke für Deine Hinweise. Wahrscheinlich brauche ich ReadingsTimestamp() dann gar nicht. Ich habe das jetzt so versucht zu lösen, meine geänderte Funktion vom ersten Post (habe einen neuen Dummy dy_OelBetankung mit den Readings Liter und LiterForWeekly eingeführt):
#Oel Tagesverbrauch berechnen
sub
prg_Daily_Stat_Oel()
{
my $BetankungHeute;
# ev. Betankung von Heute holen
$BetankungHeute = ReadingsVal("dy_OelBetankung", "Liter", 0);
# Zunächst Tagesverbrauch (aktueller Wert - Wert von gestern) berechnen
# Ölstand nimmt im Gegensatz zum Stromzähler ab, deshalb Minuend und Subtrahend vertauscht!
$data{DPval} = Value("dy_OelLastDay") - ReadingsVal("CustomSensor_Oel","Oelmenge",0) + $BetankungHeute;
# Tagesverbrauch in OelDaily speichern
fhem ("set dy_OelDaily $data{DPval}");
# Aktuellen Wert in OelLastDay speichern (entspricht Ölstand am Tagesende)
$data{DPval} = ReadingsVal("CustomSensor_Oel","Oelmenge",0);
fhem ("set dy_OelLastDay $data{DPval}");
# Betankung von Heute rücksetzen aber vorher für wöchentliche Berechnung speichern
if ($BetankungHeute > 0) {
fhem ("setreading dy_OelBetankung LiterForWeekly $BetankungHeute");
fhem ("setreading dy_OelBetankung Liter 0");
}
fhem("save");
}
Ich würde also bei einer Betankung an dem Tag z.B. das hier eingeben:
setreading dy_OelBetankung Liter 2000
Dann sollte die Funktion kurz vor Mitternacht den Tagesverbrauch korrigieren, sich den Wert für die wöchentliche Korrektur (Sonntags) speichern und die Betankung auf 0 rücksetzen. Ausserdem habe ich einen filelog angelegt um die Betankungen zu archivieren. Ich habe diese Woche eine Lieferung, mal schauen ob's funktioniert.
Kleine weitere Frage, fhem ("setreading dy_OelBetankung LiterForWeekly $BetankungHeute"); sollte bezüglich der Verwendung von $BetankungHeute gehen, oder? Ich verstehe nämlich nicht wirklich das $data{DPval} aus den Zeilen weiter oben, das ist aus dem Stromzähler Bsp. kopiert:
http://www.fhemwiki.de/wiki/Stromz%C3%A4hler_und_1-Wire,_OWServer,_OWDevice
Ist $data{DPval} ein Hash-Element-Zugriff? Warum wurde das im Stromzähler Bsp. so gemacht?
Danke,
Tom
Moin Tom,
@betateilchen, vielen Dank, habe jetzt auch "slider" entdeckt.
attr dy_OelBetankung setList Liter:slider,1000,1,4000
Mit "slider" kannst Du dann ohne setreading die Liter eingeben (zB. 1000 bis 4000 in einer Schritten).
Kannte ich vorher auch noch nicht. 8)
Zum code kann ich Dir leider noch nix sagen/schreiben. So weit bin ich noch nicht. :-[
Viele Grüße
Sunny
@Sunny: Danke für den Hinweis mit dem Slider.
Ich habe jetzt eine noch elegantere Variante gefunden glaube ich. Da die Gefahr besteht, dass ich die Betankung an dem Tag vergesse einzugeben rechne ich mir diese jetzt automatisch aus:
#------------------------------------------------------------------------------
# Oel Tagesverbrauch berechnen
sub
prg_Daily_Stat_Oel()
{
my ($val, $OelDiff);
# Zunächst Tagesverbrauch (aktueller Wert - Wert von gestern) berechnen
# Ölstand nimmt im Gegensatz zum Stromzähler ab, deshalb Minuend und Subtrahend vertauscht!
$OelDiff = Value("dy_OelLastDay") - ReadingsVal("CustomSensor_Oel", "Oelmenge", 0);
# Bei Betankung an diesem Tag ist die Differenz negativ
if ($OelDiff < -250) {
$OelDiff = ReadingsVal("CustomSensor_Oel", "Oelmenge", 0) - Value("dy_OelLastDay");
# Tagesverbrauch in OelDaily für diesen einen Tag auf 0 setzen
fhem ("set dy_OelDaily 0");
# Betankung archivieren/loggen
fhem ("set dy_OelBetankung $OelDiff");
}
else {
# Tagesverbrauch in OelDaily speichern
fhem ("set dy_OelDaily $OelDiff");
}
# Aktuellen Wert in OelLastDay speichern (entspricht Ölstand am Tagesende)
$val = ReadingsVal("CustomSensor_Oel", "Oelmenge", 0);
fhem ("set dy_OelLastDay $val");
fhem("save");
}
Diese Funktion wird wie gesagt 23:50 in 99_myUtils.pm aufgerufen. Eine ähnliche Funktion existiert noch, die den Wochenverbrauch Sonntags berechnet. Ausserdem lasse ich die ausgerechneten Betankungen in einem FileLog archivieren.
Im FHEM cfg Datei sieht das dann etwa so aus (nur das Wichtigste, ohne FileLog, room etc.):
define dy_OelLastDay dummy
define dy_OelDaily dummy
define dy_OelBetankung dummy
define at_FuncDailyOel at *23:50:10 {prg_Daily_Stat_Oel()}
Getestet mit und ohne Betankung, funktioniert gut. Danke nochmal für alle Hinweise hier.
Grüße Tom