From acd20b98f21ee01a9c150041358b1cc272652f92 Mon Sep 17 00:00:00 2001 From: Camerooooon Date: Sun, 19 Jun 2022 20:31:41 -0700 Subject: [PATCH 01/10] Add command for iterating through thermal zone --- src/interface.rs | 6 ++++++ src/main.rs | 13 +++++++++++++ src/thermal.rs | 30 ++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 src/thermal.rs diff --git a/src/interface.rs b/src/interface.rs index eca3b5d6..52ad3fc8 100644 --- a/src/interface.rs +++ b/src/interface.rs @@ -1,5 +1,6 @@ use super::config::Config; use super::daemon::{daemon_init, Checker}; +use super::thermal::read_thermal_zones; use super::display::{ print_available_governors, print_cpu_governors, print_cpu_speeds, print_cpu_temp, print_cpus, print_freq, print_power, print_turbo, @@ -17,6 +18,7 @@ pub trait Getter { fn freq(&self, raw: bool); fn power(&self, raw: bool); fn usage(&self, raw: bool); + fn thermal(&self, raw: bool); fn turbo(&self, raw: bool); fn available_govs(&self, raw: bool); fn cpus(&self, raw: bool); @@ -72,6 +74,10 @@ impl Getter for Get { } } + fn thermal(&self, raw: bool) { + read_thermal_zones(); + } + fn turbo(&self, raw: bool) { match check_turbo_enabled() { Ok(turbo_enabled) => print_turbo(turbo_enabled, raw), diff --git a/src/main.rs b/src/main.rs index cc50440b..05167e9a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -47,6 +47,7 @@ pub mod power; pub mod settings; pub mod system; pub mod terminal; +pub mod thermal; #[derive(StructOpt)] enum GetType { @@ -56,6 +57,13 @@ enum GetType { #[structopt(short, long)] raw: bool, }, + + /// Get the thermal zones + #[structopt(name = "thermal")] + Thermal { + #[structopt(short, long)] + raw: bool, + }, /// Get the power #[structopt(name = "usage")] @@ -250,9 +258,14 @@ fn parse_args(config: config::Config) { GetType::Power { raw } => { int.get.power(raw); } + GetType::Usage { raw } => { int.get.usage(raw); } + + GetType::Thermal { raw } => { + int.get.thermal(raw); + } GetType::Turbo { raw } => { int.get.turbo(raw); diff --git a/src/thermal.rs b/src/thermal.rs new file mode 100644 index 00000000..e42df1c6 --- /dev/null +++ b/src/thermal.rs @@ -0,0 +1,30 @@ +use std::fs::{read_dir}; + +pub struct ThermalZone { + pub name: String, + pub location: String, + pub temp: i32, + pub enabled: bool, +} + +impl Default for ThermalZone { + fn default() -> Self { + ThermalZone { + name: "unknown".to_string(), + location: "unknown".to_string(), + temp: 0, + enabled: false, + } + } +} + +pub fn read_thermal_zones() -> Vec:: { + let mut zones = Vec::::new(); + + for a in read_dir("/sys/class/thermal/").expect("Could not read thermal directory") { + let path_string: String = format!("{:?}", a.unwrap().path()); + println!("{}", path_string); + + } + zones +} From 18d65548400d7e58ad9acac289aaa489b07fb97d Mon Sep 17 00:00:00 2001 From: Camerooooon Date: Sun, 19 Jun 2022 20:58:36 -0700 Subject: [PATCH 02/10] Only list thermal zones not cooling devices --- src/thermal.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/thermal.rs b/src/thermal.rs index e42df1c6..59e3c42d 100644 --- a/src/thermal.rs +++ b/src/thermal.rs @@ -1,5 +1,7 @@ use std::fs::{read_dir}; +const THERMAL_ZONE_DIR: &str = "/sys/class/thermal/"; + pub struct ThermalZone { pub name: String, pub location: String, @@ -21,8 +23,11 @@ impl Default for ThermalZone { pub fn read_thermal_zones() -> Vec:: { let mut zones = Vec::::new(); - for a in read_dir("/sys/class/thermal/").expect("Could not read thermal directory") { - let path_string: String = format!("{:?}", a.unwrap().path()); + for a in read_dir(THERMAL_ZONE_DIR).expect("Could not read thermal directory") { + let path_string: String = format!("{}", a.unwrap().path().to_string_lossy()); + if !path_string.starts_with(&[THERMAL_ZONE_DIR, "thermal_zone"].concat()) { + continue; + } println!("{}", path_string); } From 532b05f97c60f16a31598970b92ab546876ded83 Mon Sep 17 00:00:00 2001 From: Camerooooon Date: Sun, 19 Jun 2022 20:58:54 -0700 Subject: [PATCH 03/10] Formatting --- src/interface.rs | 2 +- src/main.rs | 4 ++-- src/thermal.rs | 5 ++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/interface.rs b/src/interface.rs index 52ad3fc8..b1eba9e9 100644 --- a/src/interface.rs +++ b/src/interface.rs @@ -1,6 +1,5 @@ use super::config::Config; use super::daemon::{daemon_init, Checker}; -use super::thermal::read_thermal_zones; use super::display::{ print_available_governors, print_cpu_governors, print_cpu_speeds, print_cpu_temp, print_cpus, print_freq, print_power, print_turbo, @@ -11,6 +10,7 @@ use super::system::{ check_available_governors, check_cpu_freq, check_cpu_name, check_turbo_enabled, get_cpu_percent, list_cpu_governors, list_cpu_speeds, list_cpu_temp, list_cpus, }; +use super::thermal::read_thermal_zones; pub struct Get {} diff --git a/src/main.rs b/src/main.rs index 05167e9a..357fa2be 100644 --- a/src/main.rs +++ b/src/main.rs @@ -57,7 +57,7 @@ enum GetType { #[structopt(short, long)] raw: bool, }, - + /// Get the thermal zones #[structopt(name = "thermal")] Thermal { @@ -262,7 +262,7 @@ fn parse_args(config: config::Config) { GetType::Usage { raw } => { int.get.usage(raw); } - + GetType::Thermal { raw } => { int.get.thermal(raw); } diff --git a/src/thermal.rs b/src/thermal.rs index 59e3c42d..57217631 100644 --- a/src/thermal.rs +++ b/src/thermal.rs @@ -1,4 +1,4 @@ -use std::fs::{read_dir}; +use std::fs::read_dir; const THERMAL_ZONE_DIR: &str = "/sys/class/thermal/"; @@ -20,7 +20,7 @@ impl Default for ThermalZone { } } -pub fn read_thermal_zones() -> Vec:: { +pub fn read_thermal_zones() -> Vec { let mut zones = Vec::::new(); for a in read_dir(THERMAL_ZONE_DIR).expect("Could not read thermal directory") { @@ -29,7 +29,6 @@ pub fn read_thermal_zones() -> Vec:: { continue; } println!("{}", path_string); - } zones } From 5fe5bc983433326e39abafb585240df264b65e81 Mon Sep 17 00:00:00 2001 From: Camerooooon Date: Sun, 19 Jun 2022 21:47:29 -0700 Subject: [PATCH 04/10] Make read_int and read_str work outside of only cpus --- src/cpu.rs | 42 +++++------------------------------------- src/system.rs | 21 +++++++++++++++++++++ src/thermal.rs | 8 ++++++++ 3 files changed, 34 insertions(+), 37 deletions(-) diff --git a/src/cpu.rs b/src/cpu.rs index 0b37710b..ce5841c3 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -3,15 +3,13 @@ use std::io::{Read, Write}; use std::path::Path; use super::display::{print_cpu, render_cpu}; -use super::system::{calculate_cpu_percent, ProcStat}; +use super::system::{calculate_cpu_percent, ProcStat, read_int, read_str}; use super::Error; #[cfg(test)] use mockall::{automock, predicate::*}; #[cfg_attr(test, automock)] pub trait Speed { - fn read_int(&mut self, sub_path: &str) -> i32; - fn read_str(&mut self, sub_path: &str) -> String; fn read_temp(&mut self, sub_path: &str) -> Result; fn write_value(&mut self, value: WritableValue) -> Result<(), Error>; fn update(&mut self) -> Result<(), Error>; @@ -49,36 +47,6 @@ pub enum WritableValue { } impl Speed for CPU { - /// A generic function to take a path and a single cpu (single core) and get an i32 - fn read_int(&mut self, sub_path: &str) -> i32 { - let mut info: String = String::new(); - let cpu_info_path: String = format!("/sys/devices/system/cpu/{}/{}", self.name, sub_path); - - File::open(cpu_info_path) - .unwrap() - .read_to_string(&mut info) - .unwrap(); - - // Remove newline - info.pop(); - info.parse::() - .unwrap_or_else(|e| panic!("Could not parse {}\n{}", sub_path, e)) - } - - fn read_str(&mut self, sub_path: &str) -> String { - let mut info: String = String::new(); - let cpu_info_path: String = format!("/sys/devices/system/cpu/{}/{}", self.name, sub_path); - - File::open(cpu_info_path) - .unwrap() - .read_to_string(&mut info) - .unwrap(); - - // Remove newline - info.pop(); - info - } - fn read_temp(&mut self, sub_path: &str) -> Result { let mut info: String = String::new(); let cpu_info_path: String = format!( @@ -163,15 +131,15 @@ impl Speed for CPU { } fn get_max(&mut self) { - self.max_freq = self.read_int("cpufreq/scaling_max_freq"); + self.max_freq = read_int(&format!("/sys/devices/system/cpu/{}/{}", self.name, "cpufreq/scaling_max_freq")).unwrap_or(0); } fn get_min(&mut self) { - self.min_freq = self.read_int("cpufreq/scaling_min_freq"); + self.min_freq = read_int(&format!("/sys/devices/system/cpu/{}/{}", self.name, "cpufreq/scaling_min_freq")).unwrap_or(0); } fn get_cur(&mut self) { - self.cur_freq = self.read_int("cpufreq/scaling_cur_freq"); + self.cur_freq = read_int(&format!("/sys/devices/system/cpu/{}/{}", self.name, "cpufreq/scaling_cur_freq")).unwrap_or(0); } fn get_temp(&mut self) -> Result<(), Error> { @@ -180,7 +148,7 @@ impl Speed for CPU { } fn get_gov(&mut self) -> Result<(), Error> { - self.gov = self.read_str("cpufreq/scaling_governor"); + self.gov = read_str(&format!("/sys/devices/system/cpu/{}/{}", self.name, "cpufreq/scaling_governor")).unwrap_or("unknown".to_string()); Ok(()) } diff --git a/src/system.rs b/src/system.rs index fe842194..75f914a5 100644 --- a/src/system.rs +++ b/src/system.rs @@ -290,6 +290,27 @@ pub fn list_cpu_governors() -> Vec { list_cpus().into_iter().map(|x| x.gov).collect() } +pub fn read_int(path: &str) -> Result { + let mut value: String = String::new(); + + File::open(path)?.read_to_string(&mut value)?; + + // Remove trailing newline + value.pop(); + Ok(value.parse::().unwrap_or_else(|e| panic!("Could not parse {}\n{}", path, e))) +} + +pub fn read_str(path: &str) -> Result { + let mut value: String = String::new(); + + File::open(path)?.read_to_string(&mut value)?; + + // Remove trailing newline + value.pop(); + Ok(value) +} + + #[cfg(test)] mod tests { use std::any::type_name; diff --git a/src/thermal.rs b/src/thermal.rs index 57217631..d1325342 100644 --- a/src/thermal.rs +++ b/src/thermal.rs @@ -1,4 +1,5 @@ use std::fs::read_dir; +use super::Error; const THERMAL_ZONE_DIR: &str = "/sys/class/thermal/"; @@ -9,6 +10,10 @@ pub struct ThermalZone { pub enabled: bool, } +pub trait Thermal { + fn update(&mut self) -> Result<(), Error>; +} + impl Default for ThermalZone { fn default() -> Self { ThermalZone { @@ -28,6 +33,9 @@ pub fn read_thermal_zones() -> Vec { if !path_string.starts_with(&[THERMAL_ZONE_DIR, "thermal_zone"].concat()) { continue; } + + + println!("{}", path_string); } zones From 098a7ace3613862025f24cfd9183b9cb9bba2587 Mon Sep 17 00:00:00 2001 From: Camerooooon Date: Sun, 19 Jun 2022 21:47:38 -0700 Subject: [PATCH 05/10] Cargo format --- src/cpu.rs | 26 +++++++++++++++++++++----- src/system.rs | 5 +++-- src/thermal.rs | 4 +--- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/cpu.rs b/src/cpu.rs index ce5841c3..73b5d2ba 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -3,7 +3,7 @@ use std::io::{Read, Write}; use std::path::Path; use super::display::{print_cpu, render_cpu}; -use super::system::{calculate_cpu_percent, ProcStat, read_int, read_str}; +use super::system::{calculate_cpu_percent, read_int, read_str, ProcStat}; use super::Error; #[cfg(test)] @@ -131,15 +131,27 @@ impl Speed for CPU { } fn get_max(&mut self) { - self.max_freq = read_int(&format!("/sys/devices/system/cpu/{}/{}", self.name, "cpufreq/scaling_max_freq")).unwrap_or(0); + self.max_freq = read_int(&format!( + "/sys/devices/system/cpu/{}/{}", + self.name, "cpufreq/scaling_max_freq" + )) + .unwrap_or(0); } fn get_min(&mut self) { - self.min_freq = read_int(&format!("/sys/devices/system/cpu/{}/{}", self.name, "cpufreq/scaling_min_freq")).unwrap_or(0); + self.min_freq = read_int(&format!( + "/sys/devices/system/cpu/{}/{}", + self.name, "cpufreq/scaling_min_freq" + )) + .unwrap_or(0); } fn get_cur(&mut self) { - self.cur_freq = read_int(&format!("/sys/devices/system/cpu/{}/{}", self.name, "cpufreq/scaling_cur_freq")).unwrap_or(0); + self.cur_freq = read_int(&format!( + "/sys/devices/system/cpu/{}/{}", + self.name, "cpufreq/scaling_cur_freq" + )) + .unwrap_or(0); } fn get_temp(&mut self) -> Result<(), Error> { @@ -148,7 +160,11 @@ impl Speed for CPU { } fn get_gov(&mut self) -> Result<(), Error> { - self.gov = read_str(&format!("/sys/devices/system/cpu/{}/{}", self.name, "cpufreq/scaling_governor")).unwrap_or("unknown".to_string()); + self.gov = read_str(&format!( + "/sys/devices/system/cpu/{}/{}", + self.name, "cpufreq/scaling_governor" + )) + .unwrap_or("unknown".to_string()); Ok(()) } diff --git a/src/system.rs b/src/system.rs index 75f914a5..c77d402c 100644 --- a/src/system.rs +++ b/src/system.rs @@ -297,7 +297,9 @@ pub fn read_int(path: &str) -> Result { // Remove trailing newline value.pop(); - Ok(value.parse::().unwrap_or_else(|e| panic!("Could not parse {}\n{}", path, e))) + Ok(value + .parse::() + .unwrap_or_else(|e| panic!("Could not parse {}\n{}", path, e))) } pub fn read_str(path: &str) -> Result { @@ -310,7 +312,6 @@ pub fn read_str(path: &str) -> Result { Ok(value) } - #[cfg(test)] mod tests { use std::any::type_name; diff --git a/src/thermal.rs b/src/thermal.rs index d1325342..d779af2c 100644 --- a/src/thermal.rs +++ b/src/thermal.rs @@ -1,5 +1,5 @@ -use std::fs::read_dir; use super::Error; +use std::fs::read_dir; const THERMAL_ZONE_DIR: &str = "/sys/class/thermal/"; @@ -34,8 +34,6 @@ pub fn read_thermal_zones() -> Vec { continue; } - - println!("{}", path_string); } zones From 5f608b61bbf3cc8c50c16b787844919fa5467193 Mon Sep 17 00:00:00 2001 From: Camerooooon Date: Mon, 20 Jun 2022 22:09:03 -0700 Subject: [PATCH 06/10] Parsing and printing of thermal zones --- src/interface.rs | 9 ++++++++- src/thermal.rs | 29 ++++++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/interface.rs b/src/interface.rs index b1eba9e9..5f53db0d 100644 --- a/src/interface.rs +++ b/src/interface.rs @@ -75,7 +75,14 @@ impl Getter for Get { } fn thermal(&self, raw: bool) { - read_thermal_zones(); + let zones = read_thermal_zones(); + if raw { + println!("{:?}", zones) + } else { + for zone in zones { + println!("{}", zone); + } + } } fn turbo(&self, raw: bool) { diff --git a/src/thermal.rs b/src/thermal.rs index d779af2c..f0a89ac4 100644 --- a/src/thermal.rs +++ b/src/thermal.rs @@ -1,11 +1,16 @@ use super::Error; +use std::fmt::Formatter; +use std::fmt::Display; +use super::system::{read_int, read_str}; use std::fs::read_dir; +use colored::*; const THERMAL_ZONE_DIR: &str = "/sys/class/thermal/"; +#[derive(Debug)] pub struct ThermalZone { pub name: String, - pub location: String, + pub path: String, pub temp: i32, pub enabled: bool, } @@ -18,13 +23,20 @@ impl Default for ThermalZone { fn default() -> Self { ThermalZone { name: "unknown".to_string(), - location: "unknown".to_string(), + path: "unknown".to_string(), temp: 0, enabled: false, } } } +impl Display for ThermalZone { + fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { + + write!(f, "{} {} {}", if self.enabled { self.name.green() } else { self.name.red() }, self.temp.to_string().yellow(), self.path) + } +} + pub fn read_thermal_zones() -> Vec { let mut zones = Vec::::new(); @@ -34,7 +46,18 @@ pub fn read_thermal_zones() -> Vec { continue; } - println!("{}", path_string); + let mut zone = ThermalZone::default(); + + zone.temp = read_int(&[&path_string, "/temp"].concat()).unwrap_or(0); + zone.name = read_str(&[&path_string, "/type"].concat()).unwrap_or("unknown".to_string()); + zone.enabled = if read_str(&[&path_string, "/mode"].concat()).unwrap_or("disable".to_string()) == "enabled" { + true + } else { + false + }; + zone.path = path_string; + + zones.push(zone); } zones } From beaf908614277edaed8e2be45eedde69b6ce85e3 Mon Sep 17 00:00:00 2001 From: Camerooooon Date: Mon, 20 Jun 2022 22:21:22 -0700 Subject: [PATCH 07/10] Remove old test because it doesn't seem to be useful anymore --- src/cpu.rs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/cpu.rs b/src/cpu.rs index 73b5d2ba..d0e53527 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -187,14 +187,16 @@ impl Speed for CPU { mod tests { use super::*; - #[test] - fn render_unit_test() { - let mut mock = MockSpeed::new(); - mock.expect_read_int().return_const(42); - mock.expect_read_str().return_const("yflat".to_string()); - - // This passes, as expected - assert_eq!(mock.read_str("zflat"), "yflat"); - assert_eq!(mock.read_int("abc"), 42); - } + // Since the read_int and read_str functions are no longer implemented for speed this test is + // pointless I beleive. + // #[test] + // fn render_unit_test() { + // let mut mock = MockSpeed::new(); + // mock.expect_read_int().return_const(42); + // mock.expect_read_str().return_const("yflat".to_string()); + + // // This passes, as expected + // assert_eq!(mock.read_str("zflat"), "yflat"); + // assert_eq!(mock.read_int("abc"), 42); + // } } From 83904e2ff8f6427f124d9a3bd4cd3b615455367c Mon Sep 17 00:00:00 2001 From: Camerooooon Date: Mon, 20 Jun 2022 22:21:49 -0700 Subject: [PATCH 08/10] Cargo fomat --- src/thermal.rs | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/thermal.rs b/src/thermal.rs index f0a89ac4..071a6504 100644 --- a/src/thermal.rs +++ b/src/thermal.rs @@ -1,9 +1,9 @@ +use super::system::{read_int, read_str}; use super::Error; -use std::fmt::Formatter; +use colored::*; use std::fmt::Display; -use super::system::{read_int, read_str}; +use std::fmt::Formatter; use std::fs::read_dir; -use colored::*; const THERMAL_ZONE_DIR: &str = "/sys/class/thermal/"; @@ -32,8 +32,17 @@ impl Default for ThermalZone { impl Display for ThermalZone { fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { - - write!(f, "{} {} {}", if self.enabled { self.name.green() } else { self.name.red() }, self.temp.to_string().yellow(), self.path) + write!( + f, + "{} {} {}", + if self.enabled { + self.name.green() + } else { + self.name.red() + }, + self.temp.to_string().yellow(), + self.path + ) } } @@ -50,7 +59,10 @@ pub fn read_thermal_zones() -> Vec { zone.temp = read_int(&[&path_string, "/temp"].concat()).unwrap_or(0); zone.name = read_str(&[&path_string, "/type"].concat()).unwrap_or("unknown".to_string()); - zone.enabled = if read_str(&[&path_string, "/mode"].concat()).unwrap_or("disable".to_string()) == "enabled" { + zone.enabled = if read_str(&[&path_string, "/mode"].concat()) + .unwrap_or("disable".to_string()) + == "enabled" + { true } else { false From 8eed10a98f00fce069ae0f662530834a535fff85 Mon Sep 17 00:00:00 2001 From: Camerooooon Date: Mon, 20 Jun 2022 23:06:48 -0700 Subject: [PATCH 09/10] Remove old tests --- src/cpu.rs | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/cpu.rs b/src/cpu.rs index d0e53527..f976b456 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -182,21 +182,3 @@ impl Speed for CPU { render_cpu(self) } } - -#[cfg(test)] -mod tests { - use super::*; - - // Since the read_int and read_str functions are no longer implemented for speed this test is - // pointless I beleive. - // #[test] - // fn render_unit_test() { - // let mut mock = MockSpeed::new(); - // mock.expect_read_int().return_const(42); - // mock.expect_read_str().return_const("yflat".to_string()); - - // // This passes, as expected - // assert_eq!(mock.read_str("zflat"), "yflat"); - // assert_eq!(mock.read_int("abc"), 42); - // } -} From fa8d715fd9a58662651326d68aa377a537bfc606 Mon Sep 17 00:00:00 2001 From: Camerooooon Date: Mon, 20 Jun 2022 23:13:02 -0700 Subject: [PATCH 10/10] Improve look of get thermal command --- src/thermal.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/thermal.rs b/src/thermal.rs index 071a6504..298cb70e 100644 --- a/src/thermal.rs +++ b/src/thermal.rs @@ -34,13 +34,14 @@ impl Display for ThermalZone { fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { write!( f, - "{} {} {}", + "{} {}{} {}", if self.enabled { self.name.green() } else { self.name.red() }, - self.temp.to_string().yellow(), + (self.temp / 1000).to_string().yellow(), + "C°".yellow(), self.path ) }