diff --git a/pages/racetracker.py b/pages/racetracker.py index 09cb03a..2aecdb0 100644 --- a/pages/racetracker.py +++ b/pages/racetracker.py @@ -306,12 +306,18 @@ class RaceTracker(Page): ctx.move_to(8, 260) ctx.show_text(f"!!! Time drift of {self.app.track.hero_timedelta} seconds") + x0 = 8 x1 = 96 y0 = 150 yoffset = 18 ctx.select_font_face("Ubuntu", cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD) ctx.set_font_size(16) + + # Debug: Phase anzeigen + ctx.move_to(360, 35) + ctx.show_text(str(self.app.track.hero_racephase)) + ctx.move_to(x0, y0) ctx.show_text("Type") ctx.move_to(x1, y0) diff --git a/tracker.py b/tracker.py index 7bd6c61..5d03e28 100644 --- a/tracker.py +++ b/tracker.py @@ -98,11 +98,13 @@ class Tracker(): self.hero_raceid = None # Aktuell ausgewählte Regatta self.hero_racephase = 0 # Bei Änderung Event auslösen + self.hero_shortened = False # Bahnverkürzung aktiv # MQTT self.client = mqtt.Client() self.client.on_connect = self.mqtt_on_connect self.client.on_message = self.mqtt_on_message + self.client_race_age = 0 # Age of last mqtt race data in seconds self.hero_orgstatus = None self.hero_racestatus = None @@ -251,21 +253,21 @@ class Tracker(): else: return math.degrees(2 * math.pi - azimut + math.pi * 3 / 2) - def hero_query_org(self): + def hero_query(self, raceid): """ - Abfrage des Datenservers / Basisdaten - - Namen der Regatten und Kurse + Query Regatta Hero HTTP-Server """ ssl_context = ssl.create_default_context() conn = http.client.HTTPSConnection(self.hero_host, self.hero_port, context=ssl_context) endpoint = '/mapupdate' payload = self.http_payload_template - payload['raceid'] = '[No race]' + payload['raceid'] = raceid json_data = json.dumps(payload) headers = { 'Content-Type': 'application/json', 'Content-Length': str(len(json_data)) } + data = {} # empty try: conn.request("POST", endpoint, body=json_data, headers=headers) response = conn.getresponse() @@ -274,13 +276,21 @@ class Tracker(): data = json.loads(response.read().decode()) else: self.log.warning(f"HTTP: Failed to retrieve data. Status code: {response.status}") - return + return data except http.client.HTTPException as e: self.log.warning(f"HTTP error occurred: {e}") except ssl.SSLError as ssl_error: self.log.warning(f"SSL error occurred: {ssl_error}") finally: conn.close() + return data + + def hero_query_org(self): + """ + Abfrage des Datenservers / Basisdaten + - Namen der Regatten und Kurse + """ + data = self.hero_query('[No race]') self.viewerpass = data['org']['viewerPasscode'] self.courses = [] for c in data['org']['courses']: @@ -294,32 +304,10 @@ class Tracker(): self.hero_raceid = self.races[0] def hero_query_course(self, raceid): - # Bojen und Kurs für ein gegebenes Rennen - ssl_context = ssl.create_default_context() - endpoint = '/mapupdate' - conn = http.client.HTTPSConnection(self.hero_host, self.hero_port, context=ssl_context) - payload = self.http_payload_template - payload['raceid'] = raceid - json_data = json.dumps(payload) - headers = { - 'Content-Type': 'application/json', - 'Content-Length': str(len(json_data)) - } - try: - conn.request("POST", endpoint, body=json_data, headers=headers) - response = conn.getresponse() - if response.status == 200: - self.log.info("HTTP: Response received successfully!") - data = json.loads(response.read().decode()) - else: - self.log.warning(f"HTTP: Failed to retrieve data. Status code: {response.status}") - return - except http.client.HTTPException as e: - self.log.warning(f"HTTP error occurred: {e}") - except ssl.SSLError as ssl_error: - self.log.warning(f"SSL error occurred: {ssl_error}") - finally: - conn.close() + """ + Bojen und Kurs für ein gegebenes Rennen + """ + data = self.hero_query(raceid) print(self.hero_orgdata) @@ -334,6 +322,23 @@ class Tracker(): print(self.buoys) # Kurse + self.courses = [] + for c in data['org']['courses']: + self.courses.append(c) + self.races = [] + for r in data['org']['races'].values(): + if not r['hiderace']: + self.races.append(r['raceid']) + + def hero_query_race(self, raceid): + """ + Aktuelle Regattadaten vom HTTP-Server holen, ggf. weil MQTT nichts mehr sendet + """ + data = self.hero_query(raceid) + self.hero_racestatus = data['race']['racestatus'] + print(self.hero_racestatus) + # 'raceactive': False + # 'racefinished': True def get_position(self): # Positionsabfrage für die Payload @@ -407,6 +412,7 @@ class Tracker(): elif msg.topic.startswith(f"regattahero/racestatus/{self.hero_orgid}"): # kommt alle 1s # dem Topic angehängt ist noch die raceid + self.client_race_age = 0 payload = json.loads(msg.payload) self.hero_racestatus = payload['racestatus'] racephase = payload['racestatus']['racephase'] @@ -431,9 +437,11 @@ class Tracker(): elif self.hero_racephase == 2: if racephase == 3: self.hero_play_audio('vierMin') + elif racephase == 4: + self.hero_play_audio('dreiMin') elif self.hero_racephase == 3: if racephase == 4: - pass + self.hero_play_audio('dreiMin') if racephase == 1: self.hero_play_audio('startVerschiebung') @@ -449,6 +457,9 @@ class Tracker(): elif racephase == 6: # Blauer Peter runter pass + elif self.hero_racephase == 6: + if racephase == 1: + self.hero_play_audio('startVerschiebung') elif self.hero_racephase == 7: if racephase == 8: # Gestartet @@ -457,8 +468,10 @@ class Tracker(): if racephase == 2: if payload['racestatus']['recallgeneral']: self.hero_play_audio('allgmRueck') - else: + elif payload['racestatus']['racecancelled']: self.hero_play_audio('abbruch') + elif payload['racestatus']['racefinished']: + self.hero_play_audio('endeWettfahrt') self.hero_racephase = racephase # TODO Einzelrückruf, keine Änderung in der Phase! @@ -482,6 +495,13 @@ class Tracker(): # payload['racestatus']['racestarted'] # payload['racesettings'] + + # Bahnverkürzung + if payload['racestatus']['shortend'] and not self.hero_shortened: + self.hero_shortened = True + self.hero_play_audio('bahnVerk') + self.log.info("Bahnverkürzung: Zu Bahnmarke {}".format(payload['racestatus']['shortendsel'])) + """ time: negativ: Zeit vor dem Start, positiv: Zeit nach dem Start in Sekunden @@ -579,8 +599,19 @@ class Tracker(): self.client.loop_start() while not appdata.shutdown: time.sleep(1) + self.client_race_age += 1 if self.activated and self.hero_raceid is not None: self.mqtt_publish(topic, payload, bv_lat, bv_lon, bv_sog) + if self.client_race_age > 15: + # Server sendet keine Daten mehr oder Verbindung verloren + # TODO Frage den http-Server nach den letzten Racestatus + self.log.warning(f"Keine Daten vom MQTT-Sever seit ca. {self.client_race_age} Sekunden") + self.log.warning("Hole Daten vom HTTP-Server") + self.hero_query_race(self.hero_raceid) + if self.hero_racestatus['racefinished'] == True: + self.hero_racephase = 0 + self.hero_play_audio('endeWettfahrt') + self.activated = False self.client.loop_stop() self.client.disconnect() if cfg['trace']: