mirror of
https://github.com/zvx-echo6/meshai.git
synced 2026-06-11 01:14:45 +02:00
feat: Full alert engine — 17 conditions, scaling cooldown, per-condition TUI toggles
Alert conditions across all 5 pillars: Infrastructure: offline, recovery, new router Power: battery 50/25/10%, 7-day trend, USB→battery, solar not charging Utilization: sustained >20% for 6h, packet flood >500/24h Coverage: infra single gateway, feeder offline, region blackout Scores: mesh <70, region <60 Scaling cooldown: immediate → 12h → 24h → 48h → stop Recovery notifications when conditions resolve Per-condition on/off toggles in TUI Battery trend queries SQLite node_snapshots for 7-day history Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
c8400233bd
commit
736d6a313a
4 changed files with 712 additions and 194 deletions
|
|
@ -187,6 +187,45 @@ class RegionAnchor:
|
|||
cities: list[str] = field(default_factory=list) # e.g., ["Twin Falls", "Burley", "Jerome"]
|
||||
|
||||
|
||||
@dataclass
|
||||
class AlertRulesConfig:
|
||||
"""Per-condition alert toggles and thresholds."""
|
||||
|
||||
# Infrastructure
|
||||
infra_offline: bool = True
|
||||
infra_recovery: bool = True
|
||||
new_router: bool = True
|
||||
|
||||
# Power
|
||||
battery_trend_declining: bool = True
|
||||
battery_warning: bool = True
|
||||
battery_critical: bool = True
|
||||
battery_emergency: bool = True
|
||||
battery_warning_threshold: int = 50
|
||||
battery_critical_threshold: int = 25
|
||||
battery_emergency_threshold: int = 10
|
||||
power_source_change: bool = True
|
||||
solar_not_charging: bool = True
|
||||
|
||||
# Utilization
|
||||
sustained_high_util: bool = True
|
||||
high_util_threshold: float = 20.0
|
||||
high_util_hours: int = 6
|
||||
packet_flood: bool = True
|
||||
packet_flood_threshold: int = 500
|
||||
|
||||
# Coverage
|
||||
infra_single_gateway: bool = True
|
||||
feeder_offline: bool = True
|
||||
region_total_blackout: bool = True
|
||||
|
||||
# Health Scores
|
||||
mesh_score_alert: bool = True
|
||||
mesh_score_threshold: int = 70
|
||||
region_score_alert: bool = True
|
||||
region_score_threshold: int = 60
|
||||
|
||||
|
||||
@dataclass
|
||||
class MeshIntelligenceConfig:
|
||||
"""Mesh intelligence and health scoring settings."""
|
||||
|
|
@ -202,6 +241,7 @@ class MeshIntelligenceConfig:
|
|||
critical_nodes: list[str] = field(default_factory=list) # Short names of critical nodes (e.g., ["MHR", "HPR"])
|
||||
alert_channel: int = -1 # Channel to broadcast alerts on. -1 = disabled, 0+ = channel index
|
||||
alert_cooldown_minutes: int = 30 # Min minutes between repeated alerts for same condition
|
||||
alert_rules: AlertRulesConfig = field(default_factory=AlertRulesConfig)
|
||||
|
||||
|
||||
@dataclass
|
||||
|
|
@ -272,6 +312,9 @@ def _dict_to_dataclass(cls, data: dict):
|
|||
if isinstance(item, dict) else item
|
||||
for item in value
|
||||
]
|
||||
# Handle AlertRulesConfig
|
||||
elif key == "alert_rules" and isinstance(value, dict):
|
||||
kwargs[key] = _dict_to_dataclass(AlertRulesConfig, value)
|
||||
else:
|
||||
kwargs[key] = value
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue