NMEA0183 in eigenes Modul ausgelagert
This commit is contained in:
		
							parent
							
								
									b1fdb592b0
								
							
						
					
					
						commit
						df04c9ad8e
					
				
							
								
								
									
										3
									
								
								TODO
								
								
								
								
							
							
						
						
									
										3
									
								
								TODO
								
								
								
								
							|  | @ -1,5 +1,8 @@ | |||
| Aufgaben- und Planungs- und Ideenliste | ||||
| 
 | ||||
| - datareader für mehrere I²C-Sensoren. History muß entsprechend | ||||
|   eine Liste sein. | ||||
| 
 | ||||
| - Barograph | ||||
| 
 | ||||
| - Ankeralarm | ||||
|  |  | |||
|  | @ -0,0 +1,69 @@ | |||
| """ | ||||
| NMEA0183 verarbeiten | ||||
| 
 | ||||
| """ | ||||
| 
 | ||||
| def DBS(boatdata, msg): | ||||
|     # Wassertiefe unter der Oberfläche | ||||
|     pass | ||||
| 
 | ||||
| def DBT(boatdata, msg): | ||||
|     # Wassertiefe unter Geber | ||||
|     pass | ||||
| 
 | ||||
| def GLL(boatdata, msg): | ||||
|     print("-> GLL") | ||||
|     boatdata.setValue("LAT", msg.latitude) | ||||
|     boatdata.setValue("LON", msg.longitude) | ||||
| 
 | ||||
| def HDT(boatdata, msg): | ||||
|     # Heading True | ||||
|     print("-> HDT") | ||||
|     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 RSA(boatdata, msg): | ||||
|     # Rudder Sensor Angle | ||||
|     # negative Werte bedeuten Backbord | ||||
|     # Boatdata: RPOS primär, PRPOS sekundär | ||||
|     print("-> RSA") | ||||
|     print(msg.fields) | ||||
| 
 | ||||
| def RTE(boatdata, msg): | ||||
|     # Route | ||||
|     print("-> RTE") | ||||
|     print(msg.fields) | ||||
| 
 | ||||
| def VHW(boatdata, msg): | ||||
|     boatdata.setValue("STW", float(msg.water_speed_knots)) | ||||
| 
 | ||||
| def VTG(boatdata, msg): | ||||
|     boatdata.setValue("COG", int(msg.true_track)) | ||||
|     #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 WPL(boatdata, msg): | ||||
|     print("-> WPL") | ||||
|     print(msg.fields) | ||||
| 
 | ||||
| # 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, | ||||
|     "GLL": GLL, | ||||
|     "MWV": MWV, | ||||
|     "RSA": RSA, | ||||
|     "RTE": RTE, | ||||
|     "VHW": VHW, | ||||
|     "VTG": VTG, | ||||
|     "WPL": WPL | ||||
| } | ||||
							
								
								
									
										49
									
								
								obp60v.py
								
								
								
								
							
							
						
						
									
										49
									
								
								obp60v.py
								
								
								
								
							|  | @ -102,6 +102,7 @@ import time | |||
| from datetime import datetime | ||||
| from nmea2000 import Device, BoatData, History, HistoryBuffer | ||||
| from nmea2000 import parser | ||||
| import nmea0183 | ||||
| import pages | ||||
| import struct | ||||
| 
 | ||||
|  | @ -203,8 +204,10 @@ def rxd_0183(devname): | |||
|         return | ||||
|     setthreadtitle("0183listener") | ||||
|     while not shutdown: | ||||
|         try: | ||||
|         raw = ser.readline().decode('ascii') | ||||
|         if len(raw) == 0: | ||||
|             continue | ||||
|         try: | ||||
|             msg = pynmea2.parse(raw) | ||||
|         except pynmea2.nmea.ParseError: | ||||
|             print(f"NMEA0183: Parse-Error: {raw}") | ||||
|  | @ -215,25 +218,15 @@ def rxd_0183(devname): | |||
|         except: | ||||
|             print(f"NMEA0183: Sentence type missing: {raw}") | ||||
|             continue | ||||
|         if stype == 'GLL': | ||||
|             boatdata.setValue("LAT", msg.latitude) | ||||
|             boatdata.setValue("LON", msg.longitude) | ||||
|         elif stype == 'VTG': | ||||
|             boatdata.setValue("COG", int(msg.true_track)) | ||||
|             #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) | ||||
|         elif stype == 'VHW': | ||||
|             boatdata.setValue("STW", float(msg.water_speed_knots)) | ||||
|         elif stype == 'WPL': | ||||
|             # Wegepunkt | ||||
|             print(msg.fields) | ||||
|         elif stype == 'RTE': | ||||
|             # Route | ||||
|             print(msg.fields) | ||||
|         # 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 | ||||
|             print("Nicht implementiert") | ||||
|             print(msg) | ||||
|     ser.close() | ||||
| 
 | ||||
|  | @ -258,7 +251,7 @@ def rxd_gps(devname, devspeed): | |||
|             print(msg.fields) | ||||
|     ser.close() | ||||
| 
 | ||||
| def datareader(histpath, history): | ||||
| def datareader(cfg, history): | ||||
|     """ | ||||
|     Daten zu fest definierten Zeitpunkten lesen | ||||
| 
 | ||||
|  | @ -272,9 +265,9 @@ def datareader(histpath, history): | |||
|     setthreadtitle("datareader") | ||||
| 
 | ||||
|     # Speicherpfad für Meßwertdaten | ||||
|     if not os.path.exists(histpath): | ||||
|         os.makedirs(histpath) | ||||
|     history.basepath = histpath | ||||
|     if not os.path.exists(cfg['histpath']): | ||||
|         os.makedirs(cfg['histpath']) | ||||
|     history.basepath = cfg['histpath'] | ||||
|     # Serien initialisieren | ||||
|     history.addSeries("BMP280-75", 336 ,75) | ||||
|     history.addSeries("BMP280-150", 336 , 150) | ||||
|  | @ -687,17 +680,23 @@ if __name__ == "__main__": | |||
| 
 | ||||
|     # Schnittstellen aktivieren | ||||
|     if cfg['can']: | ||||
|         print("CAN enabled") | ||||
|         t_rxd_n2k = threading.Thread(target=rxd_n2k, args=(cfg['can_intf'],)) | ||||
|         t_rxd_n2k.start() | ||||
|     if cfg['nmea0183']: | ||||
|         print("NMEA0183 enabled") | ||||
|         t_rxd_0183 = threading.Thread(target=rxd_0183, args=(cfg['0183_port'],)) | ||||
|         t_rxd_0183.start() | ||||
|     if cfg['gps']: | ||||
|         print("GPS enabled (local)") | ||||
|         t_rxd_gps = threading.Thread(target=rxd_gps, args=(cfg['gps_port'],)) | ||||
|         t_rxd_gps.start() | ||||
|     if not cfg['simulation']: | ||||
|         t_data = threading.Thread(target=datareader, args=(cfg['histpath'], history)) | ||||
|         if cfg['bme280']: | ||||
|             t_data = threading.Thread(target=datareader, args=(cfg, history)) | ||||
|             t_data.start() | ||||
|     else: | ||||
|         print("Simulation mode enabled") | ||||
| 
 | ||||
|     app = Frontend(cfg, owndevice, boatdata, profile) | ||||
|     app.run() | ||||
|  | @ -708,6 +707,6 @@ if __name__ == "__main__": | |||
|         t_rxd_0183.join() | ||||
|     if cfg['gps']: | ||||
|         t_rxd_gps.join() | ||||
|     if not cfg['simulation']: | ||||
|     if not cfg['simulation'] and cfg['bme280']: | ||||
|         t_data.join() | ||||
|     print("Another fine product of the Sirius Cybernetics Corporation.") | ||||
|  |  | |||
|  | @ -28,6 +28,10 @@ Damit eine saubere Skala auf der Y-Achse erreicht wird, gibt einige | |||
| feste Skalierungen. | ||||
| Standard: 20hPa von unten nach oben, z.B. 1015, 1020, 1025, 1030, 1035 | ||||
| 
 | ||||
| TODO  | ||||
|   - wenn keine Luftdruckdaten vorliegen, dann eine entsprechende | ||||
|     Meldung anzeigen | ||||
| 
 | ||||
| """ | ||||
| 
 | ||||
| import time | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue