Rewrites lingering github.com / *.sr.ht references to this Gitea instance,
translating GitHub and Sourcehut URL shapes to Gitea's (/blob/<ref>/ and
sr.ht /tree/<ref>/item/ -> /src/branch/<ref>/, /tree/<tag> -> /src/tag/<tag>,
/actions/workflows/X -> /actions?workflow=X, /edit/ -> /_edit/).
Left pointing at the old hosts on purpose: pull-request links (PRs were not
migrated), forks that were never migrated, and GitHub-only surfaces Gitea
lacks. OpenPGP identity proofs are untouched by design.
Drop the [tool.uv.sources] override that pointed donglora at the
sibling client-py checkout. uv.lock now resolves donglora from
pypi.org, so example consumers get the published package.
Rewrite all scripts against the DongLoRa Protocol v2 async Dongle surface, and extract the shared MeshCore US preset into a single module.
* _common.py: MESHCORE_US preset (910.525 MHz / BW 62.5 / SF 7 / CR 4/5 / sync 0x1424 / 20 dBm) plus small helpers, imported by every example.
* New: explore.py, which prints the device capabilities and runs a single TX + RX roundtrip for quick hardware validation.
* simple_rx.py, simple_tx.py, ping_pong.py, lora_bridge.py all switch to donglora.Dongle and the new Modulation / LoRaConfig types.
* all_commands.py removed; it was an index of the old v0.1 command enum that no longer exists after the Protocol v2 split.
* justfile: drop stale recipes that referenced removed scripts.
- clients/python → client-py GitHub link
- Removed meshcore/orac/telemetry recipes from README (scripts never existed)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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) <noreply@anthropic.com>
- Add cargo-binutils to mise.toml (needed for `just size`)
- Remove jj from mise.toml (optional, not a build dependency)
- Silence `mise install` output when tools are current (--quiet)
- Add `just outdated` recipe with embassy-executor exclusion
(esp-rtos 0.2 pins embassy-executor ^0.9; 0.10 renamed arch-*
features to platform-*, which crashes cargo-outdated)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New protocol command (tag 8): GetMac returns the board's 6-byte hardware
address. Useful when multiple dongles are connected to one host.
Response (tag 6): MacAddress containing 6 raw bytes.
Updated: PROTOCOL.md, CHANGELOG, donglora.py decoder, all_commands.py.
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.
All examples now catch serial.SerialException instead of crashing with
a traceback. This covers port contention (multiple processes), device
disconnect, and USB errors. meshcore_rx.py already had this.
Remove all varint/zigzag encoding. Every field is now struct.pack/unpack
with fixed-size little-endian format strings. RadioConfig is a single
struct.pack('<IBBBHB', ...) call. Response decoding uses struct.unpack_from
with known offsets. No encoding helpers needed beyond struct.
- Each board exports TX_POWER_RANGE constant (min, max dBm)
- RadioConfig::validate() uses the board's range, not hardcoded limits
- TX_POWER_MAX sentinel (-128 on the wire) means "use board's maximum"
— resolved to the actual max before storing config
- GetConfig returns the resolved actual power, not the sentinel
- Default configs in examples use TX_POWER_MAX
- Protocol docs updated
ROOT CAUSE: postcard encodes u8 and i8 as raw bytes, NOT varint/zigzag.
The Python encoders used varint() for u8 and zigzag() for i8. For small
values this was silently correct (varint(7) == raw byte 7), but for
tx_power_dbm: zigzag(14) = 28, which the new validation correctly
rejected as out of range (-9..22). This was a pre-existing bug masked
by the absence of validation.
Fix all RadioConfig field encoders in both donglora.py and meshcore_rx.py.
Fix docs/PROTOCOL.md to correctly document i8 as raw byte, not zigzag.
Restore full config validation.