feature: add current battery charging state, update field names (#1106)

This commit is contained in:
Clement Tsang 2023-04-19 00:46:57 -04:00 committed by GitHub
parent 3e1aa9c75a
commit 1c95411494
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 67 additions and 22 deletions

View File

@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [#1022](https://github.com/ClementTsang/bottom/pull/1022): Support three-character hex colour strings for styling.
- [#1024](https://github.com/ClementTsang/bottom/pull/1024): Support FreeBSD temperature sensors based on `hw.temperature`.
- [#1063](https://github.com/ClementTsang/bottom/pull/1063): Add buffer and cache memory tracking.
- [#1106](https://github.com/ClementTsang/bottom/pull/1106): Add current battery charging state.
## Changes
@ -32,6 +33,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [#1064](https://github.com/ClementTsang/bottom/pull/1064): Migrate away from heim for storage information.
- [#812](https://github.com/ClementTsang/bottom/issues/812): Fully remove heim from bottom.
- [#1075](https://github.com/ClementTsang/bottom/issues/1075): Update how drives are named in Windows.
- [#1106](https://github.com/ClementTsang/bottom/pull/1106): Rename battery consumption field to rate.
## Other

View File

@ -17,7 +17,8 @@ The battery widget can be enabled through either the `--battery` flag, the `batt
The following data is displayed for batteries:
- Charge percent
- Consumption
- Consumption rate
- Charging state
- Time to empty/charge, based on the current state
- Battery health percent

View File

@ -11,7 +11,7 @@
use starship_battery::{
units::{power::watt, ratio::percent, time::second},
Battery, Manager,
Battery, Manager, State,
};
#[derive(Debug, Clone)]
@ -21,6 +21,7 @@ pub struct BatteryHarvest {
pub secs_until_empty: Option<i64>,
pub power_consumption_rate_watts: f64,
pub health_percent: f64,
pub state: State,
}
pub fn refresh_batteries(manager: &Manager, batteries: &mut [Battery]) -> Vec<BatteryHarvest> {
@ -40,6 +41,7 @@ pub fn refresh_batteries(manager: &Manager, batteries: &mut [Battery]) -> Vec<Ba
charge_percent: f64::from(battery.state_of_charge().get::<percent>()),
power_consumption_rate_watts: f64::from(battery.energy_rate().get::<watt>()),
health_percent: f64::from(battery.state_of_health().get::<percent>()),
state: battery.state(),
})
} else {
None

View File

@ -122,24 +122,42 @@ impl Painter {
fn long_time(secs: i64) -> String {
let time = time::Duration::seconds(secs);
let num_minutes = time.whole_minutes() - time.whole_hours() * 60;
let num_hours = time.whole_hours();
let num_minutes = time.whole_minutes() - num_hours * 60;
let num_seconds = time.whole_seconds() - time.whole_minutes() * 60;
format!(
"{} hour{}, {} minute{}, {} second{}",
time.whole_hours(),
if time.whole_hours() == 1 { "" } else { "s" },
num_minutes,
if num_minutes == 1 { "" } else { "s" },
num_seconds,
if num_seconds == 1 { "" } else { "s" },
)
if num_hours > 0 {
format!(
"{} hour{}, {} minute{}, {} second{}",
num_hours,
if num_hours == 1 { "" } else { "s" },
num_minutes,
if num_minutes == 1 { "" } else { "s" },
num_seconds,
if num_seconds == 1 { "" } else { "s" },
)
} else {
format!(
"{} minute{}, {} second{}",
num_minutes,
if num_minutes == 1 { "" } else { "s" },
num_seconds,
if num_seconds == 1 { "" } else { "s" },
)
}
}
fn short_time(secs: i64) -> String {
let time = time::Duration::seconds(secs);
let num_minutes = time.whole_minutes() - time.whole_hours() * 60;
let num_hours = time.whole_hours();
let num_minutes = time.whole_minutes() - num_hours * 60;
let num_seconds = time.whole_seconds() - time.whole_minutes() * 60;
format!("{}h {}m {}s", time.whole_hours(), num_minutes, num_seconds,)
if num_hours > 0 {
format!("{}h {}m {}s", time.whole_hours(), num_minutes, num_seconds,)
} else {
format!("{}m {}s", num_minutes, num_seconds,)
}
}
let mut battery_rows = Vec::with_capacity(4);
@ -154,17 +172,22 @@ impl Painter {
}),
]));
battery_rows.push(
Row::new(vec!["Consumption", &battery_details.watt_consumption])
Row::new(vec!["Rate", &battery_details.watt_consumption])
.style(self.colours.text_style),
);
let s: String; // Keep string in scope.
battery_rows.push(
Row::new(vec!["State", &battery_details.state]).style(self.colours.text_style),
);
let mut s: String; // Keep string in scope.
{
let style = self.colours.text_style;
match &battery_details.battery_duration {
BatteryDuration::ToEmpty(secs) => {
if half_width > 25 {
s = long_time(*secs);
s = long_time(*secs);
if half_width as usize > s.len() {
battery_rows.push(Row::new(vec!["Time to empty", &s]).style(style));
} else {
s = short_time(*secs);
@ -172,15 +195,18 @@ impl Painter {
}
}
BatteryDuration::ToFull(secs) => {
if half_width > 25 {
s = long_time(*secs);
s = long_time(*secs);
if half_width as usize > s.len() {
battery_rows.push(Row::new(vec!["Time to full", &s]).style(style));
} else {
s = short_time(*secs);
battery_rows.push(Row::new(vec!["To full", &s]).style(style));
}
}
BatteryDuration::Unknown => {}
BatteryDuration::Empty
| BatteryDuration::Full
| BatteryDuration::Unknown => {}
}
}

View File

@ -18,6 +18,8 @@ use crate::widgets::{DiskWidgetData, TempWidgetData};
pub enum BatteryDuration {
ToEmpty(i64),
ToFull(i64),
Empty,
Full,
#[default]
Unknown,
}
@ -29,6 +31,7 @@ pub struct ConvertedBatteryData {
pub watt_consumption: String,
pub battery_duration: BatteryDuration,
pub health: String,
pub state: String,
}
#[derive(Default, Debug)]
@ -527,9 +530,20 @@ pub fn convert_battery_harvest(current_data: &DataCollection) -> Vec<ConvertedBa
} else if let Some(secs) = battery_harvest.secs_until_full {
BatteryDuration::ToFull(secs)
} else {
BatteryDuration::Unknown
match battery_harvest.state {
starship_battery::State::Empty => BatteryDuration::Empty,
starship_battery::State::Full => BatteryDuration::Full,
_ => BatteryDuration::Unknown,
}
},
health: format!("{:.2}%", battery_harvest.health_percent),
state: {
let mut s = battery_harvest.state.to_string();
if !s.is_empty() {
s[0..1].make_ascii_uppercase();
}
s
},
})
.collect()
}