added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
32
bundles/org.openhab.binding.tankerkoenig/.classpath
Normal file
32
bundles/org.openhab.binding.tankerkoenig/.classpath
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
23
bundles/org.openhab.binding.tankerkoenig/.project
Normal file
23
bundles/org.openhab.binding.tankerkoenig/.project
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.openhab.binding.tankerkoenig</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
13
bundles/org.openhab.binding.tankerkoenig/NOTICE
Normal file
13
bundles/org.openhab.binding.tankerkoenig/NOTICE
Normal file
@@ -0,0 +1,13 @@
|
||||
This content is produced and maintained by the openHAB project.
|
||||
|
||||
* Project home: https://www.openhab.org
|
||||
|
||||
== Declared Project Licenses
|
||||
|
||||
This program and the accompanying materials are made available under the terms
|
||||
of the Eclipse Public License 2.0 which is available at
|
||||
https://www.eclipse.org/legal/epl-2.0/.
|
||||
|
||||
== Source Code
|
||||
|
||||
https://github.com/openhab/openhab-addons
|
||||
190
bundles/org.openhab.binding.tankerkoenig/README.md
Normal file
190
bundles/org.openhab.binding.tankerkoenig/README.md
Normal file
@@ -0,0 +1,190 @@
|
||||
# Tankerkönig Binding
|
||||
|
||||
The binding uses the Tankerkönig API <https://www.tankerkoenig.de> for collecting gas price data of German gas stations.
|
||||
Special thanks to the creators of Tankerkönig for providing an easy way to get data from the [MTS-K] (Markttransparenzstelle für Kraftstoffe).
|
||||
|
||||
Tankerkönig is providing this service for free, however they request to prevent overloading of their server by reducing the number of web-requests.
|
||||
This binding handles those requests (minimum Refresh Interval is 10 minutes, a webserver does handle a maximum of 10 stations).
|
||||
The data will be updated for each Station individually after the initialization and after each Refresh Interval for all (open) stations (Note: changing the Webservice will cause the Refresh Interval to restart).
|
||||
Additionally one may select the mode Opening-Times in which only those Stations get polled which are actually open.
|
||||
For a correct usage of opening times the binding needs the information if the actual day is a holiday.
|
||||
|
||||
Note:
|
||||
While using the mode Opening-Times the channel "station_open" will NOT show "close" because during such times no update is being requested from that Station!
|
||||
|
||||
## Preparation
|
||||
|
||||
In order to use this binding one needs to prepare:
|
||||
|
||||
- minimal Java Version is 1.8.0_101-b13 (otherwise the https request will not produce a usable return)
|
||||
|
||||
- a personal API-Key
|
||||
|
||||
Request a free Tankerkönig API key from: <https://creativecommons.tankerkoenig.de/> (Select the tab "API-Key").
|
||||
|
||||
- LocationIDs of the selected gas stations
|
||||
|
||||
Search for the gas station IDs via the [finder tool](https://creativecommons.tankerkoenig.de/TankstellenFinder/index.html) (Select tab "Tools" -> "Tankstellenfinder").
|
||||
Drag the red marker on the map to the rough location of desired gas stations.
|
||||
Select the gas stations and click "Tankstellen übernehmen" on the right.
|
||||
This will download a file holding the location IDs.
|
||||
For example: `a7cdd9cf-b467-4aac-8eab-d662f082511e`
|
||||
|
||||
## Supported Things
|
||||
|
||||
This binding supports:
|
||||
|
||||
-Webservice (bridge)
|
||||
|
||||
-Station (thing)
|
||||
|
||||
## Discovery
|
||||
|
||||
The binding provides no discovery.
|
||||
The desired Webservice and Stations must be configured manually or via a things file.
|
||||
|
||||
## Binding configuration
|
||||
|
||||
The binding has no configuration options itself, all configuration is done at 'Bridge' and 'Things' level.
|
||||
|
||||
## Thing configuration
|
||||
|
||||
The Webservice (bridge) needs to be configured with the personal API-Key, the desired Refresh Interval (the time interval between price-updates, default 60 minutes, minimum 10 minutes) and the Opening-Times mode selection (in this mode price-updates are only requested from stations that are actually open).
|
||||
A single Webservice can handle up to 10 Stations.
|
||||
|
||||
Each Station needs to be configured with a LocationID and the Webservice to which it is linked.
|
||||
|
||||
## Channels
|
||||
|
||||
The binding introduces the channel `holiday` for the Webservice and the channels `e10`, `e5`, `diesel` and `station_open` for the Stations:
|
||||
|
||||
| Channel ID | Channel Description | Supported item type | Advanced |
|
||||
|--------------|---------------------------------------|---------------------|----------|
|
||||
| holiday | ON if today is a holiday | Switch | False |
|
||||
| e10 | price of e10 | Number | False |
|
||||
| e5 | price of e5 | Number | False |
|
||||
| diesel | price of diesel | Number | False |
|
||||
| station_open | reported opening-state of the station | Contact | False |
|
||||
|
||||
## Example
|
||||
|
||||
Note: All apikeys and locationids are only examples!
|
||||
|
||||
tankerkoenig.things:
|
||||
|
||||
```
|
||||
Bridge tankerkoenig:webservice:WebserviceName "MyWebserviceName" [ apikey="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", refresh= 60, modeOpeningTime =false ] {
|
||||
Thing station StationName1 "MyStationName1" @ "GasStations"[ locationid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" ]
|
||||
Thing station StationName2 "MyStationName2" @ "GasStations"[ locationid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" ]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
tankerkoenig.items:
|
||||
|
||||
```
|
||||
Switch Station_Holidays "Today is holiday: [%s]" { channel="tankerkoenig:webservice:WebserviceName:holiday"}
|
||||
Number E10_1 "E10 [%.3f €]" { channel="tankerkoenig:station:WebserviceName:StationName1:e10" }
|
||||
Number E5_1 "E5 [%.3f €]" { channel="tankerkoenig:station:WebserviceName:StationName1:e5" }
|
||||
Number Diesel_1 "Diesel [%.3f €]" { channel="tankerkoenig:station:WebserviceName:StationName1:diesel"}
|
||||
Contact Station_Open_1 "Station is [%s]" { channel="tankerkoenig:station:WebserviceName:StationName1:station_open"}
|
||||
Number E10_2 "E10 [%.3f €]" { channel="tankerkoenig:station:WebserviceName:StationName2:e10"}
|
||||
Number E5_2 "E5 [%.3f €]" { channel="tankerkoenig:station:WebserviceName:StationName2:e5"}
|
||||
Number Diesel_2 "Diesel [%.3f €]" { channel="tankerkoenig:station:WebserviceName:StationName2:diesel"}
|
||||
Contact Station_Open_2 "Station is [%s]" { channel="tankerkoenig:station:WebserviceName:StationName2:station_open"}
|
||||
```
|
||||
|
||||
## FAQ
|
||||
|
||||
-The Webservice stays OFFLINE
|
||||
|
||||
If only a Webservice is configured, it will remain OFFLINE until a Station is configured as well.
|
||||
Each Station schedules a daily job to update detail-data, on completion of that job the Station and the Webservice will change to ONLINE.
|
||||
The further price-updates for all Stations are scheduled by the Webservice using the Refresh Interval.
|
||||
|
||||
-The Station(s) and Webservice stay OFFLINE
|
||||
|
||||
Set the logging level for the binding to DEBUG (Karaf-Console command: "log:set DEBUG org.openhab.binding.tankerkoenig".
|
||||
Create a new Station (in order to start the "initialize" routine).
|
||||
Check the openhab.log for entries like:
|
||||
|
||||
```
|
||||
2017-06-25 16:02:12.679 [DEBUG] [ig.internal.data.TankerkoenigService] - getTankerkoenigDetailResult IOException:
|
||||
java.io.IOException: java.util.concurrent.ExecutionException: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
|
||||
......
|
||||
```
|
||||
|
||||
This indicates a missing certificate of a certification authority (CA) in the certificate-store of the Java JDK under which openHAB is running.
|
||||
In most cases, updating to the latest version of JDK solves this because the store of cacerts are maintained and updated in Java releases.
|
||||
|
||||
Note: You must restart openHAB after a Java update.
|
||||
|
||||
If you receive the error because you are running an old Linux installation which does not have the latest java-versions available in its package-repositories, you may be able to fix the issue using one of the three options below:
|
||||
|
||||
1.) Update the Linux system and install the latest Java version
|
||||
|
||||
2.) Download the most recent JDK and install it directly on to your system without using a pre-composed package
|
||||
|
||||
On Debian based systems one can use: http://www.webupd8.org/2012/09/install-oracle-java-8-in-ubuntu-via-ppa.html
|
||||
|
||||
3.) Update the cacerts store by importing the missing certificate
|
||||
|
||||
Note: Using this version, loaded certificates will expire!
|
||||
If you still want to import the missing certificate, the example below may help:
|
||||
Check which Java package you have installed:
|
||||
|
||||
```java
|
||||
>> sudo dpkg -l | grep java
|
||||
>> ii oracle-java8-jdk 8u65 armhf Java™ Platform, Standard Edition 8 Development Kit
|
||||
```
|
||||
|
||||
Find the ca-store of your JDK
|
||||
|
||||
```java
|
||||
>> sudo dpkg -L oracle-java8-jdk | grep cacerts
|
||||
>> /usr/lib/jvm/jdk-8-oracle-arm32-vfp-hflt/jre/lib/security/cacerts
|
||||
```
|
||||
|
||||
Check which CA has validated the certificate
|
||||
|
||||
Navigate to https://creativecommons.tankerkoenig.de/
|
||||
|
||||
Check which CA has validated the certificate
|
||||
|
||||
Export the certificate of the certificate authority
|
||||
|
||||
Import the certificate to the CA-store which you have found
|
||||
|
||||
```java
|
||||
>> cd /usr/lib/jvm/jdk-8-oracle-arm32-vfp-hflt/jre/lib/security
|
||||
>> keytool -import -keystore cacerts -alias LetsEncrypt -file ca.crt
|
||||
```
|
||||
|
||||
The required password is "changeit".
|
||||
|
||||
Restart your server
|
||||
|
||||
-The Station(s) and Webservice go to OFFLINE after being ONLINE
|
||||
|
||||
Either the web-request to Tankerkönig returned a failure or no valid response was received (this could be caused by a banned API-key).
|
||||
In both cases the Webservice and the Station(s) go OFFLINE.
|
||||
If the Tankerkönig return indicates an error a descriptive message (in German) is added next to the OFFLINE which will be displayed on the Webservice and Station(s) pages on Paper UI.
|
||||
On the next receipt of a valid message Webservice and Station(s) will go ONLINE again.
|
||||
The scheduled polling of price-data is canceled in case of no valid response.
|
||||
Users should check the log for any reports to solve the reason for the OFFLINE status.
|
||||
In order to restart the polling a change of the Webservice has to be saved (for example a change in the Refresh Interval).
|
||||
|
||||
Note: If the API-key is banned by Tankerkönig, the reason has to be cleared with Tankerkönig!
|
||||
|
||||
-How to set the switch item for the channel holiday?
|
||||
|
||||
The correct usage of opening times needs the information if the actual day is a holiday.
|
||||
The binding expects a switch item linked to the Webservice channel holiday.
|
||||
This switch can be set either manually (only suggested for testing!) or by a rule which uses the [ephemeris action](https://www.openhab.org/docs/configuration/actions.html#ephemeris) to set that switch.
|
||||
|
||||
## Tankerkönig API
|
||||
|
||||
* <https://creativecommons.tankerkoenig.de/> (sorry, only available in German)
|
||||
|
||||
* [MTS-K]: <https://www.bundeskartellamt.de/DE/Wirtschaftsbereiche/Mineral%C3%B6l/MTS-Kraftstoffe/Verbraucher/verbraucher_node.html>
|
||||
* [openhab1-addons rules]: <https://github.com/openhab/openhab1-addons/wiki/Samples-Rules#how-to-calculate-public-holidays>
|
||||
17
bundles/org.openhab.binding.tankerkoenig/pom.xml
Normal file
17
bundles/org.openhab.binding.tankerkoenig/pom.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.openhab.addons.bundles</groupId>
|
||||
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
|
||||
<version>3.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>org.openhab.binding.tankerkoenig</artifactId>
|
||||
|
||||
<name>openHAB Add-ons :: Bundles :: Tankerkoenig Binding</name>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.binding.tankerkoenig-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
|
||||
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
|
||||
|
||||
<feature name="openhab-binding-tankerkoenig" description="Tankerkoenig Binding" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.tankerkoenig/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.tankerkoenig.internal;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
||||
/**
|
||||
* The {@link TankerkoenigBinding} class defines common constants, which are
|
||||
* used across the whole binding.
|
||||
*
|
||||
* @author Dennis Dollinger - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class TankerkoenigBindingConstants {
|
||||
|
||||
public static final String BINDING_ID = "tankerkoenig";
|
||||
|
||||
// List of all Thing Type UIDs
|
||||
public static final ThingTypeUID THING_TYPE_TANKSTELLE = new ThingTypeUID(BINDING_ID, "station");
|
||||
public static final ThingTypeUID BRIDGE_THING_TYPE = new ThingTypeUID(BINDING_ID, "webservice");
|
||||
|
||||
public static final Set<ThingTypeUID> BRIDGE_THING_TYPES_UIDS = Collections.singleton(BRIDGE_THING_TYPE);
|
||||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.singleton(THING_TYPE_TANKSTELLE);
|
||||
|
||||
// List of all Channel ids
|
||||
public static final String CHANNEL_DIESEL = "diesel";
|
||||
public static final String CHANNEL_E10 = "e10";
|
||||
public static final String CHANNEL_E5 = "e5";
|
||||
public static final String CHANNEL_STATION_OPEN = "station_open";
|
||||
public static final String CHANNEL_HOLIDAY = "holiday";
|
||||
|
||||
// config
|
||||
public static final String CONFIG_LOCATION_ID = "locationid";
|
||||
public static final String CONFIG_API_KEY = "apikey";
|
||||
public static final String CONFIG_REFRESH = "refresh";
|
||||
public static final String CONFIG_MODE_OPENINGTIME = "modeOpeningTime";
|
||||
|
||||
// String used Identify unsucessful web-return
|
||||
public static final String NO_VALID_RESPONSE = "No valid response from the web-request!";
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.tankerkoenig.internal;
|
||||
|
||||
import static org.openhab.binding.tankerkoenig.internal.TankerkoenigBindingConstants.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.tankerkoenig.internal.handler.StationHandler;
|
||||
import org.openhab.binding.tankerkoenig.internal.handler.WebserviceHandler;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
|
||||
/**
|
||||
* The {@link TankerkoenigHandlerFactory} is responsible for creating things and thing
|
||||
* handlers.
|
||||
*
|
||||
* @author Dennis Dollinger - Initial contribution
|
||||
*/
|
||||
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.tankerkoenig")
|
||||
@NonNullByDefault
|
||||
public class TankerkoenigHandlerFactory extends BaseThingHandlerFactory {
|
||||
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.unmodifiableSet(Stream
|
||||
.concat(BRIDGE_THING_TYPES_UIDS.stream(), TankerkoenigBindingConstants.SUPPORTED_THING_TYPES_UIDS.stream())
|
||||
.collect(Collectors.toSet()));
|
||||
|
||||
@Override
|
||||
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
||||
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable ThingHandler createHandler(Thing thing) {
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
if (thingTypeUID.equals(BRIDGE_THING_TYPE)) {
|
||||
WebserviceHandler handler = new WebserviceHandler((Bridge) thing);
|
||||
return handler;
|
||||
} else if (thingTypeUID.equals(THING_TYPE_TANKSTELLE)) {
|
||||
return new StationHandler(thing);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.tankerkoenig.internal.data;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.tankerkoenig.internal.dto.TankerkoenigDetailResult;
|
||||
import org.openhab.binding.tankerkoenig.internal.dto.TankerkoenigListResult;
|
||||
import org.openhab.binding.tankerkoenig.internal.serializer.CustomTankerkoenigDetailResultDeserializer;
|
||||
import org.openhab.binding.tankerkoenig.internal.serializer.CustomTankerkoenigListResultDeserializer;
|
||||
import org.openhab.core.io.net.http.HttpUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
/***
|
||||
* Serivce class requesting data from tankerkoenig api and providing result objects
|
||||
*
|
||||
* @author Dennis Dollinger - Initial contribution
|
||||
* @author Juergen Baginski - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class TankerkoenigService {
|
||||
private final Logger logger = LoggerFactory.getLogger(TankerkoenigService.class);
|
||||
|
||||
private final Gson gson = new GsonBuilder()
|
||||
.registerTypeAdapter(TankerkoenigListResult.class, new CustomTankerkoenigListResultDeserializer()).create();
|
||||
private final Gson gsonDetail = new GsonBuilder()
|
||||
.registerTypeAdapter(TankerkoenigDetailResult.class, new CustomTankerkoenigDetailResultDeserializer())
|
||||
.create();
|
||||
private static final int REQUEST_TIMEOUT = 5000;
|
||||
|
||||
public @Nullable TankerkoenigListResult getStationListData(String apikey, String locationIDs, String userAgent) {
|
||||
return getTankerkoenigListResult(apikey, locationIDs, userAgent);
|
||||
}
|
||||
|
||||
public @Nullable TankerkoenigDetailResult getStationDetailData(String apikey, String locationID, String userAgent) {
|
||||
return getTankerkoenigDetailResult(apikey, locationID, userAgent);
|
||||
}
|
||||
|
||||
private @Nullable String getResponseString(String apiKey, String locationIDs, String userAgent, boolean detail)
|
||||
throws IOException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("https://creativecommons.tankerkoenig.de/json/");
|
||||
if (detail) {
|
||||
sb.append("detail.php?id=");
|
||||
} else {
|
||||
sb.append("prices.php?ids=");
|
||||
}
|
||||
sb.append(locationIDs);
|
||||
sb.append("&apikey=");
|
||||
sb.append(apiKey);
|
||||
String url = sb.toString();
|
||||
try {
|
||||
Properties urlHeader = new Properties();
|
||||
urlHeader.put("USER-AGENT", userAgent);
|
||||
return HttpUtil.executeUrl("GET", url, urlHeader, null, "", REQUEST_TIMEOUT);
|
||||
} catch (MalformedURLException e) {
|
||||
logger.debug("Error in getResponseString: ", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private @Nullable TankerkoenigListResult getTankerkoenigListResult(String apikey, String locationIDs,
|
||||
String userAgent) {
|
||||
try {
|
||||
String jsonData = getResponseString(apikey, locationIDs, userAgent, false);
|
||||
logger.debug("json-String: {}", jsonData);
|
||||
return gson.fromJson(jsonData, TankerkoenigListResult.class);
|
||||
} catch (IOException e) {
|
||||
logger.debug("Error in getTankerkoenigListResult: ", e);
|
||||
// the return of an empty result will force the status-update OFFLINE!
|
||||
return TankerkoenigListResult.emptyResult();
|
||||
}
|
||||
}
|
||||
|
||||
private @Nullable TankerkoenigDetailResult getTankerkoenigDetailResult(String apiKey, String locationID,
|
||||
String userAgent) {
|
||||
try {
|
||||
String jsonData = getResponseString(apiKey, locationID, userAgent, true);
|
||||
logger.debug("getTankerkoenigDetailResult jsonData : {}", jsonData);
|
||||
return gsonDetail.fromJson(jsonData, TankerkoenigDetailResult.class);
|
||||
} catch (IOException e) {
|
||||
logger.debug("getTankerkoenigDetailResult IOException: ", e);
|
||||
// the return of an empty result will force the status-update OFFLINE!
|
||||
return TankerkoenigDetailResult.emptyResult();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.tankerkoenig.internal.dto;
|
||||
|
||||
/**
|
||||
* The {@link LittleStation} class is the representing java model for the station specific json result of the prices
|
||||
* request. (LittleStation because it has nearly no other information than gas prices. Stripped down version of
|
||||
* Station.java)
|
||||
*
|
||||
* @author Dennis Dollinger - Initial contribution
|
||||
*/
|
||||
public class LittleStation {
|
||||
|
||||
private String e5;
|
||||
private String e10;
|
||||
private String diesel;
|
||||
private String status;
|
||||
private String id;
|
||||
private Boolean open;
|
||||
|
||||
public String getE5() {
|
||||
return e5;
|
||||
}
|
||||
|
||||
public void setE5(String e5) {
|
||||
this.e5 = e5;
|
||||
}
|
||||
|
||||
public String getE10() {
|
||||
return e10;
|
||||
}
|
||||
|
||||
public void setE10(String e10) {
|
||||
this.e10 = e10;
|
||||
}
|
||||
|
||||
public String getDiesel() {
|
||||
return diesel;
|
||||
}
|
||||
|
||||
public void setDiesel(String diesel) {
|
||||
this.diesel = diesel;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setID(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Boolean isOpen() {
|
||||
return open;
|
||||
}
|
||||
|
||||
public void setOpen(Boolean isOpen) {
|
||||
this.open = isOpen;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.tankerkoenig.internal.dto;
|
||||
|
||||
/**
|
||||
* The {@link OpeningTime} class is representing single Opening Time entry from the api request (i.e one setting like
|
||||
* "Montag" "09:00" "18:00")
|
||||
*
|
||||
* @author Jürgen Baginski - Initial contribution
|
||||
*/
|
||||
public class OpeningTime {
|
||||
|
||||
private String text;
|
||||
private String start;
|
||||
private String end;
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public String getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public void setStart(String start) {
|
||||
this.start = start;
|
||||
}
|
||||
|
||||
public String getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
public void setEnd(String end) {
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(" ").append(this.getText()).append(" Open: ").append(this.getStart()).append(" Close: ")
|
||||
.append(this.getEnd());
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.tankerkoenig.internal.dto;
|
||||
|
||||
/**
|
||||
* The {@link OpeningTimes} class is representing all OpeningTimes entries for a station from the api request (i.e array
|
||||
* of settings like "Montag" "09:00" "18:00")
|
||||
* plus the boolean WholeDay (open).
|
||||
*
|
||||
* @author Jürgen Baginski - Initial contribution
|
||||
*/
|
||||
public class OpeningTimes {
|
||||
|
||||
private Boolean wholeDay;
|
||||
private OpeningTime[] openingTimes;
|
||||
private String id;
|
||||
|
||||
public OpeningTimes(String id, Boolean wholeDay, OpeningTime[] lopeningTimes) {
|
||||
this.wholeDay = wholeDay;
|
||||
this.openingTimes = lopeningTimes;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Boolean getWholeDay() {
|
||||
return wholeDay;
|
||||
}
|
||||
|
||||
public void setWholeDay(Boolean wholeDay) {
|
||||
this.wholeDay = wholeDay;
|
||||
}
|
||||
|
||||
public OpeningTime[] getOpeningTimes() {
|
||||
return openingTimes;
|
||||
}
|
||||
|
||||
public void setOpeningTimes(OpeningTime[] openingTimes) {
|
||||
this.openingTimes = openingTimes;
|
||||
}
|
||||
|
||||
public String getid() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setid(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("WholeDay: ").append(this.getWholeDay().toString()).append("/ Days: ");
|
||||
for (OpeningTime ot : this.getOpeningTimes()) {
|
||||
sb.append(ot.toString());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.tankerkoenig.internal.dto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The {@link Prices} class is the representing java model for the station specific json result of the tankerkoenig.de
|
||||
* api
|
||||
*
|
||||
* @author Dennis Dollinger - Initial contribution
|
||||
*/
|
||||
public class Prices {
|
||||
|
||||
private List<LittleStation> stations;
|
||||
|
||||
public List<LittleStation> getStations() {
|
||||
return stations;
|
||||
}
|
||||
|
||||
public void setStations(List<LittleStation> stations) {
|
||||
this.stations = stations;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.tankerkoenig.internal.dto;
|
||||
|
||||
/**
|
||||
* The {@link Station} class is the representing java model for the station specific json result of the tankerkoenig.de
|
||||
* details.php
|
||||
* api
|
||||
*
|
||||
* @author Dennis Dollinger - Initial contribution
|
||||
*/
|
||||
public class Station {
|
||||
|
||||
private String id;
|
||||
private String name;
|
||||
|
||||
private String e5;
|
||||
private String e10;
|
||||
private String diesel;
|
||||
|
||||
private String brand;
|
||||
private String street;
|
||||
private String place;
|
||||
private String postCode;
|
||||
private Boolean open;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getE5() {
|
||||
return e5;
|
||||
}
|
||||
|
||||
public void setE5(String e5) {
|
||||
this.e5 = e5;
|
||||
}
|
||||
|
||||
public String getE10() {
|
||||
return e10;
|
||||
}
|
||||
|
||||
public void setE10(String e10) {
|
||||
this.e10 = e10;
|
||||
}
|
||||
|
||||
public String getDiesel() {
|
||||
return diesel;
|
||||
}
|
||||
|
||||
public void setDiesel(String diesel) {
|
||||
this.diesel = diesel;
|
||||
}
|
||||
|
||||
public String getBrand() {
|
||||
return brand;
|
||||
}
|
||||
|
||||
public void setBrand(String brand) {
|
||||
this.brand = brand;
|
||||
}
|
||||
|
||||
public String getStreet() {
|
||||
return street;
|
||||
}
|
||||
|
||||
public void setStreet(String street) {
|
||||
this.street = street;
|
||||
}
|
||||
|
||||
public String getPlace() {
|
||||
return place;
|
||||
}
|
||||
|
||||
public void setPlace(String place) {
|
||||
this.place = place;
|
||||
}
|
||||
|
||||
public String getPostCode() {
|
||||
return postCode;
|
||||
}
|
||||
|
||||
public void setPostCode(String postCode) {
|
||||
this.postCode = postCode;
|
||||
}
|
||||
|
||||
public Boolean isOpen() {
|
||||
return open;
|
||||
}
|
||||
|
||||
public void setOpen(Boolean isOpen) {
|
||||
this.open = isOpen;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.tankerkoenig.internal.dto;
|
||||
|
||||
import org.openhab.binding.tankerkoenig.internal.TankerkoenigBindingConstants;
|
||||
|
||||
/***
|
||||
* The {@link TankerkoenigDetailResult} class is the representing java model for the json result of the tankerkoenig.de
|
||||
* details request
|
||||
* Actually used for OpeningTimes only.
|
||||
*
|
||||
* @author Dennis Dollinger - Initial contribution
|
||||
* @author Jürgen Baginski - Initial contribution
|
||||
*/
|
||||
public class TankerkoenigDetailResult {
|
||||
|
||||
private boolean ok;
|
||||
private boolean wholeDay;
|
||||
private OpeningTimes openingTimes;
|
||||
private LittleStation littleStation;
|
||||
private String message;
|
||||
|
||||
public boolean isOk() {
|
||||
return ok;
|
||||
}
|
||||
|
||||
public void setOk(boolean ok) {
|
||||
this.ok = ok;
|
||||
}
|
||||
|
||||
public boolean iswholeDay() {
|
||||
return wholeDay;
|
||||
}
|
||||
|
||||
public void setwholeDay(boolean WholeDay) {
|
||||
this.wholeDay = WholeDay;
|
||||
}
|
||||
|
||||
public static TankerkoenigDetailResult emptyResult() {
|
||||
TankerkoenigDetailResult emptyResult = new TankerkoenigDetailResult();
|
||||
emptyResult.setOk(false);
|
||||
emptyResult.setMessage(TankerkoenigBindingConstants.NO_VALID_RESPONSE);
|
||||
return emptyResult;
|
||||
}
|
||||
|
||||
public LittleStation getLittleStation() {
|
||||
return littleStation;
|
||||
}
|
||||
|
||||
public void setLittleStation(LittleStation littleStation) {
|
||||
this.littleStation = littleStation;
|
||||
}
|
||||
|
||||
public OpeningTimes getOpeningTimes() {
|
||||
return openingTimes;
|
||||
}
|
||||
|
||||
public void setOpeningTimes(OpeningTimes openingTimes) {
|
||||
this.openingTimes = openingTimes;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.tankerkoenig.internal.dto;
|
||||
|
||||
import org.openhab.binding.tankerkoenig.internal.TankerkoenigBindingConstants;
|
||||
|
||||
/***
|
||||
* The {@link TankerkoenigListResult} class is the representing java model for the json result of the tankerkoenig.de
|
||||
* api
|
||||
*
|
||||
* @author Dennis Dollinger - Initial contribution
|
||||
*/
|
||||
public class TankerkoenigListResult {
|
||||
|
||||
private boolean ok;
|
||||
private Prices prices;
|
||||
private String message;
|
||||
|
||||
public boolean isOk() {
|
||||
return ok;
|
||||
}
|
||||
|
||||
public void setOk(boolean ok) {
|
||||
this.ok = ok;
|
||||
}
|
||||
|
||||
public Prices getPrices() {
|
||||
return prices;
|
||||
}
|
||||
|
||||
public void setPrices(Prices prices) {
|
||||
this.prices = prices;
|
||||
}
|
||||
|
||||
public static TankerkoenigListResult emptyResult() {
|
||||
TankerkoenigListResult emptyResult = new TankerkoenigListResult();
|
||||
emptyResult.setOk(false);
|
||||
emptyResult.setMessage(TankerkoenigBindingConstants.NO_VALID_RESPONSE);
|
||||
return emptyResult;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.tankerkoenig.internal.handler;
|
||||
|
||||
import static org.openhab.binding.tankerkoenig.internal.TankerkoenigBindingConstants.*;
|
||||
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.openhab.binding.tankerkoenig.internal.TankerkoenigBindingConstants;
|
||||
import org.openhab.binding.tankerkoenig.internal.data.TankerkoenigService;
|
||||
import org.openhab.binding.tankerkoenig.internal.dto.LittleStation;
|
||||
import org.openhab.binding.tankerkoenig.internal.dto.OpeningTimes;
|
||||
import org.openhab.binding.tankerkoenig.internal.dto.TankerkoenigDetailResult;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.OpenClosedType;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.ThingStatusInfo;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link StationHandler} is responsible for handling commands, which are
|
||||
* sent to one of the channels.
|
||||
*
|
||||
* @author Dennis Dollinger - Initial contribution
|
||||
* @author Jürgen Baginski - Initial contribution
|
||||
*/
|
||||
public class StationHandler extends BaseThingHandler {
|
||||
private static final Pattern IS_NUMERIC_PATTERN = Pattern.compile("\\d+(\\.\\d+)?");
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(StationHandler.class);
|
||||
|
||||
private String apiKey;
|
||||
private boolean modeOpeningTime;
|
||||
private String locationID;
|
||||
private OpeningTimes openingTimes;
|
||||
private String userAgent;
|
||||
private final TankerkoenigService service = new TankerkoenigService();
|
||||
private TankerkoenigDetailResult result;
|
||||
|
||||
private ScheduledFuture<?> pollingJob;
|
||||
|
||||
public StationHandler(Thing thing) {
|
||||
super(thing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
// no code needed.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
logger.debug("Initializing Tankerkoenig handler '{}'", getThing().getUID());
|
||||
Configuration config = getThing().getConfiguration();
|
||||
setLocationID((String) config.get(TankerkoenigBindingConstants.CONFIG_LOCATION_ID));
|
||||
setApiKey((String) config.get(TankerkoenigBindingConstants.CONFIG_API_KEY));
|
||||
Bridge b = getBridge();
|
||||
if (b == null) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE,
|
||||
"Could not find bridge (tankerkoenig config). Did you select one?");
|
||||
return;
|
||||
}
|
||||
WebserviceHandler handler = (WebserviceHandler) b.getHandler();
|
||||
userAgent = handler.getUserAgent();
|
||||
setApiKey(handler.getApiKey());
|
||||
setModeOpeningTime(handler.isModeOpeningTime());
|
||||
if (b.getThings().size() > 10) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||
"The limitation of station things for one tankerkoenig webservice (the bridge) is limited to 10.");
|
||||
return;
|
||||
}
|
||||
updateStatus(ThingStatus.UNKNOWN);
|
||||
|
||||
pollingJob = scheduler.scheduleWithFixedDelay(() -> {
|
||||
try {
|
||||
logger.debug("Try to refresh detail data");
|
||||
updateDetailData();
|
||||
} catch (RuntimeException r) {
|
||||
logger.debug("Caught exception in ScheduledExecutorService of TankerkoenigHandler", r);
|
||||
// no status change, since in case of error in here,
|
||||
// the old values for opening time will be continue to be used
|
||||
}
|
||||
}, 15, 86400, TimeUnit.SECONDS);// 24*60*60 = 86400, a whole day in seconds!
|
||||
logger.debug("Refresh job scheduled to run every 24 hours for '{}'", getThing().getUID());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (pollingJob != null) {
|
||||
pollingJob.cancel(true);
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
|
||||
logger.debug("Bridge Status updated to {} for device: {}", bridgeStatusInfo.getStatus(), getThing().getUID());
|
||||
if (bridgeStatusInfo.getStatus() != ThingStatus.ONLINE) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE, bridgeStatusInfo.getDescription());
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* Updates the channels of a station item
|
||||
*
|
||||
* @param station
|
||||
*/
|
||||
public void updateData(LittleStation station) {
|
||||
logger.debug("Update Tankerkoenig data '{}'", getThing().getUID());
|
||||
if (IS_NUMERIC_PATTERN.matcher(station.getDiesel()).matches()) {
|
||||
DecimalType diesel = new DecimalType(station.getDiesel());
|
||||
updateState(CHANNEL_DIESEL, diesel);
|
||||
} else {
|
||||
updateState(CHANNEL_DIESEL, UnDefType.UNDEF);
|
||||
}
|
||||
if (IS_NUMERIC_PATTERN.matcher(station.getE10()).matches()) {
|
||||
DecimalType e10 = new DecimalType(station.getE10());
|
||||
updateState(CHANNEL_E10, e10);
|
||||
} else {
|
||||
updateState(CHANNEL_E10, UnDefType.UNDEF);
|
||||
}
|
||||
if (IS_NUMERIC_PATTERN.matcher(station.getE5()).matches()) {
|
||||
DecimalType e5 = new DecimalType(station.getE5());
|
||||
updateState(CHANNEL_E5, e5);
|
||||
} else {
|
||||
updateState(CHANNEL_E5, UnDefType.UNDEF);
|
||||
}
|
||||
updateState(CHANNEL_STATION_OPEN, (station.isOpen() ? OpenClosedType.OPEN : OpenClosedType.CLOSED));
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
}
|
||||
|
||||
/***
|
||||
* Updates the detail-data from tankerkoenig api, actually only the opening times are used.
|
||||
*/
|
||||
public void updateDetailData() {
|
||||
result = service.getStationDetailData(getApiKey(), locationID, userAgent);
|
||||
|
||||
if (result.isOk()) {
|
||||
setOpeningTimes(result.getOpeningTimes());
|
||||
LittleStation s = result.getLittleStation();
|
||||
if (s == null) {
|
||||
logger.debug("Station with id {} is not updated!", getLocationID());
|
||||
} else {
|
||||
updateData(s);
|
||||
}
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
WebserviceHandler handler = (WebserviceHandler) getBridge().getHandler();
|
||||
handler.updateStatus(ThingStatus.ONLINE);
|
||||
logger.debug("updateDetailData openingTimes: {}", openingTimes);
|
||||
} else {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, result.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public String getLocationID() {
|
||||
return locationID;
|
||||
}
|
||||
|
||||
public void setLocationID(String locationID) {
|
||||
this.locationID = locationID;
|
||||
}
|
||||
|
||||
public String getApiKey() {
|
||||
return apiKey;
|
||||
}
|
||||
|
||||
public void setApiKey(String apiKey) {
|
||||
this.apiKey = apiKey;
|
||||
}
|
||||
|
||||
public boolean isModeOpeningTime() {
|
||||
return modeOpeningTime;
|
||||
}
|
||||
|
||||
public void setModeOpeningTime(boolean modeOpeningTime) {
|
||||
this.modeOpeningTime = modeOpeningTime;
|
||||
}
|
||||
|
||||
public OpeningTimes getOpeningTimes() {
|
||||
return openingTimes;
|
||||
}
|
||||
|
||||
public void setOpeningTimes(OpeningTimes openingTimes) {
|
||||
this.openingTimes = openingTimes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,368 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.tankerkoenig.internal.handler;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.text.ParseException;
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.openhab.binding.tankerkoenig.internal.TankerkoenigBindingConstants;
|
||||
import org.openhab.binding.tankerkoenig.internal.data.TankerkoenigService;
|
||||
import org.openhab.binding.tankerkoenig.internal.dto.LittleStation;
|
||||
import org.openhab.binding.tankerkoenig.internal.dto.OpeningTime;
|
||||
import org.openhab.binding.tankerkoenig.internal.dto.OpeningTimes;
|
||||
import org.openhab.binding.tankerkoenig.internal.dto.TankerkoenigListResult;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.binding.BaseBridgeHandler;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.framework.Version;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link WebserviceHandler} is responsible for handling the things (stations)
|
||||
*
|
||||
* @author Dennis Dollinger - Initial contribution
|
||||
* @author Jürgen Baginski - Initial contribution
|
||||
*/
|
||||
public class WebserviceHandler extends BaseBridgeHandler {
|
||||
private final Logger logger = LoggerFactory.getLogger(WebserviceHandler.class);
|
||||
|
||||
private String apiKey;
|
||||
private int refreshInterval;
|
||||
private boolean modeOpeningTime;
|
||||
private String userAgent;
|
||||
private boolean isHoliday;
|
||||
private final TankerkoenigService service = new TankerkoenigService();
|
||||
private TankerkoenigListResult tankerkoenigListResult;
|
||||
|
||||
private final Map<String, LittleStation> stationMap = new HashMap<>();
|
||||
|
||||
private ScheduledFuture<?> pollingJob;
|
||||
|
||||
public WebserviceHandler(Bridge bridge) {
|
||||
super(bridge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
if (channelUID.getId().equals(TankerkoenigBindingConstants.CHANNEL_HOLIDAY)) {
|
||||
logger.debug("HandleCommand recieved: {}", channelUID.getId());
|
||||
isHoliday = (command == OnOffType.ON);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
logger.debug("Initialize Bridge");
|
||||
Configuration config = getThing().getConfiguration();
|
||||
setApiKey((String) config.get(TankerkoenigBindingConstants.CONFIG_API_KEY));
|
||||
setRefreshInterval(((BigDecimal) config.get(TankerkoenigBindingConstants.CONFIG_REFRESH)).intValue());
|
||||
setModeOpeningTime((boolean) config.get(TankerkoenigBindingConstants.CONFIG_MODE_OPENINGTIME));
|
||||
// set the UserAgent, this string is used by TankerkoenigService
|
||||
// to set a custom UserAgent for the WebRequest as specifically requested by Tankerkoening.de!
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("openHAB, Tankerkoenig-Binding Version ");
|
||||
Version version = FrameworkUtil.getBundle(getClass()).getVersion();
|
||||
sb.append(version.toString());
|
||||
userAgent = sb.toString();
|
||||
|
||||
updateStatus(ThingStatus.UNKNOWN);
|
||||
|
||||
int pollingPeriod = getRefreshInterval();
|
||||
pollingJob = scheduler.scheduleWithFixedDelay(() -> {
|
||||
logger.debug("Try to refresh data");
|
||||
try {
|
||||
updateStationData();
|
||||
updateStationThings();
|
||||
} catch (RuntimeException r) {
|
||||
logger.debug("Caught exception in ScheduledExecutorService of BridgeHandler. RuntimeException: ", r);
|
||||
updateStatus(ThingStatus.OFFLINE);
|
||||
}
|
||||
}, pollingPeriod, pollingPeriod, TimeUnit.MINUTES);
|
||||
logger.debug("Refresh job scheduled to run every {} min. for '{}'", pollingPeriod, getThing().getUID());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (pollingJob != null) {
|
||||
pollingJob.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateStatus(ThingStatus status) {
|
||||
updateStatus(status, ThingStatusDetail.NONE, null);
|
||||
}
|
||||
|
||||
/***
|
||||
* Updates the data from tankerkoenig api (no update on things)
|
||||
*/
|
||||
public void updateStationData() {
|
||||
// Get data
|
||||
try {
|
||||
String locationIDsString = "";
|
||||
if (modeOpeningTime) {
|
||||
logger.debug("Opening times are used");
|
||||
locationIDsString = generateOpenLocationIDsString();
|
||||
} else {
|
||||
logger.debug("No opening times are used");
|
||||
locationIDsString = generateLocationIDsString();
|
||||
}
|
||||
if (locationIDsString.isEmpty()) {
|
||||
logger.debug("No tankstellen id's found. Nothing to update");
|
||||
return;
|
||||
}
|
||||
TankerkoenigListResult result = service.getStationListData(getApiKey(), locationIDsString, userAgent);
|
||||
if (!result.isOk()) {
|
||||
// two possibel reasons for result.isOK=false
|
||||
// A-tankerkoenig returns false on a web-request
|
||||
// in this case the field "message" holds information for the reason.
|
||||
// B-the web-request does not return a valid json-string,
|
||||
// in this case an emptyReturn object is created with the message "No valid response from the
|
||||
// web-request!"
|
||||
// in both cases the Webservice and the Station(s) will go OFFLINE
|
||||
// only in case A the pollingJob gets canceled!
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, result.getMessage());
|
||||
// if the Bridge goes OFFLINE, all connected Stations will go OFFLINE as well.
|
||||
// The bridge reports its statusUpdate and the things react using the bridgeStatusChanged-Method!
|
||||
// Only if the message is NOT "No valid response from the web-request!" the scheduled job gets stopped!
|
||||
if (!result.getMessage().equals(TankerkoenigBindingConstants.NO_VALID_RESPONSE)) {
|
||||
pollingJob.cancel(true);
|
||||
}
|
||||
} else {
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
setTankerkoenigListResult(result);
|
||||
stationMap.clear();
|
||||
for (LittleStation station : result.getPrices().getStations()) {
|
||||
station.setOpen("open".equals(station.getStatus()));
|
||||
stationMap.put(station.getID(), station);
|
||||
}
|
||||
logger.debug("UpdateStationData: tankstellenList.size {}", stationMap.size());
|
||||
}
|
||||
} catch (ParseException e) {
|
||||
logger.error("ParseException: ", e);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* Updates all registered station with new data
|
||||
*/
|
||||
public void updateStationThings() {
|
||||
logger.debug("UpdateStationThings: getThing().getThings().size {}", getThing().getThings().size());
|
||||
for (Thing thing : getThing().getThings()) {
|
||||
StationHandler tkh = (StationHandler) thing.getHandler();
|
||||
LittleStation s = stationMap.get(tkh.getLocationID());
|
||||
if (s == null) {
|
||||
logger.debug("Station with id {} is not updated!", tkh.getLocationID());
|
||||
} else {
|
||||
tkh.updateData(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* Generates a comma separated string with all station id's
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String generateLocationIDsString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Thing thing : getThing().getThings()) {
|
||||
StationHandler tkh = (StationHandler) thing.getHandler();
|
||||
if (sb.length() > 0) {
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append(tkh.getLocationID());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/***
|
||||
* Generates a comma separated string of all open station id's
|
||||
* calculated using the data stored in opentimesList
|
||||
* The settings in the section "override" from the json detail response are NOT used!
|
||||
*
|
||||
* @return String
|
||||
* @throws ParseException
|
||||
*/
|
||||
private String generateOpenLocationIDsString() throws ParseException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
LocalDate today = LocalDate.now();
|
||||
for (Thing thing : getThing().getThings()) {
|
||||
String start = "00:00";
|
||||
String ende = "00:00";
|
||||
StationHandler tkh = (StationHandler) thing.getHandler();
|
||||
Boolean foundIt = false;
|
||||
OpeningTimes oTimes = tkh.getOpeningTimes();
|
||||
// oTimes could be NULL, assume wholeDay open in this case!
|
||||
if (oTimes != null) {
|
||||
if (oTimes.getWholeDay()) {
|
||||
// WholeDay open, use this ID!
|
||||
foundIt = true;
|
||||
logger.debug("Found a setting for WholeDay.");
|
||||
// "start" and "ende" are set manually!
|
||||
start = "00:00";
|
||||
ende = "23:59";
|
||||
} else {
|
||||
OpeningTime[] o = oTimes.getOpeningTimes();
|
||||
logger.debug("o.length: {}", o.length);
|
||||
int i = 0;
|
||||
do {
|
||||
logger.debug("Checking opening time i: {}", i);
|
||||
String day = o[i].getText();
|
||||
String open = o[i].getStart();
|
||||
String close = o[i].getEnd();
|
||||
DayOfWeek weekday = today.getDayOfWeek();
|
||||
logger.debug("Checking day: {}", day);
|
||||
logger.debug("Todays weekday: {}", weekday);
|
||||
if (isHoliday) {
|
||||
weekday = DayOfWeek.SUNDAY;
|
||||
logger.debug("Today is a holiday using : {}", weekday);
|
||||
}
|
||||
// if Daily, further checking not needed!
|
||||
if (day.contains("täglich")) {
|
||||
logger.debug("Found a setting for daily opening times.");
|
||||
foundIt = true;
|
||||
} else {
|
||||
switch (weekday) {
|
||||
case MONDAY:
|
||||
if ((day.contains("Werktags")) || (day.contains("Mo"))) {
|
||||
logger.debug("Found a setting which is valid for today (Monday).");
|
||||
foundIt = true;
|
||||
}
|
||||
break;
|
||||
case TUESDAY:
|
||||
if ((day.contains("Werktags")) || (day.contains("Di")) || (day.contains("Mo-Fr"))) {
|
||||
logger.debug("Found a setting which is valid for today (Tuesday).");
|
||||
foundIt = true;
|
||||
}
|
||||
break;
|
||||
case WEDNESDAY:
|
||||
if ((day.contains("Werktags")) || (day.contains("Mi")) || (day.contains("Mo-Fr"))) {
|
||||
logger.debug("Found a setting which is valid for today (Wednesday).");
|
||||
foundIt = true;
|
||||
}
|
||||
break;
|
||||
case THURSDAY:
|
||||
if ((day.contains("Werktags")) || (day.contains("Do")) || (day.contains("Mo-Fr"))) {
|
||||
logger.debug("Found a setting which is valid for today (Thursday).");
|
||||
foundIt = true;
|
||||
}
|
||||
break;
|
||||
case FRIDAY:
|
||||
if ((day.contains("Werktags")) || (day.contains("Fr"))) {
|
||||
logger.debug("Found a setting which is valid for today (Fryday).");
|
||||
foundIt = true;
|
||||
}
|
||||
break;
|
||||
case SATURDAY:
|
||||
if ((day.contains("Wochendende")) || (day.contains("Sa"))) {
|
||||
logger.debug("Found a setting which is valid for today (Saturday).");
|
||||
foundIt = true;
|
||||
}
|
||||
break;
|
||||
case SUNDAY:
|
||||
if ((day.contains("Wochenende")) || (day.contains("So"))) {
|
||||
logger.debug("Found a setting which is valid for today (Sunday).");
|
||||
foundIt = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (foundIt) {
|
||||
start = open;
|
||||
ende = close;
|
||||
break;
|
||||
}
|
||||
}
|
||||
i = i + 1;
|
||||
} while (i < o.length);
|
||||
}
|
||||
} else {
|
||||
// no OpeningTimes found, assuming WholeDay open!
|
||||
foundIt = true;
|
||||
logger.debug("No OpeningTimes are found, assuming WholeDay.");
|
||||
// "start" and "ende" are set manually!
|
||||
start = "00:00";
|
||||
ende = "23:59";
|
||||
}
|
||||
LocalTime opening = LocalTime.parse(start);
|
||||
LocalTime closing = LocalTime.parse(ende);
|
||||
LocalTime now = LocalTime.now();
|
||||
if (!opening.equals(closing)) {
|
||||
// Tankerkoenig.de does update the status "open" every 4 minutes
|
||||
// due to this the status "open" could be sent up to 4 minutes after the published opening time
|
||||
// therefore the first update is called 4 minutes after opening time!
|
||||
opening = opening.plusMinutes(4);
|
||||
}
|
||||
if ((opening.equals(closing)) || ((now.isAfter(opening) & (now.isBefore(closing))))) {
|
||||
logger.debug("Now is within opening times for today.");
|
||||
if (sb.length() > 0) {
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append(tkh.getLocationID());
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String getApiKey() {
|
||||
return apiKey;
|
||||
}
|
||||
|
||||
public void setApiKey(String apiKey) {
|
||||
this.apiKey = apiKey;
|
||||
}
|
||||
|
||||
public int getRefreshInterval() {
|
||||
return refreshInterval;
|
||||
}
|
||||
|
||||
public void setRefreshInterval(int refreshInterval) {
|
||||
this.refreshInterval = refreshInterval;
|
||||
}
|
||||
|
||||
public TankerkoenigListResult getTankerkoenigListResult() {
|
||||
return tankerkoenigListResult;
|
||||
}
|
||||
|
||||
public void setTankerkoenigListResult(TankerkoenigListResult tankerkoenigListResult) {
|
||||
this.tankerkoenigListResult = tankerkoenigListResult;
|
||||
}
|
||||
|
||||
public boolean isModeOpeningTime() {
|
||||
return modeOpeningTime;
|
||||
}
|
||||
|
||||
public void setModeOpeningTime(boolean modeOpeningTime) {
|
||||
this.modeOpeningTime = modeOpeningTime;
|
||||
}
|
||||
|
||||
public String getUserAgent() {
|
||||
return userAgent;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.tankerkoenig.internal.serializer;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import org.openhab.binding.tankerkoenig.internal.dto.LittleStation;
|
||||
import org.openhab.binding.tankerkoenig.internal.dto.OpeningTime;
|
||||
import org.openhab.binding.tankerkoenig.internal.dto.OpeningTimes;
|
||||
import org.openhab.binding.tankerkoenig.internal.dto.TankerkoenigDetailResult;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
|
||||
/***
|
||||
* Custom Deserializer for the detail result of tankerkoenigs api response
|
||||
*
|
||||
* @author Jürgen Baginski - Initial contribution
|
||||
*/
|
||||
public class CustomTankerkoenigDetailResultDeserializer implements JsonDeserializer<TankerkoenigDetailResult> {
|
||||
|
||||
@Override
|
||||
public TankerkoenigDetailResult deserialize(final JsonElement json, final Type typeOfT,
|
||||
final JsonDeserializationContext context) throws JsonParseException {
|
||||
final JsonObject jsonObject = json.getAsJsonObject();
|
||||
final Boolean isOK = jsonObject.get("ok").getAsBoolean();
|
||||
TankerkoenigDetailResult result = new TankerkoenigDetailResult();
|
||||
if (isOK) {
|
||||
final JsonObject jsonStation = jsonObject.get("station").getAsJsonObject();
|
||||
final Boolean isWholeDay = jsonStation.get("wholeDay").getAsBoolean();
|
||||
final LittleStation littleStation = new LittleStation();
|
||||
if (!jsonStation.get("e10").isJsonNull()) {
|
||||
final String e10 = jsonStation.get("e10").getAsString();
|
||||
littleStation.setE10(e10);
|
||||
}
|
||||
if (!jsonStation.get("e5").isJsonNull()) {
|
||||
final String e5 = jsonStation.get("e5").getAsString();
|
||||
littleStation.setE5(e5);
|
||||
}
|
||||
if (!jsonStation.get("diesel").isJsonNull()) {
|
||||
final String diesel = jsonStation.get("diesel").getAsString();
|
||||
littleStation.setDiesel(diesel);
|
||||
}
|
||||
final Boolean isOpen = jsonStation.get("isOpen").getAsBoolean();
|
||||
final String stationID = jsonStation.get("id").getAsString();
|
||||
OpeningTime[] openingTime = context.deserialize(jsonStation.get("openingTimes"), OpeningTime[].class);
|
||||
littleStation.setOpen(isOpen);
|
||||
littleStation.setID(stationID);
|
||||
final OpeningTimes openingTimes = new OpeningTimes(stationID, isWholeDay, openingTime);
|
||||
result.setLittleStation(littleStation);
|
||||
result.setOk(isOK);
|
||||
result.setwholeDay(isWholeDay);
|
||||
result.setOpeningTimes(openingTimes);
|
||||
} else {
|
||||
final String message = jsonObject.get("message").getAsString();
|
||||
result.setOk(isOK);
|
||||
result.setMessage(message);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.tankerkoenig.internal.serializer;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.openhab.binding.tankerkoenig.internal.dto.LittleStation;
|
||||
import org.openhab.binding.tankerkoenig.internal.dto.Prices;
|
||||
import org.openhab.binding.tankerkoenig.internal.dto.TankerkoenigListResult;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
|
||||
/***
|
||||
* Custom Deserializer fopr the list result of tankerkoenigs api response
|
||||
*
|
||||
* @author Dennis Dollinger - Initial contribution
|
||||
*/
|
||||
public class CustomTankerkoenigListResultDeserializer implements JsonDeserializer<TankerkoenigListResult> {
|
||||
|
||||
private final Gson gson = new Gson();
|
||||
|
||||
@Override
|
||||
public TankerkoenigListResult deserialize(final JsonElement json, final Type typeOfT,
|
||||
final JsonDeserializationContext context) throws JsonParseException {
|
||||
final JsonObject jsonObject = json.getAsJsonObject();
|
||||
|
||||
final Boolean isOK = jsonObject.get("ok").getAsBoolean();
|
||||
TankerkoenigListResult result = new TankerkoenigListResult();
|
||||
if (isOK) {
|
||||
result.setOk(jsonObject.get("ok").getAsBoolean());
|
||||
JsonObject jsonPrices = jsonObject.get("prices").getAsJsonObject();
|
||||
Set<Entry<String, JsonElement>> objects = jsonPrices.entrySet();
|
||||
Prices p = new Prices();
|
||||
result.setPrices(p);
|
||||
List<LittleStation> list = new ArrayList<>();
|
||||
for (Entry<String, JsonElement> entry : objects) {
|
||||
JsonElement jsonElement = entry.getValue();
|
||||
LittleStation station = gson.fromJson(jsonElement, LittleStation.class);
|
||||
station.setID(entry.getKey());
|
||||
list.add(station);
|
||||
}
|
||||
result.getPrices().setStations(list);
|
||||
} else {
|
||||
result.setOk(jsonObject.get("ok").getAsBoolean());
|
||||
result.setMessage(jsonObject.get("message").getAsString());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<binding:binding id="tankerkoenig" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:binding="https://openhab.org/schemas/binding/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/binding/v1.0.0 https://openhab.org/schemas/binding-1.0.0.xsd">
|
||||
|
||||
<name>Tankerkönig Binding</name>
|
||||
<description>The Tankerkönig Binding allows to poll fuel prices of German gas stations by using the Tankerkoenig.de
|
||||
API.</description>
|
||||
<author>Dennis Dollinger / Jürgen Baginski</author>
|
||||
|
||||
</binding:binding>
|
||||
@@ -0,0 +1,29 @@
|
||||
# binding
|
||||
binding.tankerkoenig.name = Tankerkönig Binding
|
||||
binding.tankerkoenig.description = Das Tankerkönig Binding ermöglicht es über die Tankerkoenig.de API Spritpreise von deutschen Tankstellen abzurufen.
|
||||
|
||||
# thing types
|
||||
thing-type.tankerkoenig.webservice.label = Tankerkönig Webservice
|
||||
thing-type.tankerkoenig.webservice.description = Der Tankerkönig Werbservice ermöglicht es die Spritpreise von 1 bis 10 Tankstellen abzufragen.
|
||||
thing-type.config.tankerkoenig.webservice.apikey.label=API-Key
|
||||
thing-type.config.tankerkoenig.webservice.apikey.description=Tankerkönig API-Key. Der Schlüssel ist auf der Tankerkönig Webseite erhältlich.
|
||||
thing-type.config.tankerkoenig.webservice.refresh.label=Aktualisierungsintervall
|
||||
thing-type.config.tankerkoenig.webservice.refresh.description=Spezifiziert das Aktualisierungsintervall in Minuten. Minimum 10 Minuten.
|
||||
thing-type.config.tankerkoenig.webservice.modeOpeningTime.label=Öffnungszeiten
|
||||
thing-type.config.tankerkoenig.webservice.modeOpeningTime.description=Im Mode Öffnungszeiten werden nur die zur Zeit geöffneten Tankstellen abgefragt.
|
||||
thing-type.tankerkoenig.station.label=Tankstelle
|
||||
thing-type.tankerkoenig.station.description=Stellt die Informationen zu den E5-, E10-, und Diesel-Preisen einer Tankstelle bereit.
|
||||
thing-type.config.tankerkoenig.station.locationid.label=Tankstellen-ID
|
||||
thing-type.config.tankerkoenig.station.locationid.description=Tankstellen-ID. Die ID ist auf der Tankerkönig Webseite erhältlich.
|
||||
# channel types
|
||||
channel-type.tankerkoenig.diesel.label = Diesel
|
||||
channel-type.tankerkoenig.e5.label = E5
|
||||
channel-type.tankerkoenig.e10.label = E10
|
||||
channel-type.tankerkoenig.station_open.label = Öffnungs-Status
|
||||
channel-type.tankerkoenig.holiday.label = Feiertag
|
||||
|
||||
channel-type.tankerkoenig.diesel.description = Diesel-Preis
|
||||
channel-type.tankerkoenig.e5.description= E5-Preis
|
||||
channel-type.tankerkoenig.e10.description = E10-Preis
|
||||
channel-type.tankerkoenig.station_open.description = Gemeldeter Öffnungs-Status
|
||||
channel-type.tankerkoenig.holiday.description = ON, wenn Heute ein Feiertag ist
|
||||
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="tankerkoenig"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
<thing-type id="station">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="webservice"/>
|
||||
</supported-bridge-type-refs>
|
||||
<label>Gas-Station</label>
|
||||
<description>Provides the prices of gas types E5-, E10- and Diesel of that station and if that station reports as
|
||||
opened.</description>
|
||||
<channels>
|
||||
<channel id="diesel" typeId="diesel"/>
|
||||
<channel id="e10" typeId="e10"/>
|
||||
<channel id="e5" typeId="e5"/>
|
||||
<channel id="station_open" typeId="station_open"/>
|
||||
</channels>
|
||||
<config-description>
|
||||
<parameter name="locationid" type="text" required="true">
|
||||
<label>Gas-Station-ID</label>
|
||||
<description>Fuel-Station-ID. You can get the required ID for your Gas-Station via the Tankerkönig website.</description>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
<channel-type id="diesel">
|
||||
<item-type>Number</item-type>
|
||||
<label>Diesel</label>
|
||||
<description>price for diesel</description>
|
||||
<state pattern="%.3f €" readOnly="true"></state>
|
||||
</channel-type>
|
||||
<channel-type id="e10">
|
||||
<item-type>Number</item-type>
|
||||
<label>E10</label>
|
||||
<description>price for E10</description>
|
||||
<state pattern="%.3f €" readOnly="true"></state>
|
||||
</channel-type>
|
||||
<channel-type id="e5">
|
||||
<item-type>Number</item-type>
|
||||
<label>E5</label>
|
||||
<description>price for E5</description>
|
||||
<state pattern="%.3f €" readOnly="true"></state>
|
||||
</channel-type>
|
||||
<channel-type id="station_open">
|
||||
<item-type>Contact</item-type>
|
||||
<label>Opening State</label>
|
||||
<description>The reported opening-state of that Station.</description>
|
||||
<state pattern="%s" readOnly="true"></state>
|
||||
</channel-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="tankerkoenig"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
<bridge-type id="webservice">
|
||||
<label>Tankerkönig Webservice</label>
|
||||
<description>The Tankerkönig Webservice can handle 1 to 10 gas stations.</description>
|
||||
<channels>
|
||||
<channel id="holiday" typeId="holiday"/>
|
||||
</channels>
|
||||
<config-description>
|
||||
<parameter name="apikey" type="text" required="true">
|
||||
<label>API-Key</label>
|
||||
<description>API-Key. Necessary registration on the Tankerkönig website.</description>
|
||||
<default></default>
|
||||
</parameter>
|
||||
<parameter name="refresh" type="integer" required="true" min="10">
|
||||
<label>Refresh Time</label>
|
||||
<description>Sets the refresh time. Minimum is 10 minutes.</description>
|
||||
<default>60</default>
|
||||
</parameter>
|
||||
<parameter name="modeOpeningTime" type="boolean">
|
||||
<label>Opening Time</label>
|
||||
<description>In mode Opening Time only those gas stations are polled that are actually open.</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</bridge-type>
|
||||
<channel-type id="holiday">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Holiday</label>
|
||||
<description>ON if today is a holiday.</description>
|
||||
</channel-type>
|
||||
</thing:thing-descriptions>
|
||||
Reference in New Issue
Block a user