Ankerseite und mehr NMEA0183 code
This commit is contained in:
parent
5d8b33b086
commit
664d6c7d49
5
README
5
README
|
@ -31,9 +31,12 @@ Abhängigkeiten
|
||||||
- python3-heapdict
|
- python3-heapdict
|
||||||
- python3-setproctitle
|
- python3-setproctitle
|
||||||
|
|
||||||
Für GPS
|
Für GPS und/oder NMEA0183
|
||||||
- python3-serial
|
- python3-serial
|
||||||
- python3-nmea2
|
- python3-nmea2
|
||||||
|
Achtung: in Debian ist Version 1.15, die aktuelle Version 1.19 hat
|
||||||
|
weitere Satzarten implementiert. Allerdings ist dort auch kein AIS
|
||||||
|
vorhanden.
|
||||||
|
|
||||||
Für BME280
|
Für BME280
|
||||||
- python3-smbus2
|
- python3-smbus2
|
||||||
|
|
69
nmea0183.py
69
nmea0183.py
|
@ -13,6 +13,13 @@ def DBT(boatdata, msg):
|
||||||
pass
|
pass
|
||||||
#boatdata.setValue("DBT", msg.depth)
|
#boatdata.setValue("DBT", msg.depth)
|
||||||
|
|
||||||
|
def DPT(boatdata, msg):
|
||||||
|
# Depth
|
||||||
|
print("-> DPT")
|
||||||
|
print(msg.fields)
|
||||||
|
print(msg.data)
|
||||||
|
#boatdata.setValue("DBT", msg.depth)
|
||||||
|
|
||||||
def GBS(boatdata, msg):
|
def GBS(boatdata, msg):
|
||||||
# GNSS satellite fault detection
|
# GNSS satellite fault detection
|
||||||
"""
|
"""
|
||||||
|
@ -42,9 +49,20 @@ def GGA(boatdata, msg):
|
||||||
boatdata.setValue("HDOP", msg.horizontal_dil)
|
boatdata.setValue("HDOP", msg.horizontal_dil)
|
||||||
|
|
||||||
def GLL(boatdata, msg):
|
def GLL(boatdata, msg):
|
||||||
print("-> GLL")
|
# Position data: position fix, time of position fix, and status
|
||||||
boatdata.setValue("LAT", msg.latitude)
|
# UTC of position ignored
|
||||||
boatdata.setValue("LON", msg.longitude)
|
print(msg.data)
|
||||||
|
if not msg.status == 'A':
|
||||||
|
return
|
||||||
|
lat_fac = 1 if msg.lat_dir == 'N' else -1
|
||||||
|
lat_deg = int(msg.lat[0:2])
|
||||||
|
lat_min = float(msg.lat[2:])
|
||||||
|
print(lat_deg, lat_min)
|
||||||
|
boatdata.setValue("LAT", lat_fac * lat_deg + lat_min / 60)
|
||||||
|
lon_fac = 1 if msg.lon_dir == 'E' else -1
|
||||||
|
lon_deg = int(msg.lon[0:3])
|
||||||
|
lon_min = float(msg.lon[3:])
|
||||||
|
boatdata.setValue("LON", lon_fac * lon_deg + lon_min / 60)
|
||||||
|
|
||||||
def GSA(boatdata, msg):
|
def GSA(boatdata, msg):
|
||||||
# Satellites
|
# Satellites
|
||||||
|
@ -113,8 +131,10 @@ def HDM(boatdata, msg):
|
||||||
|
|
||||||
def HDT(boatdata, msg):
|
def HDT(boatdata, msg):
|
||||||
# Heading True
|
# Heading True
|
||||||
print("-> HDT")
|
if msg.hdg_true == 'T':
|
||||||
print(msg.fields)
|
boatdata.setValue("HDT", msg.heading)
|
||||||
|
else:
|
||||||
|
print("HDT: T not set!")
|
||||||
|
|
||||||
def HTD(boatdata, msg):
|
def HTD(boatdata, msg):
|
||||||
# Heading/Track control data
|
# Heading/Track control data
|
||||||
|
@ -141,20 +161,25 @@ def RMB(boatdata, msg):
|
||||||
|
|
||||||
def RMC(boatdata, msg):
|
def RMC(boatdata, msg):
|
||||||
# Recommended Minimum Navigation Information
|
# Recommended Minimum Navigation Information
|
||||||
# print("-> RMC")
|
#print("-> RMC")
|
||||||
# print(msg.timestamp, msg.datestamp)
|
# print(msg.timestamp, msg.datestamp)
|
||||||
# print(msg.status) # V=Warning, P=Precise, A=?
|
# print(msg.status) # V=Warning, P=Precise, A=OK
|
||||||
# mag_variation, mag_var_dir E/W
|
# mag_variation, mag_var_dir E/W
|
||||||
# true_course
|
# TODO nav_status welche Bedeutung?
|
||||||
if msg.lat_dir == 'N':
|
if not msg.status == 'A':
|
||||||
boatdata.setValue("LAT", msg.lat)
|
return
|
||||||
else:
|
lat_fac = 1 if msg.lat_dir == 'N' else -1
|
||||||
boatdata.setValue("LAT", msg.lat) * -1
|
lat_deg = int(msg.lat[0:2])
|
||||||
if msg.lon_dir == 'E':
|
lat_min = float(msg.lat[2:])
|
||||||
boatdata.setValue("LON", msg.lon)
|
boatdata.setValue("LAT", lat_fac * lat_deg + lat_min / 60)
|
||||||
else:
|
lon_fac = 1 if msg.lon_dir == 'E' else -1
|
||||||
boatdata.setValue("LON", msg.lon) * -1
|
lon_deg = int(msg.lon[0:3])
|
||||||
boatdata.setValue("SOG", msg.spd_over_grnd)
|
lon_min = float(msg.lon[3:])
|
||||||
|
boatdata.setValue("LON", lon_fac * lon_deg + lon_min / 60)
|
||||||
|
if msg.spd_over_grnd:
|
||||||
|
boatdata.setValue("SOG", float(msg.spd_over_grnd))
|
||||||
|
if msg.true_course:
|
||||||
|
boatdata.setValue("COG", float(msg.true_course))
|
||||||
|
|
||||||
def ROT(boatdata, msg):
|
def ROT(boatdata, msg):
|
||||||
# Rate Of Turn
|
# Rate Of Turn
|
||||||
|
@ -242,7 +267,13 @@ def XDR(boatdata, msg):
|
||||||
# units: D
|
# units: D
|
||||||
# id: Yaw
|
# id: Yaw
|
||||||
if msg.id.lower() == 'yaw':
|
if msg.id.lower() == 'yaw':
|
||||||
boatdata.setValue("YAW", msg.value)
|
boatdata.setValue("YAW", float(msg.value))
|
||||||
|
elif msg.id.lower() == 'ptch':
|
||||||
|
boatdata.setValue("PTCH", float(msg.value))
|
||||||
|
elif msg.id.lower() == 'roll':
|
||||||
|
boatdata.setValue("ROLL", float(msg.value))
|
||||||
|
elif msg.id.lower() == 'barometer':
|
||||||
|
boatdata.setValue("xdrPress", float(msg.value))
|
||||||
else:
|
else:
|
||||||
print(f"-> XDR: {msg.type}, {msg.value}, {msg.units}, {msg.id}")
|
print(f"-> XDR: {msg.type}, {msg.value}, {msg.units}, {msg.id}")
|
||||||
|
|
||||||
|
@ -275,6 +306,7 @@ def VDO(boatdata, msg):
|
||||||
decoder = {
|
decoder = {
|
||||||
"DBS": DBS,
|
"DBS": DBS,
|
||||||
"DBT": DBT,
|
"DBT": DBT,
|
||||||
|
"DPT": DPT,
|
||||||
"GBS": GBS,
|
"GBS": GBS,
|
||||||
"GGA": GGA,
|
"GGA": GGA,
|
||||||
"GLL": GLL,
|
"GLL": GLL,
|
||||||
|
@ -282,6 +314,7 @@ decoder = {
|
||||||
"GSV": GSV,
|
"GSV": GSV,
|
||||||
"HDG": HDG,
|
"HDG": HDG,
|
||||||
"HDM": HDM,
|
"HDM": HDM,
|
||||||
|
"HDT": HDT,
|
||||||
"HTD": HTD,
|
"HTD": HTD,
|
||||||
"MWV": MWV,
|
"MWV": MWV,
|
||||||
"MTW": MTW,
|
"MTW": MTW,
|
||||||
|
|
|
@ -14,6 +14,7 @@ Daten
|
||||||
- Alarm aktiv J/N
|
- Alarm aktiv J/N
|
||||||
- Alarmradius
|
- Alarmradius
|
||||||
- GPS Abweichung/ Fehler in der Horizontalen
|
- GPS Abweichung/ Fehler in der Horizontalen
|
||||||
|
- Zeitpunkt des Ankeraus
|
||||||
|
|
||||||
Darstellung:
|
Darstellung:
|
||||||
- Modi:
|
- Modi:
|
||||||
|
@ -29,6 +30,7 @@ Es gibt verschiedene Unterseiten
|
||||||
import os
|
import os
|
||||||
import cairo
|
import cairo
|
||||||
import math
|
import math
|
||||||
|
import time
|
||||||
from .page import Page
|
from .page import Page
|
||||||
|
|
||||||
class Anchor(Page):
|
class Anchor(Page):
|
||||||
|
@ -41,6 +43,7 @@ class Anchor(Page):
|
||||||
self.buttonlabel[5] = '' # ALARM erst möglich wenn der Anker unten ist
|
self.buttonlabel[5] = '' # ALARM erst möglich wenn der Anker unten ist
|
||||||
|
|
||||||
self.mode = 'N' # (N)ormal, (C)onfiguration
|
self.mode = 'N' # (N)ormal, (C)onfiguration
|
||||||
|
self.scale = 50 # Radius of display circle in meter
|
||||||
|
|
||||||
self._bd = boatdata
|
self._bd = boatdata
|
||||||
|
|
||||||
|
@ -54,6 +57,7 @@ class Anchor(Page):
|
||||||
self.anchor_lat = 0
|
self.anchor_lat = 0
|
||||||
self.anchor_lon = 0
|
self.anchor_lon = 0
|
||||||
self.anchor_depth = -1
|
self.anchor_depth = -1
|
||||||
|
self.anchor_ts = None # Timestamp of dropped anchor
|
||||||
self.lat = 0
|
self.lat = 0
|
||||||
self.lon = 0
|
self.lon = 0
|
||||||
self.heading = -1
|
self.heading = -1
|
||||||
|
@ -75,13 +79,15 @@ class Anchor(Page):
|
||||||
self.anchor_lat = self._bd.lat
|
self.anchor_lat = self._bd.lat
|
||||||
self.anchor_lon = self._bd.lon
|
self.anchor_lon = self._bd.lon
|
||||||
self.anchor_set = True
|
self.anchor_set = True
|
||||||
|
self.anchor_ts = time.time()
|
||||||
self.buttonlabel[2] = 'RISE'
|
self.buttonlabel[2] = 'RISE'
|
||||||
self.buttonlabel[5] = 'ALARM'
|
self.buttonlabel[5] = 'ALARM'
|
||||||
else:
|
else:
|
||||||
self.anchor_set = False
|
self.anchor_set = False
|
||||||
self.alarm = False
|
self.alarm = False
|
||||||
self.alarm_enabled = False
|
self.alarm_enabled = False
|
||||||
self.buttonlabel[2] = 'SET'
|
self.anchor_ts = None
|
||||||
|
self.buttonlabel[2] = 'DROP'
|
||||||
self.buttonlabel[5] = ''
|
self.buttonlabel[5] = ''
|
||||||
if buttonid == 5:
|
if buttonid == 5:
|
||||||
# Bei aktivem Alarm kann mit dieser Taste der Alarm zurückgesetzt
|
# Bei aktivem Alarm kann mit dieser Taste der Alarm zurückgesetzt
|
||||||
|
@ -142,27 +148,57 @@ class Anchor(Page):
|
||||||
cy = 150
|
cy = 150
|
||||||
r = 125
|
r = 125
|
||||||
|
|
||||||
ctx.set_line_width(1.5)
|
# Skala
|
||||||
|
ctx.set_line_width(1)
|
||||||
ctx.arc(cx, cy, r, 0, 2*math.pi)
|
ctx.arc(cx, cy, r, 0, 2*math.pi)
|
||||||
|
ctx.move_to(cx + 10, cy + 0.5)
|
||||||
|
ctx.line_to(cx + r - 4, cy + 0.5)
|
||||||
|
ctx.move_to(cx + r / 2, cy + 20)
|
||||||
|
# Pfeil links
|
||||||
|
ctx.move_to(cx + 10, cy + 0.5)
|
||||||
|
ctx.line_to(cx + 16, cy - 4 + 0.5)
|
||||||
|
ctx.move_to(cx + 10, cy + 0.5)
|
||||||
|
ctx.line_to(cx + 16, cy + 4 + 0.5)
|
||||||
|
# Pfeil rechts
|
||||||
|
ctx.move_to(cx + r - 4, cy + 0.5)
|
||||||
|
ctx.line_to(cx + r - 10, cy - 4 + 0.5)
|
||||||
|
ctx.move_to(cx + r - 4, cy + 0.5)
|
||||||
|
ctx.line_to(cx + r - 10, cy + 4 + 0.5)
|
||||||
|
|
||||||
|
ctx.set_font_size(16)
|
||||||
|
self.draw_text_center(ctx, cx + r / 2, cy + 8, str(self.scale) + " m")
|
||||||
ctx.stroke()
|
ctx.stroke()
|
||||||
|
|
||||||
# Ankersymbol falls Anker fallen gelassen wurde, ansonsten nur Kreis-
|
ctx.set_line_width(1.5)
|
||||||
# mittelpunkt kennzeichnen
|
# Ankersymbol falls Anker fallen gelassen wurde
|
||||||
|
# Ansonsten ist das Boot-Symbol im Mittelpunkt
|
||||||
if self.anchor_set:
|
if self.anchor_set:
|
||||||
ctx.save()
|
ctx.save()
|
||||||
ctx.set_source_surface(self.sym_anchor, cx-8, cy-8)
|
ctx.set_source_surface(self.sym_anchor, cx-8, cy-8)
|
||||||
ctx.paint()
|
ctx.paint()
|
||||||
ctx.restore()
|
ctx.restore()
|
||||||
else:
|
|
||||||
ctx.move_to(cx-6, cy-6)
|
|
||||||
ctx.line_to(cx+6, cy+6)
|
|
||||||
ctx.move_to(cx+6, cy-6)
|
|
||||||
ctx.line_to(cx-6, cy+6)
|
|
||||||
ctx.stroke()
|
|
||||||
|
|
||||||
# Boot zeichnen
|
# Boot zeichnen
|
||||||
# Heading beachten
|
# Heading beachten
|
||||||
|
# Wir arbeiten mit einer Kopie, weil bx/by im Laufe der Zeit von
|
||||||
|
# cx/cy abweichen werden
|
||||||
|
if self.anchor_set:
|
||||||
|
bx = cx
|
||||||
|
by = cy + 30
|
||||||
|
else:
|
||||||
|
bx = cx
|
||||||
|
by = cy + 8
|
||||||
|
p = ((bx - 5, by), (bx - 5, by - 10), (bx, by - 16), (bx + 5, by - 10), (bx + 5, by), (bx - 6, by))
|
||||||
|
if self._bd.hdt.value:
|
||||||
|
# Rotiere Boot-Symbol um eigenes Zentrum
|
||||||
|
boat = self.rotate((bx, by - 8), p, self._bd.hdt.value)
|
||||||
|
else:
|
||||||
|
# Kein Heading, Boot immer zeichnen
|
||||||
|
boat = p
|
||||||
|
ctx.move_to(*boat[0])
|
||||||
|
for point in boat[1:]:
|
||||||
|
ctx.line_to(*point)
|
||||||
|
ctx.stroke()
|
||||||
|
|
||||||
# Windpfeil zeichnen
|
# Windpfeil zeichnen
|
||||||
if self._bd.awa.value:
|
if self._bd.awa.value:
|
||||||
|
|
Loading…
Reference in New Issue