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 | ||||||
|  |  | ||||||
							
								
								
									
										67
									
								
								nmea0183.py
								
								
								
								
							
							
						
						
									
										67
									
								
								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 | ||||||
|  | @ -143,18 +163,23 @@ 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