Getting fuel prices from Tankerkoenig.de

I created a set of rules that gets the fuel prices of german fuel stations from Tankerkoenig.de.

You need:
an API-Key from Tankerkoenig.de (API_Key)
the IDs of the desired fuel stations ( for example: Tankstelle1_ID, Tankstelle2_ID, Tankstelle3_ID)
Number-Items for the prices (E10, E5 and Diesel) of each station (E10_1, E5_1, Diesel_1, E10_2,…)
DateTime Items that hold the Opening and closing times of each station (Opening1, Closing1, Opening2,…)

The rule OpeningTimes is called at System started and daily once at 0:03:50. In this rule the opening times of all stations are parsed from JSON returned from the “.details”-script, they are aved in the DateTime Items (Opening1, Closing1, Opening2,…)

The rule Benzinpreise is called every 10 minute (at Minute 07:50, 17:50, 27:50 …), in there each station is checked if it is open, for all open stations the prices of read with the .prices script and saved in the Number Items (E10_1, E5_1, Diesel_1, E10_2,…).

In both rules an Lambda-expression is used the reuse code that needs to run several times.

import org.eclipse.xtext.xbase.lib.Functions
import java.util.ArrayList
import com.sun.xml.internal.ws.util.StringUtils

val String Tankstelle1_ID=
val String Tankstelle2_ID=
val String Tankstell3_ID=
val String API_Key=
var String Status
var Number E10
var Number E5
var Number Diesel
var String TankstellenMarke
var String TankstellenStrasse
var String TankstellenOrt
var String TankstellenURL
//Lambda expression for the update of Opening and Closing times
val Functions$Function4<DateTimeItem, DateTimeItem, String, String> OpeningTimes= [Open, Close, API_Key, TankstellenID |
var String URL= “https://creativecommons.tankerkoenig.de/json/detail.php?id=” + TankstellenID + “&apikey=” + API_Key
var String json = sendHttpGetRequest(URL)
if (json!=null) {
var Boolean OK = transform(“JSONPATH”, “$.ok”, json)
if (OK=true) {
var Boolean WholeDay= transform (“JSONPATH”, “$.station.wholeDay”, json)
if (WholeDay) {
//Open the whole day! Create times that show that.
Open.postUpdate((now.withTimeAtStartOfDay).toString)
Close.postUpdate((now.withTimeAtStartOfDay.plusMinutes(1439)).toString)
} else {
// das ganze Array auswerten!
var i = 0
var int WochenTagHeute=now.getDayOfWeek
var Boolean FoundIt= false
do {
FoundIt= false
var String Tag=transform(“JSONPATH”, “$.station.openingTimes[” + i +"].text", json)
var String StartZeit=transform(“JSONPATH”, “$.station.openingTimes[” + i +"].start", json)
var String EndZeit=transform(“JSONPATH”, “$.station.openingTimes[” + i +"].end", json)
// if Daily, further checking not needed!
if Tag.contains(“täglich”) {
FoundIt=true
} else {
switch WochenTagHeute {
// checking different settings, NOT SURE if all possible settings are covered!!
case 1: {
if Tag.contains(“Werktags”) || Tag.contains(“Mo”) {
FoundIt=true
}
}
case 2: {
if Tag.contains(“Werktags”) || Tag.contains(“Di”) || Tag.contains(“Mo-Fr”) {
FoundIt=true
}
}
case 3: {
if Tag.contains(“Werktags”) || Tag.contains(“Mi”) || Tag.contains(“Mo-Fr”) {
FoundIt=true
}
}
case 4: {
if Tag.contains(“Werktags”) || Tag.contains(“Do”) || Tag.contains(“Mo-Fr”) {
FoundIt=true
}
}
case 5: {
if Tag.contains(“Werktags”) || Tag.contains(“Fr”) {
FoundIt=true
}
}
case 6: {
if Tag.contains(“Wochenende”) || Tag.contains(“Sa”) {
FoundIt=true
}
}
case 7: {
if Tag.contains(“Wochenende”) || Tag.contains(“So”) {
FoundIt=true
}
}
}
}
if FoundIt==true {
var String MyString=(parse(now.getYear() + “-” + now.getMonthOfYear() + “-” + now.getDayOfMonth() + “T”+StartZeit)).toString
Open.postUpdate((parse(now.getYear() + “-” + now.getMonthOfYear() + “-” + now.getDayOfMonth() + “T”+StartZeit)).toString)
if (StartZeit==EndZeit) {
Close.postUpdate((parse(now.getYear() + “-” + now.getMonthOfYear() + “-” + now.plusHours(24).getDayOfMonth() + “T”+EndZeit)).toString)
} else {
Close.postUpdate((parse(now.getYear() + “-” + now.getMonthOfYear() + “-” + now.getDayOfMonth() + “T”+EndZeit)).toString)
}
}
i=i+1
} while(transform(“JSONPATH”, “$.station.openingTimes[” + i +"].text", json)!={})
}
}
else {
var String HttpError = transform(“JSONPATH”, “$.message”, json)
logInfo(“OpeningTimes Lambda”, “HttpError = {}”, HttpError)
}
}
else {
logInfo(“OpeningTimes Lambda”, “Empty Return from HTTPRequest”)
}
]

//Lambda expression for the update of prices
val Functions$Function5<NumberItem, NumberItem, NumberItem, String, String> UpdatePrices= [E10_, E5_, Diesel_, JSON_String, TankstellenID |
var String Status = transform(“JSONPATH”, “$.prices.” + TankstellenID + “.status”, JSON_String)
//logInfo(“Benzinpreise lambda”, “Status = {}”, Status)
if (Status==“open”) {
var Number E10 = transform(“JSONPATH”, “$.prices.” + TankstellenID + “.e10”, JSON_String)
var Number E5 = transform(“JSONPATH”, “$.prices.” + TankstellenID + “.e5”, JSON_String)
var Number Diesel = transform(“JSONPATH”, “$.prices.” + TankstellenID + “.diesel”, JSON_String)
//logInfo(“Benzinpreise lambda”, “E10 = {}”, E10)
//logInfo(“Benzinpreise lambda”, “E10 = {}”, E5)
//logInfo(“Benzinpreise lambda”, “E10 = {}”, Diesel)
E10_.postUpdate(E10.toString)
E5_.postUpdate(E5.toString)
Diesel_.postUpdate(Diesel.toString)
}
]
//rule that reads the prices from the selected stations if they are open!
rule Benzinpreise
when
Time cron "50 7,17,27,37,47,57 * * * ?"
then
var String URL= "https://creativecommons.tankerkoenig.de/json/prices.php?ids=
var ArrayList TankstellenList = new ArrayList()
//First Check wether each station is open
if (now.isAfter((Opening1.state as DateTimeType).calendar.timeInMillis) && now.isBefore((Closing1.state as DateTimeType).calendar.timeInMillis)) {
TankstellenList.add(Tankstelle1_ID)
}
if (now.isAfter((Opening2.state as DateTimeType).calendar.timeInMillis) && now.isBefore((Closing2.state as DateTimeType).calendar.timeInMillis)) {
TankstellenList.add(Tankstelle2_ID)
}
if (now.isAfter((Opening3.state as DateTimeType).calendar.timeInMillis) && now.isBefore((Closing3.state as DateTimeType).calendar.timeInMillis)) {
TankstellenList.add(Tankstelle3_ID)
}
TankstellenURL=”"
if (TankstellenList.length>0) {
var StringBuilder sb=new StringBuilder
TankstellenList.forEach [ tl |
TankstellenURL=TankstellenURL + “,” +tl
]
sb.append(TankstellenURL)
TankstellenURL=sb.substring(1,sb.length ) // Removing the starting ","
URL= URL+TankstellenURL+ “&apikey=” + API_Key
var String json = sendHttpGetRequest( URL)
if (json!=null) {
var Boolean OK = transform(“JSONPATH”, “$.ok”, json)
if (OK=true) {
//Update the prices for all stations
UpdatePrices.apply(E10_1, E5_1, Diesel_1,json,Tankstelle1_ID)
UpdatePrices.apply(E10_2, E5_2, Diesel_2,json,Tankstelle2_ID)
UpdatePrices.apply(E10_3, E5_3, Diesel_3,json,Tankstelle3_ID)
}
else {
var String HttpError = transform(“JSONPATH”, “$.message”, json)
logInfo(“Benzinpreise”, “HttpError = {}”, HttpError)
}
}
else {
logInfo(“Benzinpreise”, “Empty Return from HTTPRequest”)
}
}
else {
logInfo(“Benzinpreise”, “All Stations are closed!”)
}
end

//rule to get the Opening and Closing times for each station
rule “OpeningTimes”

when
Time cron “50 3 0 * * ?” or System started
then
logInfo (“Tankstellendaten”, “Start”)
OpeningTimes.apply(Opening1,Closing1,API_Key,Tankstelle1_ID)
OpeningTimes.apply(Opening2,Closing2,API_Key,Tankstelle2_ID)
OpeningTimes.apply(Opening3,Closing3,API_Key,Tankstelle3_ID)
logInfo(“OpeningTimes”, “Opening1 = {}”, Opening1)
logInfo(“OpeningTimes”, “Closing1 = {}”, Closing1)
logInfo(“OpeningTimes”, “Opening2 = {}”, Opening2)
logInfo(“OpeningTimes”, “Closing2 = {}”, Closing2)
logInfo(“OpeningTimes”, “Opening3 = {}”, Opening3)
logInfo(“OpeningTimes”, “Closing3 = {}”, Closing3)
end

If anybody has any suggestions in order to improve the code used, I’m happy to take advices.

Hey @opus,
shouldn’t this be solved by New OH2 binding: Tankerkoenig ?

Yes, it should.
I’m trying to help the author with the further ideas I have.
In order to only request the prices from the actually open stations I needed some parsing code. Doing sthe needed trials in Eclipse is at moment a bit “heavy” for me. So I decided to code it as a rule initially and move it into the binding after words.

1 Like