diff --git a/CHANGELOG.md b/CHANGELOG.md index 52b6a84a..94942ddb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Changed +- Convert fan curve percentage to 0-255 expected by kernel driver only if '%' char is used, otherwise the expected range for fan power is 0-255 +### Added +- LED modes for G513QR # [4.0.4] - 2021-10-02 ### Changed diff --git a/asusctl/src/profiles_cli.rs b/asusctl/src/profiles_cli.rs index 06c7d488..1d53c7c8 100644 --- a/asusctl/src/profiles_cli.rs +++ b/asusctl/src/profiles_cli.rs @@ -44,7 +44,8 @@ pub struct FanCurveCommand { #[options( meta = "", - help = "data format = 30c:1%,49c:2%,59c:3%,69c:4%,79c:31%,89c:49%,99c:56%,109c:58%. `mod-profile` required" + help = "data format = 30c:1%,49c:2%,59c:3%,69c:4%,79c:31%,89c:49%,99c:56%,109c:58%. + `--mod-profile` required. If '%' is omitted the fan range is 0-255" )] pub data: Option, } diff --git a/rog-profiles/src/error.rs b/rog-profiles/src/error.rs index 6980e904..2ead72b8 100644 --- a/rog-profiles/src/error.rs +++ b/rog-profiles/src/error.rs @@ -12,6 +12,7 @@ pub enum ProfileError { ParseFanCurveDigit(std::num::ParseIntError), /// (pwm/temp, prev, next) ParseFanCurvePrevHigher(&'static str, u8, u8), + ParseFanCurvePercentOver100(u8), // Zbus(zbus::Error), } @@ -34,6 +35,9 @@ impl fmt::Display for ProfileError { "Invalid {}, previous value {} is higher than next value {}", part, prev, next ), + ProfileError::ParseFanCurvePercentOver100(value) => { + write!(f, "Invalid percentage, {} is higher than 100", value) + } // Error::Zbus(detail) => write!(f, "Zbus error: {}", detail), } } diff --git a/rog-profiles/src/fan_curve_set.rs b/rog-profiles/src/fan_curve_set.rs index 1096cab2..3d6e97f2 100644 --- a/rog-profiles/src/fan_curve_set.rs +++ b/rog-profiles/src/fan_curve_set.rs @@ -37,14 +37,24 @@ pub struct CurveData { impl std::str::FromStr for CurveData { type Err = ProfileError; + /// Parse a string to the correct values that the fan curve kernel driver expects + /// + /// If the fan curve is given with percentage char '%' then the fan power values are converted + /// otherwise the expected fan power range is 0-255. + /// + /// Temperature range is 0-255 in degrees C. You don't want to be setting over 100. fn from_str(input: &str) -> Result { let mut temp = [0u8; 8]; let mut pwm = [0u8; 8]; let mut temp_prev = 0; let mut pwm_prev = 0; + let mut percentages = false; for (index, value) in input.split(',').enumerate() { for (select, num) in value.splitn(2, |c| c == 'c' || c == ':').enumerate() { + if num.contains('%') { + percentages = true; + } let r = num.trim_matches(|c| c == 'c' || c == ':' || c == '%'); let r = r.parse::().map_err(ProfileError::ParseFanCurveDigit)?; @@ -59,15 +69,22 @@ impl std::str::FromStr for CurveData { temp_prev = r; temp[index] = r; } else { - if pwm_prev > r { + let mut p = r; + if percentages { + p *= 255 / 100; + if p > 100 { + return Err(ProfileError::ParseFanCurvePercentOver100(r)); + } + } + if pwm_prev > p { return Err(ProfileError::ParseFanCurvePrevHigher( "percentage", pwm_prev, - r, + p, )); } - pwm_prev = r; - pwm[index] = r; + pwm_prev = p; + pwm[index] = p; } } }