Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[deutschebahn] DB API Marketplace adjustments #12786

Merged
merged 3 commits into from May 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 17 additions & 12 deletions bundles/org.openhab.binding.deutschebahn/README.md
Expand Up @@ -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

Expand All @@ -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. |
Expand All @@ -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"`
Expand Down Expand Up @@ -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.
Expand Down
Expand Up @@ -32,9 +32,14 @@
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.
Expand Down
Expand Up @@ -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;
Expand Down Expand Up @@ -53,7 +52,6 @@
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
Expand Down Expand Up @@ -116,7 +114,7 @@ public int getMaxPosition() {
private final ScheduledExecutorService executorService;

/**
* Creates an new {@link DeutscheBahnTimetableHandler}.
* Creates a new {@link DeutscheBahnTimetableHandler}.
*/
public DeutscheBahnTimetableHandler( //
final Bridge bridge, //
Expand Down Expand Up @@ -152,7 +150,11 @@ public void initialize() {
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();
Expand Down Expand Up @@ -183,7 +185,7 @@ public void initialize() {
});
} 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());
}
Expand All @@ -195,7 +197,7 @@ public void dispose() {
}

/**
* 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());
Expand Down Expand Up @@ -298,7 +300,7 @@ private void updateThings(GroupedThings groupedThings, final List<TimetableStop>
}

/**
* 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();
Expand Down
Expand Up @@ -52,7 +52,6 @@ private final class ChannelWithConfig {
* 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( //
Expand Down Expand Up @@ -166,8 +165,7 @@ private static String getAttributeName(ChannelUID channelUid) {
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);
}

/**
Expand Down
Expand Up @@ -41,7 +41,7 @@
*
* 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
*
Expand Down Expand Up @@ -370,7 +370,9 @@ private static List<String> mapDateToStringList(@Nullable Date value) {
if (value == null) {
return Collections.emptyList();
} else {
return Collections.singletonList(DATETIME_FORMAT.format(value));
synchronized (DATETIME_FORMAT) {
return Collections.singletonList(DATETIME_FORMAT.format(value));
}
}
}

Expand Down
Expand Up @@ -22,99 +22,99 @@
*
* 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() {
Expand All @@ -124,7 +124,7 @@ private 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 {
Expand Down