feat: decode Config response in donglora.py, add all_commands.py example

Config response (GetConfig) now returns decoded RadioConfig fields instead
of raw hex. New all_commands.py exercises all 8 protocol commands in
sequence — Ping, SetConfig, GetConfig, StartRx, StopRx, Transmit,
DisplayOff, DisplayOn.
This commit is contained in:
swaits committed 2026-03-29 22:24:46 -06:00
1 parent 84be92f263
commit 6359b16135
2 files changed
+56

No files matched your search

+51
View File
@@ -0,0 +1,51 @@
#!/usr/bin/env python3
"""Exercise every DongLoRa command to verify the API works.
Usage:
uv run examples/all_commands.py [PORT]
"""
# /// script
# requires-python = ">=3.10"
# dependencies = ["cobs", "pyserial"]
# ///
import serial
import sys
sys.path.insert(0, __import__("pathlib").Path(__file__).parent.as_posix())
import donglora as dl # noqa: E402
try:
ser = dl.connect(sys.argv[1] if len(sys.argv) > 1 else None)
print("── Ping ──")
print(dl.send(ser, "Ping"))
print("\n── SetConfig ──")
print(dl.send(ser, "SetConfig", config=dl.DEFAULT_CONFIG))
print("\n── GetConfig ──")
print(dl.send(ser, "GetConfig"))
print("\n── StartRx ──")
print(dl.send(ser, "StartRx"))
print("\n── StopRx ──")
print(dl.send(ser, "StopRx"))
print("\n── Transmit ──")
print(dl.send(ser, "Transmit", payload=b"Hello from all_commands.py!"))
print("\n── DisplayOff ──")
print(dl.send(ser, "DisplayOff"))
print("\n── DisplayOn ──")
print(dl.send(ser, "DisplayOn"))
print("\nAll 8 commands exercised successfully.")
except KeyboardInterrupt:
print("\nInterrupted.")
except serial.SerialException as e:
print(f"\nSerial error: {e}", file=sys.stderr)
sys.exit(1)
+5
View File
@@ -125,6 +125,11 @@ def decode_response(data: bytes) -> dict:
if tag == 0: if tag == 0:
return {"type": "Pong"} return {"type": "Pong"}
elif tag == 1: elif tag == 1:
if len(rest) >= 10:
freq_hz, bw, sf, cr, sync_word, pwr = struct.unpack_from("<IBBBHB", rest, 0)
tx_power_dbm = struct.unpack_from("<b", rest, 9)[0]
return {"type": "Config", "freq_hz": freq_hz, "bw": bw, "sf": sf,
"cr": cr, "sync_word": sync_word, "tx_power_dbm": tx_power_dbm}
return {"type": "Config", "raw": rest.hex()} return {"type": "Config", "raw": rest.hex()}
elif tag == 2: elif tag == 2:
rssi = struct.unpack_from("<h", rest, 0)[0] rssi = struct.unpack_from("<h", rest, 0)[0]