From 0bd5337ad4aeddf5b3a709a95dbeaab75dfa8454 Mon Sep 17 00:00:00 2001 From: fxqnlr Date: Mon, 23 Sep 2024 14:52:55 +0200 Subject: initial commit --- main.rs | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 main.rs (limited to 'main.rs') diff --git a/main.rs b/main.rs new file mode 100644 index 0000000..d6bf3d9 --- /dev/null +++ b/main.rs @@ -0,0 +1,82 @@ +use std::{ + collections::HashMap, env, fs::File, io::Read, process::Command, thread::sleep, time::Duration, +}; + +fn main() { + let mut args = env::args(); + + assert!( + args.len() > 2, + "Too few arguments, provide battery id and values with warning levels" + ); + // Skip process (argc[0]) + args.next(); + + // 1: Battery ID + let bat = args.next().expect("Invalid Battery id"); + let bat_path = format!("/sys/class/power_supply/{bat}"); + let cap_path = format!("{bat_path}/capacity"); + let status_path = format!("{bat_path}/status"); + + // 2: Sleep + let sleep_secs = args + .next() + .expect("Invalid sleep duration") + .parse::() + .expect("Invalid sleep value"); + + let mut warnings: HashMap = HashMap::new(); + for arg in args { + let (lvl, value) = arg.split_at(1); + assert!( + lvl == "l" || lvl == "n" || lvl == "c", + "Unknown notification level" + ); + warnings.insert( + value.parse::().expect("Invalid battery value"), + lvl.to_string(), + ); + } + + let mut cap_cache = String::new(); + loop { + let cur_cap = read_file(&cap_path); + if cur_cap != cap_cache { + cap_cache.clone_from(&cur_cap); + if &read_file(&status_path) == "Charging" { continue; }; + let val = cur_cap + .parse::() + .expect("Couldn't parse capacity value"); + if let Some(lvl) = warnings.get(&val) { + notify(lvl, val); + }; + } + sleep(Duration::from_secs(sleep_secs)); + } +} + +fn read_file(path: &str) -> String { + let mut f = File::open(path).expect("Could't open file"); + let mut buf = String::new(); + f.read_to_string(&mut buf).expect("Couldn't read file"); + buf.trim().to_string() +} + +fn notify(lvl: &str, remaining: u8) { + let urgency = match lvl { + "l" => "low", + "n" => "normal", + "c" => "critical", + _ => unreachable!(), + }; + let notif = format!("Remaining battery capacity: {remaining}"); + Command::new("notify-send") + .arg("--app-name=esbnd") + .arg("--category=device") + .arg("--icon=battery-low-symbolic") + .arg("-u") + .arg(urgency) + .arg(notif) + .spawn() + .expect("Couldn't send notification"); +} -- cgit v1.2.3