1use crate::{BatteryInfo, Result};
7use serde::{Deserialize, Serialize};
8use std::time::Duration;
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct PowerProfile {
13 pub total_power_draw: Option<f32>,
15 pub cpu_power: Option<f32>,
17 pub gpu_power: Option<f32>,
19 pub memory_power: Option<f32>,
21 pub storage_power: Option<f32>,
23 pub network_power: Option<f32>,
25 pub other_power: Option<f32>,
27 pub efficiency_score: f64,
29 pub thermal_throttling_risk: ThrottlingRisk,
31 pub power_state: PowerState,
33 pub available_power_modes: Vec<PowerMode>,
35}
36
37#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
39pub enum ThrottlingRisk {
40 None,
42 Low,
44 Moderate,
46 High,
48 Critical,
50}
51
52#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
54pub enum PowerState {
55 HighPerformance,
57 Balanced,
59 PowerSaver,
61 BatteryOptimized,
63 Custom(String),
65 Unknown,
67}
68
69#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
71pub struct PowerMode {
72 pub name: String,
74 pub description: String,
76 pub is_active: bool,
78 pub power_savings_percent: Option<f32>,
80 pub performance_impact_percent: Option<f32>,
82}
83
84#[derive(Debug, Clone, Serialize, Deserialize)]
86pub struct PowerOptimization {
87 pub category: OptimizationCategory,
89 pub recommendation: String,
91 pub expected_savings_watts: Option<f32>,
93 pub performance_impact: f64,
95 pub priority: OptimizationPriority,
97}
98
99#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
101pub enum OptimizationCategory {
102 CPUScaling,
104 GPUPowerLimit,
106 DisplayBrightness,
108 BackgroundProcesses,
110 NetworkInterfaces,
112 StorageDevices,
114 ThermalManagement,
116 SystemSettings,
118}
119
120#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
122pub enum OptimizationPriority {
123 Low,
125 Medium,
127 High,
129 Critical,
131}
132
133impl PowerProfile {
134 pub fn query() -> Result<Self> {
136 let total_power_draw = Self::query_total_power_draw()?;
137 let cpu_power = Self::query_cpu_power()?;
138 let gpu_power = Self::query_gpu_power()?;
139 let memory_power = Self::query_memory_power()?;
140 let storage_power = Self::query_storage_power()?;
141 let network_power = Self::query_network_power()?;
142 let other_power = Self::query_other_power()?;
143
144 let efficiency_score = Self::calculate_efficiency_score(total_power_draw);
145 let thermal_throttling_risk = Self::assess_throttling_risk()?;
146 let power_state = Self::query_power_state()?;
147 let available_power_modes = Self::query_available_power_modes()?;
148
149 Ok(Self {
150 total_power_draw,
151 cpu_power,
152 gpu_power,
153 memory_power,
154 storage_power,
155 network_power,
156 other_power,
157 efficiency_score,
158 thermal_throttling_risk,
159 power_state,
160 available_power_modes,
161 })
162 }
163
164 pub fn estimate_battery_life(&self, battery: &BatteryInfo) -> Option<Duration> {
166 if let (Some(power_draw), Some(capacity_wh)) = (self.total_power_draw, battery.capacity_wh()) {
167 if power_draw > 0.0 {
168 let remaining_wh = capacity_wh * (battery.charge_percent() as f32 / 100.0);
170
171 let hours_remaining = remaining_wh / power_draw;
173
174 let seconds = (hours_remaining * 3600.0) as u64;
176 return Some(Duration::from_secs(seconds));
177 }
178 }
179 None
180 }
181
182 pub fn suggest_power_optimizations(&self) -> Vec<PowerOptimization> {
184 let mut optimizations = Vec::new();
185
186 if let Some(cpu_power) = self.cpu_power {
188 if cpu_power > 50.0 {
189 optimizations.push(PowerOptimization {
190 category: OptimizationCategory::CPUScaling,
191 recommendation: "Consider reducing CPU frequency or enabling power saving mode".to_string(),
192 expected_savings_watts: Some(cpu_power * 0.2),
193 performance_impact: 0.85,
194 priority: OptimizationPriority::Medium,
195 });
196 }
197 }
198
199 if let Some(gpu_power) = self.gpu_power {
201 if gpu_power > 100.0 {
202 optimizations.push(PowerOptimization {
203 category: OptimizationCategory::GPUPowerLimit,
204 recommendation: "GPU power consumption is high. Consider lowering power limit or reducing graphics settings".to_string(),
205 expected_savings_watts: Some(gpu_power * 0.15),
206 performance_impact: 0.90,
207 priority: OptimizationPriority::Medium,
208 });
209 }
210 }
211
212 match self.thermal_throttling_risk {
214 ThrottlingRisk::High | ThrottlingRisk::Critical => {
215 optimizations.push(PowerOptimization {
216 category: OptimizationCategory::ThermalManagement,
217 recommendation: "High thermal throttling risk detected. Reduce workload or improve cooling".to_string(),
218 expected_savings_watts: None,
219 performance_impact: 1.0,
220 priority: OptimizationPriority::Critical,
221 });
222 }
223 ThrottlingRisk::Moderate => {
224 optimizations.push(PowerOptimization {
225 category: OptimizationCategory::ThermalManagement,
226 recommendation: "Consider improving system cooling or reducing sustained workloads".to_string(),
227 expected_savings_watts: None,
228 performance_impact: 0.95,
229 priority: OptimizationPriority::Medium,
230 });
231 }
232 _ => {}
233 }
234
235 optimizations
236 }
237
238 pub fn calculate_efficiency_with_performance(&self, performance_score: f64) -> f64 {
240 if let Some(power_draw) = self.total_power_draw {
241 if power_draw > 0.0 {
242 return (performance_score / power_draw as f64).min(1.0);
244 }
245 }
246 0.0
247 }
248
249 fn query_total_power_draw() -> Result<Option<f32>> {
250 Ok(None)
253 }
254
255 fn query_cpu_power() -> Result<Option<f32>> {
256 Ok(None)
258 }
259
260 fn query_gpu_power() -> Result<Option<f32>> {
261 Ok(None)
263 }
264
265 fn query_memory_power() -> Result<Option<f32>> {
266 Ok(None)
268 }
269
270 fn query_storage_power() -> Result<Option<f32>> {
271 Ok(None)
273 }
274
275 fn query_network_power() -> Result<Option<f32>> {
276 Ok(None)
278 }
279
280 fn query_other_power() -> Result<Option<f32>> {
281 Ok(None)
283 }
284
285 fn calculate_efficiency_score(total_power_draw: Option<f32>) -> f64 {
286 if let Some(power) = total_power_draw {
288 if power < 50.0 {
289 0.9
290 } else if power < 100.0 {
291 0.7
292 } else if power < 200.0 {
293 0.5
294 } else {
295 0.3
296 }
297 } else {
298 0.0
299 }
300 }
301
302 fn assess_throttling_risk() -> Result<ThrottlingRisk> {
303 Ok(ThrottlingRisk::None)
306 }
307
308 fn query_power_state() -> Result<PowerState> {
309 Ok(PowerState::Unknown)
311 }
312
313 fn query_available_power_modes() -> Result<Vec<PowerMode>> {
314 Ok(vec![])
316 }
317}
318
319impl std::fmt::Display for PowerState {
320 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
321 match self {
322 PowerState::HighPerformance => write!(f, "High Performance"),
323 PowerState::Balanced => write!(f, "Balanced"),
324 PowerState::PowerSaver => write!(f, "Power Saver"),
325 PowerState::BatteryOptimized => write!(f, "Battery Optimized"),
326 PowerState::Custom(name) => write!(f, "Custom: {}", name),
327 PowerState::Unknown => write!(f, "Unknown"),
328 }
329 }
330}
331
332impl std::fmt::Display for ThrottlingRisk {
333 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
334 match self {
335 ThrottlingRisk::None => write!(f, "None"),
336 ThrottlingRisk::Low => write!(f, "Low"),
337 ThrottlingRisk::Moderate => write!(f, "Moderate"),
338 ThrottlingRisk::High => write!(f, "High"),
339 ThrottlingRisk::Critical => write!(f, "Critical"),
340 }
341 }
342}