mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Fan curve enablement
- Add CtrlProfileTask - Add method to reset active profile curve to platform default - Wrap the zbus methods for profiles + fan curves - Enable CLI args for fan curves - CLI mod and save curves
This commit is contained in:
@@ -8,7 +8,11 @@ pub enum ProfileError {
|
||||
NotSupported,
|
||||
NotFound(String),
|
||||
Io(std::io::Error),
|
||||
//Zbus(zbus::Error),
|
||||
ParseProfileName,
|
||||
ParseFanCurveDigit(std::num::ParseIntError),
|
||||
/// (pwm/temp, prev, next)
|
||||
ParseFanCurvePrevHigher(&'static str, u8, u8),
|
||||
// Zbus(zbus::Error),
|
||||
}
|
||||
|
||||
impl fmt::Display for ProfileError {
|
||||
@@ -21,7 +25,16 @@ impl fmt::Display for ProfileError {
|
||||
ProfileError::NotSupported => write!(f, "Not supported"),
|
||||
ProfileError::NotFound(deets) => write!(f, "Not found: {}", deets),
|
||||
ProfileError::Io(detail) => write!(f, "std::io error: {}", detail),
|
||||
//Error::Zbus(detail) => write!(f, "Zbus error: {}", detail),
|
||||
ProfileError::ParseProfileName => write!(f, "Invalid profile name"),
|
||||
ProfileError::ParseFanCurveDigit(e) => {
|
||||
write!(f, "Could not parse number to 0-255: {}", e)
|
||||
}
|
||||
ProfileError::ParseFanCurvePrevHigher(part, prev, next) => write!(
|
||||
f,
|
||||
"Invalid {}, previous value {} is higher than next value {}",
|
||||
part, prev, next
|
||||
),
|
||||
// Error::Zbus(detail) => write!(f, "Zbus error: {}", detail),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,24 +4,24 @@ use udev::Device;
|
||||
#[cfg(feature = "dbus")]
|
||||
use zvariant_derive::Type;
|
||||
|
||||
use crate::{error::ProfileError, write_to_fan, FanCurvePU};
|
||||
use crate::{error::ProfileError, FanCurvePU};
|
||||
|
||||
pub fn pwm_str(fan: char, index: char) -> String {
|
||||
pub(crate) fn pwm_str(fan: char, index: usize) -> String {
|
||||
let mut buf = "pwm1_auto_point1_pwm".to_string();
|
||||
unsafe {
|
||||
let tmp = buf.as_bytes_mut();
|
||||
tmp[3] = fan as u8;
|
||||
tmp[15] = index as u8;
|
||||
tmp[15] = char::from_digit(index as u32 + 1, 10).unwrap() as u8;
|
||||
}
|
||||
buf
|
||||
}
|
||||
|
||||
pub fn temp_str(fan: char, index: char) -> String {
|
||||
pub(crate) fn temp_str(fan: char, index: usize) -> String {
|
||||
let mut buf = "pwm1_auto_point1_temp".to_string();
|
||||
unsafe {
|
||||
let tmp = buf.as_bytes_mut();
|
||||
tmp[3] = fan as u8;
|
||||
tmp[15] = index as u8;
|
||||
tmp[15] = char::from_digit(index as u32 + 1, 10).unwrap() as u8;
|
||||
}
|
||||
buf
|
||||
}
|
||||
@@ -29,22 +29,135 @@ pub fn temp_str(fan: char, index: char) -> String {
|
||||
#[cfg_attr(feature = "dbus", derive(Type))]
|
||||
#[derive(Deserialize, Serialize, Default, Debug, Clone)]
|
||||
pub struct CurveData {
|
||||
pub fan: FanCurvePU,
|
||||
pub pwm: [u8; 8],
|
||||
pub temp: [u8; 8],
|
||||
pub(crate) fan: FanCurvePU,
|
||||
pub(crate) pwm: [u8; 8],
|
||||
pub(crate) temp: [u8; 8],
|
||||
}
|
||||
|
||||
impl std::str::FromStr for CurveData {
|
||||
type Err = ProfileError;
|
||||
|
||||
fn from_str(input: &str) -> Result<Self, Self::Err> {
|
||||
let mut temp = [0u8; 8];
|
||||
let mut pwm = [0u8; 8];
|
||||
let mut temp_prev = 0;
|
||||
let mut pwm_prev = 0;
|
||||
|
||||
for (index, value) in input.split(',').enumerate() {
|
||||
for (select, num) in value.splitn(2, |c| c == 'c' || c == ':').enumerate() {
|
||||
let r = num.trim_matches(|c| c == 'c' || c == ':' || c == '%');
|
||||
let r = r.parse::<u8>().map_err(ProfileError::ParseFanCurveDigit)?;
|
||||
|
||||
if select == 0 {
|
||||
if temp_prev > r {
|
||||
return Err(ProfileError::ParseFanCurvePrevHigher(
|
||||
"temperature",
|
||||
temp_prev,
|
||||
r,
|
||||
));
|
||||
}
|
||||
temp_prev = r;
|
||||
temp[index] = r;
|
||||
} else {
|
||||
if pwm_prev > r {
|
||||
return Err(ProfileError::ParseFanCurvePrevHigher(
|
||||
"percentage",
|
||||
pwm_prev,
|
||||
r,
|
||||
));
|
||||
}
|
||||
pwm_prev = r;
|
||||
pwm[index] = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Self {
|
||||
fan: FanCurvePU::CPU,
|
||||
pwm,
|
||||
temp,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl CurveData {
|
||||
pub fn set_fan(&mut self, fan: FanCurvePU) {
|
||||
self.fan = fan;
|
||||
}
|
||||
|
||||
fn set_val_from_attr(tmp: &str, device: &Device, buf: &mut [u8; 8]) {
|
||||
if let Some(n) = tmp.chars().nth(15) {
|
||||
let i = n.to_digit(10).unwrap() as usize;
|
||||
let d = device.attribute_value(tmp).unwrap();
|
||||
let d: u8 = d.to_string_lossy().parse().unwrap();
|
||||
buf[i - 1] = d;
|
||||
}
|
||||
}
|
||||
|
||||
fn read_from_device(&mut self, device: &Device) {
|
||||
for attr in device.attributes() {
|
||||
let tmp = attr.name().to_string_lossy();
|
||||
if tmp.starts_with("pwm1") && tmp.ends_with("_temp") {
|
||||
Self::set_val_from_attr(tmp.as_ref(), device, &mut self.temp)
|
||||
}
|
||||
if tmp.starts_with("pwm1") && tmp.ends_with("_pwm") {
|
||||
Self::set_val_from_attr(tmp.as_ref(), device, &mut self.pwm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn init_if_zeroed(&mut self, device: &mut Device) -> std::io::Result<()> {
|
||||
if self.pwm == [0u8; 8] && self.temp == [0u8; 8] {
|
||||
// Need to reset the device to defaults to get the proper profile defaults
|
||||
match self.fan {
|
||||
FanCurvePU::CPU => device.set_attribute_value("pwm1_enable", "3")?,
|
||||
FanCurvePU::GPU => device.set_attribute_value("pwm2_enable", "3")?,
|
||||
};
|
||||
self.read_from_device(device);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Write this curve to the device fan specified by `self.fan`
|
||||
fn write_to_device(&self, device: &mut Device, enable: bool) -> std::io::Result<()> {
|
||||
let pwm_num = match self.fan {
|
||||
FanCurvePU::CPU => '1',
|
||||
FanCurvePU::GPU => '2',
|
||||
};
|
||||
let enable = if enable { "1" } else { "2" };
|
||||
|
||||
for (index, out) in self.pwm.iter().enumerate() {
|
||||
let pwm = pwm_str(pwm_num, index);
|
||||
device.set_attribute_value(&pwm, &out.to_string())?;
|
||||
}
|
||||
|
||||
for (index, out) in self.temp.iter().enumerate() {
|
||||
let temp = temp_str(pwm_num, index);
|
||||
device.set_attribute_value(&temp, &out.to_string())?;
|
||||
}
|
||||
|
||||
// Enable must be done *after* all points are written
|
||||
match self.fan {
|
||||
FanCurvePU::CPU => device.set_attribute_value("pwm1_enable", enable)?,
|
||||
FanCurvePU::GPU => device.set_attribute_value("pwm2_enable", enable)?,
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// A `FanCurveSet` contains both CPU and GPU fan curve data
|
||||
#[cfg_attr(feature = "dbus", derive(Type))]
|
||||
#[derive(Deserialize, Serialize, Debug, Clone)]
|
||||
pub struct FanCurveSet {
|
||||
pub cpu: CurveData,
|
||||
pub gpu: CurveData,
|
||||
pub(crate) enabled: bool,
|
||||
pub(crate) cpu: CurveData,
|
||||
pub(crate) gpu: CurveData,
|
||||
}
|
||||
|
||||
impl Default for FanCurveSet {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
enabled: false,
|
||||
cpu: CurveData {
|
||||
fan: FanCurvePU::CPU,
|
||||
pwm: [0u8; 8],
|
||||
@@ -60,80 +173,71 @@ impl Default for FanCurveSet {
|
||||
}
|
||||
|
||||
impl FanCurveSet {
|
||||
pub fn get_device() -> Result<Device, ProfileError> {
|
||||
let mut enumerator = udev::Enumerator::new()?;
|
||||
enumerator.match_subsystem("hwmon")?;
|
||||
|
||||
for device in enumerator.scan_devices().unwrap() {
|
||||
if device.parent_with_subsystem("platform").unwrap().is_some() {
|
||||
if let Some(name) = device.attribute_value("name") {
|
||||
if name == "asus_custom_fan_curve" {
|
||||
return Ok(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(ProfileError::NotSupported)
|
||||
pub(crate) fn read_cpu_from_device(&mut self, device: &Device) {
|
||||
self.cpu.read_from_device(device);
|
||||
}
|
||||
|
||||
pub fn is_supported() -> Result<bool, ProfileError> {
|
||||
if Self::get_device().is_ok() {
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
Ok(false)
|
||||
pub(crate) fn read_gpu_from_device(&mut self, device: &Device) {
|
||||
self.gpu.read_from_device(device);
|
||||
}
|
||||
|
||||
pub fn new() -> Result<(Self, Device), ProfileError> {
|
||||
if let Ok(device) = Self::get_device() {
|
||||
let mut fans = Self {
|
||||
cpu: CurveData::default(),
|
||||
gpu: CurveData::default(),
|
||||
};
|
||||
|
||||
fans.cpu.fan = FanCurvePU::CPU;
|
||||
fans.cpu.fan = FanCurvePU::GPU;
|
||||
|
||||
fans.read_from_device(&device);
|
||||
|
||||
return Ok((fans, device));
|
||||
}
|
||||
|
||||
Err(ProfileError::NotSupported)
|
||||
pub(crate) fn write_cpu_fan(&mut self, device: &mut Device) -> std::io::Result<()> {
|
||||
self.cpu.init_if_zeroed(device)?;
|
||||
self.cpu.write_to_device(device, self.enabled)
|
||||
}
|
||||
|
||||
fn set_val_from_attr(tmp: &str, device: &Device, buf: &mut [u8; 8]) {
|
||||
if let Some(n) = tmp.chars().nth(15) {
|
||||
let i = n.to_digit(10).unwrap() as usize;
|
||||
let d = device.attribute_value(tmp).unwrap();
|
||||
let d: u8 = d.to_string_lossy().parse().unwrap();
|
||||
buf[i - 1] = d;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_from_device(&mut self, device: &Device) {
|
||||
for attr in device.attributes() {
|
||||
let tmp = attr.name().to_string_lossy();
|
||||
if tmp.starts_with("pwm1") && tmp.ends_with("_temp") {
|
||||
Self::set_val_from_attr(tmp.as_ref(), device, &mut self.cpu.temp)
|
||||
}
|
||||
if tmp.starts_with("pwm1") && tmp.ends_with("_pwm") {
|
||||
Self::set_val_from_attr(tmp.as_ref(), device, &mut self.cpu.pwm)
|
||||
}
|
||||
if tmp.starts_with("pwm2") && tmp.ends_with("_temp") {
|
||||
Self::set_val_from_attr(tmp.as_ref(), device, &mut self.gpu.temp)
|
||||
}
|
||||
if tmp.starts_with("pwm2") && tmp.ends_with("_pwm") {
|
||||
Self::set_val_from_attr(tmp.as_ref(), device, &mut self.gpu.pwm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_cpu_fan(&self, device: &mut Device) {
|
||||
write_to_fan(&self.cpu, '1', device);
|
||||
}
|
||||
|
||||
pub fn write_gpu_fan(&self, device: &mut Device) {
|
||||
write_to_fan(&self.gpu, '2', device);
|
||||
pub(crate) fn write_gpu_fan(&mut self, device: &mut Device) -> std::io::Result<()> {
|
||||
self.gpu.init_if_zeroed(device)?;
|
||||
self.gpu.write_to_device(device, self.enabled)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::str::FromStr;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn curve_data_from_str() {
|
||||
let curve =
|
||||
CurveData::from_str("30c:1%,49c:2%,59c:3%,69c:4%,79c:31%,89c:49%,99c:56%,109c:58%")
|
||||
.unwrap();
|
||||
assert_eq!(curve.fan, FanCurvePU::CPU);
|
||||
assert_eq!(curve.temp, [30, 49, 59, 69, 79, 89, 99, 109]);
|
||||
assert_eq!(curve.pwm, [1, 2, 3, 4, 31, 49, 56, 58]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn curve_data_from_str_simple() {
|
||||
let curve = CurveData::from_str("30:1,49:2,59:3,69:4,79:31,89:49,99:56,109:58").unwrap();
|
||||
assert_eq!(curve.fan, FanCurvePU::CPU);
|
||||
assert_eq!(curve.temp, [30, 49, 59, 69, 79, 89, 99, 109]);
|
||||
assert_eq!(curve.pwm, [1, 2, 3, 4, 31, 49, 56, 58]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn curve_data_from_str_invalid_pwm() {
|
||||
let curve =
|
||||
CurveData::from_str("30c:4%,49c:2%,59c:3%,69c:4%,79c:31%,89c:49%,99c:56%,109c:58%");
|
||||
assert!(&curve.is_err());
|
||||
assert!(matches!(
|
||||
curve,
|
||||
Err(ProfileError::ParseFanCurvePrevHigher(_, _, _))
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_pwm_str() {
|
||||
assert_eq!(pwm_str('1', 0), "pwm1_auto_point1_pwm");
|
||||
assert_eq!(pwm_str('1', 4), "pwm1_auto_point5_pwm");
|
||||
assert_eq!(pwm_str('1', 7), "pwm1_auto_point8_pwm");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_temp_str() {
|
||||
assert_eq!(temp_str('1', 0), "pwm1_auto_point1_temp");
|
||||
assert_eq!(temp_str('1', 4), "pwm1_auto_point5_temp");
|
||||
assert_eq!(temp_str('1', 7), "pwm1_auto_point8_temp");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ pub fn find_fan_curve_node() -> Result<Option<Device>, ProfileError> {
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "dbus", derive(Type))]
|
||||
#[derive(Deserialize, Serialize, Debug, Clone, Copy)]
|
||||
#[derive(Deserialize, Serialize, Debug, PartialEq, Clone, Copy)]
|
||||
pub enum Profile {
|
||||
Balanced,
|
||||
Performance,
|
||||
@@ -51,10 +51,7 @@ impl Profile {
|
||||
}
|
||||
|
||||
pub fn get_active_profile() -> Result<Profile, ProfileError> {
|
||||
let mut file = OpenOptions::new()
|
||||
.read(true)
|
||||
.open(&PLATFORM_PROFILE)
|
||||
.unwrap_or_else(|_| panic!("{} not found", &PLATFORM_PROFILE));
|
||||
let mut file = OpenOptions::new().read(true).open(&PLATFORM_PROFILE)?;
|
||||
|
||||
let mut buf = String::new();
|
||||
file.read_to_string(&mut buf)?;
|
||||
@@ -62,10 +59,7 @@ impl Profile {
|
||||
}
|
||||
|
||||
pub fn get_profile_names() -> Result<Vec<Profile>, ProfileError> {
|
||||
let mut file = OpenOptions::new()
|
||||
.read(true)
|
||||
.open(&PLATFORM_PROFILES)
|
||||
.unwrap_or_else(|_| panic!("{} not found", &PLATFORM_PROFILES));
|
||||
let mut file = OpenOptions::new().read(true).open(&PLATFORM_PROFILES)?;
|
||||
|
||||
let mut buf = String::new();
|
||||
file.read_to_string(&mut buf)?;
|
||||
@@ -73,10 +67,7 @@ impl Profile {
|
||||
}
|
||||
|
||||
pub fn set_profile(profile: Profile) -> Result<(), ProfileError> {
|
||||
let mut file = OpenOptions::new()
|
||||
.write(true)
|
||||
.open(PLATFORM_PROFILE)
|
||||
.unwrap_or_else(|_| panic!("{} not found", PLATFORM_PROFILE));
|
||||
let mut file = OpenOptions::new().write(true).open(PLATFORM_PROFILE)?;
|
||||
|
||||
file.write_all(<&str>::from(profile).as_bytes())?;
|
||||
Ok(())
|
||||
@@ -110,8 +101,21 @@ impl From<&str> for Profile {
|
||||
}
|
||||
}
|
||||
|
||||
impl std::str::FromStr for Profile {
|
||||
type Err = ProfileError;
|
||||
|
||||
fn from_str(profile: &str) -> Result<Self, Self::Err> {
|
||||
match profile.to_ascii_lowercase().trim() {
|
||||
"balanced" => Ok(Profile::Balanced),
|
||||
"performance" => Ok(Profile::Performance),
|
||||
"quiet" => Ok(Profile::Quiet),
|
||||
_ => Err(ProfileError::ParseProfileName),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "dbus", derive(Type))]
|
||||
#[derive(Deserialize, Serialize, Debug, Clone, Copy)]
|
||||
#[derive(Deserialize, Serialize, Debug, PartialEq, Clone, Copy)]
|
||||
pub enum FanCurvePU {
|
||||
CPU,
|
||||
GPU,
|
||||
@@ -126,27 +130,63 @@ impl From<FanCurvePU> for &str {
|
||||
}
|
||||
}
|
||||
|
||||
impl std::str::FromStr for FanCurvePU {
|
||||
type Err = ProfileError;
|
||||
|
||||
fn from_str(fan: &str) -> Result<Self, Self::Err> {
|
||||
match fan.to_ascii_lowercase().trim() {
|
||||
"cpu" => Ok(FanCurvePU::CPU),
|
||||
"gpu" => Ok(FanCurvePU::GPU),
|
||||
_ => Err(ProfileError::ParseProfileName),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FanCurvePU {
|
||||
fn default() -> Self {
|
||||
Self::CPU
|
||||
}
|
||||
}
|
||||
|
||||
/// Main purpose of `FanCurves` is to enable retoring state on system boot
|
||||
/// Main purpose of `FanCurves` is to enable restoring state on system boot
|
||||
#[cfg_attr(feature = "dbus", derive(Type))]
|
||||
#[derive(Deserialize, Serialize, Debug, Default)]
|
||||
pub struct FanCurveProfiles {
|
||||
enabled: Vec<Profile>,
|
||||
balanced: FanCurveSet,
|
||||
performance: FanCurveSet,
|
||||
quiet: FanCurveSet,
|
||||
}
|
||||
|
||||
impl FanCurveProfiles {
|
||||
pub fn get_device() -> Result<Device, ProfileError> {
|
||||
let mut enumerator = udev::Enumerator::new()?;
|
||||
enumerator.match_subsystem("hwmon")?;
|
||||
|
||||
for device in enumerator.scan_devices()? {
|
||||
if device.parent_with_subsystem("platform")?.is_some() {
|
||||
if let Some(name) = device.attribute_value("name") {
|
||||
if name == "asus_custom_fan_curve" {
|
||||
return Ok(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(ProfileError::NotSupported)
|
||||
}
|
||||
|
||||
pub fn is_supported() -> Result<bool, ProfileError> {
|
||||
if Self::get_device().is_ok() {
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
///
|
||||
pub fn read_from_dev_profile(&mut self, profile: Profile, device: &Device) {
|
||||
let mut tmp = FanCurveSet::default();
|
||||
tmp.read_from_device(device);
|
||||
tmp.read_cpu_from_device(device);
|
||||
tmp.read_gpu_from_device(device);
|
||||
match profile {
|
||||
Profile::Balanced => self.balanced = tmp,
|
||||
Profile::Performance => self.performance = tmp,
|
||||
@@ -154,22 +194,67 @@ impl FanCurveProfiles {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_to_platform(&self, profile: Profile, device: &mut Device) {
|
||||
/// Reset the stored (self) and device curve to the defaults of the platform.
|
||||
///
|
||||
/// Each platform_profile has a different default and the defualt can be read
|
||||
/// only for the currently active profile.
|
||||
pub fn set_active_curve_to_defaults(
|
||||
&mut self,
|
||||
profile: Profile,
|
||||
device: &mut Device,
|
||||
) -> std::io::Result<()> {
|
||||
// Do reset
|
||||
device.set_attribute_value("pwm1_enable", "3")?;
|
||||
device.set_attribute_value("pwm2_enable", "3")?;
|
||||
// Then read
|
||||
let mut tmp = FanCurveSet::default();
|
||||
tmp.read_cpu_from_device(device);
|
||||
tmp.read_gpu_from_device(device);
|
||||
match profile {
|
||||
Profile::Balanced => self.balanced = tmp,
|
||||
Profile::Performance => self.performance = tmp,
|
||||
Profile::Quiet => self.quiet = tmp,
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Write the curves for the selected profile to the device. If the curve is
|
||||
/// in the enabled list it will become active.
|
||||
pub fn write_profile_curve_to_platform(
|
||||
&mut self,
|
||||
profile: Profile,
|
||||
device: &mut Device,
|
||||
) -> std::io::Result<()> {
|
||||
let fans = match profile {
|
||||
Profile::Balanced => &self.balanced,
|
||||
Profile::Performance => &self.performance,
|
||||
Profile::Quiet => &self.quiet,
|
||||
Profile::Balanced => &mut self.balanced,
|
||||
Profile::Performance => &mut self.performance,
|
||||
Profile::Quiet => &mut self.quiet,
|
||||
};
|
||||
fans.write_cpu_fan(device);
|
||||
fans.write_gpu_fan(device);
|
||||
fans.write_cpu_fan(device)?;
|
||||
fans.write_gpu_fan(device)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_enabled_curve_profiles(&self) -> &[Profile] {
|
||||
&self.enabled
|
||||
pub fn get_enabled_curve_profiles(&self) -> Vec<Profile> {
|
||||
let mut tmp = Vec::new();
|
||||
if self.balanced.enabled {
|
||||
tmp.push(Profile::Balanced);
|
||||
}
|
||||
if self.performance.enabled {
|
||||
tmp.push(Profile::Performance);
|
||||
}
|
||||
if self.quiet.enabled {
|
||||
tmp.push(Profile::Quiet);
|
||||
}
|
||||
tmp
|
||||
}
|
||||
|
||||
pub fn set_enabled_curve_profiles(&mut self, profiles: Vec<Profile>) {
|
||||
self.enabled = profiles
|
||||
pub fn set_profile_curve_enabled(&mut self, profile: Profile, enabled: bool) {
|
||||
match profile {
|
||||
Profile::Balanced => self.balanced.enabled = enabled,
|
||||
Profile::Performance => self.performance.enabled = enabled,
|
||||
Profile::Quiet => self.quiet.enabled = enabled,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_all_fan_curves(&self) -> Vec<FanCurveSet> {
|
||||
@@ -180,11 +265,11 @@ impl FanCurveProfiles {
|
||||
]
|
||||
}
|
||||
|
||||
pub fn get_active_fan_curves(&self) -> &FanCurveSet {
|
||||
match Profile::get_active_profile().unwrap() {
|
||||
Profile::Balanced => &self.balanced,
|
||||
Profile::Performance => &self.performance,
|
||||
Profile::Quiet => &self.quiet,
|
||||
pub fn get_active_fan_curves(&self) -> Result<&FanCurveSet, ProfileError> {
|
||||
match Profile::get_active_profile()? {
|
||||
Profile::Balanced => Ok(&self.balanced),
|
||||
Profile::Performance => Ok(&self.performance),
|
||||
Profile::Quiet => Ok(&self.quiet),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,16 +298,7 @@ impl FanCurveProfiles {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_and_set_fan_curve(
|
||||
&mut self,
|
||||
curve: CurveData,
|
||||
profile: Profile,
|
||||
device: &mut Device,
|
||||
) {
|
||||
match curve.fan {
|
||||
FanCurvePU::CPU => write_to_fan(&curve, '1', device),
|
||||
FanCurvePU::GPU => write_to_fan(&curve, '2', device),
|
||||
}
|
||||
pub fn save_fan_curve(&mut self, curve: CurveData, profile: Profile) -> std::io::Result<()> {
|
||||
match profile {
|
||||
Profile::Balanced => match curve.fan {
|
||||
FanCurvePU::CPU => self.balanced.cpu = curve,
|
||||
@@ -237,33 +313,6 @@ impl FanCurveProfiles {
|
||||
FanCurvePU::GPU => self.quiet.gpu = curve,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_to_fan(curve: &CurveData, pwm_num: char, device: &mut Device) {
|
||||
let mut pwm = "pwmN_auto_pointN_pwm".to_string();
|
||||
|
||||
for (index, out) in curve.pwm.iter().enumerate() {
|
||||
unsafe {
|
||||
let buf = pwm.as_bytes_mut();
|
||||
buf[3] = pwm_num as u8;
|
||||
// Should be quite safe to unwrap as we're not going over 8
|
||||
buf[15] = char::from_digit(index as u32 + 1, 10).unwrap() as u8;
|
||||
}
|
||||
let out = out.to_string();
|
||||
device.set_attribute_value(&pwm, &out).unwrap();
|
||||
}
|
||||
|
||||
let mut pwm = "pwmN_auto_pointN_temp".to_string();
|
||||
|
||||
for (index, out) in curve.temp.iter().enumerate() {
|
||||
unsafe {
|
||||
let buf = pwm.as_bytes_mut();
|
||||
buf[3] = pwm_num as u8;
|
||||
// Should be quite safe to unwrap as we're not going over 8
|
||||
buf[15] = char::from_digit(index as u32 + 1, 10).unwrap() as u8;
|
||||
}
|
||||
let out = out.to_string();
|
||||
device.set_attribute_value(&pwm, &out).unwrap();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user