NMEA0183 Empfangscode in entsprechendes Modul verlagert
This commit is contained in:
		
							parent
							
								
									612783454e
								
							
						
					
					
						commit
						5b000f4f1f
					
				
							
								
								
									
										6
									
								
								TODO
								
								
								
								
							
							
						
						
									
										6
									
								
								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