]> git.basschouten.com Git - openhab-addons.git/commitdiff
[deutschebahn] DB API Marketplace adjustments (#12786)
authorSönke Küper <soenkekueper@outlook.de>
Thu, 26 May 2022 11:09:09 +0000 (13:09 +0200)
committerGitHub <noreply@github.com>
Thu, 26 May 2022 11:09:09 +0000 (13:09 +0200)
* Changes API URL and authentication Headers for DB API Marketplace.
* Fixed some typos and code style findings.

Signed-off-by: Sönke Küper <soenkekueper@gmx.de>
22 files changed:
bundles/org.openhab.binding.deutschebahn/README.md
bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/DeutscheBahnTimetableConfiguration.java
bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/DeutscheBahnTimetableHandler.java
bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/DeutscheBahnTrainHandler.java
bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/EventAttribute.java
bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/MessageCodes.java
bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/TimetableStopFilter.java
bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/TripLabelAttribute.java
bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/filter/ChannelNameEquals.java
bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/filter/FilterParser.java
bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/filter/FilterScanner.java
bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/timetable/TimetablesV1Api.java
bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/timetable/TimetablesV1ApiFactory.java
bundles/org.openhab.binding.deutschebahn/src/main/java/org/openhab/binding/deutschebahn/internal/timetable/TimetablesV1Impl.java
bundles/org.openhab.binding.deutschebahn/src/main/resources/OH-INF/i18n/deutschebahn.properties
bundles/org.openhab.binding.deutschebahn/src/main/resources/OH-INF/thing/thing-types.xml
bundles/org.openhab.binding.deutschebahn/src/test/java/org/openhab/binding/deutschebahn/internal/DeutscheBahnTimetableHandlerTest.java
bundles/org.openhab.binding.deutschebahn/src/test/java/org/openhab/binding/deutschebahn/internal/timetable/TimetableLoaderTest.java
bundles/org.openhab.binding.deutschebahn/src/test/java/org/openhab/binding/deutschebahn/internal/timetable/TimetableStubHttpCallable.java
bundles/org.openhab.binding.deutschebahn/src/test/java/org/openhab/binding/deutschebahn/internal/timetable/TimetablesApiTestModule.java
bundles/org.openhab.binding.deutschebahn/src/test/java/org/openhab/binding/deutschebahn/internal/timetable/TimetablesV1ImplTest.java
bundles/org.openhab.binding.deutschebahn/src/test/java/org/openhab/binding/deutschebahn/internal/timetable/TimetablesV1ImplTestHelper.java

index 9a2aec47e50934954017d05959bea34356f5d869..944c401b6d0aeb76147670f17fdc41011fc5159a 100644 (file)
@@ -14,14 +14,18 @@ The information are requested from the timetable api of Deutsche Bahn developer
 
 To configure a timetable you first need to register at Deutsche Bahn developer portal and register for timetable API to get an access key.
 
-1. Go to [Deutsche Bahn Developer](https://developer.deutschebahn.com)
+1. Go to [DB API Marketplace](https://developers.deutschebahn.com/)
 2. Register new account or login with an existing one
-3. If no application is configured yet (check Tab "Meine Anwendungen") create a new application. Only the name is required, any other fields can be left blank.
-4. Go to APIs - Timetables v1 (may be displayed on second page)
-5. Choose your previously created application and hit "Abonnieren"
-6. In confirmation-dialog choose "Wechsel zu meine Abonnements"
-7. Create an access key for the production environment by hitting "Schlüssel Erstellen"
-8. Copy the "Zugangstoken". This is required to access the api from openHAB.
+3. If no application is configured yet (check Tab "Anwendungen" at top) create a new application. Only the name is required, for example openHAB, any other fields can be left blank.
+4. Remember the shown **Client ID** and **Client Secret**.
+5. Go to **Katalog** and search for **Timetables** api.
+6. Within **Zugehörige APIs** select the Timetables api.
+7. Select **Abonnieren** at top left of the page.
+8. Select the Nutzungsplan **Free** by clicking **Abonnieren**.
+9. Select the previously created application.
+10. Click **Next**.
+11. Click **Fertig**.
+12. Now you have successfully registered the api within an application. The **Client ID** and **Client Secret** can now be used during bridge configuration.
 
 ### Determine the EVA-No of your station
 
@@ -31,13 +35,14 @@ You can look up the number within the csv file available at [Haltestellendaten](
 ### Configure timetable bridge
 
 With access key for developer portal and eva no. of your station you're ready to configure a timetable (bridge) for this station.
-In addition you can configure if only arrivals, only departures or all trains should be contained within the timetable.
+In addition, you can configure if only arrivals, only departures or all trains should be contained within the timetable.
 
 **timetable** parameters:
 
 | Property | Default | Required | Description |
 |-|-|-|-|
-| `accessToken` | | Yes | The access token for the timetable api within the developer portal of Deutsche Bahn. |
+| `clientId` | | Yes | The Client ID for the application with registered timetable api within the DB API Marketplace. |
+| `clientSecret` | | Yes | The Client Secret (API Key) for the application with registered timetable api within the DB API Marketplace. |
 | `evaNo` | | Yes | The eva nr. of the train station for which the timetable will be requested.|
 | `trainFilter` |  | Yes | Selects the trains that will be displayed in the timetable. Either only arrivals, only departures or all trains can be displayed. |
 | `additionalFilter` | | No | Specifies additional filters for trains, that should be displayed within the timetable. |
@@ -48,7 +53,7 @@ and only trains that matches the given filter will be contained within the timet
 
 To specify an advanced filter you can
 
-- specify a filter for the value of a given channel. Therefore you must specify the channel name (with channel group) and specify a compare value like this: 
+- specify a filter for the value of a given channel. Therefore, you must specify the channel name (with channel group) and specify a compare value like this: 
 `departure#line="RE60"` this will select all trains with line RE60
 - use regular expressions for expected channel values, for example:  `departure#line="RE.*"`, this will match all lines starting with "RE".
 - combine multiple statements as "and" conjunction by using `&`. If used, both parts must match, for example: `departure#line="RE60" & trip#category="WFB"`
@@ -82,10 +87,10 @@ train things, the channels of these trains will be undefined.
 ## Channels
 
 Each train has a set of channels, that provides access to any information served by the timetable API. A detailed description of the values and their meaning can be found within
-the [Timetables V1 API Description](https://developer.deutschebahn.com/store/apis/info?name=Timetables&version=v1&provider=DBOpenData&).
+the [Timetables V1 API Description](https://developers.deutschebahn.com/db-api-marketplace/apis/product/timetables).
 The information are grouped into three channel-groups:
 The first channel group (trip) contains all information for the trip of the train, for example the category (like ICE, RE, S).
-The second and third channel group contains information about the the arrival and the departure of the train at the given station. 
+The second and third channel group contains information about the arrival and the departure of the train at the given station. 
 Both of the groups may provide an 'UNDEF' channel value, when the train does not arrive / depart at this station
 (due it starts or ends at the given station). If you have configured your timetable to contain only departures (with property trainFilter) the departure channel values will always be defined 
 and if you have selected only arrivals the arrival channel values will always be defined.
index cfabcb9ba545b82cade6c89c328a254a9ec271c0..5d77da6660ae1fdabee30e02e345024d978f6115 100644 (file)
@@ -32,9 +32,14 @@ import org.openhab.binding.deutschebahn.internal.filter.TimetableStopPredicate;
 public class DeutscheBahnTimetableConfiguration {
 
     /**
-     * Access-Token.
+     * Client-ID for DB-API Application
      */
-    public String accessToken = "";
+    public String clientId = "";
+
+    /**
+     * Client-Secret for DB-API Application
+     */
+    public String clientSecret = "";
 
     /**
      * evaNo of the station to be queried.
index 72e192c434a1a6d96818a90ba1b408010e17e2e4..2b837c808e8889e2ff4895c3289b449fe335afa7 100644 (file)
@@ -13,7 +13,6 @@
 package org.openhab.binding.deutschebahn.internal;
 
 import java.io.IOException;
-import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
@@ -53,7 +52,6 @@ import org.openhab.core.types.Command;
 import org.openhab.core.types.UnDefType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.xml.sax.SAXException;
 
 /**
  * The {@link DeutscheBahnTimetableHandler} is responsible for handling commands, which are
@@ -116,7 +114,7 @@ public class DeutscheBahnTimetableHandler extends BaseBridgeHandler {
     private final ScheduledExecutorService executorService;
 
     /**
-     * Creates an new {@link DeutscheBahnTimetableHandler}.
+     * Creates a new {@link DeutscheBahnTimetableHandler}.
      */
     public DeutscheBahnTimetableHandler( //
             final Bridge bridge, //
@@ -152,7 +150,11 @@ public class DeutscheBahnTimetableHandler extends BaseBridgeHandler {
         final DeutscheBahnTimetableConfiguration config = this.getConfigAs(DeutscheBahnTimetableConfiguration.class);
 
         try {
-            final TimetablesV1Api api = this.timetablesV1ApiFactory.create(config.accessToken, HttpUtil::executeUrl);
+            final TimetablesV1Api api = this.timetablesV1ApiFactory.create( //
+                    config.clientId, //
+                    config.clientSecret, //
+                    HttpUtil::executeUrl //
+            );
 
             final TimetableStopFilter stopFilter = config.getTrainFilterFilter();
             final TimetableStopPredicate additionalFilter = config.getAdditionalFilter();
@@ -183,7 +185,7 @@ public class DeutscheBahnTimetableHandler extends BaseBridgeHandler {
             });
         } catch (FilterScannerException | FilterParserException e) {
             this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
-        } catch (JAXBException | SAXException | URISyntaxException e) {
+        } catch (JAXBException e) {
             this.logger.error("Error initializing api", e);
             this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
         }
@@ -195,7 +197,7 @@ public class DeutscheBahnTimetableHandler extends BaseBridgeHandler {
     }
 
     /**
-     * Schedules an job that updates the timetable every 30 seconds.
+     * Schedules a job that updates the timetable every 30 seconds.
      */
     private void restartJob() {
         this.logger.debug("Restarting jobs for bridge {}", this.getThing().getUID());
@@ -298,7 +300,7 @@ public class DeutscheBahnTimetableHandler extends BaseBridgeHandler {
     }
 
     /**
-     * Returns an map containing the things grouped by timetable stop position.
+     * Returns a map containing the things grouped by timetable stop position.
      */
     private GroupedThings groupThingsPerPosition() {
         final GroupedThings groupedThings = new GroupedThings();
index 8b206309eaebc2574ebb6ecf29341ea752efb01e..eb57ab3f838c03cf5e2d65a001c0d06c1f493093 100644 (file)
@@ -52,7 +52,6 @@ public class DeutscheBahnTrainHandler extends BaseThingHandler {
          * Creates an new ChannelWithConfig.
          * 
          * @param channelUid The UID of the channel
-         * @param configuration Configuration for the given channel.
          * @param attributeSelection The attribute that provides the state that will be displayed.
          */
         public ChannelWithConfig( //
@@ -166,8 +165,7 @@ public class DeutscheBahnTrainHandler extends BaseThingHandler {
         final String channelId = channelUid.getId();
         int hashIndex = channelId.indexOf("#");
         assert hashIndex > 0;
-        final String attributeName = channelId.substring(hashIndex + 1);
-        return attributeName;
+        return channelId.substring(hashIndex + 1);
     }
 
     /**
index 49d96349a4679b517797cadd997132e9ee9454d1..f4ebfae3b1d442863362c6b4ffdca3bb10dee162 100644 (file)
@@ -41,7 +41,7 @@ import org.openhab.core.types.State;
  *
  * chapter "1.2.11 Event" in Technical Interface Description for external Developers
  *
- * @see https://developer.deutschebahn.com/store/apis/info?name=Timetables&version=v1&provider=DBOpenData&#tab1
+ * @see <a href="https://developers.deutschebahn.com/db-api-marketplace/apis/product/timetables">DB API Marketplace</a>
  *
  * @author Sönke Küper - initial contribution
  *
@@ -370,7 +370,9 @@ public final class EventAttribute<VALUE_TYPE, STATE_TYPE extends State>
         if (value == null) {
             return Collections.emptyList();
         } else {
-            return Collections.singletonList(DATETIME_FORMAT.format(value));
+            synchronized (DATETIME_FORMAT) {
+                return Collections.singletonList(DATETIME_FORMAT.format(value));
+            }
         }
     }
 
index 124f68638e66542be7808beb2f2893babb8b71d8..5a5df60ed7c3850209ef15e8b8bf340345adf5b4 100644 (file)
@@ -22,99 +22,99 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
  * 
  * chapter "2 List of all codes" in Technical Interface Description for external Developers
  *
- * @see https://developer.deutschebahn.com/store/apis/info?name=Timetables&version=v1&provider=DBOpenData&#tab1
+ * @see <a href="https://developers.deutschebahn.com/db-api-marketplace/apis/product/timetables">DB API Marketplace</a>
  *
  * @author Sönke Küper - initial contribution
  */
 @NonNullByDefault
 public final class MessageCodes {
 
-    private static Map<Integer, String> codes = new HashMap<>();
+    private static final Map<Integer, String> CODES = new HashMap<>();
     static {
-        codes.put(0, "keine Verspätungsbegründung");
-        codes.put(2, "Polizeiliche Ermittlung");
-        codes.put(3, "Feuerwehreinsatz an der Strecke");
-        codes.put(4, "kurzfristiger Personalausfall");
-        codes.put(5, "ärztliche Versorgung eines Fahrgastes");
-        codes.put(6, "Betätigen der Notbremse");
-        codes.put(7, "Personen im Gleis");
-        codes.put(8, "Notarzteinsatz am Gleis");
-        codes.put(9, "Streikauswirkungen");
-        codes.put(10, "Tiere im Gleis");
-        codes.put(11, "Unwetter");
-        codes.put(12, "Warten auf ein verspätetes Schiff");
-        codes.put(13, "Pass- und Zollkontrolle");
-        codes.put(14, "Technische Störung am Bahnhof");
-        codes.put(15, "Beeinträchtigung durch Vandalismus");
-        codes.put(16, "Entschärfung einer Fliegerbombe");
-        codes.put(17, "Beschädigung einer Brücke");
-        codes.put(18, "umgestürzter Baum im Gleis");
-        codes.put(19, "Unfall an einem Bahnübergang");
-        codes.put(20, "Tiere im Gleis");
-        codes.put(21, "Warten auf Fahrgäste aus einem anderen Zug");
-        codes.put(22, "Witterungsbedingte Störung");
-        codes.put(23, "Feuerwehreinsatz auf Bahngelände");
-        codes.put(24, "Verspätung im Ausland");
-        codes.put(25, "Warten auf weitere Wagen");
-        codes.put(28, "Gegenstände im Gleis");
-        codes.put(29, "Ersatzverkehr mit Bus ist eingerichtet");
-        codes.put(31, "Bauarbeiten");
-        codes.put(32, "Verzögerung beim Ein-/Ausstieg");
-        codes.put(33, "Oberleitungsstörung");
-        codes.put(34, "Signalstörung");
-        codes.put(35, "Streckensperrung");
-        codes.put(36, "technische Störung am Zug");
-        codes.put(38, "technische Störung an der Strecke");
-        codes.put(39, "Anhängen von zusätzlichen Wagen");
-        codes.put(40, "Stellwerksstörung /-ausfall");
-        codes.put(41, "Störung an einem Bahnübergang");
-        codes.put(42, "außerplanmäßige Geschwindigkeitsbeschränkung");
-        codes.put(43, "Verspätung eines vorausfahrenden Zuges");
-        codes.put(44, "Warten auf einen entgegenkommenden Zug");
-        codes.put(45, "Überholung");
-        codes.put(46, "Warten auf freie Einfahrt");
-        codes.put(47, "verspätete Bereitstellung des Zuges");
-        codes.put(48, "Verspätung aus vorheriger Fahrt");
-        codes.put(55, "technische Störung an einem anderen Zug");
-        codes.put(56, "Warten auf Fahrgäste aus einem Bus");
-        codes.put(57, "Zusätzlicher Halt zum Ein-/Ausstieg für Reisende");
-        codes.put(58, "Umleitung des Zuges");
-        codes.put(59, "Schnee und Eis");
-        codes.put(60, "Reduzierte Geschwindigkeit wegen Sturm");
-        codes.put(61, "Türstörung");
-        codes.put(62, "behobene technische Störung am Zug");
-        codes.put(63, "technische Untersuchung am Zug");
-        codes.put(64, "Weichenstörung");
-        codes.put(65, "Erdrutsch");
-        codes.put(66, "Hochwasser");
-        codes.put(70, "WLAN im gesamten Zug nicht verfügbar");
-        codes.put(71, "WLAN in einem/mehreren Wagen nicht verfügbar");
-        codes.put(72, "Info-/Entertainment nicht verfügbar");
-        codes.put(73, "Heute: Mehrzweckabteil vorne");
-        codes.put(74, "Heute: Mehrzweckabteil hinten");
-        codes.put(75, "Heute: 1. Klasse vorne");
-        codes.put(76, "Heute: 1. Klasse hinten");
-        codes.put(77, "ohne 1. Klasse");
-        codes.put(79, "ohne Mehrzweckabteil");
-        codes.put(80, "andere Reihenfolge der Wagen");
-        codes.put(82, "mehrere Wagen fehlen");
-        codes.put(83, "Störung fahrzeuggebundene Einstiegshilfe");
-        codes.put(84, "Zug verkehrt richtig gereiht");
-        codes.put(85, "ein Wagen fehlt");
-        codes.put(86, "gesamter Zug ohne Reservierung");
-        codes.put(87, "einzelne Wagen ohne Reservierung");
-        codes.put(88, "keine Qualitätsmängel");
-        codes.put(89, "Reservierungen sind wieder vorhanden");
-        codes.put(90, "kein gastronomisches Angebot");
-        codes.put(91, "fehlende Fahrradbeförderung");
-        codes.put(92, "Eingeschränkte Fahrradbeförderung");
-        codes.put(93, "keine behindertengerechte Einrichtung");
-        codes.put(94, "Ersatzbewirtschaftung");
-        codes.put(95, "Ohne behindertengerechtes WC");
-        codes.put(96, "Überbesetzung mit Kulanzleistungen");
-        codes.put(97, "Überbesetzung ohne Kulanzleistungen");
-        codes.put(98, "sonstige Qualitätsmängel");
-        codes.put(99, "Verzögerungen im Betriebsablauf");
+        CODES.put(0, "keine Verspätungsbegründung");
+        CODES.put(2, "Polizeiliche Ermittlung");
+        CODES.put(3, "Feuerwehreinsatz an der Strecke");
+        CODES.put(4, "kurzfristiger Personalausfall");
+        CODES.put(5, "ärztliche Versorgung eines Fahrgastes");
+        CODES.put(6, "Betätigen der Notbremse");
+        CODES.put(7, "Personen im Gleis");
+        CODES.put(8, "Notarzteinsatz am Gleis");
+        CODES.put(9, "Streikauswirkungen");
+        CODES.put(10, "Tiere im Gleis");
+        CODES.put(11, "Unwetter");
+        CODES.put(12, "Warten auf ein verspätetes Schiff");
+        CODES.put(13, "Pass- und Zollkontrolle");
+        CODES.put(14, "Technische Störung am Bahnhof");
+        CODES.put(15, "Beeinträchtigung durch Vandalismus");
+        CODES.put(16, "Entschärfung einer Fliegerbombe");
+        CODES.put(17, "Beschädigung einer Brücke");
+        CODES.put(18, "umgestürzter Baum im Gleis");
+        CODES.put(19, "Unfall an einem Bahnübergang");
+        CODES.put(20, "Tiere im Gleis");
+        CODES.put(21, "Warten auf Fahrgäste aus einem anderen Zug");
+        CODES.put(22, "Witterungsbedingte Störung");
+        CODES.put(23, "Feuerwehreinsatz auf Bahngelände");
+        CODES.put(24, "Verspätung im Ausland");
+        CODES.put(25, "Warten auf weitere Wagen");
+        CODES.put(28, "Gegenstände im Gleis");
+        CODES.put(29, "Ersatzverkehr mit Bus ist eingerichtet");
+        CODES.put(31, "Bauarbeiten");
+        CODES.put(32, "Verzögerung beim Ein-/Ausstieg");
+        CODES.put(33, "Oberleitungsstörung");
+        CODES.put(34, "Signalstörung");
+        CODES.put(35, "Streckensperrung");
+        CODES.put(36, "technische Störung am Zug");
+        CODES.put(38, "technische Störung an der Strecke");
+        CODES.put(39, "Anhängen von zusätzlichen Wagen");
+        CODES.put(40, "Stellwerksstörung /-ausfall");
+        CODES.put(41, "Störung an einem Bahnübergang");
+        CODES.put(42, "außerplanmäßige Geschwindigkeitsbeschränkung");
+        CODES.put(43, "Verspätung eines vorausfahrenden Zuges");
+        CODES.put(44, "Warten auf einen entgegenkommenden Zug");
+        CODES.put(45, "Überholung");
+        CODES.put(46, "Warten auf freie Einfahrt");
+        CODES.put(47, "verspätete Bereitstellung des Zuges");
+        CODES.put(48, "Verspätung aus vorheriger Fahrt");
+        CODES.put(55, "technische Störung an einem anderen Zug");
+        CODES.put(56, "Warten auf Fahrgäste aus einem Bus");
+        CODES.put(57, "Zusätzlicher Halt zum Ein-/Ausstieg für Reisende");
+        CODES.put(58, "Umleitung des Zuges");
+        CODES.put(59, "Schnee und Eis");
+        CODES.put(60, "Reduzierte Geschwindigkeit wegen Sturm");
+        CODES.put(61, "Türstörung");
+        CODES.put(62, "behobene technische Störung am Zug");
+        CODES.put(63, "technische Untersuchung am Zug");
+        CODES.put(64, "Weichenstörung");
+        CODES.put(65, "Erdrutsch");
+        CODES.put(66, "Hochwasser");
+        CODES.put(70, "WLAN im gesamten Zug nicht verfügbar");
+        CODES.put(71, "WLAN in einem/mehreren Wagen nicht verfügbar");
+        CODES.put(72, "Info-/Entertainment nicht verfügbar");
+        CODES.put(73, "Heute: Mehrzweckabteil vorne");
+        CODES.put(74, "Heute: Mehrzweckabteil hinten");
+        CODES.put(75, "Heute: 1. Klasse vorne");
+        CODES.put(76, "Heute: 1. Klasse hinten");
+        CODES.put(77, "ohne 1. Klasse");
+        CODES.put(79, "ohne Mehrzweckabteil");
+        CODES.put(80, "andere Reihenfolge der Wagen");
+        CODES.put(82, "mehrere Wagen fehlen");
+        CODES.put(83, "Störung fahrzeuggebundene Einstiegshilfe");
+        CODES.put(84, "Zug verkehrt richtig gereiht");
+        CODES.put(85, "ein Wagen fehlt");
+        CODES.put(86, "gesamter Zug ohne Reservierung");
+        CODES.put(87, "einzelne Wagen ohne Reservierung");
+        CODES.put(88, "keine Qualitätsmängel");
+        CODES.put(89, "Reservierungen sind wieder vorhanden");
+        CODES.put(90, "kein gastronomisches Angebot");
+        CODES.put(91, "fehlende Fahrradbeförderung");
+        CODES.put(92, "Eingeschränkte Fahrradbeförderung");
+        CODES.put(93, "keine behindertengerechte Einrichtung");
+        CODES.put(94, "Ersatzbewirtschaftung");
+        CODES.put(95, "Ohne behindertengerechtes WC");
+        CODES.put(96, "Überbesetzung mit Kulanzleistungen");
+        CODES.put(97, "Überbesetzung ohne Kulanzleistungen");
+        CODES.put(98, "sonstige Qualitätsmängel");
+        CODES.put(99, "Verzögerungen im Betriebsablauf");
     }
 
     private MessageCodes() {
@@ -124,7 +124,7 @@ public final class MessageCodes {
      * Returns the message for the given code or emtpy string if not present.
      */
     public static String getMessage(final int code) {
-        final String message = codes.get(code);
+        final String message = CODES.get(code);
         if (message == null) {
             return "";
         } else {
index dee9af962651320edc682c3b9422f92ffbd5f8a7..e1a049bf7bc09b00f323a45843d6a49f6864a0e9 100644 (file)
@@ -52,5 +52,5 @@ public enum TimetableStopFilter implements TimetableStopPredicate {
         public boolean test(TimetableStop t) {
             return t.getAr() != null;
         }
-    };
+    }
 }
index 4237a946a60e1828ccfdd05d569f1b098c884bf1..2d48619b209bf5f708150a95f84196a2799f7b7c 100644 (file)
@@ -31,7 +31,8 @@ import org.openhab.core.types.UnDefType;
  * 
  * chapter "1.2.7 TripLabel" in Technical Interface Description for external Developers
  *
- * @see https://developer.deutschebahn.com/store/apis/info?name=Timetables&version=v1&provider=DBOpenData&#tab1
+ * @see @see <a href="https://developers.deutschebahn.com/db-api-marketplace/apis/product/timetables">DB API
+ *      Marketplace</a>
  * 
  * @author Sönke Küper - Initial contribution.
  * 
index be918aa13ec7e255b419f89375406af4f1ec2990..b856989faef64592a500d4830a9a8241500cb424 100644 (file)
@@ -31,7 +31,7 @@ public final class ChannelNameEquals extends FilterToken {
 
     private final String channelName;
     private final Pattern filterValue;
-    private String channelGroup;
+    private final String channelGroup;
 
     /**
      * Creates an new {@link ChannelNameEquals}.
@@ -66,7 +66,7 @@ public final class ChannelNameEquals extends FilterToken {
 
     @Override
     public String toString() {
-        return this.channelGroup + "#" + channelName + "=\"" + this.filterValue.toString() + "\"";
+        return this.channelGroup + "#" + channelName + "=\"" + this.filterValue + "\"";
     }
 
     @Override
index 2ee5d2a5e0cf773ff17f14604a4b5130e5d97e16..e64cc5915ac9161a28da11ba32a436871da30d54 100644 (file)
@@ -31,7 +31,7 @@ public final class FilterParser {
     private abstract static class State implements FilterTokenVisitor<State> {
 
         @Nullable
-        private State previousState;
+        private final State previousState;
 
         public State(@Nullable State previousState) {
             this.previousState = previousState;
@@ -110,7 +110,7 @@ public final class FilterParser {
 
         @Override
         public State handle(BracketCloseToken token) throws FilterParserException {
-            throw new FilterParserException("Unexpected token " + token.toString() + " at " + token.getPosition());
+            throw new FilterParserException("Unexpected token " + token + " at " + token.getPosition());
         }
 
         @Override
@@ -147,14 +147,14 @@ public final class FilterParser {
 
         @Override
         public State handle(OrOperator operator) throws FilterParserException {
-            throw new FilterParserException("Invalid second argument for '&' operator " + operator.toString() + " at "
-                    + operator.getPosition());
+            throw new FilterParserException(
+                    "Invalid second argument for '&' operator " + operator + " at " + operator.getPosition());
         }
 
         @Override
         public State handle(AndOperator operator) throws FilterParserException {
-            throw new FilterParserException("Invalid second argument for '&' operator " + operator.toString() + " at "
-                    + operator.getPosition());
+            throw new FilterParserException(
+                    "Invalid second argument for '&' operator " + operator + " at " + operator.getPosition());
         }
 
         @Override
@@ -165,7 +165,7 @@ public final class FilterParser {
         @Override
         public State handle(BracketCloseToken token) throws FilterParserException {
             throw new FilterParserException(
-                    "Invalid second argument for '&' operator " + token.toString() + " at " + token.getPosition());
+                    "Invalid second argument for '&' operator " + token + " at " + token.getPosition());
         }
 
         @Override
@@ -193,14 +193,14 @@ public final class FilterParser {
 
         @Override
         public State handle(OrOperator operator) throws FilterParserException {
-            throw new FilterParserException("Invalid second argument for '|' operator " + operator.toString() + " at "
-                    + operator.getPosition());
+            throw new FilterParserException(
+                    "Invalid second argument for '|' operator " + operator + " at " + operator.getPosition());
         }
 
         @Override
         public State handle(AndOperator operator) throws FilterParserException {
-            throw new FilterParserException("Invalid second argument for '|' operator " + operator.toString() + " at "
-                    + operator.getPosition());
+            throw new FilterParserException(
+                    "Invalid second argument for '|' operator " + operator + " at " + operator.getPosition());
         }
 
         @Override
@@ -211,7 +211,7 @@ public final class FilterParser {
         @Override
         public State handle(BracketCloseToken token) throws FilterParserException {
             throw new FilterParserException(
-                    "Invalid second argument for '|' operator " + token.toString() + " at " + token.getPosition());
+                    "Invalid second argument for '|' operator " + token + " at " + token.getPosition());
         }
 
         @Override
index 0b22efe56e4bbb1c23dafea8b30b4b0e770854c3..e0074416abb9df3d86e803f5be8a74a50301b142 100644 (file)
@@ -146,7 +146,7 @@ public final class FilterScanner {
 
         private final int startPosition;
         private final String channelName;
-        private String channelGroup;
+        private final String channelGroup;
 
         /**
          * Creates an new {@link ExpectQuotesState}.
index 6c5864375d8ae14daf2581da72d3f564ecf9a854..e1664c4bd1cdf9efdef62ee004b99c8bb81b41bd 100644 (file)
@@ -21,7 +21,7 @@ import org.openhab.binding.deutschebahn.internal.timetable.dto.Timetable;
 /**
  * Interface for timetables API in V1.
  * 
- * @see https://developer.deutschebahn.com/store/apis/info?name=Timetables&version=v1&provider=DBOpenData
+ * @see <a href="https://developers.deutschebahn.com/db-api-marketplace/apis/product/timetables">DB API Marketplace</a>
  *
  * @author Sönke Küper - initial contribution
  */
@@ -33,7 +33,7 @@ public interface TimetablesV1Api {
      * Calls the "/plan" endpoint of the rest-service.
      *
      * REST-endpoint documentation: (from
-     * {@see https://developer.deutschebahn.com/store/apis/info?name=Timetables&version=v1&provider=DBOpenData}).
+     * {@see https://developers.deutschebahn.com/db-api-marketplace/apis/product/timetables}).
      * Returns a Timetable object (see Timetable) that contains planned data for the specified station (evaNo)
      * within the hourly time slice given by date (format YYMMDD) and hour (format HH). The data includes stops
      * for all trips that arrive or depart within that slice. There is a small overlap between slices since some
@@ -58,7 +58,7 @@ public interface TimetablesV1Api {
      * Calls the "/fchg" endpoint of the rest-service.
      *
      * REST-endpoint documentation: (from
-     * {@see https://developer.deutschebahn.com/store/apis/info?name=Timetables&version=v1&provider=DBOpenData}).
+     * {@see https://developers.deutschebahn.com/db-api-marketplace/apis/product/timetables}).
      * Returns a Timetable object (see Timetable) that contains all known changes for the station given by evaNo.
      *
      * The data includes all known changes from now on until undefinitely into the future. Once changes become obsolete
@@ -82,7 +82,7 @@ public interface TimetablesV1Api {
      * Calls the "/plan" endpoint of the rest-service.
      *
      * REST-endpoint documentation: (from
-     * {@see https://developer.deutschebahn.com/store/apis/info?name=Timetables&version=v1&provider=DBOpenData}).
+     * {@see https://developers.deutschebahn.com/db-api-marketplace/apis/product/timetables}).
      * Returns a Timetable object (see Timetable) that contains all recent changes for the station given by evaNo.
      * Recent changes are always a subset of the full changes. They may equal full changes but are typically much
      * smaller.
index c254c0e251ea2596ae1e98ea97935c6198bb15b3..d8d565247c0a8f0fcd1b4001d469e93b3b9f0aa3 100644 (file)
  */
 package org.openhab.binding.deutschebahn.internal.timetable;
 
-import java.net.URISyntaxException;
-
 import javax.xml.bind.JAXBException;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.openhab.binding.deutschebahn.internal.timetable.TimetablesV1Impl.HttpCallable;
-import org.xml.sax.SAXException;
 
 /**
  * Factory for {@link TimetablesV1Api}.
@@ -31,6 +28,6 @@ public interface TimetablesV1ApiFactory {
     /**
      * Creates an new instance of the {@link TimetablesV1Api}.
      */
-    public abstract TimetablesV1Api create(final String authToken, final HttpCallable httpCallable)
-            throws JAXBException, SAXException, URISyntaxException;
+    public abstract TimetablesV1Api create(final String clientId, final String clientSecret,
+            final HttpCallable httpCallable) throws JAXBException;
 }
index 7dae36c77ecd4b8bb7681148ba2345c3a38a96bf..7e1b585554ac3de801cbd083b13298d212e6759d 100644 (file)
@@ -15,7 +15,6 @@ package org.openhab.binding.deutschebahn.internal.timetable;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.StringReader;
-import java.net.URISyntaxException;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.Properties;
@@ -50,7 +49,7 @@ public final class TimetablesV1Impl implements TimetablesV1Api {
 
         /**
          * Executes the given <code>url</code> with the given <code>httpMethod</code>.
-         * Furthermore the <code>http.proxyXXX</code> System variables are read and
+         * Furthermore, the <code>http.proxyXXX</code> System variables are read and
          * set into the {@link org.eclipse.jetty.client.HttpClient}.
          *
          * @param httpMethod the HTTP method to use
@@ -61,35 +60,43 @@ public final class TimetablesV1Impl implements TimetablesV1Api {
          * @param contentType the content type of the given <code>content</code>
          * @param timeout the socket timeout in milliseconds to wait for data
          * @return the response body or <code>NULL</code> when the request went wrong
-         * @throws IOException when the request execution failed, timed out or it was interrupted
+         * @throws IOException when the request execution failed, timed out, or it was interrupted
          */
         public abstract String executeUrl(String httpMethod, String url, Properties httpHeaders,
                 @Nullable InputStream content, @Nullable String contentType, int timeout) throws IOException;
     }
 
-    private static final String PLAN_URL = "https://api.deutschebahn.com/timetables/v1/plan/%evaNo%/%date%/%hour%";
-    private static final String FCHG_URL = "https://api.deutschebahn.com/timetables/v1/fchg/%evaNo%";
-    private static final String RCHG_URL = "https://api.deutschebahn.com/timetables/v1/rchg/%evaNo%";
+    private static final String BASE_URL = "https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1";
+    private static final String PLAN_URL = BASE_URL + "/plan/%evaNo%/%date%/%hour%";
+    private static final String FCHG_URL = BASE_URL + "/fchg/%evaNo%";
+    private static final String RCHG_URL = BASE_URL + "/rchg/%evaNo%";
+
+    private static final String DB_CLIENT_ID_HEADER_NAME = "DB-Client-Id";
+    private static final String DB_CLIENT_SECRET_HEADER_NAME = "DB-Api-Key";
 
     private static final int REQUEST_TIMEOUT_MS = (int) TimeUnit.SECONDS.toMillis(30);
     private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyMMdd");
     private static final SimpleDateFormat HOUR_FORMAT = new SimpleDateFormat("HH");
 
-    private final String authToken;
+    private final String clientId;
+    private final String clientSecret;
     private final HttpCallable httpCallable;
 
     private final Logger logger = LoggerFactory.getLogger(TimetablesV1Impl.class);
-    private JAXBContext jaxbContext;
+    private final JAXBContext jaxbContext;
     // private Schema schema;
 
     /**
-     * Creates an new {@link TimetablesV1Impl}.
+     * Creates a new {@link TimetablesV1Impl}.
      * 
-     * @param authToken The authentication token for timetable api on developer.deutschebahn.com.
+     * @param clientSecret The client secret for application with linked timetable api on developers.deutschebahn.com.
      */
-    public TimetablesV1Impl(final String authToken, final HttpCallable httpCallable)
-            throws JAXBException, SAXException, URISyntaxException {
-        this.authToken = authToken;
+    public TimetablesV1Impl( //
+            final String clientId, //
+            final String clientSecret, //
+            final HttpCallable httpCallable) throws JAXBException {
+        this.clientId = clientId;
+        this.clientSecret = clientSecret;
         this.httpCallable = httpCallable;
 
         // The results from webservice does not conform to the schema provided. The triplabel-Element (tl) is expected
@@ -149,7 +156,7 @@ public final class TimetablesV1Impl implements TimetablesV1Api {
         }
 
         try {
-            return unmarshal(response, Timetable.class);
+            return unmarshal(response);
         } catch (JAXBException | SAXException e) {
             this.logger.error("Error parsing response from timetable api.", e);
             throw new IOException(e);
@@ -162,22 +169,21 @@ public final class TimetablesV1Impl implements TimetablesV1Api {
     private Properties createHeaders() {
         final Properties headers = new Properties();
         headers.put(HttpHeader.ACCEPT.asString(), "application/xml");
-        headers.put(HttpHeader.AUTHORIZATION.asString(), "Bearer " + this.authToken);
+        headers.put(DB_CLIENT_ID_HEADER_NAME, this.clientId);
+        headers.put(DB_CLIENT_SECRET_HEADER_NAME, this.clientSecret);
         return headers;
     }
 
-    private <T> T unmarshal(final String xmlContent, final Class<T> clazz) throws JAXBException, SAXException {
+    private <T> T unmarshal(final String xmlContent) throws JAXBException, SAXException {
         return unmarshal( //
                 jaxbContext, //
                 null, // Provide no schema, due webservice results are not schema-valid.
-                xmlContent, //
-                clazz //
-        );
+                xmlContent);
     }
 
     @SuppressWarnings("unchecked")
     private static <T> T unmarshal(final JAXBContext jaxbContext, @Nullable final Schema schema,
-            final String xmlContent, final Class<T> clss) throws JAXBException {
+            final String xmlContent) throws JAXBException {
         final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
         unmarshaller.setSchema(schema);
         final JAXBElement<T> resultObject = (JAXBElement<T>) unmarshaller.unmarshal(new StringReader(xmlContent));
index 93aa011039db538604ef4863c40b6d218fe65d71..b59ed0707c792f95ed28399dbea1caf2bde3f27a 100644 (file)
@@ -8,22 +8,24 @@ binding.deutschebahn.description = This binding provides timetable information f
 thing-type.deutschebahn.timetable.label = Deutsche Bahn Timetable
 thing-type.deutschebahn.timetable.description = Connection to the timetable API of Deutsche Bahn. Provides timetable data that can be displayed using the train things.
 thing-type.deutschebahn.train.label = Train
-thing-type.deutschebahn.train.description = Displays informations about an train within the given timetable at one station.
+thing-type.deutschebahn.train.description = Displays information about a train within the given timetable at one station.
 thing-type.deutschebahn.train.group.arrival.label = Arrival
-thing-type.deutschebahn.train.group.arrival.description = Contains all informations about the arrival of the train at the station. Channels may be empty, if the trains starts at this station.
+thing-type.deutschebahn.train.group.arrival.description = Contains all information about the arrival of the train at the station. Channels may be empty, if the trains starts at this station.
 thing-type.deutschebahn.train.group.departure.label = Departure
-thing-type.deutschebahn.train.group.departure.description = Contains all informations about the departure of the train at the station. Channels may be empty, if the trains ends at this station.
+thing-type.deutschebahn.train.group.departure.description = Contains all information about the departure of the train at the station. Channels may be empty, if the trains ends at this station.
 thing-type.deutschebahn.train.group.trip.label = Trip
-thing-type.deutschebahn.train.group.trip.description = Contains all informations about the trip of the train.
+thing-type.deutschebahn.train.group.trip.description = Contains all information about the trip of the train.
 
 # thing types config
 
-thing-type.config.deutschebahn.timetable.accessToken.label = Access Token
-thing-type.config.deutschebahn.timetable.accessToken.description = Access Token from Deutsche Bahn developer portal for accessing the webservice api.
+thing-type.config.deutschebahn.timetable.clientId.label = Client Id
+thing-type.config.deutschebahn.timetable.clientId.description = Client ID from Application within DB API Marketplace for accessing the timetables webservice api.
+thing-type.config.deutschebahn.timetable.clientSecret.label = Client Secret (API Key)
+thing-type.config.deutschebahn.timetable.clientSecret.description = Client Secret (API Key) from Application within DB API Marketplace for accessing the timetables webservice api.
 thing-type.config.deutschebahn.timetable.evaNo.label = EvaNo of Station
 thing-type.config.deutschebahn.timetable.evaNo.description = evaNo of the station, for which the timetable should be requested. see https://data.deutschebahn.com/dataset.tags.EVA-Nr..html
 thing-type.config.deutschebahn.timetable.trainFilter.label = Train Filter
-thing-type.config.deutschebahn.timetable.trainFilter.description = Selects the trains that will be be displayed in this timetable. If not set only departures will be provided.
+thing-type.config.deutschebahn.timetable.trainFilter.description = Selects the trains that will be displayed in this timetable. If not set only departures will be provided.
 thing-type.config.deutschebahn.timetable.trainFilter.option.all = All
 thing-type.config.deutschebahn.timetable.trainFilter.option.arrivals = Arrivals
 thing-type.config.deutschebahn.timetable.trainFilter.option.departures = Departures
@@ -33,9 +35,9 @@ thing-type.config.deutschebahn.train.position.description = Selects the position
 # channel group types
 
 channel-group-type.deutschebahn.eventAttributes.label = Event Attributes
-channel-group-type.deutschebahn.eventAttributes.description = Contains all attributes for an event (arrival / departure) of an train at the station.
+channel-group-type.deutschebahn.eventAttributes.description = Contains all attributes for an event (arrival / departure) of a train at the station.
 channel-group-type.deutschebahn.tripAttributes.label = Trip Attributes
-channel-group-type.deutschebahn.tripAttributes.description = Contains all informations about the trip of the train.
+channel-group-type.deutschebahn.tripAttributes.description = Contains all information about the trip of the train.
 
 # channel types
 
@@ -51,7 +53,7 @@ channel-type.deutschebahn.changed-final-station.description = Changed final stat
 channel-type.deutschebahn.changed-intermediate-stations.label = Changed Intermediate Stations
 channel-type.deutschebahn.changed-intermediate-stations.description = Returns the changed stations this train came from (for arrivals) or the stations this train will go to (for departures). Stations will be separated by single dash.
 channel-type.deutschebahn.changed-path.label = Changed Path
-channel-type.deutschebahn.changed-path.description = Provides the planned path of a train. For arrival, the path indicates the stations that come before the current station. The first element then is the trip’s start station. For departure, the path indicates the stations that come after the current station. The last ele-ment in the path then is the trip’s destination station. Note that the current station is never included in the path (neither for arrival nor for departure).
+channel-type.deutschebahn.changed-path.description = Provides the planned path of a train. For arrival, the path indicates the stations that come before the current station. The first element then is the trip’s start station. For departure, the path indicates the stations that come after the current station. The last element in the path then is the trip’s destination station. Note that the current station is never included in the path (neither for arrival nor for departure).
 channel-type.deutschebahn.changed-platform.label = Changed Platform
 channel-type.deutschebahn.changed-platform.description = Provides the changed platform of a train.
 channel-type.deutschebahn.changed-status.label = Changed Status
@@ -71,7 +73,7 @@ channel-type.deutschebahn.hidden.description = On if the event should not be sho
 channel-type.deutschebahn.line.label = Line
 channel-type.deutschebahn.line.description = The line indicator.
 channel-type.deutschebahn.messages.label = Messages
-channel-type.deutschebahn.messages.description = Messages for this train. Contains all translated codes from the messages of the selected train stop. Multiple messages will be separated with an single dash.
+channel-type.deutschebahn.messages.description = Messages for this train. Contains all translated codes from the messages of the selected train stop. Multiple messages will be separated with a single dash.
 channel-type.deutschebahn.number.label = Number
 channel-type.deutschebahn.number.description = Provides the trip/train number, e.g. "4523".
 channel-type.deutschebahn.owner.label = Owner
@@ -83,7 +85,7 @@ channel-type.deutschebahn.planned-final-station.description = Planned final stat
 channel-type.deutschebahn.planned-intermediate-stations.label = Planned Intermediate Stations
 channel-type.deutschebahn.planned-intermediate-stations.description = Returns the planned stations this train came from (for arrivals) or the stations this train will go to (for departures). Stations will be separated by single dash.
 channel-type.deutschebahn.planned-path.label = Planned Path
-channel-type.deutschebahn.planned-path.description = Provides the planned path of a train. For arrival, the path indicates the stations that come before the current station. The first element then is the trip’s start station. For departure, the path indicates the stations that come after the current station. The last ele-ment in the path then is the trip’s destination station. Note that the current station is never included in the path (neither for arrival nor for departure).
+channel-type.deutschebahn.planned-path.description = Provides the planned path of a train. For arrival, the path indicates the stations that come before the current station. The first element then is the trip’s start station. For departure, the path indicates the stations that come after the current station. The last element in the path then is the trip’s destination station. Note that the current station is never included in the path (neither for arrival nor for departure).
 channel-type.deutschebahn.planned-platform.label = Planned Platform
 channel-type.deutschebahn.planned-platform.description = Provides the planned platform of a train.
 channel-type.deutschebahn.planned-status.label = Planned Status
index 18eebbe775a25aa873ecd929f78b794dd12cc5f6..8bbcce8f12cb06d20ceaccf01b3e6de375188711 100644 (file)
                        train things.</description>
 
                <config-description>
-                       <parameter name="accessToken" type="text" required="true">
-                               <label>Access Token</label>
-                               <description>Access Token from Deutsche Bahn developer portal for accessing the webservice api.</description>
+                       <parameter name="clientId" type="text" required="true">
+                               <label>Client Id</label>
+                               <description>Client ID from Application within DB API Marketplace for accessing the timetables webservice api.</description>
+                       </parameter>
+                       <parameter name="clientSecret" type="text" required="true">
+                               <label>Client Secret (API Key)</label>
+                               <description>Client Secret (API Key) from Application within DB API Marketplace for accessing the timetables
+                                       webservice api.</description>
                        </parameter>
                        <parameter name="evaNo" type="text" required="true" pattern="80\d{5,5}">
                                <label>EvaNo of Station</label>
@@ -24,7 +29,7 @@
                                <advanced>true</advanced>
                                <default>departures</default>
                                <label>Train Filter</label>
-                               <description>Selects the trains that will be be displayed in this timetable. If not set only departures will be
+                               <description>Selects the trains that will be displayed in this timetable. If not set only departures will be
                                        provided.</description>
                                <options>
                                        <option value="all">All</option>
                        <bridge-type-ref id="timetable"/>
                </supported-bridge-type-refs>
                <label>Train</label>
-               <description>Displays informations about an train within the given timetable at one station.</description>
+               <description>Displays information about a train within the given timetable at one station.</description>
                <channel-groups>
                        <channel-group typeId="tripAttributes" id="trip">
                                <label>Trip</label>
-                               <description>Contains all informations about the trip of the train.
+                               <description>Contains all information about the trip of the train.
                                </description>
                        </channel-group>
                        <channel-group typeId="eventAttributes" id="arrival">
                                <label>Arrival</label>
-                               <description>Contains all informations about the arrival of the train at the station.
+                               <description>Contains all information about the arrival of the train at the station.
                                        Channels may be empty, if the
                                        trains starts at this station.
                                </description>
                        </channel-group>
                        <channel-group typeId="eventAttributes" id="departure">
                                <label>Departure</label>
-                               <description>Contains all informations about the departure of the train at the station.
+                               <description>Contains all information about the departure of the train at the station.
                                        Channels may be empty, if the
                                        trains ends at this station.
                                </description>
@@ -77,7 +82,7 @@
 
        <channel-group-type id="tripAttributes">
                <label>Trip Attributes</label>
-               <description>Contains all informations about the trip of the train.</description>
+               <description>Contains all information about the trip of the train.</description>
                <channels>
                        <channel typeId="category" id="category"/>
                        <channel typeId="number" id="number"/>
@@ -89,7 +94,7 @@
 
        <channel-group-type id="eventAttributes">
                <label>Event Attributes</label>
-               <description>Contains all attributes for an event (arrival / departure) of an train at the station.</description>
+               <description>Contains all attributes for an event (arrival / departure) of a train at the station.</description>
                <channels>
                        <channel typeId="planned-path" id="planned-path"/>
                        <channel typeId="changed-path" id="changed-path"/>
                <item-type>String</item-type>
                <label>Messages</label>
                <description>Messages for this train. Contains all translated codes from the messages of the selected train stop.
-                       Multiple messages will be separated with an single dash.</description>
+                       Multiple messages will be separated with a single dash.</description>
                <state readOnly="true"/>
        </channel-type>
 
                        For arrival, the path indicates the stations that come before the
                        current station. The first element then is the trip’s
                        start station. For departure, the path indicates the stations
-                       that come after the current station. The last ele-ment
+                       that come after the current station. The last element
                        in the path then is the trip’s destination station. Note that
                        the current station is never included in the path
                        (neither for arrival nor for departure).</description>
                        For arrival, the path indicates the stations that come before the
                        current station. The first element then is the trip’s
                        start station. For departure, the path indicates the stations
-                       that come after the current station. The last ele-ment
+                       that come after the current station. The last element
                        in the path then is the trip’s destination station. Note that
                        the current station is never included in the path
                        (neither for arrival nor for departure).</description>
index ae05dc37bc165bddd965b2225950637f2fca9ffd..4fb18028eafe6716a4c586243ca00438a2642998 100644 (file)
  */
 package org.openhab.binding.deutschebahn.internal;
 
-import static org.mockito.ArgumentMatchers.*;
-import static org.mockito.Mockito.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import java.util.ArrayList;
 import java.util.Calendar;
@@ -172,7 +177,7 @@ public class DeutscheBahnTimetableHandlerTest implements TimetablesV1ImplTestHel
         final TimetablesV1ApiStub stubWithError = TimetablesV1ApiStub.createWithException();
 
         final DeutscheBahnTimetableHandler handler = createAndInitHandler(callback, bridge,
-                (String authToken, HttpCallable httpCallable) -> stubWithError);
+                (String clientId, String clientSecret, HttpCallable httpCallable) -> stubWithError);
 
         try {
             verify(callback).statusUpdated(eq(bridge), argThat(arg -> arg.getStatus().equals(ThingStatus.UNKNOWN)));
@@ -212,7 +217,7 @@ public class DeutscheBahnTimetableHandlerTest implements TimetablesV1ImplTestHel
         final TimetablesV1ApiStub stubWithData = TimetablesV1ApiStub.createWithResult(timetable);
 
         final DeutscheBahnTimetableHandler handler = createAndInitHandler(callback, bridge,
-                (String authToken, HttpCallable httpCallable) -> stubWithData);
+                (String clientId, String clientSecret, HttpCallable httpCallable) -> stubWithData);
 
         try {
             verify(callback).statusUpdated(eq(bridge), argThat(arg -> arg.getStatus().equals(ThingStatus.UNKNOWN)));
index dd856c30cfc22de4b874fbf6cfc280dc5fdc3e71..977b608d9a1b9407e9601dac3a4f177c0a56ede7 100644 (file)
@@ -45,11 +45,11 @@ public class TimetableLoaderTest implements TimetablesV1ImplTestHelper {
 
         final List<TimetableStop> stops = loader.getTimetableStops();
         assertThat(timeTableTestModule.getRequestedPlanUrls(),
-                contains("https://api.deutschebahn.com/timetables/v1/plan/8000226/210816/09",
-                        "https://api.deutschebahn.com/timetables/v1/plan/8000226/210816/10",
-                        "https://api.deutschebahn.com/timetables/v1/plan/8000226/210816/11"));
+                contains("https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/plan/8000226/210816/09",
+                        "https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/plan/8000226/210816/10",
+                        "https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/plan/8000226/210816/11"));
         assertThat(timeTableTestModule.getRequestedFullChangesUrls(),
-                contains("https://api.deutschebahn.com/timetables/v1/fchg/8000226"));
+                contains("https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/fchg/8000226"));
         assertThat(timeTableTestModule.getRequestedRecentChangesUrls(), empty());
 
         assertThat(stops, hasSize(21));
@@ -75,9 +75,9 @@ public class TimetableLoaderTest implements TimetablesV1ImplTestHelper {
 
         final List<TimetableStop> stops = loader.getTimetableStops();
         assertThat(timeTableTestModule.getRequestedPlanUrls(),
-                contains("https://api.deutschebahn.com/timetables/v1/plan/8000226/210816/09"));
+                contains("https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/plan/8000226/210816/09"));
         assertThat(timeTableTestModule.getRequestedFullChangesUrls(),
-                contains("https://api.deutschebahn.com/timetables/v1/fchg/8000226"));
+                contains("https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/fchg/8000226"));
         assertThat(timeTableTestModule.getRequestedRecentChangesUrls(), empty());
 
         assertThat(stops, hasSize(8));
@@ -91,11 +91,11 @@ public class TimetableLoaderTest implements TimetablesV1ImplTestHelper {
         final List<TimetableStop> stops02 = loader.getTimetableStops();
         assertThat(stops02, hasSize(13));
         assertThat(timeTableTestModule.getRequestedPlanUrls(),
-                contains("https://api.deutschebahn.com/timetables/v1/plan/8000226/210816/09",
-                        "https://api.deutschebahn.com/timetables/v1/plan/8000226/210816/10"));
+                contains("https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/plan/8000226/210816/09",
+                        "https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/plan/8000226/210816/10"));
         assertThat(timeTableTestModule.getRequestedFullChangesUrls(),
-                contains("https://api.deutschebahn.com/timetables/v1/fchg/8000226",
-                        "https://api.deutschebahn.com/timetables/v1/fchg/8000226"));
+                contains("https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/fchg/8000226",
+                        "https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/fchg/8000226"));
         assertThat(timeTableTestModule.getRequestedRecentChangesUrls(), empty());
 
         assertEquals("-5296516961807204721-2108160906-5", stops02.get(0).getId());
@@ -114,9 +114,9 @@ public class TimetableLoaderTest implements TimetablesV1ImplTestHelper {
         // First call - plan and full changes are requested.
         loader.getTimetableStops();
         assertThat(timeTableTestModule.getRequestedPlanUrls(),
-                contains("https://api.deutschebahn.com/timetables/v1/plan/8000226/210816/09"));
+                contains("https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/plan/8000226/210816/09"));
         assertThat(timeTableTestModule.getRequestedFullChangesUrls(),
-                contains("https://api.deutschebahn.com/timetables/v1/fchg/8000226"));
+                contains("https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/fchg/8000226"));
         assertThat(timeTableTestModule.getRequestedRecentChangesUrls(), empty());
 
         // Changes are updated only every 30 seconds, so move clock ahead 20 seconds, no request is made
@@ -124,43 +124,43 @@ public class TimetableLoaderTest implements TimetablesV1ImplTestHelper {
         loader.getTimetableStops();
 
         assertThat(timeTableTestModule.getRequestedPlanUrls(),
-                contains("https://api.deutschebahn.com/timetables/v1/plan/8000226/210816/09"));
+                contains("https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/plan/8000226/210816/09"));
         assertThat(timeTableTestModule.getRequestedFullChangesUrls(),
-                contains("https://api.deutschebahn.com/timetables/v1/fchg/8000226"));
+                contains("https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/fchg/8000226"));
         assertThat(timeTableTestModule.getRequestedRecentChangesUrls(), empty());
 
         // Move ahead 10 seconds, so recent changes are fetched
         timeProvider.moveAhead(10);
         loader.getTimetableStops();
         assertThat(timeTableTestModule.getRequestedPlanUrls(),
-                contains("https://api.deutschebahn.com/timetables/v1/plan/8000226/210816/09"));
+                contains("https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/plan/8000226/210816/09"));
         assertThat(timeTableTestModule.getRequestedFullChangesUrls(),
-                contains("https://api.deutschebahn.com/timetables/v1/fchg/8000226"));
+                contains("https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/fchg/8000226"));
         assertThat(timeTableTestModule.getRequestedRecentChangesUrls(),
-                contains("https://api.deutschebahn.com/timetables/v1/rchg/8000226"));
+                contains("https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/rchg/8000226"));
 
         // Move again ahead 30 seconds, recent changes are fetched again
         timeProvider.moveAhead(30);
         loader.getTimetableStops();
         assertThat(timeTableTestModule.getRequestedPlanUrls(),
-                contains("https://api.deutschebahn.com/timetables/v1/plan/8000226/210816/09"));
+                contains("https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/plan/8000226/210816/09"));
         assertThat(timeTableTestModule.getRequestedFullChangesUrls(),
-                contains("https://api.deutschebahn.com/timetables/v1/fchg/8000226"));
+                contains("https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/fchg/8000226"));
         assertThat(timeTableTestModule.getRequestedRecentChangesUrls(),
-                contains("https://api.deutschebahn.com/timetables/v1/rchg/8000226",
-                        "https://api.deutschebahn.com/timetables/v1/rchg/8000226"));
+                contains("https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/rchg/8000226",
+                        "https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/rchg/8000226"));
 
         // If recent change were not updated last 120 seconds the full changes must be requested
         timeProvider.moveAhead(120);
         loader.getTimetableStops();
         assertThat(timeTableTestModule.getRequestedPlanUrls(),
-                contains("https://api.deutschebahn.com/timetables/v1/plan/8000226/210816/09"));
+                contains("https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/plan/8000226/210816/09"));
         assertThat(timeTableTestModule.getRequestedFullChangesUrls(),
-                contains("https://api.deutschebahn.com/timetables/v1/fchg/8000226",
-                        "https://api.deutschebahn.com/timetables/v1/fchg/8000226"));
+                contains("https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/fchg/8000226",
+                        "https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/fchg/8000226"));
         assertThat(timeTableTestModule.getRequestedRecentChangesUrls(),
-                contains("https://api.deutschebahn.com/timetables/v1/rchg/8000226",
-                        "https://api.deutschebahn.com/timetables/v1/rchg/8000226"));
+                contains("https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/rchg/8000226",
+                        "https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/rchg/8000226"));
     }
 
     @Test
@@ -171,7 +171,8 @@ public class TimetableLoaderTest implements TimetablesV1ImplTestHelper {
                 EventType.ARRIVAL, timeProvider, EVA_LEHRTE, 20);
 
         // Simulate that only one url is available
-        timeTableTestModule.addAvailableUrl("https://api.deutschebahn.com/timetables/v1/plan/8000226/210816/09");
+        timeTableTestModule.addAvailableUrl(
+                "https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/plan/8000226/210816/09");
 
         timeProvider.time = new GregorianCalendar(2021, Calendar.AUGUST, 16, 9, 0);
 
@@ -191,7 +192,8 @@ public class TimetableLoaderTest implements TimetablesV1ImplTestHelper {
                 EventType.DEPARTURE, timeProvider, EVA_LEHRTE, 20);
 
         // Simulate that only one url is available
-        timeTableTestModule.addAvailableUrl("https://api.deutschebahn.com/timetables/v1/plan/8000226/210816/09");
+        timeTableTestModule.addAvailableUrl(
+                "https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/plan/8000226/210816/09");
 
         timeProvider.time = new GregorianCalendar(2021, Calendar.AUGUST, 16, 9, 0);
 
@@ -214,9 +216,9 @@ public class TimetableLoaderTest implements TimetablesV1ImplTestHelper {
 
         final List<TimetableStop> stops = loader.getTimetableStops();
         assertThat(timeTableTestModule.getRequestedPlanUrls(),
-                contains("https://api.deutschebahn.com/timetables/v1/plan/8000226/210816/09"));
+                contains("https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/plan/8000226/210816/09"));
         assertThat(timeTableTestModule.getRequestedFullChangesUrls(),
-                contains("https://api.deutschebahn.com/timetables/v1/fchg/8000226"));
+                contains("https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/fchg/8000226"));
         assertThat(timeTableTestModule.getRequestedRecentChangesUrls(), empty());
 
         // Stop -5296516961807204721-2108160906-5 has its planned time at 9:34, but its included because its changed
index 5c226dcdf1f00321adaf3f121475664a15e06d4a..41728c04bae4a2a0e609a09a180e605d6dacb570 100644 (file)
@@ -39,11 +39,11 @@ import org.openhab.binding.deutschebahn.internal.timetable.TimetablesV1Impl.Http
 public class TimetableStubHttpCallable implements HttpCallable {
 
     private static final Pattern PLAN_URL_PATTERN = Pattern
-            .compile("https://api.deutschebahn.com/timetables/v1/plan/(\\d+)/(\\d+)/(\\d+)");
+            .compile("https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/plan/(\\d+)/(\\d+)/(\\d+)");
     private static final Pattern FULL_CHANGES_URL_PATTERN = Pattern
-            .compile("https://api.deutschebahn.com/timetables/v1/fchg/(\\d+)");
+            .compile("https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/fchg/(\\d+)");
     private static final Pattern RECENT_CHANGES_URL_PATTERN = Pattern
-            .compile("https://api.deutschebahn.com/timetables/v1/rchg/(\\d+)");
+            .compile("https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/rchg/(\\d+)");
 
     private final File testdataDir;
     private final List<String> requestedPlanUrls;
index 96f5002d724fd1e1a2888cce885036d410b6d9f6..f061300a2156c2e157e7425354a71bc2d0134330 100644 (file)
  */
 package org.openhab.binding.deutschebahn.internal.timetable;
 
-import java.net.URISyntaxException;
 import java.util.List;
 
-import javax.xml.bind.JAXBException;
-
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.openhab.binding.deutschebahn.internal.timetable.TimetablesV1Impl.HttpCallable;
-import org.xml.sax.SAXException;
 
 /**
  * Testmodule that contains the {@link TimetablesV1Api} and {@link TimetableStubHttpCallable}.
@@ -59,13 +55,6 @@ public final class TimetablesApiTestModule {
     }
 
     public TimetablesV1ApiFactory getApiFactory() {
-        return new TimetablesV1ApiFactory() {
-
-            @Override
-            public TimetablesV1Api create(String authToken, HttpCallable httpCallable)
-                    throws JAXBException, SAXException, URISyntaxException {
-                return api;
-            }
-        };
+        return (String clientId, String clientSecret, HttpCallable httpCallable) -> api;
     }
 }
index 2d47b2dad0edbd10a10d7e5d541650f9a40f78c6..5a7facd56de03c8a1379da92810922927a4cbbcd 100644 (file)
@@ -56,7 +56,7 @@ public class TimetablesV1ImplTest implements TimetablesV1ImplTestHelper {
     public void testGetDataForHannoverHBF() throws Exception {
         TimetablesV1Api timeTableApi = createApiWithTestdata().getApi();
 
-        Date time = new GregorianCalendar(2021, Calendar.OCTOBER, 14, 11, 00).getTime();
+        Date time = new GregorianCalendar(2021, Calendar.OCTOBER, 14, 11, 0).getTime();
 
         Timetable timeTable = timeTableApi.getPlan(EVA_HANNOVER_HBF, time);
         assertNotNull(timeTable);
index 9b30f7a65fa0188a38d668dfa4bf0210c43a8955..bb31ebaf8e4e7e694e2a0a538e8e7775ad8c9c42 100644 (file)
@@ -29,7 +29,8 @@ public interface TimetablesV1ImplTestHelper {
 
     public static final String EVA_LEHRTE = "8000226";
     public static final String EVA_HANNOVER_HBF = "8000152";
-    public static final String AUTH_TOKEN = "354c8161cd7fb0936c840240280c131e";
+    public static final String CLIENT_ID = "bdwrpmxuo6157jrekftlbcc6ju9awo";
+    public static final String CLIENT_SECRET = "354c8161cd7fb0936c840240280c131e";
 
     /**
      * Creates an {@link TimetablesApiTestModule} that uses http response data from file system.
@@ -49,7 +50,7 @@ public interface TimetablesV1ImplTestHelper {
         assertNotNull(timetablesData);
         final File testDataDir = new File(timetablesData.toURI());
         final TimetableStubHttpCallable httpStub = new TimetableStubHttpCallable(testDataDir);
-        final TimetablesV1Impl timeTableApi = new TimetablesV1Impl(AUTH_TOKEN, httpStub);
+        final TimetablesV1Impl timeTableApi = new TimetablesV1Impl(CLIENT_ID, CLIENT_SECRET, httpStub);
         return new TimetablesApiTestModule(timeTableApi, httpStub);
     }
 }