hardware_query/
battery.rs

1use crate::{HardwareQueryError, Result};
2use serde::{Deserialize, Serialize};
3
4/// Battery status
5#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
6pub enum BatteryStatus {
7    Charging,
8    Discharging,
9    Full,
10    NotCharging,
11    Unknown,
12}
13
14impl std::fmt::Display for BatteryStatus {
15    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
16        match self {
17            BatteryStatus::Charging => write!(f, "Charging"),
18            BatteryStatus::Discharging => write!(f, "Discharging"),
19            BatteryStatus::Full => write!(f, "Full"),
20            BatteryStatus::NotCharging => write!(f, "Not Charging"),
21            BatteryStatus::Unknown => write!(f, "Unknown"),
22        }
23    }
24}
25
26/// Battery information
27#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct BatteryInfo {
29    /// Current battery percentage (0-100)
30    pub percentage: f32,
31    /// Battery status
32    pub status: BatteryStatus,
33    /// Time remaining in minutes (if available)
34    pub time_remaining_minutes: Option<u32>,
35    /// Battery health percentage (0-100)
36    pub health_percent: Option<f32>,
37    /// Design capacity in Wh
38    pub design_capacity_wh: Option<f32>,
39    /// Current capacity in Wh
40    pub current_capacity_wh: Option<f32>,
41    /// Cycle count
42    pub cycle_count: Option<u32>,
43    /// Battery temperature in Celsius
44    pub temperature: Option<f32>,
45    /// Voltage in Volts
46    pub voltage: Option<f32>,
47    /// Current in Amperes
48    pub current: Option<f32>,
49    /// Battery manufacturer
50    pub manufacturer: Option<String>,
51    /// Battery model
52    pub model: Option<String>,
53    /// Battery serial number
54    pub serial_number: Option<String>,
55}
56
57impl BatteryInfo {
58    /// Query battery information
59    pub fn query() -> Result<Self> {
60        // This would be platform-specific implementation
61        // For now, return an error if no battery detected
62        Err(HardwareQueryError::device_not_found("No battery detected"))
63    }
64
65    /// Get battery percentage
66    pub fn percentage(&self) -> f32 {
67        self.percentage
68    }
69
70    /// Get battery status
71    pub fn status(&self) -> &BatteryStatus {
72        &self.status
73    }
74
75    /// Check if battery is charging
76    pub fn is_charging(&self) -> bool {
77        matches!(self.status, BatteryStatus::Charging)
78    }
79
80    /// Check if battery is discharging
81    pub fn is_discharging(&self) -> bool {
82        matches!(self.status, BatteryStatus::Discharging)
83    }
84
85    /// Get time remaining in hours
86    pub fn time_remaining_hours(&self) -> Option<f32> {
87        self.time_remaining_minutes
88            .map(|minutes| minutes as f32 / 60.0)
89    }
90
91    /// Get battery health percentage
92    pub fn health_percent(&self) -> Option<f32> {
93        self.health_percent
94    }
95
96    /// Calculate battery wear percentage
97    pub fn wear_percent(&self) -> Option<f32> {
98        match (self.design_capacity_wh, self.current_capacity_wh) {
99            (Some(design), Some(current)) if design > 0.0 => {
100                Some(((design - current) / design) * 100.0)
101            }
102            _ => None,
103        }
104    }
105
106    /// Check if battery needs replacement (>20% wear or <80% health)
107    pub fn needs_replacement(&self) -> bool {
108        if let Some(health) = self.health_percent {
109            health < 80.0
110        } else if let Some(wear) = self.wear_percent() {
111            wear > 20.0
112        } else {
113            false
114        }
115    }
116
117    /// Get current capacity in Wh (used by power estimation)
118    pub fn capacity_wh(&self) -> Option<f32> {
119        self.current_capacity_wh
120    }
121
122    /// Get charge percentage (alias for percentage)
123    pub fn charge_percent(&self) -> f32 {
124        self.percentage
125    }
126}