@@ -90,6 +90,7 @@ def __init__(self, uart, debug=False):
90
90
self .height_geoid = None
91
91
self .speed_knots = None
92
92
self .track_angle_deg = None
93
+ self ._sats = None
93
94
self .sats = None
94
95
self .isactivedata = None
95
96
self .true_track = None
@@ -121,9 +122,9 @@ def update(self):
121
122
print (sentence )
122
123
data_type , args = sentence
123
124
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 )
125
126
126
- # Check for all currently known talkers
127
+ # Check for all currently known GNSS talkers
127
128
# GA - Galileo
128
129
# GB - BeiDou Systems
129
130
# GI - NavIC
@@ -132,17 +133,19 @@ def update(self):
132
133
# GQ - QZSS
133
134
# GN - GNSS / More than one of the above
134
135
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
139
138
140
139
if sentence_type == b'GLL' : # Geographic position - Latitude/Longitude
141
140
self ._parse_gpgll (args )
142
141
elif sentence_type == b'RMC' : # Minimum location info
143
142
self ._parse_gprmc (args )
144
143
elif sentence_type == b'GGA' : # 3D location fix
145
144
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 )
146
149
return True
147
150
148
151
def send_command (self , command , add_checksum = True ):
@@ -253,6 +256,13 @@ def _parse_sentence(self):
253
256
data_type = sentence [1 :delimiter ]
254
257
return (data_type , sentence [delimiter + 1 :])
255
258
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
+
256
266
def _parse_gpgll (self , args ):
257
267
data = args .split ("," )
258
268
if data is None or data [0 ] is None or (data [0 ] == "" ):
@@ -414,7 +424,8 @@ def _parse_gpgga(self, args):
414
424
self .altitude_m = _parse_float (data [8 ])
415
425
self .height_geoid = _parse_float (data [10 ])
416
426
417
- def _parse_gpgsa (self , args ):
427
+ def _parse_gpgsa (self , talker , args ):
428
+ talker = talker .decode ('ascii' )
418
429
data = args .split ("," )
419
430
if data is None or (data [0 ] == "" ):
420
431
return # Unexpected number of params
@@ -424,9 +435,9 @@ def _parse_gpgsa(self, args):
424
435
# Parse 3d fix
425
436
self .fix_quality_3d = _parse_int (data [1 ])
426
437
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 )) )
430
441
431
442
# Parse PDOP, dilution of precision
432
443
self .pdop = _parse_float (data [- 3 ])
@@ -435,9 +446,10 @@ def _parse_gpgsa(self, args):
435
446
# Parse VDOP, vertical dilution of precision
436
447
self .vdop = _parse_float (data [- 1 ])
437
448
438
- def _parse_gpgsv (self , args ):
449
+ def _parse_gpgsv (self , talker , args ):
439
450
# Parse the arguments (everything after data type) for NMEA GPGGA
440
451
# 3D location fix sentence.
452
+ talker = talker .decode ('ascii' )
441
453
data = args .split ("," )
442
454
if data is None or (data [0 ] == "" ):
443
455
return # Unexpected number of params.
@@ -454,33 +466,40 @@ def _parse_gpgsv(self, args):
454
466
455
467
sat_tup = data [3 :]
456
468
457
- satdict = {}
458
- for i in range (len (sat_tup ) / 4 ):
469
+ satlist = []
470
+ for i in range (len (sat_tup ) // 4 ):
459
471
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
462
473
satdeg = _parse_int (sat_tup [1 + j ]) # Elevation in degrees
463
474
satazim = _parse_int (sat_tup [2 + j ]) # Azimuth in degrees
464
475
satsnr = _parse_int (sat_tup [3 + j ]) # signal-to-noise ratio in dB
465
476
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 ()
467
502
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
484
503
self .satellites_prev = self .satellites
485
504
486
505
0 commit comments