Initial commit
This commit is contained in:
commit
278ec3928b
|
@ -0,0 +1,4 @@
|
||||||
|
.venv/
|
||||||
|
**/__pycache__
|
||||||
|
*.pyc
|
||||||
|
lastrun.txt
|
|
@ -0,0 +1,66 @@
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
|
||||||
|
from pprint import pprint
|
||||||
|
|
||||||
|
from vag_api import VagApi
|
||||||
|
from vag_zza import VagZza
|
||||||
|
|
||||||
|
from station_map import *
|
||||||
|
|
||||||
|
|
||||||
|
def display_train(zza, train):
|
||||||
|
line = train['Linienname']
|
||||||
|
via = ""
|
||||||
|
dest = zza.get_closest_destination(train['Richtungstext'])
|
||||||
|
|
||||||
|
if line == "U1":
|
||||||
|
if dest not in ("Langwasser-Süd", "Fürth Hardhöhe"):
|
||||||
|
line = "U11"
|
||||||
|
|
||||||
|
# Via für Standort Maximilianstraße
|
||||||
|
if dest in ("Fürth Hardhöhe", "Fürth Klinikum", "Fürth / Stadthalle"):
|
||||||
|
via = "Stadtgrenze - Fürth / Hauptbahnhof"
|
||||||
|
elif dest in ("Fürth / Hauptbahnhof", "Jakobinenstraße"):
|
||||||
|
via = "Stadtgrenze"
|
||||||
|
elif dest in ("Weißer Turm", "Hauptbahnhof"):
|
||||||
|
via = "Plärrer"
|
||||||
|
elif dest in ("Aufseßplatz", "Maffeiplatz", "Frankenstraße", "Hasenbuck", "Bauernfeindstraße", "Messe"):
|
||||||
|
via = "Plärrer - Hauptbahnhof"
|
||||||
|
elif dest in ("Scharfreiterring", "Langwasser-Süd"):
|
||||||
|
via = "Plärrer - Hauptbahnhof - Messe"
|
||||||
|
|
||||||
|
if dest == "":
|
||||||
|
line = "Sonderzug"
|
||||||
|
dest = "Bitte achten Sie auf die Zugbeschilderung"
|
||||||
|
|
||||||
|
zza.set_line(line)
|
||||||
|
zza.set_via(via)
|
||||||
|
zza.set_destination(dest)
|
||||||
|
zza.update()
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("-p", "--port", type=str, required=True, help="Serial port for display")
|
||||||
|
parser.add_argument("-s", "--station", type=str, required=True, help="Station name to display departures of")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
api = VagApi()
|
||||||
|
api.load_station_data("stations.json")
|
||||||
|
|
||||||
|
try:
|
||||||
|
station_id = int(args.station)
|
||||||
|
except ValueError:
|
||||||
|
station_id = api.get_station_info(args.station)[0]['VGNKennung']
|
||||||
|
|
||||||
|
departures = api.get_departures(station_id, products=["Ubahn"])
|
||||||
|
train = departures[0]
|
||||||
|
|
||||||
|
zza = VagZza(args.port)
|
||||||
|
pprint(train)
|
||||||
|
display_train(zza, train)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
|
@ -0,0 +1,8 @@
|
||||||
|
MAP_LINE = {
|
||||||
|
"U1": 3,
|
||||||
|
"U2": 9
|
||||||
|
}
|
||||||
|
|
||||||
|
MAP_DESTINATION = {
|
||||||
|
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,41 @@
|
||||||
|
import json
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
class VagApi:
|
||||||
|
def __init__(self):
|
||||||
|
self.station_data = []
|
||||||
|
|
||||||
|
def load_station_data(self, filename):
|
||||||
|
with open(filename, 'r', encoding='utf-8') as f:
|
||||||
|
self.station_data = json.load(f)['Haltestellen']
|
||||||
|
|
||||||
|
def get_station_info(self, query):
|
||||||
|
matches = []
|
||||||
|
if type(query) is str:
|
||||||
|
query = query.lower()
|
||||||
|
str_query = True
|
||||||
|
else:
|
||||||
|
str_query = False
|
||||||
|
|
||||||
|
for station in self.station_data:
|
||||||
|
if str_query:
|
||||||
|
if query in station['Haltestellenname'].lower() or query in station['VAGKennung'].lower():
|
||||||
|
matches.append(station)
|
||||||
|
else:
|
||||||
|
if station['VGNKennung'] == query:
|
||||||
|
matches.append(station)
|
||||||
|
|
||||||
|
return matches
|
||||||
|
|
||||||
|
def get_stations(self, query = ""):
|
||||||
|
resp = requests.get("https://start.vag.de/dm/api/haltestellen.json/vgn", params={'name': query})
|
||||||
|
resp.raise_for_status()
|
||||||
|
data = resp.json()
|
||||||
|
return data
|
||||||
|
|
||||||
|
def get_departures(self, station, delay_min=0, products=['Ubahn', 'Tram', 'Bus']):
|
||||||
|
resp = requests.get(f"https://start.vag.de/dm/api/abfahrten.json/vgn/{station}", params={'timedelay': delay_min, 'product': ",".join(products)})
|
||||||
|
resp.raise_for_status()
|
||||||
|
data = resp.json()
|
||||||
|
return data['Abfahrten']
|
|
@ -0,0 +1,67 @@
|
||||||
|
import serial
|
||||||
|
import time
|
||||||
|
|
||||||
|
from difflib import SequenceMatcher
|
||||||
|
|
||||||
|
from vag_zza_map import *
|
||||||
|
|
||||||
|
|
||||||
|
class VagZza:
|
||||||
|
def __init__(self, port):
|
||||||
|
self.port = serial.Serial(port, baudrate=9600)
|
||||||
|
|
||||||
|
def home(self):
|
||||||
|
self.port.write(b"HOME\n")
|
||||||
|
time.sleep(0.05)
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
self.port.write(b"START\n")
|
||||||
|
time.sleep(0.05)
|
||||||
|
|
||||||
|
def set_unit(self, pos, code):
|
||||||
|
self.port.write(f"UNIT:{pos}:{code}\n".encode('ascii'))
|
||||||
|
time.sleep(0.05)
|
||||||
|
|
||||||
|
def set_line(self, line):
|
||||||
|
code = None
|
||||||
|
for c, text in MAP_LINE.items():
|
||||||
|
if text.lower() == line.lower():
|
||||||
|
code = c
|
||||||
|
break
|
||||||
|
if code is None:
|
||||||
|
raise ValueError(f"Line text not found: {line}")
|
||||||
|
self.set_unit(0, code)
|
||||||
|
self.set_unit(3, code)
|
||||||
|
|
||||||
|
def set_via(self, via):
|
||||||
|
code = None
|
||||||
|
for c, text in MAP_VIA.items():
|
||||||
|
if text.lower() == via.lower():
|
||||||
|
code = c
|
||||||
|
break
|
||||||
|
if code is None:
|
||||||
|
raise ValueError(f"Via text not found: {via}")
|
||||||
|
self.set_unit(1, code)
|
||||||
|
self.set_unit(4, code)
|
||||||
|
|
||||||
|
def set_destination(self, dest):
|
||||||
|
code = None
|
||||||
|
for c, text in MAP_DESTINATION.items():
|
||||||
|
if text.lower() == dest.lower():
|
||||||
|
code = c
|
||||||
|
break
|
||||||
|
if code is None:
|
||||||
|
raise ValueError(f"Destination text not found: {dest}")
|
||||||
|
self.set_unit(2, code)
|
||||||
|
self.set_unit(5, code)
|
||||||
|
|
||||||
|
def get_closest_destination(self, dest):
|
||||||
|
match = ""
|
||||||
|
match_score = 0.0
|
||||||
|
for text in MAP_DESTINATION.values():
|
||||||
|
score = SequenceMatcher(None, dest, text).ratio()
|
||||||
|
if score > 0.6 and score > match_score:
|
||||||
|
print(text, score)
|
||||||
|
match = text
|
||||||
|
match_score = score
|
||||||
|
return match
|
|
@ -0,0 +1,128 @@
|
||||||
|
MAP_LINE = {
|
||||||
|
0: "Gerät gestört",
|
||||||
|
1: "",
|
||||||
|
2: "U1",
|
||||||
|
3: "U11",
|
||||||
|
4: "",
|
||||||
|
5: "U1 Kurzzug",
|
||||||
|
6: "U11 Kurzzug",
|
||||||
|
7: "",
|
||||||
|
8: "U2",
|
||||||
|
9: "U21",
|
||||||
|
10: "",
|
||||||
|
11: "U2 Kurzzug",
|
||||||
|
12: "U21 Kurzzug",
|
||||||
|
13: "",
|
||||||
|
14: "",
|
||||||
|
15: "",
|
||||||
|
16: "",
|
||||||
|
17: "",
|
||||||
|
18: "",
|
||||||
|
19: "Kurzzug",
|
||||||
|
20: "",
|
||||||
|
21: "",
|
||||||
|
22: "",
|
||||||
|
23: "",
|
||||||
|
24: "",
|
||||||
|
25: "",
|
||||||
|
26: "",
|
||||||
|
27: "Benutzen",
|
||||||
|
28: "",
|
||||||
|
29: "",
|
||||||
|
30: "",
|
||||||
|
31: "",
|
||||||
|
32: "",
|
||||||
|
33: "",
|
||||||
|
34: "Sonderzug",
|
||||||
|
35: "Arbeitszug",
|
||||||
|
36: "Werkstattzug",
|
||||||
|
37: "Fahrschule",
|
||||||
|
38: "Abstellanlage",
|
||||||
|
39: ""
|
||||||
|
}
|
||||||
|
|
||||||
|
MAP_VIA = {
|
||||||
|
0: "",
|
||||||
|
1: "",
|
||||||
|
2: "Plärrer - Hauptbahnhof - Messe",
|
||||||
|
3: "Hauptbahnhof - Messe",
|
||||||
|
4: "Messe",
|
||||||
|
5: "Messe - Hauptbahnhof - Plärrer",
|
||||||
|
6: "Hauptbahnhof - Plärrer",
|
||||||
|
7: "Plärrer",
|
||||||
|
8: "Plärrer - Hauptbahnhof - Rathenauplatz",
|
||||||
|
9: "Hauptbahnhof - Rathenauplatz",
|
||||||
|
10: "Rathenauplatz",
|
||||||
|
11: "Rathenauplatz - Hauptbahnhof - Plärrer",
|
||||||
|
12: "Plärrer - Hauptbahnhof",
|
||||||
|
13: "Frankenstraße",
|
||||||
|
14: "Hauptbahnhof",
|
||||||
|
15: "Frankenstraße - Messe",
|
||||||
|
16: "Messe - Langwasser-Mitte",
|
||||||
|
17: "Langwasser-Mitte",
|
||||||
|
18: "Maximilianstraße - Stadtgrenze",
|
||||||
|
19: "Stadtgrenze",
|
||||||
|
20: "Maximilianstraße",
|
||||||
|
21: "",
|
||||||
|
22: "Rothenburgerstraße - Schweinau",
|
||||||
|
23: "Schweinau",
|
||||||
|
24: "",
|
||||||
|
25: "",
|
||||||
|
26: "",
|
||||||
|
27: "Sie bitte den",
|
||||||
|
28: "",
|
||||||
|
29: "Maximilianstraße - Fürth / Hauptbahnhof",
|
||||||
|
30: "",
|
||||||
|
31: "Stadtgrenze - Fürth / Hauptbahnhof",
|
||||||
|
32: "",
|
||||||
|
33: "",
|
||||||
|
34: "",
|
||||||
|
35: "",
|
||||||
|
36: "",
|
||||||
|
37: "",
|
||||||
|
38: "",
|
||||||
|
39: ""
|
||||||
|
}
|
||||||
|
|
||||||
|
MAP_DESTINATION = {
|
||||||
|
0: "",
|
||||||
|
1: "",
|
||||||
|
2: "Langwasser-Süd",
|
||||||
|
3: "Scharfreiterring",
|
||||||
|
4: "Messe",
|
||||||
|
5: "Bauernfeindstraße",
|
||||||
|
6: "Hasenbuck",
|
||||||
|
7: "Frankenstraße",
|
||||||
|
8: "Maffeiplatz",
|
||||||
|
9: "Aufseßplatz",
|
||||||
|
10: "Weißer Turm",
|
||||||
|
11: "Plärrer",
|
||||||
|
12: "Gostenhof",
|
||||||
|
13: "Bärenschanze",
|
||||||
|
14: "Eberhardshof",
|
||||||
|
15: "Muggenhof",
|
||||||
|
16: "Jakobinenstraße",
|
||||||
|
17: "Fürth / Hauptbahnhof",
|
||||||
|
18: "",
|
||||||
|
19: "Fürth / Stadthalle",
|
||||||
|
20: "Fürth Klinikum",
|
||||||
|
21: "Fürth Hardhöhe",
|
||||||
|
22: "Ziegelstein",
|
||||||
|
23: "Herrnhütte",
|
||||||
|
24: "Nordostbahnhof",
|
||||||
|
25: "Rathenauplatz",
|
||||||
|
26: "Hauptbahnhof",
|
||||||
|
27: "Bahnsteig gegenüber",
|
||||||
|
28: "",
|
||||||
|
29: "St. Leonhard",
|
||||||
|
30: "Schweinau",
|
||||||
|
31: "Hohe Marter",
|
||||||
|
32: "Röthenbach",
|
||||||
|
33: "Betriebsschluß Gleis 1",
|
||||||
|
34: "Bitte achten Sie auf die Zugbeschilderung",
|
||||||
|
35: "Betriebsschluß Gleis 2",
|
||||||
|
36: "Bitte achten Sie auf die Lautsprecherdurchsage",
|
||||||
|
37: "Benutzen Sie bitte die Busse vor dem Bahnhof",
|
||||||
|
38: "Nicht einsteigen",
|
||||||
|
39: ""
|
||||||
|
}
|
Loading…
Reference in New Issue