Erste funktionsfähige Tracker-Version

This commit is contained in:
2025-09-15 19:33:33 +02:00
parent ebb7b42d48
commit eb41bdafa4
6 changed files with 291 additions and 92 deletions

View File

@@ -12,6 +12,9 @@ Wenn die Verbindung zum Server im Internet nicht funktioniert, werden
die Positionen in eine Warteschlange gesichert und nach
Wiederherstellung der Verbindung übertragen.
TODO
- Nach einem Disconnect manuelle Neuverbindung ermöglichen
"""
import os
@@ -23,11 +26,8 @@ import socket
class Tracker():
def __init__(self, trackertype='NONE'):
validtypes = ('HERO', 'SDCARD', 'SERVER', 'NONE')
trackertype = trackertype.upper()
if trackertype not in validtypes:
raise TypeError(f"Invalid tracker type: '{valtype}'. Only supported: {validtypes}")
self.ttype = trackertype
self.ttype = 'NONE'
self.set_type(trackertype)
self.appdata = None
@@ -44,7 +44,8 @@ class Tracker():
self.sog = None
self.hero_orgstatus = None
self.hero_racestatus = None # Akluelle Regatta
self.hero_racestatus = None # Aktuelle Regatta
self.hero_raceid = None
# TODO Wirklich alles im Tracker oder ist einiges generisch?
self.boatid = None
@@ -75,6 +76,16 @@ class Tracker():
def set_active(self, newval):
self.activated = newval
def set_hero_raceid(self, newraceid):
self.hero_raceid = newraceid
def set_type(self, newtype):
validtypes = ('HERO', 'SDCARD', 'SERVER', 'NONE')
newtype = newtype.upper()
if newtype not in validtypes:
raise TypeError(f"Invalid tracker type: '{newtype}'. Only supported: {validtypes}")
self.ttype = newtype
def get_position(self):
# Positionsabfrage für die Payload
# LAT, LON, TSPOS, SOG
@@ -124,25 +135,39 @@ class Tracker():
if self.hero_orgstatus['allLogout']:
print("All logout received!")
client.disconnect()
sys.exit(0) # TODO nur die MQTT-Task beenden
self.activated = False
return
if self.hero_orgstatus['message']:
# TODO Alarm-Funktion nutzen?
print("Nachricht der Wettfahrtkeitung:")
print(orgstatus['message'])
print(self.hero_orgstatus['message'])
#print(self.hero_orgstatus)
elif msg.topic.startswith("regattahero/racestatus/thomas"):
# kommt alle 1s
# dem Topic angehängt ist noch die raceid
payload = json.loads(msg.payload)
racestatus = payload['racestatus']
self.hero_racestatus = payload['racestatus']
print(self.hero_racestatus['flags'])
#print(self.hero_racestatus)
"""
time: negativ: Zeit vor dem Start, positiv: Zeit nach dem Start
in Sekunden
flags: [0, 0, 14, 10]
raceactive: true bedeutet orange Flagge ist oben
racestarted: true
Signale der Wettfahrtleitung hier anzeigen
Regattaabbruch
Bahnverkürzung
Rückrufe
phase: 0 vor dem Start racephase: 1
racephase: 4
5 Vorbereitungssignal
racephase: 6 nach vorbereitnug wieder runter
7: Rennen gestartet
"""
else:
print(f"UNKNOWN TOPIC: {msg.topic}")
@@ -152,16 +177,19 @@ class Tracker():
"""
Payload vorbelegt als Template, so daß nur noch die veränderlichen
GPS-Daten eingefügt werden müssen: LAT LON SOG TIMESTAMP
isTracking kann ausgeschaltet werden,
"""
lat = bv_lat.getValueRaw()
lon = bv_lon.getValueRaw()
sog = bv_sog.getValueRaw()
if lat and lon and sog:
if lat and lon and (sog is not None):
payload['raceid'] = self.hero_raceid
payload['gps']['lat'] = round(lat, 5)
payload['gps']['lon'] = round(lon, 5)
payload['gps']['speed'] = sog
payload['gps']['timestamp'] = time.strftime("%Y-%m-%dT%H:%M:%S.000Z", time.gmtime())
print(payload)
client.publish(topic, json.dumps(payload))
else:
print("No GPS data available. Nothing published!")
@@ -189,13 +217,13 @@ class Tracker():
payload = {
"passcode": cfg['passcode'],
"orgid": cfg['orgname'],
"raceid": "Demo Regatta", # TODO aus Selektion einstellen
"raceid": None, # Nach Auswahl einstellen
"gps": {
"lat": 0.0,
"lon": 0.0,
"speed": 0.0,
"age": 1000,
"odo": 1000,
"age": 500,
# "odo": 1000, # deprecated
"bat": 1.0,
"timestamp": "" # ISO8601 Format mit Millisekunden in UTC
},
@@ -206,7 +234,9 @@ class Tracker():
"boatclass": boat['class'],
"handicap": boat['handicap'],
"club": boat['club'],
"boatname": boat['name']
"boatname": boat['name'],
"isTracking": True,
"hasGivenUp": False
}
}
@@ -218,7 +248,7 @@ class Tracker():
client.loop_start()
while not appdata.shutdown:
time.sleep(1)
if appdata.track.is_active():
if self.activated and self.hero_raceid is not None:
self.mqtt_publish(client, topic, payload, bv_lat, bv_lon, bv_sog)
client.loop_stop()
client.disconnect()