Implement comprehensive dashboard improvements and maintenance mode

- Storage widget: Restructure with Name/Temp/Wear/Usage columns, SMART details as descriptions
- Host navigation: Only cycle through connected hosts, no disconnected hosts
- Auto-discovery: Skip config files, use predefined CMTEC host list
- Maintenance mode: Suppress notifications during backup via /tmp/cm-maintenance file
- CPU thresholds: Update to warning ≥9.0, critical ≥10.0 for production use
- Agent-dashboard separation: Agent provides descriptions, dashboard displays only
This commit is contained in:
2025-10-13 11:18:23 +02:00
parent bb69f0f31b
commit cd4764596f
5 changed files with 103 additions and 41 deletions

View File

@@ -357,6 +357,8 @@ struct SmartDeviceData {
health_status: String,
capacity_gb: Option<f32>,
used_gb: Option<f32>,
#[serde(default)]
description: Option<Vec<String>>,
}
impl SmartDeviceData {
@@ -389,6 +391,21 @@ impl SmartDeviceData {
})
.unwrap_or_else(|| "UNKNOWN".to_string());
// Build SMART description with key metrics
let mut smart_details = Vec::new();
if available_spare > 0.0 {
smart_details.push(format!("Spare: {}%", available_spare as u32));
}
if power_on_hours > 0 {
smart_details.push(format!("Hours: {}", power_on_hours));
}
let description = if smart_details.is_empty() {
None
} else {
Some(vec![smart_details.join(", ")])
};
Self {
name: device.to_string(),
temperature_c,
@@ -398,6 +415,7 @@ impl SmartDeviceData {
health_status,
capacity_gb: None, // Will be set later by the collector
used_gb: None, // Will be set later by the collector
description,
}
}
}

View File

@@ -1,4 +1,5 @@
use std::collections::HashMap;
use std::path::Path;
use chrono::{DateTime, Utc};
use chrono_tz::Europe::Stockholm;
use lettre::{Message, SmtpTransport, Transport};
@@ -150,11 +151,20 @@ impl NotificationManager {
false
}
fn is_maintenance_mode() -> bool {
Path::new("/tmp/cm-maintenance").exists()
}
pub async fn send_notification(&mut self, change: StatusChange) {
if !self.config.enabled {
return;
}
if Self::is_maintenance_mode() {
info!("Suppressing notification for {}.{} (maintenance mode active)", change.component, change.metric);
return;
}
if self.is_rate_limited(&change) {
warn!("Rate limiting notification for {}.{}", change.component, change.metric);
return;