[gelöst] Idee gesucht - wie kann ich Öllieferungen in FHEM ablegen/archivieren

Begonnen von Tom Major, 26 Oktober 2015, 18:37:11

Vorheriges Thema - Nächstes Thema

Tom Major

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
Früher: FHEM 5.x
Jetzt: RaspberryMatic / ioBroker

betateilchen

-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Sunny

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  ;)
FHEM 6.0 (RPi's 1b-4,CeleronM,Odroid C1+)
1-Wire (DS18B20,DS2406) |miniCUL|miniCUL868WLAN|HM|IT(-1500,LR-3500) |FB6591,FB7490,FB7580|DECT200|Powerline546E|520E|openwrt
Anfänger: Linux,FHEM+Perl

Tom Major

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
Früher: FHEM 5.x
Jetzt: RaspberryMatic / ioBroker

betateilchen

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.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Tom Major

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
Früher: FHEM 5.x
Jetzt: RaspberryMatic / ioBroker

Sunny

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
FHEM 6.0 (RPi's 1b-4,CeleronM,Odroid C1+)
1-Wire (DS18B20,DS2406) |miniCUL|miniCUL868WLAN|HM|IT(-1500,LR-3500) |FB6591,FB7490,FB7580|DECT200|Powerline546E|520E|openwrt
Anfänger: Linux,FHEM+Perl

Tom Major

@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
Früher: FHEM 5.x
Jetzt: RaspberryMatic / ioBroker