refactor: remove battery conversion step (#1652)
* refactor: remove battery conversion step * also fix a bug with margins in battery * fixes
This commit is contained in:
parent
4a4d53dafb
commit
cd6c60c054
|
@ -124,7 +124,7 @@ pub struct DataCollection {
|
|||
pub io_labels: Vec<(String, String)>,
|
||||
pub temp_harvest: Vec<temperature::TempHarvest>,
|
||||
#[cfg(feature = "battery")]
|
||||
pub battery_harvest: Vec<batteries::BatteryHarvest>,
|
||||
pub battery_harvest: Vec<batteries::BatteryData>,
|
||||
#[cfg(feature = "zfs")]
|
||||
pub arc_harvest: memory::MemHarvest,
|
||||
#[cfg(feature = "gpu")]
|
||||
|
@ -451,7 +451,7 @@ impl DataCollection {
|
|||
}
|
||||
|
||||
#[cfg(feature = "battery")]
|
||||
fn eat_battery(&mut self, list_of_batteries: Vec<batteries::BatteryHarvest>) {
|
||||
fn eat_battery(&mut self, list_of_batteries: Vec<batteries::BatteryData>) {
|
||||
self.battery_harvest = list_of_batteries;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ pub struct AppWidgetStates {
|
|||
pub proc_state: ProcState,
|
||||
pub temp_state: TempState,
|
||||
pub disk_state: DiskState,
|
||||
pub battery_state: BatteryState,
|
||||
pub battery_state: AppBatteryState,
|
||||
pub basic_table_widget_state: Option<BasicTableWidgetState>,
|
||||
}
|
||||
|
||||
|
@ -381,13 +381,13 @@ pub struct BasicTableWidgetState {
|
|||
pub right_brc: Option<(u16, u16)>,
|
||||
}
|
||||
|
||||
pub struct BatteryState {
|
||||
pub struct AppBatteryState {
|
||||
pub widget_states: HashMap<u64, BatteryWidgetState>,
|
||||
}
|
||||
|
||||
impl BatteryState {
|
||||
impl AppBatteryState {
|
||||
pub fn init(widget_states: HashMap<u64, BatteryWidgetState>) -> Self {
|
||||
BatteryState { widget_states }
|
||||
AppBatteryState { widget_states }
|
||||
}
|
||||
|
||||
pub fn get_mut_widget_state(&mut self, widget_id: u64) -> Option<&mut BatteryWidgetState> {
|
||||
|
|
|
@ -133,11 +133,10 @@ where
|
|||
&mut self, f: &mut Frame<'_>, draw_info: &DrawInfo, widget: Option<&mut BottomWidget>,
|
||||
painter: &Painter,
|
||||
) {
|
||||
let draw_horizontal = !self.props.is_basic || draw_info.is_on_widget();
|
||||
let draw_loc = draw_info.loc;
|
||||
let margined_draw_loc = Layout::default()
|
||||
.constraints([Constraint::Percentage(100)])
|
||||
.horizontal_margin(u16::from(!draw_horizontal))
|
||||
.horizontal_margin(u16::from(self.props.is_basic && !draw_info.is_on_widget()))
|
||||
.direction(Direction::Horizontal)
|
||||
.split(draw_loc)[0];
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ use crate::{
|
|||
Painter,
|
||||
},
|
||||
constants::*,
|
||||
data_conversion::BatteryDuration,
|
||||
data_collection::batteries::BatteryState,
|
||||
};
|
||||
|
||||
impl Painter {
|
||||
|
@ -27,8 +27,8 @@ impl Painter {
|
|||
.widget_states
|
||||
.get_mut(&widget_id)
|
||||
{
|
||||
let is_on_widget = widget_id == app_state.current_widget.widget_id;
|
||||
let border_style = if is_on_widget {
|
||||
let is_selected = widget_id == app_state.current_widget.widget_id;
|
||||
let border_style = if is_selected {
|
||||
self.styles.highlighted_border_style
|
||||
} else {
|
||||
self.styles.border_style
|
||||
|
@ -42,7 +42,7 @@ impl Painter {
|
|||
let block = {
|
||||
let mut block = widget_block(
|
||||
app_state.app_config_fields.use_basic_mode,
|
||||
is_on_widget,
|
||||
is_selected,
|
||||
self.styles.border_type,
|
||||
)
|
||||
.border_style(border_style)
|
||||
|
@ -113,7 +113,7 @@ impl Painter {
|
|||
|
||||
let margined_draw_loc = Layout::default()
|
||||
.constraints([Constraint::Percentage(100)])
|
||||
.horizontal_margin(u16::from(!(is_on_widget || is_basic)))
|
||||
.horizontal_margin(u16::from(is_basic && !is_selected))
|
||||
.direction(Direction::Horizontal)
|
||||
.split(draw_loc)[0];
|
||||
|
||||
|
@ -124,13 +124,14 @@ impl Painter {
|
|||
{
|
||||
let full_width = draw_loc.width.saturating_sub(2);
|
||||
let bar_length = usize::from(full_width.saturating_sub(6));
|
||||
let charge_percentage = battery_details.charge_percentage;
|
||||
let num_bars = calculate_basic_use_bars(charge_percentage, bar_length);
|
||||
let charge_percent = battery_details.charge_percent;
|
||||
|
||||
let num_bars = calculate_basic_use_bars(charge_percent, bar_length);
|
||||
let bars = format!(
|
||||
"[{}{}{:3.0}%]",
|
||||
"|".repeat(num_bars),
|
||||
" ".repeat(bar_length - num_bars),
|
||||
charge_percentage,
|
||||
charge_percent,
|
||||
);
|
||||
|
||||
let mut battery_charge_rows = Vec::with_capacity(2);
|
||||
|
@ -138,9 +139,9 @@ impl Painter {
|
|||
Cell::from("Charge").style(self.styles.text_style)
|
||||
]));
|
||||
battery_charge_rows.push(Row::new([Cell::from(bars).style(
|
||||
if charge_percentage < 10.0 {
|
||||
if charge_percent < 10.0 {
|
||||
self.styles.low_battery
|
||||
} else if charge_percentage < 50.0 {
|
||||
} else if charge_percent < 50.0 {
|
||||
self.styles.medium_battery
|
||||
} else {
|
||||
self.styles.high_battery
|
||||
|
@ -148,31 +149,25 @@ impl Painter {
|
|||
)]));
|
||||
|
||||
let mut battery_rows = Vec::with_capacity(3);
|
||||
let watt_consumption = battery_details.watt_consumption();
|
||||
let health = battery_details.health();
|
||||
|
||||
battery_rows.push(Row::new([""]).bottom_margin(table_gap + 1));
|
||||
battery_rows.push(
|
||||
Row::new(["Rate", &battery_details.watt_consumption])
|
||||
.style(self.styles.text_style),
|
||||
);
|
||||
battery_rows
|
||||
.push(Row::new(["Rate", &watt_consumption]).style(self.styles.text_style));
|
||||
|
||||
battery_rows.push(
|
||||
Row::new(["State", &battery_details.state]).style(self.styles.text_style),
|
||||
Row::new(["State", battery_details.state.as_str()])
|
||||
.style(self.styles.text_style),
|
||||
);
|
||||
|
||||
let mut time: String; // Keep string lifetime in scope.
|
||||
{
|
||||
let style = self.styles.text_style;
|
||||
match &battery_details.battery_duration {
|
||||
BatteryDuration::ToEmpty(secs) => {
|
||||
time = long_time(*secs);
|
||||
|
||||
if full_width as usize > time.len() {
|
||||
battery_rows.push(Row::new(["Time to empty", &time]).style(style));
|
||||
} else {
|
||||
time = short_time(*secs);
|
||||
battery_rows.push(Row::new(["To empty", &time]).style(style));
|
||||
}
|
||||
}
|
||||
BatteryDuration::ToFull(secs) => {
|
||||
match &battery_details.state {
|
||||
BatteryState::Charging {
|
||||
time_to_full: Some(secs),
|
||||
} => {
|
||||
time = long_time(*secs);
|
||||
|
||||
if full_width as usize > time.len() {
|
||||
|
@ -182,15 +177,23 @@ impl Painter {
|
|||
battery_rows.push(Row::new(["To full", &time]).style(style));
|
||||
}
|
||||
}
|
||||
BatteryDuration::Empty
|
||||
| BatteryDuration::Full
|
||||
| BatteryDuration::Unknown => {}
|
||||
BatteryState::Discharging {
|
||||
time_to_empty: Some(secs),
|
||||
} => {
|
||||
time = long_time(*secs);
|
||||
|
||||
if full_width as usize > time.len() {
|
||||
battery_rows.push(Row::new(["Time to empty", &time]).style(style));
|
||||
} else {
|
||||
time = short_time(*secs);
|
||||
battery_rows.push(Row::new(["To empty", &time]).style(style));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
battery_rows.push(
|
||||
Row::new(["Health", &battery_details.health]).style(self.styles.text_style),
|
||||
);
|
||||
battery_rows.push(Row::new(["Health", &health]).style(self.styles.text_style));
|
||||
|
||||
let header = if app_state.converted_data.battery_data.len() > 1 {
|
||||
Row::new([""]).bottom_margin(table_gap)
|
||||
|
@ -241,7 +244,7 @@ impl Painter {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_hms(secs: i64) -> (i64, i64, i64) {
|
||||
fn get_hms(secs: u32) -> (u32, u32, u32) {
|
||||
let hours = secs / (60 * 60);
|
||||
let minutes = (secs / 60) - hours * 60;
|
||||
let seconds = secs - minutes * 60 - hours * 60 * 60;
|
||||
|
@ -249,7 +252,7 @@ fn get_hms(secs: i64) -> (i64, i64, i64) {
|
|||
(hours, minutes, seconds)
|
||||
}
|
||||
|
||||
fn long_time(secs: i64) -> String {
|
||||
fn long_time(secs: u32) -> String {
|
||||
let (hours, minutes, seconds) = get_hms(secs);
|
||||
|
||||
if hours > 0 {
|
||||
|
@ -266,7 +269,7 @@ fn long_time(secs: i64) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
fn short_time(secs: i64) -> String {
|
||||
fn short_time(secs: u32) -> String {
|
||||
let (hours, minutes, seconds) = get_hms(secs);
|
||||
|
||||
if hours > 0 {
|
||||
|
|
|
@ -6,9 +6,7 @@ pub mod nvidia;
|
|||
#[cfg(all(target_os = "linux", feature = "gpu"))]
|
||||
pub mod amd;
|
||||
|
||||
#[cfg(feature = "battery")]
|
||||
pub mod batteries;
|
||||
|
||||
pub mod cpu;
|
||||
pub mod disks;
|
||||
pub mod error;
|
||||
|
@ -45,7 +43,7 @@ pub struct Data {
|
|||
pub disks: Option<Vec<disks::DiskHarvest>>,
|
||||
pub io: Option<disks::IoHarvest>,
|
||||
#[cfg(feature = "battery")]
|
||||
pub list_of_batteries: Option<Vec<batteries::BatteryHarvest>>,
|
||||
pub list_of_batteries: Option<Vec<batteries::BatteryData>>,
|
||||
#[cfg(feature = "zfs")]
|
||||
pub arc: Option<memory::MemHarvest>,
|
||||
#[cfg(feature = "gpu")]
|
||||
|
|
|
@ -1,11 +1,104 @@
|
|||
//! Data collection for batteries.
|
||||
//! Uses the battery crate.
|
||||
//!
|
||||
//! For Linux, macOS, Windows, FreeBSD, Dragonfly, and iOS, this is handled by
|
||||
//! the battery crate.
|
||||
//! Covers battery usage for:
|
||||
//! - Linux 2.6.39+
|
||||
//! - MacOS 10.10+
|
||||
//! - iOS
|
||||
//! - Windows 7+
|
||||
//! - FreeBSD
|
||||
//! - DragonFlyBSD
|
||||
//!
|
||||
//! For more information, refer to the [starship_battery](https://github.com/starship/rust-battery) repo/docs.
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(any(target_os = "windows", target_os = "macos", target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "ios"))] {
|
||||
pub mod battery;
|
||||
pub use self::battery::*;
|
||||
#[cfg(feature = "battery")]
|
||||
use starship_battery::{
|
||||
units::{power::watt, ratio::percent, time::second},
|
||||
Battery, Manager, State,
|
||||
};
|
||||
|
||||
/// Battery state.
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub enum BatteryState {
|
||||
Charging {
|
||||
/// Time to full in seconds.
|
||||
time_to_full: Option<u32>,
|
||||
},
|
||||
Discharging {
|
||||
/// Time to empty in seconds.
|
||||
time_to_empty: Option<u32>,
|
||||
},
|
||||
Empty,
|
||||
Full,
|
||||
#[default]
|
||||
Unknown,
|
||||
}
|
||||
|
||||
impl BatteryState {
|
||||
/// Return the string representation.
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
BatteryState::Charging { .. } => "Charging",
|
||||
BatteryState::Discharging { .. } => "Discharging",
|
||||
BatteryState::Empty => "Empty",
|
||||
BatteryState::Full => "Full",
|
||||
BatteryState::Unknown => "Unknown",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct BatteryData {
|
||||
/// Current charge percent.
|
||||
pub charge_percent: f64,
|
||||
/// Power consumption, in watts.
|
||||
pub power_consumption: f64,
|
||||
/// Reported battery health.
|
||||
pub health_percent: f64,
|
||||
/// The current battery "state" (e.g. is it full, charging, etc.).
|
||||
pub state: BatteryState,
|
||||
}
|
||||
|
||||
impl BatteryData {
|
||||
pub fn watt_consumption(&self) -> String {
|
||||
format!("{:.2}W", self.power_consumption)
|
||||
}
|
||||
|
||||
pub fn health(&self) -> String {
|
||||
format!("{:.2}%", self.health_percent)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "battery")]
|
||||
pub fn refresh_batteries(manager: &Manager, batteries: &mut [Battery]) -> Vec<BatteryData> {
|
||||
batteries
|
||||
.iter_mut()
|
||||
.filter_map(|battery| {
|
||||
if manager.refresh(battery).is_ok() {
|
||||
Some(BatteryData {
|
||||
charge_percent: f64::from(battery.state_of_charge().get::<percent>()),
|
||||
power_consumption: f64::from(battery.energy_rate().get::<watt>()),
|
||||
health_percent: f64::from(battery.state_of_health().get::<percent>()),
|
||||
state: match battery.state() {
|
||||
State::Unknown => BatteryState::Unknown,
|
||||
State::Charging => BatteryState::Charging {
|
||||
time_to_full: {
|
||||
let optional_time = battery.time_to_full();
|
||||
optional_time.map(|time| f64::from(time.get::<second>()) as u32)
|
||||
},
|
||||
},
|
||||
State::Discharging => BatteryState::Discharging {
|
||||
time_to_empty: {
|
||||
let optional_time = battery.time_to_empty();
|
||||
optional_time.map(|time| f64::from(time.get::<second>()) as u32)
|
||||
},
|
||||
},
|
||||
State::Empty => BatteryState::Empty,
|
||||
State::Full => BatteryState::Full,
|
||||
},
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
//! Uses the battery crate from svartalf.
|
||||
//! Covers battery usage for:
|
||||
//! - Linux 2.6.39+
|
||||
//! - MacOS 10.10+
|
||||
//! - iOS
|
||||
//! - Windows 7+
|
||||
//! - FreeBSD
|
||||
//! - DragonFlyBSD
|
||||
//!
|
||||
//! For more information, refer to the [starship_battery](https://github.com/starship/rust-battery) repo/docs.
|
||||
|
||||
use starship_battery::{
|
||||
units::{power::watt, ratio::percent, time::second},
|
||||
Battery, Manager, State,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct BatteryHarvest {
|
||||
pub charge_percent: f64,
|
||||
pub secs_until_full: Option<i64>,
|
||||
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> {
|
||||
batteries
|
||||
.iter_mut()
|
||||
.filter_map(|battery| {
|
||||
if manager.refresh(battery).is_ok() {
|
||||
Some(BatteryHarvest {
|
||||
secs_until_full: {
|
||||
let optional_time = battery.time_to_full();
|
||||
optional_time.map(|time| f64::from(time.get::<second>()) as i64)
|
||||
},
|
||||
secs_until_empty: {
|
||||
let optional_time = battery.time_to_empty();
|
||||
optional_time.map(|time| f64::from(time.get::<second>()) as i64)
|
||||
},
|
||||
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
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
}
|
|
@ -8,30 +8,13 @@ use std::borrow::Cow;
|
|||
use crate::{
|
||||
app::{data_farmer::DataCollection, AxisScaling},
|
||||
canvas::components::time_chart::Point,
|
||||
data_collection::{cpu::CpuDataType, memory::MemHarvest, temperature::TemperatureType},
|
||||
data_collection::{
|
||||
batteries::BatteryData, cpu::CpuDataType, memory::MemHarvest, temperature::TemperatureType,
|
||||
},
|
||||
utils::{data_prefixes::*, data_units::DataUnit},
|
||||
widgets::{DiskWidgetData, TempWidgetData},
|
||||
};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub enum BatteryDuration {
|
||||
ToEmpty(i64),
|
||||
ToFull(i64),
|
||||
Empty,
|
||||
Full,
|
||||
#[default]
|
||||
Unknown,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct ConvertedBatteryData {
|
||||
pub charge_percentage: f64,
|
||||
pub watt_consumption: String,
|
||||
pub battery_duration: BatteryDuration,
|
||||
pub health: String,
|
||||
pub state: String,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct ConvertedNetworkData {
|
||||
pub rx: Vec<Point>,
|
||||
|
@ -90,7 +73,8 @@ pub struct ConvertedData {
|
|||
|
||||
pub load_avg_data: [f32; 3],
|
||||
pub cpu_data: Vec<CpuWidgetData>,
|
||||
pub battery_data: Vec<ConvertedBatteryData>,
|
||||
|
||||
pub battery_data: Vec<BatteryData>,
|
||||
pub disk_data: Vec<DiskWidgetData>,
|
||||
pub temp_data: Vec<TempWidgetData>,
|
||||
}
|
||||
|
@ -508,37 +492,6 @@ pub fn dec_bytes_string(value: u64) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "battery")]
|
||||
pub fn convert_battery_harvest(current_data: &DataCollection) -> Vec<ConvertedBatteryData> {
|
||||
current_data
|
||||
.battery_harvest
|
||||
.iter()
|
||||
.map(|battery_harvest| ConvertedBatteryData {
|
||||
charge_percentage: battery_harvest.charge_percent,
|
||||
watt_consumption: format!("{:.2}W", battery_harvest.power_consumption_rate_watts),
|
||||
battery_duration: if let Some(secs) = battery_harvest.secs_until_empty {
|
||||
BatteryDuration::ToEmpty(secs)
|
||||
} else if let Some(secs) = battery_harvest.secs_until_full {
|
||||
BatteryDuration::ToFull(secs)
|
||||
} else {
|
||||
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()
|
||||
}
|
||||
|
||||
#[cfg(feature = "zfs")]
|
||||
pub fn convert_arc_data_points(current_data: &DataCollection) -> Vec<Point> {
|
||||
let mut result: Vec<Point> = Vec::new();
|
||||
|
|
|
@ -513,7 +513,7 @@ pub fn start_bottom() -> anyhow::Result<()> {
|
|||
{
|
||||
if app.used_widgets.use_battery {
|
||||
app.converted_data.battery_data =
|
||||
convert_battery_harvest(&app.data_collection);
|
||||
app.data_collection.battery_harvest.clone();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -493,7 +493,7 @@ pub(crate) fn init_app(args: BottomArgs, config: Config) -> Result<(App, BottomL
|
|||
proc_state: ProcState::init(proc_state_map),
|
||||
temp_state: TempState::init(temp_state_map),
|
||||
disk_state: DiskState::init(disk_state_map),
|
||||
battery_state: BatteryState::init(battery_state_map),
|
||||
battery_state: AppBatteryState::init(battery_state_map),
|
||||
basic_table_widget_state,
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue