use std::fs; // use std::fmt; use std::path::Path; fn read_gpu_stats(dir: String) -> Result> { // print!("Opening {}\n", dir); let filename_usage = format!("{}/gpu_busy_percent", dir); let dirname = format!("{}/hwmon", dir); let dir = Path::new(&dirname); // let usage = fs::read_to_string(filename_usage)?.trim_end().parse::()?; let usage = format!("{}", fs::read_to_string(filename_usage)?.trim_end()); // No need to convert from ASCII to int to ASCII let hwmon_path = fs::read_dir(dir)?.next().unwrap()?.path(); let mut temp_str = "".to_owned(); for i in 1..=8 { let path = hwmon_path.join(format!("temp{i}_input")); let lbl = hwmon_path.join(format!("temp{i}_label")); let symbol = match fs::read_to_string(lbl) { Ok(s) => match s.trim_end() { "junction" => "", "mem" => "", _ => "", // Includes "edge" }, _ => "", // Default icon if no label found }; match fs::read_to_string(path) { Ok(s) => { // let temperature_int = s.trim_end().parse::()? / 1000; let t = s.get(0..s.len()-4).unwrap_or(""); if i > 1 {temp_str.push_str(" ")}; // temp_str.push_str(&format!("{symbol}{t:>3}℃")) temp_str.push_str(&format!("{symbol}{t:>2}℃")) // If the temp hits 100C we have bigger problems than a layout shift }, _ => break, }; } // // let temperature = fs::read_to_string(path)?.trim_end().parse::()? / 1000; // let temp_raw = fs::read_to_string(hwmon_path.join("temp1_input"))?; // let temperature = format!("{}", temp_raw.get(0..temp_raw.len()-4).unwrap_or("")); // return Ok(format!("{:>3}% {:>3}℃", usage, temperature)); return Ok(format!("{:>3}% {}", usage, temp_str)); } fn main() { let mut output_str = " ".to_owned(); for i in 0..8 { let dir = format!("/sys/class/drm/card{}/device", i); match read_gpu_stats(dir) { Ok(s) => { if i > 0 {output_str.push_str("\r ")}; // Gap between GPUs output_str.push_str(&s) }, _ => break, }; } print!("{}\n", output_str); }