Enable fan curves

This commit is contained in:
Luke D. Jones
2024-03-14 17:17:55 +13:00
parent f6ad631a0f
commit 6b0edc6da1
8 changed files with 327 additions and 96 deletions

View File

@@ -11,7 +11,9 @@ edition = "2021"
[dependencies]
betrayer = { git = "https://github.com/flukejones/betrayer.git", features = ["winit"] }
betrayer = { git = "https://github.com/flukejones/betrayer.git", features = [
"winit",
] }
asusd = { path = "../asusd" }
config-traits = { path = "../config-traits" }
@@ -52,11 +54,18 @@ winit = "*"
git = "https://github.com/flukejones/sixtyfps.git"
branch = "asusctl"
default-features = false
features = ["std", "gettext", "compat-1-0", "backend-winit-wayland", "backend-linuxkms", "renderer-femtovg"]
features = [
"std",
"gettext",
"compat-1-0",
"backend-winit-wayland",
"backend-linuxkms",
"renderer-femtovg",
]
[build-dependencies.slint-build]
git = "https://github.com/flukejones/sixtyfps.git"
branch = "asusctl"
[dev-dependencies]
cargo-husky.workspace = true
cargo-husky.workspace = true

View File

@@ -8,13 +8,15 @@ use rog_dbus::zbus_aura::AuraProxy;
use rog_dbus::zbus_fan_curves::FanCurvesProxy;
use rog_dbus::zbus_platform::{PlatformProxy, PlatformProxyBlocking};
use rog_platform::platform::{Properties, ThrottlePolicy};
use rog_profiles::fan_curve_set::CurveData;
use rog_profiles::FanCurvePU;
use slint::{ComponentHandle, Model, PhysicalSize, RgbaColor, SharedString, Weak};
use zbus::proxy::CacheProperties;
use crate::config::Config;
use crate::{
AnimePageData, AppSettingsPageData, AuraPageData, AvailableSystemProperties, FanPageData,
MainWindow, Node, PowerZones as SlintPowerZones, SystemPageData,
FanType, MainWindow, Node, PowerZones as SlintPowerZones, Profile, SystemPageData,
};
// This macro expects are consistent naming between proxy calls and slint
@@ -122,6 +124,122 @@ pub fn setup_window(config: Arc<Mutex<Config>>) -> MainWindow {
ui
}
pub fn update_fan_data(
handle: Weak<MainWindow>,
bal: Vec<CurveData>,
perf: Vec<CurveData>,
quiet: Vec<CurveData>,
) {
handle
.upgrade_in_event_loop(move |handle| {
let global = handle.global::<FanPageData>();
let collect = |temp: &[u8], pwm: &[u8]| -> slint::ModelRc<Node> {
let tmp: Vec<Node> = temp
.iter()
.zip(pwm.iter())
.map(|(x, y)| Node {
x: *x as f32,
y: *y as f32,
})
.collect();
tmp.as_slice().into()
};
for fan in bal {
global.set_balanced_available(true);
match fan.fan {
rog_profiles::FanCurvePU::CPU => {
global.set_cpu_fan_available(true);
global.set_balanced_cpu_enabled(fan.enabled);
global.set_balanced_cpu(collect(&fan.temp, &fan.pwm))
}
rog_profiles::FanCurvePU::GPU => {
global.set_gpu_fan_available(true);
global.set_balanced_gpu_enabled(fan.enabled);
global.set_balanced_gpu(collect(&fan.temp, &fan.pwm))
}
rog_profiles::FanCurvePU::MID => {
global.set_mid_fan_available(true);
global.set_balanced_mid_enabled(fan.enabled);
global.set_balanced_mid(collect(&fan.temp, &fan.pwm))
}
}
}
for fan in perf {
global.set_performance_available(true);
match fan.fan {
rog_profiles::FanCurvePU::CPU => {
global.set_performance_cpu_enabled(fan.enabled);
global.set_performance_cpu(collect(&fan.temp, &fan.pwm))
}
rog_profiles::FanCurvePU::GPU => {
global.set_performance_gpu_enabled(fan.enabled);
global.set_performance_gpu(collect(&fan.temp, &fan.pwm))
}
rog_profiles::FanCurvePU::MID => {
global.set_performance_mid_enabled(fan.enabled);
global.set_performance_mid(collect(&fan.temp, &fan.pwm))
}
}
}
for fan in quiet {
global.set_quiet_available(true);
match fan.fan {
rog_profiles::FanCurvePU::CPU => {
global.set_quiet_cpu(collect(&fan.temp, &fan.pwm))
}
rog_profiles::FanCurvePU::GPU => {
global.set_quiet_gpu(collect(&fan.temp, &fan.pwm))
}
rog_profiles::FanCurvePU::MID => {
global.set_quiet_mid(collect(&fan.temp, &fan.pwm))
}
}
}
})
.unwrap();
}
impl From<Profile> for ThrottlePolicy {
fn from(value: Profile) -> Self {
match value {
Profile::Balanced => ThrottlePolicy::Balanced,
Profile::Performance => ThrottlePolicy::Performance,
Profile::Quiet => ThrottlePolicy::Quiet,
}
}
}
impl From<ThrottlePolicy> for Profile {
fn from(value: ThrottlePolicy) -> Self {
match value {
ThrottlePolicy::Balanced => Profile::Balanced,
ThrottlePolicy::Performance => Profile::Performance,
ThrottlePolicy::Quiet => Profile::Quiet,
}
}
}
impl From<FanType> for FanCurvePU {
fn from(value: FanType) -> Self {
match value {
FanType::CPU => FanCurvePU::CPU,
FanType::Middle => FanCurvePU::MID,
FanType::GPU => FanCurvePU::GPU,
}
}
}
impl From<FanCurvePU> for FanType {
fn from(value: FanCurvePU) -> Self {
match value {
FanCurvePU::CPU => FanType::CPU,
FanCurvePU::GPU => FanType::GPU,
FanCurvePU::MID => FanType::Middle,
}
}
}
pub fn setup_fan_curve_page(ui: &MainWindow, _config: Arc<Mutex<Config>>) {
let handle = ui.as_weak();
@@ -130,6 +248,7 @@ pub fn setup_fan_curve_page(ui: &MainWindow, _config: Arc<Mutex<Config>>) {
let conn = zbus::Connection::system().await.unwrap();
let fans = FanCurvesProxy::new(&conn).await.unwrap();
let handle_copy = handle.clone();
// Do initial setup
let balanced = fans.fan_curve_data(ThrottlePolicy::Balanced).await.unwrap();
let perf = fans
@@ -137,75 +256,60 @@ pub fn setup_fan_curve_page(ui: &MainWindow, _config: Arc<Mutex<Config>>) {
.await
.unwrap();
let quiet = fans.fan_curve_data(ThrottlePolicy::Quiet).await.unwrap();
update_fan_data(handle, balanced, perf, quiet);
handle
let handle_next1 = handle_copy.clone();
handle_copy
.upgrade_in_event_loop(move |handle| {
let global = handle.global::<FanPageData>();
let collect = |temp: &[u8], pwm: &[u8]| -> slint::ModelRc<Node> {
let tmp: Vec<Node> = temp
.iter()
.zip(pwm.iter())
.map(|(x, y)| Node {
x: *x as f32,
y: *y as f32,
})
.collect();
tmp.as_slice().into()
};
let fans1 = fans.clone();
global.on_set_profile_default(move |profile| {
let fans = fans1.clone();
let handle_next = handle_next1.clone();
tokio::spawn(async move {
fans.set_curves_to_defaults(profile.into()).await.unwrap();
for fan in balanced {
match fan.fan {
rog_profiles::FanCurvePU::CPU => {
global.set_balanced_cpu_available(true);
global.set_balanced_cpu(collect(&fan.temp, &fan.pwm))
}
rog_profiles::FanCurvePU::GPU => {
global.set_balanced_gpu_available(true);
global.set_balanced_gpu(collect(&fan.temp, &fan.pwm))
}
rog_profiles::FanCurvePU::MID => {
global.set_balanced_mid_available(true);
global.set_balanced_mid(collect(&fan.temp, &fan.pwm))
}
}
}
for fan in perf {
match fan.fan {
rog_profiles::FanCurvePU::CPU => {
global.set_performance_cpu_available(true);
global.set_performance_cpu(collect(&fan.temp, &fan.pwm))
}
rog_profiles::FanCurvePU::GPU => {
global.set_performance_gpu_available(true);
global.set_performance_gpu(collect(&fan.temp, &fan.pwm))
}
rog_profiles::FanCurvePU::MID => {
global.set_performance_mid_available(true);
global.set_performance_mid(collect(&fan.temp, &fan.pwm))
}
}
}
for fan in quiet {
match fan.fan {
rog_profiles::FanCurvePU::CPU => {
global.set_quiet_cpu_available(true);
global.set_quiet_cpu(collect(&fan.temp, &fan.pwm))
}
rog_profiles::FanCurvePU::GPU => {
global.set_quiet_gpu_available(true);
global.set_quiet_gpu(collect(&fan.temp, &fan.pwm))
}
rog_profiles::FanCurvePU::MID => {
global.set_quiet_mid_available(true);
global.set_quiet_mid(collect(&fan.temp, &fan.pwm))
}
}
}
let balanced = fans.fan_curve_data(ThrottlePolicy::Balanced).await.unwrap();
let perf = fans
.fan_curve_data(ThrottlePolicy::Performance)
.await
.unwrap();
let quiet = fans.fan_curve_data(ThrottlePolicy::Quiet).await.unwrap();
update_fan_data(handle_next, balanced, perf, quiet);
});
});
global.on_set_fan_data(move |fan, profile, enabled, data| {
let fans = fans.clone();
let data: Vec<Node> = data.iter().collect();
let data = fan_data_for(fan, enabled, data);
tokio::spawn(async move {
fans.set_fan_curve(profile.into(), data).await.unwrap();
});
});
})
.unwrap();
});
}
fn fan_data_for(fan: FanType, enabled: bool, data: Vec<Node>) -> CurveData {
let mut temp = [0u8; 8];
let mut pwm = [0u8; 8];
for (i, n) in data.iter().enumerate() {
if i == 8 {
break;
}
temp[i] = n.x as u8;
pwm[i] = n.y as u8;
}
CurveData {
fan: fan.into(),
pwm,
temp,
enabled,
}
}
pub fn setup_app_settings_page(ui: &MainWindow, config: Arc<Mutex<Config>>) {
let config_copy = config.clone();
let global = ui.global::<AppSettingsPageData>();

View File

@@ -5,7 +5,7 @@ import { Profile, FanType, FanPageData } from "../types/fan_types.slint";
component FanTab inherits Rectangle {
in-out property <bool> enabled: false;
in-out property <bool> tab_enabled: false;
in-out property <bool> tab_enabled: true;
in property <Profile> profile;
in property <FanType> fan_type;
callback apply();
@@ -15,22 +15,17 @@ component FanTab inherits Rectangle {
in property <string> title;
in-out property <[Node]> nodes;
if !root.tab_enabled: VerticalLayout {
alignment: center;
HorizontalLayout {
alignment: center;
Text {
font-size: 24px;
text: "WIP: Not enabled yet";
}
}
}
VerticalLayout {
HorizontalLayout {
Graph {
if root.tab_enabled: Graph {
nodes <=> root.nodes;
}
if !root.tab_enabled: Rectangle {
Text {
font-size: 24px;
text: @tr("This fan is not avilable on this machine");
}
}
}
HorizontalLayout {
@@ -61,7 +56,7 @@ component FanTab inherits Rectangle {
}
Button {
text: @tr("Factory Default");
text: @tr("Factory Default (all fans)");
enabled <=> root.tab_enabled;
clicked => {
root.default();
@@ -79,21 +74,54 @@ export component PageFans inherits VerticalLayout {
Tab {
title: @tr("CPU");
FanTab {
tab_enabled <=> FanPageData.cpu_fan_available;
enabled <=> FanPageData.balanced_cpu_enabled;
nodes <=> FanPageData.balanced_cpu;
apply => {
FanPageData.set_fan_data(FanType.CPU, Profile.Balanced, self.enabled, FanPageData.balanced_cpu);
}
toggled => {
FanPageData.set_fan_data(FanType.CPU, Profile.Balanced, self.enabled, FanPageData.balanced_cpu);
}
default => {
FanPageData.set_profile_default(Profile.Balanced);
}
}
}
Tab {
title: @tr("Mid");
FanTab {
tab_enabled <=> FanPageData.mid_fan_available;
enabled <=> FanPageData.balanced_mid_enabled;
nodes <=> FanPageData.balanced_mid;
apply => {
FanPageData.set_fan_data(FanType.Middle, Profile.Balanced, self.enabled, FanPageData.balanced_mid);
}
toggled => {
FanPageData.set_fan_data(FanType.Middle, Profile.Balanced, self.enabled, FanPageData.balanced_mid);
}
default => {
FanPageData.set_profile_default(Profile.Balanced);
}
}
}
Tab {
title: @tr("GPU");
FanTab {
tab_enabled <=> FanPageData.gpu_fan_available;
enabled <=> FanPageData.balanced_gpu_enabled;
nodes <=> FanPageData.balanced_gpu;
apply => {
FanPageData.set_fan_data(FanType.GPU, Profile.Balanced, self.enabled, FanPageData.balanced_gpu);
}
toggled => {
FanPageData.set_fan_data(FanType.GPU, Profile.Balanced, self.enabled, FanPageData.balanced_gpu);
}
default => {
FanPageData.set_profile_default(Profile.Balanced);
}
}
}
}
@@ -105,21 +133,54 @@ export component PageFans inherits VerticalLayout {
Tab {
title: @tr("CPU");
FanTab {
tab_enabled <=> FanPageData.cpu_fan_available;
enabled <=> FanPageData.performance_cpu_enabled;
nodes <=> FanPageData.performance_cpu;
apply => {
FanPageData.set_fan_data(FanType.CPU, Profile.Performance, self.enabled, FanPageData.performance_cpu);
}
toggled => {
FanPageData.set_fan_data(FanType.CPU, Profile.Performance, self.enabled, FanPageData.performance_cpu);
}
default => {
FanPageData.set_profile_default(Profile.Performance);
}
}
}
Tab {
title: @tr("Mid");
FanTab {
tab_enabled <=> FanPageData.mid_fan_available;
enabled <=> FanPageData.performance_mid_enabled;
nodes <=> FanPageData.performance_mid;
apply => {
FanPageData.set_fan_data(FanType.Middle, Profile.Performance, self.enabled, FanPageData.performance_mid);
}
toggled => {
FanPageData.set_fan_data(FanType.Middle, Profile.Performance, self.enabled, FanPageData.performance_mid);
}
default => {
FanPageData.set_profile_default(Profile.Performance);
}
}
}
Tab {
title: @tr("GPU");
FanTab {
tab_enabled <=> FanPageData.gpu_fan_available;
enabled <=> FanPageData.performance_gpu_enabled;
nodes <=> FanPageData.performance_gpu;
apply => {
FanPageData.set_fan_data(FanType.GPU, Profile.Performance, self.enabled, FanPageData.performance_gpu);
}
toggled => {
FanPageData.set_fan_data(FanType.GPU, Profile.Performance, self.enabled, FanPageData.performance_gpu);
}
default => {
FanPageData.set_profile_default(Profile.Performance);
}
}
}
}
@@ -131,21 +192,54 @@ export component PageFans inherits VerticalLayout {
Tab {
title: @tr("CPU");
FanTab {
tab_enabled <=> FanPageData.cpu_fan_available;
enabled <=> FanPageData.quiet_cpu_enabled;
nodes <=> FanPageData.quiet_cpu;
apply => {
FanPageData.set_fan_data(FanType.CPU, Profile.Quiet, self.enabled, FanPageData.quiet_cpu);
}
toggled => {
FanPageData.set_fan_data(FanType.CPU, Profile.Quiet, self.enabled, FanPageData.quiet_cpu);
}
default => {
FanPageData.set_profile_default(Profile.Quiet);
}
}
}
Tab {
title: @tr("Mid");
FanTab {
tab_enabled <=> FanPageData.mid_fan_available;
enabled <=> FanPageData.quiet_mid_enabled;
nodes <=> FanPageData.quiet_mid;
apply => {
FanPageData.set_fan_data(FanType.Middle, Profile.Quiet, self.enabled, FanPageData.quiet_mid);
}
toggled => {
FanPageData.set_fan_data(FanType.Middle, Profile.Quiet, self.enabled, FanPageData.quiet_mid);
}
default => {
FanPageData.set_profile_default(Profile.Quiet);
}
}
}
Tab {
title: @tr("GPU");
FanTab {
tab_enabled <=> FanPageData.gpu_fan_available;
enabled <=> FanPageData.quiet_gpu_enabled;
nodes <=> FanPageData.quiet_gpu;
apply => {
FanPageData.set_fan_data(FanType.GPU, Profile.Quiet, self.enabled, FanPageData.quiet_gpu);
}
toggled => {
FanPageData.set_fan_data(FanType.GPU, Profile.Quiet, self.enabled, FanPageData.quiet_gpu);
}
default => {
FanPageData.set_profile_default(Profile.Quiet);
}
}
}
}

View File

@@ -16,15 +16,25 @@ export global FanPageData {
in-out property <[Profile]> available_profiles: [Profile.Balanced, Profile.Performance, Profile.Quiet];
in-out property <[FanType]> available_fans: [FanType.CPU, FanType.Middle, FanType.GPU];
in-out property <bool> balanced_cpu_available: true;
in-out property <bool> balanced_gpu_available: true;
in-out property <bool> balanced_mid_available: false;
in-out property <bool> performance_cpu_available: true;
in-out property <bool> performance_gpu_available: true;
in-out property <bool> performance_mid_available: false;
in-out property <bool> quiet_cpu_available: true;
in-out property <bool> quiet_gpu_available: true;
in-out property <bool> quiet_mid_available: false;
in-out property <bool> cpu_fan_available: true;
in-out property <bool> gpu_fan_available: true;
in-out property <bool> mid_fan_available: false;
in-out property <bool> balanced_available: true;
in-out property <bool> performance_available: true;
in-out property <bool> quiet_available: false;
in-out property <bool> balanced_cpu_enabled: true;
in-out property <bool> balanced_gpu_enabled: true;
in-out property <bool> balanced_mid_enabled: false;
in-out property <bool> performance_cpu_enabled: true;
in-out property <bool> performance_gpu_enabled: true;
in-out property <bool> performance_mid_enabled: false;
in-out property <bool> quiet_cpu_enabled: true;
in-out property <bool> quiet_gpu_enabled: true;
in-out property <bool> quiet_mid_enabled: false;
callback set_fan_data(FanType, Profile, bool, [Node]);
callback set_profile_default(Profile);
in-out property <[Node]> balanced_cpu: [
{