From 86d35bf80aecd5b33e718b17017118671d982f5c Mon Sep 17 00:00:00 2001 From: Stephen Waits Date: Fri, 3 Apr 2026 11:32:52 -0600 Subject: [PATCH] feat(examples): add SNR-based packet filtering to LoRa bridge Drop INVALID and UNRELIABLE packets per PROTOCOL.md quality grading to avoid retransmitting likely-corrupt data. MARGINAL packets are forwarded with a warning tag. All RX log lines now include SNR. Co-Authored-By: Claude Opus 4.6 (1M context) --- examples/lora_bridge.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/examples/lora_bridge.py b/examples/lora_bridge.py index 3e731e91..de373616 100755 --- a/examples/lora_bridge.py +++ b/examples/lora_bridge.py @@ -68,7 +68,27 @@ def radio_to_tcp(ser: serial.Serial, sock: socket.socket): resp = dl.decode_response(data) if resp["type"] == "RxPacket": payload = resp["payload"] - print(f" RX→TCP len:{len(payload):3d} rssi:{resp['rssi']}dBm") + snr = resp["snr"] + rssi = resp["rssi"] + sf = dl.DEFAULT_CONFIG["sf"] + min_snr = -2.5 * (sf - 4) + + # Grade per PROTOCOL.md — drop likely-corrupt packets + if snr < -32 or snr > 32: + grade = "INVALID" + elif snr < min_snr: + grade = "UNRELIABLE" + elif snr < min_snr + 3: + grade = "MARGINAL" + else: + grade = "GOOD" + + if grade in ("INVALID", "UNRELIABLE"): + print(f" RX drop len:{len(payload):3d} rssi:{rssi}dBm snr:{snr}dB [{grade}]") + continue + + tag = f" [{grade}]" if grade == "MARGINAL" else "" + print(f" RX→TCP len:{len(payload):3d} rssi:{rssi}dBm snr:{snr}dB{tag}") tcp_send(sock, payload) except (serial.SerialException, OSError) as e: print(f" [radio→tcp error: {e}]")