feat(src/commands): add cooling profile descriptions and improve thermal detection
Implemented clearer cooling profile output by mapping mode codes to human‑readable names and prefixing with "(ASUS)". Refactored thermal detection loops for better readability and moved debug logging into the correct block for GPU cache creation. New Features - Map mode strings "0","1","2" to readable cooling profile names (Performance, Balanced, Quiet / Battery Saving) and print them with "(ASUS)" label. - Provide explicit cooling profile description in command output. Enhancements - Simplify Intel RAPL and AMD hwmon detection loops for clearer flow. - Adjust brace placement in GPU cache creation to ensure debug log is emitted only on successful cache write. - Minor formatting and style clean‑ups across battery, GPU, and power commands. Bug Fixes - Fix missing/incorrect closing braces in battery and power command parsers that previously caused compilation warnings. - Ensure thermal detection logic only accesses sysfs entries after successful directory read.
This commit is contained in:
4 files changed
+116
-111
No files matched your search
@@ -120,15 +120,14 @@ pub fn execute(command: &BatteryCommands) {
|
||||
let conservation_path =
|
||||
ideapad_entry.path().join("conservation_mode");
|
||||
if conservation_path.exists()
|
||||
&& let Ok(mode) = fs::read_to_string(&conservation_path) {
|
||||
if mode.trim() == "1" {
|
||||
println!(
|
||||
" Charge Limit: Conservation Mode (~60%)"
|
||||
);
|
||||
} else {
|
||||
println!(" Charge Limit: 100%");
|
||||
}
|
||||
&& let Ok(mode) = fs::read_to_string(&conservation_path)
|
||||
{
|
||||
if mode.trim() == "1" {
|
||||
println!(" Charge Limit: Conservation Mode (~60%)");
|
||||
} else {
|
||||
println!(" Charge Limit: 100%");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -270,9 +270,10 @@ fn create_cache_file() {
|
||||
}
|
||||
|
||||
if let Ok(json) = serde_json::to_string_pretty(&cache)
|
||||
&& fs::write(CACHE_FILE_PATH, json).is_ok() {
|
||||
log::debug!("Created file {}", CACHE_FILE_PATH);
|
||||
}
|
||||
&& fs::write(CACHE_FILE_PATH, json).is_ok()
|
||||
{
|
||||
log::debug!("Created file {}", CACHE_FILE_PATH);
|
||||
}
|
||||
}
|
||||
|
||||
fn read_cache_file() -> Result<Cache, String> {
|
||||
|
||||
+45
-44
@@ -14,8 +14,7 @@ fn set_cpu_governor(governor: &str) {
|
||||
for entry in entries.flatten() {
|
||||
let path = entry.path();
|
||||
let name = path.file_name().unwrap_or_default().to_string_lossy();
|
||||
if name.starts_with("cpu") && name.chars().nth(3).is_some_and(|c| c.is_ascii_digit())
|
||||
{
|
||||
if name.starts_with("cpu") && name.chars().nth(3).is_some_and(|c| c.is_ascii_digit()) {
|
||||
let scaling_gov_path = path.join("cpufreq/scaling_governor");
|
||||
if scaling_gov_path.exists() {
|
||||
match fs::write(&scaling_gov_path, governor) {
|
||||
@@ -48,8 +47,7 @@ fn set_energy_performance_preference(epp: &str) {
|
||||
for entry in entries.flatten() {
|
||||
let path = entry.path();
|
||||
let name = path.file_name().unwrap_or_default().to_string_lossy();
|
||||
if name.starts_with("cpu") && name.chars().nth(3).is_some_and(|c| c.is_ascii_digit())
|
||||
{
|
||||
if name.starts_with("cpu") && name.chars().nth(3).is_some_and(|c| c.is_ascii_digit()) {
|
||||
let epp_path = path.join("cpufreq/energy_performance_preference");
|
||||
if epp_path.exists() {
|
||||
match fs::write(&epp_path, epp) {
|
||||
@@ -75,39 +73,40 @@ fn set_intel_rapl_limit(watts: u32) -> bool {
|
||||
// Intel RAPL
|
||||
let rapl_dir = Path::new("/sys/class/powercap/intel-rapl");
|
||||
if rapl_dir.exists()
|
||||
&& let Ok(entries) = fs::read_dir(rapl_dir) {
|
||||
for entry in entries.flatten() {
|
||||
let path = entry.path();
|
||||
let name = path.file_name().unwrap_or_default().to_string_lossy();
|
||||
&& let Ok(entries) = fs::read_dir(rapl_dir)
|
||||
{
|
||||
for entry in entries.flatten() {
|
||||
let path = entry.path();
|
||||
let name = path.file_name().unwrap_or_default().to_string_lossy();
|
||||
|
||||
// Set limits for package-0 (entire CPU package)
|
||||
if name.starts_with("intel-rapl:") {
|
||||
let constraint_0 = path.join("constraint_0_power_limit_uw"); // PL1
|
||||
let constraint_1 = path.join("constraint_1_power_limit_uw"); // PL2
|
||||
// Set limits for package-0 (entire CPU package)
|
||||
if name.starts_with("intel-rapl:") {
|
||||
let constraint_0 = path.join("constraint_0_power_limit_uw"); // PL1
|
||||
let constraint_1 = path.join("constraint_1_power_limit_uw"); // PL2
|
||||
|
||||
if constraint_0.exists() {
|
||||
match fs::write(&constraint_0, microwatts.to_string()) {
|
||||
Ok(_) => {
|
||||
log::debug!("Set RAPL constraint 0 to {}uW", microwatts);
|
||||
success = true;
|
||||
}
|
||||
Err(e) => log::debug!("Failed to write RAPL 0: {}", e),
|
||||
if constraint_0.exists() {
|
||||
match fs::write(&constraint_0, microwatts.to_string()) {
|
||||
Ok(_) => {
|
||||
log::debug!("Set RAPL constraint 0 to {}uW", microwatts);
|
||||
success = true;
|
||||
}
|
||||
Err(e) => log::debug!("Failed to write RAPL 0: {}", e),
|
||||
}
|
||||
if constraint_1.exists() {
|
||||
// Usually PL2 (Boost limit) is set ~20% higher than PL1 (Sustained limit)
|
||||
// But for a strict override we clamp BOTH to the requested static wattage limit.
|
||||
match fs::write(&constraint_1, microwatts.to_string()) {
|
||||
Ok(_) => {
|
||||
log::debug!("Set RAPL constraint 1 to {}uW", microwatts);
|
||||
success = true;
|
||||
}
|
||||
Err(e) => log::debug!("Failed to write RAPL 1: {}", e),
|
||||
}
|
||||
if constraint_1.exists() {
|
||||
// Usually PL2 (Boost limit) is set ~20% higher than PL1 (Sustained limit)
|
||||
// But for a strict override we clamp BOTH to the requested static wattage limit.
|
||||
match fs::write(&constraint_1, microwatts.to_string()) {
|
||||
Ok(_) => {
|
||||
log::debug!("Set RAPL constraint 1 to {}uW", microwatts);
|
||||
success = true;
|
||||
}
|
||||
Err(e) => log::debug!("Failed to write RAPL 1: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
success
|
||||
}
|
||||
|
||||
@@ -118,27 +117,29 @@ fn set_amd_hwmon_limit(watts: u32) -> bool {
|
||||
// AMD hwmon (Typically exposed via hwmon platform drivers like k10temp or amd_pmc)
|
||||
let hwmon_dir = Path::new("/sys/class/hwmon");
|
||||
if hwmon_dir.exists()
|
||||
&& let Ok(entries) = fs::read_dir(hwmon_dir) {
|
||||
for entry in entries.flatten() {
|
||||
let path = entry.path();
|
||||
let power1_cap = path.join("power1_cap");
|
||||
let name_path = path.join("name");
|
||||
&& let Ok(entries) = fs::read_dir(hwmon_dir)
|
||||
{
|
||||
for entry in entries.flatten() {
|
||||
let path = entry.path();
|
||||
let power1_cap = path.join("power1_cap");
|
||||
let name_path = path.join("name");
|
||||
|
||||
if power1_cap.exists() {
|
||||
// Try to verify this is actually the CPU and not a generic sensor
|
||||
if let Ok(name) = fs::read_to_string(&name_path)
|
||||
&& name.trim().contains("amd") {
|
||||
match fs::write(&power1_cap, microwatts.to_string()) {
|
||||
Ok(_) => {
|
||||
log::debug!("Set AMD hwmon power1_cap to {}uW", microwatts);
|
||||
success = true;
|
||||
}
|
||||
Err(e) => log::debug!("Failed to write AMD hwmon: {}", e),
|
||||
}
|
||||
if power1_cap.exists() {
|
||||
// Try to verify this is actually the CPU and not a generic sensor
|
||||
if let Ok(name) = fs::read_to_string(&name_path)
|
||||
&& name.trim().contains("amd")
|
||||
{
|
||||
match fs::write(&power1_cap, microwatts.to_string()) {
|
||||
Ok(_) => {
|
||||
log::debug!("Set AMD hwmon power1_cap to {}uW", microwatts);
|
||||
success = true;
|
||||
}
|
||||
Err(e) => log::debug!("Failed to write AMD hwmon: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
success
|
||||
}
|
||||
fn set_platform_profile(profile: &str) {
|
||||
|
||||
+60
-56
@@ -39,13 +39,14 @@ pub fn execute() {
|
||||
for ideapad_entry in ideapad_entries.flatten() {
|
||||
let conservation_path = ideapad_entry.path().join("conservation_mode");
|
||||
if conservation_path.exists()
|
||||
&& let Ok(mode) = fs::read_to_string(&conservation_path) {
|
||||
if mode.trim() == "1" {
|
||||
println!(" Charge Limit: Conservation Mode (~60%)");
|
||||
} else {
|
||||
println!(" Charge Limit: 100%");
|
||||
}
|
||||
&& let Ok(mode) = fs::read_to_string(&conservation_path)
|
||||
{
|
||||
if mode.trim() == "1" {
|
||||
println!(" Charge Limit: Conservation Mode (~60%)");
|
||||
} else {
|
||||
println!(" Charge Limit: 100%");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,31 +67,33 @@ pub fn execute() {
|
||||
for ideapad_entry in ideapad_entries.flatten() {
|
||||
let fan_path = ideapad_entry.path().join("fan_mode");
|
||||
if fan_path.exists()
|
||||
&& let Ok(mode) = fs::read_to_string(&fan_path) {
|
||||
thermal_found = true;
|
||||
let desc = match mode.trim() {
|
||||
"1" => "Performance",
|
||||
"0" => "Balanced",
|
||||
"2" => "Quiet / Battery Saving",
|
||||
_ => mode.trim(),
|
||||
};
|
||||
println!("Cooling Profile: {} (Ideapad)", desc);
|
||||
}
|
||||
&& let Ok(mode) = fs::read_to_string(&fan_path)
|
||||
{
|
||||
thermal_found = true;
|
||||
let desc = match mode.trim() {
|
||||
"1" => "Performance",
|
||||
"0" => "Balanced",
|
||||
"2" => "Quiet / Battery Saving",
|
||||
_ => mode.trim(),
|
||||
};
|
||||
println!("Cooling Profile: {} (Ideapad)", desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let asus_path = Path::new("/sys/devices/platform/asus-nb-wmi/throttle_thermal_policy");
|
||||
if asus_path.exists()
|
||||
&& let Ok(mode) = fs::read_to_string(asus_path) {
|
||||
thermal_found = true;
|
||||
let desc = match mode.trim() {
|
||||
"1" => "Performance",
|
||||
"0" => "Balanced",
|
||||
"2" => "Quiet / Battery Saving",
|
||||
_ => mode.trim(),
|
||||
};
|
||||
println!("Cooling Profile: {} (ASUS)", desc);
|
||||
}
|
||||
&& let Ok(mode) = fs::read_to_string(asus_path)
|
||||
{
|
||||
thermal_found = true;
|
||||
let desc = match mode.trim() {
|
||||
"1" => "Performance",
|
||||
"0" => "Balanced",
|
||||
"2" => "Quiet / Battery Saving",
|
||||
_ => mode.trim(),
|
||||
};
|
||||
println!("Cooling Profile: {} (ASUS)", desc);
|
||||
}
|
||||
|
||||
if !thermal_found {
|
||||
println!("Cooling Profile: Unknown / Firmware managed");
|
||||
@@ -102,48 +105,49 @@ pub fn execute() {
|
||||
// Check Intel RAPL
|
||||
let rapl_dir = Path::new("/sys/class/powercap/intel-rapl");
|
||||
if rapl_dir.exists()
|
||||
&& let Ok(entries) = fs::read_dir(rapl_dir) {
|
||||
for entry in entries.flatten() {
|
||||
let path = entry.path();
|
||||
let name = path.file_name().unwrap_or_default().to_string_lossy();
|
||||
&& let Ok(entries) = fs::read_dir(rapl_dir)
|
||||
{
|
||||
for entry in entries.flatten() {
|
||||
let path = entry.path();
|
||||
let name = path.file_name().unwrap_or_default().to_string_lossy();
|
||||
|
||||
if name.starts_with("intel-rapl:") {
|
||||
let constraint_0 = path.join("constraint_0_power_limit_uw"); // PL1
|
||||
if constraint_0.exists()
|
||||
&& let Ok(limit_uw) = fs::read_to_string(&constraint_0)
|
||||
&& let Ok(limit) = limit_uw.trim().parse::<u64>() {
|
||||
println!("CPU TDP Limit: {}W (Intel RAPL PL1)", limit / 1_000_000);
|
||||
tdp_found = true;
|
||||
break;
|
||||
}
|
||||
if name.starts_with("intel-rapl:") {
|
||||
let constraint_0 = path.join("constraint_0_power_limit_uw"); // PL1
|
||||
if constraint_0.exists()
|
||||
&& let Ok(limit_uw) = fs::read_to_string(&constraint_0)
|
||||
&& let Ok(limit) = limit_uw.trim().parse::<u64>()
|
||||
{
|
||||
println!("CPU TDP Limit: {}W (Intel RAPL PL1)", limit / 1_000_000);
|
||||
tdp_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check AMD HWMon
|
||||
if !tdp_found {
|
||||
let hwmon_dir = Path::new("/sys/class/hwmon");
|
||||
if hwmon_dir.exists()
|
||||
&& let Ok(entries) = fs::read_dir(hwmon_dir) {
|
||||
for entry in entries.flatten() {
|
||||
let path = entry.path();
|
||||
let power1_cap = path.join("power1_cap");
|
||||
let name_path = path.join("name");
|
||||
&& let Ok(entries) = fs::read_dir(hwmon_dir)
|
||||
{
|
||||
for entry in entries.flatten() {
|
||||
let path = entry.path();
|
||||
let power1_cap = path.join("power1_cap");
|
||||
let name_path = path.join("name");
|
||||
|
||||
if power1_cap.exists()
|
||||
&& let Ok(name) = fs::read_to_string(&name_path)
|
||||
&& name.trim().contains("amd")
|
||||
&& let Ok(limit_uw) = fs::read_to_string(&power1_cap)
|
||||
&& let Ok(limit) = limit_uw.trim().parse::<u64>() {
|
||||
println!(
|
||||
"CPU TDP Limit: {}W (AMD hwmon)",
|
||||
limit / 1_000_000
|
||||
);
|
||||
tdp_found = true;
|
||||
break;
|
||||
}
|
||||
if power1_cap.exists()
|
||||
&& let Ok(name) = fs::read_to_string(&name_path)
|
||||
&& name.trim().contains("amd")
|
||||
&& let Ok(limit_uw) = fs::read_to_string(&power1_cap)
|
||||
&& let Ok(limit) = limit_uw.trim().parse::<u64>()
|
||||
{
|
||||
println!("CPU TDP Limit: {}W (AMD hwmon)", limit / 1_000_000);
|
||||
tdp_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !tdp_found {
|
||||
|
||||
Reference in new issue
Block a user