Initial commit
This commit is contained in:
parent
3100ee0591
commit
633467b6f2
13 changed files with 158 additions and 41 deletions
|
|
@ -2,6 +2,21 @@ use crate::{App, AppInput};
|
|||
use relm4::ComponentSender;
|
||||
use std::{fs, path::PathBuf, sync::Mutex};
|
||||
|
||||
const WIFI_STRONG: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/assets/WiFi Strong.svg");
|
||||
const WIFI_MEDIUM: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/assets/WiFi Medium.svg");
|
||||
const WIFI_WEAK: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/assets/WiFi Weak.svg");
|
||||
const WIFI_OFF: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/assets/WiFi Connecting.svg");
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Stats {
|
||||
pub cpu: String,
|
||||
pub mem: String,
|
||||
pub power: String,
|
||||
pub bat: String,
|
||||
pub wifi_ssid: String,
|
||||
pub wifi_icon: &'static str,
|
||||
}
|
||||
|
||||
struct CpuSnapshot {
|
||||
total: u64,
|
||||
idle: u64,
|
||||
|
|
@ -35,7 +50,7 @@ fn read_cpu() -> f32 {
|
|||
(dtotal - didle) as f32 / dtotal as f32 * 100.0
|
||||
}
|
||||
|
||||
fn read_ram() -> f32 {
|
||||
fn read_ram() -> u64 {
|
||||
let text = fs::read_to_string("/proc/meminfo").unwrap_or_default();
|
||||
let mut total = 0u64;
|
||||
let mut avail = 0u64;
|
||||
|
|
@ -47,10 +62,7 @@ fn read_ram() -> f32 {
|
|||
_ => {}
|
||||
}
|
||||
}
|
||||
if total == 0 {
|
||||
return 0.0;
|
||||
}
|
||||
(total - avail) as f32 / total as f32 * 100.0
|
||||
total.saturating_sub(avail)
|
||||
}
|
||||
|
||||
fn bat_path() -> Option<PathBuf> {
|
||||
|
|
@ -92,29 +104,76 @@ fn read_battery() -> Option<u8> {
|
|||
.ok()
|
||||
}
|
||||
|
||||
async fn read_wifi() -> String {
|
||||
let out = tokio::process::Command::new("iw")
|
||||
async fn read_wifi() -> (String, &'static str) {
|
||||
let dev_out = tokio::process::Command::new("iw")
|
||||
.arg("dev")
|
||||
.output()
|
||||
.await
|
||||
.ok();
|
||||
let stdout = match out {
|
||||
let dev_stdout = match dev_out {
|
||||
Some(o) if o.status.success() => String::from_utf8_lossy(&o.stdout).into_owned(),
|
||||
_ => return "—".into(),
|
||||
_ => return ("—".into(), WIFI_OFF),
|
||||
};
|
||||
stdout
|
||||
|
||||
let iface = dev_stdout
|
||||
.lines()
|
||||
.find_map(|l| l.trim().strip_prefix("ssid ").map(str::to_string))
|
||||
.unwrap_or_else(|| "—".into())
|
||||
.find_map(|l| l.trim().strip_prefix("Interface ").map(str::to_string));
|
||||
let Some(iface) = iface else {
|
||||
return ("—".into(), WIFI_OFF);
|
||||
};
|
||||
|
||||
let link_out = tokio::process::Command::new("iw")
|
||||
.args(["dev", &iface, "link"])
|
||||
.output()
|
||||
.await
|
||||
.ok();
|
||||
let link_stdout = match link_out {
|
||||
Some(o) if o.status.success() => String::from_utf8_lossy(&o.stdout).into_owned(),
|
||||
_ => return ("—".into(), WIFI_OFF),
|
||||
};
|
||||
|
||||
let mut ssid = None;
|
||||
let mut rssi: Option<i32> = None;
|
||||
for line in link_stdout.lines() {
|
||||
let t = line.trim();
|
||||
if let Some(s) = t.strip_prefix("SSID: ") {
|
||||
ssid = Some(s.to_string());
|
||||
} else if let Some(r) = t.strip_prefix("signal: ") {
|
||||
rssi = r.split_whitespace().next().and_then(|s| s.parse().ok());
|
||||
}
|
||||
}
|
||||
|
||||
let Some(ssid) = ssid else {
|
||||
return ("—".into(), WIFI_OFF);
|
||||
};
|
||||
|
||||
let icon = match rssi {
|
||||
Some(r) if r >= -55 => WIFI_STRONG,
|
||||
Some(r) if r >= -70 => WIFI_MEDIUM,
|
||||
_ => WIFI_WEAK,
|
||||
};
|
||||
|
||||
(ssid, icon)
|
||||
}
|
||||
|
||||
pub async fn poll() -> String {
|
||||
pub async fn poll() -> Stats {
|
||||
let cpu = read_cpu();
|
||||
let ram = read_ram();
|
||||
let power = read_power().map_or_else(|| "—W".into(), |w| format!("{w:.1}W"));
|
||||
let bat = read_battery().map_or_else(|| "—".into(), |p| format!("{p}%"));
|
||||
let wifi = read_wifi().await;
|
||||
format!("CPU {cpu:.0}% MEM {ram:.0}% {power} BAT {bat} {wifi}")
|
||||
let mem = read_ram();
|
||||
let power = read_power().map_or_else(|| " —W".into(), |w| format!("{w:4.1}W"));
|
||||
let bat = read_battery().map_or_else(|| " —".into(), |p| format!("{p:3}%"));
|
||||
let (wifi_ssid, wifi_icon) = read_wifi().await;
|
||||
Stats {
|
||||
cpu: format!("{cpu:3.0}%"),
|
||||
mem: if mem >= 1024 * 1024 {
|
||||
format!("{:.1}G", mem as f32 / (1024.0 * 1024.0))
|
||||
} else {
|
||||
format!("{}M", mem / 1024)
|
||||
},
|
||||
power,
|
||||
bat,
|
||||
wifi_ssid,
|
||||
wifi_icon,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn spawn_poller(sender: ComponentSender<App>) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue