Commit 998aafe
Changed files (4)
internal
get
lib
system
internal/get/system_info.go
@@ -47,6 +47,7 @@ type systemInfoStruct struct {
BatteryFull float64
BatteryDesignCapacity float64
BatteryCycleCount uint64
+ BatteryTimeToEmpty uint64
}
func convertKBtoGB(v uint64) float64 {
@@ -134,6 +135,23 @@ func getSystemInfo() systemInfoStruct {
log.Fatal().Msg("Unknown error occurred")
}
+ //// time to empty
+ var batteryTimeToEmpty uint64
+ resultTimeToEmpty := C.battery_time_to_empty()
+
+ switch result.error {
+ case C.BATTERY_TIME_TO_EMPTY_SUCCESS:
+ batteryTimeToEmpty = uint64(resultTimeToEmpty.time_to_empty_seconds)
+ case C.BATTERY_TIME_TO_EMPTY_NO_BATTERY:
+ batteryTimeToEmpty = 0
+ case C.BATTERY_TIME_TO_EMPTY_NO_TIME_TO_EMPTY:
+ batteryTimeToEmpty = 0
+ case C.BATTERY_TIME_TO_EMPTY_MANAGER_ERROR:
+ log.Fatal().Msg("Battery manager error")
+ default:
+ log.Fatal().Msg("Unknown error occurred")
+ }
+
// return
return systemInfoStruct{
Username: username.Username,
@@ -149,6 +167,7 @@ func getSystemInfo() systemInfoStruct {
BatteryFull: batteryFull,
BatteryDesignCapacity: batteryDesignCapacity,
BatteryCycleCount: batteryCycleCount,
+ BatteryTimeToEmpty: batteryTimeToEmpty,
}
}
@@ -188,7 +207,23 @@ func SystemInfo() {
batteryPercentStr = color.Red(batteryFormat)
}
- batteryStdout := fmt.Sprintf("%s: %s (Health: %s, Cycles: %s)", color.Green("Battery"), batteryPercentStr, color.Blue(strconv.Itoa(batteryHealth)+"%"), color.Blue(strconv.Itoa(int(systemInfo.BatteryCycleCount))))
+ // convert BatteryTimeToEmpty from second to hour
+ var batteryTimeToEmptyFormatted string
+ if systemInfo.BatteryTimeToEmpty > 0 {
+ hours := systemInfo.BatteryTimeToEmpty / 3600
+ minutes := (systemInfo.BatteryTimeToEmpty % 3600) / 60
+ batteryTimeToEmptyFormatted = fmt.Sprintf("%02d:%02d", hours, minutes)
+ } else {
+ batteryTimeToEmptyFormatted = "--:--"
+ }
+
+ batteryStdout := fmt.Sprintf(
+ "%s: %s (Health: %s, Cycles: %s, Time Remaining: %s)",
+ color.Green("Battery"), batteryPercentStr,
+ color.Blue(strconv.Itoa(batteryHealth)+"%"),
+ color.Blue(strconv.Itoa(int(systemInfo.BatteryCycleCount))),
+ color.Blue(batteryTimeToEmptyFormatted),
+ )
fmt.Println(batteryStdout)
}
}
lib/system/src/battery_time_to_empty.rs
@@ -0,0 +1,120 @@
+use battery;
+use log::error;
+
+#[repr(C)]
+#[derive(Debug)]
+pub enum BatteryTimeToEmptyError {
+ Success = 0,
+ NoBattery = 1,
+ NoTimeToEmpty = 2,
+ ManagerError = 3,
+}
+
+#[repr(C)]
+pub struct BatteryTimeToEmptyResult {
+ pub time_to_empty_seconds: u64,
+ pub error: BatteryTimeToEmptyError,
+}
+
+#[no_mangle]
+pub extern "C" fn battery_time_to_empty() -> BatteryTimeToEmptyResult {
+ match battery::Manager::new() {
+ Ok(manager) => {
+ match manager.batteries() {
+ Ok(batteries) => {
+ // Get the first battery if available
+ if let Some(battery) = batteries.into_iter().next() {
+ match battery {
+ Ok(bat) => {
+ match bat.time_to_empty() {
+ Some(time) => {
+ // Convert Time to seconds as u64
+ let seconds = time.get::<battery::units::time::second>();
+ BatteryTimeToEmptyResult {
+ time_to_empty_seconds: seconds as u64,
+ error: BatteryTimeToEmptyError::Success,
+ }
+ }
+ None => {
+ error!("No time to empty available");
+ BatteryTimeToEmptyResult {
+ time_to_empty_seconds: 0,
+ error: BatteryTimeToEmptyError::NoTimeToEmpty,
+ }
+ }
+ }
+ }
+ Err(e) => {
+ error!("Battery error: {}", e);
+ BatteryTimeToEmptyResult {
+ time_to_empty_seconds: 0,
+ error: BatteryTimeToEmptyError::NoBattery,
+ }
+ }
+ }
+ } else {
+ error!("No batteries found");
+ BatteryTimeToEmptyResult {
+ time_to_empty_seconds: 0,
+ error: BatteryTimeToEmptyError::NoBattery,
+ }
+ }
+ }
+ Err(e) => {
+ error!("Failed to get batteries: {}", e);
+ BatteryTimeToEmptyResult {
+ time_to_empty_seconds: 0,
+ error: BatteryTimeToEmptyError::ManagerError,
+ }
+ }
+ }
+ }
+ Err(e) => {
+ error!("Failed to create battery manager: {}", e);
+ BatteryTimeToEmptyResult {
+ time_to_empty_seconds: 0,
+ error: BatteryTimeToEmptyError::ManagerError,
+ }
+ }
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+
+ #[test]
+ fn test_battery_time_to_empty() {
+ let result = battery_time_to_empty();
+
+ match result.error {
+ BatteryTimeToEmptyError::Success => {
+ println!(
+ "Battery time to empty: {} seconds",
+ result.time_to_empty_seconds
+ );
+ assert!(result.time_to_empty_seconds > 0);
+ }
+ BatteryTimeToEmptyError::NoBattery => {
+ println!("No battery found");
+ assert_eq!(result.time_to_empty_seconds, 0);
+ }
+ BatteryTimeToEmptyError::NoTimeToEmpty => {
+ println!("No time to empty available");
+ assert_eq!(result.time_to_empty_seconds, 0);
+ }
+ BatteryTimeToEmptyError::ManagerError => {
+ println!("Battery manager error");
+ assert_eq!(result.time_to_empty_seconds, 0);
+ }
+ }
+
+ assert!(matches!(
+ result.error,
+ BatteryTimeToEmptyError::Success
+ | BatteryTimeToEmptyError::NoBattery
+ | BatteryTimeToEmptyError::NoTimeToEmpty
+ | BatteryTimeToEmptyError::ManagerError
+ ));
+ }
+}
lib/system/src/lib.rs
@@ -2,8 +2,12 @@ extern crate battery;
extern crate log;
extern crate sysinfo;
-mod sensors;
mod battery_cycle_count;
+mod battery_time_to_empty;
+mod sensors;
pub use battery_cycle_count::{battery_cycle_count, BatteryError, BatteryResult};
+pub use battery_time_to_empty::{
+ battery_time_to_empty, BatteryTimeToEmptyError, BatteryTimeToEmptyResult,
+};
pub use sensors::{sensors, SensorError, SensorResult};
lib/system.h
@@ -13,6 +13,21 @@ struct BatteryResult {
struct BatteryResult battery_cycle_count(void);
+// battery time to empty
+enum BatteryTimeToEmptyError {
+ BATTERY_TIME_TO_EMPTY_SUCCESS = 0,
+ BATTERY_TIME_TO_EMPTY_NO_BATTERY = 1,
+ BATTERY_TIME_TO_EMPTY_NO_TIME_TO_EMPTY = 2,
+ BATTERY_TIME_TO_EMPTY_MANAGER_ERROR = 3
+};
+
+struct BatteryTimeToEmptyResult {
+ unsigned long long time_to_empty_seconds;
+ enum BatteryTimeToEmptyError error;
+};
+
+struct BatteryTimeToEmptyResult battery_time_to_empty(void);
+
// sensors
enum SensorError {