Commit Graph
195 Commits
Author SHA1 Message Date
Nic Jansma 0c81dbe073 Add MESHCORE_TELEMETRY_POLL_24H_EXEMPT cooldown exemption for contact telemetry (#905) 2026-09-07 08:18:52 +02:00
l5y 3d89366e89 docs: trim operator docs to instructions, close doc/behavior drift (#904)
* docs: trim operator docs to instructions, close doc/behavior drift

* docs: strip em-dashes and bold from operator docs; trim changelog
2026-09-06 13:04:20 +02:00
l5y 39e5d01d26 data,web: Reticulum finalization — radio metadata, chat tags, federation zeros (#900)
* data,web: Reticulum finalization — radio metadata, chat tags, federation zeros

* web: purge destinations with their nodes
2026-08-31 12:01:36 +02:00
l5y d61cca93c0 web: reticulum aspects, identity groups, identity page, honest detail views (#899)
* web: reticulum aspects, identity groups, identity page, honest detail views

* web,data: fix staging findings, naming, row controls, transport gate

* web,data: fix Reticulum naming, row controls, and the transport gate

* web,data: fix Reticulum naming, row controls, and the transport gate

* web: cover the identity-group wiring and destination fetchers
2026-08-29 17:13:35 +02:00
l5y 96e0dbfd05 data,web: key Reticulum nodes on identity; discover host aspects (#897)
* data,web: key Reticulum nodes on destinations; fix e2e field findings (#888)

* data,web: key Reticulum nodes on identity; discover host aspects

* data,web: restore announced names and interfaces on host destinations

* data,web,docs: fix review findings on identity-keyed Reticulum nodes
2026-08-28 21:11:31 +02:00
Edwin Knuth dc0679234f data: derive the Reticulum ingestor's own node id; scope CONNECTION out (#888) (#896)
Answers the two questions left open on #888 after #893.

INGESTOR_NODE_ID was required for PROTOCOL=reticulum because a passive
announce listener has no handshake revealing "our" node id. The premise
holds; the conclusion did not follow. The ingestor now owns an RNS
identity, generated on first run and stored 0600 as potato_mesh_identity
inside the app-owned RETICULUM_CONFIG_DIR, and derives its !xxxxxxxx
through the same identity-hash mapping applied to every peer, so its own
row is shaped like any other Reticulum row. A plain PROTOCOL=reticulum
deployment brings up the heartbeat, and so the reticulum packets/hour
scope, unaided; the variable still overrides, which also means no key is
generated for a deployment that does not need one. The identity is local
and never announced, so nothing new transmits. Persist-or-nothing is
deliberate: an unstorable identity would be regenerated per start and
each generation is a different node id, filing one orphan ingestor row
per restart, so the provider reports no id and warns instead. An existing
but unreadable key file is never overwritten. The startup warning #890
emitted for an unset INGESTOR_NODE_ID is removed.

CONNECTION and RETICULUM_CONFIG_DIR/RETICULUM_INTERFACES are disjoint
rather than in conflict: CONNECTION names one serial, TCP, or BLE
endpoint and an RNS stack has no such thing, which is why connect() has
always ignored it. What was wrong was the silence, since the image sets a
serial default for every protocol. connect() now says once at info that
the value is dropped and names the two variables that do apply. The image
default stays: removing it would change how meshtastic and meshcore
containers resolve their port, and a Reticulum follow-up is the wrong
change to carry that.

SPEC RN9/RN10, ACCEPTANCE RN-A9/RN-A10; CONTRACTS, README and
.env.example reconciled. 100% line and branch coverage on the provider;
pytest 1442 passed, rspec 1717 examples 0 failures.
2026-08-28 10:16:56 +02:00
l5y 5294261892 web: add reticulum frontend support (#894)
* web: add reticulum frontend support

* docs: update readme

* web: address ui review comments
2026-08-27 12:15:05 +02:00
l5y 4b586316ae fix reticulum protocol loose ends from #888 review (#893)
* fix reticulum protocol loose ends from #888 review

* data: fix quoted Compose defaults blacking out every channel

* data,web: fix four defects found reviewing this PR
2026-08-27 08:04:08 +02:00
Edwin Knuthandoregonknuths a25140ee57 Add Reticulum announce ingestor provider (#888) (#890)
Co-authored-by: oregonknuths <159513803+oregonknuths@users.noreply.github.com>
2026-08-24 21:41:16 +02:00
Edwin Knuthandoregonknuths ace03b6807 Add Reticulum protocol support to the web tier (#888) (#889)
Co-authored-by: oregonknuths <159513803+oregonknuths@users.noreply.github.com>
2026-08-24 21:34:39 +02:00
l5y 40dfa14dfa chore: release 0.7.5 (#892)
* chore: release 0.7.5

* app: raise iOS deployment target to 15.0; stop mobile CI failing fast
2026-08-24 19:48:29 +02:00
l5y 24a9226df4 data: gate every ingestor transmission behind TX_ENABLED/TX_ANNOUNCE (#891) 2026-08-24 17:18:19 +02:00
seybsen 376320b2e2 Make the activity announcement opt-in via ANNOUNCE (default off) (#886)
The periodic activity announcement was gated only by RX_ONLY, which
defaults to off, so a stock ingestor deployed to feed a map starts
broadcasting on its community's default channel without the operator
having chosen to. The only opt-out, RX_ONLY=1, also silences the
MeshCore telemetry polls, so "ingest but stay quiet" was not expressible.

Add an ANNOUNCE boolean (default 0) as an opt-in gate on top of RX_ONLY,
which keeps its meaning as the global TX kill switch and overrides
ANNOUNCE=1. Amend SPEC MA7 (which had explicitly ruled out a separate
enable env) and MA-A7 with the reasoning, document both flags in the
README env table — the RX_ONLY row did not mention the announcement at
all — and add gate unit tests for all four combinations plus the
missing-attribute fail-closed path.
2026-08-24 12:29:04 +02:00
l5y a676a2997e data,web: Meshtastic waypoints as a first-class POI layer (#874)
* data,web: Meshtastic waypoints as a first-class POI layer

* web: re-roll waypoint UI to signed-off variants + node-page section

* web: reconcile stats-pushdown plan spec with the five-table W9 umbrella

* web: legend waypoint sample follows the 1c-B teardrop marker
2026-07-29 18:22:08 +02:00
l5y 5d2790bb48 data: harden MeshCore subscribe against unknown EventType (#867) 2026-07-28 12:55:55 +02:00
l5y e0b9c22fab chore: bump version to 0.7.4 (#863) 2026-07-27 17:06:12 +02:00
l5y cd771c4eea data: count every MeshCore RX-log frame; stamp position radio metadata (#861) 2026-07-27 11:21:16 +02:00
l5y 207150f235 web: mesh activity map card (#860)
* data,web: /api/stats packets rate as <scope>.packets.hour

* data,web: /api/stats packets as <scope>.packets.hour; total sums protocols

* web: mesh activity map card - packets/h total + per-protocol split

* web: /api/stats/activity bucketed packets/hour time-series

* web: mesh activity card draws the real 24h sparkline

* web: /charts mesh-activity figure, mobile card strip, legend-toggle fix

* web: mesh-activity design-review remediation

* web: /api/stats total sums rounded per-protocol rates + doc fixes
2026-07-26 20:59:26 +02:00
l5y b52f3949e4 data,web: mesh activity reporting & announcements (#859) 2026-07-26 09:09:28 +02:00
l5y 8d25dd42cd fix(docker): bump ingestor base to python 3.12.10 for cryptography's Rust MSRV (#858) 2026-07-25 19:34:22 +02:00
l5y b013faf13d web,data: reconcile MeshCore stale same-name node duplicates (#857)
* web,data: reconcile MeshCore stale same-name node duplicates

* data: MeshCore roster sync must not warm last_heard
2026-07-24 23:25:48 +02:00
l5y 3878597c8d data,web: ingest every telemetry family from both protocols (#850)
* data,web: ingest every telemetry family from both protocols

* data: 24h per-node telemetry poll cooldown; RX_ONLY ingestor switch
2026-07-23 11:51:30 +02:00
l5y 22c470d9e6 data: meshcore rf metrics rssi/snr/hops/path (#849) 2026-07-22 21:41:57 +02:00
l5y 0cd2b2c4d4 Bump all packages to 0.7.3 (#845)
* Bump all packages to 0.7.3

* ci: disable Flutter mobile release workflow
2026-07-18 12:11:49 +02:00
l5y ea5560f9aa fix(docker): armv7 ingestor build toolchain; disable matrix fail-fast (#842) 2026-07-07 19:42:33 +02:00
l5y 211ae52d55 web: fix MeshCore ghost nodes (stale contact enrichment discarded) (#841)
* web: fix MeshCore ghost nodes (stale contact enrichment discarded)

* web: guard short_name gap-fill against empty strings; codify Known gaps
2026-07-06 09:27:36 +02:00
l5y 2479a6554f fix: UDP-transport hardening, bridge tracker coverage, CI repairs; release 0.7.2 (#840)
* fix: UDP-transport hardening, bridge tracker coverage, CI repairs; release 0.7.2

* fix: UDP-transport hardening, bridge tracker coverage, CI repairs; release 0.7.2
2026-07-06 00:30:52 +02:00
TJ PaulsonandClaude Opus 4.8 1b934ee6f7 feat(ingestor): passive UDP transport (Mesh via UDP), primary-channel only (#838)
Adds an optional passive UDP transport (TRANSPORT=udp) that reads the node's
"Mesh via UDP" LAN multicast instead of holding the radio's single API/serial
slot, filters to the PRIMARY channel by channel-hash (fail-closed), decrypts
with the default PSK, and enriches payloads to match the API-path packet shape
so the collector receives identical records. Implemented as a MeshProtocol
provider; 100% unit coverage on new modules; real-capture fixtures included
(node IDs/GPS anonymized). See PR description for details.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 22:24:26 +02:00
l5y 6d9d524e09 improve log wiring and capture all meshcore adverts (#836)
* data: fix meshcore adverts gap and capture adv from other nodes

* web: improve log wiring
2026-06-30 12:57:04 +02:00
l5y bc6d0187cc web: fix MeshCore chat duplicates and warm-cache message gap (#834) 2026-06-29 20:59:30 +02:00
l5y 266f8ff8bd chore: bump version 0.7.1 (#833) 2026-06-29 14:45:37 +02:00
l5y 1804a8a75e web: add visual feedback to pubsub events (#824) 2026-06-24 20:34:35 +02:00
l5y 8083206210 web: implement pubsub (#821) 2026-06-24 17:35:33 +02:00
l5y f5f9298746 web: add pagination to all APIs (#820) 2026-06-24 13:02:50 +02:00
l5y 7eccbfb89a fix: unify Meshtastic custom LoRa label with MeshCore format (#818) 2026-06-23 21:58:18 +02:00
l5y 3790686ab2 web: version JS/CSS assets to bust stale browser caches (#815) 2026-06-23 21:23:35 +02:00
George c8668a730c fix: report custom LoRa config as "Custom SF{sf}/BW{bw}/CR{cr}" when use_preset=False (#811) (#812) 2026-06-23 19:46:30 +02:00
l5y af64b2c60f web: fix apis to use consistently use camel case (#802) 2026-06-21 20:17:40 +02:00
l5y 5e0363a0ec web: breaking change on stats api (#801)
* web: breaking change on stats api

* address review comments
2026-06-21 13:41:41 +02:00
l5y 512b4f157b Fix regression where Meshcore chat senders show as Meshtastic (#794)
* Fix regression where Meshcore chat senders show as Meshtastic

* Address review feedback for protocol misclassification fix

- ingest.rb: exclude wrapper ``protocol`` key from /api/nodes batch-limit
  count so the documented 1000-node maximum still applies after the
  Python ingestor started stamping protocol at the wrapper level.
- Drop plan-file references from production and test comments per the
  repo guidelines; the why is already explained inline.

* Address protocol-fallback review feedback

- Neighbor placeholder now inherits the source node's protocol from the
  surrounding /api/neighbors entry, so the badge tracks the radio the
  peer lives on instead of collapsing to the neutral "Unknown" label
  (review item #1).
- resolve_record_protocol logs one warn_log line when an explicit
  protocol stamp is rejected as malformed, making misbehaving custom
  protocol adapters visible in the operator log instead of silently
  falling back (review item #3).

* Extract buildNodePlaceholder helper for testability

The neighbor placeholder logic in main.js lives inside an untested
closure, so codecov reported the protocol-propagation lines as
uncovered.  Extract the small placeholder builder into long-link-router
so it can be unit tested directly; the closure-internal call site stays
trivial (one factory call + one fallback call).
2026-05-24 09:49:45 +02:00
l5y 8a89185fbe fix sentinel position data (#792)
* fix sentinel position data

* address review comments
2026-05-18 21:27:47 +02:00
l5y b187ba2066 data: move connected event to after ensure_contacts (#789)
* data: move connected event to after ensure_contacts

* data: address review comments
2026-05-18 08:57:08 +02:00
l5y c32da2c541 chore: bump to 0.6.4 (#785) 2026-05-03 17:01:28 +02:00
l5y 73e161f432 web: fix liveliness of api data hydration bug (#783)
* web: fix liveliness of api data hydration bug

* web: address review comments
2026-05-03 13:05:37 +02:00
l5y 1041e06644 data: refactor 4/7 interfaces (#775)
* data: refactor 4/7 interfaces

* data: address PR #775 review feedback

Fix the two CI test regressions caused by the package split:
- ``factory._load_ble_interface`` no longer keeps a stale module-level
  ``BLEInterface`` cache that survived ``monkeypatch`` teardown across
  tests. The package-level attribute is now the single cache; the
  ``factory.py`` global was removed.  This unblocks
  ``test_load_ble_interface_sets_global``.
- ``interfaces/__init__.py`` re-resolves ``SerialInterface`` and
  ``TCPInterface`` from ``meshtastic.*`` at package-load time so that a
  test that pops ``data.mesh_ingestor.interfaces`` from ``sys.modules``
  and re-imports picks up the freshly registered classes rather than
  whatever a cached ``factory.py`` first resolved.  This unblocks
  ``test_interfaces_patch_handles_preimported_serial``.

Restore 100% patch coverage on the interfaces subpackage by:
- Adding tests for previously uncovered, testable paths:
  ``_extract_host_node_id(None)``, ``_ensure_channel_metadata``,
  ``_normalise_nodeinfo_packet`` (None input + dict-conversion fallback),
  ``_resolve_lora_message`` (radio_section paths), ``_modem_preset``
  (preset attr fallback + unparseable value), ``_camelcase_enum_name``
  separator-only input, ``_region_frequency`` no-digit enum name,
  ``_ensure_radio_metadata`` unresolvable-message path, plus the
  unknown-section recursive branch of ``_candidate_node_id``.
- Marking genuinely unreachable defensive branches with
  ``pragma: no cover`` (BLE receive loop body, upstream API regression
  guards, patch re-entry guard, unreachable ``NoAvailableMeshInterface``
  fallback).
2026-05-02 22:59:52 +02:00
l5y f6aff3bdb8 data: refactor 3/7 protocols (#774)
* data: refactor 3/7 protocols

* data: address PR #774 review feedback

- Rewrite the parents[4] path comment in protocols/meshcore/debug_log.py
  to clearly explain why the index changed from parents[3] (the original
  pre-split index) without contradicting the code.
- Add tests covering the six lines flagged uncovered by codecov:
  * _process_self_info host-position branch (handlers.py:78)
  * on_contact_msg early-return for missing text/sender_ts (handlers.py:278)
  * close() RuntimeError swallow when loop closes mid-call (interface.py:155-156)
  * _run_meshcore wrapper around _ensure_channel_names failure (runner.py:131-132)

Restores 100% patch coverage on the meshcore package.
2026-05-02 22:05:43 +02:00
l5y 09d9e7be13 chore: bump version to 0.6.3 (#779)
* chore: bump version to 0.6.3

* chore: bump version to 0.6.3
2026-04-29 22:06:29 +02:00
l5yandClaude Opus 4.7 161f22bf12 chore: bump version to 0.6.2 (#763)
Backfill v0.6.1 CHANGELOG entry (previously undocumented),
add v0.6.2 entry covering 9 commits since v0.6.1, and bump
the version string across data, web, matrix, and app along
with the README docker-pull examples.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 19:02:26 +02:00
l5y 491678f75b data: catch packet handler errors (#759)
* data: catch packet handler errors

* data: address review comments

* data: address review comments
2026-04-21 11:41:44 +02:00
l5y db236d58e2 web: fix meshcore message duplication with 120s dupe protection (#758)
* web: fix meshcore message duplication with 120s dupe protection

* web: fix meshcore message duplication with 120s dupe protection

* web: address review comments

* web: address review comments
2026-04-21 10:13:39 +02:00