swaits e9c4bb3e93 feat!: Python client Protocol v2 rewrite with async Dongle surface
The 1.0 Python client, mirroring the Rust client 1.0 API and the DongLoRa Protocol v2 wire format.

* Module split: monolithic protocol.py / client.py replaced with dongle.py (high-level async Dongle), session.py (reader task + tag routing), frame.py (streaming FrameDecoder + encode_frame), commands.py / events.py / errors.py / modulation.py / info.py / crc.py / chip_id (re-export) matching the donglora-protocol Rust crate.

* Async API throughout. Serial I/O via asyncio-serial; mux connections via asyncio streams. The blocking client surface is gone.

* thiserror-equivalent error hierarchy (DongloraError base with Timeout, TransportClosed, ReaderExited, BadFrame, ErrClientError variants mirroring the Rust ClientError).

* Tag-aware dispatch with concurrent in-flight commands: TagAllocator hands out 16-bit device tags, Session routes each response back to the originating coroutine.

* Auto-recovery from ERR(ENOTCONFIGURED): the Dongle caches the last SET_CONFIG and silently re-applies on timeout.

* 500 ms background keepalive task per PROTOCOL.md §3.4.

* Tests rewritten: test_dongle, test_session, test_frame, test_events, test_modulation, test_crc, test_ergonomics; old test_client / test_protocol removed.

* Sticky mux reconnect (from the prior fix commit) is preserved: once a mux socket is in use, reconnects commit to it instead of falling back to USB.
2026-04-22 09:53:35 -06:00
2026-04-03 10:28:38 -06:00

DongLoRa Python Client

Python client library for talking to a DongLoRa device — either directly over USB or through the mux daemon.

Install

pip install donglora

Or with uv:

uv add donglora

Quick Start

import donglora as dl

ser = dl.connect()
dl.send(ser, "SetConfig", config=dl.DEFAULT_CONFIG)
dl.send(ser, "StartRx")

while True:
    pkt = dl.recv(ser)
    if pkt:
        print(pkt["rssi"], pkt["payload"].hex())

Connection Functions

Function Description
connect() Auto-detect: TCP mux, Unix socket mux, then USB serial
connect_default() Convenience wrapper with default timeout
try_connect() Like connect() but non-blocking — raises if no device found
connect_mux_auto() Mux only — never falls back to USB serial
mux_connect() Connect via Unix domain socket
mux_tcp_connect() Connect via TCP

Module Structure

Module Contents
donglora.protocol Wire types, RadioConfig, encode/decode, constants
donglora.codec COBS framing
donglora.discovery USB device discovery by VID:PID
donglora.transport MuxConnection (socket wrapper)
donglora.connect Connection auto-detection and mux helpers
donglora.client High-level send/recv/validate

Everything is re-exported from the top-level donglora package.

Dependencies

  • cobs — COBS framing
  • pyserial — USB serial communication

Optional extras: meshcore (crypto), orac (AI bot).

Development

just check    # fmt + lint + test
just fmt      # format code
just test     # run tests
S
Description
No description provided
Readme
165 KiB
0 Stars 1 Watchers 0 Forks
Languages
Python 99.7%
Just 0.3%