Skip to content

Instantly share code, notes, and snippets.

@dschanoeh
Last active July 13, 2022 10:09
Show Gist options
  • Save dschanoeh/a6d5e670cb1dd8be6090d1b6ebb4609c to your computer and use it in GitHub Desktop.
Save dschanoeh/a6d5e670cb1dd8be6090d1b6ebb4609c to your computer and use it in GitHub Desktop.
A Scriptable Widget That Displays Deutsche Bahn Connections and Their Delay
/*
* This script queries the API documented at https://docs.marudor.de
* to retrieve the next Deutsche Bahn connections between two given
* stations. Only direct connections are supported.
*/
// ====== Configuration ======
/* Eva Number of the stations
* Find yours here https://download-data.deutschebahn.com/static/datasets/haltestellen/D_Bahnhof_2020_alle.CSV
*/
const START_STATION = "";
const DESTINATION_STATION = "";
// How many connections the widget will display
const CONNECTIONS_TO_SHOW = 3;
// Toggle to only show regional trains
const ONLY_REGIONAL = true;
async function createWidget() {
let listwidget = new ListWidget();
let connections = await getConnections();
if (connections != null) {
displayStations(listwidget, connections)
displayConnections(listwidget, connections);
}
return listwidget;
}
let widget = await createWidget();
if (config.runsInWidget) {
Script.setWidget(widget);
} else {
widget.presentMedium();
}
Script.complete();
// Retrieves the connections object based on the given configuration
async function getConnections() {
let url = "https://marudor.de/api/hafas/v3/tripSearch";
let currentTime = new Date();
let body = {
"start": START_STATION,
"destination": DESTINATION_STATION,
"time": currentTime.toISOString(),
"transferTime": 0,
"maxChanges": 0,
"searchForDeparture": true,
"onlyRegional": ONLY_REGIONAL
};
let req = new Request(url);
req.body = JSON.stringify(body);
req.headers = {"Content-type": "application/json;charset=UTF-8"}
req.method = "POST";
log(req.body)
let responseBody = await req.loadJSON();
if(req.response.statusCode != 200) {
log("Received status code: " + req.response.statusCode)
log("Body: " + JSON.stringify(responseBody))
return null
}
return responseBody
}
function displayStations(stack, connections) {
let firstRoute = connections.routes[0]
let departureStation = firstRoute.segments[0].segmentStart.title
let arrivalStation = firstRoute.segments[0].segmentDestination.title
let stationsText = stack.addText("🚆 " + departureStation + " --> " + arrivalStation)
stationsText.font = Font.boldSystemFont(16)
stationsText.centerAlignText();
}
// Renders the connections
function displayConnections(stack, connections) {
let routes = connections.routes
log(JSON.stringify(routes))
for (let i in routes) {
if (i >= CONNECTIONS_TO_SHOW) {
break;
}
let route = routes[i]
let departurePlatform = route.departure.platform
let departureTime = new Date(route.departure.time)
let arrivalTime = new Date(route.arrival.time)
let departureDelay = route.departure.delay
let arrivalDelay = route.arrival.delay
let trainName = route.segments[0].train.name
// Skip connections that are in the past
if (departureTime < new Date()) {
continue;
}
let nameText = stack.addText(trainName + " (🚉" + departurePlatform + ")")
nameText.font = Font.semiboldSystemFont(16)
let timeText = stack.addText(
departureTime.toLocaleTimeString() + " (+" + departureDelay + ")" + " --> " +
arrivalTime.toLocaleTimeString() + " (+" + arrivalDelay + ")")
timeText.font = Font.regularSystemFont(14)
if (departureDelay <= 3) {
timeText.textColor = Color.green()
} else {
timeText.textColor = Color.red()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment