@@ -90,6 +90,7 @@ def __init__(self, uart, debug=False):
9090 self .height_geoid = None
9191 self .speed_knots = None
9292 self .track_angle_deg = None
93+ self ._sats = None
9394 self .sats = None
9495 self .isactivedata = None
9596 self .true_track = None
@@ -121,9 +122,9 @@ def update(self):
121122 print (sentence )
122123 data_type , args = sentence
123124 data_type = bytes (data_type .upper (), "ascii" )
124- (talker , sentence_type ) = (data_type [: 2 ], data_type [ 2 :] )
125+ (talker , sentence_type ) = self . _parse_talker (data_type )
125126
126- # Check for all currently known talkers
127+ # Check for all currently known GNSS talkers
127128 # GA - Galileo
128129 # GB - BeiDou Systems
129130 # GI - NavIC
@@ -132,17 +133,19 @@ def update(self):
132133 # GQ - QZSS
133134 # GN - GNSS / More than one of the above
134135 if talker not in (b'GA' , b'GB' , b'GI' , b'GL' , b'GP' , b'GQ' , b'GN' ):
135- if self .debug :
136- print (f" Unknown talker: { talker } " )
137- # We don't know the talker so it's not new data
138- return False
136+ # It's not a known GNSS source of data
137+ return True
139138
140139 if sentence_type == b'GLL' : # Geographic position - Latitude/Longitude
141140 self ._parse_gpgll (args )
142141 elif sentence_type == b'RMC' : # Minimum location info
143142 self ._parse_gprmc (args )
144143 elif sentence_type == b'GGA' : # 3D location fix
145144 self ._parse_gpgga (args )
145+ elif sentence_type == b'GSV' : # Satellites in view
146+ self ._parse_gpgsv (talker , args )
147+ elif sentence_type == b'GSA' : # GPS DOP and active satellites
148+ self ._parse_gpgsa (talker , args )
146149 return True
147150
148151 def send_command (self , command , add_checksum = True ):
@@ -253,6 +256,13 @@ def _parse_sentence(self):
253256 data_type = sentence [1 :delimiter ]
254257 return (data_type , sentence [delimiter + 1 :])
255258
259+ def _parse_talker (self , data_type ):
260+ # Split the data_type into talker and sentence_type
261+ if data_type [0 ] == b'P' : # Proprietary codes
262+ return (data_type [:1 ], data_type [1 :])
263+ else :
264+ return (data_type [:2 ], data_type [2 :])
265+
256266 def _parse_gpgll (self , args ):
257267 data = args .split ("," )
258268 if data is None or data [0 ] is None or (data [0 ] == "" ):
@@ -414,7 +424,8 @@ def _parse_gpgga(self, args):
414424 self .altitude_m = _parse_float (data [8 ])
415425 self .height_geoid = _parse_float (data [10 ])
416426
417- def _parse_gpgsa (self , args ):
427+ def _parse_gpgsa (self , talker , args ):
428+ talker = talker .decode ('ascii' )
418429 data = args .split ("," )
419430 if data is None or (data [0 ] == "" ):
420431 return # Unexpected number of params
@@ -424,9 +435,9 @@ def _parse_gpgsa(self, args):
424435 # Parse 3d fix
425436 self .fix_quality_3d = _parse_int (data [1 ])
426437 satlist = list (filter (None , data [2 :- 4 ]))
427- self .sat_prns = {}
428- for i , sat in enumerate ( satlist , 1 ) :
429- self .sat_prns [ "gps{} " .format (i )] = _parse_int (sat )
438+ self .sat_prns = []
439+ for sat in satlist :
440+ self .sat_prns . append ( "{}{} " .format (talker , _parse_int (sat )) )
430441
431442 # Parse PDOP, dilution of precision
432443 self .pdop = _parse_float (data [- 3 ])
@@ -435,9 +446,10 @@ def _parse_gpgsa(self, args):
435446 # Parse VDOP, vertical dilution of precision
436447 self .vdop = _parse_float (data [- 1 ])
437448
438- def _parse_gpgsv (self , args ):
449+ def _parse_gpgsv (self , talker , args ):
439450 # Parse the arguments (everything after data type) for NMEA GPGGA
440451 # 3D location fix sentence.
452+ talker = talker .decode ('ascii' )
441453 data = args .split ("," )
442454 if data is None or (data [0 ] == "" ):
443455 return # Unexpected number of params.
@@ -454,33 +466,40 @@ def _parse_gpgsv(self, args):
454466
455467 sat_tup = data [3 :]
456468
457- satdict = {}
458- for i in range (len (sat_tup ) / 4 ):
469+ satlist = []
470+ for i in range (len (sat_tup ) // 4 ):
459471 j = i * 4
460- key = "gps{}" .format (i + (4 * (self .mess_num - 1 )))
461- satnum = _parse_int (sat_tup [0 + j ]) # Satellite number
472+ satnum = "{}{}" .format (talker , _parse_int (sat_tup [0 + j ])) # Satellite number
462473 satdeg = _parse_int (sat_tup [1 + j ]) # Elevation in degrees
463474 satazim = _parse_int (sat_tup [2 + j ]) # Azimuth in degrees
464475 satsnr = _parse_int (sat_tup [3 + j ]) # signal-to-noise ratio in dB
465476 value = (satnum , satdeg , satazim , satsnr )
466- satdict [key ] = value
477+ satlist .append (value )
478+
479+ if self ._sats is None :
480+ self ._sats = []
481+ for value in satlist :
482+ self ._sats .append (value )
483+
484+ if self .mess_num == self .total_mess_num :
485+ # Last part of GSV message
486+ if len (self ._sats ) == self .satellites :
487+ # Transfer received satellites to self.sats
488+ if self .sats is None :
489+ self .sats = {}
490+ else :
491+ # Remove all old data from self.sats which
492+ # match the current talker
493+ old = []
494+ for i in self .sats :
495+ if i [0 :2 ] == talker :
496+ old .append (i )
497+ for i in old :
498+ self .sats .pop (i )
499+ for s in self ._sats :
500+ self .sats [s [0 ]] = s
501+ self ._sats .clear ()
467502
468- if self .sats is None :
469- self .sats = {}
470- for satnum in satdict :
471- self .sats [satnum ] = satdict [satnum ]
472-
473- try :
474- if self .satellites < self .satellites_prev :
475- for i in self .sats :
476- try :
477- if int (i [- 2 ]) >= self .satellites :
478- del self .sats [i ]
479- except ValueError :
480- if int (i [- 1 ]) >= self .satellites :
481- del self .sats [i ]
482- except TypeError :
483- pass
484503 self .satellites_prev = self .satellites
485504
486505
0 commit comments