use std::{ collections::HashMap, time::Duration, }; use pscand_core::{ helpers::PowerHelper, scanner::{ MetricValue, Scanner, }, }; struct PowerScanner; #[no_mangle] pub extern fn pscand_scanner() -> *mut std::os::raw::c_void { Box::into_raw(Box::new(PowerScanner)) as *mut std::os::raw::c_void } impl Default for PowerScanner { fn default() -> Self { Self } } impl Scanner for PowerScanner { fn name(&self) -> &'static str { "power" } fn interval(&self) -> Duration { Duration::from_secs(2) } fn init(&mut self, _config: &toml::Value) -> pscand_core::Result<()> { Ok(()) } fn collect(&self) -> pscand_core::Result> { let mut metrics = HashMap::new(); if let Ok(Some(battery)) = PowerHelper::battery_info() { metrics.insert( "battery_present".to_string(), MetricValue::from_bool(battery.present), ); metrics.insert( "battery_charge_percent".to_string(), MetricValue::Integer(battery.charge_percent as i64), ); metrics.insert( "battery_voltage_v".to_string(), MetricValue::from_f64(battery.voltage), ); metrics.insert( "battery_power_now_mw".to_string(), MetricValue::Integer(battery.power_now), ); metrics.insert( "battery_status".to_string(), MetricValue::from_string(&battery.status), ); } if let Ok(supplies) = PowerHelper::power_supplies() { for (name, info) in supplies { if let Some(status) = info.get("status") { metrics.insert( format!("supply_{}_status", name), MetricValue::from_string(status), ); } if let Some(online) = info.get("online") { metrics.insert( format!("supply_{}_online", name), MetricValue::from_bool(online == "1"), ); } if let Some(capacity) = info.get("capacity") { if let Ok(cap) = capacity.parse::() { metrics.insert( format!("supply_{}_capacity", name), MetricValue::Integer(cap as i64), ); } } } } if let Ok(state) = PowerHelper::suspend_state() { metrics.insert( "suspend_state".to_string(), MetricValue::from_string(&state), ); } Ok(metrics) } fn cleanup(&mut self) -> pscand_core::Result<()> { Ok(()) } }