Commit Graph
12 Commits
Author SHA1 Message Date
Treehouse-00 b526343981 feat(api): summarise neighbor link history in buckets 2026-09-07 21:29:48 +01:00
Treehouse-00 4d8f8d41bd feat(plugins): stream an install or update's progress over server-sent events 2026-09-07 21:29:48 +01:00
Treehouse-00 89d8a9813f perf(web): send the frontend compressed and cacheable 2026-09-07 21:29:48 +01:00
dmduran12andOz 7a0aec7b60 feat(presets): expose bundled broker presets via GET /api/broker_presets
Adds a new read-only endpoint that serves the bundled `repeater/presets/*.yaml`
catalogue so the admin UI can render a network picker without bundling its own
copy of the broker dicts. The UI side of this is paired with
pyMC-dev/pyMC-RepeaterUI#TBD which retires src/assets/broker-templates.json
in favour of authClient.get('/api/broker_presets').

Why
The UI previously shipped a separate JSON snapshot of every supported MC2MQTT
network. The JSON and these YAML files drifted: the Waev entry on the UI side
pointed at mqtt-a.waev.app with audience mqtt.waev.app (single primary, no
failover) while the YAML side here listed two brokers (A + B). The result was
that operators picking 'Waev' from the dropdown silently lost the redundancy
this preset is meant to provide.

What changes

repeater/presets/*.yaml
- Add optional top-level `display_name` and `website` fields. The loader
  treats them as advisory metadata for the UI; the runtime connection code
  never reads them. `display_name` falls back to the titlecased filename
  stem if absent so existing third-party presets keep rendering.

repeater/presets/waev.yaml
- Collapse from two broker entries (waev-a, waev-b) to a single broker on
  `mqtt.waev.app`. The Waev edge Worker (see waev/src/router.ts:
  MQTT_PRIMARY_FAILOVER_TIMEOUT_MS) already does server-side A/B failover on
  the alias host with a 1500 ms timeout. Two independent client connections
  would defeat the dedup-on-pubkey-hash contract on the waev ingest side.
  Operators who want to pin to a specific container can edit host/audience
  after import.

repeater/presets/meshmapper.yaml (new)
- Port of the historical MeshMapper entry from the UI's deprecated JSON.
  Single broker on mqtt.meshmapper.cc, format: letsmesh (matches the
  published wire contract; bump to a dedicated value if/when wire-level
  differentiation lands).

repeater/web/api_endpoints.py
- New `broker_presets` CherryPy handler at `GET /api/broker_presets`.
  Unauthenticated to match the existing `mqtt_status` precedent — the
  response carries only public hostnames + TLS hints, no PII. Imports the
  presets module lazily so a broken YAML never blocks process startup.
  Response shape:
    {
      success: true,
      data: [{ id, name, website?, brokers: [ ... raw YAML dicts ... ] }, …]
    }

tests/test_presets.py
- Locks the new metadata fields (display_name, website) on all three presets.
- Locks the Waev single-alias-broker design with an explicit comment tying
  the test to the waev Worker failover code.
- Adds MeshMapper coverage parallel to the other public-network presets.
- Adds a stub-instance test that drives the new `broker_presets` method on
  an APIEndpoints stand-in (bypassing the heavyweight `__init__`) and
  asserts the UI-ready response shape.

Verification
- New endpoint serves the expected three presets (letsmesh: 2 brokers,
  meshmapper: 1, waev: 1) when exercised end-to-end against a local mock
  that imports the real preset loader.
- Existing legacy-config migration tests (broker_index 0/1/-1 → preset +
  overrides) still pass — the override pipeline is untouched.

Co-Authored-By: Oz <oz-agent@warp.dev>
2026-05-14 15:14:10 -07:00
Treehouse⚡️ d5903c372b Add Southern California radio preset 2026-05-13 10:44:20 -07:00
dmduran12andOz 4ee2977236 feat: add /ws/companion_frame WebSocket proxy
Bridges browser WebSocket connections to companion TCP frame servers.
Uses configured bind_address (not hardcoded 127.0.0.1) so the proxy
works regardless of how the frame server is bound.

- JWT auth (same pattern as PacketWebSocket)
- Resolves companion by name → (host, port) from config
- Raw byte pipe: WS ↔ TCP, no protocol parsing
- Diagnostic logging throughout for troubleshooting

Co-Authored-By: Oz <oz-agent@warp.dev>
2026-03-13 08:52:08 -07:00
dmduran12andOz 2b4012eeb6 feat: add /ws/companion_frame WebSocket proxy
Dumb byte pipe between browser WebSocket and companion TCP frame server.
Allows browser clients to speak the MeshCore companion frame protocol
directly — all parsing lives client-side.

New file: repeater/web/companion_ws_proxy.py
- ws4py handler with JWT auth (same pattern as PacketWebSocket)
- Resolves companion_name → TCP port from config
- Bidirectional byte forwarding: WS ↔ TCP

http_server.py: mount at /ws/companion_frame alongside /ws/packets

Co-Authored-By: Oz <oz-agent@warp.dev>
2026-03-12 17:50:20 -07:00
dmduran12andWarp d28a966e2e Enable gzip compression for bulk_packets endpoint
Reduces payload size for large packet downloads, improving performance
on slow network connections.

Co-Authored-By: Warp <agent@warp.dev>
2026-02-03 11:35:02 -08:00
dmduran12andWarp 047b983497 Add timestamp filtering to bulk_packets endpoint
Add start_timestamp and end_timestamp parameters to the bulk_packets API
endpoint to allow time-range filtering for bulk packet retrieval.

Co-Authored-By: Warp <agent@warp.dev>
2026-02-03 11:03:05 -08:00
dmduran12andWarp 64100d6311 fix: use correct Semtech LoRa airtime formula
Replace simplified airtime calculation with the proper Semtech reference
formula that accounts for:
- Coding rate (CR)
- CRC overhead
- Explicit/implicit header mode
- Low data rate optimization (SF11/SF12 at 125kHz)

The previous formula significantly underestimated airtime, especially
at higher spreading factors, leading to inaccurate duty cycle tracking.

Reference: https://www.semtech.com/design-support/lora-calculator

Co-Authored-By: Warp <agent@warp.dev>
2026-01-18 17:16:21 -08:00
dmduran12andWarp 2ab4a62011 feat(api): Add POST /api/update_radio_config endpoint
Adds a new endpoint to update radio and repeater configuration via HTTP API,
supporting both persisted storage and live in-memory updates.

Supported settings:
- Radio: tx_power (2-30 dBm)
- Delays: tx_delay_factor, direct_tx_delay_factor, rx_delay_base
- Repeater: node_name, latitude, longitude, max_flood_hops,
  flood_advert_interval_hours, advert_interval_minutes

Features:
- Validates all input parameters with appropriate ranges
- Saves to config.yaml for persistence
- Updates daemon's in-memory config for immediate effect (no restart needed)
- Returns live_update status so clients know if restart is required

This enables web dashboards like pyMC Console to configure the repeater
without requiring SSH access or service restarts for most settings.

Co-Authored-By: Warp <agent@warp.dev>
2025-12-27 19:47:49 -08:00
dmduran12andWarp e74e062fe5 feat(api): Expose additional config values in /api/stats
Adds the following fields to the stats API response for MeshCore CLI parity:

- config.repeater.max_flood_hops: Max flood hops setting (for 'get flood.max')
- config.repeater.advert_interval_minutes: Local advert interval (for 'get advert.interval')
- config.delays.rx_delay_base: RX delay base setting (for 'get rxdelay')

These fields are already present in config.yaml but were not exposed via the
stats API, making them inaccessible to web dashboards and CLI tools that
communicate over HTTP.

This enables pyMC Console's Terminal to display these values without
requiring direct config file access.

Co-Authored-By: Warp <agent@warp.dev>
2025-12-27 19:46:29 -08:00