Lokaler Tracker funktionsfähig. Bugfixes.
This commit is contained in:
parent
f0ebdd0201
commit
e7a96390f2
7
TODO
7
TODO
|
@ -6,6 +6,13 @@ Aufgaben, Planungs- und Ideenliste
|
||||||
b) lokal
|
b) lokal
|
||||||
c) Server
|
c) Server
|
||||||
|
|
||||||
|
- Internationalisierung
|
||||||
|
1. EN (Standardsprache)
|
||||||
|
2. DE
|
||||||
|
3. FR
|
||||||
|
4. ES
|
||||||
|
5. IT
|
||||||
|
|
||||||
- Satelliten: SatelliteList verwenden und dieses auch in
|
- Satelliten: SatelliteList verwenden und dieses auch in
|
||||||
nmea2000 implementieren
|
nmea2000 implementieren
|
||||||
- Satellitenübersicht / SkyView
|
- Satellitenübersicht / SkyView
|
||||||
|
|
12
obp60v.py
12
obp60v.py
|
@ -115,7 +115,7 @@ import pages
|
||||||
|
|
||||||
__author__ = "Thomas Hooge"
|
__author__ = "Thomas Hooge"
|
||||||
__copyright__ = "Copyleft 2024-2025, all rights reversed"
|
__copyright__ = "Copyleft 2024-2025, all rights reversed"
|
||||||
__version__ = "0.2"
|
__version__ = "0.3"
|
||||||
__email__ = "thomas@hoogi.de"
|
__email__ = "thomas@hoogi.de"
|
||||||
__status__ = "Development"
|
__status__ = "Development"
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ cfg = {
|
||||||
'loglevel': 3,
|
'loglevel': 3,
|
||||||
'imgpath': os.path.join(sys.path[0], 'images'),
|
'imgpath': os.path.join(sys.path[0], 'images'),
|
||||||
'audiopath': os.path.join(sys.path[0], 'audio'),
|
'audiopath': os.path.join(sys.path[0], 'audio'),
|
||||||
'histpath' = '~/.local/lib/obp60v',
|
'histpath': '~/.local/lib/obp60v',
|
||||||
'deviceid': 100,
|
'deviceid': 100,
|
||||||
'manufcode': 2046, # Open Boat Projects (OBP)
|
'manufcode': 2046, # Open Boat Projects (OBP)
|
||||||
'devfunc': 120, # Display
|
'devfunc': 120, # Display
|
||||||
|
@ -749,6 +749,7 @@ if __name__ == "__main__":
|
||||||
cfg['tracker']['mqtt_pass'] = config.get('tracker', 'mqtt_pass')
|
cfg['tracker']['mqtt_pass'] = config.get('tracker', 'mqtt_pass')
|
||||||
cfg['tracker']['logdir'] = cfg['logdir']
|
cfg['tracker']['logdir'] = cfg['logdir']
|
||||||
cfg['tracker']['trace'] = config.getboolean('tracker', 'trace')
|
cfg['tracker']['trace'] = config.getboolean('tracker', 'trace')
|
||||||
|
cfg['tracker']['interval'] = config.getint('tracker', 'interval')
|
||||||
|
|
||||||
# Boat data
|
# Boat data
|
||||||
cfg['boat']['name'] = config.get('boat', 'name')
|
cfg['boat']['name'] = config.get('boat', 'name')
|
||||||
|
@ -806,13 +807,14 @@ if __name__ == "__main__":
|
||||||
log.info("Networking enabled")
|
log.info("Networking enabled")
|
||||||
t_rxd_net = threading.Thread(target=rxd_network, args=(cfg['net_port'],cfg['net_addr']))
|
t_rxd_net = threading.Thread(target=rxd_network, args=(cfg['net_port'],cfg['net_addr']))
|
||||||
t_rxd_net.start()
|
t_rxd_net.start()
|
||||||
if cfg['tracker']['type'] == 'NONE':
|
if cfg['tracker']['type'] != 'NONE':
|
||||||
log.info(f"Tracking enabled, mode {cfg['tracker']['type']}")
|
log.info(f"Tracking enabled, mode {cfg['tracker']['type']}")
|
||||||
#appdata.track.set_type( cfg['tracker']['type'])
|
#appdata.track.set_type( cfg['tracker']['type'])
|
||||||
if cfg['tracker']['type'] == 'HERO':
|
if cfg['tracker']['type'] == 'HERO':
|
||||||
t_tracker = threading.Thread(target=appdata.track.mqtt_tracker, args=(cfg['tracker'],cfg['boat'],appdata,boatdata))
|
t_tracker = threading.Thread(target=appdata.track.mqtt_tracker, args=(cfg['tracker'],cfg['boat'],appdata,boatdata))
|
||||||
elif cfg['tracker']['type'] IN ['LOCAL', 'SDCARD']:
|
t_tracker.start()
|
||||||
t_tracker = threading.Thread(target=appdata.track.local_tracker, args=(cfg['tracker'],cfg['boat'],appdata,boatdata))
|
elif cfg['tracker']['type'] in ['LOCAL', 'SDCARD']:
|
||||||
|
t_tracker = threading.Thread(target=appdata.track.local_tracker, args=(cfg,appdata,boatdata))
|
||||||
t_tracker.start()
|
t_tracker.start()
|
||||||
if not cfg['simulation']:
|
if not cfg['simulation']:
|
||||||
if cfg['bme280']:
|
if cfg['bme280']:
|
||||||
|
|
|
@ -45,7 +45,10 @@ class Barograph(Page):
|
||||||
# Meßwert alle 15 Minuten:
|
# Meßwert alle 15 Minuten:
|
||||||
# 84 Stunden * 4 Werte je Stunde = 336 Meßwerte
|
# 84 Stunden * 4 Werte je Stunde = 336 Meßwerte
|
||||||
self.bd = boatdata
|
self.bd = boatdata
|
||||||
self.source = 'I' # (I)ntern, e(X)tern
|
if not cfg['bme280']:
|
||||||
|
self.source = None # keine Datenquelle!
|
||||||
|
else:
|
||||||
|
self.source = 'I' # (I)ntern, e(X)tern, None=Disabled
|
||||||
self.zoom = (1, 2, 3, 6, 12)
|
self.zoom = (1, 2, 3, 6, 12)
|
||||||
self.zoomindex = 4
|
self.zoomindex = 4
|
||||||
self.series = (75, 150, 300, 600, 900)
|
self.series = (75, 150, 300, 600, 900)
|
||||||
|
@ -65,6 +68,7 @@ class Barograph(Page):
|
||||||
self.buttonlabel[2] = '-'
|
self.buttonlabel[2] = '-'
|
||||||
self.buttonlabel[5] = 'SRC'
|
self.buttonlabel[5] = 'SRC'
|
||||||
|
|
||||||
|
self.data = None
|
||||||
self.refresh = time.time() - 30
|
self.refresh = time.time() - 30
|
||||||
|
|
||||||
def handle_key(self, buttonid):
|
def handle_key(self, buttonid):
|
||||||
|
@ -113,6 +117,9 @@ class Barograph(Page):
|
||||||
Transfer data from history to page buffer
|
Transfer data from history to page buffer
|
||||||
set y-axis according to data
|
set y-axis according to data
|
||||||
"""
|
"""
|
||||||
|
if self.source == None:
|
||||||
|
# TODO hier muß noch Arbeit reingesteckt werden!
|
||||||
|
return False
|
||||||
self.data = []
|
self.data = []
|
||||||
self.vmin = 9999
|
self.vmin = 9999
|
||||||
self.vmax = 0
|
self.vmax = 0
|
||||||
|
@ -363,8 +370,13 @@ class Barograph(Page):
|
||||||
ctx.stroke()
|
ctx.stroke()
|
||||||
|
|
||||||
# Meßdaten
|
# Meßdaten
|
||||||
|
if self.data:
|
||||||
for v in self.data:
|
for v in self.data:
|
||||||
x0 -= 1
|
x0 -= 1
|
||||||
if v > 0:
|
if v > 0:
|
||||||
ctx.rectangle(x0, y0 - (v - ysmin) * dy, 1.5, 1.5)
|
ctx.rectangle(x0, y0 - (v - ysmin) * dy, 1.5, 1.5)
|
||||||
ctx.fill()
|
ctx.fill()
|
||||||
|
else:
|
||||||
|
# Keine Daten vorhanden!
|
||||||
|
# TODO iregndwas nettes anzeigen
|
||||||
|
pass
|
||||||
|
|
|
@ -33,14 +33,16 @@ class RaceTracker(Page):
|
||||||
self.bv_lat = boatdata.getRef("LAT")
|
self.bv_lat = boatdata.getRef("LAT")
|
||||||
self.bv_lon = boatdata.getRef("LON")
|
self.bv_lon = boatdata.getRef("LON")
|
||||||
self.bv_sog = boatdata.getRef("SOG")
|
self.bv_sog = boatdata.getRef("SOG")
|
||||||
|
self.bv_hdop = boatdata.getRef("HDOP")
|
||||||
self.races = None
|
self.races = None
|
||||||
|
self.raceid = None
|
||||||
if self.ttype == 'HERO':
|
if self.ttype == 'HERO':
|
||||||
self.raceid = self.app.track.hero_raceid # Ausgewählte Regatta
|
self.raceid = self.app.track.hero_raceid # Ausgewählte Regatta
|
||||||
self.buttonlabel[1] = 'MODE'
|
self.buttonlabel[1] = 'MODE'
|
||||||
self.buttonlabel[2] = 'INFO'
|
self.buttonlabel[2] = 'INFO'
|
||||||
self.buttonlabel[5] = 'ABORT'
|
self.buttonlabel[5] = 'ABORT'
|
||||||
else:
|
elif self.ttype in ('LOCAL','SDCARD'):
|
||||||
self.raceid = None
|
self.buttonlabel[5] = 'ON'
|
||||||
self.menupos = 0
|
self.menupos = 0
|
||||||
self.mode = 'N' # (N)ormal, (C)onfiguration, (M)itteilung
|
self.mode = 'N' # (N)ormal, (C)onfiguration, (M)itteilung
|
||||||
self.query_active = False
|
self.query_active = False
|
||||||
|
@ -92,6 +94,8 @@ class RaceTracker(Page):
|
||||||
self.buttonlabel = self.savebuttons.copy()
|
self.buttonlabel = self.savebuttons.copy()
|
||||||
return True
|
return True
|
||||||
if buttonid == 1:
|
if buttonid == 1:
|
||||||
|
if not self.ttype == 'HERO':
|
||||||
|
return False
|
||||||
# Modus umschalten
|
# Modus umschalten
|
||||||
if self.mode == 'N':
|
if self.mode == 'N':
|
||||||
self.mode = 'C'
|
self.mode = 'C'
|
||||||
|
@ -110,6 +114,8 @@ class RaceTracker(Page):
|
||||||
self.buttonlabel[5] = 'ABORT'
|
self.buttonlabel[5] = 'ABORT'
|
||||||
return True
|
return True
|
||||||
elif buttonid == 2:
|
elif buttonid == 2:
|
||||||
|
if not self.ttype == 'HERO':
|
||||||
|
return False
|
||||||
if self.mode == 'N':
|
if self.mode == 'N':
|
||||||
self.mode = 'M' # Nachrichten der Wettfahrtleitung
|
self.mode = 'M' # Nachrichten der Wettfahrtleitung
|
||||||
self.buttonlabel[2] = ''
|
self.buttonlabel[2] = ''
|
||||||
|
@ -140,6 +146,17 @@ class RaceTracker(Page):
|
||||||
return True
|
return True
|
||||||
elif buttonid == 5:
|
elif buttonid == 5:
|
||||||
if self.mode == 'N':
|
if self.mode == 'N':
|
||||||
|
if self.ttype in ('LOCAL','SDCARD'):
|
||||||
|
# Tracking ein/-ausschalten
|
||||||
|
if self.app.track.is_active():
|
||||||
|
self.app.track.set_active(False)
|
||||||
|
self.buttonlabel[5] = 'ON'
|
||||||
|
else:
|
||||||
|
self.app.track.set_active(True)
|
||||||
|
self.buttonlabel[5] = 'OFF'
|
||||||
|
else:
|
||||||
|
if self.ttype == ('HERO'):
|
||||||
|
# Rennabbruch verarbeiten
|
||||||
self.query_active = True;
|
self.query_active = True;
|
||||||
self.savebuttons = self.buttonlabel.copy()
|
self.savebuttons = self.buttonlabel.copy()
|
||||||
self.buttonlabel[1] = ""
|
self.buttonlabel[1] = ""
|
||||||
|
@ -180,16 +197,22 @@ class RaceTracker(Page):
|
||||||
ctx.set_font_size(16)
|
ctx.set_font_size(16)
|
||||||
ctx.move_to(x, y)
|
ctx.move_to(x, y)
|
||||||
ctx.show_text("Disabled by 'NONE in configuration'.")
|
ctx.show_text("Disabled by 'NONE in configuration'.")
|
||||||
y += 40
|
y += 30
|
||||||
ctx.move_to(x, y)
|
ctx.move_to(x, y)
|
||||||
ctx.show_text("Currently only tracker type 'HERO' is")
|
ctx.show_text("Currently only tracker types 'HERO' and 'LOCAL'")
|
||||||
y += 20
|
y += 20
|
||||||
ctx.move_to(x, y)
|
ctx.move_to(x, y)
|
||||||
ctx.show_text("implemented. Please visit the Regatta")
|
ctx.show_text("are implemented.")
|
||||||
|
y += 30
|
||||||
|
ctx.move_to(x, y)
|
||||||
|
ctx.show_text("'LOCAL' tracks positions in file system.")
|
||||||
|
y += 30
|
||||||
|
ctx.move_to(x, y)
|
||||||
|
ctx.show_text("For 'HERO' pleast visit the Regatta Hero")
|
||||||
y += 20
|
y += 20
|
||||||
ctx.move_to(x, y)
|
ctx.move_to(x, y)
|
||||||
ctx.show_text("Hero web page for detailed description.")
|
ctx.show_text("web page for detailed description.")
|
||||||
y += 40
|
y += 20
|
||||||
ctx.move_to(x, y)
|
ctx.move_to(x, y)
|
||||||
ctx.show_text("Additionally you should contact your local")
|
ctx.show_text("Additionally you should contact your local")
|
||||||
y += 20
|
y += 20
|
||||||
|
@ -198,19 +221,61 @@ class RaceTracker(Page):
|
||||||
|
|
||||||
def draw_local(self, ctx):
|
def draw_local(self, ctx):
|
||||||
x = 8
|
x = 8
|
||||||
|
x1 = 130
|
||||||
y = 50
|
y = 50
|
||||||
ctx.select_font_face("Ubuntu", cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD)
|
ctx.select_font_face("Ubuntu", cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD)
|
||||||
ctx.set_font_size(24)
|
ctx.set_font_size(24)
|
||||||
ctx.move_to(x, y)
|
ctx.move_to(x, y)
|
||||||
ctx.show_text("Local Tracking")
|
ctx.show_text("Local Tracking")
|
||||||
|
|
||||||
|
ctx.select_font_face("Ubuntu", cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD)
|
||||||
|
ctx.set_font_size(16)
|
||||||
|
|
||||||
|
y += 30
|
||||||
|
ctx.move_to(x, y)
|
||||||
|
ctx.show_text("Activated: ")
|
||||||
|
ctx.show_text("Yes" if self.app.track.is_active() else "No")
|
||||||
|
y += 20
|
||||||
|
ctx.move_to(x, y)
|
||||||
|
ctx.show_text(f"Log interval: {self.app.track.local_dt} seconds")
|
||||||
|
#ctx.show_text(str(self.app.track.local_dt))
|
||||||
|
y += 20
|
||||||
|
ctx.move_to(x, y)
|
||||||
|
ctx.show_text("Log entries written: ")
|
||||||
|
ctx.show_text(str(self.app.track.local_lfdno))
|
||||||
|
|
||||||
# Anzeige
|
# Anzeige
|
||||||
# - LAT, LON
|
# - LAT, LON
|
||||||
# - bisher gespeicherte Anzahl Positionen
|
# - bisher gespeicherte Anzahl Positionen
|
||||||
# - Zeitabstand zwischen den einzelnen Messungen
|
# - Zeitabstand zwischen den einzelnen Messungen
|
||||||
# - Hinweis wo gespeichert wird
|
# - Hinweis wo gespeichert wird
|
||||||
|
y += 30
|
||||||
|
ctx.move_to(x, y)
|
||||||
|
ctx.show_text("Latitude: ")
|
||||||
|
ctx.move_to(x1, y)
|
||||||
|
ctx.show_text(self.bv_lat.format())
|
||||||
|
y += 20
|
||||||
|
ctx.move_to(x, y)
|
||||||
|
ctx.show_text("Longitude: ")
|
||||||
|
ctx.move_to(x1, y)
|
||||||
|
ctx.show_text(self.bv_lon.format())
|
||||||
|
y += 20
|
||||||
|
ctx.move_to(x, y)
|
||||||
|
ctx.show_text("HDOP: ")
|
||||||
|
ctx.move_to(x1, y)
|
||||||
|
ctx.show_text(self.bv_hdop.format() or '---')
|
||||||
|
y += 20
|
||||||
|
ctx.move_to(x, y)
|
||||||
|
ctx.show_text("Speed: ")
|
||||||
|
ctx.move_to(x1, y)
|
||||||
|
ctx.show_text(self.bv_sog.format())
|
||||||
|
|
||||||
def draw_normal(self, ctx):
|
def draw_hero(self, ctx):
|
||||||
|
"""
|
||||||
|
Regatta Hero Normalansicht
|
||||||
|
TODO
|
||||||
|
racephase anzeige zu Debuggingzwecken
|
||||||
|
"""
|
||||||
|
|
||||||
ctx.select_font_face("DSEG7 Classic")
|
ctx.select_font_face("DSEG7 Classic")
|
||||||
ctx.set_font_size(80)
|
ctx.set_font_size(80)
|
||||||
|
@ -448,10 +513,12 @@ class RaceTracker(Page):
|
||||||
|
|
||||||
def draw(self, ctx):
|
def draw(self, ctx):
|
||||||
if self.mode == 'N':
|
if self.mode == 'N':
|
||||||
if self.ttype == 'NONE':
|
if self.ttype in ('LOCAL', 'SDCARD'):
|
||||||
self.draw_none(ctx)
|
self.draw_local(ctx)
|
||||||
|
elif self.ttype == 'HERO':
|
||||||
|
self.draw_hero(ctx)
|
||||||
else:
|
else:
|
||||||
self.draw_normal(ctx)
|
self.draw_none(ctx)
|
||||||
elif self.mode == 'C':
|
elif self.mode == 'C':
|
||||||
self.draw_config(ctx)
|
self.draw_config(ctx)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
"""
|
||||||
|
Wind / Windlupe
|
||||||
|
|
||||||
|
TODO
|
||||||
|
- Windlupe:
|
||||||
|
Wenn der Wind achterlich kommt, dann andere Ansicht / Skala verwenden
|
||||||
|
|
||||||
|
"""
|
||||||
import os
|
import os
|
||||||
import cairo
|
import cairo
|
||||||
import math
|
import math
|
||||||
|
|
32
tracker.py
32
tracker.py
|
@ -48,6 +48,9 @@ class Tracker():
|
||||||
raise TypeError("Invalid tracker type: '{}'. Only supported: {}".format(cfg['tracker']['type'], ','.join(validtypes)))
|
raise TypeError("Invalid tracker type: '{}'. Only supported: {}".format(cfg['tracker']['type'], ','.join(validtypes)))
|
||||||
self.ttype = cfg['tracker']['type']
|
self.ttype = cfg['tracker']['type']
|
||||||
|
|
||||||
|
self.local_lfdno = 0
|
||||||
|
self.local_dt = cfg['tracker']['interval'] # Eintrag alle <n> Sekunden schreiben
|
||||||
|
|
||||||
self.trace = cfg['tracker']['trace'] # Debugging
|
self.trace = cfg['tracker']['trace'] # Debugging
|
||||||
self.trace_fh = None # File Handle der Tracedatei
|
self.trace_fh = None # File Handle der Tracedatei
|
||||||
|
|
||||||
|
@ -127,9 +130,11 @@ class Tracker():
|
||||||
def set_active(self, newval):
|
def set_active(self, newval):
|
||||||
self.activated = newval
|
self.activated = newval
|
||||||
|
|
||||||
def local_tracker(self, cfg, boat, appdata, boatdata):
|
def local_tracker(self, cfg, appdata, boatdata):
|
||||||
# TODO / WIP
|
|
||||||
self.log.info("Local tracker enabled")
|
self.log.info("Local tracker enabled")
|
||||||
|
if not os.path.exists(cfg['histpath']):
|
||||||
|
os.makedirs(cfg['histpath'])
|
||||||
|
self.log.info(f"History path created: '{cfg['histpath']}'")
|
||||||
|
|
||||||
# Zugriff auf Boatdata: Referenzen für leichten schnellen Zugriff
|
# Zugriff auf Boatdata: Referenzen für leichten schnellen Zugriff
|
||||||
bv_lat = boatdata.getRef("LAT")
|
bv_lat = boatdata.getRef("LAT")
|
||||||
|
@ -137,20 +142,25 @@ class Tracker():
|
||||||
bv_hdop = boatdata.getRef("HDOP")
|
bv_hdop = boatdata.getRef("HDOP")
|
||||||
bv_tspos = boatdata.getRef("TSPOS")
|
bv_tspos = boatdata.getRef("TSPOS")
|
||||||
|
|
||||||
self.local_dt = 15
|
trackerfile = os.path.join(cfg['histpath'], "localtrack.log")
|
||||||
self.local_lfdno = 0
|
|
||||||
trackerfile = "/tmp/test.log" # TODO Konfiguration lesen
|
|
||||||
fh = open(trackerfile, 'a+')
|
fh = open(trackerfile, 'a+')
|
||||||
|
n = 0
|
||||||
while not appdata.shutdown:
|
while not appdata.shutdown:
|
||||||
time.sleep(self.local_dt)
|
time.sleep(1)
|
||||||
|
if not self.activated:
|
||||||
|
continue
|
||||||
|
n += 1
|
||||||
|
if n % self.local_dt != 0:
|
||||||
|
continue
|
||||||
self.local_lfdno += 1
|
self.local_lfdno += 1
|
||||||
data = f"{},{},{},{}\n".format(
|
data = "{},{}Z,{},{},{}\n".format(
|
||||||
self.local_lfdno,
|
self.local_lfdno,
|
||||||
bv_tspos.getValueRaw(),
|
bv_tspos.getValue(),
|
||||||
bv_lat.getValueRaw(),
|
bv_lat.getValue(),
|
||||||
bv_lon.getValueRaw(),
|
bv_lon.getValue(),
|
||||||
bv_hdop.getValueRaw())
|
bv_hdop.getValue())
|
||||||
fh.write(data)
|
fh.write(data)
|
||||||
|
fh.flush()
|
||||||
fh.close()
|
fh.close()
|
||||||
|
|
||||||
def set_hero_raceid(self, newraceid):
|
def set_hero_raceid(self, newraceid):
|
||||||
|
|
Loading…
Reference in New Issue