feat(dashboard): MeshCore transport + per-family routing GUI controls (#10)

* feat(dashboard): MeshCore transport + per-family routing GUI controls

Add Transport mode selector (Meshtastic/MeshCore/Both) and MeshCore
host/port fields to the Config Connection section, and an independent
per-family "MeshCore channel" number input in Notifications (blank = not
broadcast on MeshCore, sends null). Extends the ConnectionConfig and
per-family toggle TS types.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(routing): MeshCore routing by channel name, not index

MeshCore channels are {name,PSK} (up to 40+ slots, not Meshtastic's 0-7).
The send index is a fragile slot position, so store the channel NAME per
family and resolve name->slot against the companion's live channel table
at send time; never blind-send to an unresolved slot. GUI field becomes a
channel-name text box. meshtastic path unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(routing): thread per-family meshcore_channel through the broadcast send path

MeshBroadcastChannel now carries the rule's meshcore_channel name and
passes it to send_message, so per-family MeshCore routing actually fires
end-to-end (dispatcher -> channel -> composite -> MeshCoreTransport).
Meshtastic path unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Matt Johnson <mj@k7zvx.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
malice 2026-07-02 16:49:59 -06:00 committed by GitHub
commit 24cb6a31df
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 358 additions and 45 deletions

View file

@ -102,7 +102,6 @@ def _mc_config(**overrides):
transport="meshcore",
meshcore_host="127.0.0.1",
meshcore_port=5050,
meshcore_channel_index=0,
)
for k, v in overrides.items():
setattr(cfg, k, v)
@ -178,7 +177,6 @@ class TestTransportMaxChars:
tcp_port=4403,
meshcore_host="127.0.0.1",
meshcore_port=5050,
meshcore_channel_index=0,
)
comp = build_transport(cfg_both)
assert isinstance(comp, CompositeTransport)