use crate::device::macos_native::get_native_metrics_manager;
use crate::device::{ChassisInfo, ChassisReader};
use crate::utils::get_hostname;
use chrono::Local;
use std::collections::HashMap;
pub struct AppleSiliconNativeChassisReader {
hostname: String,
}
impl Default for AppleSiliconNativeChassisReader {
fn default() -> Self {
Self::new()
}
}
impl AppleSiliconNativeChassisReader {
pub fn new() -> Self {
Self {
hostname: get_hostname(),
}
}
}
impl ChassisReader for AppleSiliconNativeChassisReader {
fn get_chassis_info(&self) -> Option<ChassisInfo> {
let manager = get_native_metrics_manager()?;
let data = manager.collect_once().ok()?;
let mut detail = HashMap::new();
detail.insert("platform".to_string(), "Apple Silicon".to_string());
detail.insert("api".to_string(), "Native (IOReport/SMC)".to_string());
let validate_power = |mw: f64| -> f64 { (mw / 1000.0).clamp(0.0, 10000.0) };
let cpu_power_watts = validate_power(data.cpu_power_mw);
let gpu_power_watts = validate_power(data.gpu_power_mw);
let ane_power_watts = validate_power(data.ane_power_mw);
detail.insert(
"cpu_power_watts".to_string(),
format!("{cpu_power_watts:.2}"),
);
detail.insert(
"gpu_power_watts".to_string(),
format!("{gpu_power_watts:.2}"),
);
detail.insert(
"ane_power_watts".to_string(),
format!("{ane_power_watts:.2}"),
);
if data.e_cluster_frequency > 0 {
detail.insert(
"e_cluster_freq_mhz".to_string(),
data.e_cluster_frequency.to_string(),
);
}
if data.p_cluster_frequency > 0 {
detail.insert(
"p_cluster_freq_mhz".to_string(),
data.p_cluster_frequency.to_string(),
);
}
let total_power_watts = if data.combined_power_mw > 0.0 {
Some(validate_power(data.combined_power_mw))
} else {
let sum = cpu_power_watts + gpu_power_watts + ane_power_watts;
if sum > 0.0 { Some(sum) } else { None }
};
let hostname = self.hostname.clone();
Some(ChassisInfo {
host_id: hostname.clone(),
hostname: hostname.clone(),
instance: hostname,
total_power_watts,
inlet_temperature: None, outlet_temperature: None, thermal_pressure: data.thermal_pressure_level,
fan_speeds: Vec::new(), psu_status: Vec::new(), detail,
time: Local::now().format("%Y-%m-%d %H:%M:%S").to_string(),
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_apple_silicon_native_chassis_reader_creation() {
let reader = AppleSiliconNativeChassisReader::new();
assert!(!reader.hostname.is_empty());
}
}