summaryrefslogtreecommitdiff
path: root/main.rs
diff options
context:
space:
mode:
authorfxqnlr <[email protected]>2024-09-23 14:52:55 +0200
committerfxqnlr <[email protected]>2024-09-23 14:52:55 +0200
commit0bd5337ad4aeddf5b3a709a95dbeaab75dfa8454 (patch)
tree845cfe0e388ba06a391e7f974aaa549b3459cece /main.rs
downloadesbnd-0bd5337ad4aeddf5b3a709a95dbeaab75dfa8454.tar
esbnd-0bd5337ad4aeddf5b3a709a95dbeaab75dfa8454.tar.gz
esbnd-0bd5337ad4aeddf5b3a709a95dbeaab75dfa8454.zip
initial commit
Diffstat (limited to 'main.rs')
-rw-r--r--main.rs82
1 files changed, 82 insertions, 0 deletions
diff --git a/main.rs b/main.rs
new file mode 100644
index 0000000..d6bf3d9
--- /dev/null
+++ b/main.rs
@@ -0,0 +1,82 @@
1use std::{
2 collections::HashMap, env, fs::File, io::Read, process::Command, thread::sleep, time::Duration,
3};
4
5fn main() {
6 let mut args = env::args();
7
8 assert!(
9 args.len() > 2,
10 "Too few arguments, provide battery id and values with warning levels"
11 );
12 // Skip process (argc[0])
13 args.next();
14
15 // 1: Battery ID
16 let bat = args.next().expect("Invalid Battery id");
17 let bat_path = format!("/sys/class/power_supply/{bat}");
18 let cap_path = format!("{bat_path}/capacity");
19 let status_path = format!("{bat_path}/status");
20
21 // 2: Sleep
22 let sleep_secs = args
23 .next()
24 .expect("Invalid sleep duration")
25 .parse::<u64>()
26 .expect("Invalid sleep value");
27
28 let mut warnings: HashMap<u8, String> = HashMap::new();
29 for arg in args {
30 let (lvl, value) = arg.split_at(1);
31 assert!(
32 lvl == "l" || lvl == "n" || lvl == "c",
33 "Unknown notification level"
34 );
35 warnings.insert(
36 value.parse::<u8>().expect("Invalid battery value"),
37 lvl.to_string(),
38 );
39 }
40
41 let mut cap_cache = String::new();
42 loop {
43 let cur_cap = read_file(&cap_path);
44 if cur_cap != cap_cache {
45 cap_cache.clone_from(&cur_cap);
46 if &read_file(&status_path) == "Charging" { continue; };
47 let val = cur_cap
48 .parse::<u8>()
49 .expect("Couldn't parse capacity value");
50 if let Some(lvl) = warnings.get(&val) {
51 notify(lvl, val);
52 };
53 }
54 sleep(Duration::from_secs(sleep_secs));
55 }
56}
57
58fn read_file(path: &str) -> String {
59 let mut f = File::open(path).expect("Could't open file");
60 let mut buf = String::new();
61 f.read_to_string(&mut buf).expect("Couldn't read file");
62 buf.trim().to_string()
63}
64
65fn notify(lvl: &str, remaining: u8) {
66 let urgency = match lvl {
67 "l" => "low",
68 "n" => "normal",
69 "c" => "critical",
70 _ => unreachable!(),
71 };
72 let notif = format!("Remaining battery capacity: {remaining}");
73 Command::new("notify-send")
74 .arg("--app-name=esbnd")
75 .arg("--category=device")
76 .arg("--icon=battery-low-symbolic")
77 .arg("-u")
78 .arg(urgency)
79 .arg(notif)
80 .spawn()
81 .expect("Couldn't send notification");
82}