From 022a144705c67c22e41ba7a1451ca687fc80a9fa Mon Sep 17 00:00:00 2001 From: "Luke D. Jones" Date: Sat, 7 Jan 2023 11:44:30 +1300 Subject: [PATCH] Fix profile controller not detecting if platform_profile is changed Closes #313 --- CHANGELOG.md | 1 + daemon/src/ctrl_profiles/trait_impls.rs | 90 +++++++++++++++++++------ rog-platform/src/lib.rs | 15 +++++ rog-platform/src/macros.rs | 34 ++++++++++ rog-platform/src/platform.rs | 4 +- 5 files changed, 122 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8eca4a56..ed554b51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - ROGCC: Add CLI opt for loading a keyboard layout for testing, with live-reload on file change - ROGCC: Add CLI opt for viewing all layout files + filenames to help find a layout matching your laptop + Both of these options would hopefully be temporary and replaced with a "wizard" GUI helper +- Fix profile controller not detecting if platform_profile is changed ### BREAKING - Rename aura dbus method from `per_key_raw` to `direct_addressing_raw` and add doc comment - Changes to aura.conf: diff --git a/daemon/src/ctrl_profiles/trait_impls.rs b/daemon/src/ctrl_profiles/trait_impls.rs index 18685458..018f0785 100644 --- a/daemon/src/ctrl_profiles/trait_impls.rs +++ b/daemon/src/ctrl_profiles/trait_impls.rs @@ -1,7 +1,8 @@ +use std::str::FromStr; use std::sync::Arc; use async_trait::async_trait; -use log::{info, warn}; +use log::{error, info, warn}; use rog_profiles::fan_curve_set::{CurveData, FanCurveSet}; use rog_profiles::{FanCurveProfiles, Profile}; use zbus::export::futures_util::lock::Mutex; @@ -200,6 +201,7 @@ impl CtrlTask for ProfileZbus { async fn create_tasks(&self, signal_ctxt: SignalContext<'static>) -> Result<(), RogError> { let ctrl = self.0.clone(); + let sig_ctx = signal_ctxt.clone(); let mut watch = self .0 .lock() @@ -209,25 +211,73 @@ impl CtrlTask for ProfileZbus { tokio::spawn(async move { let mut buffer = [0; 32]; - watch - .event_stream(&mut buffer) - .unwrap() - .for_each(|_| async { - let mut lock = ctrl.lock().await; - let new_thermal = lock.platform.get_throttle_thermal_policy().unwrap(); - let new_profile = Profile::from_throttle_thermal_policy(new_thermal); - if new_profile != lock.profile_config.active_profile { - info!("throttle_thermal_policy changed to {new_profile}"); - lock.profile_config.active_profile = new_profile; - lock.write_profile_curve_to_platform().unwrap(); - lock.save_config(); - Profile::set_profile(lock.profile_config.active_profile).unwrap(); - } - Self::notify_profile(&signal_ctxt, lock.profile_config.active_profile) - .await - .ok(); - }) - .await; + if let Ok(stream) = watch.event_stream(&mut buffer) { + stream + .for_each(|_| async { + let mut lock = ctrl.lock().await; + if let Ok(profile) = + lock.platform.get_throttle_thermal_policy().map_err(|e| { + error!("get_throttle_thermal_policy error: {e}"); + }) + { + let new_profile = Profile::from_throttle_thermal_policy(profile); + if new_profile != lock.profile_config.active_profile { + info!("platform_profile changed to {new_profile}"); + lock.profile_config.active_profile = new_profile; + lock.write_profile_curve_to_platform().unwrap(); + lock.save_config(); + Profile::set_profile(lock.profile_config.active_profile) + .map_err(|e| { + error!("Profile::set_profile() error: {e}"); + }) + .ok(); + } + Self::notify_profile(&sig_ctx, lock.profile_config.active_profile) + .await + .ok(); + } + }) + .await; + } + }); + + let ctrl = self.0.clone(); + let mut watch = self.0.lock().await.platform.monitor_platform_profile()?; + + tokio::spawn(async move { + let mut buffer = [0; 32]; + if let Ok(stream) = watch.event_stream(&mut buffer) { + stream + .for_each(|_| async { + let mut lock = ctrl.lock().await; + if let Ok(profile) = lock.platform.get_platform_profile().map_err(|e| { + error!("get_platform_profile error: {e}"); + }) { + if let Ok(new_profile) = Profile::from_str(&profile).map_err(|e| { + error!("Profile::from_str(&profile) error: {e}"); + }) { + if new_profile != lock.profile_config.active_profile { + info!("platform_profile changed to {new_profile}"); + lock.profile_config.active_profile = new_profile; + lock.write_profile_curve_to_platform().unwrap(); + lock.save_config(); + Profile::set_profile(lock.profile_config.active_profile) + .map_err(|e| { + error!("Profile::set_profile() error: {e}"); + }) + .ok(); + } + Self::notify_profile( + &signal_ctxt, + lock.profile_config.active_profile, + ) + .await + .ok(); + } + } + }) + .await; + } }); Ok(()) diff --git a/rog-platform/src/lib.rs b/rog-platform/src/lib.rs index ffc3a89a..4666158a 100644 --- a/rog-platform/src/lib.rs +++ b/rog-platform/src/lib.rs @@ -82,6 +82,21 @@ pub fn write_attr_u8_array(device: &mut Device, attr: &str, values: &[u8]) -> Re .map_err(|e| PlatformError::IoPath(attr.into(), e)) } +pub fn read_attr_string(device: &Device, attr_name: &str) -> Result { + if let Some(value) = device.attribute_value(attr_name) { + let tmp = value.to_string_lossy().to_string(); + return Ok(tmp); + } + Err(PlatformError::AttrNotFound(attr_name.to_owned())) +} + +pub fn write_attr_string(device: &mut Device, attr: &str, value: &str) -> Result<()> { + let tmp = value.trim(); + device + .set_attribute_value(attr, tmp) + .map_err(|e| PlatformError::IoPath(attr.into(), e)) +} + #[cfg(test)] mod tests { #[test] diff --git a/rog-platform/src/macros.rs b/rog-platform/src/macros.rs index 9be9efa5..51daffc5 100644 --- a/rog-platform/src/macros.rs +++ b/rog-platform/src/macros.rs @@ -141,3 +141,37 @@ macro_rules! attr_u8_array { $crate::watch_attr!($attr_name $item); }; } + +#[macro_export] +macro_rules! get_attr_string { + ($(#[$doc_comment:meta])? $attr_name:literal $item:ident) => { + concat_idents::concat_idents!(fn_name = get_, $attr_name { + $(#[$doc_comment])* + pub fn fn_name(&self) -> Result { + $crate::read_attr_string(&to_device(&self.$item)?, $attr_name) + } + }); + }; +} + +#[macro_export] +macro_rules! set_attr_string { + ($(#[$doc_comment:meta])? $attr_name:literal $item:ident) => { + concat_idents::concat_idents!(fn_name = set_, $attr_name { + $(#[$doc_comment])* + pub fn fn_name(&self, values: &str) -> Result<()> { + $crate::write_attr_string(&mut to_device(&self.$item)?, $attr_name, values) + } + }); + }; +} + +#[macro_export] +macro_rules! attr_string { + ($attr_name:literal, $item:ident) => { + $crate::has_attr!($attr_name $item); + $crate::get_attr_string!($attr_name $item); + $crate::set_attr_string!($attr_name $item); + $crate::watch_attr!($attr_name $item); + }; +} diff --git a/rog-platform/src/platform.rs b/rog-platform/src/platform.rs index c208d653..82e8874e 100644 --- a/rog-platform/src/platform.rs +++ b/rog-platform/src/platform.rs @@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize}; use zbus::zvariant::Type; use crate::error::{PlatformError, Result}; -use crate::{attr_bool, attr_u8, to_device}; +use crate::{attr_bool, attr_string, attr_u8, to_device}; /// The "platform" device provides access to things like: /// - `dgpu_disable` @@ -36,7 +36,7 @@ impl AsusPlatform { attr_u8!("throttle_thermal_policy", path); // The acpi platform_profile support - attr_u8!("platform_profile", pp_path); + attr_string!("platform_profile", pp_path); pub fn new() -> Result { let mut enumerator = udev::Enumerator::new().map_err(|err| {