temperature: per-device breakdown in panel, device filter config option
This commit is contained in:
parent
8bbe211dd4
commit
88a0886681
6 changed files with 144 additions and 16 deletions
|
|
@ -1,25 +1,79 @@
|
|||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
|
||||
pub fn read_temp_celsius() -> Option<i32> {
|
||||
let mut max: Option<i32> = None;
|
||||
#[derive(Debug)]
|
||||
pub struct ThermalDevice {
|
||||
pub name: String,
|
||||
pub celsius: i32,
|
||||
}
|
||||
|
||||
pub fn read_thermal_devices() -> Vec<ThermalDevice> {
|
||||
let mut by_name: HashMap<String, i32> = HashMap::new();
|
||||
|
||||
for i in 0.. {
|
||||
let path = format!("/sys/class/thermal/thermal_zone{i}/temp");
|
||||
match fs::read_to_string(&path) {
|
||||
Ok(s) => {
|
||||
if let Ok(millic) = s.trim().parse::<i32>() {
|
||||
let c = millic / 1000;
|
||||
max = Some(max.map_or(c, |m: i32| m.max(c)));
|
||||
}
|
||||
}
|
||||
let temp_path = format!("/sys/class/thermal/thermal_zone{i}/temp");
|
||||
let type_path = format!("/sys/class/thermal/thermal_zone{i}/type");
|
||||
|
||||
let temp_str = match fs::read_to_string(&temp_path) {
|
||||
Ok(s) => s,
|
||||
Err(_) => break,
|
||||
};
|
||||
|
||||
let millic: i32 = match temp_str.trim().parse() {
|
||||
Ok(v) => v,
|
||||
Err(_) => continue,
|
||||
};
|
||||
let celsius = millic / 1000;
|
||||
|
||||
let name = fs::read_to_string(&type_path)
|
||||
.map(|s| s.trim().to_string())
|
||||
.unwrap_or_else(|_| format!("zone{i}"));
|
||||
|
||||
// Keep the highest temp seen for each device type
|
||||
let entry = by_name.entry(name).or_insert(celsius);
|
||||
if celsius > *entry {
|
||||
*entry = celsius;
|
||||
}
|
||||
}
|
||||
max
|
||||
|
||||
let mut devices: Vec<ThermalDevice> = by_name
|
||||
.into_iter()
|
||||
.map(|(name, celsius)| ThermalDevice { name, celsius })
|
||||
.collect();
|
||||
|
||||
// Sort descending by temp so the hottest shows first
|
||||
devices.sort_by(|a, b| b.celsius.cmp(&a.celsius));
|
||||
devices
|
||||
}
|
||||
|
||||
pub fn emit_temp(out: &mut impl Write) {
|
||||
if let Some(c) = read_temp_celsius() {
|
||||
let _ = writeln!(out, "{{\"type\":\"temp\",\"celsius\":{c}}}");
|
||||
let devices = read_thermal_devices();
|
||||
if devices.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let max = devices.iter().map(|d| d.celsius).max().unwrap_or(0);
|
||||
|
||||
let devices_json: Vec<String> = devices
|
||||
.iter()
|
||||
.map(|d| {
|
||||
format!(
|
||||
"{{\"name\":{},\"celsius\":{}}}",
|
||||
json_str(&d.name),
|
||||
d.celsius
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let _ = writeln!(
|
||||
out,
|
||||
"{{\"type\":\"temp\",\"celsius\":{max},\"devices\":[{}]}}",
|
||||
devices_json.join(",")
|
||||
);
|
||||
}
|
||||
|
||||
fn json_str(s: &str) -> String {
|
||||
let escaped = s.replace('\\', "\\\\").replace('"', "\\\"");
|
||||
format!("\"{escaped}\"")
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue