Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

Copy link
Owner Author

@ChristophObermeier ChristophObermeier commented Dec 16, 2020

Introduction

Get the departures of the next MVG transport service at your preferred MVG station.

Requirements

  • Apple Device with iOS 14.
  • Scriptable latest.

Setup

  1. Copy the source code ("raw").
  2. Open Scriptable.
  3. Select "+" and insert the copy of the script.
  4. Choose the title of the script (e. g. MVG Departure).
  5. Save with "Done".
  6. Back to the iOS Homescreen and get into the "wiggle mode".
  7. Press the "+" symbol and look for "Scriptable" (Liste ist alphabetisch).
  8. Choose widget size (large) and "Add widget".
  9. Go into the settings of the widget.
  10. Choose script of step #4.
  11. Select when interaction "Run Script".
  12. Use your preferred station, e. g. "Marienplatz", "Messestadt Ost" or "Odeonsplatz" as parameter without "".
  13. Save and enjoy the widget!

Disclaimer

For private use only! Please enjoy responsibly :)

FAQs

  • Specific products can be chosen in the script, e. g. ubahn / sbahn.

Changelog

24.01.2021
  • Stations with more than one word like "Messestadt Ost" can now be entered as given.
  • Fixed a bug with n/a delay.
  • Minor UI changes.

31.12.2020 11:10

  • Minor UI changes.
  • Changed standard product to "ubahn".

16.12.2020 16:45

  • First Draft.

Credits

Thaaaaaank youuuuuu @simonbs for Scriptable.app for you great widgets and thank you @leftshift, @florianlederer & @rasshofer for the inspiration!

For more widgets visit: Scriptables.net
Download with ScriptDude
@rasshofer

This comment has been minimized.

Copy link

@rasshofer rasshofer commented Dec 19, 2020

Nice idea! 🙌

@digixjan

This comment has been minimized.

Copy link

@digixjan digixjan commented Dec 31, 2020

Leider bekomme ich ständig diese Fehlermeldung, habe den Code schon ein paar mal reinkopiert, kann kein cut&paste error sein... was kann ich tun?

5BF3BCA9-2B6C-447C-8E91-2887C9563D91

@ChristophObermeier

This comment has been minimized.

Copy link
Owner Author

@ChristophObermeier ChristophObermeier commented Dec 31, 2020

Leider bekomme ich ständig diese Fehlermeldung, habe den Code schon ein paar mal reinkopiert, kann kein cut&paste error sein... was kann ich tun?

5BF3BCA9-2B6C-447C-8E91-2887C9563D91

Da wird die "Destination" nicht erkannt. Von welcher Station möchtest Du denn die Abfahrten sehen?

@digixjan

This comment has been minimized.

Copy link

@digixjan digixjan commented Dec 31, 2020

Ich habe es in den Widget-Settings mit „Wettersteinplatz“ und „Marienplatz“ versucht, beides führt zu der genannten Fehlermeldung
Uploading 3C18CAE3-4CBC-4D2E-9706-76D99AB8BC01.jpeg…

@digixjan

This comment has been minimized.

Copy link

@digixjan digixjan commented Dec 31, 2020

Ich korrigiere: Marienplatz geht, Wettersteinplatz nicht

@ChristophObermeier

This comment has been minimized.

Copy link
Owner Author

@ChristophObermeier ChristophObermeier commented Dec 31, 2020

Ich habe es gerade probiert, bei mir funktioniert's:

@digixjan

This comment has been minimized.

Copy link

@digixjan digixjan commented Dec 31, 2020

Seltsam. Was könnte ich falsch machen?

315F7603-820D-4DB0-9DCA-56F6B6111347
A14E8BF4-647C-4236-A5A4-66605562552F

@ChristophObermeier

This comment has been minimized.

Copy link
Owner Author

@ChristophObermeier ChristophObermeier commented Dec 31, 2020

Ich denke es liegt am "Produkt", im Standard ist dort aktuell folgendes gesetzt:

//Set your preferred MVG products
const footway = false
const bus = true
const ubahn = false
const sbahn = false
const tram = false
const zug = false

Dich interessiert wsl. die Abfahrt der nächsten U-Bahn und da müsstest Du die Passage im Script folgendermaßen ändern:
const footway = false
const bus = false
const ubahn = true
const sbahn = false
const tram = false
const zug = false

@digixjan

This comment has been minimized.

Copy link

@digixjan digixjan commented Dec 31, 2020

Ja, das war‘s. Vermutlich weil es an Haltestelle Wettersteinplatz weder Bus noch Sbahn-gibt, dafür aber Tram und U. Dann steigt das Script mit Fehlermeldung aus. Danke dafür! Super hilfreiches Script!

@ChristophObermeier

This comment has been minimized.

Copy link
Owner Author

@ChristophObermeier ChristophObermeier commented Jan 1, 2021

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

This comment has been minimized.

Copy link

@Bernd95 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

This comment has been minimized.

Copy link
Owner Author

@ChristophObermeier 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

This comment has been minimized.

Copy link

@Bernd95 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

This comment has been minimized.

Copy link
Owner Author

@ChristophObermeier 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

This comment has been minimized.

Copy link

@Bernd95 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

This comment has been minimized.

Copy link
Owner Author

@ChristophObermeier ChristophObermeier commented Jan 24, 2021

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

This comment has been minimized.

Copy link

@Bernd95 Bernd95 commented Jan 24, 2021

Sehr schön, funktioniert perfekt :)

@ChristophObermeier

This comment has been minimized.

Copy link
Owner Author

@ChristophObermeier ChristophObermeier commented Jan 24, 2021

You‘re welcome ;-)

@JDTm

This comment has been minimized.

Copy link

@JDTm 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

This comment has been minimized.

Copy link
Owner Author

@ChristophObermeier ChristophObermeier commented Apr 5, 2021

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