| 274 | self._use_gpsd = False |
| 275 | self._running = False |
| 276 | self._thread = None |
| 277 | self._lock = threading.Lock() |
| 278 | |
| 279 | # Current GPS state |
| 280 | self.latitude = None |
| 281 | self.longitude = None |
| 282 | self.altitude = None |
| 283 | self.speed_kmh = None |
| 284 | self.course = None |
| 285 | self.fix_quality = 0 |
| 286 | self.satellites = 0 |
| 287 | self.satellites_in_view = 0 |
| 288 | self.snr_max = None |
| 289 | self.hdop = None |
| 290 | self.last_update = 0 |
| 291 | self.last_sentence = 0 |
| 292 | self._gsv_by_talker = {} |
| 293 | # Per-satellite sky view (prn/elev/az/snr) keyed by talker, plus the |
| 294 | # in-flight accumulator that stitches the multi-message GSV sequence |
| 295 | # (each sentence carries ≤4 satellites) back into one sweep. |
| 296 | self._sats_by_talker = {} |
| 297 | self._gsv_accum = {} |