fix: notification system improvements and threshold corrections

- Fix leftover severity references (info→routine in filter dropdown)
- Fix node_id int handling in connector and channels (handle both int and string)
- Add LLM-generated reports for notifications (replace raw data dumps)
- Fix health.score.composite attribute path for RF reports
- Add deterministic HF band conditions from SFI/Kp values
- Remove max_tokens from LLM calls (character limits at delivery)
- Weather feed improvements: show event_type + area, local events first
- Fix is_online to use configured offline_threshold_hours in data store
- Update stale defaults: offline 24→2h, battery_warning 20→30%
- Add TODO comments for packet_threshold scale bug

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
K7ZVX 2026-05-14 06:02:08 +00:00
commit 95ec7d5351
13 changed files with 1145 additions and 1133 deletions

View file

@ -119,18 +119,18 @@ mesh_sources: []
# enabled: true
# region_radius_miles: 40.0 # Radius for region clustering
# locality_radius_miles: 8.0 # Radius for locality clustering
# offline_threshold_hours: 24 # Hours before node considered offline
# offline_threshold_hours: 2 # Hours before node considered offline
# packet_threshold: 500 # Non-text packets per 24h to flag
# battery_warning_percent: 20 # Battery level for warnings
# battery_warning_percent: 30 # Battery level for warnings
# infra_overrides: [] # Node IDs to exclude from infrastructure
# region_labels: {} # Override auto-names: {"Twin Falls": "Magic Valley"}
mesh_intelligence:
enabled: false
region_radius_miles: 40.0
locality_radius_miles: 8.0
offline_threshold_hours: 24
offline_threshold_hours: 2
packet_threshold: 500
battery_warning_percent: 20
battery_warning_percent: 30
infra_overrides: []
region_labels: {}

View file

@ -284,6 +284,7 @@ class MeshIntelligenceConfig:
locality_radius_miles: float = 8.0 # Radius for locality clustering within regions
offline_threshold_hours: int = 2 # Hours before node considered offline
packet_threshold: int = 500 # Non-text packets per 24h to flag
# TODO: behavior pillar uses wrong scale - see meshai-v03-notification-handoff.md bug #2
battery_warning_percent: int = 30 # Battery level for warnings
# Alert settings

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -8,8 +8,8 @@
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
<script type="module" crossorigin src="/assets/index-BXyt_EfK.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-CtFYHJy4.css">
<script type="module" crossorigin src="/assets/index-Bildyb1E.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-QhNRb-ap.css">
</head>
<body>
<div id="root"></div>

View file

@ -2116,7 +2116,7 @@ class MeshDataStore:
infra_roles = {"ROUTER", "ROUTER_CLIENT", "ROUTER_LATE", "REPEATER"}
return [n for n in self._nodes.values() if n.role in infra_roles]
def get_low_battery_nodes(self, threshold: float = 20.0) -> list[UnifiedNode]:
def get_low_battery_nodes(self, threshold: float = 30.0) -> list[UnifiedNode]:
"""Get nodes with low battery."""
return [
n

View file

@ -28,6 +28,7 @@ INFRASTRUCTURE_ROLES = {"ROUTER", "ROUTER_LATE", "ROUTER_CLIENT"}
DEFAULT_LOCALITY_RADIUS_MILES = 8.0
DEFAULT_OFFLINE_THRESHOLD_HOURS = 2 # Hours before node considered offline
DEFAULT_PACKET_THRESHOLD = 7200 # Non-text packets per 24h (5/min avg)
# TODO: behavior pillar uses wrong scale - see meshai-v03-notification-handoff.md bug #2
# NOTE: This is aligned with notification config's packet_flood threshold.
# 5 packets/min avg × 60 min × 24 hr = 7,200 packets/day.
# A node averaging 5+ non-text packets/min is misbehaving.

View file

@ -630,7 +630,7 @@ class MeshReporter:
usb += 1
elif node.battery_percent >= 50:
ok += 1
elif node.battery_percent >= 20:
elif node.battery_percent >= 30:
low += 1
else:
critical += 1