From 2884b476085e28d21f7ebf1c4dc9f0dffec9156d Mon Sep 17 00:00:00 2001 From: Julian Metzler Date: Sun, 12 Jun 2022 14:27:27 +0200 Subject: [PATCH] =?UTF-8?q?=C3=84nderungen=20an=20den=20Zugl=C3=A4ufen=3F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | 12 +- run.py | 666 +++++++++++++++++++++++------------------------ 2 files changed, 339 insertions(+), 339 deletions(-) diff --git a/requirements.txt b/requirements.txt index d9e7374..dd99585 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ -certifi==2019.11.28 -chardet==3.0.4 -idna==2.8 -pyserial==3.4 -requests==2.21.0 -urllib3==1.24.3 +certifi==2019.11.28 +chardet==3.0.4 +idna==2.8 +pyserial==3.4 +requests==2.21.0 +urllib3==1.24.3 diff --git a/run.py b/run.py index 0f95a75..1dec1cf 100644 --- a/run.py +++ b/run.py @@ -1,333 +1,333 @@ -import datetime -import hashlib -import json -import time -import traceback - -from db_infoscreen import DBInfoscreen -from splitflap.krone import Krone8200Controller -from splitflap.display import SplitFlapDisplay, CustomMapField -from splitflap.exceptions import CommunicationError - -from util import timeout - -RX_ADDRESS = (0x41, 0x41) - -MAP_ROUTE = { - 0: "Halensee, Schöneberg, Südkreuz, Neukölln", - 1: "Schöneberg, Südkreuz, Neukölln, Baumschulenweg", - 2: "Schöneberg, Südkreuz, Neukölln, Schöneweide", - 3: "Schöneberg, Neukölln, Schöneweide, Grünau", - 4: "Gesundbrunnen, Schönhauser Allee, Ostkreuz, Treptower Park", - 5: "Gesundbrunnen, Schönhauser Allee, Ostkreuz, Neukölln", - 6: "Gesundbrunnen, Ostkreuz, Neukölln, Südkreuz", - 7: "Gesundbrunnen, Ostkreuz, Neukölln, Schöneberg", - 8: "Westend", - 9: "Westend, Jungfernheide", - 10: "Westend, Jungfernheide, Westhafen", - 11: "Westend, Jungfernheide, Westhafen, Gesundbrunnen", - 12: "Westend, Jungfernheide, Gesundbrunnen, Schönhauser Allee", - 13: "Jungfernheide, Gesundbrunnen, Schönhauser Allee, Ostkreuz", - 14: "Gesundbrunnen, Ostkreuz, Schöneberg", - 15: "Halensee, Schöneberg, Südkreuz, Neukölln", - 16: "Schöneberg, Südkreuz, Neukölln, Ostkreuz", - 17: "Schöneberg, Neukölln, Ostkreuz, Gesundbrunnen", - 18: "Halensee", - 19: "Halensee, Bundesplatz", - 20: "Halensee, Bundesplatz, Schöneberg", - 21: "Halensee, Bundesplatz, Schöneberg, Südkreuz", - 22: "Schöneberg, Ostkreuz, Gesundbrunnen", - 23: "weiter als S2 über Buch", - 24: "Jungfernheide, Gesundbrunnen", - 25: "Jungfernheide, Gesundbrunnen, Bornholmer Straße, Schönholz", - 26: "Westkreuz, Schöneberg, Südkreuz, Neukölln", - 27: "Westkreuz, Schöneberg, Neukölln, Baumschulenweg", - 28: "Westkreuz, Schöneberg, Neukölln, Schöneweide", - 29: "Westkreuz, Schöneberg, Schöneweide, Grünau", - 30: "Gesundbrunnen, Ostkreuz, Schöneberg, Westkreuz", - 31: "Westkreuz, Schöneberg, Neukölln, Ostkreuz", - 32: "Westkreuz, Neukölln, Ostkreuz, Gesundbrunnen", - 33: "Westkreuz", - 34: "Westkreuz, Halensee", - 35: "Westkreuz, Halensee, Bundesplatz", - 36: "Westkreuz, Halensee, Bundesplatz, Schöneberg", - 37: "Westkreuz, Halensee, Schöneberg, Südkreuz", - 38: "Westkreuz, Schöneberg, Ostkreuz, Gesundbrunnen", - 39: "Jungfernheide", - 40: "Jungfernheide, Westhafen", - 41: "Jungfernheide, Westhafen, Gesundbrunnen", - 42: "Jungfernheide, Westhafen, Gesundbrunnen, Schönhauser Allee", - 43: "Jungfernheide, Gesundbrunnen, Bornholmer Straße", - 44: "Schöneberg, Neukölln Kurzzug", - 45: "Neukölln, Schöneweide Kurzzug", - 46: "Gesundbrunnen, Ostkreuz Kurzzug", - 47: "Westend Kurzzug", - 48: "Westend, Jungfernheide Kurzzug", - 49: "Jungfernheide, Gesundbrunnen Kurzzug", - 50: "Schöneberg, Neukölln Kurzzug", - 51: "Neukölln, Ostkreuz Kurzzug", - 52: "Halensee Kurzzug", - 53: "Halensee, Bundesplatz Kurzzug", - 54: "Halensee, Schöneberg Kurzzug", - 55: "Schöneberg, Ostkreuz Kurzzug", - 56: "Westend, Gesundbrunnen Kurzzug", - 57: "Gesundbrunnen, Bornholmer Straße Kurzzug", - 58: "Gesundbrunnen, Schönholz Kurzzug", - 59: "Westkreuz, Neukölln Kurzzug", - 60: "Westkreuz, Schöneweide Kurzzug", - 61: "Ostkreuz, Gesundbrunnen Kurzzug", - 62: "Westkreuz Kurzzug", - 63: "Westkreuz, Halensee Kurzzug", - 64: "Westkreuz, Schöneberg Kurzzug", - 65: "Westkreuz, Ostkreuz Kurzzug", - 66: "Jungfernheide Kurzzug", - 67: "Jungfernheide, Gesundbrunnen Kurzzug", - 68: "Gesundbrunnen, Ostkreuz, Südkreuz, Westkreuz", - 69: "Westkreuz, Südkreuz, Ostkreuz, Gesundbrunnen", - 70: "Gesundbrunnen, Schönhauser Allee Kurzzug", - 71: "Messe Nord/ICC (Witzleben)", - 72: "In die letzten 4 Wagen bitte nicht einsteigen", - 73: "Zug fährt später", - 74: "Ansage beachten", - 75: "Kurzzug", - 76: "Ersatzverkehr", - 77: "Zugverkehr unterbrochen", - 78: "Zugverkehr unregelmäßig" -} - -MAP_LINE = { - 1: "S1", - 3: "S2", - 5: "S3", - 7: "S4", - 9: "S5", - 11: "S6", - 13: "S7", - 15: "S8", - 17: "S9", - 19: "S10", - 21: "S75", - 23: "S85", - 25: "S86", - 27: "S25", - 29: "S45", - 31: "S46", - 33: "S26", - 35: "S41", - 37: "S42", - 39: "S47" -} - -MAP_DESTINATION = { - 0: "Alexanderplatz", - 1: "Ahrensfelde", - 2: "Anhalter Bahnhof", - 3: "Baumschulenweg", - 4: "Bernau", - 5: "Birkenwerder", - 6: "Blankenburg", - 7: "Blankenfelde", - 8: "Buch", - 9: "Bundesplatz", - 10: "Charlottenburg", - 11: "Erkner", - 12: "Falkensee", - 13: "Friedrichshagen", - 14: "Friedrichstraße", - 15: "Schönefeld Flughafen", - 16: "Frohnau", - 17: "Gesundbrunnen", - 18: "Greifswalder Straße", - 19: "Grunewald", - 20: "Grünau", - 21: "Halensee", - 22: "Ostbahnhof", - 23: "Hermannstraße", - 24: "Hermsdorf", - 25: "Henningsdorf", - 26: "Hoppegarten (Markt)", - 27: "Karlshorst", - 28: "Königs Wusterhausen", - 29: "Köpenik", - 30: "Lichtenberg", - 31: "Lichtenrade", - 32: "Lichterfeld Süd", - 33: "Mahlow", - 34: "Mahlsdorf", - 35: "Marienfelde", - 36: "Nordbahnhof", - 37: "Olympiastadion", - 38: "Oranienburg", - 39: "Ostkreuz", - 40: "Südkreuz", - 41: "Pichelsberg", - 42: "Potsdam Hbf", - 43: "Potsdamer Platz", - 44: "Westhafen", - 45: "Rangsdorf", - 46: "Spandau", - 47: "Schöneberg", - 48: "Schöneweide", - 49: "Schönholz", - 50: "Sellheimbrücke", - 51: "Spindlersfeld", - 52: "Rathaus Steglitz", - 53: "Strausberg", - 54: "Strausberg Nord", - 55: "Streslow", - 56: "Tegel", - 57: "Tempelhof", - 58: "Wannsee", - 59: "Warschauer Straße", - 60: "Westend", - 61: "Westkreuz", - 62: "Zehlendorf", - 63: "Zoologischer Garten", - 64: "Zeuthen", - 65: "Berlin Hbf", - 66: "Landsberger Allee", - 67: "Marzahn", - 68: "Neukölln", - 69: "Pankow", - 70: "Schönhauser Allee", - 71: "Springpfuhl", - 72: "Treptower Park", - 73: "Ring ↻", - 74: "Ring ↺", - 75: "Gesundbrunnen/Ring", - 76: "Beusselstraße", - 77: "Wedding", - 78: "Nicht einsteigen" -} - - -class BerlinSplitFlapDisplay(SplitFlapDisplay): - route = CustomMapField(MAP_ROUTE, start_address=1, x=0, y=0, module_width=20, module_height=1, home_pos=99) - line = CustomMapField(MAP_LINE, start_address=2, x=0, y=1, module_width=4, module_height=1, home_pos=99) - destination = CustomMapField(MAP_DESTINATION, start_address=3, x=4, y=1, module_width=16, module_height=1, home_pos=99) - - -@timeout(30) -def get_trains(dbi, station): - return dbi.get_trains(station) - - -def main(): - controller = Krone8200Controller("/dev/serial/by-path/platform-3f980000.usb-usb-0:1.5.4:1.0-port0", RX_ADDRESS, debug=True) - display = BerlinSplitFlapDisplay(controller) - dbi = DBInfoscreen("dbf.finalrewind.org") - - last_update = 0 - last_heartbeat = 0 - while True: - now = time.time() - - if now - last_heartbeat >= 10: - print("\n" + "=" * 60 + "\n") - print("Sending heartbeat") - controller.send_end_comm() - last_heartbeat = now - continue - - if now - last_update < 60: - time.sleep(1) - continue - - print("\n" + "=" * 60 + "\n") - - try: - trains = get_trains(dbi, "Berlin Westkreuz") - trains = dbi.calc_real_times(trains) - display.clear() - line = "" - dest = "" - route = "" - - trains.sort(key=dbi.time_sort) - for train in trains: - # Only show trains within the next 3 minutes - now_dt = datetime.datetime.now() - departure_time = datetime.datetime.strptime(train['actualDeparture'] or train['actualArrival'], "%H:%M").time() - departure_date = (now_dt.date() + datetime.timedelta(days=1)) if (now_dt.time().hour - departure_time.hour) >= 2 else now_dt.date() - departure_dt = datetime.datetime.combine(departure_date, departure_time) - delta = departure_dt - now_dt - if delta.total_seconds() / 60 > 3: - continue - - line = "".join(train['train'].split()) - display.line.set(line) - if line == "S41": - dest = "Ring ↻" - elif line == "S42": - dest = "Ring ↺" - else: - dest = train['destination'].replace("Berlin-", "").replace("Berlin", "").replace("(S)", "").strip() - if dest == "Westkreuz": - dest = "Nicht einsteigen" - if dest not in MAP_DESTINATION.values(): - continue - display.destination.set(dest) - - delay = train['delayDeparture'] or train['delayArrival'] or 0 - - route = "" - if train['train'] == "Bus SEV": - route = "Ersatzverkehr" - elif all(map(lambda t: t['isCancelled'], trains[:20])): - route = "Zugverkehr unterbrochen" - elif all(map(lambda t: t['isCancelled'], trains[:5])): - route = "Zugverkehr unregelmäßig" - elif train['isCancelled'] or delay > 60: - route = "Ansage beachten" - elif delay > 2: - route = "Zug fährt später" - elif line == "S41": - route = "Gesundbrunnen, Schönhauser Allee, Ostkreuz, Neukölln" - elif line == "S42": - route = "Schöneberg, Neukölln, Ostkreuz, Gesundbrunnen" - elif line == "S46" and dest == "Königs Wusterhausen": - route = "Schöneberg, Südkreuz, Neukölln, Baumschulenweg" - elif line == "S46" and dest == "Westend": - route = "Messe Nord/ICC (Witzleben)" - elif dest == "": - route = "Ansage beachten" - display.route.set(route) - break - - print(display.render_ascii()) - - try: - with open("status.json", 'r') as f: - status = json.load(f) - except (FileNotFoundError, ValueError): - status = {'displayHash': None} - - display_hash = hashlib.sha256(bytes(line + dest + route, 'utf-8')).hexdigest() - - update = True - if status['displayHash'] == display_hash: - print("No need to update display.") - update = False - else: - status['displayHash'] = display_hash - - if update: - num_tries = 10 - for i in range(num_tries): - try: - display.update() - break - except CommunicationError: - print("Communication error! Retrying... {}/{}".format(i+1, num_tries)) - time.sleep(5) - - with open("status.json", 'w') as f: - json.dump(status, f) - except: - traceback.print_exc() - - last_update = now - - -if __name__ == "__main__": - main() +import datetime +import hashlib +import json +import time +import traceback + +from db_infoscreen import DBInfoscreen +from splitflap.krone import Krone8200Controller +from splitflap.display import SplitFlapDisplay, CustomMapField +from splitflap.exceptions import CommunicationError + +from util import timeout + +RX_ADDRESS = (0x41, 0x41) + +MAP_ROUTE = { + 0: "Halensee, Schöneberg, Südkreuz, Neukölln", + 1: "Schöneberg, Südkreuz, Neukölln, Baumschulenweg", + 2: "Schöneberg, Südkreuz, Neukölln, Schöneweide", + 3: "Schöneberg, Neukölln, Schöneweide, Grünau", + 4: "Gesundbrunnen, Schönhauser Allee, Ostkreuz, Treptower Park", + 5: "Gesundbrunnen, Schönhauser Allee, Ostkreuz, Neukölln", + 6: "Gesundbrunnen, Ostkreuz, Neukölln, Südkreuz", + 7: "Gesundbrunnen, Ostkreuz, Neukölln, Schöneberg", + 8: "Westend", + 9: "Westend, Jungfernheide", + 10: "Westend, Jungfernheide, Westhafen", + 11: "Westend, Jungfernheide, Westhafen, Gesundbrunnen", + 12: "Westend, Jungfernheide, Gesundbrunnen, Schönhauser Allee", + 13: "Jungfernheide, Gesundbrunnen, Schönhauser Allee, Ostkreuz", + 14: "Gesundbrunnen, Ostkreuz, Schöneberg", + 15: "Halensee, Schöneberg, Südkreuz, Neukölln", + 16: "Schöneberg, Südkreuz, Neukölln, Ostkreuz", + 17: "Schöneberg, Neukölln, Ostkreuz, Gesundbrunnen", + 18: "Halensee", + 19: "Halensee, Bundesplatz", + 20: "Halensee, Bundesplatz, Schöneberg", + 21: "Halensee, Bundesplatz, Schöneberg, Südkreuz", + 22: "Schöneberg, Ostkreuz, Gesundbrunnen", + 23: "weiter als S2 über Buch", + 24: "Jungfernheide, Gesundbrunnen", + 25: "Jungfernheide, Gesundbrunnen, Bornholmer Straße, Schönholz", + 26: "Westkreuz, Schöneberg, Südkreuz, Neukölln", + 27: "Westkreuz, Schöneberg, Neukölln, Baumschulenweg", + 28: "Westkreuz, Schöneberg, Neukölln, Schöneweide", + 29: "Westkreuz, Schöneberg, Schöneweide, Grünau", + 30: "Gesundbrunnen, Ostkreuz, Schöneberg, Westkreuz", + 31: "Westkreuz, Schöneberg, Neukölln, Ostkreuz", + 32: "Westkreuz, Neukölln, Ostkreuz, Gesundbrunnen", + 33: "Westkreuz", + 34: "Westkreuz, Halensee", + 35: "Westkreuz, Halensee, Bundesplatz", + 36: "Westkreuz, Halensee, Bundesplatz, Schöneberg", + 37: "Westkreuz, Halensee, Schöneberg, Südkreuz", + 38: "Westkreuz, Schöneberg, Ostkreuz, Gesundbrunnen", + 39: "Jungfernheide", + 40: "Jungfernheide, Westhafen", + 41: "Jungfernheide, Westhafen, Gesundbrunnen", + 42: "Jungfernheide, Westhafen, Gesundbrunnen, Schönhauser Allee", + 43: "Jungfernheide, Gesundbrunnen, Bornholmer Straße", + 44: "Schöneberg, Neukölln Kurzzug", + 45: "Neukölln, Schöneweide Kurzzug", + 46: "Gesundbrunnen, Ostkreuz Kurzzug", + 47: "Westend Kurzzug", + 48: "Westend, Jungfernheide Kurzzug", + 49: "Jungfernheide, Gesundbrunnen Kurzzug", + 50: "Schöneberg, Neukölln Kurzzug", + 51: "Neukölln, Ostkreuz Kurzzug", + 52: "Halensee Kurzzug", + 53: "Halensee, Bundesplatz Kurzzug", + 54: "Halensee, Schöneberg Kurzzug", + 55: "Schöneberg, Ostkreuz Kurzzug", + 56: "Westend, Gesundbrunnen Kurzzug", + 57: "Gesundbrunnen, Bornholmer Straße Kurzzug", + 58: "Gesundbrunnen, Schönholz Kurzzug", + 59: "Westkreuz, Neukölln Kurzzug", + 60: "Westkreuz, Schöneweide Kurzzug", + 61: "Ostkreuz, Gesundbrunnen Kurzzug", + 62: "Westkreuz Kurzzug", + 63: "Westkreuz, Halensee Kurzzug", + 64: "Westkreuz, Schöneberg Kurzzug", + 65: "Westkreuz, Ostkreuz Kurzzug", + 66: "Jungfernheide Kurzzug", + 67: "Jungfernheide, Gesundbrunnen Kurzzug", + 68: "Gesundbrunnen, Ostkreuz, Südkreuz, Westkreuz", + 69: "Westkreuz, Südkreuz, Ostkreuz, Gesundbrunnen", + 70: "Gesundbrunnen, Schönhauser Allee Kurzzug", + 71: "Messe Nord/ICC (Witzleben)", + 72: "In die letzten 4 Wagen bitte nicht einsteigen", + 73: "Zug fährt später", + 74: "Ansage beachten", + 75: "Kurzzug", + 76: "Ersatzverkehr", + 77: "Zugverkehr unterbrochen", + 78: "Zugverkehr unregelmäßig" +} + +MAP_LINE = { + 1: "S1", + 3: "S2", + 5: "S3", + 7: "S4", + 9: "S5", + 11: "S6", + 13: "S7", + 15: "S8", + 17: "S9", + 19: "S10", + 21: "S75", + 23: "S85", + 25: "S86", + 27: "S25", + 29: "S45", + 31: "S46", + 33: "S26", + 35: "S41", + 37: "S42", + 39: "S47" +} + +MAP_DESTINATION = { + 0: "Alexanderplatz", + 1: "Ahrensfelde", + 2: "Anhalter Bahnhof", + 3: "Baumschulenweg", + 4: "Bernau", + 5: "Birkenwerder", + 6: "Blankenburg", + 7: "Blankenfelde", + 8: "Buch", + 9: "Bundesplatz", + 10: "Charlottenburg", + 11: "Erkner", + 12: "Falkensee", + 13: "Friedrichshagen", + 14: "Friedrichstraße", + 15: "Schönefeld Flughafen", + 16: "Frohnau", + 17: "Gesundbrunnen", + 18: "Greifswalder Straße", + 19: "Grunewald", + 20: "Grünau", + 21: "Halensee", + 22: "Ostbahnhof", + 23: "Hermannstraße", + 24: "Hermsdorf", + 25: "Henningsdorf", + 26: "Hoppegarten (Markt)", + 27: "Karlshorst", + 28: "Königs Wusterhausen", + 29: "Köpenik", + 30: "Lichtenberg", + 31: "Lichtenrade", + 32: "Lichterfeld Süd", + 33: "Mahlow", + 34: "Mahlsdorf", + 35: "Marienfelde", + 36: "Nordbahnhof", + 37: "Olympiastadion", + 38: "Oranienburg", + 39: "Ostkreuz", + 40: "Südkreuz", + 41: "Pichelsberg", + 42: "Potsdam Hbf", + 43: "Potsdamer Platz", + 44: "Westhafen", + 45: "Rangsdorf", + 46: "Spandau", + 47: "Schöneberg", + 48: "Schöneweide", + 49: "Schönholz", + 50: "Sellheimbrücke", + 51: "Spindlersfeld", + 52: "Rathaus Steglitz", + 53: "Strausberg", + 54: "Strausberg Nord", + 55: "Streslow", + 56: "Tegel", + 57: "Tempelhof", + 58: "Wannsee", + 59: "Warschauer Straße", + 60: "Westend", + 61: "Westkreuz", + 62: "Zehlendorf", + 63: "Zoologischer Garten", + 64: "Zeuthen", + 65: "Berlin Hbf", + 66: "Landsberger Allee", + 67: "Marzahn", + 68: "Neukölln", + 69: "Pankow", + 70: "Schönhauser Allee", + 71: "Springpfuhl", + 72: "Treptower Park", + 73: "Ring ↻", + 74: "Ring ↺", + 75: "Gesundbrunnen/Ring", + 76: "Beusselstraße", + 77: "Wedding", + 78: "Nicht einsteigen" +} + + +class BerlinSplitFlapDisplay(SplitFlapDisplay): + route = CustomMapField(MAP_ROUTE, start_address=1, x=0, y=0, module_width=20, module_height=1, home_pos=99) + line = CustomMapField(MAP_LINE, start_address=2, x=0, y=1, module_width=4, module_height=1, home_pos=99) + destination = CustomMapField(MAP_DESTINATION, start_address=3, x=4, y=1, module_width=16, module_height=1, home_pos=99) + + +@timeout(30) +def get_trains(dbi, station): + return dbi.get_trains(station) + + +def main(): + controller = Krone8200Controller("/dev/serial/by-path/platform-3f980000.usb-usb-0:1.5.4:1.0-port0", RX_ADDRESS, debug=True) + display = BerlinSplitFlapDisplay(controller) + dbi = DBInfoscreen("dbf.finalrewind.org") + + last_update = 0 + last_heartbeat = 0 + while True: + now = time.time() + + if now - last_heartbeat >= 10: + print("\n" + "=" * 60 + "\n") + print("Sending heartbeat") + controller.send_end_comm() + last_heartbeat = now + continue + + if now - last_update < 60: + time.sleep(1) + continue + + print("\n" + "=" * 60 + "\n") + + try: + trains = get_trains(dbi, "Berlin Westkreuz") + trains = dbi.calc_real_times(trains) + display.clear() + line = "" + dest = "" + route = "" + + trains.sort(key=dbi.time_sort) + for train in trains: + # Only show trains within the next 3 minutes + now_dt = datetime.datetime.now() + departure_time = datetime.datetime.strptime(train['actualDeparture'] or train['actualArrival'], "%H:%M").time() + departure_date = (now_dt.date() + datetime.timedelta(days=1)) if (now_dt.time().hour - departure_time.hour) >= 2 else now_dt.date() + departure_dt = datetime.datetime.combine(departure_date, departure_time) + delta = departure_dt - now_dt + if delta.total_seconds() / 60 > 3: + continue + + line = "".join(train['train'].split()) + display.line.set(line) + if line == "S41": + dest = "Ring ↻" + elif line == "S42": + dest = "Ring ↺" + else: + dest = train['destination'].replace("Berlin-", "").replace("Berlin", "").replace("(S)", "").strip() + if dest == "Westkreuz": + dest = "Nicht einsteigen" + if dest not in MAP_DESTINATION.values(): + continue + display.destination.set(dest) + + delay = train['delayDeparture'] or train['delayArrival'] or 0 + + route = "" + if train['train'] == "Bus SEV": + route = "Ersatzverkehr" + elif all(map(lambda t: t['isCancelled'], trains[:20])): + route = "Zugverkehr unterbrochen" + elif all(map(lambda t: t['isCancelled'], trains[:5])): + route = "Zugverkehr unregelmäßig" + elif train['isCancelled'] or delay > 60: + route = "Ansage beachten" + elif delay > 2: + route = "Zug fährt später" + elif line == "S41": + route = "Gesundbrunnen, Schönhauser Allee, Ostkreuz, Neukölln" + elif line == "S42": + route = "Schöneberg, Neukölln, Ostkreuz, Gesundbrunnen" + elif line == "S46" and dest == "Königs Wusterhausen": + route = "Schöneberg, Südkreuz, Neukölln, Baumschulenweg" + elif line == "S46" and dest == "Westend": + route = "Messe Nord/ICC (Witzleben)" + elif dest == "": + route = "Ansage beachten" + display.route.set(route) + break + + print(display.render_ascii()) + + try: + with open("status.json", 'r') as f: + status = json.load(f) + except (FileNotFoundError, ValueError): + status = {'displayHash': None} + + display_hash = hashlib.sha256(bytes(line + dest + route, 'utf-8')).hexdigest() + + update = True + if status['displayHash'] == display_hash: + print("No need to update display.") + update = False + else: + status['displayHash'] = display_hash + + if update: + num_tries = 10 + for i in range(num_tries): + try: + display.update() + break + except CommunicationError: + print("Communication error! Retrying... {}/{}".format(i+1, num_tries)) + time.sleep(5) + + with open("status.json", 'w') as f: + json.dump(status, f) + except: + traceback.print_exc() + + last_update = now + + +if __name__ == "__main__": + main()