Appdata für Header, Flaggensymbole laden

This commit is contained in:
Thomas Hooge 2025-09-15 08:30:15 +02:00
parent f3c9ced477
commit 766b191109
20 changed files with 125 additions and 50 deletions

View File

@ -2,13 +2,48 @@
Generische Applikationsdaten Generische Applikationsdaten
""" """
import os
from tracker import Tracker from tracker import Tracker
class AppData(): class AppData():
def __init__(self): def __init__(self):
self.shutdown = False # Globaler Ausschalter self.shutdown = False # Globaler Ausschalter
self.track = Tracker('NONE') self.track = Tracker('NONE')
self.frontend = None self.frontend = None
# Für u.a. Header-Indikatoren
# TODO
self.status = {
'AP': False, # Accesspoint
'WIFI': False, # Wireless Client
'TCP': False, # TCP Network
'N2K': False, # NMEA2000
'183': False, # NMEA0183
'USB': False, # USB Datenverbindung
'GPS': False, # GPS-Fix und -daten
'TRK': False # Tracker
}
def setFrontend(self, frontend): def setFrontend(self, frontend):
self.frontend = frontend # Referenz zur GUI self.frontend = frontend # Referenz zur GUI
def refreshStatus(self):
self.status['AP'] = False
self.status['TCP'] = False
self.status['WIFI'] = False
for intf in os.listdir('/sys/class/net'):
statefile = os.path.join('/sys/class/net', interface, 'operstate')
wififile = os.path.join('/sys/class/net', interface, 'wireless')
if os.path.exists(statefile):
with open(statefile) as fh:
state = f.read().strip()
if state == 'up':
if os.path.exists(wififile):
self.status['WIFI'] = True
else:
self.status['TCP'] = True
self.status['TRK'] = self.track.is_active()

View File

@ -235,6 +235,7 @@ def rxd_gps(devname, devspeed):
def rxd_network(address, port): def rxd_network(address, port):
# WIP Daten über Netzwerk empfangen # WIP Daten über Netzwerk empfangen
# Wir verwenden UDP. Ein verlorenes Paket tut uns nicht weh. # Wir verwenden UDP. Ein verlorenes Paket tut uns nicht weh.
setthreadtitle("NETlistener")
sock = socket.socket() sock = socket.socket()
sock.connect((address, port)) sock.connect((address, port))
while not appdata.shutdown: while not appdata.shutdown:
@ -610,7 +611,7 @@ def init_profile(config, cfg, boatdata):
if n >= pages_max: if n >= pages_max:
break break
clist = { clist = {
0: pages.System(0, cfg, boatdata) 0: pages.System(0, cfg, appdata, boatdata)
} }
for i, p in pagedef.items(): for i, p in pagedef.items():
try: try:

View File

@ -37,7 +37,7 @@ from .page import Page
class Anchor(Page): class Anchor(Page):
def __init__(self, pageno, cfg, appdata, boatdata): def __init__(self, pageno, cfg, appdata, boatdata):
super().__init__(pageno, cfg, boatdata) super().__init__(pageno, cfg, appdata, boatdata)
self.sym_anchor = cairo.ImageSurface.create_from_png(os.path.join(cfg['imgpath'], "anchor.png")) self.sym_anchor = cairo.ImageSurface.create_from_png(os.path.join(cfg['imgpath'], "anchor.png"))
self.buttonlabel[1] = 'MODE' self.buttonlabel[1] = 'MODE'
self.buttonlabel[2] = 'DROP' self.buttonlabel[2] = 'DROP'

View File

@ -6,7 +6,7 @@ from .page import Page
class ApparentWind(Page): class ApparentWind(Page):
def __init__(self, pageno, cfg, appdata, boatdata): def __init__(self, pageno, cfg, appdata, boatdata):
super().__init__(pageno, cfg, boatdata) super().__init__(pageno, cfg, appdata, boatdata)
self.buttonlabel[1] = 'MODE' self.buttonlabel[1] = 'MODE'
self.mode = 'L' # (W)ind (L)ens self.mode = 'L' # (W)ind (L)ens
try: try:

View File

@ -12,7 +12,7 @@ from .page import Page
class Autobahn(Page): class Autobahn(Page):
def __init__(self, pageno, cfg, appdata, boatdata): def __init__(self, pageno, cfg, appdata, boatdata):
super().__init__(pageno, cfg, boatdata) super().__init__(pageno, cfg, appdata, boatdata)
self.xte = self.bd.getRef("XTE") self.xte = self.bd.getRef("XTE")
self.cog = self.bd.getRef("COG") self.cog = self.bd.getRef("COG")
self.btw = self.bd.getRef("BTW") self.btw = self.bd.getRef("BTW")

View File

@ -41,7 +41,7 @@ from .page import Page
class Barograph(Page): class Barograph(Page):
def __init__(self, pageno, cfg, appdata, boatdata): def __init__(self, pageno, cfg, appdata, boatdata):
super().__init__(pageno, cfg, boatdata) super().__init__(pageno, cfg, appdata, boatdata)
# 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

View File

@ -23,7 +23,7 @@ import nmea2000.lookup
class Fluid(Page): class Fluid(Page):
def __init__(self, pageno, cfg, appdata, boatdata, fluidtype): def __init__(self, pageno, cfg, appdata, boatdata, fluidtype):
super().__init__(pageno, cfg, boatdata) super().__init__(pageno, cfg, appdata, boatdata)
self.fluidtype = int(fluidtype) self.fluidtype = int(fluidtype)
if self.fluidtype == 0: if self.fluidtype == 0:
self.symbol = cairo.ImageSurface.create_from_png(os.path.join(cfg['imgpath'], "fuelpump.png")) self.symbol = cairo.ImageSurface.create_from_png(os.path.join(cfg['imgpath'], "fuelpump.png"))

View File

@ -21,7 +21,7 @@ from .page import Page
class FourValues(Page): class FourValues(Page):
def __init__(self, pageno, cfg, appdata, boatdata, boatvalue1, boatvalue2, boatvalue3, boatvalue4): def __init__(self, pageno, cfg, appdata, boatdata, boatvalue1, boatvalue2, boatvalue3, boatvalue4):
super().__init__(pageno, cfg, boatdata) super().__init__(pageno, cfg, appdata, boatdata)
self.value1 = boatvalue1 self.value1 = boatvalue1
self.value2 = boatvalue2 self.value2 = boatvalue2
self.value3 = boatvalue3 self.value3 = boatvalue3

View File

@ -19,7 +19,7 @@ from .page import Page
class FourValues2(Page): class FourValues2(Page):
def __init__(self, pageno, cfg, appdata, boatdata, boatvalue1, boatvalue2, boatvalue3, boatvalue4): def __init__(self, pageno, cfg, appdata, boatdata, boatvalue1, boatvalue2, boatvalue3, boatvalue4):
super().__init__(pageno, cfg, boatdata) super().__init__(pageno, cfg, appdata, boatdata)
self.value1 = boatvalue1 self.value1 = boatvalue1
self.value2 = boatvalue2 self.value2 = boatvalue2
self.value3 = boatvalue3 self.value3 = boatvalue3

View File

@ -16,7 +16,7 @@ from .page import Page
class Keel(Page): class Keel(Page):
def __init__(self, pageno, cfg, appdata, boatdata): def __init__(self, pageno, cfg, appdata, boatdata):
super().__init__(pageno, cfg, boatdata) super().__init__(pageno, cfg, appdata, boatdata)
# Wert für Kielrotation # Wert für Kielrotation
self.valref = self.bd.getRef("xdrRotK") self.valref = self.bd.getRef("xdrRotK")

View File

@ -4,7 +4,7 @@ from .page import Page
class OneValue(Page): class OneValue(Page):
def __init__(self, pageno, cfg, appdata, boatdata, boatvalue): def __init__(self, pageno, cfg, appdata, boatdata, boatvalue):
super().__init__(pageno, cfg, boatdata) super().__init__(pageno, cfg, appdata, boatdata)
self.ref1 = self.bd.getRef(boatvalue) self.ref1 = self.bd.getRef(boatvalue)
def draw(self, ctx): def draw(self, ctx):

View File

@ -64,10 +64,11 @@ class Page():
c = 2 * asin(sqrt(a)) c = 2 * asin(sqrt(a))
return c * 3440 return c * 3440
def __init__(self, pageno, cfg, boatdata): def __init__(self, pageno, cfg, appdata, boatdata):
self.pageno = pageno self.pageno = pageno
self.cfg = cfg self.cfg = cfg
self.fullscreen = cfg['guistyle'] == 'fullscreen' self.fullscreen = cfg['guistyle'] == 'fullscreen'
self.appdata = appdata
self.bd = boatdata self.bd = boatdata
self.header = True self.header = True
self.footer = True self.footer = True
@ -126,7 +127,7 @@ class Page():
def draw_header(self, ctx): def draw_header(self, ctx):
""" """
Mögliche Zeichen für aktivierte Funktionen Mögliche Zeichen für aktivierte Funktionen (max. 8)
AP - Accesspoint ist aktiv AP - Accesspoint ist aktiv
WIFI - WIFI-Client WIFI - WIFI-Client
TCP TCP
@ -134,6 +135,7 @@ class Page():
183 183
USB USB
GPS - GPS Fix vorhanden GPS - GPS Fix vorhanden
TRK - Tracking aktiv
# TODO Umstellung auf Symbole je 16 Pixel zum Platz sparen # TODO Umstellung auf Symbole je 16 Pixel zum Platz sparen
Neu: Nummer der aktiven Seite (1 - 10) Neu: Nummer der aktiven Seite (1 - 10)
""" """
@ -143,6 +145,10 @@ class Page():
ctx.show_text(f"N2K GPS") ctx.show_text(f"N2K GPS")
ctx.stroke() ctx.stroke()
# AP: Nicht implementiert
# WIFI:
# /proc/net/wireless
# Tastenstatus # Tastenstatus
ctx.save() ctx.save()
if self.keylock: if self.keylock:

View File

@ -5,7 +5,7 @@ from .page import Page
class Rudder(Page): class Rudder(Page):
def __init__(self, pageno, cfg, appdata, boatdata): def __init__(self, pageno, cfg, appdata, boatdata):
super().__init__(pageno, cfg, boatdata) super().__init__(pageno, cfg, appdata, boatdata)
self.buttonlabel[1] = 'MODE' self.buttonlabel[1] = 'MODE'
self.mode = 'P' self.mode = 'P'
# Werte für Ruderausschlag # Werte für Ruderausschlag

View File

@ -20,7 +20,7 @@ class SixValues(Page):
def __init__(self, pageno, cfg, appdata, boatdata, boatvalue1, boatvalue2, def __init__(self, pageno, cfg, appdata, boatdata, boatvalue1, boatvalue2,
boatvalue3, boatvalue4, boatvalue5, boatvalue6): boatvalue3, boatvalue4, boatvalue5, boatvalue6):
super().__init__(pageno, cfg, boatdata) super().__init__(pageno, cfg, appdata, boatdata)
self.value1 = boatvalue1 self.value1 = boatvalue1
self.value2 = boatvalue2 self.value2 = boatvalue2
self.value3 = boatvalue3 self.value3 = boatvalue3

View File

@ -15,7 +15,7 @@ from .page import Page
class SkyView(Page): class SkyView(Page):
def __init__(self, pageno, cfg, appdata, boatdata): def __init__(self, pageno, cfg, appdata, boatdata):
super().__init__(pageno, cfg, boatdata) super().__init__(pageno, cfg, appdata, boatdata)
def pol2cart(azimut, elevation): def pol2cart(azimut, elevation):
''' '''

View File

@ -4,8 +4,8 @@ import datetime
class System(Page): class System(Page):
def __init__(self, pageno, cfg, boatdata): def __init__(self, pageno, cfg, appdata, boatdata):
super().__init__(pageno, cfg, boatdata) super().__init__(pageno, cfg, appdata, boatdata)
self.buttonlabel[1] = 'MODE' self.buttonlabel[1] = 'MODE'
self.buttonlabel[2] = 'STBY' self.buttonlabel[2] = 'STBY'
self.mode = ('I', 'N') # (I)nformation (N)MEA2000 Device List self.mode = ('I', 'N') # (I)nformation (N)MEA2000 Device List

View File

@ -4,7 +4,7 @@ from .page import Page
class ThreeValues(Page): class ThreeValues(Page):
def __init__(self, pageno, cfg, appdata, boatdata, boatvalue1, boatvalue2, boatvalue3): def __init__(self, pageno, cfg, appdata, boatdata, boatvalue1, boatvalue2, boatvalue3):
super().__init__(pageno, cfg, boatdata) super().__init__(pageno, cfg, appdata, boatdata)
self.ref1 = self.bd.getRef(boatvalue1) self.ref1 = self.bd.getRef(boatvalue1)
self.ref2 = self.bd.getRef(boatvalue2) self.ref2 = self.bd.getRef(boatvalue2)
self.ref3 = self.bd.getRef(boatvalue3) self.ref3 = self.bd.getRef(boatvalue3)

View File

@ -1,22 +1,32 @@
""" """
Tracker with MQTT client Tracker mit MQTT client
Es gibt zwei Modi: Track und Race
A) Track: Es wird nur der Track gesended / aufgezeichnet
B) Race: Es werden zusätzlich Regattadaten angezeigt, das beinhaltet
die Auswahl einer Regatta, das Teilnehmen, das Aufgeben und die
Signalisierung vor und während einer Wettfahrt.
Das Tracking kann über eine Taste ein- und ausgeschaltet werden.
Um versehentliches Umschalten zu vermeiden ist eine Nachfrage
integriert.
- currentry only Ragatta hero supported - currentry only Ragatta hero supported
TODO get data from mqtt thread Behandlung von Verbindungsabbrüchen:
Verbindungsabbrüche
- on_disconnect - on_disconnect
""" """
import os
import cairo import cairo
from .page import Page from .page import Page
class Tracker(Page): class Tracker(Page):
def __init__(self, pageno, cfg, appdata, boatdata): def __init__(self, pageno, cfg, appdata, boatdata):
super().__init__(pageno, cfg, boatdata) super().__init__(pageno, cfg, appdata, boatdata)
self._appdata = appdata self._appdata = appdata
self.bv_lat = boatdata.getRef("LAT") self.bv_lat = boatdata.getRef("LAT")
self.bv_lon = boatdata.getRef("LON") self.bv_lon = boatdata.getRef("LON")
@ -25,6 +35,20 @@ class Tracker(Page):
self.buttonlabel[2] = 'ON' self.buttonlabel[2] = 'ON'
self.mode = 'N' # (N)ormal, (C)onfiguration self.mode = 'N' # (N)ormal, (C)onfiguration
# Flaggengröße: 96 x 64 Pixel
self.flagpos = ((208, 140), (308, 140), (208, 210), (308, 210))
# Flaggen laden
flag = ('alpha', 'answer', 'black', 'blue', 'charlie', 'class',
'finish', 'hotel', 'india', 'november', 'orange',
'papa', 'repeat_one', 'sierra', 'start', 'uniform',
'xray', 'yankee', 'zulu')
self.sym_flag = {}
for f in flag:
flagfile = os.path.join(cfg['imgpath'], 'flags', f + '.png')
self.sym_flag[f] = cairo.ImageSurface.create_from_png(flagfile)
print(self.sym_flag)
def handle_key(self, buttonid): def handle_key(self, buttonid):
if buttonid == 1: if buttonid == 1:
# Modus umschalten # Modus umschalten
@ -47,47 +71,57 @@ class Tracker(Page):
def draw_normal(self, ctx): def draw_normal(self, ctx):
# Name # Name
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(32) #ctx.set_font_size(32)
ctx.move_to(20, 80) #ctx.move_to(20, 80)
ctx.show_text("Tracker") #ctx.show_text("Tracker")
ctx.set_font_size(16) ctx.select_font_face("DSEG7 Classic")
ctx.set_font_size(80)
if self._appdata.track.is_active():
ctx.move_to(20, 120) ctx.move_to(20, 120)
ctx.show_text("-00:00")
else:
ctx.move_to(100, 120)
ctx.show_text("off")
x0 = 8
x1 = 104
y0 = 150
ctx.select_font_face("Ubuntu", cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD)
ctx.set_font_size(16)
ctx.move_to(x0, y0)
ctx.show_text("Type: ") ctx.show_text("Type: ")
ctx.move_to(x1, y0)
ctx.show_text(self._appdata.track.ttype) ctx.show_text(self._appdata.track.ttype)
ctx.move_to(20, 140) ctx.move_to(x0, y0 + 16)
ctx.show_text("active: ") ctx.show_text("Regatta")
if self._appdata.track.is_active(): ctx.move_to(x1, y0 + 16)
ctx.show_text("yes") ctx.show_text('')
else:
ctx.show_text("no")
ctx.move_to(20, 160) ctx.move_to(x0, y0 + 32)
ctx.show_text("Lat=") ctx.show_text("Lat=")
ctx.move_to(x1, y0 + 32)
ctx.show_text(self.bv_lat.format()) ctx.show_text(self.bv_lat.format())
ctx.move_to(20, 180)
ctx.move_to(x0, y0 + 48)
ctx.show_text("Lon=") ctx.show_text("Lon=")
ctx.move_to(x1, y0 + 48)
ctx.show_text(self.bv_lon.format()) ctx.show_text(self.bv_lon.format())
ctx.move_to(20, 200)
ctx.move_to(x0, y0 + 64)
ctx.show_text("Sog=") ctx.show_text("Sog=")
ctx.move_to(x1, y0 + 64)
ctx.show_text(self.bv_sog.format()) ctx.show_text(self.bv_sog.format())
# Ausgewählte Regatta (raceid)
x = 250
y = 100
ctx.move_to(x, y - 24)
ctx.show_text("Regatta: ")
# if ...
# else
# "not selected"
def draw_config(self, ctx): def draw_config(self, ctx):
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(32) ctx.set_font_size(32)
ctx.move_to(20, 80) ctx.move_to(20, 80)
ctx.show_text("Tracker config") ctx.show_text("Tracker configuration")
# Daten aus Konfiguration anzeigen # Daten aus Konfiguration anzeigen
# - boot # - boot
# - tracker # - tracker
@ -109,7 +143,6 @@ class Tracker(Page):
ctx.show_text("keine") ctx.show_text("keine")
ctx.move_to(20, 120) ctx.move_to(20, 120)
ctx.show_text("Type: ") ctx.show_text("Type: ")
ctx.show_text(self._appdata.track.ttype) ctx.show_text(self._appdata.track.ttype)

View File

@ -17,7 +17,7 @@ from .page import Page
class TwoValues(Page): class TwoValues(Page):
def __init__(self, pageno, cfg, appdata, boatdata, boatvalue1, boatvalue2): def __init__(self, pageno, cfg, appdata, boatdata, boatvalue1, boatvalue2):
super().__init__(pageno, cfg, boatdata) super().__init__(pageno, cfg, appdata, boatdata)
self.ref1 = self.bd.getRef(boatvalue1) self.ref1 = self.bd.getRef(boatvalue1)
self.ref2 = self.bd.getRef(boatvalue2) self.ref2 = self.bd.getRef(boatvalue2)
#print(self.ref1.valname) #print(self.ref1.valname)

View File

@ -18,7 +18,7 @@ class Voltage(Page):
avg = (1, 10, 60, 300); avg = (1, 10, 60, 300);
def __init__(self, pageno, cfg, appdata, boatdata): def __init__(self, pageno, cfg, appdata, boatdata):
super().__init__(pageno, cfg, boatdata) super().__init__(pageno, cfg, appdata, boatdata)
self.trend = True self.trend = True
self.mode = 'A' self.mode = 'A'
self.avgindex = 0 self.avgindex = 0