Commit graph

13 commits

Author SHA1 Message Date
de400068dd feat(mesh): config-driven regions with stale purge and coverage fix
- Extended RegionAnchor with local_name, description, aliases, cities
- Moved region geographic context from hardcoded Python to config.yaml
- Added 7-day stale node purge in _do_refresh (556 → 267 nodes)
- Fixed coverage lookup: str(node_num) → node_num (int key)
- Added bidirectional neighbor lookup for better region assignment
- Dynamic geography building in router from config
- Reporter reads region context from config instead of hardcoded dict

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-05 06:33:38 +00:00
4183abe755 refactor: DELETE NodeHealth — reporter uses UnifiedNode directly
NodeHealth is gone. MeshHealth.nodes is now dict[int, UnifiedNode].
Reporter reads all fields from UnifiedNode: coverage, environment,
neighbors, hw_model — everything available without cross-referencing.
This eliminates the entire category of field missing on NodeHealth bugs.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-05 05:12:45 +00:00
a384fd7a20 Implement 5-pillar health scoring with coverage
- Update HealthScore with coverage pillar (20% weight)
- Adjust weights: Infra 30%, Util 25%, Coverage 20%, Behavior 15%, Power 10%
- Add coverage metrics: avg_gateways, single_gw_count, full_count
- Add health score fields to UnifiedNode for direct sync
- compute() now syncs scores back to UnifiedNode objects
- Coverage scoring penalizes single-gateway nodes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-05 04:59:41 +00:00
d8189e2e4d fix: Add hw_model and missing fields to NodeHealth
- hw_model, neighbor_count, packets_sent_24h fields
- node_id_hex, battery_trend, packets_by_type, predicted_depletion_hours properties
- Populate hw_model from node data when creating NodeHealth
- Fixes reporter crash on node detail view
2026-05-05 04:26:52 +00:00
e9ddfa7e26 fix: Add node_num property to NodeHealth class
NodeHealth stored node_id as hex string but mesh_reporter.py
expected node_num integer. Added computed property to convert.
2026-05-05 04:16:00 +00:00
8c3b6a1f09 fix: Fundamental ID matching — packets, telemetry, and utilization now work
Root cause: health engine keyed nodes by database row IDs instead of
Meshtastic node numbers. Packets and telemetry could never match.

Fixed:
- Store _node_num on all normalized nodes (mesh_sources.py)
- Key health engine node dict by _node_num (mesh_health.py)
- Fix packet field names: from_node not from/fromId
- Fix telemetry parsing: handle telemetryType/value structure
- Increase packet/telemetry fetch limits for 24h coverage
- Fix utilization formula to compute actual airtime percentage
2026-05-04 21:47:18 +00:00
3959444a09 feat: Complete data pipeline — utilization, behavior, power, solar, traceroutes all wired 2026-05-04 21:22:30 +00:00
df197cc395 fix: Scope detection, follow-up context, utilization calculation, duplicate disambiguation
- router.py: Fixed region scope detection to match longest region name first
- router.py: Added region abbreviations (SCID, SWID, etc.) for quick matching
- router.py: Added city name mapping (Boise -> South Western ID, etc.)
- router.py: Fixed node longname matching (case-insensitive substring)
- router.py: Added follow-up message context tracking (_user_mesh_context)
- router.py: Added more mesh keywords (noisy, traffic, packets, etc.)
- mesh_reporter.py: Added disambiguation for duplicate shortnames in region detail
- mesh_health.py: Added util_data_available flag to track packet data presence
- mesh_health.py: Passes has_packet_data through score computation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-04 20:56:54 +00:00
44c74ccfd4 feat: Phase 3 - LLM mesh health integration, recommendations, and health commands
New files:
- mesh_reporter.py: MeshReporter class for prompt injection
  - build_tier1_summary(): ~500-800 token mesh health summary
  - build_region_detail(): Detailed region breakdown
  - build_node_detail(): Single node info with recommendations
  - build_recommendations(): Optimization suggestions
  - build_lora_compact(): Short format for LoRa messages
  - list_regions_compact(): Region list with scores

- commands/health.py: !health and !region commands
  - !health: Quick mesh summary (no LLM)
  - !region [name]: Region info or list all regions

Modified files:
- router.py: Mesh question detection and prompt injection
  - _is_mesh_question(): Keyword/phrase matching
  - _detect_mesh_scope(): Node/region/mesh scope detection
  - Inject Tier 1/2 data for mesh questions
  - Add mesh awareness instructions to LLM

- main.py: Create MeshReporter, pass to dispatcher/router

- commands/dispatcher.py: Register health/region commands

- mesh_health.py: Fix role type (int -> str)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-04 19:19:42 +00:00
584616c8a5 feat: Infer node region from neighbors
Nodes without GPS can be assigned to a region based on their
neighbors. Uses edge data to build neighbor graph, then assigns
unlocated nodes to the most common region among their neighbors.
Iterates until no more assignments possible.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-04 17:38:57 +00:00
c3f1347b4b refactor: Replace auto-clustering with fixed region anchors
- Regions are now user-defined anchor points (name + lat/lon)
- Nodes assigned to nearest region, no distance limits
- Removed auto-naming and region_labels/infra_overrides
- Added Idaho region defaults in TUI
- Simpler, deterministic, user-controlled

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-04 17:35:28 +00:00
fe2b77097b fix: Handle Meshview GPS and timestamp formats
- last_lat/last_long are scaled integers (divide by 1e7)
- last_seen_us is in microseconds (divide by 1e6)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-04 17:21:51 +00:00
a7c409e406 feat: Add Phase 2 - Geographic Hierarchy and Health Scoring
Implements mesh intelligence with geo clustering, four-pillar health scoring,
and auto-naming regions from GPS data.

New: geo.py, mesh_health.py
Modified: config.py, main.py, router.py, configurator.py, config.example.yaml

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-04 16:43:12 +00:00