Skip to content

Instantly share code, notes, and snippets.

@ChristophObermeier
Last active February 8, 2023 12:21
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ChristophObermeier/5f67ed2b69c52212476a200a260e2a0a to your computer and use it in GitHub Desktop.
Save ChristophObermeier/5f67ed2b69c52212476a200a260e2a0a to your computer and use it in GitHub Desktop.
Get the next departure of your local MVG station for selected product(s).
// ***MVG Departure Widget***
//
// Copyright (C) 2020 by ChristophObermeier
//
// Permission to use, copy, modify, and/or distribute this software is hereby granted.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
// IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
// OF THIS SOFTWARE.
//
// Variables used by Scriptable.
// These must be at the very top of the file. Do not edit.
// icon-color: blue; icon-glyph: train;
// * Script for scriptable to catch the next metro in munich at your location
//*jshint esversion: 6 */
// Get your Station here https://www.mvg.de/dienste/abfahrtszeiten.html
//"München" is not required to enter
const station = args.widgetParameter
//Set for Debug in App
//const station = "Odeonsplatz"
//Adds "&" to combined station
var clearstation = station.replace(" ","&")
//Get Station ID
const mvgstatID = "https://www.mvg.de/api/fahrinfo/location/queryWeb?q=" + clearstation
var responseID
responseID = await new Request(mvgstatID).loadJSON()
// Store the MVG ID
const mvgID = responseID.locations[0].id.toString()
//Set your preferred MVG products
const footway = false
const bus = false
const ubahn = true
const sbahn = false
const tram = false
const zug = false
//Get departures
const mvgReq = "https://www.mvg.de/api/fahrinfo/departure/" + mvgID + "?sbahn=" + sbahn + "&ubahn=" + ubahn + "&bus=" + bus + "&tram=" + tram + "&footway" + footway + "&zug=" + zug
var response
response = await new Request(mvgReq).loadJSON()
//Calculates Departure time
function calculateTimeOffset(times)
{
return Math.round((times - Date.now()) / 60000)
}
//Calculates real departure incl. delay
function calculatedeparture (delay, time) {
if (delay == undefined)
{
return time
}
else
{
return delay+time
}
}
//Shorten Destination, if length exceeds space
function truncate(destination, n)
{
return (destination.length > 20) ? destination.substr(0, 19) + '...' : destination
}
// Store the MVG values.
// Departure #1
const destination1 = truncate(response.departures[0].destination.toString())
const label1 = response.departures[0].label.toString()
const platform1 = response.departures[0].platform
const bgcolor1 = response.departures[0].lineBackgroundColor
const delay1 = response.departures[0].delay
const time1 = calculateTimeOffset(response.departures[0].departureTime)
const abfahrt1 = calculatedeparture(delay1,time1)
// Departure #2
const destination2 = truncate(response.departures[1].destination.toString())
const label2 = response.departures[1].label.toString()
const platform2 = response.departures[1].platform
const delay2 = response.departures[1].delay
const time2 = calculateTimeOffset(response.departures[1].departureTime)
const abfahrt2 = calculatedeparture(delay2,time2)
// Departure #3
const destination3 = truncate(response.departures[2].destination.toString())
const label3 = response.departures[2].label.toString()
const platform3 = response.departures[2].platform
const delay3 = response.departures[2].delay
const time3 = calculateTimeOffset(response.departures[2].departureTime)
const abfahrt3 = calculatedeparture(delay3,time3)
// Departure #4
const destination4 = truncate(response.departures[3].destination.toString())
const label4 = response.departures[3].label.toString()
const platform4 = response.departures[3].platform
const delay4 = response.departures[3].delay
const time4 = calculateTimeOffset(response.departures[3].departureTime)
const abfahrt4 = calculatedeparture(delay4,time4)
const widget = await createWidget()
if (!config.runsInWidget) {
await widget.presentMedium()
}
Script.setWidget(widget)
function createWidget() {
let widget = new ListWidget()
widget.backgroundColor = new Color("004d99")
let title = widget.addText("🚉 Next Departures @" + [station])
title.font = Font.boldSystemFont(15)
title.textColor = Color.white()
title.centerAlignText()
title.minimumScaleFactor = 0.6
title.lineLimit = 2
widget.addSpacer(15)
//Departure #1
let destinationText1 = widget.addText("⏱"+abfahrt1 + "min " + label1 + "➡️ " + destination1 + " @" + platform1)
destinationText1.font = Font.boldSystemFont(10)
destinationText1.textColor = Color.white()
destinationText1.centerAlignText()
destinationText1.minimumScaleFactor = 0.4
widget.addSpacer(10)
//Departure #2
let destinationText2 = widget.addText("⏱"+abfahrt2 + "min " + label2 + "➡️ " + destination2 + " @" + platform2)
destinationText2.font = Font.boldSystemFont(10)
destinationText2.textColor = Color.white()
destinationText2.centerAlignText()
destinationText2.minimumScaleFactor = 0.4
widget.addSpacer(10)
//Departure #3
let destinationText3 = widget.addText("⏱"+abfahrt3 + "min " + label3 + "➡️ " + destination3 + " @" + platform3)
destinationText3.font = Font.boldSystemFont(10)
destinationText3.textColor = Color.white()
destinationText3.centerAlignText()
destinationText3.minimumScaleFactor = 0.4
widget.addSpacer(10)
//Departure #4
let destinationText4 = widget.addText("⏱"+abfahrt4 + "min " + label4 + "➡️ " +destination4 + " @" + platform4)
destinationText4.font = Font.boldSystemFont(10)
destinationText4.textColor = Color.white()
destinationText4.centerAlignText()
destinationText4.minimumScaleFactor = 0.4
return widget
}
Script.complete()
@ChristophObermeier
Copy link
Author

Ja, da liefert die API der MVG dann keine Resultate. Werde entsprechende aussagekräftigere Fehlermeldungen im nächsten Update mit aufnehmen.
Freut mich, dass das Skript weiterhilft!
VG

@Bernd95
Copy link

Bernd95 commented Jan 17, 2021

Ich habe zwei Frage/Probleme:
Wie gehe ich mit Haltestellen um, die aus zwei Worten bestehen, z.B. Messestadt West.
Bei der Ermittlung der Abfahrtszeit geht scheinbar manchmal etwas schief: Ich habe dafür oft die Anzeige "NaNmin", also scheinbar wird versucht, irgendetwas als Zahl zu interpretieren, was keine ist.

@ChristophObermeier
Copy link
Author

ChristophObermeier commented Jan 17, 2021

Hi @Bernd95,
bei diesen Haltestellen musst Du ein „&“ einfügen, z. B. „Messestadt&West“. Ich werde demnächst die Anzeige ohne „&“ verbessern.
4239D52C-A3A2-46D4-B4E6-E62976B540B8
Hast Du ein Beispiel für den Fehler bei den Abfahrtszeiten?

@Bernd95
Copy link

Bernd95 commented Jan 17, 2021

Ich habe es gleich mal mit Messestadt West probiert, aber mit Messestadt Ost und Odeonsplatz ist es ähnlich:
Bildschirmfoto 2021-01-17 um 12 57 43
Bildschirmfoto 2021-01-17 um 13 00 13

@ChristophObermeier
Copy link
Author

ChristophObermeier commented Jan 18, 2021

Hi @Bernd95,
ich habe mir jetzt bei Stationen längere Zeit angeschaut und konnte den Fehler nicht reproduzieren. Verwendest Du die aktuelle Version meines Scripts?
2B16540D-F4DF-4B9C-9C94-4A666101DD5A

@Bernd95
Copy link

Bernd95 commented Jan 18, 2021

Ja, ich habe die aktuelle Version. Ich habe jetzt eine ganze Weile mit verschiedenen Haltestellen getestet und mir dabei die Werte für departureTime, delay, time und abfahrt auf der Console ausgeben lassen. Dabei habe ich dann irgendwann gesehen, dass delay manchmal als undefined ausgegeben wird. Dann habe ich die URLs im Firefox angeschaut und dabei festgestellt, dass es Einträge im JSON gibt, die das Attribut delay gar nicht enthalten - keine Ahnung, warum das so ist. Aber vielleicht kannst Du das abfangen und in diesem Fall den delay=0 setzen.
Bei der Gelegenheit könntest Du vielleicht noch einen Standardwert für die Haltestelle vorgeben, falls kein Argemunt angegeben wird - dann kann man in Scriptable besser testen.

@ChristophObermeier
Copy link
Author

Hi @Bernd95,
bitte auf die neue Version aktualisieren. Bug sollte behoben sein.
Außerdem ist es nun nicht mehr nötig Stationen mit mehr als einem Wort mit "&" zu kombinieren. Kann direkt mit Leerzeichen eingegeben werden, z. B. "Messestadt Ost".
VG

@Bernd95
Copy link

Bernd95 commented Jan 24, 2021

Sehr schön, funktioniert perfekt :)

@ChristophObermeier
Copy link
Author

You‘re welcome ;-)

@JDTm
Copy link

JDTm commented Apr 4, 2021

Wie gebe ich denn Neuperlach Süd ein => Neuperlach Sud

Das Widget braucht ja relativ viel Platz, gehen auch zwei Stationen Nebeneinander?

@ChristophObermeier
Copy link
Author

Hi,
hier die Lösung:
F2AAD0E9-2A1D-4129-9DCF-C11E3097E8BB
BD3CA745-2DBE-4155-B6DD-50C549DCF232
Auf Grund der Länge mancher Stationen ist es schwierig, zwei Stationen nebeneinander anzuzeigen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment