use std::collections::HashMap; use std::fs; use std::io::Write; #[derive(Debug)] pub struct ThermalDevice { pub name: String, pub celsius: i32, } pub fn read_thermal_devices() -> Vec { let mut by_name: HashMap = HashMap::new(); for i in 0.. { 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; } } let mut devices: Vec = 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) { 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 = 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}\"") }