Compare commits
3 Commits
17ce090ef8
...
00079662df
Author | SHA1 | Date | |
---|---|---|---|
00079662df
|
|||
c2eee03ac2
|
|||
eba6f977ec
|
@@ -1,7 +1,4 @@
|
|||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
// use std::path::Path;
|
|
||||||
// use std::io::prelude::*;
|
|
||||||
// use regex::Regex;
|
|
||||||
use std::io::{self, BufRead, BufReader};
|
use std::io::{self, BufRead, BufReader};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
@@ -26,15 +23,15 @@ struct CpuTimes {
|
|||||||
impl CpuTimes {
|
impl CpuTimes {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
CpuTimes {
|
CpuTimes {
|
||||||
user: 0,
|
user: 0,
|
||||||
nice: 0,
|
nice: 0,
|
||||||
system: 0,
|
system: 0,
|
||||||
idle: 0,
|
idle: 0,
|
||||||
iowait: 0,
|
iowait: 0,
|
||||||
irq: 0,
|
irq: 0,
|
||||||
softirq: 0,
|
softirq: 0,
|
||||||
steal: 0,
|
steal: 0,
|
||||||
guest: 0,
|
guest: 0,
|
||||||
guest_nice: 0
|
guest_nice: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -98,15 +95,15 @@ impl UnibarModuleCpu {
|
|||||||
|
|
||||||
if fields.len() >= 8 {
|
if fields.len() >= 8 {
|
||||||
return Ok(CpuTimes {
|
return Ok(CpuTimes {
|
||||||
user: fields[0],
|
user: fields[0],
|
||||||
nice: fields[1],
|
nice: fields[1],
|
||||||
system: fields[2],
|
system: fields[2],
|
||||||
idle: fields[3],
|
idle: fields[3],
|
||||||
iowait: fields[4],
|
iowait: fields[4],
|
||||||
irq: fields[5],
|
irq: fields[5],
|
||||||
softirq: fields[6],
|
softirq: fields[6],
|
||||||
steal: fields[7],
|
steal: fields[7],
|
||||||
guest: if fields.len() > 8 { fields[8] } else { 0 },
|
guest: if fields.len() > 8 { fields[8] } else { 0 },
|
||||||
guest_nice: if fields.len() > 9 { fields[9] } else { 0 },
|
guest_nice: if fields.len() > 9 { fields[9] } else { 0 },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -66,7 +66,7 @@ impl bar_modules::BarModuleActions for UnibarModuleMusic {
|
|||||||
parts.push(format!("{}", self.current_stdout));
|
parts.push(format!("{}", self.current_stdout));
|
||||||
|
|
||||||
if self.opts.music_progress {
|
if self.opts.music_progress {
|
||||||
parts.push(format!("[{}]", self.progress_stdout));
|
parts.push(format!("[{}]", self.progress_stdout.trim()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return format!("{}", parts.join(" "));
|
return format!("{}", parts.join(" "));
|
||||||
|
142
src/bar_modules/bar_module_power.rs
Normal file
142
src/bar_modules/bar_module_power.rs
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
use std::process::{Stdio, Command};
|
||||||
|
//use std::collections::HashMap;
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
|
use crate::common;
|
||||||
|
use crate::bar_modules;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct UnibarModulePower {
|
||||||
|
opts: common::AppOptions,
|
||||||
|
power_info: PowerData,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone)]
|
||||||
|
struct PowerData {
|
||||||
|
charging: bool,
|
||||||
|
level: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PowerData {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
PowerData {
|
||||||
|
charging: true,
|
||||||
|
level: 100,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UnibarModulePower {
|
||||||
|
// --------------------
|
||||||
|
pub fn new(o :common::AppOptions) -> Self {
|
||||||
|
UnibarModulePower {
|
||||||
|
opts: o,
|
||||||
|
power_info: PowerData::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl bar_modules::BarModuleActions for UnibarModulePower {
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
fn generate_data(&mut self) {
|
||||||
|
// Following command is used to get power data:
|
||||||
|
// % upower -i /org/freedesktop/UPower/devices/DisplayDevice
|
||||||
|
//
|
||||||
|
// In UPower, the "display device" is a special object that represents the combined
|
||||||
|
// power status that should be shown in desktop environments.
|
||||||
|
//
|
||||||
|
// Purpose:
|
||||||
|
//
|
||||||
|
// It acts as a central point of information for the power icon displayed in your
|
||||||
|
// system's notification area or taskbar.
|
||||||
|
// Instead of desktop environments having to query all individual power sources,
|
||||||
|
// they can access this single "display device" to get a summary of the overall
|
||||||
|
// power status.
|
||||||
|
//
|
||||||
|
// Key characteristics:
|
||||||
|
//
|
||||||
|
// Composite device: It combines information from multiple power sources
|
||||||
|
// (like batteries, UPS) to provide a unified view.
|
||||||
|
// Object path: It has a dedicated object path, typically
|
||||||
|
// /org/freedesktop/UPower/devices/DisplayDevice.
|
||||||
|
// Properties: It exposes properties like Type, State, Percentage, TimeToEmpty,
|
||||||
|
// TimeToFull, and IconName to describe the device's status and
|
||||||
|
// icon representation.
|
||||||
|
// Dynamic Type: Unlike real devices, the Type of the display device can
|
||||||
|
// change (e.g., from Battery to UPS) depending on the current power situation.
|
||||||
|
//
|
||||||
|
// In essence, the "display device" simplifies power management for desktop environments
|
||||||
|
// by providing a convenient interface to show the relevant power information to the user.
|
||||||
|
//
|
||||||
|
let power_dump = Command::new("upower")
|
||||||
|
.arg("--dump")
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
let power_str = String::from_utf8(power_dump.stdout).unwrap();
|
||||||
|
let lines: Vec<&str> = power_str.split('\n').map(|s| s.trim()).collect();
|
||||||
|
let mut found_device: bool = false;
|
||||||
|
|
||||||
|
// let devices: HashMap<String, HashMap<String, String>>::new();
|
||||||
|
// let cur_dev: HashMap<String, String>::new();
|
||||||
|
|
||||||
|
for line in lines {
|
||||||
|
if line.is_empty() { continue };
|
||||||
|
|
||||||
|
let dev_re = Regex::new(r"^Device:\s+(.*)").unwrap();
|
||||||
|
if let Some(caps) = dev_re.captures(line) {
|
||||||
|
if let Some((last, _els)) = &caps[1].split('/').collect::<Vec<_>>().split_last() {
|
||||||
|
if self.opts.debug {
|
||||||
|
println!("-----> Power dump - Device - {:#?}", last);
|
||||||
|
}
|
||||||
|
if last.to_string() == "DisplayDevice" {
|
||||||
|
found_device = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if found_device {
|
||||||
|
let level_re = Regex::new(r"^percentage:\s+(\d+)").unwrap();
|
||||||
|
if let Some(caps) = level_re.captures(line) {
|
||||||
|
self.power_info.level = caps[1].parse().unwrap_or(0);
|
||||||
|
if self.opts.debug {
|
||||||
|
println!("-----> Power dump - level - {:#?}", self.power_info.level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let state_re = Regex::new(r"^state:\s+(\S+)").unwrap();
|
||||||
|
if let Some(caps) = state_re.captures(line) {
|
||||||
|
self.power_info.charging = caps[1].to_string() != "discharging";
|
||||||
|
if self.opts.debug {
|
||||||
|
println!("-----> Power dump - charging - {:#?}", self.power_info.charging);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if self.opts.debug {
|
||||||
|
// println!("-----> Power dump {:#?}", line);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
fn get_content(&self) -> String {
|
||||||
|
// return format!("{}", parts.join(" "));
|
||||||
|
return format!("{:.0}%", self.power_info.level);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
fn get_icon(&self) -> String {
|
||||||
|
match self.power_info.charging {
|
||||||
|
true => return "🔌".to_string(),
|
||||||
|
false => return "🔋".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl bar_modules::BarModuleDebug for UnibarModulePower {
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
fn post_debug(&self) {
|
||||||
|
}
|
||||||
|
}
|
@@ -22,3 +22,4 @@ pub mod bar_module_music;
|
|||||||
pub mod bar_module_network;
|
pub mod bar_module_network;
|
||||||
pub mod bar_module_memory;
|
pub mod bar_module_memory;
|
||||||
pub mod bar_module_cpu;
|
pub mod bar_module_cpu;
|
||||||
|
pub mod bar_module_power;
|
||||||
|
@@ -57,6 +57,7 @@ impl Unibar {
|
|||||||
Box::new(bar_modules::bar_module_music::UnibarModuleMusic::new(self.opts.clone())),
|
Box::new(bar_modules::bar_module_music::UnibarModuleMusic::new(self.opts.clone())),
|
||||||
Box::new(bar_modules::bar_module_memory::UnibarModuleMemory::new(self.opts.clone())),
|
Box::new(bar_modules::bar_module_memory::UnibarModuleMemory::new(self.opts.clone())),
|
||||||
Box::new(bar_modules::bar_module_cpu::UnibarModuleCpu::new(self.opts.clone())),
|
Box::new(bar_modules::bar_module_cpu::UnibarModuleCpu::new(self.opts.clone())),
|
||||||
|
Box::new(bar_modules::bar_module_power::UnibarModulePower::new(self.opts.clone())),
|
||||||
Box::new(bar_modules::bar_module_network::UnibarModuleNetwork::new(self.opts.clone())),
|
Box::new(bar_modules::bar_module_network::UnibarModuleNetwork::new(self.opts.clone())),
|
||||||
Box::new(bar_modules::bar_module_weather::UnibarModuleWeather::new(self.opts.clone())),
|
Box::new(bar_modules::bar_module_weather::UnibarModuleWeather::new(self.opts.clone())),
|
||||||
];
|
];
|
||||||
@@ -88,6 +89,7 @@ impl Unibar {
|
|||||||
Box::new(bar_modules::bar_module_memory::UnibarModuleMemory::new(self.opts.clone())),
|
Box::new(bar_modules::bar_module_memory::UnibarModuleMemory::new(self.opts.clone())),
|
||||||
Box::new(bar_modules::bar_module_network::UnibarModuleNetwork::new(self.opts.clone())),
|
Box::new(bar_modules::bar_module_network::UnibarModuleNetwork::new(self.opts.clone())),
|
||||||
Box::new(bar_modules::bar_module_cpu::UnibarModuleCpu::new(self.opts.clone())),
|
Box::new(bar_modules::bar_module_cpu::UnibarModuleCpu::new(self.opts.clone())),
|
||||||
|
Box::new(bar_modules::bar_module_power::UnibarModulePower::new(self.opts.clone())),
|
||||||
];
|
];
|
||||||
for md in bar_modules_debugged {
|
for md in bar_modules_debugged {
|
||||||
md.post_debug();
|
md.post_debug();
|
||||||
|
Reference in New Issue
Block a user