From cc2e5cf613ba0f2797adf82f2e05323d6ee288d6 Mon Sep 17 00:00:00 2001 From: Jono Targett Date: Sat, 14 Mar 2026 23:36:24 +1030 Subject: [PATCH] messy dirty hack code --- ubx.py => asset.py | 0 assethandler.py | 59 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 52 insertions(+), 7 deletions(-) rename ubx.py => asset.py (100%) diff --git a/ubx.py b/asset.py similarity index 100% rename from ubx.py rename to asset.py diff --git a/assethandler.py b/assethandler.py index a0341bc..b8055a1 100755 --- a/assethandler.py +++ b/assethandler.py @@ -4,6 +4,7 @@ import asyncio import uuid import aioserial import aiomqtt +import pyubx2 SERIAL_PORT = "/tmp/ttyV0" BAUD = 115200 @@ -12,14 +13,58 @@ SERIAL_PUBLISH_TOPIC = "serial/data" SERIAL_COMMAND_TOPIC = "serial/command" -async def serial_reader(ser, client): - while True: - data = await ser.read_async(64) - if data: - await client.publish(SERIAL_PUBLISH_TOPIC, data) - # Hand back to event loop - await asyncio.sleep(0) +async def parse_serial(ser): + """ + Async generator: read raw bytes from serial and yield parsed UBX/NMEA messages. + """ + buffer = bytearray() + # pyubx2 requires a file-like object, so we'll use a memoryview wrapper + class StreamWrapper: + def read(self, n=1): + # grab at most n bytes from buffer + if not buffer: + raise BlockingIOError + out = buffer[:n] + del buffer[:n] + return bytes(out) + + ubr = pyubx2.UBXReader(StreamWrapper(), parsing=True) + + while True: + # read available data from serial (small chunks) + chunk = await ser.read_async(200) + if chunk: + buffer.extend(chunk) + + # attempt to parse as many messages as possible + try: + while True: + raw, parsed = ubr.read() + if raw is None: + break + yield raw, parsed + except (BlockingIOError, Exception): + # incomplete message; wait for more bytes + pass + except pyubx2.UBXStreamError: + pass # silently ignore incomplete packets + else: + await asyncio.sleep(0) # yield control + + +async def serial_reader(ser, mqtt_client): + """ + Coroutine wrapper around async generator parse_serial. + Feeds parsed UBX/NMEA messages to MQTT. + """ + async for raw, parsed in parse_serial(ser): + # For example, publish raw bytes to MQTT + print(parsed) + await mqtt_client.publish("serial/parsed", str(parsed)) + await mqtt_client.publish("serial/raw", raw) + # Optional: inspect parsed fields + # print(parsed) async def mqtt_command_writer(ser, client): async for message in client.messages: