Spritpreismonitor: Unterschied zwischen den Versionen
DeeSPe (Diskussion | Beiträge) (Randnotiz entfernt) |
DeeSPe (Diskussion | Beiträge) KKeine Bearbeitungszusammenfassung |
||
Zeile 203: | Zeile 203: | ||
### Funktion für Ermittlung vom niedrigsten Preis für readingsGroup rg_Benzinpreise ### | ### Funktion für Ermittlung vom niedrigsten Preis für readingsGroup rg_Benzinpreise ### | ||
####################################################################################### | ####################################################################################### | ||
# damit die Funktion richtig funktioniert müssen alle Tankstellenname mit "Tankstelle_" beginnen | |||
# oder entsprechend das devspec2array auf die eigenen Namen anpassen | |||
sub BenzinLP($) { | sub BenzinLP($) { | ||
my ($r) = @_; | my ($r) = @_; | ||
return (sort map {ReadingsNum($_,$r,0)} devspec2array("Tankstelle_.*"))[0]; | |||
} | } | ||
</pre> | </pre> |
Version vom 8. Februar 2021, 16:40 Uhr
Die hier vorgestellten Fragmente ermöglichen es, mit Hilfe von HTTPMOD bei clever-tanken.de von Wunschtankstellen die Spritpreise zu protokollieren. Die Credits dafür gehen an Forum-Benutzer Phil__ . Die Original Diskussion im Forum ist hier.
Alternativ können die Kraftstoffpreise auch über die Webseite tankerkönig.de bezogen werden. Die Vorgehensweise dafür ist im Detail in diesem Blog beschrieben.
Einleitung
Im folgenden wird mit Hilfe des Moduls HTTPMOD der Spritpreis von ausgewählten Tankstellen abgerufen. Die Daten werden gefiltert, gespeichert und als Diagramm aufbereitet.
Zum Nachbau ist es erforderlich, "seine" Wunschtankstellen bei Clever-Tanken zu suchen. Jede Tankstelle hat eine eigene Nummer:
/tankstelle_details/0815
Die 600 in den Beispielen gibt das Abrufintervall in Sekunden an.
Konfiguration
Die erforderlichen Definitionen in der FHEM Konfiguration bestehen aus mehreren Teilen. Zunächst die erforderlichen Einstellungen, um die Daten der gewünschten Tankstellen abzuholen:
define Shell HTTPMOD http://www.clever-tanken.de/tankstelle_details/4871 600 attr Shell enableControlSet 1 attr Shell reading01Name Diesel attr Shell reading01Regex "price-type-name">Diesel<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Shell reading02Name SuperE5 attr Shell reading02Regex "price-type-name">Super.E5<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Shell reading03Name SuperE10 attr Shell reading03Regex "price-type-name">Super.E10<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Shell reading04Name SuperPlus attr Shell reading04Regex "price-type-name">SuperPlus<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Shell reading05Name ShellVPowerRacing attr Shell reading05Regex "price-type-name">Shell.V-Power.Racing<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Shell reading06Name ShellVPowerDiesel attr Shell reading06Regex "price-type-name">Shell.V-Power.Diesel<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Shell stateFormat E5: SuperE5, E10: SuperE10, D: Diesel, SP: SuperPlus attr Shell timeout 5 define Total HTTPMOD http://www.clever-tanken.de/tankstelle_details/4870 600 attr Total enableControlSet 1 attr Total reading01Name Diesel attr Total reading01Regex "price-type-name">Diesel<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Total reading02Name SuperE5 attr Total reading02Regex "price-type-name">Super.E5<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Total reading03Name SuperE10 attr Total reading03Regex "price-type-name">Super.E10<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Total reading04Name SuperPlus attr Total reading04Regex "price-type-name">SuperPlus<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Total reading05Name LKWDiesel attr Total reading05Regex "price-type-name">LKW-Diesel<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Total reading06Name TESuperPlus attr Total reading06Regex "price-type-name">Total.Excellium.Super.Plus<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Total reading07Name TEDiesel attr Total reading07Regex "price-type-name">Total.Excellium.Diesel<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Total reading08Name Autogas attr Total reading08Regex "price-type-name">Autogas<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Total reading09Name Erdgas attr Total reading09Regex "price-type-name">Erdgas<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Total reading10Name Wasserstoff attr Total reading10Regex "price-type-name">Wasserstoff<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Total stateFormat E5: SuperE5, E10: SuperE10, D: Diesel, SP: SuperPlus attr Total timeout 5 define Aral HTTPMOD http://www.clever-tanken.de/tankstelle_details/4869 600 attr Aral enableControlSet 1 attr Aral reading01Name Diesel attr Aral reading01Regex "price-type-name">Diesel<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Aral reading02Name SuperE5 attr Aral reading02Regex "price-type-name">Super.E5<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Aral reading03Name SuperE10 attr Aral reading03Regex "price-type-name">Super.E10<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Aral reading04Name AralSuperPlus attr Aral reading04Regex "price-type-name">ARAL.Superplus<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Aral reading05Name Autogas attr Aral reading05Regex "price-type-name">Autogas<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Aral reading06Name AralUltimate102 attr Aral reading06Regex "price-type-name">ARAL.Ultimate.102<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Aral reading07Name ARALUltimateDiesel attr Aral reading07Regex "price-type-name">ARAL.Ultimate.Diesel<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Aral stateFormat E5: SuperE5, E10: SuperE10, D: Diesel, SP: AralSuperPlus attr Aral timeout 5 define Esso HTTPMOD http://www.clever-tanken.de/tankstelle_details/17413 600 attr Esso enableControlSet 1 attr Esso reading01Name Diesel attr Esso reading01Regex "price-type-name">Diesel<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Esso reading02Name SuperE5 attr Esso reading02Regex "price-type-name">Super.E5<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Esso reading03Name SuperE10 attr Esso reading03Regex "price-type-name">Super.E10<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Esso reading04Name EssoSuperPlus attr Esso reading04Regex "price-type-name">Esso.Superplus<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Esso reading05Name Autogas attr Esso reading05Regex "price-type-name">Autogas<[\d\D]{600,900}"current-price-.">(\d.\d\d) attr Esso stateFormat E5: SuperE5, E10: SuperE10, D: Diesel, SP: EssoSuperPlus attr Esso timeout 5
Wer die Anzeige der Benzinpreise inklusive der obligatorisch abschließenden "9" möchte, muss zu jedem readingsName einen entsprechenden Zusatzzeile hinzufügen:
# Addiert zum Wert ($val) des Readings (readingsName_Diesel) den Wert 0.009 attr Shell reading01OExpr $val + 0.009
Diese Zeile fügt dem Dieselpreis der Shell-Tankstelle bei einem Literpreis von 1.29 die Ziffer "9" hinzu und ergibt 1.299.
Dieses feste Konstrukt, dass man einfach die 0.009 addiert, kann man auch dynamisch erzeugen.
Ich habe dazu beim RegEx eine zweite Capture Gruppe definiert. Dadurch entstehen jeweils zwei Readings mit dem jeweiligen Kraftstoffnamen und den Suffixen "-1" und "-2". Der neu dazu gekommene Wert wird dann noch durch 1000 dividiert. In einem userReading (mit dem ursprünglichen Kraftstoffnamen - also ohne das Suffix) werden dann beide Werte summiert.
Dazu hier mal eine Beispielkonfiguration:
define Tankstelle_Agip HTTPMOD http://www.clever-tanken.de/tankstelle_details/34459 900 attr Tankstelle_Agip alignTime 00:00 attr Tankstelle_Agip enableControlSet 1 attr Tankstelle_Agip event-on-change-reading SuperE5.*,SuperE10.*,Diesel.*,SuperPlus.* attr Tankstelle_Agip reading01-2OExpr $val/1000 attr Tankstelle_Agip reading01Name SuperE5 attr Tankstelle_Agip reading01Regex "price-type-name">Super.E5<[\d\D]{200,900}"current-price-\d">(\d.\d\d)<[\d\D]{40,60}"suffix-price-\d">(\d) attr Tankstelle_Agip reading02-2OExpr $val/1000 attr Tankstelle_Agip reading02Name SuperE10 attr Tankstelle_Agip reading02Regex "price-type-name">Super.E10<[\d\D]{700,900}"current-price-\d">(\d.\d\d)<[\d\D]{40,60}"suffix-price-\d">(\d) attr Tankstelle_Agip reading03-2OExpr $val/1000 attr Tankstelle_Agip reading03Name Diesel attr Tankstelle_Agip reading03Regex "price-type-name">Diesel<[\d\D]{700,900}"current-price-\d">(\d.\d\d)<[\d\D]{40,60}"suffix-price-\d">(\d) attr Tankstelle_Agip reading04-2OExpr $val/1000 attr Tankstelle_Agip reading04Name SuperPlus attr Tankstelle_Agip reading04Regex "price-type-name">SuperPlus<[\d\D]{200,900}"current-price-\d">(\d.\d\d)<[\d\D]{40,60}"suffix-price-\d">(\d) attr Tankstelle_Agip reading05Name street attr Tankstelle_Agip reading05Regex "streetAddress">(.*)< attr Tankstelle_Agip reading06Name zip attr Tankstelle_Agip reading06Regex "http://schema.org/postalCode">(.*)< attr Tankstelle_Agip reading07Name city attr Tankstelle_Agip reading07Regex "http://schema.org/addressCountry">(.*)< attr Tankstelle_Agip stateFormat E5: SuperE5, E10: SuperE10, SP: SuperPlus, D: Diesel attr Tankstelle_Agip timeout 10 attr Tankstelle_Agip userReadings SuperE5:SuperE5-.* {ReadingsNum($name,"SuperE5-1",0)+ReadingsNum($name,"SuperE5-2",0)},\ SuperE10:SuperE10-.* {ReadingsNum($name,"SuperE10-1",0)+ReadingsNum($name,"SuperE10-2",0)},\ SuperPlus:SuperPlus-.* {ReadingsNum($name,"SuperPlus-1",0)+ReadingsNum($name,"SuperPlus-2",0)},\ Diesel:Diesel-.* {ReadingsNum($name,"Diesel-1",0)+ReadingsNum($name,"Diesel-2",0)}
Dazu kommen noch die Definitionen für das FileLog:
define FileLog_Spritpreise FileLog /media/usblog/fhem/log/spritpreise-langen-%Y-%m.log (Shell|Total|Aral):(SuperE5|Diesel).* attr FileLog_Spritpreise alias Log Spritpreise attr FileLog_Spritpreise group Logfile attr FileLog_Spritpreise logtype text attr FileLog_Spritpreise room Spritpreise
Sowie eine passende readingsGroup:
define Spritpreise readingsGroup (Shell|Total|Aral):(SuperE5|Diesel).* attr Spritpreise group Spritpreisuebersicht attr Spritpreise notime 1 attr Spritpreise room Spritpreise #attr Spritpreise style style="font-size:16px" # führt ggf. zu einem PERL WARNING attr Spritpreise valueFormat {'%.2f €'} #attr Spritpreise valueStyle {Werte($READING,$VALUE)} # führt ggf. zu einem PERL WARNING
Eine etwas andere readingsGroup, passend zu der Definition "Tankstelle_Agip" mit farblicher Hervorhebung des Tiefstpreises und hochgestellter letzter Ziffer.
define rg_Benzinpreise readingsGroup <Tankstelle>,<Diesel>,<Super E5>,<Super E10>,<Super Plus>,<PLZ>,<Ort>,<Straße> Tankstelle_.*:Diesel,SuperE5,SuperE10,SuperPlus,zip,city,street attr rg_Benzinpreise alias Benzinpreisübersicht attr rg_Benzinpreise cellStyle {"r:1" => 'style="font-weight:bold"'} attr rg_Benzinpreise valueFormat {"$1<sup>$2</sup> €" if ($READING=~/^Super|Diesel/ && $VALUE=~/^(\d\.\d\d)(\d)$/)} attr rg_Benzinpreise valueStyle {'style="color:red"' if ($READING=~/^Super|Diesel/ && $VALUE eq BenzinLP($READING))}
Und eine Plotdefinition
define SVG_FileLog_Spritpreise_1 SVG FileLog_Spritpreise:SVG_FileLog_Spritpreise_1:CURRENT attr SVG_FileLog_Spritpreise_1 group Spritpreisverlauf attr SVG_FileLog_Spritpreise_1 room Spritpreise
Farbliche Hervorhebung
Folgender Code gehört in 99_myUtils.pm; die Werte können natürlich entsprechend eigener Wünsche und Vorlieben angepasst werden.
################################################### ### Spritpreisübersicht - Farbsortierung ### ################################################### sub Werte($$) { my ($name, $wert) = @_; # Log(3,"$name $wert"); if ($name eq "Diesel") { return 'style="color:red"' if($wert >= 1.39); return 'style="color:blue"' if(($wert >= 1.33) && ($wert < 1.39)); return 'style="color:green;;font-weight:bold"' if($wert <= 1.32); }elsif ($name eq "SuperE10") { return 'style="color:crimson"' if($wert >= 1.70); return 'style="color:yellow"' if(($wert >= 1.55) && ($wert < 1.70)); return 'style="color:lightgreen;;font-weight:bold"' if($wert < 1.55); }elsif ($name eq "SuperE5") { return 'style="color:red"' if($wert >= 1.59); return 'style="color:blue"' if(($wert >= 1.49) && ($wert < 1.59)); return 'style="color:green;;font-weight:bold"' if($wert <= 1.48); } } ####################################################################################### ### Funktion für Ermittlung vom niedrigsten Preis für readingsGroup rg_Benzinpreise ### ####################################################################################### # damit die Funktion richtig funktioniert müssen alle Tankstellenname mit "Tankstelle_" beginnen # oder entsprechend das devspec2array auf die eigenen Namen anpassen sub BenzinLP($) { my ($r) = @_; return (sort map {ReadingsNum($_,$r,0)} devspec2array("Tankstelle_.*"))[0]; }
Die zugehörige .gplot Datei
SVG_FileLog_Spritpreise_1.gplot
# Created by FHEM/98_SVG.pm, 2014-10-22 12:57:34 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 'Spritpreise' set ytics set y2tics set grid set ylabel "Preise (€/Liter)" set y2label "Preise (€/Liter)" #FileLog 4:Aral.Diesel\x3a:1: #FileLog 4:Shell.Diesel\x3a:1: #FileLog 4:Total.Diesel\x3a:1: #FileLog 4:Aral.SuperE5\x3a:1: #FileLog 4:Shell.SuperE5\x3a:1: #FileLog 4:Total.SuperE5\x3a:1: plot "<IN>" using 1:2 axes x1y2 title 'Aral Diesel' ls l2 lw 1 with lines,\ "<IN>" using 1:2 axes x1y2 title 'Shell Diesel' ls l1 lw 1 with lines,\ "<IN>" using 1:2 axes x1y2 title 'Total Diesel' ls l0 lw 1 with lines,\ "<IN>" using 1:2 axes x1y2 title 'Aral Super' ls l3 lw 1 with lines,\ "<IN>" using 1:2 axes x1y2 title 'Shell Super' ls l4 lw 1 with lines,\ "<IN>" using 1:2 axes x1y2 title 'Total Super' ls l5 lw 1 with lines
Tricks für HTTPMOD
Je nach Internetverbindung und Geschwindigkeit des FHEM Rechners kann das Modul manchmal Probleme haben, die Daten schnell genug zu verarbeiten.
Eine Lösung dazu wäre, die Daten vorher mit wget auf einem eigenen Webserver zu speichern (z.B. ein lokaler Apache) und HTTPMOD auf diesen zugreifen zu lassen.
Links
- Vorstellung und Diskussion im FHEM Forum
- Der "Datenlieferant": Clever Tanken
- Eine Anleitung, wie man das mit wget macht, gibt es hier (ist aber noch nicht ganz fertig)
- Umsetzung für Tankerkönig API