Commit Graph
3 Commits
Author SHA1 Message Date
Jean-Pierre MartineauandClaude Opus 4.8 3f8c698625 Trace TX optimization round-trip; restore TX when no result
Two correctness fixes for remote-admin TX optimization:

1. Reverse/round-trip measurement path. The optimizer traced a one-way path
   ending at the (possibly far) target and waited for the target itself to
   originate the trace reply, which never returns when the target is only
   reachable via other repeaters, so every trace timed out. Now we trace out
   to the target and back (the MeshCore A,B,A convention) so a reachable
   near node answers; the target only forwards. Its received SNR is read from
   its hop by hash (the round trip turn-around) rather than by position.

2. Restore original TX on no result. If not one trace gets through at any
   level there is no meaningful winner, so leave the node at its original
   power (applied=False) and warn, instead of writing a bogus value.

Mock updated to model each hop SNR from the node that transmitted into it and
to drop traces on the bottleneck hop. Added round-trip / target-hash tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 14:45:03 -04:00
Jean-Pierre MartineauandClaude Opus 4.8 c75a2eb2e3 Replace local TX optimizer with remote-admin, path-based tuning
Tune the TX power of a remote node we have admin rights on (the hop before
a chosen target) to maximize the SNR the target receives from it, instead of
tuning the local device against a path bottleneck.

- Device gains admin_login / get_remote_tx_power / set_remote_tx_power
  (MeshCoreDevice via send_login_sync + `set tx <dbm>` send_cmd; MockDevice
  models target SNR as an inverted-U in the admin node's TX with a reliability
  dropoff at the band edges).
- tx_optimizer: forced-path sweep with a lexicographic objective (reliability
  first, then SNR), median-based levels, coarse+refine search, and a verify
  pass; near-SNR ties break toward lower power. Outlier-robust by construction.
- AdminStore remembers per-node admin passwords in <config_dir>/admin.json
  (owner-only perms), cleared automatically when a login is rejected.
- Configurable 12-28 dBi default range (tx_opt_min/tx_opt_max).
- tx-optimize tool: path/password prompts, live progress, persistence, applies
  the winner on finish, and renders an interactive HTML chart.
- Rewrote TX result models, widgets, plot, repository.record_tx_sample, and the
  TX tests for the new flow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 13:58:15 -04:00
Jean-Pierre MartineauandClaude Opus 4.8 43353f83a9 Initial commit: MeshTools with device discovery & selection
MeshTools is a Rich+Questionary interactive / Typer-scriptable toolkit for
tuning a MeshCore mesh over a serial companion device, with SQLite-logged runs
and Plotly visualizations. Includes the skeleton (trace, info, history),
TX-power optimization, and a MockDevice simulator (--mock).

Device discovery & selection:
- core/discovery.py: enumerate serial ports (pyserial), flag/sort likely LoRa
  hardware by USB vendor id, stable_id for replug-safe identity.
- core/device_store.py: remember the last successfully connected device in
  <config_dir>/devices.json (independent of --db).
- core/selection.py: non-interactive resolver (--port > profile > remembered >
  sole device > guidance error) for the CLI.
- ui/device_picker.py + menu startup: interactive picker preselecting the
  remembered default; banner reflects the choice.
- tools/devices.py: `meshtools devices` lists/marks attached devices.
- AppContext resolves the port and records last-known-good on connect success.

Fixes:
- theme.py: force UTF-8 on stdout/stderr so glyphs don't crash legacy consoles.
- connection.py: friendly message when meshcore is missing; pin meshcore>=2.3.
- trace/tx-optimize: fall back to free-text target entry when the device
  reports no contacts (autocomplete requires non-empty choices).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 17:02:34 -04:00