FHEM: Spritpreise von Tankerkönig.de einbinden

Tankerkönig.de bietet eine schöne API mit JSON Ausgabe an.
Um diese in FHEM einzubinden braucht mal als Erstes einen eigenen API Key. Den bekommt man kostenlos hier. Mit diesem ist dann der Zugriff auf die Daten von Tankerkönig möglich.

Um an die ID der Tankstelle zu gelangen gibt es mehrere Möglichkeiten.
Ich beschreibe hier mal einen von diesen Wegen über die Webseite:

  1. Auf Tankerkönig.de die PLZ oder den Ort eingeben
  2. Die Tankstelle aussuchen und anklicken
  3. Meldung anklicken –> öffnet eine neue Seite
  4. Die URL kopieren und in Notepad einfügen oder direkt die ID rauskopieren
    http://www.tankerkoenig.de/MTS-K-Complaints/Complaint.php?station={"id"%3A"cfe5f775-a134-4d0f-934c-2e3c03a27675"2C"isOpen":true,"prices":{"diesel_price":"0.989","e5_price":"1.239","e10_price":"1.199"},"name":"METTMANN, DÜSSELDORFERSTR.168.","brand":"Shell","street":"DÜSSELDORFERSTR. 168","houseNumber":"","postCode":"40822","place":"Mettmann","location":{"lat":51.2542,"lng":6.95995}}

    tankerkoenig_url

    Tankerkönig URL ID

    5. ID abspeichern brauchen wir ja im FHEM Script

In FHEM legen wir nun ein neues Device an, hier der vollständige Code:

define TS.Station HTTPMOD https://creativecommons.tankerkoenig.de/json/prices.php?ids=["<Tankstellen-ID>"]&apikey=<DEIN-API-KEY> 1800
attr TS.Station userattr event-min-interval event-on-change-reading icon reading1Name reading1Regex reading2Name reading2Regex reading3Name reading3Regex requestHeader stateFormat timeout
attr TS.Station event-on-change-reading .*
attr TS.Station group Spritpreise
attr TS.Station icon car
attr TS.Station reading1Name Diesel
attr TS.Station reading1Regex diesel":([\d\.]+)
attr TS.Station reading2Name Super_E10
attr TS.Station reading2Regex e10":([\d\.]+)
attr TS.Station reading3Name Super_E5
attr TS.Station reading3Regex e5":([\d\.]+)
attr TS.Station requestHeader Content-Type: application/json
attr TS.Station room I.Spritpreise
attr TS.Station stateFormat {sprintf("Diesel %.3f €\n SuperE10 %.3f €\n SuperE5 %.3f €", ReadingsVal($name,"Diesel",0), ReadingsVal($name,"Super_E10",0), ReadingsVal($name,"Super_E5",0))}
attr TS.Station timeout 5

Das Ganze macht man dann mit sovielen Tankstellen wie man haben will.

Meine Reading-Gruppe sieht so aus, wobei die TS.Station(nix,2,3) die Stationen und Super_E5/Diesel die Werte sind die angezeigt werden:
define Spritpreise readingsGroup (TS.Station|TS.Station2|TS.Station3):(Super_E5|Diesel).*
attr Spritpreise group Spritpreisuebersicht
attr Spritpreise notime 1
attr Spritpreise room I.Spritpreise
attr Spritpreise style style="font-size:16px"
attr Spritpreise valueFormat {'%.3f '}
attr Spritpreise valueStyle {Werte($READING,$VALUE)}

für die Farbansicht hier die 99_myUtils.pm Auszug:
###################################################
###     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.11) && ($wert < 1.39));
return ‘style=”color:green;;font-weight:bold”‘ if($wert <= 1.10);
}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.55);
return ‘style=”color:blue”‘ if(($wert >= 1.25) && ($wert < 1.55));
return ‘style=”color:green;;font-weight:bold”‘ if($wert <= 1.25);
}
}

Das SVG Plott sieht aus:
define plot.I.Me.Tanken SVG logdb:TS.Station
attr plot.I.Me.Tanken group Spritpreisverlauf
attr plot.I.Me.Tanken room I.Spritpreise

# Created by FHEM/98_SVG.pm, 2016-04-19 00:54:42
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 '<TL>'
set ytics
set y2tics
set grid
set ylabel "Preis"
set y2label "Preis"

#logdb TS.Station:Diesel
#logdb TS.Station:Super_E5
#logdb TS.Station2:Diesel
#logdb TS.Station2:Super_E5
#logdb TS.Station3:Diesel
#logdb TS.Station3:Super_E5

plot "<IN>" using 1:2 axes x1y2 title 'Esso Diesel' ls l0 lw 1 with lines,\
     "<IN>" using 1:2 axes x1y2 title 'Esso Super' ls l1 lw 1 with lines,\
     "<IN>" using 1:2 axes x1y2 title 'Star Diesel' ls l2 lw 1 with lines,\
     "<IN>" using 1:2 axes x1y2 title 'Star Super' ls l3 lw 1 with lines,\
     "<IN>" using 1:2 axes x1y2 title 'Shell Diesel' ls l4 lw 1 with lines,\
     "<IN>" using 1:2 axes x1y2 title 'Shell Super' ls l5 lw 1 with lines

Damit werten wir jetzt ein schmales JSON anstatt eine ganze Webseite wie bei den anderen Spritpreis-Aufrufen:
HTTP/1.1 200 OK Server: nginx/1.10.0 (Ubuntu) Date: Mon, 23 May 2016 13:08:40 GMT Content-Type: application/json; charset=utf-8 Connection: close Access-Control-Allow-Origin: * Access-Control-Allow-Headers: origin, x-requested-with, content-type, accept Access-Control-Allow-Methods: GET {"ok":true,"license":"CC BY 4.0 - http:\/\/creativecommons.tankerkoenig.de","data":"MTS-K","prices":{"005056ba-7cb6-1ed2-bceb-a04b9ccd8d3e":{"status":"open","e5":1.269,"e10":1.249,"diesel":1.039}}}

Vielen Dank an Zag der den Hauptteil beigetragen hat und die Idee dazu gab.
Vielen Dank an Gisbert für den Hinweis mit der prices.php .

Zusätzliches:

Es gibt mehrere Aufrufe von der Tankerkönig API:
– define TS.Station HTTPMOD https://creativecommons.tankerkoenig.de/json/detail.php?id=>TankstellenID>&apikey=<api-key> 1800
zeigt mehr Details zur Tankstelle an (zb: inklusive Öffnungszeiten)
HTTP/1.1 200 OK Server: nginx/1.6.2 (Ubuntu) Date: Tue, 19 Apr 2016 11:26:48 GMT Content-Type: application/json; charset=utf-8 Connection: close X-Powered-By: PHP/5.6.4-4ubuntu6.4 Access-Control-Allow-Origin: * Access-Control-Allow-Headers: origin, x-requested-with, content-type, accept Access-Control-Allow-Methods: GET {"status":"ok","ok":true,"license":"CC BY 4.0 - http:\/\/creativecommons.tankerkoenig.de","data":"MTS-K","station":{"id":"0b7c12d6-8995-448d-b3f9-399350334a70","name":"Esso Tankstelle","brand":"ESSO","street":"DUESSELDORFER STR. 198","houseNumber":" ","postCode":40822,"place":"METTMANN","overrides":[],"wholeDay":false,"isOpen":true,"e5":1.269,"e10":1.249,"diesel":1.019,"lat":51.255093,"lng":6.956276,"state":null,"openingTimes":[{"text":"Mo-Fr","start":"06:00:00","end":"22:00:00"},{"text":"Samstag","start":"07:00:00","end":"22:00:00"},{"text":"Sonntag","start":"08:00:00","end":"22:00:00"}]}}

Aufrufe: 42

10 Kommentare

  1. Toll geschrieben, hat sofort geklappt.
    Leider hat Tankerkönig nach einer Woche meinen API-Key gesperrt weil zu viele einzelne Aufrufe. Laut Tankerkönig sollen mehrere Tankstellen in einer Abfrage zusammengefasst und nicht einzeln abgefagt werden.
    Leider sind meine Perl-Kenntnisse nahe Null. Schade

  2. Ich schaue mir das mal an.
    Danke für den Hinweis, ich habe noch keine EMail mit den Hinweis auf die Benutzung einees anderen Links bekommen.

  3. Hallo Marcus,
    vielen Dank für deinen Hinweis auf Tankerkönig beim Fhem-Treffen in Köln.
    Tankerkönig hat sich bei mir per mail gemeldet und wünscht, dass ich die Preise per prices.php beziehe statt mit detail.php.
    Ich hab das geändert, aber es scheint nicht zu funktionieren; es werden keine Werte in das Reading geschrieben.
    Viele Grüße
    Gisbert

    1. Hallo Marcus,

      die Abfrage per prices.php funktioniert wie folgt:

      https://creativecommons.tankerkoenig.de/json/prices.php?ids=%5B“Tankstellen-ID”%5D&apikey= 1800
      (es müssen 2 Hochkommata sein; die Formatierung des Blogs macht daraus Gänsefüßchen)

      Man beachte die Mehrzahl ids, d.h. es können mehrere Tankstellen mit einer Anfrage angefragt werden.

      Details siehe hierzu: https://creativecommons.tankerkoenig.de/#techInfo

      Und hier: https://creativecommons.tankerkoenig.de/#demo

      Ich weiß aber nicht, ob es möglich ist, die Mehrfachantworten dann in Fhem auseinander zu pflücken. Ich habe es deshalb wie oben angegeben gelöst.

      Viele Grüße
      Gisbert

      1. Hallo Gisbert,
        habe die Änderung oben im Beitrag aktualisiert.
        Mit mehreren Tankstellen abrufen auf einmal, habe ich auch noch nicht umgesetzt.
        VG
        Marcus

  4. Mir scheint hier fehlt die Subroutine “Werte”, die hier aufgerufen wird!?
    attr Spritpreise valueStyle {Werte($READING,$VALUE)}

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

2 × 5 =

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.