NMEA0183 Empfangscode in entsprechendes Modul verlagert
This commit is contained in:
parent
612783454e
commit
5b000f4f1f
4
TODO
4
TODO
|
@ -1,8 +1,10 @@
|
||||||
Aufgaben, Planungs- und Ideenliste
|
Aufgaben, Planungs- und Ideenliste
|
||||||
|
|
||||||
- Tracker
|
- Tracker
|
||||||
Regatta Hero
|
a) Regatta Hero
|
||||||
python3-paho-mqtt benötigt
|
python3-paho-mqtt benötigt
|
||||||
|
b) lokal
|
||||||
|
c) Server
|
||||||
|
|
||||||
- Satelliten: SatelliteList verwenden und dieses auch in
|
- Satelliten: SatelliteList verwenden und dieses auch in
|
||||||
nmea2000 implementieren
|
nmea2000 implementieren
|
||||||
|
|
44
nmea0183.py
44
nmea0183.py
|
@ -7,6 +7,50 @@ TODO Multi-Sentence verarbeiten
|
||||||
AIS-Sentences mit Binärdaten
|
AIS-Sentences mit Binärdaten
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import serial
|
||||||
|
from setproctitle import setthreadtitle
|
||||||
|
|
||||||
|
# Empfangsthread
|
||||||
|
def rxd_0183(appdata, devname):
|
||||||
|
# Prüfe ob NMEA0183-Port vorhanden ist und sich öffnen läßt
|
||||||
|
try:
|
||||||
|
ser = serial.Serial(devname, 115200, timeout=3)
|
||||||
|
except serial.SerialException as e:
|
||||||
|
print("NMEA0183 serial port not available")
|
||||||
|
return
|
||||||
|
setthreadtitle("0183listener")
|
||||||
|
while not appdata.shutdown:
|
||||||
|
raw = ser.readline().decode('ascii')
|
||||||
|
if len(raw.strip()) == 0:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
msg = pynmea2.parse(raw)
|
||||||
|
except pynmea2.nmea.ParseError:
|
||||||
|
print(f"NMEA0183: Parse-Error: {raw}", end='')
|
||||||
|
continue
|
||||||
|
# sentence_type kann fehlen
|
||||||
|
try:
|
||||||
|
stype = msg.sentence_type
|
||||||
|
except:
|
||||||
|
print(f"NMEA0183: Sentence type missing: {raw}")
|
||||||
|
continue
|
||||||
|
# WIP Neuer Code aus Modul
|
||||||
|
# TODO Filter mit gewünschen Satztypen
|
||||||
|
# if stype in stypefilter:
|
||||||
|
# continue
|
||||||
|
if stype in decoder:
|
||||||
|
decoder[stype](boatdata, msg)
|
||||||
|
else:
|
||||||
|
# Hier unbekannter Satztyp: protokollieren und ignorieren
|
||||||
|
"""
|
||||||
|
['checksum', 'data', 'fields', 'identifier', 'name_to_idx', 'parse',
|
||||||
|
'proprietary_re', 'query_re', 'render', 'sentence_re',
|
||||||
|
'sentence_type', 'sentence_types', 'talker', 'talker_re']
|
||||||
|
"""
|
||||||
|
print(f"Nicht implementiert: '{stype}' from {msg.talker}")
|
||||||
|
|
||||||
|
ser.close()
|
||||||
|
|
||||||
def DBS(boatdata, msg):
|
def DBS(boatdata, msg):
|
||||||
# Wassertiefe unter der Oberfläche
|
# Wassertiefe unter der Oberfläche
|
||||||
pass
|
pass
|
||||||
|
|
45
obp60v.py
45
obp60v.py
|
@ -108,8 +108,8 @@ import struct
|
||||||
import uuid
|
import uuid
|
||||||
import json
|
import json
|
||||||
|
|
||||||
import nmea0183
|
|
||||||
from appdata import AppData
|
from appdata import AppData
|
||||||
|
import nmea0183
|
||||||
import pages
|
import pages
|
||||||
|
|
||||||
__author__ = "Thomas Hooge"
|
__author__ = "Thomas Hooge"
|
||||||
|
@ -118,6 +118,7 @@ __version__ = "0.2"
|
||||||
__email__ = "thomas@hoogi.de"
|
__email__ = "thomas@hoogi.de"
|
||||||
__status__ = "Development"
|
__status__ = "Development"
|
||||||
|
|
||||||
|
# Standardkonfiguration, kann durch Konfigdatei überschrieben werden
|
||||||
cfg = {
|
cfg = {
|
||||||
'cfgfile': 'obp60v.conf',
|
'cfgfile': 'obp60v.conf',
|
||||||
'logdir': '~/.local/share/obp60v',
|
'logdir': '~/.local/share/obp60v',
|
||||||
|
@ -205,46 +206,6 @@ def rxd_n2k(device):
|
||||||
pass
|
pass
|
||||||
bus.shutdown()
|
bus.shutdown()
|
||||||
|
|
||||||
def rxd_0183(devname):
|
|
||||||
# Prüfe ob NMEA0183-Port vorhanden ist und sich öffnen läßt
|
|
||||||
try:
|
|
||||||
ser = serial.Serial(devname, 115200, timeout=3)
|
|
||||||
except serial.SerialException as e:
|
|
||||||
print("NMEA0183 serial port not available")
|
|
||||||
return
|
|
||||||
setthreadtitle("0183listener")
|
|
||||||
while not appdata.shutdown:
|
|
||||||
raw = ser.readline().decode('ascii')
|
|
||||||
if len(raw.strip()) == 0:
|
|
||||||
continue
|
|
||||||
try:
|
|
||||||
msg = pynmea2.parse(raw)
|
|
||||||
except pynmea2.nmea.ParseError:
|
|
||||||
print(f"NMEA0183: Parse-Error: {raw}", end='')
|
|
||||||
continue
|
|
||||||
# sentence_type kann fehlen
|
|
||||||
try:
|
|
||||||
stype = msg.sentence_type
|
|
||||||
except:
|
|
||||||
print(f"NMEA0183: Sentence type missing: {raw}")
|
|
||||||
continue
|
|
||||||
# WIP Neuer Code aus Modul
|
|
||||||
# TODO Filter mit gewünschen Satztypen
|
|
||||||
# if stype in stypefilter:
|
|
||||||
# continue
|
|
||||||
if stype in nmea0183.decoder:
|
|
||||||
nmea0183.decoder[stype](boatdata, msg)
|
|
||||||
else:
|
|
||||||
# Hier unbekannter Satztyp: protokollieren und ignorieren
|
|
||||||
"""
|
|
||||||
['checksum', 'data', 'fields', 'identifier', 'name_to_idx', 'parse',
|
|
||||||
'proprietary_re', 'query_re', 'render', 'sentence_re',
|
|
||||||
'sentence_type', 'sentence_types', 'talker', 'talker_re']
|
|
||||||
"""
|
|
||||||
print(f"Nicht implementiert: '{stype}' from {msg.talker}")
|
|
||||||
|
|
||||||
ser.close()
|
|
||||||
|
|
||||||
def rxd_gps(devname, devspeed):
|
def rxd_gps(devname, devspeed):
|
||||||
# Prüfe ob GPS-Port vorhanden ist und sich öffnen läßt
|
# Prüfe ob GPS-Port vorhanden ist und sich öffnen läßt
|
||||||
try:
|
try:
|
||||||
|
@ -789,7 +750,7 @@ if __name__ == "__main__":
|
||||||
t_rxd_n2k.start()
|
t_rxd_n2k.start()
|
||||||
if cfg['nmea0183']:
|
if cfg['nmea0183']:
|
||||||
print("NMEA0183 enabled, library version {}".format(pynmea2.version))
|
print("NMEA0183 enabled, library version {}".format(pynmea2.version))
|
||||||
t_rxd_0183 = threading.Thread(target=rxd_0183, args=(cfg['0183_port'],))
|
t_rxd_0183 = threading.Thread(target=nmea0183.rxd_0183, args=(appdata,cfg['0183_port'],))
|
||||||
t_rxd_0183.start()
|
t_rxd_0183.start()
|
||||||
if cfg['gps']:
|
if cfg['gps']:
|
||||||
print("GPS enabled (local)")
|
print("GPS enabled (local)")
|
||||||
|
|
|
@ -23,11 +23,15 @@ class Tracker(Page):
|
||||||
self.bv_sog = boatdata.getRef("SOG")
|
self.bv_sog = boatdata.getRef("SOG")
|
||||||
self.buttonlabel[1] = 'MODE'
|
self.buttonlabel[1] = 'MODE'
|
||||||
self.buttonlabel[2] = 'ON'
|
self.buttonlabel[2] = 'ON'
|
||||||
|
self.mode = 'N' # (N)ormal, (C)onfiguration
|
||||||
|
|
||||||
def handle_key(self, buttonid):
|
def handle_key(self, buttonid):
|
||||||
if buttonid == 1:
|
if buttonid == 1:
|
||||||
|
# Modus umschalten
|
||||||
pass
|
if self.mode == 'N':
|
||||||
|
self.mode = 'C'
|
||||||
|
else:
|
||||||
|
self.mode = 'N'
|
||||||
elif buttonid == 2:
|
elif buttonid == 2:
|
||||||
# Tracking ein/-ausschalten
|
# Tracking ein/-ausschalten
|
||||||
if self._appdata.track.is_active():
|
if self._appdata.track.is_active():
|
||||||
|
@ -37,7 +41,7 @@ class Tracker(Page):
|
||||||
self._appdata.track.set_active(True)
|
self._appdata.track.set_active(True)
|
||||||
self.buttonlabel[2] = 'OFF'
|
self.buttonlabel[2] = 'OFF'
|
||||||
|
|
||||||
def draw(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)
|
||||||
|
@ -66,11 +70,32 @@ class Tracker(Page):
|
||||||
ctx.show_text("Sog=")
|
ctx.show_text("Sog=")
|
||||||
ctx.show_text(self.bv_sog.format())
|
ctx.show_text(self.bv_sog.format())
|
||||||
|
|
||||||
# Mögliche Regatten
|
# Ausgewählte Regatta (raceid)
|
||||||
x = 250
|
x = 250
|
||||||
y = 160
|
y = 100
|
||||||
ctx.move_to(x, y - 24)
|
ctx.move_to(x, y - 24)
|
||||||
ctx.show_text("Regatten")
|
ctx.show_text("Regatta: ")
|
||||||
|
# if ...
|
||||||
|
# else
|
||||||
|
# "not selected"
|
||||||
|
|
||||||
|
def draw_config(self, ctx):
|
||||||
|
ctx.select_font_face("Ubuntu", cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD)
|
||||||
|
ctx.set_font_size(32)
|
||||||
|
ctx.move_to(20, 80)
|
||||||
|
ctx.show_text("Tracker config")
|
||||||
|
# Daten aus Konfiguration anzeigen
|
||||||
|
# - boot
|
||||||
|
# - tracker
|
||||||
|
|
||||||
|
ctx.set_font_size(16)
|
||||||
|
|
||||||
|
# Mögliche Regatten
|
||||||
|
# -> auf Konfigurationsmodus verschieben
|
||||||
|
x = 250
|
||||||
|
y = 100
|
||||||
|
ctx.move_to(x, y - 24)
|
||||||
|
ctx.show_text("Regattas")
|
||||||
for r in self._appdata.track.hero_get_races():
|
for r in self._appdata.track.hero_get_races():
|
||||||
ctx.move_to(x, y)
|
ctx.move_to(x, y)
|
||||||
ctx.show_text(r)
|
ctx.show_text(r)
|
||||||
|
@ -79,3 +104,14 @@ class Tracker(Page):
|
||||||
ctx.move_to(x, y)
|
ctx.move_to(x, y)
|
||||||
ctx.show_text("keine")
|
ctx.show_text("keine")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ctx.move_to(20, 120)
|
||||||
|
ctx.show_text("Type: ")
|
||||||
|
ctx.show_text(self._appdata.track.ttype)
|
||||||
|
|
||||||
|
def draw(self, ctx):
|
||||||
|
if self.mode == 'N':
|
||||||
|
self.draw_normal(ctx)
|
||||||
|
else:
|
||||||
|
self.draw_config(ctx)
|
||||||
|
|
12
tracker.py
12
tracker.py
|
@ -4,7 +4,8 @@ Tracker-Daten
|
||||||
Mögliche Typen:
|
Mögliche Typen:
|
||||||
HERO - Regatta Hero
|
HERO - Regatta Hero
|
||||||
SDCARD
|
SDCARD
|
||||||
SERVER
|
LOCAL
|
||||||
|
SERVER - spezielle Software benötigt, kann auch ein Raspi an Bord sein
|
||||||
NONE - kein Tracking
|
NONE - kein Tracking
|
||||||
|
|
||||||
Wenn die Verbindung zum Server im Internet nicht funktioniert, werden
|
Wenn die Verbindung zum Server im Internet nicht funktioniert, werden
|
||||||
|
@ -45,6 +46,15 @@ class Tracker():
|
||||||
self.hero_orgstatus = None
|
self.hero_orgstatus = None
|
||||||
self.hero_racestatus = None # Akluelle Regatta
|
self.hero_racestatus = None # Akluelle Regatta
|
||||||
|
|
||||||
|
# TODO Wirklich alles im Tracker oder ist einiges generisch?
|
||||||
|
self.boatid = None
|
||||||
|
self.sailno = None
|
||||||
|
self.boatname = None
|
||||||
|
self.boatclass = None
|
||||||
|
self.handicap = None
|
||||||
|
self.club = None
|
||||||
|
self.team = None
|
||||||
|
|
||||||
def is_server_active(self, hostname, port):
|
def is_server_active(self, hostname, port):
|
||||||
"""
|
"""
|
||||||
ohne Netzwerkverbindung wirft socket.gethostbyname eine Exception,
|
ohne Netzwerkverbindung wirft socket.gethostbyname eine Exception,
|
||||||
|
|
Loading…
Reference in New Issue