mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f290594562 | |||
| 423bd54f79 | |||
| ea0eaef8a6 | |||
| ef62a26148 | |||
| 2f916fa4e5 | |||
| e42fd10404 | |||
| 93edd1b632 | |||
| 6957a08d83 | |||
| 98569b98e7 | |||
| 573568d6e2 | |||
| 3ec37a4dac | |||
| 11483b28a6 | |||
| 2cce83d164 | |||
| 42b92f3b87 | |||
| 9154aaa97c | |||
| 8d8b5e5f51 | |||
| 9418b63454 | |||
| 2d396a49da | |||
| a6d89a622b | |||
| 51bcb0082b | |||
| eb54250e4d | |||
| eafc831231 | |||
| c625e97b7b | |||
| fea56879d6 | |||
| 03052e129b | |||
| 3dbc893905 | |||
| 50152961c7 |
+17
-1
@@ -5,12 +5,25 @@ 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]
|
||||
## [v4.7.0-RC2]
|
||||
## [v4.7.1]
|
||||
### Changed
|
||||
- Fixes to asusctl CLI tool to show fan curves
|
||||
- Fixes to asusd to ensure fan curve defaults are loaded if the config file fails
|
||||
- Further refine the asusctl CLI for fan-curve control
|
||||
- Fixes to AniMe detection
|
||||
- Fixes to aura config creation/loading
|
||||
|
||||
### Added
|
||||
- Support for GV601V LED modes
|
||||
|
||||
## [v4.7.0]
|
||||
### Added
|
||||
- Support for FX507Z LED modes
|
||||
- Support for GL503V LED modes
|
||||
- Support for G733C LED modes
|
||||
- Support for GV601VI LED modes
|
||||
- Support for FX505G LED modes
|
||||
- Support for GA402X LED modes
|
||||
- Support for G634J LED modes (layout is in progress)
|
||||
- Support the Rear Glow on some laptops
|
||||
- Added field to aura_support to determine which LED power zones are supported. This will need folks to contribute data.
|
||||
@@ -26,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Add generation of typescript types from the rust types used via dbus using typeshare
|
||||
- Add generation of introspection XML from asusd dbus
|
||||
- Add a reworked gnome extension to the main repo under `desktop-extensions/gnome/`. This was done to better keep the extension in sync with work done on asusd, especially around breaking dbus
|
||||
- Add support for the mid fan custom curves on some laptops
|
||||
### Changed
|
||||
- Move FX506HC to FX506H in arua DB to catch full series of this range
|
||||
- Move FX506LH to FX506L in arua DB to catch full series of this range
|
||||
@@ -35,10 +49,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Prevent the multiple notifications from a profile change from occuring (too many functions with side effects!)
|
||||
- Apply keyboard brightness when setting a mode
|
||||
- Update GL503 led config
|
||||
- Arua LED power control has been heavily refactored for 0x19b6+ devices
|
||||
- Rog Control Center:
|
||||
- Added option to enable/disable system tray
|
||||
- Added button to fully quit app (exits from background)
|
||||
- Moved application settings to new page
|
||||
- Aura LED power refactor is now taken advantage of in RCC, exposing all settings
|
||||
### BREAKING
|
||||
- All Anime related DBUS methods/notifs are changed
|
||||
- All dbus interfaces that handled an enum have now been forced to use the enum as String type, not uint or similar, this unfortunately breaks a heap of stuff but has the benefit of allowing asusctl to use crates to generate a typescript (or other) binding to the types being used by zbus for the proxies. The implication here is that there will be an eventual tighter integration with the gnome extension and maybe KDE also.
|
||||
|
||||
Generated
+263
-228
File diff suppressed because it is too large
Load Diff
+4
-3
@@ -1,9 +1,10 @@
|
||||
[workspace]
|
||||
members = ["asusctl", "asusd", "asusd-user", "config-traits", "rog-platform", "rog-dbus", "rog-anime", "rog-aura", "rog-profiles", "rog-control-center", "simulators"]
|
||||
default-members = ["asusctl", "asusd", "asusd-user", "rog-control-center"]
|
||||
workspace.resolver = "2"
|
||||
|
||||
[workspace.package]
|
||||
version = "4.7.0-RC1"
|
||||
version = "4.7.1"
|
||||
|
||||
[workspace.dependencies]
|
||||
async-trait = "^0.1"
|
||||
@@ -12,8 +13,8 @@ concat-idents = "^1.1"
|
||||
dirs = "^4.0"
|
||||
smol = "^1.3"
|
||||
|
||||
zbus = "~3.13.1"
|
||||
logind-zbus = { version = "^3.1.0" } #, default-features = false, features = ["non_blocking"] }
|
||||
zbus = "~3.14.1"
|
||||
logind-zbus = { version = "~3.1" } #, default-features = false, features = ["non_blocking"] }
|
||||
|
||||
serde = "^1.0"
|
||||
serde_derive = "^1.0"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# `asusctl` for ASUS ROG
|
||||
|
||||
[](https://www.paypal.com/donate/?hosted_button_id=4V2DEPS7K6APC) - [Asus Linux Website](https://asus-linux.org/)
|
||||
[Become a Patron!](https://www.patreon.com/bePatron?u=7602281) - [Asus Linux Website](https://asus-linux.org/)
|
||||
|
||||
**WARNING:** Many features are developed in tandem with kernel patches. If you see a feature is missing you either need a patched kernel, or v6.1 which has all my work merged upstream.
|
||||
|
||||
|
||||
@@ -43,15 +43,27 @@ pub enum AnimeActions {
|
||||
pub struct Builtins {
|
||||
#[options(help = "print help message")]
|
||||
pub help: bool,
|
||||
#[options(meta = "", help = " <GlitchConstruction, StaticEmergence>")]
|
||||
#[options(
|
||||
meta = "",
|
||||
help = "Default is used if unspecified, <default:GlitchConstruction, StaticEmergence>"
|
||||
)]
|
||||
pub boot: AnimBooting,
|
||||
#[options(meta = "", help = "<BinaryBannerScroll, RogLogoGlitch>")]
|
||||
#[options(
|
||||
meta = "",
|
||||
help = "Default is used if unspecified, <default:BinaryBannerScroll, RogLogoGlitch>"
|
||||
)]
|
||||
pub awake: AnimAwake,
|
||||
#[options(meta = "", help = "<BannerSwipe, Starfield>")]
|
||||
#[options(
|
||||
meta = "",
|
||||
help = "Default is used if unspecified, <default:BannerSwipe, Starfield>"
|
||||
)]
|
||||
pub sleep: AnimSleeping,
|
||||
#[options(meta = "", help = "<GlitchOut, SeeYa>")]
|
||||
#[options(
|
||||
meta = "",
|
||||
help = "Default is used if unspecified, <default:GlitchOut, SeeYa>"
|
||||
)]
|
||||
pub shutdown: AnimShutdown,
|
||||
#[options(meta = "", help = "set/apply the animations")]
|
||||
#[options(meta = "", help = "set/apply the animations <true/false>")]
|
||||
pub set: Option<bool>,
|
||||
}
|
||||
|
||||
|
||||
+25
-45
@@ -4,7 +4,7 @@ use gumdrop::Options;
|
||||
use rog_aura::error::Error;
|
||||
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Colour, Direction, Speed};
|
||||
|
||||
#[derive(Options)]
|
||||
#[derive(Options, Debug)]
|
||||
pub struct LedPowerCommand1 {
|
||||
#[options(help = "print help message")]
|
||||
pub help: bool,
|
||||
@@ -20,63 +20,43 @@ pub struct LedPowerCommand1 {
|
||||
pub sleep: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Options)]
|
||||
#[derive(Options, Debug)]
|
||||
pub struct LedPowerCommand2 {
|
||||
#[options(help = "print help message")]
|
||||
pub help: bool,
|
||||
#[options(command)]
|
||||
pub command: Option<SetAuraEnabled>,
|
||||
pub command: Option<SetAuraZoneEnabled>,
|
||||
}
|
||||
|
||||
#[derive(Options)]
|
||||
pub enum SetAuraEnabled {
|
||||
#[derive(Options, Debug)]
|
||||
pub enum SetAuraZoneEnabled {
|
||||
/// Applies to both old and new models
|
||||
#[options(help = "set <keyboard, logo, lightbar, rearglow> to enabled while device is awake")]
|
||||
Awake(AuraEnabled),
|
||||
#[options(
|
||||
help = "set <keyboard, logo, lightbar, rearglow> to enabled while the device is booting"
|
||||
)]
|
||||
Boot(AuraEnabled),
|
||||
#[options(
|
||||
help = "set <keyboard, logo, lightbar, rearglow> to animate while the device is suspended"
|
||||
)]
|
||||
Sleep(AuraEnabled),
|
||||
#[options(
|
||||
help = "set <keyboard, logo, lightbar, rearglow> to animate while the device is shutdown"
|
||||
)]
|
||||
Shutdown(AuraEnabled),
|
||||
#[options(help = "")]
|
||||
Keyboard(AuraPowerStates),
|
||||
#[options(help = "")]
|
||||
Logo(AuraPowerStates),
|
||||
#[options(help = "")]
|
||||
Lightbar(AuraPowerStates),
|
||||
#[options(help = "")]
|
||||
Lid(AuraPowerStates),
|
||||
#[options(help = "")]
|
||||
RearGlow(AuraPowerStates),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Options)]
|
||||
pub struct AuraEnabled {
|
||||
#[derive(Debug, Clone, Options)]
|
||||
pub struct AuraPowerStates {
|
||||
#[options(help = "print help message")]
|
||||
pub help: bool,
|
||||
#[options(meta = "", help = "<true/false>")]
|
||||
pub keyboard: Option<bool>,
|
||||
#[options(meta = "", help = "<true/false>")]
|
||||
pub logo: Option<bool>,
|
||||
#[options(meta = "", help = "<true/false>")]
|
||||
pub frontglow: Option<bool>,
|
||||
#[options(meta = "", help = "<true/false>")]
|
||||
pub rearglow: Option<bool>,
|
||||
#[options(meta = "", help = "<true/false>")]
|
||||
pub lid: Option<bool>,
|
||||
#[options(help = "defaults to false if option unused")]
|
||||
pub boot: bool,
|
||||
#[options(help = "defaults to false if option unused")]
|
||||
pub awake: bool,
|
||||
#[options(help = "defaults to false if option unused")]
|
||||
pub sleep: bool,
|
||||
#[options(help = "defaults to false if option unused")]
|
||||
pub shutdown: bool,
|
||||
}
|
||||
|
||||
// impl FromStr for AuraEnabled {
|
||||
// type Err = Error;
|
||||
|
||||
// fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
// let s = s.to_lowercase();
|
||||
// Ok(Self {
|
||||
// help: false,
|
||||
// keyboard: None,
|
||||
// logo: None,
|
||||
// lightbar: None,
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
#[derive(Options)]
|
||||
pub struct LedBrightness {
|
||||
level: Option<u32>,
|
||||
|
||||
+50
-75
@@ -10,14 +10,15 @@ use gumdrop::{Opt, Options};
|
||||
use profiles_cli::{FanCurveCommand, ProfileCommand};
|
||||
use rog_anime::usb::get_anime_type;
|
||||
use rog_anime::{AnimTime, AnimeDataBuffer, AnimeDiagonal, AnimeGif, AnimeImage, AnimeType, Vec2};
|
||||
use rog_aura::usb::{AuraDevRog1, AuraDevRog2, AuraDevTuf, AuraDevice, AuraPowerDev};
|
||||
use rog_aura::power::KbAuraPowerState;
|
||||
use rog_aura::usb::{AuraDevRog1, AuraDevTuf, AuraDevice, AuraPowerDev};
|
||||
use rog_aura::{self, AuraEffect};
|
||||
use rog_dbus::RogDbusClientBlocking;
|
||||
use rog_platform::platform::GpuMode;
|
||||
use rog_platform::supported::*;
|
||||
use rog_profiles::error::ProfileError;
|
||||
|
||||
use crate::aura_cli::LedBrightness;
|
||||
use crate::aura_cli::{AuraPowerStates, LedBrightness};
|
||||
use crate::cli_opts::*;
|
||||
|
||||
mod anime_cli;
|
||||
@@ -503,16 +504,14 @@ fn handle_led_power_1_do_1866(
|
||||
check(power.lightbar, AuraDevRog1::Lightbar);
|
||||
|
||||
let data = AuraPowerDev {
|
||||
x1866: enabled,
|
||||
x19b6: vec![],
|
||||
tuf: vec![],
|
||||
old_rog: enabled,
|
||||
..Default::default()
|
||||
};
|
||||
dbus.proxies().led().set_led_power(data, true)?;
|
||||
|
||||
let data = AuraPowerDev {
|
||||
x1866: disabled,
|
||||
x19b6: vec![],
|
||||
tuf: vec![],
|
||||
old_rog: disabled,
|
||||
..Default::default()
|
||||
};
|
||||
dbus.proxies().led().set_led_power(data, false)?;
|
||||
|
||||
@@ -542,16 +541,14 @@ fn handle_led_power_1_do_tuf(
|
||||
check(power.keyboard, AuraDevTuf::Keyboard);
|
||||
|
||||
let data = AuraPowerDev {
|
||||
x1866: vec![],
|
||||
x19b6: vec![],
|
||||
tuf: enabled,
|
||||
..Default::default()
|
||||
};
|
||||
dbus.proxies().led().set_led_power(data, true)?;
|
||||
|
||||
let data = AuraPowerDev {
|
||||
x1866: vec![],
|
||||
x19b6: vec![],
|
||||
tuf: disabled,
|
||||
..Default::default()
|
||||
};
|
||||
dbus.proxies().led().set_led_power(data, false)?;
|
||||
|
||||
@@ -591,66 +588,25 @@ fn handle_led_power2(
|
||||
println!("This option applies only to keyboards with product ID 0x19b6");
|
||||
}
|
||||
|
||||
let mut enabled: Vec<AuraDevRog2> = Vec::new();
|
||||
let mut disabled: Vec<AuraDevRog2> = Vec::new();
|
||||
let mut check = |e: Option<bool>, a: AuraDevRog2| {
|
||||
if let Some(arg) = e {
|
||||
if arg {
|
||||
enabled.push(a);
|
||||
} else {
|
||||
disabled.push(a);
|
||||
}
|
||||
}
|
||||
let set = |power: &mut KbAuraPowerState, set_to: &AuraPowerStates| {
|
||||
power.boot = set_to.boot;
|
||||
power.awake = set_to.awake;
|
||||
power.sleep = set_to.sleep;
|
||||
power.shutdown = set_to.shutdown;
|
||||
};
|
||||
|
||||
match pow {
|
||||
aura_cli::SetAuraEnabled::Boot(arg) => {
|
||||
check(arg.keyboard, AuraDevRog2::BootKeyb);
|
||||
check(arg.logo, AuraDevRog2::BootLogo);
|
||||
check(arg.frontglow, AuraDevRog2::BootBar);
|
||||
check(arg.rearglow, AuraDevRog2::BootRearGlow);
|
||||
check(arg.lid, AuraDevRog2::AwakeLid);
|
||||
}
|
||||
aura_cli::SetAuraEnabled::Sleep(arg) => {
|
||||
check(arg.keyboard, AuraDevRog2::SleepKeyb);
|
||||
check(arg.logo, AuraDevRog2::SleepLogo);
|
||||
check(arg.frontglow, AuraDevRog2::SleepBar);
|
||||
check(arg.rearglow, AuraDevRog2::SleepRearGlow);
|
||||
check(arg.lid, AuraDevRog2::SleepLid);
|
||||
}
|
||||
aura_cli::SetAuraEnabled::Awake(arg) => {
|
||||
check(arg.keyboard, AuraDevRog2::AwakeKeyb);
|
||||
check(arg.logo, AuraDevRog2::AwakeLogo);
|
||||
check(arg.frontglow, AuraDevRog2::AwakeBar);
|
||||
check(arg.rearglow, AuraDevRog2::AwakeRearGlow);
|
||||
check(arg.lid, AuraDevRog2::AwakeLid);
|
||||
}
|
||||
aura_cli::SetAuraEnabled::Shutdown(arg) => {
|
||||
check(arg.keyboard, AuraDevRog2::ShutdownKeyb);
|
||||
check(arg.logo, AuraDevRog2::ShutdownLogo);
|
||||
check(arg.frontglow, AuraDevRog2::ShutdownBar);
|
||||
check(arg.rearglow, AuraDevRog2::ShutdownRearGlow);
|
||||
check(arg.lid, AuraDevRog2::ShutdownLid);
|
||||
let mut enabled = dbus.proxies().led().led_power()?;
|
||||
if let Some(cmd) = &power.command {
|
||||
match cmd {
|
||||
aura_cli::SetAuraZoneEnabled::Keyboard(k) => set(&mut enabled.rog.keyboard, k),
|
||||
aura_cli::SetAuraZoneEnabled::Logo(l) => set(&mut enabled.rog.logo, l),
|
||||
aura_cli::SetAuraZoneEnabled::Lightbar(l) => set(&mut enabled.rog.lightbar, l),
|
||||
aura_cli::SetAuraZoneEnabled::Lid(l) => set(&mut enabled.rog.lid, l),
|
||||
aura_cli::SetAuraZoneEnabled::RearGlow(r) => set(&mut enabled.rog.rear_glow, r),
|
||||
}
|
||||
}
|
||||
|
||||
if !enabled.is_empty() {
|
||||
let data = AuraPowerDev {
|
||||
tuf: vec![],
|
||||
x1866: vec![],
|
||||
x19b6: enabled,
|
||||
};
|
||||
dbus.proxies().led().set_led_power(data, true)?;
|
||||
}
|
||||
|
||||
if !disabled.is_empty() {
|
||||
let data = AuraPowerDev {
|
||||
tuf: vec![],
|
||||
x1866: vec![],
|
||||
x19b6: disabled,
|
||||
};
|
||||
dbus.proxies().led().set_led_power(data, false)?;
|
||||
}
|
||||
dbus.proxies().led().set_led_power(enabled, true)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -704,7 +660,7 @@ fn handle_fan_curve(
|
||||
supported: &PlatformProfileFunctions,
|
||||
cmd: &FanCurveCommand,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
if !supported.fan_curves {
|
||||
if supported.fans.is_empty() {
|
||||
println!("Fan-curves not supported by either this kernel or by the laptop.");
|
||||
println!("This requires kernel 5.17 or the fan curve patch listed in the readme.");
|
||||
return Err(ProfileError::NotSupported.into());
|
||||
@@ -722,16 +678,22 @@ fn handle_fan_curve(
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if (cmd.enabled.is_some() || cmd.fan.is_some() || cmd.data.is_some())
|
||||
if (cmd.enable_fan_curves.is_some() || cmd.fan.is_some() || cmd.data.is_some())
|
||||
&& cmd.mod_profile.is_none()
|
||||
{
|
||||
println!("--enabled, --fan, and --data options require --mod-profile");
|
||||
println!(
|
||||
"--enable-fan-curves, --enable-fan-curve, --fan, and --data options require \
|
||||
--mod-profile"
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if cmd.get_enabled {
|
||||
let res = dbus.proxies().profile().enabled_fan_profiles()?;
|
||||
println!("{:?}", res);
|
||||
let profile = dbus.proxies().profile().active_profile()?;
|
||||
let curves = dbus.proxies().profile().fan_curve_data(profile)?;
|
||||
for curve in curves.iter() {
|
||||
println!("{}", String::from(curve));
|
||||
}
|
||||
}
|
||||
|
||||
if cmd.default {
|
||||
@@ -739,16 +701,29 @@ fn handle_fan_curve(
|
||||
}
|
||||
|
||||
if let Some(profile) = cmd.mod_profile {
|
||||
if cmd.enabled.is_none() && cmd.data.is_none() {
|
||||
if cmd.enable_fan_curves.is_none() && cmd.data.is_none() {
|
||||
let data = dbus.proxies().profile().fan_curve_data(profile)?;
|
||||
let data = toml::to_string(&data)?;
|
||||
println!("\nFan curves for {:?}\n\n{}", profile, data);
|
||||
}
|
||||
|
||||
if let Some(enabled) = cmd.enabled {
|
||||
if let Some(enabled) = cmd.enable_fan_curves {
|
||||
dbus.proxies()
|
||||
.profile()
|
||||
.set_fan_curve_enabled(profile, enabled)?;
|
||||
.set_fan_curves_enabled(profile, enabled)?;
|
||||
}
|
||||
|
||||
if let Some(enabled) = cmd.enable_fan_curve {
|
||||
if let Some(fan) = cmd.fan {
|
||||
dbus.proxies()
|
||||
.profile()
|
||||
.set_profile_fan_curve_enabled(profile, fan, enabled)?;
|
||||
} else {
|
||||
println!(
|
||||
"--enable-fan-curves, --enable-fan-curve, --fan, and --data options require \
|
||||
--mod-profile"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(mut curve) = cmd.data.clone() {
|
||||
|
||||
@@ -6,13 +6,16 @@ use rog_profiles::{FanCurvePU, Profile};
|
||||
pub struct ProfileCommand {
|
||||
#[options(help = "print help message")]
|
||||
pub help: bool,
|
||||
|
||||
#[options(help = "toggle to next profile in list")]
|
||||
pub next: bool,
|
||||
|
||||
#[options(help = "list available profiles")]
|
||||
pub list: bool,
|
||||
|
||||
#[options(help = "get profile")]
|
||||
pub profile_get: bool,
|
||||
|
||||
#[options(meta = "", help = "set the active profile")]
|
||||
pub profile_set: Option<Profile>,
|
||||
}
|
||||
@@ -24,6 +27,7 @@ pub struct FanCurveCommand {
|
||||
|
||||
#[options(help = "get enabled fan profiles")]
|
||||
pub get_enabled: bool,
|
||||
|
||||
#[options(help = "set the active profile's fan curve to default")]
|
||||
pub default: bool,
|
||||
|
||||
@@ -32,21 +36,31 @@ pub struct FanCurveCommand {
|
||||
help = "profile to modify fan-curve for. Shows data if no options provided"
|
||||
)]
|
||||
pub mod_profile: Option<Profile>,
|
||||
|
||||
#[options(
|
||||
meta = "",
|
||||
help = "enable or disable <true/false> fan curve. `mod-profile` required"
|
||||
help = "enable or disable <true/false> fan all curves for a profile. `--mod_profile` \
|
||||
required"
|
||||
)]
|
||||
pub enabled: Option<bool>,
|
||||
pub enable_fan_curves: Option<bool>,
|
||||
|
||||
#[options(
|
||||
meta = "",
|
||||
help = "select fan <cpu/gpu> to modify. `mod-profile` required"
|
||||
help = "enable or disable <true/false> a single fan curve for a profile. `--mod_profile` \
|
||||
and `--fan` required"
|
||||
)]
|
||||
pub enable_fan_curve: Option<bool>,
|
||||
|
||||
#[options(
|
||||
meta = "",
|
||||
help = "select fan <cpu/gpu/mid> to modify. `--mod_profile` required"
|
||||
)]
|
||||
pub fan: Option<FanCurvePU>,
|
||||
|
||||
#[options(
|
||||
meta = "",
|
||||
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"
|
||||
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<CurveData>,
|
||||
}
|
||||
|
||||
@@ -24,7 +24,11 @@ impl GetSupported for CtrlAnime {
|
||||
type A = AnimeSupportedFunctions;
|
||||
|
||||
fn get_supported() -> Self::A {
|
||||
AnimeSupportedFunctions(HidRaw::new("193b").is_ok())
|
||||
if USBRaw::new(0x193b).is_ok() {
|
||||
AnimeSupportedFunctions(true)
|
||||
} else {
|
||||
AnimeSupportedFunctions(HidRaw::new("193b").is_ok())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,12 +67,12 @@ pub struct CtrlAnime {
|
||||
impl CtrlAnime {
|
||||
#[inline]
|
||||
pub fn new(config: AnimeConfig) -> Result<CtrlAnime, RogError> {
|
||||
let hid = HidRaw::new("193b").ok();
|
||||
let usb = USBRaw::new(0x193b).ok();
|
||||
let node = if hid.is_some() {
|
||||
unsafe { Node::Hid(hid.unwrap_unchecked()) }
|
||||
} else if usb.is_some() {
|
||||
let hid = HidRaw::new("193b").ok();
|
||||
let node = if usb.is_some() {
|
||||
unsafe { Node::Usb(usb.unwrap_unchecked()) }
|
||||
} else if hid.is_some() {
|
||||
unsafe { Node::Hid(hid.unwrap_unchecked()) }
|
||||
} else {
|
||||
return Err(RogError::Anime(AnimeError::NoDevice));
|
||||
};
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
|
||||
use config_traits::{StdConfig, StdConfigLoad};
|
||||
use rog_aura::aura_detection::LaptopLedData;
|
||||
use rog_aura::usb::{AuraDevRog1, AuraDevRog2, AuraDevTuf, AuraDevice, AuraPowerDev};
|
||||
use log::{debug, warn};
|
||||
use rog_aura::aura_detection::{LaptopLedData, ASUS_KEYBOARD_DEVICES};
|
||||
use rog_aura::power::AuraPower;
|
||||
use rog_aura::usb::{AuraDevRog1, AuraDevTuf, AuraDevice, AuraPowerDev};
|
||||
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Direction, LedBrightness, Speed, GRADIENT};
|
||||
use rog_platform::hid_raw::HidRaw;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
const CONFIG_FILE: &str = "aura.ron";
|
||||
@@ -15,7 +18,7 @@ const CONFIG_FILE: &str = "aura.ron";
|
||||
pub enum AuraPowerConfig {
|
||||
AuraDevTuf(HashSet<AuraDevTuf>),
|
||||
AuraDevRog1(HashSet<AuraDevRog1>),
|
||||
AuraDevRog2(HashSet<AuraDevRog2>),
|
||||
AuraDevRog2(AuraPower),
|
||||
}
|
||||
|
||||
impl AuraPowerConfig {
|
||||
@@ -27,10 +30,7 @@ impl AuraPowerConfig {
|
||||
let c: Vec<AuraDevRog1> = c.iter().copied().collect();
|
||||
AuraDevRog1::to_bytes(&c)
|
||||
}
|
||||
AuraPowerConfig::AuraDevRog2(c) => {
|
||||
let c: Vec<AuraDevRog2> = c.iter().copied().collect();
|
||||
AuraDevRog2::to_bytes(&c)
|
||||
}
|
||||
AuraPowerConfig::AuraDevRog2(c) => c.to_bytes(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,13 +78,9 @@ impl AuraPowerConfig {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_0x19b6(&mut self, power: AuraDevRog2, on: bool) {
|
||||
pub fn set_0x19b6(&mut self, power: AuraPower) {
|
||||
if let Self::AuraDevRog2(p) = self {
|
||||
if on {
|
||||
p.insert(power);
|
||||
} else {
|
||||
p.remove(&power);
|
||||
}
|
||||
*p = power;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,18 +90,15 @@ impl From<&AuraPowerConfig> for AuraPowerDev {
|
||||
match config {
|
||||
AuraPowerConfig::AuraDevTuf(d) => AuraPowerDev {
|
||||
tuf: d.iter().copied().collect(),
|
||||
x1866: vec![],
|
||||
x19b6: vec![],
|
||||
..Default::default()
|
||||
},
|
||||
AuraPowerConfig::AuraDevRog1(d) => AuraPowerDev {
|
||||
tuf: vec![],
|
||||
x1866: d.iter().copied().collect(),
|
||||
x19b6: vec![],
|
||||
old_rog: d.iter().copied().collect(),
|
||||
..Default::default()
|
||||
},
|
||||
AuraPowerConfig::AuraDevRog2(d) => AuraPowerDev {
|
||||
tuf: vec![],
|
||||
x1866: vec![],
|
||||
x19b6: d.iter().copied().collect(),
|
||||
rog: d.clone(),
|
||||
..Default::default()
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -123,9 +116,17 @@ pub struct AuraConfig {
|
||||
}
|
||||
|
||||
impl StdConfig for AuraConfig {
|
||||
/// Detect the keyboard type and load from default DB if data available
|
||||
fn new() -> Self {
|
||||
// Self::create_default(AuraDevice::X19b6, &LaptopLedData::get_data())
|
||||
panic!("AuraConfig::new() should not be used, use AuraConfig::create_default() instead");
|
||||
warn!("AuraConfig: creating new config");
|
||||
let mut prod_id = AuraDevice::Unknown;
|
||||
for prod in ASUS_KEYBOARD_DEVICES {
|
||||
if HidRaw::new(prod.into()).is_ok() {
|
||||
prod_id = prod;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Self::from_default_support(prod_id, &LaptopLedData::get_data())
|
||||
}
|
||||
|
||||
fn config_dir() -> std::path::PathBuf {
|
||||
@@ -140,27 +141,10 @@ impl StdConfig for AuraConfig {
|
||||
impl StdConfigLoad for AuraConfig {}
|
||||
|
||||
impl AuraConfig {
|
||||
pub fn create_default(prod_id: AuraDevice, support_data: &LaptopLedData) -> Self {
|
||||
pub fn from_default_support(prod_id: AuraDevice, support_data: &LaptopLedData) -> Self {
|
||||
// create a default config here
|
||||
let enabled = if prod_id == AuraDevice::X19b6 {
|
||||
AuraPowerConfig::AuraDevRog2(HashSet::from([
|
||||
AuraDevRog2::BootLogo,
|
||||
AuraDevRog2::BootKeyb,
|
||||
AuraDevRog2::SleepLogo,
|
||||
AuraDevRog2::SleepKeyb,
|
||||
AuraDevRog2::AwakeLogo,
|
||||
AuraDevRog2::AwakeKeyb,
|
||||
AuraDevRog2::ShutdownLogo,
|
||||
AuraDevRog2::ShutdownKeyb,
|
||||
AuraDevRog2::BootBar,
|
||||
AuraDevRog2::AwakeBar,
|
||||
AuraDevRog2::SleepBar,
|
||||
AuraDevRog2::ShutdownBar,
|
||||
AuraDevRog2::BootRearGlow,
|
||||
AuraDevRog2::AwakeRearGlow,
|
||||
AuraDevRog2::SleepRearGlow,
|
||||
AuraDevRog2::ShutdownRearGlow,
|
||||
]))
|
||||
AuraPowerConfig::AuraDevRog2(AuraPower::new_all_on())
|
||||
} else if prod_id == AuraDevice::Tuf {
|
||||
AuraPowerConfig::AuraDevTuf(HashSet::from([
|
||||
AuraDevTuf::Awake,
|
||||
@@ -187,6 +171,7 @@ impl AuraConfig {
|
||||
};
|
||||
|
||||
for n in &support_data.basic_modes {
|
||||
debug!("AuraConfig: creating default for {n}");
|
||||
config
|
||||
.builtins
|
||||
.insert(*n, AuraEffect::default_with_mode(*n));
|
||||
@@ -264,7 +249,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn set_multizone_4key_config() {
|
||||
let mut config = AuraConfig::create_default(AuraDevice::X19b6, &LaptopLedData::default());
|
||||
let mut config =
|
||||
AuraConfig::from_default_support(AuraDevice::X19b6, &LaptopLedData::default());
|
||||
|
||||
let effect = AuraEffect {
|
||||
colour1: Colour {
|
||||
@@ -354,7 +340,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn set_multizone_multimode_config() {
|
||||
let mut config = AuraConfig::create_default(AuraDevice::X19b6, &LaptopLedData::default());
|
||||
let mut config =
|
||||
AuraConfig::from_default_support(AuraDevice::X19b6, &LaptopLedData::default());
|
||||
|
||||
let effect = AuraEffect {
|
||||
zone: AuraZone::Key1,
|
||||
|
||||
@@ -112,15 +112,17 @@ impl CtrlKbdLed {
|
||||
LEDNode::None
|
||||
};
|
||||
|
||||
let mut config_init = AuraConfig::create_default(led_prod, &supported_modes);
|
||||
// New loads data fromt he DB also
|
||||
let mut config_init = AuraConfig::new();
|
||||
let mut config_loaded = config_init.clone().load();
|
||||
|
||||
// update the initialised data with what we loaded from disk
|
||||
for mode in &mut config_init.builtins {
|
||||
// update init values from loaded values if they exist
|
||||
if let Some(loaded) = config_loaded.builtins.get(mode.0) {
|
||||
*mode.1 = loaded.clone();
|
||||
}
|
||||
}
|
||||
// Then replace just incase the initialised data contains new modes added
|
||||
config_loaded.builtins = config_init.builtins;
|
||||
|
||||
if let (Some(mut multizone_init), Some(multizone_loaded)) =
|
||||
@@ -414,7 +416,7 @@ mod tests {
|
||||
// #[ignore = "Must be manually run due to detection stage"]
|
||||
fn check_set_mode_errors() {
|
||||
// Checking to ensure set_mode errors when unsupported modes are tried
|
||||
let config = AuraConfig::create_default(AuraDevice::X19b6, &LaptopLedData::default());
|
||||
let config = AuraConfig::from_default_support(AuraDevice::X19b6, &LaptopLedData::default());
|
||||
let supported_modes = LaptopLedData {
|
||||
board_name: String::new(),
|
||||
layout_name: "ga401".to_owned(),
|
||||
@@ -482,7 +484,7 @@ mod tests {
|
||||
#[test]
|
||||
fn create_multizone_if_no_config() {
|
||||
// Checking to ensure set_mode errors when unsupported modes are tried
|
||||
let config = AuraConfig::create_default(AuraDevice::X19b6, &LaptopLedData::default());
|
||||
let config = AuraConfig::from_default_support(AuraDevice::X19b6, &LaptopLedData::default());
|
||||
let supported_modes = LaptopLedData {
|
||||
board_name: String::new(),
|
||||
layout_name: "ga401".to_owned(),
|
||||
@@ -521,7 +523,7 @@ mod tests {
|
||||
#[test]
|
||||
fn next_mode_create_multizone_if_no_config() {
|
||||
// Checking to ensure set_mode errors when unsupported modes are tried
|
||||
let config = AuraConfig::create_default(AuraDevice::X19b6, &LaptopLedData::default());
|
||||
let config = AuraConfig::from_default_support(AuraDevice::X19b6, &LaptopLedData::default());
|
||||
let supported_modes = LaptopLedData {
|
||||
board_name: String::new(),
|
||||
layout_name: "ga401".to_owned(),
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use config_traits::StdConfig;
|
||||
use log::{error, info, warn};
|
||||
use log::{debug, error, info, warn};
|
||||
use rog_aura::advanced::UsbPackets;
|
||||
use rog_aura::usb::{AuraDevice, AuraPowerDev};
|
||||
use rog_aura::{AuraEffect, AuraModeNum, LedBrightness};
|
||||
@@ -53,48 +53,7 @@ impl CtrlKbdLedZbus {
|
||||
/// Set a variety of states, input is array of enum.
|
||||
/// `enabled` sets if the sent array should be disabled or enabled
|
||||
///
|
||||
/// ```text
|
||||
/// pub struct AuraPowerDev {
|
||||
/// tuf: Vec<AuraDevTuf>,
|
||||
/// x1866: Vec<AuraDevRog1>,
|
||||
/// x19b6: Vec<AuraDevRog2>,
|
||||
/// }
|
||||
/// pub enum AuraDevTuf {
|
||||
/// Boot,
|
||||
/// Awake,
|
||||
/// Sleep,
|
||||
/// Keyboard,
|
||||
/// }
|
||||
/// pub enum AuraDevRog1 {
|
||||
/// Awake = 0x000002,
|
||||
/// Keyboard = 0x080000,
|
||||
/// Lightbar = 0x040500,
|
||||
/// Boot = 0xc31209,
|
||||
/// Sleep = 0x300804,
|
||||
/// }
|
||||
/// pub enum AuraDevRog2 {
|
||||
/// BootLogo = 1,
|
||||
/// BootKeyb = 1 << 1,
|
||||
/// AwakeLogo = 1 << 2,
|
||||
/// AwakeKeyb = 1 << 3,
|
||||
/// SleepLogo = 1 << 4,
|
||||
/// SleepKeyb = 1 << 5,
|
||||
/// ShutdownLogo = 1 << 6,
|
||||
/// ShutdownKeyb = 1 << 7,
|
||||
/// BootBar = 1 << (7 + 2),
|
||||
/// AwakeBar = 1 << (7 + 3),
|
||||
/// SleepBar = 1 << (7 + 4),
|
||||
/// ShutdownBar = 1 << (7 + 5),
|
||||
/// BootLid = 1 << (15 + 1),
|
||||
/// AwakeLid = 1 << (15 + 2),
|
||||
/// SleepLid = 1 << (15 + 3),
|
||||
/// ShutdownLid = 1 << (15 + 4),
|
||||
/// BootRearGlow = 1 << (23 + 1),
|
||||
/// AwakeRearGlow = 1 << (23 + 2),
|
||||
/// SleepRearGlow = 1 << (23 + 3),
|
||||
/// ShutdownRearGlow = 1 << (23 + 4),
|
||||
/// }
|
||||
/// ```
|
||||
/// For Modern ROG devices the "enabled" flag is ignored.
|
||||
async fn set_led_power(
|
||||
&mut self,
|
||||
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
||||
@@ -105,12 +64,10 @@ impl CtrlKbdLedZbus {
|
||||
for p in options.tuf {
|
||||
ctrl.config.enabled.set_tuf(p, enabled);
|
||||
}
|
||||
for p in options.x1866 {
|
||||
for p in options.old_rog {
|
||||
ctrl.config.enabled.set_0x1866(p, enabled);
|
||||
}
|
||||
for p in options.x19b6 {
|
||||
ctrl.config.enabled.set_0x19b6(p, enabled);
|
||||
}
|
||||
ctrl.config.enabled.set_0x19b6(options.rog);
|
||||
|
||||
ctrl.config.write();
|
||||
|
||||
@@ -345,7 +302,9 @@ impl CtrlTask for CtrlKbdLedZbus {
|
||||
impl crate::Reloadable for CtrlKbdLedZbus {
|
||||
async fn reload(&mut self) -> Result<(), RogError> {
|
||||
let mut ctrl = self.0.lock().await;
|
||||
debug!("CtrlKbdLedZbus: reloading keyboard mode");
|
||||
ctrl.write_current_config_mode()?;
|
||||
debug!("CtrlKbdLedZbus: reloading power states");
|
||||
ctrl.set_power_states().map_err(|err| warn!("{err}")).ok();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use config_traits::{StdConfig, StdConfigLoad};
|
||||
use rog_profiles::fan_curve_set::FanCurveSet;
|
||||
use rog_profiles::fan_curve_set::CurveData;
|
||||
use rog_profiles::Profile;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
@@ -36,9 +36,9 @@ impl StdConfigLoad for ProfileConfig {}
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug, Default)]
|
||||
pub struct FanCurveConfig {
|
||||
pub balanced: FanCurveSet,
|
||||
pub performance: FanCurveSet,
|
||||
pub quiet: FanCurveSet,
|
||||
pub balanced: Vec<CurveData>,
|
||||
pub performance: Vec<CurveData>,
|
||||
pub quiet: Vec<CurveData>,
|
||||
}
|
||||
|
||||
impl StdConfig for FanCurveConfig {
|
||||
@@ -48,13 +48,13 @@ impl StdConfig for FanCurveConfig {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
fn config_dir() -> std::path::PathBuf {
|
||||
PathBuf::from(CONFIG_PATH_BASE)
|
||||
}
|
||||
|
||||
fn file_name(&self) -> String {
|
||||
CONFIG_FAN_FILE.to_owned()
|
||||
}
|
||||
|
||||
fn config_dir() -> std::path::PathBuf {
|
||||
PathBuf::from(CONFIG_PATH_BASE)
|
||||
}
|
||||
}
|
||||
|
||||
impl StdConfigLoad for FanCurveConfig {}
|
||||
|
||||
@@ -56,13 +56,9 @@ impl GetSupported for CtrlPlatformProfile {
|
||||
);
|
||||
}
|
||||
|
||||
let res = FanCurveProfiles::is_supported();
|
||||
let mut fan_curve_supported = res.is_err();
|
||||
if let Ok(r) = res {
|
||||
fan_curve_supported = r;
|
||||
};
|
||||
let res = FanCurveProfiles::supported_fans();
|
||||
|
||||
if !fan_curve_supported {
|
||||
if res.is_err() {
|
||||
info!(
|
||||
"fan curves kernel interface not found, your laptop does not support this, or the \
|
||||
interface is missing."
|
||||
@@ -71,7 +67,7 @@ impl GetSupported for CtrlPlatformProfile {
|
||||
|
||||
PlatformProfileFunctions {
|
||||
platform_profile: Profile::is_platform_profile_supported(),
|
||||
fan_curves: fan_curve_supported,
|
||||
fans: res.unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,7 +87,11 @@ impl CtrlPlatformProfile {
|
||||
info!("{MOD_NAME}: Device has fan curves available");
|
||||
let fan_config = FanCurveConfig::new();
|
||||
// Only do defaults if the config doesn't already exist
|
||||
if !fan_config.file_path().exists() {
|
||||
if !fan_config.file_path().exists()
|
||||
|| fan_config.balanced.is_empty()
|
||||
|| fan_config.performance.is_empty()
|
||||
|| fan_config.quiet.is_empty()
|
||||
{
|
||||
info!("{MOD_NAME}: Fetching default fan curves");
|
||||
controller.fan_curves = Some(FanCurves {
|
||||
config_file: fan_config,
|
||||
@@ -113,10 +113,10 @@ impl CtrlPlatformProfile {
|
||||
let active = Profile::get_active_profile().unwrap_or(Profile::Balanced);
|
||||
|
||||
if let Some(curves) = controller.fan_curves.as_ref() {
|
||||
info!(
|
||||
"{MOD_NAME}: {active:?}: {}",
|
||||
String::from(curves.profiles().get_fan_curves_for(active))
|
||||
);
|
||||
info!("{MOD_NAME}: {active:?}:");
|
||||
for curve in curves.profiles().get_fan_curves_for(active) {
|
||||
info!("{}", String::from(curve));
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(curves) = controller.fan_curves.as_ref() {
|
||||
|
||||
@@ -4,8 +4,8 @@ use std::sync::Arc;
|
||||
use async_trait::async_trait;
|
||||
use config_traits::StdConfig;
|
||||
use log::{error, info, warn};
|
||||
use rog_profiles::fan_curve_set::{CurveData, FanCurveSet};
|
||||
use rog_profiles::{FanCurveProfiles, Profile};
|
||||
use rog_profiles::fan_curve_set::CurveData;
|
||||
use rog_profiles::{FanCurvePU, FanCurveProfiles, Profile};
|
||||
use zbus::export::futures_util::lock::Mutex;
|
||||
use zbus::export::futures_util::StreamExt;
|
||||
use zbus::fdo::Error;
|
||||
@@ -83,19 +83,9 @@ impl ProfileZbus {
|
||||
.ok();
|
||||
}
|
||||
|
||||
/// Get a list of profiles that have fan-curves enabled.
|
||||
async fn enabled_fan_profiles(&mut self) -> zbus::fdo::Result<Vec<Profile>> {
|
||||
let mut ctrl = self.0.lock().await;
|
||||
ctrl.profile_config.read();
|
||||
if let Some(curves) = &mut ctrl.fan_curves {
|
||||
return Ok(curves.profiles().get_enabled_curve_profiles());
|
||||
}
|
||||
Err(Error::Failed(UNSUPPORTED_MSG.to_owned()))
|
||||
}
|
||||
|
||||
/// Set a profile fan curve enabled status. Will also activate a fan curve
|
||||
/// if in the same profile mode
|
||||
async fn set_fan_curve_enabled(
|
||||
/// Set all fan curves for a profile to enabled status. Will also activate a
|
||||
/// fan curve if in the same profile mode
|
||||
async fn set_fan_curves_enabled(
|
||||
&mut self,
|
||||
profile: Profile,
|
||||
enabled: bool,
|
||||
@@ -105,7 +95,33 @@ impl ProfileZbus {
|
||||
if let Some(curves) = &mut ctrl.fan_curves {
|
||||
curves
|
||||
.profiles_mut()
|
||||
.set_profile_curve_enabled(profile, enabled);
|
||||
.set_profile_curves_enabled(profile, enabled);
|
||||
|
||||
ctrl.write_profile_curve_to_platform()
|
||||
.map_err(|e| warn!("{MOD_NAME}: write_profile_curve_to_platform, {}", e))
|
||||
.ok();
|
||||
|
||||
ctrl.save_config();
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::Failed(UNSUPPORTED_MSG.to_owned()))
|
||||
}
|
||||
}
|
||||
|
||||
/// Set a single fan curve for a profile to enabled status. Will also
|
||||
/// activate a fan curve if in the same profile mode
|
||||
async fn set_profile_fan_curve_enabled(
|
||||
&mut self,
|
||||
profile: Profile,
|
||||
fan: FanCurvePU,
|
||||
enabled: bool,
|
||||
) -> zbus::fdo::Result<()> {
|
||||
let mut ctrl = self.0.lock().await;
|
||||
ctrl.profile_config.read();
|
||||
if let Some(curves) = &mut ctrl.fan_curves {
|
||||
curves
|
||||
.profiles_mut()
|
||||
.set_profile_fan_curve_enabled(profile, fan, enabled);
|
||||
|
||||
ctrl.write_profile_curve_to_platform()
|
||||
.map_err(|e| warn!("{MOD_NAME}: write_profile_curve_to_platform, {}", e))
|
||||
@@ -119,12 +135,12 @@ impl ProfileZbus {
|
||||
}
|
||||
|
||||
/// Get the fan-curve data for the currently active Profile
|
||||
async fn fan_curve_data(&mut self, profile: Profile) -> zbus::fdo::Result<FanCurveSet> {
|
||||
async fn fan_curve_data(&mut self, profile: Profile) -> zbus::fdo::Result<Vec<CurveData>> {
|
||||
let mut ctrl = self.0.lock().await;
|
||||
ctrl.profile_config.read();
|
||||
if let Some(curves) = &mut ctrl.fan_curves {
|
||||
let curve = curves.profiles().get_fan_curves_for(profile);
|
||||
return Ok(curve.clone());
|
||||
return Ok(curve.to_vec());
|
||||
}
|
||||
Err(Error::Failed(UNSUPPORTED_MSG.to_owned()))
|
||||
}
|
||||
|
||||
@@ -11,51 +11,10 @@
|
||||
Set a variety of states, input is array of enum.
|
||||
`enabled` sets if the sent array should be disabled or enabled
|
||||
|
||||
```text
|
||||
pub struct AuraPowerDev {
|
||||
tuf: Vec<AuraDevTuf>,
|
||||
x1866: Vec<AuraDevRog1>,
|
||||
x19b6: Vec<AuraDevRog2>,
|
||||
}
|
||||
pub enum AuraDevTuf {
|
||||
Boot,
|
||||
Awake,
|
||||
Sleep,
|
||||
Keyboard,
|
||||
}
|
||||
pub enum AuraDevRog1 {
|
||||
Awake = 0x000002,
|
||||
Keyboard = 0x080000,
|
||||
Lightbar = 0x040500,
|
||||
Boot = 0xc31209,
|
||||
Sleep = 0x300804,
|
||||
}
|
||||
pub enum AuraDevRog2 {
|
||||
BootLogo = 1,
|
||||
BootKeyb = 1 << 1,
|
||||
AwakeLogo = 1 << 2,
|
||||
AwakeKeyb = 1 << 3,
|
||||
SleepLogo = 1 << 4,
|
||||
SleepKeyb = 1 << 5,
|
||||
ShutdownLogo = 1 << 6,
|
||||
ShutdownKeyb = 1 << 7,
|
||||
BootBar = 1 << (7 + 2),
|
||||
AwakeBar = 1 << (7 + 3),
|
||||
SleepBar = 1 << (7 + 4),
|
||||
ShutdownBar = 1 << (7 + 5),
|
||||
BootLid = 1 << (15 + 1),
|
||||
AwakeLid = 1 << (15 + 2),
|
||||
SleepLid = 1 << (15 + 3),
|
||||
ShutdownLid = 1 << (15 + 4),
|
||||
BootRearGlow = 1 << (23 + 1),
|
||||
AwakeRearGlow = 1 << (23 + 2),
|
||||
SleepRearGlow = 1 << (23 + 3),
|
||||
ShutdownRearGlow = 1 << (23 + 4),
|
||||
}
|
||||
```
|
||||
For Modern ROG devices the "enabled" flag is ignored.
|
||||
-->
|
||||
<method name="SetLedPower">
|
||||
<arg name="options" type="(asasas)" direction="in"/>
|
||||
<arg name="options" type="(asas((sbbbb)(sbbbb)(sbbbb)(sbbbb)(sbbbb)))" direction="in"/>
|
||||
<arg name="enabled" type="b" direction="in"/>
|
||||
</method>
|
||||
<method name="SetLedMode">
|
||||
@@ -76,7 +35,7 @@
|
||||
<arg type="s" direction="out"/>
|
||||
</method>
|
||||
<method name="LedPower">
|
||||
<arg type="asasas" direction="out"/>
|
||||
<arg type="asas((sbbbb)(sbbbb)(sbbbb)(sbbbb)(sbbbb))" direction="out"/>
|
||||
</method>
|
||||
<!--
|
||||
Return the current mode data
|
||||
@@ -102,7 +61,7 @@
|
||||
<arg name="data" type="(ss(yyy)(yyy)ss)"/>
|
||||
</signal>
|
||||
<signal name="NotifyPowerStates">
|
||||
<arg name="data" type="(asasas)"/>
|
||||
<arg name="data" type="(asas((sbbbb)(sbbbb)(sbbbb)(sbbbb)(sbbbb)))"/>
|
||||
</signal>
|
||||
<!--
|
||||
Return the current LED brightness
|
||||
|
||||
+69
-65
@@ -107,6 +107,64 @@ export interface AuraEffect {
|
||||
direction: Direction;
|
||||
}
|
||||
|
||||
/** The powerr zones this laptop supports */
|
||||
export enum PowerZones {
|
||||
/** The logo on some laptop lids */
|
||||
Logo = "Logo",
|
||||
/** The full keyboard (not zones) */
|
||||
Keyboard = "Keyboard",
|
||||
/** The lightbar, typically on the front of the laptop */
|
||||
Lightbar = "Lightbar",
|
||||
/** The leds that may be placed around the edge of the laptop lid */
|
||||
Lid = "Lid",
|
||||
/** The led strip on the rear of some laptops */
|
||||
RearGlow = "RearGlow",
|
||||
}
|
||||
|
||||
export interface KbAuraPowerState {
|
||||
zone: PowerZones;
|
||||
boot: boolean;
|
||||
awake: boolean;
|
||||
sleep: boolean;
|
||||
shutdown: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Track and control the Aura keyboard power state
|
||||
*
|
||||
* # Bits for newer 0x18c6, 0x19B6, 0x1a30, keyboard models
|
||||
*
|
||||
* | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Label |
|
||||
* |--------|---------|---------|---------|----------|
|
||||
* |00000001| 00000000| 00000000| 00000000|boot_logo_|
|
||||
* |00000010| 00000000| 00000000| 00000000|boot_keyb_|
|
||||
* |00000100| 00000000| 00000000| 00000000|awake_logo|
|
||||
* |00001000| 00000000| 00000000| 00000000|awake_keyb|
|
||||
* |00010000| 00000000| 00000000| 00000000|sleep_logo|
|
||||
* |00100000| 00000000| 00000000| 00000000|sleep_keyb|
|
||||
* |01000000| 00000000| 00000000| 00000000|shut_logo_|
|
||||
* |10000000| 00000000| 00000000| 00000000|shut_keyb_|
|
||||
* |00000000| 00000010| 00000000| 00000000|boot_bar__|
|
||||
* |00000000| 00000100| 00000000| 00000000|awake_bar_|
|
||||
* |00000000| 00001000| 00000000| 00000000|sleep_bar_|
|
||||
* |00000000| 00010000| 00000000| 00000000|shut_bar__|
|
||||
* |00000000| 00000000| 00000001| 00000000|boot_lid__|
|
||||
* |00000000| 00000000| 00000010| 00000000|awkae_lid_|
|
||||
* |00000000| 00000000| 00000100| 00000000|sleep_lid_|
|
||||
* |00000000| 00000000| 00001000| 00000000|shut_lid__|
|
||||
* |00000000| 00000000| 00000000| 00000001|boot_rear_|
|
||||
* |00000000| 00000000| 00000000| 00000010|awake_rear|
|
||||
* |00000000| 00000000| 00000000| 00000100|sleep_rear|
|
||||
* |00000000| 00000000| 00000000| 00001000|shut_rear_|
|
||||
*/
|
||||
export interface AuraPower {
|
||||
keyboard: KbAuraPowerState;
|
||||
logo: KbAuraPowerState;
|
||||
lightbar: KbAuraPowerState;
|
||||
lid: KbAuraPowerState;
|
||||
rear_glow: KbAuraPowerState;
|
||||
}
|
||||
|
||||
export enum AuraDevTuf {
|
||||
Boot = "Boot",
|
||||
Awake = "Awake",
|
||||
@@ -138,74 +196,20 @@ export enum AuraDevRog1 {
|
||||
Sleep = "Sleep",
|
||||
}
|
||||
|
||||
/**
|
||||
* # Bits for newer 0x18c6, 0x19B6, 0x1a30, keyboard models
|
||||
*
|
||||
* | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Label |
|
||||
* |--------|---------|---------|---------|----------|
|
||||
* |00000001| 00000000| 00000000| 00000000|boot_logo_|
|
||||
* |00000010| 00000000| 00000000| 00000000|boot_keyb_|
|
||||
* |00000100| 00000000| 00000000| 00000000|awake_logo|
|
||||
* |00001000| 00000000| 00000000| 00000000|awake_keyb|
|
||||
* |00010000| 00000000| 00000000| 00000000|sleep_logo|
|
||||
* |00100000| 00000000| 00000000| 00000000|sleep_keyb|
|
||||
* |01000000| 00000000| 00000000| 00000000|shut_logo_|
|
||||
* |10000000| 00000000| 00000000| 00000000|shut_keyb_|
|
||||
* |00000000| 00000010| 00000000| 00000000|boot_bar__|
|
||||
* |00000000| 00000100| 00000000| 00000000|awake_bar_|
|
||||
* |00000000| 00001000| 00000000| 00000000|sleep_bar_|
|
||||
* |00000000| 00010000| 00000000| 00000000|shut_bar__|
|
||||
* |00000000| 00000000| 00000001| 00000000|boot_lid__|
|
||||
* |00000000| 00000000| 00000010| 00000000|awkae_lid_|
|
||||
* |00000000| 00000000| 00000100| 00000000|sleep_lid_|
|
||||
* |00000000| 00000000| 00001000| 00000000|shut_lid__|
|
||||
* |00000000| 00000000| 00000000| 00000001|boot_rear_|
|
||||
* |00000000| 00000000| 00000000| 00000010|awake_rear|
|
||||
* |00000000| 00000000| 00000000| 00000100|sleep_rear|
|
||||
* |00000000| 00000000| 00000000| 00001000|shut_rear_|
|
||||
*/
|
||||
export enum AuraDevRog2 {
|
||||
BootLogo = "BootLogo",
|
||||
BootKeyb = "BootKeyb",
|
||||
AwakeLogo = "AwakeLogo",
|
||||
AwakeKeyb = "AwakeKeyb",
|
||||
SleepLogo = "SleepLogo",
|
||||
SleepKeyb = "SleepKeyb",
|
||||
ShutdownLogo = "ShutdownLogo",
|
||||
ShutdownKeyb = "ShutdownKeyb",
|
||||
BootBar = "BootBar",
|
||||
AwakeBar = "AwakeBar",
|
||||
SleepBar = "SleepBar",
|
||||
ShutdownBar = "ShutdownBar",
|
||||
BootLid = "BootLid",
|
||||
AwakeLid = "AwakeLid",
|
||||
SleepLid = "SleepLid",
|
||||
ShutdownLid = "ShutdownLid",
|
||||
BootRearGlow = "BootRearGlow",
|
||||
AwakeRearGlow = "AwakeRearGlow",
|
||||
SleepRearGlow = "SleepRearGlow",
|
||||
ShutdownRearGlow = "ShutdownRearGlow",
|
||||
}
|
||||
|
||||
/** This struct is intended as a helper to pass args to generic dbus interface */
|
||||
export interface AuraPowerDev {
|
||||
/**
|
||||
* TUF laptops use a similar style of control to the older ROG devices but
|
||||
* through WMI
|
||||
*/
|
||||
tuf: AuraDevTuf[];
|
||||
x1866: AuraDevRog1[];
|
||||
x19b6: AuraDevRog2[];
|
||||
}
|
||||
|
||||
/** The powerr zones this laptop supports */
|
||||
export enum PowerZones {
|
||||
/** The logo on some laptop lids */
|
||||
Logo = "Logo",
|
||||
/** The full keyboard (not zones) */
|
||||
Keyboard = "Keyboard",
|
||||
/** The lightbar, typically on the front of the laptop */
|
||||
Lightbar = "Lightbar",
|
||||
/** The leds that may be placed around the edge of the laptop lid */
|
||||
Lid = "Lid",
|
||||
/** The led strip on the rear of some laptops */
|
||||
RearGlow = "RearGlow",
|
||||
/**
|
||||
* Pre-0x19b6 devices use a different smaller scheme to the newer ROG
|
||||
* devices
|
||||
*/
|
||||
old_rog: AuraDevRog1[];
|
||||
/** ASUS standardised control scheme from 2020 onwards */
|
||||
rog: AuraPower;
|
||||
}
|
||||
|
||||
export enum LedBrightness {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// REF: https://gjs.guide/extensions/development/creating.html
|
||||
|
||||
import { AnimeDbus } from "./modules/dbus/animatrix";
|
||||
import { Power } from "./modules/dbus/power";
|
||||
import { Supported } from "./modules/dbus/supported";
|
||||
|
||||
@@ -6,6 +6,6 @@
|
||||
"settings-schema": "org.gnome.shell.extensions.asusctl-gnome",
|
||||
"version": "4.3.2",
|
||||
"shell-version": [
|
||||
"43", "44"
|
||||
"43", "44", "45"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AuraDevRog1, AuraDevRog2, AuraDevTuf, AuraDevice, AuraEffect, AuraModeNum, AuraPowerDev, AuraZone, Direction, Speed } from "../../bindings/aura";
|
||||
import { AuraDevRog1, AuraDevTuf, AuraDevice, AuraEffect, AuraModeNum, AuraPower, AuraPowerDev, AuraZone, Direction, PowerZones, Speed } from "../../bindings/aura";
|
||||
import { DbusBase } from "./base";
|
||||
|
||||
export class AuraDbus extends DbusBase {
|
||||
@@ -7,8 +7,44 @@ export class AuraDbus extends DbusBase {
|
||||
public aura_modes: Map<AuraModeNum, AuraEffect> = new Map;
|
||||
public leds_powered: AuraPowerDev = {
|
||||
tuf: [],
|
||||
x1866: [],
|
||||
x19b6: []
|
||||
old_rog: [],
|
||||
rog: {
|
||||
keyboard: {
|
||||
zone: PowerZones.Keyboard,
|
||||
boot: false,
|
||||
awake: false,
|
||||
sleep: false,
|
||||
shutdown: false
|
||||
},
|
||||
logo: {
|
||||
zone: PowerZones.Logo,
|
||||
boot: false,
|
||||
awake: false,
|
||||
sleep: false,
|
||||
shutdown: false
|
||||
},
|
||||
lightbar: {
|
||||
zone: PowerZones.Lightbar,
|
||||
boot: false,
|
||||
awake: false,
|
||||
sleep: false,
|
||||
shutdown: false
|
||||
},
|
||||
lid: {
|
||||
zone: PowerZones.Lid,
|
||||
boot: false,
|
||||
awake: false,
|
||||
sleep: false,
|
||||
shutdown: false
|
||||
},
|
||||
rear_glow: {
|
||||
zone: PowerZones.RearGlow,
|
||||
boot: false,
|
||||
awake: false,
|
||||
sleep: false,
|
||||
shutdown: false
|
||||
},
|
||||
}
|
||||
};
|
||||
// TODO: interface or something to enforce requirement of "sync()" method
|
||||
public notifyAuraModeSubscribers: any[] = [];
|
||||
@@ -32,21 +68,51 @@ export class AuraDbus extends DbusBase {
|
||||
}
|
||||
|
||||
_parsePowerStates(data: any[]) {
|
||||
const power: AuraPowerDev = {
|
||||
tuf: [],
|
||||
x1866: [],
|
||||
x19b6: []
|
||||
};
|
||||
const power: AuraPowerDev = this.leds_powered;
|
||||
|
||||
power.tuf = data[0].map((value: string) => {
|
||||
return AuraDevTuf[value as AuraDevTuf];
|
||||
});
|
||||
power.x1866 = data[1].map((value: string) => {
|
||||
power.old_rog = data[1].map((value: string) => {
|
||||
return AuraDevRog1[value as AuraDevRog1];
|
||||
});
|
||||
power.x19b6 = data[2].map((value: string) => {
|
||||
return AuraDevRog2[value as AuraDevRog2];
|
||||
});
|
||||
power.rog = {
|
||||
keyboard: {
|
||||
zone: PowerZones[data[2][0][0] as PowerZones],
|
||||
boot: data[2][0][1],
|
||||
awake: data[2][0][2],
|
||||
sleep: data[2][0][3],
|
||||
shutdown: data[2][0][4]
|
||||
},
|
||||
logo: {
|
||||
zone: PowerZones[data[2][1][0] as PowerZones],
|
||||
boot: data[2][1][1],
|
||||
awake: data[2][1][2],
|
||||
sleep: data[2][1][3],
|
||||
shutdown: data[2][1][4]
|
||||
},
|
||||
lightbar: {
|
||||
zone: PowerZones[data[2][2][0] as PowerZones],
|
||||
boot: data[2][2][1],
|
||||
awake: data[2][2][2],
|
||||
sleep: data[2][2][3],
|
||||
shutdown: data[2][2][4]
|
||||
},
|
||||
lid: {
|
||||
zone: PowerZones[data[2][3][0] as PowerZones],
|
||||
boot: data[2][3][1],
|
||||
awake: data[2][3][2],
|
||||
sleep: data[2][3][3],
|
||||
shutdown: data[2][3][4]
|
||||
},
|
||||
rear_glow: {
|
||||
zone: PowerZones[data[2][4][0] as PowerZones],
|
||||
boot: data[2][4][1],
|
||||
awake: data[2][4][2],
|
||||
sleep: data[2][4][3],
|
||||
shutdown: data[2][4][4]
|
||||
}
|
||||
};
|
||||
|
||||
return power;
|
||||
}
|
||||
@@ -59,9 +125,9 @@ export class AuraDbus extends DbusBase {
|
||||
//@ts-ignore
|
||||
log("LED power tuf: " + this.leds_powered.tuf);
|
||||
//@ts-ignore
|
||||
log("LED power x1866: " + this.leds_powered.x1866);
|
||||
log("LED power x1866: " + this.leds_powered.old_rog);
|
||||
//@ts-ignore
|
||||
log("LED power x19b6: " + this.leds_powered.x19b6);
|
||||
log("LED power x19b6: " + this.leds_powered.rog);
|
||||
} catch (e) {
|
||||
//@ts-ignore
|
||||
log("Failed to fetch supported functionalities", e);
|
||||
@@ -180,26 +246,26 @@ export class AuraDbus extends DbusBase {
|
||||
const power: AuraPowerDev = this._parsePowerStates(data[0]);
|
||||
this.leds_powered = power;
|
||||
switch (this.device) {
|
||||
case AuraDevice.Tuf:
|
||||
//@ts-ignore
|
||||
log("LED power has changed to ", this.leds_powered.tuf);
|
||||
break;
|
||||
case AuraDevice.X1854:
|
||||
case AuraDevice.X1869:
|
||||
case AuraDevice.X18c6:
|
||||
//@ts-ignore
|
||||
log("LED power has changed to ", this.leds_powered.x1866);
|
||||
break;
|
||||
case AuraDevice.X19b6:
|
||||
case AuraDevice.X1a30:
|
||||
//@ts-ignore
|
||||
log("LED power has changed to ", this.leds_powered.x19b6);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case AuraDevice.Tuf:
|
||||
//@ts-ignore
|
||||
log("LED power has changed to ", this.leds_powered.tuf);
|
||||
break;
|
||||
case AuraDevice.X1854:
|
||||
case AuraDevice.X1869:
|
||||
case AuraDevice.X18c6:
|
||||
//@ts-ignore
|
||||
log("LED power has changed to ", this.leds_powered.old_rog);
|
||||
break;
|
||||
case AuraDevice.X19b6:
|
||||
case AuraDevice.X1a30:
|
||||
//@ts-ignore
|
||||
log("LED power has changed to ", this.leds_powered.rog);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
//@ts-ignore
|
||||
log("LED power has changed to ", this.leds_powered.x19b6);
|
||||
log("LED power has changed to ", this.leds_powered.rog);
|
||||
this.notifyAuraPowerSubscribers.forEach(sub => {
|
||||
sub.sync();
|
||||
});
|
||||
|
||||
Executable
+128
@@ -0,0 +1,128 @@
|
||||
#
|
||||
# spec file for package asus-nb-ctrl
|
||||
#
|
||||
# Copyright (c) 2020-2021 Luke Jones <luke@ljones.dev>
|
||||
#
|
||||
# All modifications and additions to the file contributed by third parties
|
||||
# remain the property of their copyright owners, unless otherwise agreed
|
||||
# upon. The license for this file, and modifications and additions to the
|
||||
# file, is the same license as for the pristine package itself (unless the
|
||||
# license for the pristine package is not an Open Source License, in which
|
||||
# case the license is the MIT License). An "Open Source License" is a
|
||||
# license that conforms to the Open Source Definition (Version 1.9)
|
||||
# published by the Open Source Initiative.
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
%if %{defined fedora}
|
||||
%global debug_package %{nil}
|
||||
%endif
|
||||
|
||||
%global rpm_dkms_opt 1
|
||||
|
||||
# Use hardening ldflags.
|
||||
%global rustflags -Clink-arg=-Wl,-z,relro,-z,now
|
||||
Name: asusctl
|
||||
Version: 4.7.0
|
||||
Release: 2
|
||||
Summary: Control fan speeds, LEDs, graphics modes, and charge levels for ASUS notebooks
|
||||
License: MPLv2
|
||||
|
||||
Group: System Environment/Kernel
|
||||
|
||||
URL: https://gitlab.com/asus-linux/asusctl
|
||||
Source: %{name}-%{version}.tar.gz
|
||||
Source1: vendor-%{name}-%{version}.tar.gz
|
||||
Source2: cargo_config
|
||||
|
||||
BuildRequires: cargo
|
||||
BuildRequires: rust-packaging
|
||||
BuildRequires: systemd-rpm-macros
|
||||
BuildRequires: clang-devel
|
||||
BuildRequires: cmake
|
||||
BuildRequires: rust
|
||||
BuildRequires: rust-std-static
|
||||
BuildRequires: pkgconfig(dbus-1)
|
||||
BuildRequires: pkgconfig(libudev)
|
||||
BuildRequires: pkgconfig(gtk+-3.0)
|
||||
BuildRequires: pkgconfig(gdk-3.0)
|
||||
BuildRequires: desktop-file-utils
|
||||
Requires: libappindicator-gtk3
|
||||
|
||||
%description
|
||||
asus-nb-ctrl is a utility for Linux to control many aspects of various
|
||||
ASUS laptops but can also be used with non-Asus laptops with reduced features.
|
||||
|
||||
It provides an interface for rootless control of some system functions such as
|
||||
fan speeds, keyboard LEDs, battery charge level, and graphics modes.
|
||||
asus-nb-ctrl enables third-party apps to use the above with dbus methods.
|
||||
|
||||
%package rog-gui
|
||||
Summary: An experimental GUI for %{name}
|
||||
|
||||
%description rog-gui
|
||||
A one-stop-shop GUI tool for asusd/asusctl. It aims to provide most controls,
|
||||
a notification service, and ability to run in the background.
|
||||
|
||||
%prep
|
||||
%autosetup
|
||||
%setup -D -T -a 1 -c -n %{name}-%{version}/vendor
|
||||
cd ..
|
||||
|
||||
mv Cargo.lock{,.bak}
|
||||
%cargo_prep
|
||||
mv Cargo.lock{.bak,}
|
||||
sed -i 's|replace-with = "local-registry"|replace-with = "vendored-sources"|' .cargo/config
|
||||
cat %{SOURCE2} >> .cargo/config
|
||||
|
||||
%build
|
||||
export RUSTFLAGS="%{rustflags}"
|
||||
%cargo_build
|
||||
#cargo build --release --frozen --offline --config .cargo/config.toml
|
||||
|
||||
%install
|
||||
export RUSTFLAGS="%{rustflags}"
|
||||
mkdir -p "%{buildroot}/%{_bindir}" "%{buildroot}%{_docdir}"
|
||||
%make_install
|
||||
|
||||
install -D -m 0644 README.md %{buildroot}/%{_docdir}/%{name}/README.md
|
||||
install -D -m 0644 rog-anime/README.md %{buildroot}/%{_docdir}/%{name}/README-anime.md
|
||||
install -D -m 0644 rog-anime/data/diagonal-template.png %{buildroot}/%{_docdir}/%{name}/diagonal-template.png
|
||||
|
||||
desktop-file-validate %{buildroot}/%{_datadir}/applications/rog-control-center.desktop
|
||||
|
||||
%files
|
||||
%license LICENSE
|
||||
%{_bindir}/asusd
|
||||
%{_bindir}/asusd-user
|
||||
%{_bindir}/asusctl
|
||||
%{_unitdir}/asusd.service
|
||||
%{_userunitdir}/asusd-user.service
|
||||
%{_udevrulesdir}/99-asusd.rules
|
||||
#%dir %{_sysconfdir}/asusd/
|
||||
%{_datadir}/asusd/aura_support.ron
|
||||
%{_datadir}/dbus-1/system.d/asusd.conf
|
||||
%{_datadir}/icons/hicolor/512x512/apps/asus_notif_yellow.png
|
||||
%{_datadir}/icons/hicolor/512x512/apps/asus_notif_green.png
|
||||
%{_datadir}/icons/hicolor/512x512/apps/asus_notif_red.png
|
||||
%{_datadir}/icons/hicolor/512x512/apps/asus_notif_blue.png
|
||||
%{_datadir}/icons/hicolor/512x512/apps/asus_notif_orange.png
|
||||
%{_datadir}/icons/hicolor/512x512/apps/asus_notif_white.png
|
||||
%{_datadir}/icons/hicolor/scalable/status/gpu-compute.svg
|
||||
%{_datadir}/icons/hicolor/scalable/status/gpu-hybrid.svg
|
||||
%{_datadir}/icons/hicolor/scalable/status/gpu-integrated.svg
|
||||
%{_datadir}/icons/hicolor/scalable/status/gpu-nvidia.svg
|
||||
%{_datadir}/icons/hicolor/scalable/status/gpu-vfio.svg
|
||||
%{_datadir}/icons/hicolor/scalable/status/notification-reboot.svg
|
||||
%{_docdir}/%{name}/
|
||||
%{_datadir}/asusd/
|
||||
|
||||
%files rog-gui
|
||||
%{_bindir}/rog-control-center
|
||||
%{_datadir}/applications/rog-control-center.desktop
|
||||
%{_datadir}/icons/hicolor/512x512/apps/rog-control-center.png
|
||||
%{_datadir}/rog-gui
|
||||
|
||||
%changelog
|
||||
@@ -31,6 +31,14 @@
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
board_name: "FX505G",
|
||||
layout_name: "fx505d",
|
||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
board_name: "FX506H",
|
||||
layout_name: "fa506i",
|
||||
@@ -375,6 +383,14 @@
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
board_name: "GA402X",
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, Pulse, Rainbow],
|
||||
basic_zones: [],
|
||||
advanced_type: None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
board_name: "GA503Q",
|
||||
layout_name: "ga401q",
|
||||
@@ -495,6 +511,14 @@
|
||||
advanced_type: Zoned([SingleZone]),
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
board_name: "GU603VV",
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: Zoned([SingleZone]),
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
board_name: "GU603Z",
|
||||
layout_name: "ga401q",
|
||||
@@ -544,11 +568,11 @@
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
board_name: "GV601VI",
|
||||
board_name: "GV601V",
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, Pulse, Strobe],
|
||||
basic_modes: [Static, Breathe, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: None,
|
||||
advanced_type: Zoned([SingleZone]),
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
|
||||
@@ -24,7 +24,7 @@ pub struct LedSupportFile(Vec<LaptopLedData>);
|
||||
/// The powerr zones this laptop supports
|
||||
#[typeshare]
|
||||
#[cfg_attr(feature = "dbus", derive(Type), zvariant(signature = "s"))]
|
||||
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Default, Clone)]
|
||||
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Default, Copy, Clone)]
|
||||
pub enum PowerZones {
|
||||
/// The logo on some laptop lids
|
||||
#[default]
|
||||
@@ -63,7 +63,7 @@ impl LaptopLedData {
|
||||
// let prod_family = dmi.product_family().expect("Could not get
|
||||
// product_family");
|
||||
|
||||
if let Some(modes) = LedSupportFile::load_from_config() {
|
||||
if let Some(modes) = LedSupportFile::load_from_supoprt_db() {
|
||||
if let Some(data) = modes.matcher(&board_name) {
|
||||
return data;
|
||||
}
|
||||
@@ -90,7 +90,12 @@ impl LedSupportFile {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn load_from_config() -> Option<Self> {
|
||||
/// Load `LedSupportFile` from the `aura_support.ron` file at
|
||||
/// `/usr/share/asusd/aura_support.ron` and append with data from
|
||||
/// `/etc/asusd/asusd_user_ledmodes.ron` if that file is available.
|
||||
///
|
||||
/// Returns `None` if neither file exists or does not parse correctly.
|
||||
pub fn load_from_supoprt_db() -> Option<Self> {
|
||||
let mut loaded = false;
|
||||
let mut data = LedSupportFile::default();
|
||||
// Load user configs first so they are first to be checked
|
||||
|
||||
@@ -17,10 +17,11 @@ use crate::LED_MSG_LEN;
|
||||
|
||||
#[typeshare]
|
||||
#[cfg_attr(feature = "dbus", derive(Type), zvariant(signature = "s"))]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Deserialize, Serialize)]
|
||||
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Deserialize, Serialize)]
|
||||
pub enum LedBrightness {
|
||||
Off,
|
||||
Low,
|
||||
#[default]
|
||||
Med,
|
||||
High,
|
||||
}
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
//! Older code that is not useful but stillr elevant as a reference
|
||||
|
||||
/// # Bits for newer 0x18c6, 0x19B6, 0x1a30, keyboard models
|
||||
///
|
||||
/// | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Label |
|
||||
/// |--------|---------|---------|---------|----------|
|
||||
/// |00000001| 00000000| 00000000| 00000000|boot_logo_|
|
||||
/// |00000010| 00000000| 00000000| 00000000|boot_keyb_|
|
||||
/// |00000100| 00000000| 00000000| 00000000|awake_logo|
|
||||
/// |00001000| 00000000| 00000000| 00000000|awake_keyb|
|
||||
/// |00010000| 00000000| 00000000| 00000000|sleep_logo|
|
||||
/// |00100000| 00000000| 00000000| 00000000|sleep_keyb|
|
||||
/// |01000000| 00000000| 00000000| 00000000|shut_logo_|
|
||||
/// |10000000| 00000000| 00000000| 00000000|shut_keyb_|
|
||||
/// |00000000| 00000010| 00000000| 00000000|boot_bar__|
|
||||
/// |00000000| 00000100| 00000000| 00000000|awake_bar_|
|
||||
/// |00000000| 00001000| 00000000| 00000000|sleep_bar_|
|
||||
/// |00000000| 00010000| 00000000| 00000000|shut_bar__|
|
||||
/// |00000000| 00000000| 00000001| 00000000|boot_lid__|
|
||||
/// |00000000| 00000000| 00000010| 00000000|awkae_lid_|
|
||||
/// |00000000| 00000000| 00000100| 00000000|sleep_lid_|
|
||||
/// |00000000| 00000000| 00001000| 00000000|shut_lid__|
|
||||
/// |00000000| 00000000| 00000000| 00000001|boot_rear_|
|
||||
/// |00000000| 00000000| 00000000| 00000010|awake_rear|
|
||||
/// |00000000| 00000000| 00000000| 00000100|sleep_rear|
|
||||
/// |00000000| 00000000| 00000000| 00001000|shut_rear_|
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
#[repr(u32)]
|
||||
pub enum AuraDevRog2 {
|
||||
BootLogo = 1,
|
||||
BootKeyb = 1 << 1,
|
||||
AwakeLogo = 1 << 2,
|
||||
AwakeKeyb = 1 << 3,
|
||||
SleepLogo = 1 << 4,
|
||||
SleepKeyb = 1 << 5,
|
||||
ShutdownLogo = 1 << 6,
|
||||
ShutdownKeyb = 1 << 7,
|
||||
BootBar = 1 << (7 + 2),
|
||||
AwakeBar = 1 << (7 + 3),
|
||||
SleepBar = 1 << (7 + 4),
|
||||
ShutdownBar = 1 << (7 + 5),
|
||||
BootLid = 1 << (15 + 1),
|
||||
AwakeLid = 1 << (15 + 2),
|
||||
SleepLid = 1 << (15 + 3),
|
||||
ShutdownLid = 1 << (15 + 4),
|
||||
BootRearGlow = 1 << (23 + 1),
|
||||
AwakeRearGlow = 1 << (23 + 2),
|
||||
SleepRearGlow = 1 << (23 + 3),
|
||||
ShutdownRearGlow = 1 << (23 + 4),
|
||||
}
|
||||
|
||||
impl From<AuraDevRog2> for u32 {
|
||||
fn from(a: AuraDevRog2) -> Self {
|
||||
a as u32
|
||||
}
|
||||
}
|
||||
|
||||
impl AuraDevRog2 {
|
||||
pub fn to_bytes(control: &[Self]) -> [u8; 4] {
|
||||
let mut a: u32 = 0;
|
||||
for n in control {
|
||||
a |= *n as u32;
|
||||
}
|
||||
[
|
||||
(a & 0xff) as u8,
|
||||
((a & 0xff00) >> 8) as u8,
|
||||
((a & 0xff0000) >> 16) as u8,
|
||||
((a & 0xff000000) >> 24) as u8,
|
||||
]
|
||||
}
|
||||
|
||||
pub const fn dev_id() -> &'static str {
|
||||
"0x196b"
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::deprecated::AuraDevRog2;
|
||||
|
||||
#[test]
|
||||
fn check_0x19b6_control_bytes_binary_rep() {
|
||||
fn to_binary_string(bytes: &[AuraDevRog2]) -> String {
|
||||
let bytes = AuraDevRog2::to_bytes(bytes);
|
||||
format!(
|
||||
"{:08b}, {:08b}, {:08b}, {:08b}",
|
||||
bytes[0], bytes[1], bytes[2], bytes[3]
|
||||
)
|
||||
}
|
||||
|
||||
let boot_logo_ = to_binary_string(&[AuraDevRog2::BootLogo]);
|
||||
let boot_keyb_ = to_binary_string(&[AuraDevRog2::BootKeyb]);
|
||||
let sleep_logo = to_binary_string(&[AuraDevRog2::SleepLogo]);
|
||||
let sleep_keyb = to_binary_string(&[AuraDevRog2::SleepKeyb]);
|
||||
let awake_logo = to_binary_string(&[AuraDevRog2::AwakeLogo]);
|
||||
let awake_keyb = to_binary_string(&[AuraDevRog2::AwakeKeyb]);
|
||||
let shut_logo_ = to_binary_string(&[AuraDevRog2::ShutdownLogo]);
|
||||
let shut_keyb_ = to_binary_string(&[AuraDevRog2::ShutdownKeyb]);
|
||||
let boot_bar__ = to_binary_string(&[AuraDevRog2::BootBar]);
|
||||
let awake_bar_ = to_binary_string(&[AuraDevRog2::AwakeBar]);
|
||||
let sleep_bar_ = to_binary_string(&[AuraDevRog2::SleepBar]);
|
||||
let shut_bar__ = to_binary_string(&[AuraDevRog2::ShutdownBar]);
|
||||
let boot_lid__ = to_binary_string(&[AuraDevRog2::BootLid]);
|
||||
let awkae_lid_ = to_binary_string(&[AuraDevRog2::AwakeLid]);
|
||||
let sleep_lid_ = to_binary_string(&[AuraDevRog2::SleepLid]);
|
||||
let shut_lid__ = to_binary_string(&[AuraDevRog2::ShutdownLid]);
|
||||
let boot_rear_ = to_binary_string(&[AuraDevRog2::BootRearGlow]);
|
||||
let awake_rear = to_binary_string(&[AuraDevRog2::AwakeRearGlow]);
|
||||
let sleep_rear = to_binary_string(&[AuraDevRog2::SleepRearGlow]);
|
||||
let shut_rear_ = to_binary_string(&[AuraDevRog2::ShutdownRearGlow]);
|
||||
|
||||
assert_eq!(boot_logo_, "00000001, 00000000, 00000000, 00000000");
|
||||
assert_eq!(boot_keyb_, "00000010, 00000000, 00000000, 00000000");
|
||||
assert_eq!(awake_logo, "00000100, 00000000, 00000000, 00000000");
|
||||
assert_eq!(awake_keyb, "00001000, 00000000, 00000000, 00000000");
|
||||
assert_eq!(sleep_logo, "00010000, 00000000, 00000000, 00000000");
|
||||
assert_eq!(sleep_keyb, "00100000, 00000000, 00000000, 00000000");
|
||||
assert_eq!(shut_logo_, "01000000, 00000000, 00000000, 00000000");
|
||||
assert_eq!(shut_keyb_, "10000000, 00000000, 00000000, 00000000");
|
||||
//
|
||||
assert_eq!(boot_bar__, "00000000, 00000010, 00000000, 00000000");
|
||||
assert_eq!(awake_bar_, "00000000, 00000100, 00000000, 00000000");
|
||||
assert_eq!(sleep_bar_, "00000000, 00001000, 00000000, 00000000");
|
||||
assert_eq!(shut_bar__, "00000000, 00010000, 00000000, 00000000");
|
||||
//
|
||||
assert_eq!(boot_lid__, "00000000, 00000000, 00000001, 00000000");
|
||||
assert_eq!(awkae_lid_, "00000000, 00000000, 00000010, 00000000");
|
||||
assert_eq!(sleep_lid_, "00000000, 00000000, 00000100, 00000000");
|
||||
assert_eq!(shut_lid__, "00000000, 00000000, 00001000, 00000000");
|
||||
//
|
||||
assert_eq!(boot_rear_, "00000000, 00000000, 00000000, 00000001");
|
||||
assert_eq!(awake_rear, "00000000, 00000000, 00000000, 00000010");
|
||||
assert_eq!(sleep_rear, "00000000, 00000000, 00000000, 00000100");
|
||||
assert_eq!(shut_rear_, "00000000, 00000000, 00000000, 00001000");
|
||||
|
||||
// All on
|
||||
let byte1 = [
|
||||
AuraDevRog2::BootLogo,
|
||||
AuraDevRog2::BootKeyb,
|
||||
AuraDevRog2::SleepLogo,
|
||||
AuraDevRog2::SleepKeyb,
|
||||
AuraDevRog2::AwakeLogo,
|
||||
AuraDevRog2::AwakeKeyb,
|
||||
AuraDevRog2::ShutdownLogo,
|
||||
AuraDevRog2::ShutdownKeyb,
|
||||
AuraDevRog2::BootBar,
|
||||
AuraDevRog2::AwakeBar,
|
||||
AuraDevRog2::SleepBar,
|
||||
AuraDevRog2::ShutdownBar,
|
||||
AuraDevRog2::AwakeLid,
|
||||
AuraDevRog2::BootLid,
|
||||
AuraDevRog2::SleepLid,
|
||||
AuraDevRog2::ShutdownLid,
|
||||
AuraDevRog2::AwakeRearGlow,
|
||||
AuraDevRog2::BootRearGlow,
|
||||
AuraDevRog2::SleepRearGlow,
|
||||
AuraDevRog2::ShutdownRearGlow,
|
||||
];
|
||||
let out = to_binary_string(&byte1);
|
||||
assert_eq!(out, "11111111, 00011110, 00001111, 00001111");
|
||||
}
|
||||
}
|
||||
@@ -522,7 +522,6 @@ mod tests {
|
||||
let mut data_path = PathBuf::from(DATA_DIR);
|
||||
data_path.push("data");
|
||||
data_path.push("aura_support.ron");
|
||||
dbg!(&data_path);
|
||||
|
||||
let mut buf = std::fs::read_to_string(&data_path).unwrap();
|
||||
let data: LedSupportFile = ron::from_str(&buf).unwrap();
|
||||
|
||||
@@ -18,6 +18,10 @@ pub mod aura_detection;
|
||||
pub mod layouts;
|
||||
pub mod usb;
|
||||
|
||||
pub mod power;
|
||||
|
||||
mod deprecated;
|
||||
|
||||
pub const LED_MSG_LEN: usize = 17;
|
||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
|
||||
|
||||
@@ -0,0 +1,344 @@
|
||||
use std::fmt::Debug;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use typeshare::typeshare;
|
||||
#[cfg(feature = "dbus")]
|
||||
use zbus::zvariant::Type;
|
||||
|
||||
use crate::aura_detection::PowerZones;
|
||||
|
||||
#[typeshare]
|
||||
#[cfg_attr(feature = "dbus", derive(Type))]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct KbAuraPowerState {
|
||||
pub zone: PowerZones,
|
||||
pub boot: bool,
|
||||
pub awake: bool,
|
||||
pub sleep: bool,
|
||||
pub shutdown: bool,
|
||||
}
|
||||
|
||||
impl Default for KbAuraPowerState {
|
||||
/// Defaults all to off
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
zone: PowerZones::Keyboard,
|
||||
boot: false,
|
||||
awake: false,
|
||||
sleep: false,
|
||||
shutdown: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl KbAuraPowerState {
|
||||
pub fn to_byte(&self, zone: PowerZones) -> u32 {
|
||||
match zone {
|
||||
PowerZones::Logo => {
|
||||
self.boot as u32
|
||||
| (self.awake as u32) << 2
|
||||
| (self.sleep as u32) << 4
|
||||
| (self.shutdown as u32) << 6
|
||||
}
|
||||
PowerZones::Keyboard => {
|
||||
(self.boot as u32) << 1
|
||||
| (self.awake as u32) << 3
|
||||
| (self.sleep as u32) << 5
|
||||
| (self.shutdown as u32) << 7
|
||||
}
|
||||
PowerZones::Lightbar => {
|
||||
(self.boot as u32) << (7 + 2)
|
||||
| (self.awake as u32) << (7 + 3)
|
||||
| (self.sleep as u32) << (7 + 4)
|
||||
| (self.shutdown as u32) << (7 + 5)
|
||||
}
|
||||
PowerZones::Lid => {
|
||||
(self.boot as u32) << (15 + 1)
|
||||
| (self.awake as u32) << (15 + 2)
|
||||
| (self.sleep as u32) << (15 + 3)
|
||||
| (self.shutdown as u32) << (15 + 4)
|
||||
}
|
||||
PowerZones::RearGlow => {
|
||||
(self.boot as u32) << (23 + 1)
|
||||
| (self.awake as u32) << (23 + 2)
|
||||
| (self.sleep as u32) << (23 + 3)
|
||||
| (self.shutdown as u32) << (23 + 4)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Track and control the Aura keyboard power state
|
||||
///
|
||||
/// # Bits for newer 0x18c6, 0x19B6, 0x1a30, keyboard models
|
||||
///
|
||||
/// | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Label |
|
||||
/// |--------|---------|---------|---------|----------|
|
||||
/// |00000001| 00000000| 00000000| 00000000|boot_logo_|
|
||||
/// |00000010| 00000000| 00000000| 00000000|boot_keyb_|
|
||||
/// |00000100| 00000000| 00000000| 00000000|awake_logo|
|
||||
/// |00001000| 00000000| 00000000| 00000000|awake_keyb|
|
||||
/// |00010000| 00000000| 00000000| 00000000|sleep_logo|
|
||||
/// |00100000| 00000000| 00000000| 00000000|sleep_keyb|
|
||||
/// |01000000| 00000000| 00000000| 00000000|shut_logo_|
|
||||
/// |10000000| 00000000| 00000000| 00000000|shut_keyb_|
|
||||
/// |00000000| 00000010| 00000000| 00000000|boot_bar__|
|
||||
/// |00000000| 00000100| 00000000| 00000000|awake_bar_|
|
||||
/// |00000000| 00001000| 00000000| 00000000|sleep_bar_|
|
||||
/// |00000000| 00010000| 00000000| 00000000|shut_bar__|
|
||||
/// |00000000| 00000000| 00000001| 00000000|boot_lid__|
|
||||
/// |00000000| 00000000| 00000010| 00000000|awkae_lid_|
|
||||
/// |00000000| 00000000| 00000100| 00000000|sleep_lid_|
|
||||
/// |00000000| 00000000| 00001000| 00000000|shut_lid__|
|
||||
/// |00000000| 00000000| 00000000| 00000001|boot_rear_|
|
||||
/// |00000000| 00000000| 00000000| 00000010|awake_rear|
|
||||
/// |00000000| 00000000| 00000000| 00000100|sleep_rear|
|
||||
/// |00000000| 00000000| 00000000| 00001000|shut_rear_|
|
||||
#[typeshare]
|
||||
#[cfg_attr(feature = "dbus", derive(Type))]
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct AuraPower {
|
||||
pub keyboard: KbAuraPowerState,
|
||||
pub logo: KbAuraPowerState,
|
||||
pub lightbar: KbAuraPowerState,
|
||||
pub lid: KbAuraPowerState,
|
||||
pub rear_glow: KbAuraPowerState,
|
||||
}
|
||||
|
||||
impl AuraPower {
|
||||
pub fn new_all_on() -> Self {
|
||||
Self {
|
||||
keyboard: KbAuraPowerState {
|
||||
zone: PowerZones::Keyboard,
|
||||
boot: true,
|
||||
awake: true,
|
||||
sleep: true,
|
||||
shutdown: true,
|
||||
},
|
||||
logo: KbAuraPowerState {
|
||||
zone: PowerZones::Logo,
|
||||
boot: true,
|
||||
awake: true,
|
||||
sleep: true,
|
||||
shutdown: true,
|
||||
},
|
||||
lightbar: KbAuraPowerState {
|
||||
zone: PowerZones::Lightbar,
|
||||
boot: true,
|
||||
awake: true,
|
||||
sleep: true,
|
||||
shutdown: true,
|
||||
},
|
||||
lid: KbAuraPowerState {
|
||||
zone: PowerZones::Lid,
|
||||
boot: true,
|
||||
awake: true,
|
||||
sleep: true,
|
||||
shutdown: true,
|
||||
},
|
||||
rear_glow: KbAuraPowerState {
|
||||
zone: PowerZones::RearGlow,
|
||||
boot: true,
|
||||
awake: true,
|
||||
sleep: true,
|
||||
shutdown: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_bytes(&self) -> [u8; 4] {
|
||||
let mut a: u32 = 0;
|
||||
a |= self.keyboard.to_byte(PowerZones::Keyboard);
|
||||
a |= self.logo.to_byte(PowerZones::Logo);
|
||||
a |= self.lid.to_byte(PowerZones::Lid);
|
||||
a |= self.lightbar.to_byte(PowerZones::Lightbar);
|
||||
a |= self.rear_glow.to_byte(PowerZones::RearGlow);
|
||||
[
|
||||
(a & 0xff) as u8,
|
||||
((a & 0xff00) >> 8) as u8,
|
||||
((a & 0xff0000) >> 16) as u8,
|
||||
((a & 0xff000000) >> 24) as u8,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_0x19b6_control_bytes_binary_rep() {
|
||||
fn to_binary_string(power: &AuraPower) -> String {
|
||||
let bytes = power.to_bytes();
|
||||
format!(
|
||||
"{:08b}, {:08b}, {:08b}, {:08b}",
|
||||
bytes[0], bytes[1], bytes[2], bytes[3]
|
||||
)
|
||||
}
|
||||
|
||||
let boot_logo_ = to_binary_string(&AuraPower {
|
||||
logo: KbAuraPowerState {
|
||||
boot: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
let boot_keyb_ = to_binary_string(&AuraPower {
|
||||
keyboard: KbAuraPowerState {
|
||||
boot: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
let sleep_logo = to_binary_string(&AuraPower {
|
||||
logo: KbAuraPowerState {
|
||||
sleep: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
let sleep_keyb = to_binary_string(&AuraPower {
|
||||
keyboard: KbAuraPowerState {
|
||||
sleep: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
let awake_logo = to_binary_string(&AuraPower {
|
||||
logo: KbAuraPowerState {
|
||||
awake: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
let awake_keyb = to_binary_string(&AuraPower {
|
||||
keyboard: KbAuraPowerState {
|
||||
awake: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
let shut_logo_ = to_binary_string(&AuraPower {
|
||||
logo: KbAuraPowerState {
|
||||
shutdown: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
let shut_keyb_ = to_binary_string(&AuraPower {
|
||||
keyboard: KbAuraPowerState {
|
||||
shutdown: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
let boot_bar__ = to_binary_string(&AuraPower {
|
||||
lightbar: KbAuraPowerState {
|
||||
boot: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
let awake_bar_ = to_binary_string(&AuraPower {
|
||||
lightbar: KbAuraPowerState {
|
||||
awake: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
let sleep_bar_ = to_binary_string(&AuraPower {
|
||||
lightbar: KbAuraPowerState {
|
||||
sleep: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
let shut_bar__ = to_binary_string(&AuraPower {
|
||||
lightbar: KbAuraPowerState {
|
||||
shutdown: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
let boot_lid__ = to_binary_string(&AuraPower {
|
||||
lid: KbAuraPowerState {
|
||||
boot: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
let awkae_lid_ = to_binary_string(&AuraPower {
|
||||
lid: KbAuraPowerState {
|
||||
awake: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
let sleep_lid_ = to_binary_string(&AuraPower {
|
||||
lid: KbAuraPowerState {
|
||||
sleep: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
let shut_lid__ = to_binary_string(&AuraPower {
|
||||
lid: KbAuraPowerState {
|
||||
shutdown: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
let boot_rear_ = to_binary_string(&AuraPower {
|
||||
rear_glow: KbAuraPowerState {
|
||||
boot: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
let awake_rear = to_binary_string(&AuraPower {
|
||||
rear_glow: KbAuraPowerState {
|
||||
awake: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
let sleep_rear = to_binary_string(&AuraPower {
|
||||
rear_glow: KbAuraPowerState {
|
||||
sleep: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
let shut_rear_ = to_binary_string(&AuraPower {
|
||||
rear_glow: KbAuraPowerState {
|
||||
shutdown: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
assert_eq!(boot_logo_, "00000001, 00000000, 00000000, 00000000");
|
||||
assert_eq!(boot_keyb_, "00000010, 00000000, 00000000, 00000000");
|
||||
assert_eq!(awake_logo, "00000100, 00000000, 00000000, 00000000");
|
||||
assert_eq!(awake_keyb, "00001000, 00000000, 00000000, 00000000");
|
||||
assert_eq!(sleep_logo, "00010000, 00000000, 00000000, 00000000");
|
||||
assert_eq!(sleep_keyb, "00100000, 00000000, 00000000, 00000000");
|
||||
assert_eq!(shut_logo_, "01000000, 00000000, 00000000, 00000000");
|
||||
assert_eq!(shut_keyb_, "10000000, 00000000, 00000000, 00000000");
|
||||
//
|
||||
assert_eq!(boot_bar__, "00000000, 00000010, 00000000, 00000000");
|
||||
assert_eq!(awake_bar_, "00000000, 00000100, 00000000, 00000000");
|
||||
assert_eq!(sleep_bar_, "00000000, 00001000, 00000000, 00000000");
|
||||
assert_eq!(shut_bar__, "00000000, 00010000, 00000000, 00000000");
|
||||
//
|
||||
assert_eq!(boot_lid__, "00000000, 00000000, 00000001, 00000000");
|
||||
assert_eq!(awkae_lid_, "00000000, 00000000, 00000010, 00000000");
|
||||
assert_eq!(sleep_lid_, "00000000, 00000000, 00000100, 00000000");
|
||||
assert_eq!(shut_lid__, "00000000, 00000000, 00001000, 00000000");
|
||||
//
|
||||
assert_eq!(boot_rear_, "00000000, 00000000, 00000000, 00000001");
|
||||
assert_eq!(awake_rear, "00000000, 00000000, 00000000, 00000010");
|
||||
assert_eq!(sleep_rear, "00000000, 00000000, 00000000, 00000100");
|
||||
assert_eq!(shut_rear_, "00000000, 00000000, 00000000, 00001000");
|
||||
|
||||
// All on
|
||||
let byte1 = AuraPower::new_all_on();
|
||||
let out = to_binary_string(&byte1);
|
||||
assert_eq!(out, "11111111, 00011110, 00001111, 00001111");
|
||||
}
|
||||
+9
-177
@@ -6,6 +6,8 @@ use typeshare::typeshare;
|
||||
#[cfg(feature = "dbus")]
|
||||
use zbus::zvariant::Type;
|
||||
|
||||
use crate::power::AuraPower;
|
||||
|
||||
pub const LED_INIT1: [u8; 2] = [0x5d, 0xb9];
|
||||
pub const LED_INIT2: &str = "]ASUS Tech.Inc."; // ] == 0x5d
|
||||
pub const LED_INIT3: [u8; 6] = [0x5d, 0x05, 0x20, 0x31, 0, 0x08];
|
||||
@@ -88,9 +90,14 @@ impl Debug for AuraDevice {
|
||||
#[cfg_attr(feature = "dbus", derive(Type))]
|
||||
#[derive(Clone, Default, Debug, Serialize, Deserialize)]
|
||||
pub struct AuraPowerDev {
|
||||
/// TUF laptops use a similar style of control to the older ROG devices but
|
||||
/// through WMI
|
||||
pub tuf: Vec<AuraDevTuf>,
|
||||
pub x1866: Vec<AuraDevRog1>,
|
||||
pub x19b6: Vec<AuraDevRog2>,
|
||||
/// Pre-0x19b6 devices use a different smaller scheme to the newer ROG
|
||||
/// devices
|
||||
pub old_rog: Vec<AuraDevRog1>,
|
||||
/// ASUS standardised control scheme from 2020 onwards
|
||||
pub rog: AuraPower,
|
||||
}
|
||||
|
||||
#[typeshare]
|
||||
@@ -177,102 +184,9 @@ impl BitAnd<AuraDevRog1> for AuraDevRog1 {
|
||||
}
|
||||
}
|
||||
|
||||
/// # Bits for newer 0x18c6, 0x19B6, 0x1a30, keyboard models
|
||||
///
|
||||
/// | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Label |
|
||||
/// |--------|---------|---------|---------|----------|
|
||||
/// |00000001| 00000000| 00000000| 00000000|boot_logo_|
|
||||
/// |00000010| 00000000| 00000000| 00000000|boot_keyb_|
|
||||
/// |00000100| 00000000| 00000000| 00000000|awake_logo|
|
||||
/// |00001000| 00000000| 00000000| 00000000|awake_keyb|
|
||||
/// |00010000| 00000000| 00000000| 00000000|sleep_logo|
|
||||
/// |00100000| 00000000| 00000000| 00000000|sleep_keyb|
|
||||
/// |01000000| 00000000| 00000000| 00000000|shut_logo_|
|
||||
/// |10000000| 00000000| 00000000| 00000000|shut_keyb_|
|
||||
/// |00000000| 00000010| 00000000| 00000000|boot_bar__|
|
||||
/// |00000000| 00000100| 00000000| 00000000|awake_bar_|
|
||||
/// |00000000| 00001000| 00000000| 00000000|sleep_bar_|
|
||||
/// |00000000| 00010000| 00000000| 00000000|shut_bar__|
|
||||
/// |00000000| 00000000| 00000001| 00000000|boot_lid__|
|
||||
/// |00000000| 00000000| 00000010| 00000000|awkae_lid_|
|
||||
/// |00000000| 00000000| 00000100| 00000000|sleep_lid_|
|
||||
/// |00000000| 00000000| 00001000| 00000000|shut_lid__|
|
||||
/// |00000000| 00000000| 00000000| 00000001|boot_rear_|
|
||||
/// |00000000| 00000000| 00000000| 00000010|awake_rear|
|
||||
/// |00000000| 00000000| 00000000| 00000100|sleep_rear|
|
||||
/// |00000000| 00000000| 00000000| 00001000|shut_rear_|
|
||||
#[typeshare]
|
||||
#[cfg_attr(feature = "dbus", derive(Type), zvariant(signature = "s"))]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum AuraDevRog2 {
|
||||
BootLogo = 1,
|
||||
BootKeyb = 1 << 1,
|
||||
AwakeLogo = 1 << 2,
|
||||
AwakeKeyb = 1 << 3,
|
||||
SleepLogo = 1 << 4,
|
||||
SleepKeyb = 1 << 5,
|
||||
ShutdownLogo = 1 << 6,
|
||||
ShutdownKeyb = 1 << 7,
|
||||
BootBar = 1 << (7 + 2),
|
||||
AwakeBar = 1 << (7 + 3),
|
||||
SleepBar = 1 << (7 + 4),
|
||||
ShutdownBar = 1 << (7 + 5),
|
||||
BootLid = 1 << (15 + 1),
|
||||
AwakeLid = 1 << (15 + 2),
|
||||
SleepLid = 1 << (15 + 3),
|
||||
ShutdownLid = 1 << (15 + 4),
|
||||
BootRearGlow = 1 << (23 + 1),
|
||||
AwakeRearGlow = 1 << (23 + 2),
|
||||
SleepRearGlow = 1 << (23 + 3),
|
||||
ShutdownRearGlow = 1 << (23 + 4),
|
||||
}
|
||||
|
||||
impl From<AuraDevRog2> for u32 {
|
||||
fn from(a: AuraDevRog2) -> Self {
|
||||
a as u32
|
||||
}
|
||||
}
|
||||
|
||||
impl AuraDevRog2 {
|
||||
pub fn to_bytes(control: &[Self]) -> [u8; 4] {
|
||||
let mut a: u32 = 0;
|
||||
for n in control {
|
||||
a |= *n as u32;
|
||||
}
|
||||
[
|
||||
(a & 0xff) as u8,
|
||||
((a & 0xff00) >> 8) as u8,
|
||||
((a & 0xff0000) >> 16) as u8,
|
||||
((a & 0xff000000) >> 24) as u8,
|
||||
]
|
||||
}
|
||||
|
||||
pub const fn dev_id() -> &'static str {
|
||||
"0x196b"
|
||||
}
|
||||
}
|
||||
|
||||
impl BitOr<AuraDevRog2> for AuraDevRog2 {
|
||||
type Output = u16;
|
||||
|
||||
fn bitor(self, rhs: AuraDevRog2) -> Self::Output {
|
||||
self as u16 | rhs as u16
|
||||
}
|
||||
}
|
||||
|
||||
impl BitAnd<AuraDevRog2> for AuraDevRog2 {
|
||||
type Output = u16;
|
||||
|
||||
fn bitand(self, rhs: AuraDevRog2) -> Self::Output {
|
||||
self as u16 & rhs as u16
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::AuraDevRog1;
|
||||
use crate::usb::AuraDevRog2;
|
||||
|
||||
#[test]
|
||||
fn check_0x1866_control_bytes() {
|
||||
@@ -308,86 +222,4 @@ mod tests {
|
||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||
assert_eq!(bytes, [0xff, 0x1f, 0x000f, 0x00]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_0x19b6_control_bytes_binary_rep() {
|
||||
fn to_binary_string(bytes: &[AuraDevRog2]) -> String {
|
||||
let bytes = AuraDevRog2::to_bytes(bytes);
|
||||
format!(
|
||||
"{:08b}, {:08b}, {:08b}, {:08b}",
|
||||
bytes[0], bytes[1], bytes[2], bytes[3]
|
||||
)
|
||||
}
|
||||
|
||||
let boot_logo_ = to_binary_string(&[AuraDevRog2::BootLogo]);
|
||||
let boot_keyb_ = to_binary_string(&[AuraDevRog2::BootKeyb]);
|
||||
let sleep_logo = to_binary_string(&[AuraDevRog2::SleepLogo]);
|
||||
let sleep_keyb = to_binary_string(&[AuraDevRog2::SleepKeyb]);
|
||||
let awake_logo = to_binary_string(&[AuraDevRog2::AwakeLogo]);
|
||||
let awake_keyb = to_binary_string(&[AuraDevRog2::AwakeKeyb]);
|
||||
let shut_logo_ = to_binary_string(&[AuraDevRog2::ShutdownLogo]);
|
||||
let shut_keyb_ = to_binary_string(&[AuraDevRog2::ShutdownKeyb]);
|
||||
let boot_bar__ = to_binary_string(&[AuraDevRog2::BootBar]);
|
||||
let awake_bar_ = to_binary_string(&[AuraDevRog2::AwakeBar]);
|
||||
let sleep_bar_ = to_binary_string(&[AuraDevRog2::SleepBar]);
|
||||
let shut_bar__ = to_binary_string(&[AuraDevRog2::ShutdownBar]);
|
||||
let boot_lid__ = to_binary_string(&[AuraDevRog2::BootLid]);
|
||||
let awkae_lid_ = to_binary_string(&[AuraDevRog2::AwakeLid]);
|
||||
let sleep_lid_ = to_binary_string(&[AuraDevRog2::SleepLid]);
|
||||
let shut_lid__ = to_binary_string(&[AuraDevRog2::ShutdownLid]);
|
||||
let boot_rear_ = to_binary_string(&[AuraDevRog2::BootRearGlow]);
|
||||
let awake_rear = to_binary_string(&[AuraDevRog2::AwakeRearGlow]);
|
||||
let sleep_rear = to_binary_string(&[AuraDevRog2::SleepRearGlow]);
|
||||
let shut_rear_ = to_binary_string(&[AuraDevRog2::ShutdownRearGlow]);
|
||||
|
||||
assert_eq!(boot_logo_, "00000001, 00000000, 00000000, 00000000");
|
||||
assert_eq!(boot_keyb_, "00000010, 00000000, 00000000, 00000000");
|
||||
assert_eq!(awake_logo, "00000100, 00000000, 00000000, 00000000");
|
||||
assert_eq!(awake_keyb, "00001000, 00000000, 00000000, 00000000");
|
||||
assert_eq!(sleep_logo, "00010000, 00000000, 00000000, 00000000");
|
||||
assert_eq!(sleep_keyb, "00100000, 00000000, 00000000, 00000000");
|
||||
assert_eq!(shut_logo_, "01000000, 00000000, 00000000, 00000000");
|
||||
assert_eq!(shut_keyb_, "10000000, 00000000, 00000000, 00000000");
|
||||
//
|
||||
assert_eq!(boot_bar__, "00000000, 00000010, 00000000, 00000000");
|
||||
assert_eq!(awake_bar_, "00000000, 00000100, 00000000, 00000000");
|
||||
assert_eq!(sleep_bar_, "00000000, 00001000, 00000000, 00000000");
|
||||
assert_eq!(shut_bar__, "00000000, 00010000, 00000000, 00000000");
|
||||
//
|
||||
assert_eq!(boot_lid__, "00000000, 00000000, 00000001, 00000000");
|
||||
assert_eq!(awkae_lid_, "00000000, 00000000, 00000010, 00000000");
|
||||
assert_eq!(sleep_lid_, "00000000, 00000000, 00000100, 00000000");
|
||||
assert_eq!(shut_lid__, "00000000, 00000000, 00001000, 00000000");
|
||||
//
|
||||
assert_eq!(boot_rear_, "00000000, 00000000, 00000000, 00000001");
|
||||
assert_eq!(awake_rear, "00000000, 00000000, 00000000, 00000010");
|
||||
assert_eq!(sleep_rear, "00000000, 00000000, 00000000, 00000100");
|
||||
assert_eq!(shut_rear_, "00000000, 00000000, 00000000, 00001000");
|
||||
|
||||
// All on
|
||||
let byte1 = [
|
||||
AuraDevRog2::BootLogo,
|
||||
AuraDevRog2::BootKeyb,
|
||||
AuraDevRog2::SleepLogo,
|
||||
AuraDevRog2::SleepKeyb,
|
||||
AuraDevRog2::AwakeLogo,
|
||||
AuraDevRog2::AwakeKeyb,
|
||||
AuraDevRog2::ShutdownLogo,
|
||||
AuraDevRog2::ShutdownKeyb,
|
||||
AuraDevRog2::BootBar,
|
||||
AuraDevRog2::AwakeBar,
|
||||
AuraDevRog2::SleepBar,
|
||||
AuraDevRog2::ShutdownBar,
|
||||
AuraDevRog2::AwakeLid,
|
||||
AuraDevRog2::BootLid,
|
||||
AuraDevRog2::SleepLid,
|
||||
AuraDevRog2::ShutdownLid,
|
||||
AuraDevRog2::AwakeRearGlow,
|
||||
AuraDevRog2::BootRearGlow,
|
||||
AuraDevRog2::SleepRearGlow,
|
||||
AuraDevRog2::ShutdownRearGlow,
|
||||
];
|
||||
let out = to_binary_string(&byte1);
|
||||
assert_eq!(out, "11111111, 00011110, 00001111, 00001111");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ fn main() -> Result<()> {
|
||||
layouts = KeyLayout::layout_files(path.clone()).unwrap();
|
||||
|
||||
if let Some(name) = &cli_parsed.board_name {
|
||||
if let Some(modes) = LedSupportFile::load_from_config() {
|
||||
if let Some(modes) = LedSupportFile::load_from_supoprt_db() {
|
||||
if let Some(data) = modes.matcher(name) {
|
||||
led_support = data;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use egui::Ui;
|
||||
use egui::{RichText, Ui};
|
||||
use rog_platform::supported::SupportedFunctions;
|
||||
use rog_profiles::Profile;
|
||||
|
||||
use crate::system_state::{FanCurvesState, ProfilesState, SystemState};
|
||||
use crate::widgets::fan_graphs;
|
||||
@@ -12,10 +11,6 @@ impl RogApp {
|
||||
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
ui.heading("Custom fan curves");
|
||||
ui.label(
|
||||
"A fan curve is only active when the related profile is active and the curve is \
|
||||
enabled",
|
||||
);
|
||||
Self::fan_curve(
|
||||
supported,
|
||||
&mut states.profiles,
|
||||
@@ -44,35 +39,68 @@ impl RogApp {
|
||||
ui: &mut Ui,
|
||||
) {
|
||||
ui.separator();
|
||||
ui.label("Enabled fan-curves");
|
||||
|
||||
let mut changed = false;
|
||||
ui.horizontal(|ui| {
|
||||
let mut item = |p: Profile, curves: &mut FanCurvesState, mut checked: bool| {
|
||||
if ui
|
||||
.add(egui::Checkbox::new(&mut checked, format!("{:?}", p)))
|
||||
.changed()
|
||||
{
|
||||
dbus.proxies()
|
||||
.profile()
|
||||
.set_fan_curve_enabled(p, checked)
|
||||
.map_err(|err| {
|
||||
*do_error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
ui.label("Current profile: ");
|
||||
ui.label(RichText::new(format!("{}", profiles.current)).strong());
|
||||
});
|
||||
|
||||
if !checked {
|
||||
curves.enabled.remove(&p);
|
||||
} else {
|
||||
curves.enabled.insert(p);
|
||||
// ui.horizontal(|ui| {
|
||||
// ui.label("Enabled fan-curves: ");
|
||||
// let mut fan_curve_enable = |profile: Profile, fan: FanCurvePU, mut
|
||||
// checked: bool| { if ui
|
||||
// .add(egui::Checkbox::new(&mut checked, format!("{:?}", fan)))
|
||||
// .changed()
|
||||
// {
|
||||
// dbus.proxies()
|
||||
// .profile()
|
||||
// .set_fan_curves_enabled(profile, checked)
|
||||
// .map_err(|err| {
|
||||
// *do_error = Some(err.to_string());
|
||||
// })
|
||||
// .ok();
|
||||
// changed = true;
|
||||
// }
|
||||
// };
|
||||
|
||||
// if let Some(curves) = curves.curves.get_mut(&profiles.current) {
|
||||
// for curve in curves.iter_mut() {
|
||||
// fan_curve_enable(profiles.current, curve.fan, curve.enabled);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("Enabled fan-curves: ");
|
||||
let mut checked = false;
|
||||
let mut label = String::default();
|
||||
if let Some(curves) = curves.curves.get_mut(&profiles.current) {
|
||||
for curve in curves.iter() {
|
||||
label.push_str(&<&str>::from(curve.fan).to_ascii_uppercase());
|
||||
label.push(' ');
|
||||
if curve.enabled {
|
||||
// TODO: it's possible to set just one fan to active
|
||||
checked = true;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
profiles.list.sort();
|
||||
for f in &profiles.list {
|
||||
item(*f, curves, curves.enabled.contains(f));
|
||||
if ui
|
||||
.add(egui::Checkbox::new(
|
||||
&mut checked,
|
||||
RichText::new(label).strong(),
|
||||
))
|
||||
.changed()
|
||||
{
|
||||
dbus.proxies()
|
||||
.profile()
|
||||
.set_fan_curves_enabled(profiles.current, checked)
|
||||
.map_err(|err| {
|
||||
*do_error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
changed = true;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ use rog_aura::usb::AuraPowerDev;
|
||||
use rog_aura::{AuraEffect, AuraModeNum};
|
||||
use rog_platform::platform::GpuMode;
|
||||
use rog_platform::supported::SupportedFunctions;
|
||||
use rog_profiles::fan_curve_set::FanCurveSet;
|
||||
use rog_profiles::fan_curve_set::CurveData;
|
||||
use rog_profiles::{FanCurvePU, Profile};
|
||||
use supergfxctl::pci_device::{GfxMode, GfxPower};
|
||||
#[cfg(not(feature = "mocking"))]
|
||||
@@ -96,8 +96,8 @@ impl ProfilesState {
|
||||
pub struct FanCurvesState {
|
||||
pub show_curve: Profile,
|
||||
pub show_graph: FanCurvePU,
|
||||
pub enabled: HashSet<Profile>,
|
||||
pub curves: BTreeMap<Profile, FanCurveSet>,
|
||||
pub curves: BTreeMap<Profile, Vec<CurveData>>,
|
||||
pub available_fans: HashSet<FanCurvePU>,
|
||||
pub drag_delta: Vec2,
|
||||
}
|
||||
|
||||
@@ -108,34 +108,24 @@ impl FanCurvesState {
|
||||
} else {
|
||||
vec![Profile::Balanced, Profile::Quiet, Profile::Performance]
|
||||
};
|
||||
let enabled = if supported.platform_profile.fan_curves {
|
||||
dbus.proxies()
|
||||
.profile()
|
||||
.enabled_fan_profiles()?
|
||||
.iter()
|
||||
.cloned()
|
||||
.collect::<HashSet<_>>()
|
||||
} else {
|
||||
HashSet::from([Profile::Balanced, Profile::Quiet, Profile::Performance])
|
||||
};
|
||||
|
||||
let mut curves: BTreeMap<Profile, FanCurveSet> = BTreeMap::new();
|
||||
let mut curves: BTreeMap<Profile, Vec<CurveData>> = BTreeMap::new();
|
||||
for p in &profiles {
|
||||
if supported.platform_profile.fan_curves {
|
||||
if !supported.platform_profile.fans.is_empty() {
|
||||
if let Ok(curve) = dbus.proxies().profile().fan_curve_data(*p) {
|
||||
curves.insert(*p, curve);
|
||||
}
|
||||
} else {
|
||||
let mut curve = FanCurveSet::default();
|
||||
curve.cpu.pwm = [30, 40, 60, 100, 140, 180, 200, 250];
|
||||
curve.cpu.temp = [20, 30, 40, 50, 70, 80, 90, 100];
|
||||
curve.gpu.pwm = [40, 80, 100, 140, 170, 200, 230, 250];
|
||||
curve.gpu.temp = [20, 30, 40, 50, 70, 80, 90, 100];
|
||||
curves.insert(*p, curve);
|
||||
curves.insert(*p, Vec::default());
|
||||
}
|
||||
}
|
||||
|
||||
let show_curve = if supported.platform_profile.fan_curves {
|
||||
let mut available_fans = HashSet::new();
|
||||
for fan in supported.platform_profile.fans.iter() {
|
||||
available_fans.insert(*fan);
|
||||
}
|
||||
|
||||
let show_curve = if !supported.platform_profile.fans.is_empty() {
|
||||
dbus.proxies().profile().active_profile()?
|
||||
} else {
|
||||
Profile::Balanced
|
||||
@@ -144,8 +134,8 @@ impl FanCurvesState {
|
||||
Ok(Self {
|
||||
show_curve,
|
||||
show_graph: FanCurvePU::CPU,
|
||||
enabled,
|
||||
curves,
|
||||
available_fans,
|
||||
drag_delta: Vec2::default(),
|
||||
})
|
||||
}
|
||||
@@ -177,7 +167,7 @@ impl AuraState {
|
||||
} else {
|
||||
BTreeMap::new()
|
||||
},
|
||||
enabled: dbus.proxies().led().led_powered().unwrap_or_default(),
|
||||
enabled: dbus.proxies().led().led_power().unwrap_or_default(),
|
||||
bright: dbus.proxies().led().led_brightness().unwrap_or_default(),
|
||||
wave_red: [0u8; 22],
|
||||
wave_green: [0u8; 22],
|
||||
@@ -427,11 +417,7 @@ impl Default for SystemState {
|
||||
aura: AuraState {
|
||||
current_mode: AuraModeNum::Static,
|
||||
modes: Default::default(),
|
||||
enabled: AuraPowerDev {
|
||||
tuf: vec![],
|
||||
x1866: vec![],
|
||||
x19b6: vec![],
|
||||
},
|
||||
enabled: AuraPowerDev::default(),
|
||||
..Default::default()
|
||||
},
|
||||
anime: AnimeState::default(),
|
||||
|
||||
@@ -274,19 +274,48 @@ pub fn start_notifications(
|
||||
let conn = zbus::Connection::system()
|
||||
.await
|
||||
.map_err(|e| {
|
||||
error!("zbus signal: receive_power_states: {e}");
|
||||
error!("zbus signal: receive_device_state: {e}");
|
||||
e
|
||||
})
|
||||
.unwrap();
|
||||
let proxy = LedProxy::new(&conn)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
error!("zbus signal: receive_device_state: {e}");
|
||||
e
|
||||
})
|
||||
.unwrap();
|
||||
if let Ok(mut p) = proxy.receive_notify_power_states().await {
|
||||
info!("Started zbus signal thread: receive_notify_power_states");
|
||||
while let Some(e) = p.next().await {
|
||||
if let Ok(out) = e.args() {
|
||||
if let Ok(mut lock) = page_states1.lock() {
|
||||
lock.aura.enabled = out.data;
|
||||
lock.set_notified();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
let page_states1 = page_states.clone();
|
||||
tokio::spawn(async move {
|
||||
let conn = zbus::Connection::system()
|
||||
.await
|
||||
.map_err(|e| {
|
||||
error!("zbus signal: receive_device_state: {e}");
|
||||
e
|
||||
})
|
||||
.unwrap();
|
||||
let proxy = AnimeProxy::new(&conn)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
error!("zbus signal: receive_power_states: {e}");
|
||||
error!("zbus signal: receive_device_state: {e}");
|
||||
e
|
||||
})
|
||||
.unwrap();
|
||||
if let Ok(p) = proxy.receive_device_state().await {
|
||||
info!("Started zbus signal thread: receive_power_states");
|
||||
info!("Started zbus signal thread: receive_device_state");
|
||||
p.for_each(|_| {
|
||||
if let Ok(_lock) = page_states1.lock() {
|
||||
// TODO: lock.anime.
|
||||
@@ -320,7 +349,7 @@ pub fn start_notifications(
|
||||
}
|
||||
|
||||
if let Ok(mut p) = proxy.receive_notify_gpu_mux_mode().await {
|
||||
info!("Started zbus signal thread: receive_power_states");
|
||||
info!("Started zbus signal thread: receive_notify_gpu_mux_mode");
|
||||
while let Some(e) = p.next().await {
|
||||
if let Ok(out) = e.args() {
|
||||
if out.mode == actual_mux_mode {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use egui::{RichText, Ui};
|
||||
use rog_aura::usb::{AuraDevRog1, AuraDevRog2, AuraDevTuf, AuraDevice, AuraPowerDev};
|
||||
use rog_aura::AuraZone;
|
||||
use rog_aura::power::{AuraPower, KbAuraPowerState};
|
||||
use rog_aura::usb::{AuraDevRog1, AuraDevTuf, AuraDevice, AuraPowerDev};
|
||||
use rog_platform::supported::SupportedFunctions;
|
||||
|
||||
use crate::system_state::SystemState;
|
||||
|
||||
pub fn aura_power_group(supported: &SupportedFunctions, states: &mut SystemState, ui: &mut Ui) {
|
||||
ui.heading("LED settings");
|
||||
ui.heading("Keyboard LED power settings");
|
||||
|
||||
match supported.keyboard_led.dev_id {
|
||||
AuraDevice::X1854 | AuraDevice::X1869 | AuraDevice::X1866 => {
|
||||
@@ -22,10 +22,10 @@ pub fn aura_power_group(supported: &SupportedFunctions, states: &mut SystemState
|
||||
|
||||
fn aura_power1(supported: &SupportedFunctions, states: &mut SystemState, ui: &mut Ui) {
|
||||
let enabled_states = &mut states.aura.enabled;
|
||||
let mut boot = enabled_states.x1866.contains(&AuraDevRog1::Boot);
|
||||
let mut sleep = enabled_states.x1866.contains(&AuraDevRog1::Sleep);
|
||||
let mut keyboard = enabled_states.x1866.contains(&AuraDevRog1::Keyboard);
|
||||
let mut lightbar = enabled_states.x1866.contains(&AuraDevRog1::Lightbar);
|
||||
let mut boot = enabled_states.old_rog.contains(&AuraDevRog1::Boot);
|
||||
let mut sleep = enabled_states.old_rog.contains(&AuraDevRog1::Sleep);
|
||||
let mut keyboard = enabled_states.old_rog.contains(&AuraDevRog1::Keyboard);
|
||||
let mut lightbar = enabled_states.old_rog.contains(&AuraDevRog1::Lightbar);
|
||||
if supported.keyboard_led.dev_id == AuraDevice::Tuf {
|
||||
boot = enabled_states.tuf.contains(&AuraDevTuf::Boot);
|
||||
sleep = enabled_states.tuf.contains(&AuraDevTuf::Sleep);
|
||||
@@ -130,8 +130,7 @@ fn aura_power1(supported: &SupportedFunctions, states: &mut SystemState, ui: &mu
|
||||
let mut send = |enable: bool, data: Vec<AuraDevTuf>| {
|
||||
let options = AuraPowerDev {
|
||||
tuf: data,
|
||||
x1866: vec![],
|
||||
x19b6: vec![],
|
||||
..Default::default()
|
||||
};
|
||||
// build data to send
|
||||
states
|
||||
@@ -153,21 +152,21 @@ fn aura_power1(supported: &SupportedFunctions, states: &mut SystemState, ui: &mu
|
||||
let mut modify_x1866 = |b: bool, a: AuraDevRog1| {
|
||||
if b {
|
||||
enabled.push(a);
|
||||
if !enabled_states.x1866.contains(&a) {
|
||||
enabled_states.x1866.push(a);
|
||||
if !enabled_states.old_rog.contains(&a) {
|
||||
enabled_states.old_rog.push(a);
|
||||
}
|
||||
} else {
|
||||
disabled.push(a);
|
||||
// This would be so much better as a hashset
|
||||
if enabled_states.x1866.contains(&a) {
|
||||
if enabled_states.old_rog.contains(&a) {
|
||||
let mut idx = 0;
|
||||
for (i, n) in enabled_states.x1866.iter().enumerate() {
|
||||
for (i, n) in enabled_states.old_rog.iter().enumerate() {
|
||||
if *n == a {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enabled_states.x1866.remove(idx);
|
||||
enabled_states.old_rog.remove(idx);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -180,9 +179,8 @@ fn aura_power1(supported: &SupportedFunctions, states: &mut SystemState, ui: &mu
|
||||
|
||||
let mut send = |enable: bool, data: Vec<AuraDevRog1>| {
|
||||
let options = AuraPowerDev {
|
||||
tuf: vec![],
|
||||
x1866: data,
|
||||
x19b6: vec![],
|
||||
old_rog: data,
|
||||
..Default::default()
|
||||
};
|
||||
// build data to send
|
||||
states
|
||||
@@ -202,115 +200,52 @@ fn aura_power1(supported: &SupportedFunctions, states: &mut SystemState, ui: &mu
|
||||
}
|
||||
|
||||
fn aura_power2(supported: &SupportedFunctions, states: &mut SystemState, ui: &mut Ui) {
|
||||
let enabled_states = &mut states.aura.enabled;
|
||||
let has_logo = supported.keyboard_led.basic_zones.contains(&AuraZone::Logo);
|
||||
let has_lightbar = supported
|
||||
.keyboard_led
|
||||
.basic_zones
|
||||
.contains(&AuraZone::BarLeft)
|
||||
|| supported
|
||||
.keyboard_led
|
||||
.basic_zones
|
||||
.contains(&AuraZone::BarRight);
|
||||
let AuraPower {
|
||||
keyboard,
|
||||
logo,
|
||||
lightbar,
|
||||
lid,
|
||||
rear_glow,
|
||||
} = &mut states.aura.enabled.rog;
|
||||
|
||||
let boot_bar = &mut enabled_states.x19b6.contains(&AuraDevRog2::AwakeBar);
|
||||
let boot_logo = &mut enabled_states.x19b6.contains(&AuraDevRog2::BootLogo);
|
||||
let boot_keyb = &mut enabled_states.x19b6.contains(&AuraDevRog2::BootKeyb);
|
||||
|
||||
let awake_bar = &mut enabled_states.x19b6.contains(&AuraDevRog2::BootBar);
|
||||
let awake_logo = &mut enabled_states.x19b6.contains(&AuraDevRog2::AwakeLogo);
|
||||
let awake_keyb = &mut enabled_states.x19b6.contains(&AuraDevRog2::AwakeKeyb);
|
||||
|
||||
let sleep_bar = &mut enabled_states.x19b6.contains(&AuraDevRog2::SleepBar);
|
||||
let sleep_logo = &mut enabled_states.x19b6.contains(&AuraDevRog2::SleepLogo);
|
||||
let sleep_keyb = &mut enabled_states.x19b6.contains(&AuraDevRog2::SleepKeyb);
|
||||
const LABELS: [&str; 4] = ["Boot", "Awake", "Sleep", "Shutdown"];
|
||||
|
||||
let mut changed = false;
|
||||
|
||||
let mut item = |keyboard: &mut bool, logo: &mut bool, lightbar: &mut bool, ui: &mut Ui| {
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
if ui.checkbox(keyboard, "Keyboard").changed() {
|
||||
changed = true;
|
||||
}
|
||||
if has_logo && ui.checkbox(logo, "Logo").changed() {
|
||||
changed = true;
|
||||
}
|
||||
if has_lightbar && ui.checkbox(lightbar, "Lightbar").changed() {
|
||||
changed = true;
|
||||
let mut item = |power: &mut KbAuraPowerState, ui: &mut Ui| {
|
||||
ui.vertical(|ui| {
|
||||
if supported.keyboard_led.power_zones.contains(&power.zone) {
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.label(RichText::new(format!("{:?}", power.zone)).size(14.0));
|
||||
});
|
||||
if ui.checkbox(&mut power.boot, LABELS[0]).changed() {
|
||||
changed = true;
|
||||
}
|
||||
if ui.checkbox(&mut power.awake, LABELS[1]).changed() {
|
||||
changed = true;
|
||||
}
|
||||
if ui.checkbox(&mut power.sleep, LABELS[2]).changed() {
|
||||
changed = true;
|
||||
}
|
||||
if ui.checkbox(&mut power.shutdown, LABELS[3]).changed() {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.vertical(|ui| {
|
||||
let h = 16.0;
|
||||
ui.set_row_height(22.0);
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.label(RichText::new("Boot").size(h));
|
||||
});
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.label(RichText::new("Awake").size(h));
|
||||
});
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.label(RichText::new("Sleep").size(h));
|
||||
});
|
||||
});
|
||||
ui.vertical(|ui| {
|
||||
ui.set_row_height(22.0);
|
||||
item(boot_keyb, boot_logo, boot_bar, ui);
|
||||
item(awake_keyb, awake_logo, awake_bar, ui);
|
||||
item(sleep_keyb, sleep_logo, sleep_bar, ui);
|
||||
});
|
||||
item(lid, ui);
|
||||
item(logo, ui);
|
||||
item(keyboard, ui);
|
||||
item(lightbar, ui);
|
||||
item(rear_glow, ui);
|
||||
});
|
||||
|
||||
if changed {
|
||||
let mut enabled = Vec::new();
|
||||
let mut disabled = Vec::new();
|
||||
|
||||
let mut modify = |b: bool, a: AuraDevRog2| {
|
||||
if b {
|
||||
enabled.push(a);
|
||||
if !enabled_states.x19b6.contains(&a) {
|
||||
enabled_states.x19b6.push(a);
|
||||
}
|
||||
} else {
|
||||
disabled.push(a);
|
||||
// This would be so much better as a hashset
|
||||
if enabled_states.x19b6.contains(&a) {
|
||||
let mut idx = 0;
|
||||
for (i, n) in enabled_states.x19b6.iter().enumerate() {
|
||||
if *n == a {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enabled_states.x19b6.remove(idx);
|
||||
}
|
||||
}
|
||||
};
|
||||
modify(*boot_keyb, AuraDevRog2::BootKeyb);
|
||||
modify(*sleep_keyb, AuraDevRog2::SleepKeyb);
|
||||
modify(*awake_keyb, AuraDevRog2::AwakeKeyb);
|
||||
if supported.keyboard_led.basic_zones.contains(&AuraZone::Logo) {
|
||||
modify(*boot_logo, AuraDevRog2::BootLogo);
|
||||
modify(*sleep_logo, AuraDevRog2::SleepLogo);
|
||||
modify(*awake_logo, AuraDevRog2::AwakeLogo);
|
||||
}
|
||||
if supported
|
||||
.keyboard_led
|
||||
.basic_zones
|
||||
.contains(&AuraZone::BarLeft)
|
||||
{
|
||||
modify(*boot_bar, AuraDevRog2::AwakeBar);
|
||||
modify(*sleep_bar, AuraDevRog2::SleepBar);
|
||||
modify(*awake_bar, AuraDevRog2::BootBar);
|
||||
}
|
||||
|
||||
let mut send = |enable: bool, data: Vec<AuraDevRog2>| {
|
||||
let mut send = |enable: bool, data: AuraPower| {
|
||||
let options = AuraPowerDev {
|
||||
tuf: vec![],
|
||||
x1866: vec![],
|
||||
x19b6: data,
|
||||
rog: data,
|
||||
..Default::default()
|
||||
};
|
||||
// build data to send
|
||||
states
|
||||
@@ -323,7 +258,15 @@ fn aura_power2(supported: &SupportedFunctions, states: &mut SystemState, ui: &mu
|
||||
})
|
||||
.ok();
|
||||
};
|
||||
send(true, enabled);
|
||||
send(false, disabled);
|
||||
send(
|
||||
true,
|
||||
AuraPower {
|
||||
keyboard: *keyboard,
|
||||
logo: *logo,
|
||||
lightbar: *lightbar,
|
||||
lid: *lid,
|
||||
rear_glow: *rear_glow,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use egui::plot::Points;
|
||||
use egui::Ui;
|
||||
use rog_platform::supported::SupportedFunctions;
|
||||
use rog_profiles::fan_curve_set::CurveData;
|
||||
use rog_profiles::{FanCurvePU, Profile};
|
||||
|
||||
use crate::system_state::FanCurvesState;
|
||||
@@ -15,20 +16,36 @@ pub fn fan_graphs(
|
||||
) {
|
||||
ui.separator();
|
||||
|
||||
let mut item = |p: Profile, ui: &mut Ui| {
|
||||
let mut item = |profile: Profile, ui: &mut Ui| {
|
||||
ui.group(|ui| {
|
||||
ui.selectable_value(&mut curves.show_curve, p, format!("{p:?}"));
|
||||
ui.add_enabled_ui(curves.show_curve == p, |ui| {
|
||||
ui.selectable_value(
|
||||
&mut curves.show_graph,
|
||||
FanCurvePU::CPU,
|
||||
format!("{:?}", FanCurvePU::CPU),
|
||||
);
|
||||
ui.selectable_value(
|
||||
&mut curves.show_graph,
|
||||
FanCurvePU::GPU,
|
||||
format!("{:?}", FanCurvePU::GPU),
|
||||
);
|
||||
if ui
|
||||
.selectable_value(&mut curves.show_curve, profile, format!("{profile:?}"))
|
||||
.clicked()
|
||||
{
|
||||
dbus.proxies().profile().set_active_profile(profile).ok();
|
||||
}
|
||||
ui.add_enabled_ui(curves.show_curve == profile, |ui| {
|
||||
if curves.available_fans.contains(&FanCurvePU::CPU) {
|
||||
ui.selectable_value(
|
||||
&mut curves.show_graph,
|
||||
FanCurvePU::CPU,
|
||||
format!("{:?}", FanCurvePU::CPU),
|
||||
);
|
||||
}
|
||||
if curves.available_fans.contains(&FanCurvePU::GPU) {
|
||||
ui.selectable_value(
|
||||
&mut curves.show_graph,
|
||||
FanCurvePU::GPU,
|
||||
format!("{:?}", FanCurvePU::GPU),
|
||||
);
|
||||
}
|
||||
if curves.available_fans.contains(&FanCurvePU::MID) {
|
||||
ui.selectable_value(
|
||||
&mut curves.show_graph,
|
||||
FanCurvePU::MID,
|
||||
format!("{:?}", FanCurvePU::MID),
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -43,11 +60,13 @@ pub fn fan_graphs(
|
||||
|
||||
use egui::plot::{Line, Plot};
|
||||
|
||||
let data = if curves.show_graph == FanCurvePU::CPU {
|
||||
&mut curve.cpu
|
||||
} else {
|
||||
&mut curve.gpu
|
||||
};
|
||||
let mut data = &mut CurveData::default();
|
||||
for c in curve {
|
||||
if c.fan == curves.show_graph {
|
||||
data = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let mut points: Vec<[f64; 2]> = data
|
||||
.temp
|
||||
|
||||
@@ -18,7 +18,7 @@ impl RogApp {
|
||||
*page = Page::System;
|
||||
}
|
||||
|
||||
if self.supported.platform_profile.fan_curves {
|
||||
if !self.supported.platform_profile.fans.is_empty() {
|
||||
ui.separator();
|
||||
if ui
|
||||
.selectable_value(page, Page::FanCurves, "Fan Curves")
|
||||
|
||||
@@ -79,7 +79,7 @@ trait Led {
|
||||
|
||||
// As property doesn't work for AuraPowerDev (complexity of serialization?)
|
||||
// #[dbus_proxy(property)]
|
||||
fn led_powered(&self) -> zbus::Result<AuraPowerDev>;
|
||||
fn led_power(&self) -> zbus::Result<AuraPowerDev>;
|
||||
}
|
||||
|
||||
pub struct LedProxyPerkey<'a>(LedProxyBlocking<'a>);
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
//!
|
||||
//! …consequently `zbus-xmlgen` did not generate code for the above interfaces.
|
||||
|
||||
use rog_profiles::fan_curve_set::{CurveData, FanCurveSet};
|
||||
use rog_profiles::Profile;
|
||||
use rog_profiles::fan_curve_set::CurveData;
|
||||
use rog_profiles::{FanCurvePU, Profile};
|
||||
use zbus::dbus_proxy;
|
||||
|
||||
#[dbus_proxy(
|
||||
@@ -30,14 +30,11 @@ use zbus::dbus_proxy;
|
||||
)]
|
||||
trait Profile {
|
||||
/// Get the fan-curve data for the currently active Profile
|
||||
fn fan_curve_data(&self, profile: Profile) -> zbus::Result<FanCurveSet>;
|
||||
fn fan_curve_data(&self, profile: Profile) -> zbus::Result<Vec<CurveData>>;
|
||||
|
||||
/// Fetch the active profile name
|
||||
fn active_profile(&self) -> zbus::Result<Profile>;
|
||||
|
||||
/// Get a list of profiles that have fan-curves enabled.
|
||||
fn enabled_fan_profiles(&self) -> zbus::Result<Vec<Profile>>;
|
||||
|
||||
/// Toggle to next platform_profile. Names provided by `Profiles`.
|
||||
/// If fan-curves are supported will also activate a fan curve for profile.
|
||||
fn next_profile(&self) -> zbus::Result<()>;
|
||||
@@ -49,7 +46,16 @@ trait Profile {
|
||||
fn set_active_profile(&self, profile: Profile) -> zbus::Result<()>;
|
||||
|
||||
/// Set a profile fan curve enabled status. Will also activate a fan curve.
|
||||
fn set_fan_curve_enabled(&self, profile: Profile, enabled: bool) -> zbus::Result<()>;
|
||||
fn set_fan_curves_enabled(&self, profile: Profile, enabled: bool) -> zbus::Result<()>;
|
||||
|
||||
/// Set a single fan curve for a profile to enabled status. Will also
|
||||
/// activate a fan curve.
|
||||
async fn set_profile_fan_curve_enabled(
|
||||
&self,
|
||||
profile: Profile,
|
||||
fan: FanCurvePU,
|
||||
enabled: bool,
|
||||
) -> zbus::Result<()>;
|
||||
|
||||
/// Set the fan curve for the specified profile, or the profile the user is
|
||||
/// currently in if profile == None. Will also activate the fan curve.
|
||||
|
||||
@@ -7,6 +7,7 @@ edition = "2021"
|
||||
[dependencies]
|
||||
log.workspace = true
|
||||
rog_aura = { path = "../rog-aura" }
|
||||
rog_profiles = { path = "../rog-profiles" }
|
||||
serde.workspace = true
|
||||
serde_derive.workspace = true
|
||||
zbus.workspace = true
|
||||
|
||||
@@ -3,6 +3,7 @@ use std::fmt;
|
||||
use rog_aura::aura_detection::PowerZones;
|
||||
use rog_aura::usb::AuraDevice;
|
||||
use rog_aura::{AdvancedAuraType, AuraModeNum, AuraZone};
|
||||
use rog_profiles::FanCurvePU;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use typeshare::typeshare;
|
||||
use zbus::zvariant::Type;
|
||||
@@ -31,7 +32,7 @@ pub struct ChargeSupportedFunctions {
|
||||
#[derive(Serialize, Deserialize, Type, Debug, Default, Clone)]
|
||||
pub struct PlatformProfileFunctions {
|
||||
pub platform_profile: bool,
|
||||
pub fan_curves: bool,
|
||||
pub fans: Vec<FanCurvePU>,
|
||||
}
|
||||
|
||||
#[typeshare]
|
||||
@@ -106,7 +107,7 @@ impl fmt::Display for PlatformProfileFunctions {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
writeln!(f, "Platform profiles:")?;
|
||||
writeln!(f, "\tplatform: {}", self.platform_profile)?;
|
||||
writeln!(f, "\tfan curves: {}", self.fan_curves)
|
||||
writeln!(f, "\tfan curves: {:?}", self.fans)
|
||||
}
|
||||
}
|
||||
impl fmt::Display for LedSupportedFunctions {
|
||||
|
||||
@@ -10,6 +10,7 @@ default = ["dbus"]
|
||||
dbus = ["zbus"]
|
||||
|
||||
[dependencies]
|
||||
log.workspace = true
|
||||
udev.workspace = true
|
||||
serde.workspace = true
|
||||
serde_derive.workspace = true
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use log::trace;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use typeshare::typeshare;
|
||||
use udev::Device;
|
||||
@@ -7,24 +8,27 @@ use zbus::zvariant::Type;
|
||||
use crate::error::ProfileError;
|
||||
use crate::FanCurvePU;
|
||||
|
||||
fn set_sysfs_name(string: &mut [u8], fan: char, index: usize) {
|
||||
string[3] = fan as u8;
|
||||
string[15] = char::from_digit(index as u32 + 1, 10).unwrap() as u8;
|
||||
}
|
||||
|
||||
pub(crate) fn pwm_str(fan: char, index: usize) -> String {
|
||||
let mut buf = "pwm1_auto_point1_pwm".to_owned();
|
||||
// The char 'X' is replaced via indexing
|
||||
let mut string = "pwmX_auto_pointX_pwm".to_owned();
|
||||
unsafe {
|
||||
let tmp = buf.as_bytes_mut();
|
||||
tmp[3] = fan as u8;
|
||||
tmp[15] = char::from_digit(index as u32 + 1, 10).unwrap() as u8;
|
||||
set_sysfs_name(string.as_bytes_mut(), fan, index);
|
||||
}
|
||||
buf
|
||||
string
|
||||
}
|
||||
|
||||
pub(crate) fn temp_str(fan: char, index: usize) -> String {
|
||||
let mut buf = "pwm1_auto_point1_temp".to_owned();
|
||||
// The char 'X' is replaced via indexing
|
||||
let mut string = "pwmX_auto_pointX_temp".to_owned();
|
||||
unsafe {
|
||||
let tmp = buf.as_bytes_mut();
|
||||
tmp[3] = fan as u8;
|
||||
tmp[15] = char::from_digit(index as u32 + 1, 10).unwrap() as u8;
|
||||
set_sysfs_name(string.as_bytes_mut(), fan, index);
|
||||
}
|
||||
buf
|
||||
string
|
||||
}
|
||||
|
||||
#[typeshare]
|
||||
@@ -34,13 +38,15 @@ pub struct CurveData {
|
||||
pub fan: FanCurvePU,
|
||||
pub pwm: [u8; 8],
|
||||
pub temp: [u8; 8],
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
impl From<&CurveData> for String {
|
||||
fn from(c: &CurveData) -> Self {
|
||||
format!(
|
||||
"{:?}: {}c:{}%,{}c:{}%,{}c:{}%,{}c:{}%,{}c:{}%,{}c:{}%,{}c:{}%,{}c:{}%",
|
||||
"{:?}: enabled: {}, {}c:{}%,{}c:{}%,{}c:{}%,{}c:{}%,{}c:{}%,{}c:{}%,{}c:{}%,{}c:{}%",
|
||||
c.fan,
|
||||
c.enabled,
|
||||
c.temp[0],
|
||||
(c.pwm[0] as u32) * 100 / 255,
|
||||
c.temp[1],
|
||||
@@ -65,7 +71,7 @@ impl std::str::FromStr for CurveData {
|
||||
type Err = ProfileError;
|
||||
|
||||
/// Parse a string to the correct values that the fan curve kernel driver
|
||||
/// expects
|
||||
/// expects. The returned `CurveData` is not enabled by default.
|
||||
///
|
||||
/// If the fan curve is given with percentage char '%' then the fan power
|
||||
/// values are converted otherwise the expected fan power range is
|
||||
@@ -126,6 +132,7 @@ impl std::str::FromStr for CurveData {
|
||||
fan: FanCurvePU::CPU,
|
||||
pwm,
|
||||
temp,
|
||||
enabled: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -144,114 +151,39 @@ impl CurveData {
|
||||
}
|
||||
}
|
||||
|
||||
fn read_from_device(&mut self, device: &Device) {
|
||||
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") {
|
||||
let pwm_num: char = self.fan.into();
|
||||
let pwm = format!("pwm{pwm_num}");
|
||||
if tmp.starts_with(&pwm) && 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") {
|
||||
if tmp.starts_with(&pwm) && 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" };
|
||||
pub fn write_to_device(&self, device: &mut Device) -> std::io::Result<()> {
|
||||
let pwm_num: char = self.fan.into();
|
||||
let enable = if self.enabled { "1" } else { "2" };
|
||||
|
||||
for (index, out) in self.pwm.iter().enumerate() {
|
||||
let pwm = pwm_str(pwm_num, index);
|
||||
trace!("writing {pwm}");
|
||||
device.set_attribute_value(&pwm, &out.to_string())?;
|
||||
}
|
||||
|
||||
for (index, out) in self.temp.iter().enumerate() {
|
||||
let temp = temp_str(pwm_num, index);
|
||||
trace!("writing {temp}");
|
||||
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
|
||||
#[typeshare]
|
||||
#[cfg_attr(feature = "dbus", derive(Type))]
|
||||
#[derive(Deserialize, Serialize, Debug, Clone)]
|
||||
pub struct FanCurveSet {
|
||||
pub enabled: bool,
|
||||
pub cpu: CurveData,
|
||||
pub gpu: CurveData,
|
||||
}
|
||||
|
||||
impl Default for FanCurveSet {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
enabled: false,
|
||||
cpu: CurveData {
|
||||
fan: FanCurvePU::CPU,
|
||||
pwm: [0u8; 8],
|
||||
temp: [0u8; 8],
|
||||
},
|
||||
gpu: CurveData {
|
||||
fan: FanCurvePU::GPU,
|
||||
pwm: [0u8; 8],
|
||||
temp: [0u8; 8],
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&FanCurveSet> for String {
|
||||
fn from(s: &FanCurveSet) -> Self {
|
||||
format!(
|
||||
"Enabled: {}, {}, {}",
|
||||
s.enabled,
|
||||
String::from(&s.cpu),
|
||||
String::from(&s.gpu),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl FanCurveSet {
|
||||
pub(crate) fn read_cpu_from_device(&mut self, device: &Device) {
|
||||
self.cpu.read_from_device(device);
|
||||
}
|
||||
|
||||
pub(crate) fn read_gpu_from_device(&mut self, device: &Device) {
|
||||
self.gpu.read_from_device(device);
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
device.set_attribute_value(format!("pwm{pwm_num}_enable"), enable)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,9 +195,10 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn curve_data_from_str_to_str() {
|
||||
let curve =
|
||||
let mut curve =
|
||||
CurveData::from_str("30c:1%,49c:2%,59c:3%,69c:4%,79c:31%,89c:49%,99c:56%,109c:58%")
|
||||
.unwrap();
|
||||
curve.enabled = true;
|
||||
assert_eq!(curve.fan, FanCurvePU::CPU);
|
||||
assert_eq!(curve.temp, [30, 49, 59, 69, 79, 89, 99, 109]);
|
||||
assert_eq!(curve.pwm, [3, 5, 8, 10, 79, 125, 143, 148]);
|
||||
@@ -274,7 +207,7 @@ mod tests {
|
||||
// End result is slightly different due to type conversions and rounding errors
|
||||
assert_eq!(
|
||||
string.as_str(),
|
||||
"CPU: 30c:1%,49c:1%,59c:3%,69c:3%,79c:30%,89c:49%,99c:56%,109c:58%"
|
||||
"CPU: enabled: true, 30c:1%,49c:1%,59c:3%,69c:3%,79c:30%,89c:49%,99c:56%,109c:58%"
|
||||
);
|
||||
|
||||
let curve = CurveData::from_str("30c:1%,49c:2%,59c:3%,69c:4%,79c:31%,89c:49%,99c:56%");
|
||||
@@ -315,14 +248,14 @@ mod tests {
|
||||
assert_eq!(temp_str('1', 7), "pwm1_auto_point8_temp");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_to_string() {
|
||||
let set = FanCurveSet::default();
|
||||
let string = String::from(&set);
|
||||
assert_eq!(
|
||||
string.as_str(),
|
||||
"Enabled: false, CPU: 0c:0%,0c:0%,0c:0%,0c:0%,0c:0%,0c:0%,0c:0%,0c:0%, GPU: \
|
||||
0c:0%,0c:0%,0c:0%,0c:0%,0c:0%,0c:0%,0c:0%,0c:0%"
|
||||
);
|
||||
}
|
||||
// #[test]
|
||||
// fn set_to_string() {
|
||||
// let set = FanCurveSet::default();
|
||||
// let string = String::from(&set);
|
||||
// assert_eq!(
|
||||
// string.as_str(),
|
||||
// "Enabled: false, CPU:
|
||||
// 0c:0%,0c:0%,0c:0%,0c:0%,0c:0%,0c:0%,0c:0%,0c:0%, GPU: \ 0c:
|
||||
// 0%,0c:0%,0c:0%,0c:0%,0c:0%,0c:0%,0c:0%,0c:0%" );
|
||||
// }
|
||||
}
|
||||
|
||||
+175
-92
@@ -7,7 +7,8 @@ use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
use error::ProfileError;
|
||||
use fan_curve_set::{CurveData, FanCurveSet};
|
||||
use fan_curve_set::CurveData;
|
||||
use log::debug;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use typeshare::typeshare;
|
||||
use udev::Device;
|
||||
@@ -131,10 +132,30 @@ impl Display for Profile {
|
||||
|
||||
#[typeshare]
|
||||
#[cfg_attr(feature = "dbus", derive(Type), zvariant(signature = "s"))]
|
||||
#[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Clone, Copy)]
|
||||
#[derive(Deserialize, Serialize, Debug, Hash, PartialEq, Eq, Clone, Copy)]
|
||||
pub enum FanCurvePU {
|
||||
CPU,
|
||||
GPU,
|
||||
MID,
|
||||
}
|
||||
|
||||
impl FanCurvePU {
|
||||
fn which_fans(device: &Device) -> Vec<Self> {
|
||||
let mut fans = Vec::with_capacity(3);
|
||||
for fan in [Self::CPU, Self::GPU, Self::MID] {
|
||||
let pwm_num: char = fan.into();
|
||||
let pwm_enable = format!("pwm{pwm_num}_enable");
|
||||
debug!("Looking for {pwm_enable}");
|
||||
for attr in device.attributes() {
|
||||
let tmp = attr.name().to_string_lossy();
|
||||
if tmp.contains(&pwm_enable) {
|
||||
debug!("Found {pwm_enable}");
|
||||
fans.push(fan);
|
||||
}
|
||||
}
|
||||
}
|
||||
fans
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FanCurvePU> for &str {
|
||||
@@ -142,6 +163,17 @@ impl From<FanCurvePU> for &str {
|
||||
match pu {
|
||||
FanCurvePU::CPU => "cpu",
|
||||
FanCurvePU::GPU => "gpu",
|
||||
FanCurvePU::MID => "mid",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FanCurvePU> for char {
|
||||
fn from(pu: FanCurvePU) -> char {
|
||||
match pu {
|
||||
FanCurvePU::CPU => '1',
|
||||
FanCurvePU::GPU => '2',
|
||||
FanCurvePU::MID => '3',
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,6 +185,7 @@ impl std::str::FromStr for FanCurvePU {
|
||||
match fan.to_ascii_lowercase().trim() {
|
||||
"cpu" => Ok(FanCurvePU::CPU),
|
||||
"gpu" => Ok(FanCurvePU::GPU),
|
||||
"mid" => Ok(FanCurvePU::MID),
|
||||
_ => Err(ProfileError::ParseProfileName),
|
||||
}
|
||||
}
|
||||
@@ -169,9 +202,9 @@ impl Default for FanCurvePU {
|
||||
#[cfg_attr(feature = "dbus", derive(Type))]
|
||||
#[derive(Deserialize, Serialize, Debug, Default)]
|
||||
pub struct FanCurveProfiles {
|
||||
pub balanced: FanCurveSet,
|
||||
pub performance: FanCurveSet,
|
||||
pub quiet: FanCurveSet,
|
||||
pub balanced: Vec<CurveData>,
|
||||
pub performance: Vec<CurveData>,
|
||||
pub quiet: Vec<CurveData>,
|
||||
}
|
||||
|
||||
impl FanCurveProfiles {
|
||||
@@ -180,35 +213,49 @@ impl FanCurveProfiles {
|
||||
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" {
|
||||
debug!("asus_custom_fan_curve found");
|
||||
return Ok(device);
|
||||
}
|
||||
}
|
||||
// }
|
||||
}
|
||||
Err(ProfileError::NotSupported)
|
||||
}
|
||||
|
||||
pub fn is_supported() -> Result<bool, ProfileError> {
|
||||
if Self::get_device().is_ok() {
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
Ok(false)
|
||||
/// Return an array of `FanCurvePU`. An empty array indicates no support for
|
||||
/// Curves.
|
||||
pub fn supported_fans() -> Result<Vec<FanCurvePU>, ProfileError> {
|
||||
let device = Self::get_device()?;
|
||||
Ok(FanCurvePU::which_fans(&device))
|
||||
}
|
||||
|
||||
///
|
||||
pub fn read_from_dev_profile(&mut self, profile: Profile, device: &Device) {
|
||||
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,
|
||||
pub fn read_from_dev_profile(
|
||||
&mut self,
|
||||
profile: Profile,
|
||||
device: &Device,
|
||||
) -> Result<(), ProfileError> {
|
||||
let fans = Self::supported_fans()?;
|
||||
let mut curves = Vec::with_capacity(3);
|
||||
|
||||
for fan in fans {
|
||||
let mut curve = CurveData {
|
||||
fan,
|
||||
..Default::default()
|
||||
};
|
||||
debug!("Reading curve for {fan:?}");
|
||||
curve.read_from_device(device);
|
||||
debug!("Curve: {curve:?}");
|
||||
curves.push(curve);
|
||||
}
|
||||
|
||||
match profile {
|
||||
Profile::Balanced => self.balanced = curves,
|
||||
Profile::Performance => self.performance = curves,
|
||||
Profile::Quiet => self.quiet = curves,
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Reset the stored (self) and device curve to the defaults of the
|
||||
@@ -220,19 +267,15 @@ impl FanCurveProfiles {
|
||||
&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,
|
||||
) -> Result<(), ProfileError> {
|
||||
let fans = Self::supported_fans()?;
|
||||
// Do reset for all
|
||||
for fan in fans {
|
||||
let pwm_num: char = fan.into();
|
||||
let pwm = format!("pwm{pwm_num}_enable");
|
||||
device.set_attribute_value(&pwm, "3")?;
|
||||
}
|
||||
self.read_from_dev_profile(profile, device)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -250,50 +293,68 @@ impl FanCurveProfiles {
|
||||
Profile::Performance => &mut self.performance,
|
||||
Profile::Quiet => &mut self.quiet,
|
||||
};
|
||||
fans.write_cpu_fan(device)?;
|
||||
fans.write_gpu_fan(device)?;
|
||||
for fan in fans {
|
||||
debug!("write_profile_curve_to_platform: writing profile:{profile}, {fan:?}");
|
||||
fan.write_to_device(device)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
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_profile_curve_enabled(&mut self, profile: Profile, enabled: bool) {
|
||||
pub fn set_profile_curves_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,
|
||||
Profile::Balanced => {
|
||||
for curve in self.balanced.iter_mut() {
|
||||
curve.enabled = enabled;
|
||||
}
|
||||
}
|
||||
Profile::Performance => {
|
||||
for curve in self.performance.iter_mut() {
|
||||
curve.enabled = enabled;
|
||||
}
|
||||
}
|
||||
Profile::Quiet => {
|
||||
for curve in self.quiet.iter_mut() {
|
||||
curve.enabled = enabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_all_fan_curves(&self) -> Vec<FanCurveSet> {
|
||||
vec![
|
||||
self.balanced.clone(),
|
||||
self.performance.clone(),
|
||||
self.quiet.clone(),
|
||||
]
|
||||
}
|
||||
|
||||
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),
|
||||
pub fn set_profile_fan_curve_enabled(
|
||||
&mut self,
|
||||
profile: Profile,
|
||||
fan: FanCurvePU,
|
||||
enabled: bool,
|
||||
) {
|
||||
match profile {
|
||||
Profile::Balanced => {
|
||||
for curve in self.balanced.iter_mut() {
|
||||
if curve.fan == fan {
|
||||
curve.enabled = enabled;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Profile::Performance => {
|
||||
for curve in self.performance.iter_mut() {
|
||||
if curve.fan == fan {
|
||||
curve.enabled = enabled;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Profile::Quiet => {
|
||||
for curve in self.quiet.iter_mut() {
|
||||
if curve.fan == fan {
|
||||
curve.enabled = enabled;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_fan_curves_for(&self, name: Profile) -> &FanCurveSet {
|
||||
pub fn get_fan_curves_for(&self, name: Profile) -> &[CurveData] {
|
||||
match name {
|
||||
Profile::Balanced => &self.balanced,
|
||||
Profile::Performance => &self.performance,
|
||||
@@ -301,37 +362,59 @@ impl FanCurveProfiles {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_fan_curve_for(&self, name: &Profile, pu: &FanCurvePU) -> &CurveData {
|
||||
pub fn get_fan_curve_for(&self, name: &Profile, pu: FanCurvePU) -> Option<&CurveData> {
|
||||
match name {
|
||||
Profile::Balanced => match pu {
|
||||
FanCurvePU::CPU => &self.balanced.cpu,
|
||||
FanCurvePU::GPU => &self.balanced.gpu,
|
||||
},
|
||||
Profile::Performance => match pu {
|
||||
FanCurvePU::CPU => &self.performance.cpu,
|
||||
FanCurvePU::GPU => &self.performance.gpu,
|
||||
},
|
||||
Profile::Quiet => match pu {
|
||||
FanCurvePU::CPU => &self.quiet.cpu,
|
||||
FanCurvePU::GPU => &self.quiet.gpu,
|
||||
},
|
||||
Profile::Balanced => {
|
||||
for this_curve in self.balanced.iter() {
|
||||
if this_curve.fan == pu {
|
||||
return Some(this_curve);
|
||||
}
|
||||
}
|
||||
}
|
||||
Profile::Performance => {
|
||||
for this_curve in self.performance.iter() {
|
||||
if this_curve.fan == pu {
|
||||
return Some(this_curve);
|
||||
}
|
||||
}
|
||||
}
|
||||
Profile::Quiet => {
|
||||
for this_curve in self.quiet.iter() {
|
||||
if this_curve.fan == pu {
|
||||
return Some(this_curve);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
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,
|
||||
FanCurvePU::GPU => self.balanced.gpu = curve,
|
||||
},
|
||||
Profile::Performance => match curve.fan {
|
||||
FanCurvePU::CPU => self.performance.cpu = curve,
|
||||
FanCurvePU::GPU => self.performance.gpu = curve,
|
||||
},
|
||||
Profile::Quiet => match curve.fan {
|
||||
FanCurvePU::CPU => self.quiet.cpu = curve,
|
||||
FanCurvePU::GPU => self.quiet.gpu = curve,
|
||||
},
|
||||
Profile::Balanced => {
|
||||
for this_curve in self.balanced.iter_mut() {
|
||||
if this_curve.fan == curve.fan {
|
||||
*this_curve = curve;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Profile::Performance => {
|
||||
for this_curve in self.performance.iter_mut() {
|
||||
if this_curve.fan == curve.fan {
|
||||
*this_curve = curve;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Profile::Quiet => {
|
||||
for this_curve in self.quiet.iter_mut() {
|
||||
if this_curve.fan == curve.fan {
|
||||
*this_curve = curve;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user