From c4ef54a308b31cd3c8ce1020e78602404053a452 Mon Sep 17 00:00:00 2001 From: Richard Date: Sun, 25 Jan 2026 11:02:58 -0800 Subject: [PATCH] Rework gpsd gps code to fix issue with early dongle which never reported sky --- python/PiFinder/gps_gpsd.py | 126 ++++++++++++++---------------------- 1 file changed, 50 insertions(+), 76 deletions(-) diff --git a/python/PiFinder/gps_gpsd.py b/python/PiFinder/gps_gpsd.py index 12f29c7f..96df6c43 100644 --- a/python/PiFinder/gps_gpsd.py +++ b/python/PiFinder/gps_gpsd.py @@ -4,7 +4,6 @@ This module is for GPS related functions """ -import asyncio from PiFinder.multiproclogging import MultiprocLogging from gpsdclient import GPSDClient import logging @@ -43,66 +42,8 @@ def is_tpv_accurate(tpv_dict): return False -async def aiter_wrapper(sync_iter): - """Wrap a synchronous iterable into an asynchronous one.""" - for item in sync_iter: - yield item - await asyncio.sleep(0) # Yield control to the event loop - - -async def process_sky_messages(client, gps_queue): - sky_stream = client.dict_stream(filter=["SKY"]) - global error_2d, error_3d - async for result in aiter_wrapper(sky_stream): - logger.debug("GPS: SKY: %s", result) - if result["class"] == "SKY": - error_2d = result.get("hdop", 999) - error_3d = result.get("pdop", 999) - if result["class"] == "SKY" and "nSat" in result: - sats_seen = result["nSat"] - sats_used = result["uSat"] - num_sats = (sats_seen, sats_used) - msg = ("satellites", num_sats) - logger.debug("Number of sats seen: %i", sats_seen) - gps_queue.put(msg) - await asyncio.sleep(0) # Yield control to the event loop - - -async def process_reading_messages(client, gps_queue, console_queue, gps_locked): - global error_in_m - tpv_stream = client.dict_stream(convert_datetime=True, filter=["TPV"]) - async for result in aiter_wrapper(tpv_stream): - if is_tpv_accurate(result): - # if True: - logger.debug("last reading is %s", result) - if result.get("lat") and result.get("lon") and result.get("altHAE"): - if not gps_locked: - gps_locked = True - console_queue.put("GPS: Locked") - logger.debug("GPS locked") - msg = ( - "fix", - { - "lat": result.get("lat"), - "lon": result.get("lon"), - "altitude": result.get("altHAE"), - "source": "GPS", - "lock": True, - "lock_type": result.get("mode", 0), - "error_in_m": error_in_m, - }, - ) - logger.debug("GPS fix: %s", msg) - gps_queue.put(msg) - - if result.get("time"): - msg = ("time", result.get("time")) - logger.debug("Setting time to %s", result.get("time")) - gps_queue.put(msg) - await asyncio.sleep(0) # Yield control to the event loop - - -async def gps_main(gps_queue, console_queue, log_queue): +def gps_main(gps_queue, console_queue, log_queue): + global error_2d, error_3d, error_in_m MultiprocLogging.configurer(log_queue) logger.info("Using GPSD GPS code") gps_locked = False @@ -110,24 +51,57 @@ async def gps_main(gps_queue, console_queue, log_queue): while True: try: with GPSDClient(host="127.0.0.1") as client: - while True: - logger.debug("GPS waking") - - # Run both functions concurrently - await asyncio.gather( - process_sky_messages(client, gps_queue), - process_reading_messages( - client, gps_queue, console_queue, gps_locked - ), - ) - - logger.debug("GPS sleeping now for 7s") - await asyncio.sleep(7) + for result in client.dict_stream( + convert_datetime=True, filter=["TPV", "SKY"] + ): + if result["class"] == "TPV" and is_tpv_accurate(result): + logger.debug("last reading is %s", result) + if ( + result.get("lat") + and result.get("lon") + and result.get("altHAE") + ): + if not gps_locked: + gps_locked = True + console_queue.put("GPS: Locked") + logger.debug("GPS locked") + msg = ( + "fix", + { + "lat": result.get("lat"), + "lon": result.get("lon"), + "altitude": result.get("altHAE"), + "source": "GPS", + "lock": True, + "lock_type": result.get("mode", 0), + "error_in_m": error_in_m, + }, + ) + logger.debug("GPS fix: %s", msg) + gps_queue.put(msg) + + if result.get("time"): + msg = ("time", result.get("time")) + logger.debug("Setting time to %s", result.get("time")) + gps_queue.put(msg) + + if result["class"] == "SKY": + logger.debug("GPS: SKY: %s", result) + print("GPS: SKY: %s", result) + if result["class"] == "SKY": + error_2d = result.get("hdop", 999) + error_3d = result.get("pdop", 999) + if result["class"] == "SKY" and "nSat" in result: + sats_seen = result["nSat"] + sats_used = result["uSat"] + num_sats = (sats_seen, sats_used) + msg = ("satellites", num_sats) + logger.debug("Number of sats seen: %i", sats_seen) + gps_queue.put(msg) except Exception as e: logger.error(f"Error in GPS monitor: {e}") - await asyncio.sleep(5) # Wait before attempting to reconnect # To run the GPS monitor def gps_monitor(gps_queue, console_queue, log_queue): - asyncio.run(gps_main(gps_queue, console_queue, log_queue)) + gps_main(gps_queue, console_queue, log_queue)