Spritpreismonitor: Unterschied zwischen den Versionen

Aus FHEMWiki
KKeine Bearbeitungszusammenfassung
(grundlegende Überarbeitungen)
Zeile 1: Zeile 1:
Die hier vorgestellten Fragmente ermöglichen es, mit Hilfe von [[HTTPMOD]] bei [http://www.clever-tanken.de clever-tanken.de] von Wunschtankstellen die Spritpreise zu protokollieren. Die Credits dafür gehen an Forum-Benutzer {{Link2FU|1774|Phil__}}. Die Original Diskussion im Forum ist {{Link2Forum|Topic=22554|Message=210795|LinkText=hier}}.
Die hier vorgestellten Geräte-Definitionen ermöglichen es, mit Hilfe von [[HTTPMOD]] bei [http://www.clever-tanken.de clever-tanken.de] die Kraftstoffpreise von gewünschten Tankstellen zu protokollieren. Die Credits dafür gehen an Forum-Benutzer {{Link2FU|1774|Phil__}}. Die Original Diskussion im Forum ist {{Link2Forum|Topic=22554|Message=210795|LinkText=hier}}.


Alternativ können die Kraftstoffpreise auch über die Webseite tankerkönig.de bezogen werden. Die Vorgehensweise dafür ist im Detail in [http://www.cyberwulf.de/2016/fhem-spritpreise-von-tankerkoenig-de/ diesem Blog] beschrieben.
Alternativ dazu können die Kraftstoffpreise auch über die Webseite tankerkönig.de bezogen werden. Die Vorgehensweise dafür ist im Detail in [http://www.cyberwulf.de/2016/fhem-spritpreise-von-tankerkoenig-de/ diesem Blog] beschrieben.


== Einleitung ==
== Einleitung ==


Im folgenden wird mit Hilfe des Moduls HTTPMOD der Spritpreis von ausgewählten Tankstellen abgerufen. Die Daten werden [[Regulärer Ausdruck|gefiltert]], gespeichert und als Diagramm aufbereitet.
Im Folgenden wird mit Hilfe des Moduls HTTPMOD der Kraftstoffpreis von ausgewählten Tankstellen abgerufen. Die Daten werden [[Regulärer Ausdruck|gefiltert]], gespeichert und als Diagramm aufbereitet.


Zum Nachbau ist es erforderlich, "seine" Wunschtankstellen bei Clever-Tanken zu suchen. Jede Tankstelle hat eine eigene Nummer:
Zum Nachbau ist es erforderlich, die persönlich gewünschten Tankstellen bei Clever-Tanken zu suchen. Jede Tankstelle hat eine eigene Nummer:
:<code>/tankstelle_details/0815</code>
:<code>/tankstelle_details/0815</code>


Zeile 13: Zeile 13:


== Konfiguration ==
== 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:
Die erforderlichen Definitionen in der FHEM [[Konfiguration]] bestehen aus mehreren Teilen. Zunächst die erforderlichen Einstellungen um die Daten der gewünschten Tankstellen abzuholen.


Beispielkonfiguration für eine Shell Tankstelle inkl. Sondersorten:
<pre>
<pre>
define Shell HTTPMOD http://www.clever-tanken.de/tankstelle_details/4871 600
define Tankstelle_Shell HTTPMOD http://www.clever-tanken.de/tankstelle_details/4871 600
attr Shell enableControlSet 1
attr Tankstelle_Shell alignTime 00:00
attr Shell reading01Name Diesel
attr Tankstelle_Shell enableControlSet 1
attr Shell reading01Regex "price-type-name">Diesel<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Shell reading01Name Diesel
attr Shell reading02Name SuperE5
attr Tankstelle_Shell reading01Regex "price-type-name">Diesel<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Shell reading02Regex "price-type-name">Super.E5<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Shell reading02Name SuperE5
attr Shell reading03Name SuperE10
attr Tankstelle_Shell reading02Regex "price-type-name">Super.E5<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Shell reading03Regex "price-type-name">Super.E10<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Shell reading03Name SuperE10
attr Shell reading04Name SuperPlus
attr Tankstelle_Shell reading03Regex "price-type-name">Super.E10<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Shell reading04Regex "price-type-name">SuperPlus<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Shell reading04Name SuperPlus
attr Shell reading05Name ShellVPowerRacing
attr Tankstelle_Shell reading04Regex "price-type-name">SuperPlus<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Shell reading05Regex "price-type-name">Shell.V-Power.Racing<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Shell reading05Name ShellVPowerRacing
attr Shell reading06Name ShellVPowerDiesel
attr Tankstelle_Shell reading05Regex "price-type-name">Shell.V-Power.Racing<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Shell reading06Regex "price-type-name">Shell.V-Power.Diesel<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Shell reading06Name ShellVPowerDiesel
attr Shell stateFormat E5: SuperE5, E10: SuperE10, D: Diesel, SP: SuperPlus
attr Tankstelle_Shell reading06Regex "price-type-name">Shell.V-Power.Diesel<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Shell timeout 5
attr Tankstelle_Shell stateFormat E5: SuperE5, E10: SuperE10, D: Diesel, SP: SuperPlus
attr Tankstelle_Shell timeout 10
</pre>


define Total HTTPMOD http://www.clever-tanken.de/tankstelle_details/4870 600
Beispielkonfiguration für eine Total Tankstelle inkl. Sondersorten:
attr Total enableControlSet 1
<pre>
attr Total reading01Name Diesel
define Tankstelle_Total HTTPMOD http://www.clever-tanken.de/tankstelle_details/4870 600
attr Total reading01Regex "price-type-name">Diesel<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Total alignTime 00:00
attr Total reading02Name SuperE5
attr Tankstelle_Total enableControlSet 1
attr Total reading02Regex "price-type-name">Super.E5<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Total reading01Name Diesel
attr Total reading03Name SuperE10
attr Tankstelle_Total reading01Regex "price-type-name">Diesel<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Total reading03Regex "price-type-name">Super.E10<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Total reading02Name SuperE5
attr Total reading04Name SuperPlus
attr Tankstelle_Total reading02Regex "price-type-name">Super.E5<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Total reading04Regex "price-type-name">SuperPlus<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Total reading03Name SuperE10
attr Total reading05Name LKWDiesel
attr Tankstelle_Total reading03Regex "price-type-name">Super.E10<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Total reading05Regex "price-type-name">LKW-Diesel<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Total reading04Name SuperPlus
attr Total reading06Name TESuperPlus
attr Tankstelle_Total reading04Regex "price-type-name">SuperPlus<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Total reading06Regex "price-type-name">Total.Excellium.Super.Plus<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Total reading05Name LKWDiesel
attr Total reading07Name TEDiesel
attr Tankstelle_Total reading05Regex "price-type-name">LKW-Diesel<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Total reading07Regex "price-type-name">Total.Excellium.Diesel<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Total reading06Name TESuperPlus
attr Total reading08Name Autogas
attr Tankstelle_Total reading06Regex "price-type-name">Total.Excellium.Super.Plus<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Total reading08Regex "price-type-name">Autogas<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Total reading07Name TEDiesel
attr Total reading09Name Erdgas
attr Tankstelle_Total reading07Regex "price-type-name">Total.Excellium.Diesel<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Total reading09Regex "price-type-name">Erdgas<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Total reading08Name Autogas
attr Total reading10Name Wasserstoff
attr Tankstelle_Total reading08Regex "price-type-name">Autogas<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Total reading10Regex "price-type-name">Wasserstoff<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Total reading09Name Erdgas
attr Total stateFormat E5: SuperE5, E10: SuperE10, D: Diesel, SP: SuperPlus
attr Tankstelle_Total reading09Regex "price-type-name">Erdgas<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Total timeout 5
attr Tankstelle_Total reading10Name Wasserstoff
attr Tankstelle_Total reading10Regex "price-type-name">Wasserstoff<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Total stateFormat E5: SuperE5, E10: SuperE10, D: Diesel, SP: SuperPlus
attr Tankstelle_Total timeout 10
</pre>


define Aral HTTPMOD http://www.clever-tanken.de/tankstelle_details/4869 600
Beispielkonfiguration für eine Aral Tankstelle inkl. Sondersorten:
attr Aral enableControlSet 1
<pre>
attr Aral reading01Name Diesel
define Tankstelle_Aral HTTPMOD http://www.clever-tanken.de/tankstelle_details/4869 600
attr Aral reading01Regex "price-type-name">Diesel<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Aral alignTime 00:00
attr Aral reading02Name SuperE5
attr Tankstelle_Aral enableControlSet 1
attr Aral reading02Regex "price-type-name">Super.E5<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Aral reading01Name Diesel
attr Aral reading03Name SuperE10
attr Tankstelle_Aral reading01Regex "price-type-name">Diesel<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Aral reading03Regex "price-type-name">Super.E10<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Aral reading02Name SuperE5
attr Aral reading04Name AralSuperPlus
attr Tankstelle_Aral reading02Regex "price-type-name">Super.E5<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Aral reading04Regex "price-type-name">ARAL.Superplus<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Aral reading03Name SuperE10
attr Aral reading05Name Autogas
attr Tankstelle_Aral reading03Regex "price-type-name">Super.E10<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Aral reading05Regex "price-type-name">Autogas<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Aral reading04Name AralSuperPlus
attr Aral reading06Name AralUltimate102
attr Tankstelle_Aral reading04Regex "price-type-name">ARAL.Superplus<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Aral reading06Regex "price-type-name">ARAL.Ultimate.102<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Aral reading05Name Autogas
attr Aral reading07Name ARALUltimateDiesel
attr Tankstelle_Aral reading05Regex "price-type-name">Autogas<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Aral reading07Regex "price-type-name">ARAL.Ultimate.Diesel<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Aral reading06Name AralUltimate102
attr Aral stateFormat E5: SuperE5, E10: SuperE10, D: Diesel, SP: AralSuperPlus
attr Tankstelle_Aral reading06Regex "price-type-name">ARAL.Ultimate.102<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Aral timeout 5
attr Tankstelle_Aral reading07Name ARALUltimateDiesel
attr Tankstelle_Aral reading07Regex "price-type-name">ARAL.Ultimate.Diesel<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Aral stateFormat E5: SuperE5, E10: SuperE10, D: Diesel, SP: AralSuperPlus
attr Tankstelle_Aral timeout 10
</pre>


define Esso HTTPMOD http://www.clever-tanken.de/tankstelle_details/17413 600
Beispielkonfiguration für eine Esso Tankstelle inkl. Sondersorten:
attr Esso enableControlSet 1
<pre>
attr Esso reading01Name Diesel
define Tankstelle_Esso HTTPMOD http://www.clever-tanken.de/tankstelle_details/17413 600
attr Esso reading01Regex "price-type-name">Diesel<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Esso alignTime 00:00
attr Esso reading02Name SuperE5
attr Tankstelle_Esso enableControlSet 1
attr Esso reading02Regex "price-type-name">Super.E5<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Esso reading01Name Diesel
attr Esso reading03Name SuperE10
attr Tankstelle_Esso reading01Regex "price-type-name">Diesel<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Esso reading03Regex "price-type-name">Super.E10<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Esso reading02Name SuperE5
attr Esso reading04Name EssoSuperPlus
attr Tankstelle_Esso reading02Regex "price-type-name">Super.E5<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Esso reading04Regex "price-type-name">Esso.Superplus<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Esso reading03Name SuperE10
attr Esso reading05Name Autogas
attr Tankstelle_Esso reading03Regex "price-type-name">Super.E10<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Esso reading05Regex "price-type-name">Autogas<[\d\D]{600,900}"current-price-.">(\d.\d\d)
attr Tankstelle_Esso reading04Name EssoSuperPlus
attr Esso stateFormat E5: SuperE5, E10: SuperE10, D: Diesel, SP: EssoSuperPlus
attr Tankstelle_Esso reading04Regex "price-type-name">Esso.Superplus<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Esso timeout 5
attr Tankstelle_Esso reading05Name Autogas
attr Tankstelle_Esso reading05Regex "price-type-name">Autogas<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Esso stateFormat E5: SuperE5, E10: SuperE10, D: Diesel, SP: EssoSuperPlus
attr Tankstelle_Esso timeout 10
</pre>
</pre>


Wer die Anzeige der Benzinpreise inklusive der obligatorisch abschließenden "9" möchte, muss zu jedem readingsName einen entsprechenden Zusatzzeile hinzufügen:


Wer die Anzeige der Kraftstoffpreise inklusive der obligatorischen abschließenden "9" möchte, muss zu jedem readingXXName eine entsprechende Zusatzzeile hinzufügen. Diese addiert zum Wert des Readings (hier Diesel) den Wert 0.009:
<pre>
<pre>
# Addiert zum Wert ($val) des Readings (readingsName_Diesel) den Wert 0.009
attr Tankstelle_Shell reading01OExpr $val+0.009
attr Shell reading01OExpr $val + 0.009
</pre>
</pre>


Diese Zeile fügt dem Dieselpreis der Shell-Tankstelle bei einem Literpreis von 1.29 die Ziffer "9" hinzu und ergibt 1.299.
Diese Zeile fügt dem Dieselpreis der Shell Tankstelle bei einem Literpreis von 1.29 die (normalerweise hochgestellte) Ziffer "9" hinzu und ergibt somit 1.299.


Dieses feste Konstrukt, dass man einfach die 0.009 addiert, kann man auch dynamisch erzeugen.<br/>
Dieses starre Konstrukt kann man allerdings 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:
Dazu wird beim RegEx eine zweite Capture Gruppe definiert. Dadurch entstehen immer zwei Readings mit dem jeweiligen Kraftstoffnamen und den Suffixen "-1" und "-2". Der neu dazu gekommene (2.) Wert wird dann noch mit dem Attribut reading0X-2OExpr durch 1000 dividiert. In entsprechenden userReadings (mit dem ursprünglichen Kraftstoffnamen - also ohne die Suffixe) werden dann beide Werte summiert.
 
Dazu hier mal eine Beispielkonfiguration für eine Agip Tankstelle, bei der auch die Straße, die Postleitzahl und die Stadt mit ausgelesen wird:
<pre>
<pre>
define Tankstelle_Agip HTTPMOD http://www.clever-tanken.de/tankstelle_details/34459 900
define Tankstelle_Agip HTTPMOD http://www.clever-tanken.de/tankstelle_details/34459 600
attr Tankstelle_Agip alignTime 00:00
attr Tankstelle_Agip alignTime 00:00
attr Tankstelle_Agip enableControlSet 1
attr Tankstelle_Agip enableControlSet 1
Zeile 137: Zeile 152:




Dazu kommen noch die Definitionen für das [[FileLog]]:
Eine passende [[readingsGroup]] mit farblicher Hervorhebung der Krafstoffpreise:
<pre>
<pre>
define FileLog_Spritpreise FileLog /media/usblog/fhem/log/spritpreise-langen-%Y-%m.log (Shell|Total|Aral):(SuperE5|Diesel).*
define Kraftstoffpreise readingsGroup Tankstelle_*:(Super|Diesel).*
attr FileLog_Spritpreise alias Log Spritpreise
attr Kraftstoffpreise notime 1
attr FileLog_Spritpreise group Logfile
#attr Kraftstoffpreise style style="font-size:16px"    # führt ggf. zu einem PERL WARNING
attr FileLog_Spritpreise logtype text
attr Kraftstoffpreise valueFormat {'%.2f €'}
attr FileLog_Spritpreise room Spritpreise
#attr Kraftstoffpreise valueStyle {KraftstoffWerte($READING,$VALUE)}    # führt ggf. zu einem PERL WARNING
</pre>
</pre>


 
Eine etwas andere [[readingsGroup]] mit farblicher Hervorhebung des Tiefstpreises der jeweiligen Kraftstoffsorte und hochgestellter letzter Ziffer beim Kraftstoffpreis:
Sowie eine passende [[readingsGroup]]:
<pre>
<pre>
define Spritpreise readingsGroup (Shell|Total|Aral):(SuperE5|Diesel).*
define rg_Kraftstoffpreise readingsGroup <Tankstelle>,<Diesel>,<Super E5>,<Super E10>,<Super Plus>,<PLZ>,<Ort>,<Straße> Tankstelle_.*:Diesel,SuperE5,SuperE10,SuperPlus,zip,city,street
attr Spritpreise group Spritpreisuebersicht
attr rg_Kraftstoffpreise alias Kraftstoffpreisübersicht
attr Spritpreise notime 1
attr rg_Kraftstoffpreise cellStyle {"r:1" => 'style="font-weight:bold"'}
attr Spritpreise room Spritpreise
attr rg_Kraftstoffpreise valueFormat {"$1<sup>$2</sup> €" if ($READING=~/^Super|Diesel/ && $VALUE=~/^(\d\.\d\d)(\d)$/)}
#attr Spritpreise style style="font-size:16px"     # führt ggf. zu einem PERL WARNING
attr rg_Kraftstoffpreise valueStyle {'style="color:green;;font-weight:bold"' if ($READING=~/^Super|Diesel/ && $VALUE eq KraftstoffLP($READING))}
attr Spritpreise valueFormat {'%.2f €'}
#attr Spritpreise valueStyle {Werte($READING,$VALUE)}     # führt ggf. zu einem PERL WARNING
</pre>
</pre>


Eine etwas andere [[readingsGroup]], passend zu der Definition "Tankstelle_Agip" mit farblicher Hervorhebung des Tiefstpreises und hochgestellter letzter Ziffer.
 
Hier noch eine mögliche Definition für das [[FileLog]]. Es werden von allen definierten Tankstellen (Namen beginnend mit "Tankstelle_") die Werte für Super und Diesel gespeichert:
<pre>
<pre>
define rg_Benzinpreise readingsGroup <Tankstelle>,<Diesel>,<Super E5>,<Super E10>,<Super Plus>,<PLZ>,<Ort>,<Straße> Tankstelle_.*:Diesel,SuperE5,SuperE10,SuperPlus,zip,city,street
define FileLog_Kraftstoffpreise FileLog ./log/Kraftstoffpreise-%Y-%m.log Tankstelle_.*:(Super|Diesel).*
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:green;;font-weight:bold"' if ($READING=~/^Super|Diesel/ && $VALUE eq BenzinLP($READING))}
</pre>
</pre>


Zeile 170: Zeile 179:
Und eine [[SVG|Plotdefinition]]
Und eine [[SVG|Plotdefinition]]
<pre>
<pre>
define SVG_FileLog_Spritpreise_1 SVG FileLog_Spritpreise:SVG_FileLog_Spritpreise_1:CURRENT
define SVG_FileLog_Kraftstoffpreise_1 SVG FileLog_Kraftstoffpreise:SVG_FileLog_Kraftstoffpreise_1:CURRENT
attr SVG_FileLog_Spritpreise_1 group Spritpreisverlauf
attr SVG_FileLog_Spritpreise_1 room Spritpreise
</pre>
</pre>


== Farbliche Hervorhebung ==
== Farbliche Hervorhebung ==
Folgender Code gehört in [[99 myUtils anlegen|99_myUtils.pm]]; die Werte können natürlich entsprechend eigener Wünsche und Vorlieben angepasst werden.
Folgender Code kommt in [[99 myUtils anlegen|99_myUtils.pm]]; die Werte können natürlich entsprechend eigener Wünsche und Vorlieben angepasst werden.
<pre>
<pre>
###################################################
########################################################
###    Spritpreisübersicht - Farbsortierung    ###
###    Kraftstoffpreisübersicht - Farbsortierung    ###
###################################################
########################################################


sub Werte($$) {
sub KraftstoffWerte($$) {
   my ($name, $wert) = @_;
   my ($name,$wert) = @_;
# Log(3,"$name $wert");
# Log(3,"$name $wert");
   if ($name eq "Diesel") {
   if ($name eq "Diesel") {
Zeile 189: Zeile 196:
     return 'style="color:blue"' if(($wert >= 1.33) && ($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);
     return 'style="color:green;;font-weight:bold"' if($wert <= 1.32);
   }elsif ($name eq "SuperE10") {
   } elsif ($name eq "SuperE10") {
     return 'style="color:crimson"' if($wert >= 1.70);  
     return 'style="color:crimson"' if($wert >= 1.70);  
     return 'style="color:yellow"' if(($wert >= 1.55) && ($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);
     return 'style="color:lightgreen;;font-weight:bold"' if($wert < 1.55);
   }elsif ($name eq "SuperE5") {
   } elsif ($name eq "SuperE5") {
     return 'style="color:red"' if($wert >= 1.59);  
     return 'style="color:red"' if($wert >= 1.59);  
     return 'style="color:blue"' if(($wert >= 1.49) && ($wert < 1.59));
     return 'style="color:blue"' if(($wert >= 1.49) && ($wert < 1.59));
Zeile 200: Zeile 207:
}
}


#######################################################################################
###########################################################################################
### Funktion für Ermittlung vom niedrigsten Preis für readingsGroup rg_Benzinpreise ###
### Funktion für Ermittlung vom niedrigsten Preis für readingsGroup rg_Kraftstoffpreise ###
#######################################################################################
###########################################################################################
# damit die Funktion richtig funktioniert müssen alle Tankstellennamen mit "Tankstelle_"
# damit die Funktion richtig funktioniert müssen alle Tankstellennamen mit "Tankstelle_"
# beginnen oder entsprechend devspec2array auf die eigenen Namen anpassen
# beginnen oder entsprechend devspec2array auf die eigenen Namen anpassen


sub BenzinLP($) {
sub KraftstoffLP($) {
   my ($r) = @_;
   my ($r) = @_;
   return (sort map {ReadingsNum($_,$r,999)} devspec2array("Tankstelle_.*"))[0];
   return (sort map {ReadingsNum($_,$r,999)} devspec2array("Tankstelle_.*"))[0];
}
}
</pre>
</pre>


=== Die zugehörige .gplot Datei ===
=== Die zugehörige .gplot Datei ===
SVG_FileLog_Spritpreise_1.gplot
SVG_FileLog_Kraftstoffpreise_1.gplot
<pre>
<pre>
# Created by FHEM/98_SVG.pm, 2014-10-22 12:57:34
# Created by FHEM/98_SVG.pm, 2014-10-22 12:57:34
Zeile 221: Zeile 229:
set timefmt "%Y-%m-%d_%H:%M:%S"
set timefmt "%Y-%m-%d_%H:%M:%S"
set xlabel " "
set xlabel " "
set title 'Spritpreise'
set title 'Kraftstoffpreise'
set ytics  
set ytics  
set y2tics  
set y2tics  
Zeile 242: Zeile 250:
     "<IN>" using 1:2 axes x1y2 title 'Total Super' ls l5 lw 1 with lines
     "<IN>" using 1:2 axes x1y2 title 'Total Super' ls l5 lw 1 with lines
</pre>
</pre>


== Tricks für HTTPMOD ==
== Tricks für HTTPMOD ==
Zeile 247: Zeile 256:


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.  
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 ==
== Links ==

Version vom 8. Februar 2021, 22:39 Uhr

Die hier vorgestellten Geräte-Definitionen ermöglichen es, mit Hilfe von HTTPMOD bei clever-tanken.de die Kraftstoffpreise von gewünschten Tankstellen zu protokollieren. Die Credits dafür gehen an Forum-Benutzer Phil__ . Die Original Diskussion im Forum ist hier.

Alternativ dazu 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 Kraftstoffpreis von ausgewählten Tankstellen abgerufen. Die Daten werden gefiltert, gespeichert und als Diagramm aufbereitet.

Zum Nachbau ist es erforderlich, die persönlich gewünschten Tankstellen 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.

Beispielkonfiguration für eine Shell Tankstelle inkl. Sondersorten:

define Tankstelle_Shell HTTPMOD http://www.clever-tanken.de/tankstelle_details/4871 600
attr Tankstelle_Shell alignTime 00:00
attr Tankstelle_Shell enableControlSet 1
attr Tankstelle_Shell reading01Name Diesel
attr Tankstelle_Shell reading01Regex "price-type-name">Diesel<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Shell reading02Name SuperE5
attr Tankstelle_Shell reading02Regex "price-type-name">Super.E5<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Shell reading03Name SuperE10
attr Tankstelle_Shell reading03Regex "price-type-name">Super.E10<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Shell reading04Name SuperPlus
attr Tankstelle_Shell reading04Regex "price-type-name">SuperPlus<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Shell reading05Name ShellVPowerRacing
attr Tankstelle_Shell reading05Regex "price-type-name">Shell.V-Power.Racing<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Shell reading06Name ShellVPowerDiesel
attr Tankstelle_Shell reading06Regex "price-type-name">Shell.V-Power.Diesel<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Shell stateFormat E5: SuperE5, E10: SuperE10, D: Diesel, SP: SuperPlus
attr Tankstelle_Shell timeout 10

Beispielkonfiguration für eine Total Tankstelle inkl. Sondersorten:

define Tankstelle_Total HTTPMOD http://www.clever-tanken.de/tankstelle_details/4870 600
attr Tankstelle_Total alignTime 00:00
attr Tankstelle_Total enableControlSet 1
attr Tankstelle_Total reading01Name Diesel
attr Tankstelle_Total reading01Regex "price-type-name">Diesel<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Total reading02Name SuperE5
attr Tankstelle_Total reading02Regex "price-type-name">Super.E5<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Total reading03Name SuperE10
attr Tankstelle_Total reading03Regex "price-type-name">Super.E10<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Total reading04Name SuperPlus
attr Tankstelle_Total reading04Regex "price-type-name">SuperPlus<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Total reading05Name LKWDiesel
attr Tankstelle_Total reading05Regex "price-type-name">LKW-Diesel<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Total reading06Name TESuperPlus
attr Tankstelle_Total reading06Regex "price-type-name">Total.Excellium.Super.Plus<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Total reading07Name TEDiesel
attr Tankstelle_Total reading07Regex "price-type-name">Total.Excellium.Diesel<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Total reading08Name Autogas
attr Tankstelle_Total reading08Regex "price-type-name">Autogas<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Total reading09Name Erdgas
attr Tankstelle_Total reading09Regex "price-type-name">Erdgas<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Total reading10Name Wasserstoff
attr Tankstelle_Total reading10Regex "price-type-name">Wasserstoff<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Total stateFormat E5: SuperE5, E10: SuperE10, D: Diesel, SP: SuperPlus
attr Tankstelle_Total timeout 10

Beispielkonfiguration für eine Aral Tankstelle inkl. Sondersorten:

define Tankstelle_Aral HTTPMOD http://www.clever-tanken.de/tankstelle_details/4869 600
attr Tankstelle_Aral alignTime 00:00
attr Tankstelle_Aral enableControlSet 1
attr Tankstelle_Aral reading01Name Diesel
attr Tankstelle_Aral reading01Regex "price-type-name">Diesel<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Aral reading02Name SuperE5
attr Tankstelle_Aral reading02Regex "price-type-name">Super.E5<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Aral reading03Name SuperE10
attr Tankstelle_Aral reading03Regex "price-type-name">Super.E10<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Aral reading04Name AralSuperPlus
attr Tankstelle_Aral reading04Regex "price-type-name">ARAL.Superplus<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Aral reading05Name Autogas
attr Tankstelle_Aral reading05Regex "price-type-name">Autogas<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Aral reading06Name AralUltimate102
attr Tankstelle_Aral reading06Regex "price-type-name">ARAL.Ultimate.102<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Aral reading07Name ARALUltimateDiesel
attr Tankstelle_Aral reading07Regex "price-type-name">ARAL.Ultimate.Diesel<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Aral stateFormat E5: SuperE5, E10: SuperE10, D: Diesel, SP: AralSuperPlus
attr Tankstelle_Aral timeout 10

Beispielkonfiguration für eine Esso Tankstelle inkl. Sondersorten:

define Tankstelle_Esso HTTPMOD http://www.clever-tanken.de/tankstelle_details/17413 600
attr Tankstelle_Esso alignTime 00:00
attr Tankstelle_Esso enableControlSet 1
attr Tankstelle_Esso reading01Name Diesel
attr Tankstelle_Esso reading01Regex "price-type-name">Diesel<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Esso reading02Name SuperE5
attr Tankstelle_Esso reading02Regex "price-type-name">Super.E5<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Esso reading03Name SuperE10
attr Tankstelle_Esso reading03Regex "price-type-name">Super.E10<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Esso reading04Name EssoSuperPlus
attr Tankstelle_Esso reading04Regex "price-type-name">Esso.Superplus<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Esso reading05Name Autogas
attr Tankstelle_Esso reading05Regex "price-type-name">Autogas<[\d\D]{600,900}"current-price-\d">(\d.\d\d)
attr Tankstelle_Esso stateFormat E5: SuperE5, E10: SuperE10, D: Diesel, SP: EssoSuperPlus
attr Tankstelle_Esso timeout 10


Wer die Anzeige der Kraftstoffpreise inklusive der obligatorischen abschließenden "9" möchte, muss zu jedem readingXXName eine entsprechende Zusatzzeile hinzufügen. Diese addiert zum Wert des Readings (hier Diesel) den Wert 0.009:

attr Tankstelle_Shell reading01OExpr $val+0.009

Diese Zeile fügt dem Dieselpreis der Shell Tankstelle bei einem Literpreis von 1.29 die (normalerweise hochgestellte) Ziffer "9" hinzu und ergibt somit 1.299.

Dieses starre Konstrukt kann man allerdings auch dynamisch erzeugen.

Dazu wird beim RegEx eine zweite Capture Gruppe definiert. Dadurch entstehen immer zwei Readings mit dem jeweiligen Kraftstoffnamen und den Suffixen "-1" und "-2". Der neu dazu gekommene (2.) Wert wird dann noch mit dem Attribut reading0X-2OExpr durch 1000 dividiert. In entsprechenden userReadings (mit dem ursprünglichen Kraftstoffnamen - also ohne die Suffixe) werden dann beide Werte summiert.

Dazu hier mal eine Beispielkonfiguration für eine Agip Tankstelle, bei der auch die Straße, die Postleitzahl und die Stadt mit ausgelesen wird:

define Tankstelle_Agip HTTPMOD http://www.clever-tanken.de/tankstelle_details/34459 600
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)}


Eine passende readingsGroup mit farblicher Hervorhebung der Krafstoffpreise:

define Kraftstoffpreise readingsGroup Tankstelle_*:(Super|Diesel).*
attr Kraftstoffpreise notime 1
#attr Kraftstoffpreise style style="font-size:16px"     # führt ggf. zu einem PERL WARNING
attr Kraftstoffpreise valueFormat {'%.2f €'}
#attr Kraftstoffpreise valueStyle {KraftstoffWerte($READING,$VALUE)}     # führt ggf. zu einem PERL WARNING

Eine etwas andere readingsGroup mit farblicher Hervorhebung des Tiefstpreises der jeweiligen Kraftstoffsorte und hochgestellter letzter Ziffer beim Kraftstoffpreis:

define rg_Kraftstoffpreise readingsGroup <Tankstelle>,<Diesel>,<Super E5>,<Super E10>,<Super Plus>,<PLZ>,<Ort>,<Straße> Tankstelle_.*:Diesel,SuperE5,SuperE10,SuperPlus,zip,city,street
attr rg_Kraftstoffpreise alias Kraftstoffpreisübersicht
attr rg_Kraftstoffpreise cellStyle {"r:1" => 'style="font-weight:bold"'}
attr rg_Kraftstoffpreise valueFormat {"$1<sup>$2</sup> €" if ($READING=~/^Super|Diesel/ && $VALUE=~/^(\d\.\d\d)(\d)$/)}
attr rg_Kraftstoffpreise valueStyle {'style="color:green;;font-weight:bold"' if ($READING=~/^Super|Diesel/ && $VALUE eq KraftstoffLP($READING))}


Hier noch eine mögliche Definition für das FileLog. Es werden von allen definierten Tankstellen (Namen beginnend mit "Tankstelle_") die Werte für Super und Diesel gespeichert:

define FileLog_Kraftstoffpreise FileLog ./log/Kraftstoffpreise-%Y-%m.log Tankstelle_.*:(Super|Diesel).*


Und eine Plotdefinition

define SVG_FileLog_Kraftstoffpreise_1 SVG FileLog_Kraftstoffpreise:SVG_FileLog_Kraftstoffpreise_1:CURRENT

Farbliche Hervorhebung

Folgender Code kommt in 99_myUtils.pm; die Werte können natürlich entsprechend eigener Wünsche und Vorlieben angepasst werden.

########################################################
###     Kraftstoffpreisübersicht - Farbsortierung    ###
########################################################

sub KraftstoffWerte($$) {
  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_Kraftstoffpreise ###
###########################################################################################
# damit die Funktion richtig funktioniert müssen alle Tankstellennamen mit "Tankstelle_"
# beginnen oder entsprechend devspec2array auf die eigenen Namen anpassen

sub KraftstoffLP($) {
  my ($r) = @_;
  return (sort map {ReadingsNum($_,$r,999)} devspec2array("Tankstelle_.*"))[0];
}


Die zugehörige .gplot Datei

SVG_FileLog_Kraftstoffpreise_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 'Kraftstoffpreise'
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