340 lines
10 KiB
Python
340 lines
10 KiB
Python
"""
|
|
NMEA0183 verarbeiten
|
|
|
|
"""
|
|
|
|
def DBS(boatdata, msg):
|
|
# Wassertiefe unter der Oberfläche
|
|
pass
|
|
#boatdata.setValue("DBS", msg.depth)
|
|
|
|
def DBT(boatdata, msg):
|
|
# Wassertiefe unter Geber
|
|
pass
|
|
#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):
|
|
# GNSS satellite fault detection
|
|
"""
|
|
(('Timestamp', 'timestamp', <function timestamp at 0x7f59cb0b65c0>), ('Expected error in latitude', 'lat_err'), ('Expected error in longitude', 'lon_err'), ('Expected error in altitude', 'alt_err'), ('PRN of most likely failed satellite', 'sat_prn_num_f'), ('Probability of missed detection for most likely failed satellite', 'pro_miss', <class 'decimal.Decimal'>), ('Estimate of bias in meters on most likely failed satellite', 'est_bias'), ('Standard deviation of bias estimate', 'est_bias_dev'))
|
|
['213024.00', '0.9', '0.6', '2.5', '', '', '', '']
|
|
NMEA0183: Parse-Error: !AIVDM,1,1,,A,H3ti3hPpDhiT0 """
|
|
print("-> GBS")
|
|
print(msg.fields)
|
|
print(msg.data)
|
|
#boatdata.setValue("LAT", msg.latitude)
|
|
|
|
def GGA(boatdata, msg):
|
|
# Time, position, and fix related data
|
|
# msg.num_sats
|
|
# msg.timestamp
|
|
if msg.gps_qual == 0:
|
|
# No fix
|
|
return
|
|
if msg.lat_dir == 'N':
|
|
boatdata.setValue("LAT", msg.latitude)
|
|
else:
|
|
boatdata.setValue("LAT", msg.latitude * -1)
|
|
if msg.lon_dir == 'E':
|
|
boatdata.setValue("LON", msg.longitude)
|
|
else:
|
|
boatdata.setValue("LON", msg.longitude * -1)
|
|
boatdata.setValue("HDOP", msg.horizontal_dil)
|
|
|
|
def GLL(boatdata, msg):
|
|
# Position data: position fix, time of position fix, and status
|
|
# UTC of position ignored
|
|
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):
|
|
# Satellites
|
|
for i in range(1, 13):
|
|
satno = getattr(msg, f"sv_id{i:02}")
|
|
if (len(satno) > 0) and not satno in boatdata.sat:
|
|
boatdata.addSatellite(int(satno))
|
|
boatdata.setValue("PDOP", float(msg.pdop))
|
|
boatdata.setValue("PDOP", float(msg.hdop))
|
|
boatdata.setValue("PDOP", float(msg.vdop))
|
|
|
|
def GSV(boatdata, msg):
|
|
# Satellites in view
|
|
# mgs_num msg.num_messages # Nachricht n von m
|
|
# msg.num_sv_in_view # Anzahl sichtbarer Satelliten
|
|
rres = None # range residuals
|
|
for i in range(1, 5):
|
|
prn_num = getattr(msg, f"sv_prn_num_{i}")
|
|
if len(prn_num) > 0:
|
|
elevation = float(getattr(msg, f"elevation_deg_{i}"))
|
|
azimuth = float(getattr(msg, f"azimuth_{i}"))
|
|
snr = getattr(msg, f"snr_{i}")
|
|
if len(snr) == 0:
|
|
snr = 0
|
|
status = 1 # prnusage tracked
|
|
else:
|
|
status = 2 # prnusage used
|
|
boatdata.updateSatellite(int(prn_num), elevation, azimuth, int(snr), rres, status)
|
|
"""
|
|
if msg.sv_prn_num_1:
|
|
if msg.snr_1 == '':
|
|
status = 1
|
|
msg.snr_1 = 0
|
|
boatdata.updateSatellite(int(msg.sv_prn_num_1), float(msg.elevation_deg_1), float(msg.azimuth_1), int(msg.snr_1), rres, status)
|
|
if msg.sv_prn_num_2:
|
|
if msg.snr_2 == '':
|
|
status = 1
|
|
msg.snr_2 = 0
|
|
boatdata.updateSatellite(int(msg.sv_prn_num_2), float(msg.elevation_deg_2), float(msg.azimuth_2), int(msg.snr_2), rres, status)
|
|
if msg.sv_prn_num_3:
|
|
if msg.snr_3 == '':
|
|
status = 1
|
|
msg.snr_3 = 0
|
|
boatdata.updateSatellite(int(msg.sv_prn_num_3), float(msg.elevation_deg_3), float(msg.azimuth_3), int(msg.snr_3), rres, status)
|
|
if msg.sv_prn_num_4:
|
|
if msg.snr_4 == '':
|
|
status = 1
|
|
msg.snr_4 = 0
|
|
boatdata.updateSatellite(int(msg.sv_prn_num_4), float(msg.elevation_deg_4), float(msg.azimuth_4), int(msg.snr_4), rres, status)
|
|
"""
|
|
|
|
def HDG(boatdata, msg):
|
|
# UNUSED: Heading - Deviation & Variation
|
|
# Magnetic Sensor heading in degrees
|
|
# msg.heading
|
|
# .deviation, dev_dir E/W
|
|
# .variation, var_dir E/W
|
|
pass
|
|
|
|
def HDM(boatdata, msg):
|
|
# Heading magnetic
|
|
if msg.magnetic == 'M':
|
|
boatdata.setValue("HDM", msg.heading)
|
|
else:
|
|
print("HDM: M not set!")
|
|
|
|
def HDT(boatdata, msg):
|
|
# Heading True
|
|
if msg.hdg_true == 'T':
|
|
boatdata.setValue("HDT", msg.heading)
|
|
else:
|
|
print("HDT: T not set!")
|
|
|
|
def HTD(boatdata, msg):
|
|
# Heading/Track control data
|
|
# e.g. $YDHTD,V,1.5,,R,N,,,,,,,,,A,,,*48
|
|
print("-> HTD")
|
|
print(msg.fields)
|
|
|
|
def MWV(boatdata, msg):
|
|
# Windgeschwindigkeit und -winkel
|
|
print(f"Wind: {msg.wind_angle}° {msg.wind_speed}kt")
|
|
boatdata.setValue("AWA", msg.wind_angle)
|
|
boatdata.setValue("AWS", msg.wind_speed)
|
|
|
|
def MTW(boatdata, msg):
|
|
# Wassertemperatur
|
|
# boatdata.setValue("WTemp", msg.xxx)
|
|
print("-> MTW Wassertemperatur")
|
|
|
|
def RMB(boatdata, msg):
|
|
# Recommended Minimum Navigation Information
|
|
# Informationen bzgl. Erreichen des nächsten Wegepunkts
|
|
#
|
|
print("-> RMB")
|
|
|
|
def RMC(boatdata, msg):
|
|
# Recommended Minimum Navigation Information
|
|
#print("-> RMC")
|
|
# print(msg.timestamp, msg.datestamp)
|
|
# print(msg.status) # V=Warning, P=Precise, A=OK
|
|
# mag_variation, mag_var_dir E/W
|
|
# TODO nav_status welche Bedeutung?
|
|
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:])
|
|
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)
|
|
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):
|
|
# Rate Of Turn
|
|
# print("-> ROT")
|
|
if msg.status == 'A':
|
|
boatdata.setValue("ROT", msg.rate_of_turn)
|
|
|
|
def RSA(boatdata, msg):
|
|
# Rudder Sensor Angle
|
|
# negative Werte bedeuten Backbord
|
|
#print("-> RSA")
|
|
# Boatdata: RPOS primär, PRPOS sekundär
|
|
if msg.rsa_starboard_status== 'A':
|
|
boatdata.setValue("RPOS", msg.rsa_starboard)
|
|
if msg.rsa_port_status == 'A':
|
|
boatdata.setValue("PRPOS", msg.rsa_port)
|
|
|
|
def RTE(boatdata, msg):
|
|
# Route
|
|
print("-> RTE")
|
|
print(msg.fields)
|
|
|
|
def VBW(boatdata, msg):
|
|
print("-> VBW")
|
|
|
|
def VHW(boatdata, msg):
|
|
print("-> VHW")
|
|
boatdata.setValue("STW", float(msg.water_speed_knots))
|
|
|
|
def VPW(boatdata, msg):
|
|
# UNUSED: Speed - Measured Parallel to Wind
|
|
# print(f"-> VPW: {msg.speed_kn} kn")
|
|
pass
|
|
|
|
def VTG(boatdata, msg):
|
|
# Track made good and speed over ground
|
|
"""
|
|
(('True Track made good', 'true_track', <class 'float'>),
|
|
('True Track made good symbol', 'true_track_sym'),
|
|
('Magnetic Track made good', 'mag_track', <class 'decimal.Decimal'>),
|
|
('Magnetic Track symbol', 'mag_track_sym'),
|
|
('Speed over ground knots', 'spd_over_grnd_kts', <class 'decimal.Decimal'>),
|
|
('Speed over ground symbol', 'spd_over_grnd_kts_sym'),
|
|
('Speed over ground kmph', 'spd_over_grnd_kmph', <class 'float'>),
|
|
('Speed over ground kmph symbol', 'spd_over_grnd_kmph_sym'),
|
|
('FAA mode indicator', 'faa_mode'))
|
|
['', 'T', '', 'M', '0.117', 'N', '0.216', 'K', 'A'] """
|
|
print("-> VTG")
|
|
# msg.true_track true_track_sym
|
|
# msg.mag_track mag_track_sym
|
|
# msg.faa_mode
|
|
#TODO klären was für Typen hier ankommen können
|
|
# bytearray, str, decimal.Decimal?
|
|
sog = float(msg.spd_over_grnd_kts)
|
|
#str von OpenCPN: sog = float(msg.spd_over_grnd_kts[:-1])
|
|
boatdata.setValue("SOG", sog)
|
|
|
|
def VWR(boatdata, msg):
|
|
# Relative Wind Speed and Angle
|
|
#print("-> VWR")
|
|
if msg.l_r == "R":
|
|
angle = msg.deg_r
|
|
else:
|
|
angle = 360 - msg.deg_r
|
|
boatdata.setValue("AWA", angle)
|
|
boatdata.setValue("AWS", msg.wind_speed_ms)
|
|
|
|
def WPL(boatdata, msg):
|
|
print("-> WPL")
|
|
print(msg.fields)
|
|
|
|
def VWT(boatdata, msg):
|
|
# True Wind Speed and Angle
|
|
if msg.direction == "R":
|
|
angle = msg.wind_angle_vessel
|
|
else:
|
|
angle = 360 - msg.wind_angle_vessel
|
|
boatdata.setValue("TWA", angle)
|
|
boatdata.setValue("TWS", msg.wind_speed_meters)
|
|
|
|
def XDR(boatdata, msg):
|
|
# Extra sensor data / Transducer Measurement
|
|
# type, value, units, id
|
|
# type: A
|
|
# units: D
|
|
# id: Yaw
|
|
if msg.id.lower() == 'yaw':
|
|
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:
|
|
print(f"-> XDR: {msg.type}, {msg.value}, {msg.units}, {msg.id}")
|
|
|
|
def XTE(boatdata, msg):
|
|
# Cross Track error measured
|
|
print("-> XTE")
|
|
|
|
def XTR(boatdata, msg):
|
|
# Cross Track error gekoppelt
|
|
print("-> XTR")
|
|
|
|
def ZDA(boatdata, msg):
|
|
# Time and date
|
|
print("-> XTE")
|
|
#boatdata.gpsd
|
|
#boatdata.gpst
|
|
|
|
# AIS
|
|
def VDM(boatdata, msg):
|
|
print("-> VDM")
|
|
print(msg.fields)
|
|
print(msg.data)
|
|
|
|
def VDO(boatdata, msg):
|
|
print("-> VDO")
|
|
|
|
|
|
# Aus Performancegründen eine direkte Sprungtabelle, ggf. können
|
|
# zukünftig außer der Funktion noch weitere Daten gespeichert werdeb
|
|
decoder = {
|
|
"DBS": DBS,
|
|
"DBT": DBT,
|
|
"DPT": DPT,
|
|
"GBS": GBS,
|
|
"GGA": GGA,
|
|
"GLL": GLL,
|
|
"GSA": GSA,
|
|
"GSV": GSV,
|
|
"HDG": HDG,
|
|
"HDM": HDM,
|
|
"HDT": HDT,
|
|
"HTD": HTD,
|
|
"MWV": MWV,
|
|
"MTW": MTW,
|
|
"RMB": RMB,
|
|
"ROT": ROT,
|
|
"RMC": RMC,
|
|
"RSA": RSA,
|
|
"RTE": RTE,
|
|
"VBW": VBW,
|
|
"VHW": VHW,
|
|
"VPW": VPW,
|
|
"VTG": VTG,
|
|
"VWR": VWR,
|
|
"VWT": VWT,
|
|
"WPL": WPL,
|
|
"XDR": XDR,
|
|
"XTE": XTE,
|
|
"XTR": XTR,
|
|
"ZDA": ZDA,
|
|
|
|
"VDM": VDM
|
|
}
|