Merge branch 'fluke/aura-crate' into 'main'

profiles: add dbus methods to change active profile

Closes #68, #73, and #81

See merge request asus-linux/asusctl!53
This commit is contained in:
Luke Jones
2021-04-25 02:37:31 +00:00
16 changed files with 499 additions and 197 deletions

View File

@@ -6,12 +6,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Changed
- Split out all aura functionality that isn't dependent on the daemon in to a
new crate `rog-aura`
- Correctly enable compute mode for nvidia plus no-reboot or logout if switching
from vfio/integrated/compute.
- Add asusd config option to not save compute/vfio mode switch.
- Enable basic multiple user anime configs (asusd-user must still be restarted)
+ Keyboard:
- Split out all aura functionality that isn't dependent on the daemon in to a
new crate `rog-aura`
- Keyboard LED control now includes:
+ Enable/disable LED's while laptop is awake
+ Enable/disable LED animation while laptop is suspended and AC plugged in
- Properly reload the last used keyboard mode on boot
+ Graphics:
- Correctly enable compute mode for nvidia plus no-reboot or logout if switching
from vfio/integrated/compute.
- Add asusd config option to not save compute/vfio mode switch.
+ Anime:
- Enable basic multiple user anime configs (asusd-user must still be restarted)
+ Profiles:
- Enable dbus methods for freq min/max, fan curve, fan preset, CPU turbo enable.
These options will apply to the active profile if no profile name is specified.
# [3.4.1] - 2021-04-11
### Changed

View File

@@ -5,7 +5,7 @@ use crate::aura_cli::{LedBrightness, SetAuraBuiltin};
use anime_cli::{AnimeActions, AnimeCommand};
use gumdrop::{Opt, Options};
use rog_anime::{AnimeDataBuffer, AnimeImage, Vec2, ANIME_DATA_LEN};
use rog_aura::{self, AuraEffect, AuraModeNum};
use rog_aura::{self, AuraEffect};
use rog_dbus::AuraDbusClient;
use rog_types::{
gfx_vendors::GfxVendors,
@@ -62,6 +62,16 @@ struct LedModeCommand {
next_mode: bool,
#[options(help = "switch to previous aura mode")]
prev_mode: bool,
#[options(
meta = "",
help = "set the keyboard LED to enabled while the device is awake"
)]
awake_enable: Option<bool>,
#[options(
meta = "",
help = "set the keyboard LED suspend animation to enabled while the device is suspended"
)]
sleep_enable: Option<bool>,
#[options(command)]
command: Option<SetAuraBuiltin>,
}
@@ -335,7 +345,12 @@ fn handle_led_mode(
supported: &LedSupportedFunctions,
mode: &LedModeCommand,
) -> Result<(), Box<dyn std::error::Error>> {
if mode.command.is_none() && !mode.prev_mode && !mode.next_mode {
if mode.command.is_none()
&& !mode.prev_mode
&& !mode.next_mode
&& mode.sleep_enable.is_none()
&& mode.awake_enable.is_none()
{
if !mode.help {
println!("Missing arg or command\n");
}
@@ -347,9 +362,13 @@ fn handle_led_mode(
.lines()
.map(|s| s.to_string())
.collect();
for command in commands.iter().filter(|mode| {
for command in commands.iter().filter(|command| {
if let Some(modes) = supported.stock_led_modes.as_ref() {
return modes.contains(&<AuraModeNum>::from(mode.as_str()));
for mode in modes {
if command.contains(&(<&str>::from(mode)).to_lowercase()) {
return true;
}
}
}
if supported.multizone_led_mode {
return true;
@@ -389,6 +408,15 @@ fn handle_led_mode(
.set_led_mode(&<AuraEffect>::from(mode))?,
}
}
if let Some(enable) = mode.awake_enable {
dbus.proxies().led().set_awake_enabled(enable)?;
}
if let Some(enable) = mode.sleep_enable {
dbus.proxies().led().set_sleep_enabled(enable)?;
}
Ok(())
}
@@ -398,18 +426,19 @@ fn handle_profile(
cmd: &ProfileCommand,
) -> Result<(), Box<dyn std::error::Error>> {
if !cmd.next
&& !cmd.create
&& !cmd.create // TODO
&& !cmd.list
&& cmd.profile.is_none()
&& !cmd.active_name
&& !cmd.active_data
&& !cmd.profiles_data
&& cmd.remove.is_none()
&& cmd.curve.is_none()
&& cmd.max_percentage.is_none()
&& cmd.curve.is_none() // TODO
&& cmd.fan_preset.is_none() // TODO
&& cmd.turbo.is_none() // TODO
&& cmd.max_percentage.is_none() // TODO
&& cmd.min_percentage.is_none()
&& cmd.fan_preset.is_none()
&& cmd.profile.is_none()
&& cmd.turbo.is_none()
// TODO
{
if !cmd.help {
println!("Missing arg or command\n");
@@ -428,6 +457,9 @@ fn handle_profile(
if let Some(lst) = cmd.self_command_list() {
println!("\n{}", lst);
}
println!("Note: turbo, frequency, fan preset and fan curve options will apply to");
println!(" to the currently active profile unless a profile name is specified");
std::process::exit(1);
}
@@ -460,10 +492,34 @@ fn handle_profile(
}
}
// This must come before the next block of actions so that changing a specific
// profile can be done
if cmd.profile.is_some() {
dbus.proxies()
.profile()
.write_command(&ProfileEvent::Cli(cmd.clone()))?
.write_command(&ProfileEvent::Cli(cmd.clone()))?;
return Ok(());
}
if let Some(turbo) = cmd.turbo {
dbus.proxies().profile().set_turbo(turbo)?;
}
if let Some(min) = cmd.min_percentage {
dbus.proxies().profile().set_min_frequency(min)?;
}
if let Some(max) = cmd.max_percentage {
dbus.proxies().profile().set_max_frequency(max)?;
}
if let Some(ref preset) = cmd.fan_preset {
dbus.proxies().profile().set_fan_preset(preset.into())?;
}
if let Some(ref curve) = cmd.curve {
let s = curve.as_config_string();
dbus.proxies().profile().set_fan_curve(&s)?;
}
Ok(())

View File

@@ -15,7 +15,7 @@ use zbus::dbus_interface;
use zvariant::ObjectPath;
use zvariant_derive::Type;
use crate::{error::Error, user_config::{UserAnimeConfig, UserConfig}};
use crate::{error::Error, user_config::UserAnimeConfig};
#[derive(Debug, Clone, Deserialize, Serialize, Type)]
pub enum TimeType {

View File

@@ -46,8 +46,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
)?));
// Need new client object for dbus control part
let (client, _) = AuraDbusClient::new().unwrap();
let anime_control =
CtrlAnime::new(anime_config, inner.clone(), client, &ANIME_INNER_EARLY_RETURN)?;
let anime_control = CtrlAnime::new(
anime_config,
inner.clone(),
client,
&ANIME_INNER_EARLY_RETURN,
)?;
anime_control.add_to_server(&mut server);
// Thread using inner
let _anime_thread = thread::Builder::new()

View File

@@ -1,4 +1,8 @@
use std::{fs::{create_dir, OpenOptions}, io::{Read, Write}, time::Duration};
use std::{
fs::{create_dir, OpenOptions},
io::{Read, Write},
time::Duration,
};
use rog_anime::{AnimTime, AnimeAction, Sequences, Vec2};
use serde_derive::{Deserialize, Serialize};
@@ -133,7 +137,7 @@ pub struct UserConfig {
impl UserConfig {
pub fn new() -> Self {
Self {
active_anime: "anime-default".to_string()
active_anime: "anime-default".to_string(),
}
}

View File

@@ -8,7 +8,7 @@ use crate::{
};
use log::{error, info, warn};
use rog_aura::{
usb::{LED_APPLY, LED_SET},
usb::{LED_APPLY, LED_AWAKE_OFF, LED_AWAKE_ON, LED_SET, LED_SLEEP_OFF, LED_SLEEP_ON},
AuraEffect, LedBrightness, LED_MSG_LEN,
};
use rog_types::supported::LedSupportedFunctions;
@@ -124,6 +124,7 @@ impl crate::ZbusAdd for CtrlKbdLedZbus {
/// LED commands are split between Brightness, Modes, Per-Key
#[dbus_interface(name = "org.asuslinux.Daemon")]
impl CtrlKbdLedZbus {
/// Set the keyboard brightness level (0-3)
fn set_brightness(&mut self, brightness: LedBrightness) {
if let Ok(ctrl) = self.inner.try_lock() {
ctrl.set_brightness(brightness)
@@ -132,6 +133,24 @@ impl CtrlKbdLedZbus {
}
}
/// Set the keyboard LED to enabled while the device is awake
fn set_awake_enabled(&mut self, enabled: bool) {
if let Ok(ctrl) = self.inner.try_lock() {
ctrl.set_awake_enable(enabled)
.map_err(|err| warn!("{}", err))
.ok();
}
}
/// Set the keyboard LED suspend animation to enabled while the device is suspended
fn set_sleep_enabled(&mut self, enabled: bool) {
if let Ok(ctrl) = self.inner.try_lock() {
ctrl.set_sleep_anim_enable(enabled)
.map_err(|err| warn!("{}", err))
.ok();
}
}
fn set_led_mode(&mut self, effect: AuraEffect) {
if let Ok(mut ctrl) = self.inner.try_lock() {
let mode_name = effect.mode_name();
@@ -261,7 +280,7 @@ impl CtrlKbdLed {
None
}
pub fn get_brightness(&self) -> Result<u8, RogError> {
fn get_brightness(&self) -> Result<u8, RogError> {
let mut file = OpenOptions::new()
.read(true)
.open(&self.bright_node)
@@ -277,7 +296,7 @@ impl CtrlKbdLed {
Ok(buf[0])
}
pub fn set_brightness(&self, brightness: LedBrightness) -> Result<(), RogError> {
fn set_brightness(&self, brightness: LedBrightness) -> Result<(), RogError> {
let path = Path::new(&self.bright_node);
let mut file =
OpenOptions::new()
@@ -294,6 +313,26 @@ impl CtrlKbdLed {
Ok(())
}
/// Set the keyboard LED to active if laptop is awake
fn set_awake_enable(&self, enabled: bool) -> Result<(), RogError> {
let bytes = if enabled { LED_AWAKE_ON } else { LED_AWAKE_OFF };
self.write_bytes(&bytes)?;
self.write_bytes(&LED_SET)?;
// Changes won't persist unless apply is set
self.write_bytes(&LED_APPLY)?;
Ok(())
}
/// Set the keyboard suspend animation to on if plugged in
fn set_sleep_anim_enable(&self, enabled: bool) -> Result<(), RogError> {
let bytes = if enabled { LED_SLEEP_ON } else { LED_SLEEP_OFF };
self.write_bytes(&bytes)?;
self.write_bytes(&LED_SET)?;
// Changes won't persist unless apply is set
self.write_bytes(&LED_APPLY)?;
Ok(())
}
fn find_led_node(id_product: &str) -> Result<String, RogError> {
let mut enumerator = udev::Enumerator::new().map_err(|err| {
warn!("{}", err);

View File

@@ -1,3 +1,5 @@
pub mod zbus;
use crate::error::RogError;
use crate::{config::Config, GetSupported};
use log::{info, warn};
@@ -10,8 +12,6 @@ use std::io::Write;
use std::path::Path;
use std::sync::Arc;
use std::sync::Mutex;
use zbus::{dbus_interface, fdo::Error};
use zvariant::ObjectPath;
static FAN_TYPE_1_PATH: &str = "/sys/devices/platform/asus-nb-wmi/throttle_thermal_policy";
static FAN_TYPE_2_PATH: &str = "/sys/devices/platform/asus-nb-wmi/fan_boost_mode";
@@ -34,160 +34,6 @@ impl GetSupported for CtrlFanAndCpu {
}
}
pub struct FanAndCpuZbus {
inner: Arc<Mutex<CtrlFanAndCpu>>,
}
impl FanAndCpuZbus {
pub fn new(inner: Arc<Mutex<CtrlFanAndCpu>>) -> Self {
Self { inner }
}
}
#[dbus_interface(name = "org.asuslinux.Daemon")]
impl FanAndCpuZbus {
/// Set profile details
fn set_profile(&self, profile: String) {
if let Ok(event) = serde_json::from_str(&profile) {
if let Ok(mut ctrl) = self.inner.try_lock() {
if let Ok(mut cfg) = ctrl.config.clone().try_lock() {
cfg.read();
ctrl.handle_profile_event(&event, &mut cfg)
.unwrap_or_else(|err| warn!("{}", err));
if let Some(profile) = cfg.power_profiles.get(&cfg.active_profile) {
if let Ok(json) = serde_json::to_string(profile) {
self.notify_profile(&json)
.unwrap_or_else(|err| warn!("{}", err));
}
}
}
}
}
}
/// Fetch the active profile name
fn next_profile(&mut self) {
if let Ok(mut ctrl) = self.inner.try_lock() {
if let Ok(mut cfg) = ctrl.config.clone().try_lock() {
cfg.read();
ctrl.do_next_profile(&mut cfg)
.unwrap_or_else(|err| warn!("{}", err));
if let Some(profile) = cfg.power_profiles.get(&cfg.active_profile) {
if let Ok(json) = serde_json::to_string(profile) {
self.notify_profile(&json)
.unwrap_or_else(|err| warn!("{}", err));
}
}
}
}
}
/// Fetch the active profile name
fn active_profile_name(&mut self) -> zbus::fdo::Result<String> {
if let Ok(ctrl) = self.inner.try_lock() {
if let Ok(mut cfg) = ctrl.config.try_lock() {
cfg.read();
return Ok(cfg.active_profile.clone());
}
}
Err(Error::Failed(
"Failed to get active profile name".to_string(),
))
}
// TODO: Profile can't implement Type because of Curve
/// Fetch the active profile details
fn profile(&mut self) -> zbus::fdo::Result<String> {
if let Ok(ctrl) = self.inner.try_lock() {
if let Ok(mut cfg) = ctrl.config.try_lock() {
cfg.read();
if let Some(profile) = cfg.power_profiles.get(&cfg.active_profile) {
if let Ok(json) = serde_json::to_string_pretty(profile) {
return Ok(json);
}
}
}
}
Err(Error::Failed(
"Failed to get active profile details".to_string(),
))
}
/// Fetch all profile data
fn profiles(&mut self) -> zbus::fdo::Result<String> {
if let Ok(ctrl) = self.inner.try_lock() {
if let Ok(mut cfg) = ctrl.config.try_lock() {
cfg.read();
if let Ok(json) = serde_json::to_string_pretty(&cfg.power_profiles) {
return Ok(json);
}
}
}
Err(Error::Failed(
"Failed to get all profile details".to_string(),
))
}
fn profile_names(&self) -> zbus::fdo::Result<Vec<String>> {
if let Ok(ctrl) = self.inner.try_lock() {
if let Ok(mut cfg) = ctrl.config.try_lock() {
cfg.read();
let profile_names = cfg.power_profiles.keys().cloned().collect::<Vec<String>>();
return Ok(profile_names);
}
}
Err(Error::Failed("Failed to get all profile names".to_string()))
}
fn remove(&self, profile: &str) -> zbus::fdo::Result<()> {
if let Ok(ctrl) = self.inner.try_lock() {
if let Ok(mut cfg) = ctrl.config.try_lock() {
cfg.read();
if !cfg.power_profiles.contains_key(profile) {
return Err(Error::Failed("Invalid profile specified".to_string()));
}
if cfg.power_profiles.keys().len() == 1 {
return Err(Error::Failed("Cannot delete the last profile".to_string()));
}
if cfg.active_profile == *profile {
return Err(Error::Failed(
"Cannot delete the active profile".to_string(),
));
}
cfg.power_profiles.remove(profile);
cfg.write();
return Ok(());
}
}
Err(Error::Failed("Failed to lock configuration".to_string()))
}
#[dbus_interface(signal)]
fn notify_profile(&self, profile: &str) -> zbus::Result<()> {}
}
impl crate::ZbusAdd for FanAndCpuZbus {
fn add_to_server(self, server: &mut zbus::ObjectServer) {
server
.at(
&ObjectPath::from_str_unchecked("/org/asuslinux/Profile"),
self,
)
.map_err(|err| {
warn!("DbusFanAndCpu: add_to_server {}", err);
err
})
.ok();
}
}
impl crate::Reloadable for CtrlFanAndCpu {
fn reload(&mut self) -> Result<(), RogError> {
if let Ok(mut config) = self.config.clone().try_lock() {

View File

@@ -0,0 +1,255 @@
use log::warn;
use rog_fan_curve::Curve;
use std::sync::Arc;
use std::sync::Mutex;
use zbus::{dbus_interface, fdo::Error};
use zvariant::ObjectPath;
use super::CtrlFanAndCpu;
pub struct FanAndCpuZbus {
inner: Arc<Mutex<CtrlFanAndCpu>>,
}
impl FanAndCpuZbus {
pub fn new(inner: Arc<Mutex<CtrlFanAndCpu>>) -> Self {
Self { inner }
}
}
#[dbus_interface(name = "org.asuslinux.Daemon")]
impl FanAndCpuZbus {
/// Set profile details
fn set_profile(&self, profile: String) {
if let Ok(event) = serde_json::from_str(&profile) {
if let Ok(mut ctrl) = self.inner.try_lock() {
if let Ok(mut cfg) = ctrl.config.clone().try_lock() {
cfg.read();
ctrl.handle_profile_event(&event, &mut cfg)
.unwrap_or_else(|err| warn!("{}", err));
if let Some(profile) = cfg.power_profiles.get(&cfg.active_profile) {
if let Ok(json) = serde_json::to_string(profile) {
self.notify_profile(&json)
.unwrap_or_else(|err| warn!("{}", err));
}
}
}
}
}
}
/// Modify the active profile
fn set_turbo(&self, enable: bool) -> zbus::fdo::Result<()> {
if let Ok(mut ctrl) = self.inner.try_lock() {
if let Ok(mut cfg) = ctrl.config.clone().try_lock() {
// Update the profile then set it
cfg.read();
let profile = cfg.active_profile.clone();
if let Some(profile) = cfg.power_profiles.get_mut(&profile) {
profile.turbo = enable;
}
ctrl.set(&profile, &mut cfg)?;
return Ok(());
}
}
Ok(())
}
/// Modify the active profile
fn set_min_frequency(&self, percentage: u8) -> zbus::fdo::Result<()> {
if let Ok(mut ctrl) = self.inner.try_lock() {
if let Ok(mut cfg) = ctrl.config.clone().try_lock() {
// Update the profile then set it
cfg.read();
let profile = cfg.active_profile.clone();
if let Some(profile) = cfg.power_profiles.get_mut(&profile) {
profile.min_percentage = percentage;
}
ctrl.set(&profile, &mut cfg)?;
return Ok(());
}
}
Ok(())
}
/// Modify the active profile
fn set_max_frequency(&self, percentage: u8) -> zbus::fdo::Result<()> {
if let Ok(mut ctrl) = self.inner.try_lock() {
if let Ok(mut cfg) = ctrl.config.clone().try_lock() {
// Update the profile then set it
cfg.read();
let profile = cfg.active_profile.clone();
if let Some(profile) = cfg.power_profiles.get_mut(&profile) {
profile.max_percentage = percentage;
}
ctrl.set(&profile, &mut cfg)?;
return Ok(());
}
}
Ok(())
}
/// Modify the active profile
fn set_fan_preset(&self, preset: u8) -> zbus::fdo::Result<()> {
if preset > 2 {
return Err(zbus::fdo::Error::InvalidArgs(
"Fan preset must be 0, 1, or 2".to_string(),
));
}
if let Ok(mut ctrl) = self.inner.try_lock() {
if let Ok(mut cfg) = ctrl.config.clone().try_lock() {
// Update the profile then set it
cfg.read();
let profile = cfg.active_profile.clone();
if let Some(profile) = cfg.power_profiles.get_mut(&profile) {
profile.fan_preset = preset;
}
ctrl.set(&profile, &mut cfg)?;
return Ok(());
}
}
Ok(())
}
/// Modify the active profile
fn set_fan_curve(&self, curve: String) -> zbus::fdo::Result<()> {
let curve = Curve::from_config_str(&curve)
.map_err(|err| zbus::fdo::Error::InvalidArgs(format!("Fan curve error: {}", err)))?;
if let Ok(mut ctrl) = self.inner.try_lock() {
if let Ok(mut cfg) = ctrl.config.clone().try_lock() {
// Update the profile then set it
cfg.read();
let profile = cfg.active_profile.clone();
if let Some(profile) = cfg.power_profiles.get_mut(&profile) {
profile.fan_curve = Some(curve);
}
ctrl.set(&profile, &mut cfg)?;
return Ok(());
}
}
Ok(())
}
/// Fetch the active profile name
fn next_profile(&mut self) {
if let Ok(mut ctrl) = self.inner.try_lock() {
if let Ok(mut cfg) = ctrl.config.clone().try_lock() {
cfg.read();
ctrl.do_next_profile(&mut cfg)
.unwrap_or_else(|err| warn!("{}", err));
if let Some(profile) = cfg.power_profiles.get(&cfg.active_profile) {
if let Ok(json) = serde_json::to_string(profile) {
self.notify_profile(&json)
.unwrap_or_else(|err| warn!("{}", err));
}
}
}
}
}
/// Fetch the active profile name
fn active_profile_name(&mut self) -> zbus::fdo::Result<String> {
if let Ok(ctrl) = self.inner.try_lock() {
if let Ok(mut cfg) = ctrl.config.try_lock() {
cfg.read();
return Ok(cfg.active_profile.clone());
}
}
Err(Error::Failed(
"Failed to get active profile name".to_string(),
))
}
// TODO: Profile can't implement Type because of Curve
/// Fetch the active profile details
fn profile(&mut self) -> zbus::fdo::Result<String> {
if let Ok(ctrl) = self.inner.try_lock() {
if let Ok(mut cfg) = ctrl.config.try_lock() {
cfg.read();
if let Some(profile) = cfg.power_profiles.get(&cfg.active_profile) {
if let Ok(json) = serde_json::to_string_pretty(profile) {
return Ok(json);
}
}
}
}
Err(Error::Failed(
"Failed to get active profile details".to_string(),
))
}
/// Fetch all profile data
fn profiles(&mut self) -> zbus::fdo::Result<String> {
if let Ok(ctrl) = self.inner.try_lock() {
if let Ok(mut cfg) = ctrl.config.try_lock() {
cfg.read();
if let Ok(json) = serde_json::to_string_pretty(&cfg.power_profiles) {
return Ok(json);
}
}
}
Err(Error::Failed(
"Failed to get all profile details".to_string(),
))
}
fn profile_names(&self) -> zbus::fdo::Result<Vec<String>> {
if let Ok(ctrl) = self.inner.try_lock() {
if let Ok(mut cfg) = ctrl.config.try_lock() {
cfg.read();
let profile_names = cfg.power_profiles.keys().cloned().collect::<Vec<String>>();
return Ok(profile_names);
}
}
Err(Error::Failed("Failed to get all profile names".to_string()))
}
fn remove(&self, profile: &str) -> zbus::fdo::Result<()> {
if let Ok(ctrl) = self.inner.try_lock() {
if let Ok(mut cfg) = ctrl.config.try_lock() {
cfg.read();
if !cfg.power_profiles.contains_key(profile) {
return Err(Error::Failed("Invalid profile specified".to_string()));
}
if cfg.power_profiles.keys().len() == 1 {
return Err(Error::Failed("Cannot delete the last profile".to_string()));
}
if cfg.active_profile == *profile {
return Err(Error::Failed(
"Cannot delete the active profile".to_string(),
));
}
cfg.power_profiles.remove(profile);
cfg.write();
return Ok(());
}
}
Err(Error::Failed("Failed to lock configuration".to_string()))
}
#[dbus_interface(signal)]
fn notify_profile(&self, profile: &str) -> zbus::Result<()> {}
}
impl crate::ZbusAdd for FanAndCpuZbus {
fn add_to_server(self, server: &mut zbus::ObjectServer) {
server
.at(
&ObjectPath::from_str_unchecked("/org/asuslinux/Profile"),
self,
)
.map_err(|err| {
warn!("DbusFanAndCpu: add_to_server {}", err);
err
})
.ok();
}
}

View File

@@ -4,8 +4,8 @@ use zbus::dbus_interface;
use zvariant::ObjectPath;
use crate::{
ctrl_anime::CtrlAnime, ctrl_charge::CtrlCharge, ctrl_fan_cpu::CtrlFanAndCpu,
ctrl_leds::CtrlKbdLed, ctrl_rog_bios::CtrlRogBios, GetSupported,
ctrl_anime::CtrlAnime, ctrl_charge::CtrlCharge, ctrl_leds::CtrlKbdLed,
ctrl_profiles::CtrlFanAndCpu, ctrl_rog_bios::CtrlRogBios, GetSupported,
};
use rog_types::supported::{

View File

@@ -1,11 +1,11 @@
use daemon::ctrl_leds::{CtrlKbdLed, CtrlKbdLedTask, CtrlKbdLedZbus, CtrlKbdLedReloader};
use daemon::ctrl_leds::{CtrlKbdLed, CtrlKbdLedReloader, CtrlKbdLedTask, CtrlKbdLedZbus};
use daemon::{
config::Config, ctrl_supported::SupportedFunctions, laptops::print_board_info, GetSupported,
};
use daemon::{config_anime::AnimeConfig, config_aura::AuraConfig, ctrl_charge::CtrlCharge};
use daemon::{ctrl_anime::*, ctrl_gfx::gfx::CtrlGraphics};
use daemon::{
ctrl_fan_cpu::{CtrlFanAndCpu, FanAndCpuZbus},
ctrl_profiles::{zbus::FanAndCpuZbus, CtrlFanAndCpu},
laptops::LaptopLedData,
};

View File

@@ -96,3 +96,10 @@ impl From<std::io::Error> for RogError {
RogError::Io(err)
}
}
impl From<RogError> for zbus::fdo::Error {
#[inline]
fn from(err: RogError) -> Self {
zbus::fdo::Error::Failed(format!("{}", err))
}
}

View File

@@ -8,6 +8,10 @@ pub(crate) mod config_old;
pub mod ctrl_anime;
/// Control of battery charge level
pub mod ctrl_charge;
/// GPU switching and power
pub mod ctrl_gfx;
/// Keyboard LED brightness control, RGB, and LED display modes
pub mod ctrl_leds;
/// Control CPU min/max freq and turbo, fan mode, fan curves
///
/// Intel machines can control:
@@ -19,11 +23,7 @@ pub mod ctrl_charge;
/// - CPU turbo enable/disable
/// - Fan mode (normal, boost, silent)
/// - Fan min/max RPM curve
pub mod ctrl_fan_cpu;
/// GPU switching and power
pub mod ctrl_gfx;
/// Keyboard LED brightness control, RGB, and LED display modes
pub mod ctrl_leds;
pub mod ctrl_profiles;
/// Control ASUS bios function such as boot sound, Optimus/Dedicated gfx mode
pub mod ctrl_rog_bios;
/// Laptop matching to determine capabilities

View File

@@ -1,8 +1,3 @@
use std::{
path::{Path, PathBuf},
time::Duration,
};
use serde_derive::{Deserialize, Serialize};
use crate::error::Error;
@@ -27,7 +22,7 @@ impl Sequences {
/// Use a base `AnimeAction` to generate the precomputed data and insert in to
/// the run buffer
#[inline]
pub fn insert(&mut self, index: usize) -> Result<(), Error> {
pub fn insert(&mut self, _index: usize) -> Result<(), Error> {
Ok(())
}

View File

@@ -14,3 +14,23 @@ pub const fn aura_brightness_bytes(brightness: u8) -> [u8; 17] {
0x5A, 0xBA, 0xC5, 0xC4, brightness, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
]
}
/// Enable the keyboard when laptop is awake
pub const LED_AWAKE_ON: [u8; 17] = [
0x5d, 0xbd, 0x01, 0xcf, 0x17, 0x0b, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
];
/// Disable the keyboard when laptop is awake
pub const LED_AWAKE_OFF: [u8; 17] = [
0x5d, 0xbd, 0x01, 0xc3, 0x13, 0x09, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
];
/// Enable animations when the laptop is suspended while plugged in
pub const LED_SLEEP_ON: [u8; 17] = [
0x5d, 0xbd, 0x01, 0xff, 0x1f, 0x0f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
];
/// Disable animations when the laptop is suspended while plugged in
pub const LED_SLEEP_OFF: [u8; 17] = [
0x5d, 0xbd, 0x01, 0xcf, 0x17, 0x0b, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
];

View File

@@ -44,7 +44,12 @@ trait Daemon {
/// SetLedMode method
fn set_led_mode(&self, effect: &AuraEffect) -> zbus::Result<()>;
/// NotifyLed signal
/// SetAwakeEnabled method
fn set_awake_enabled(&self, enabled: bool) -> zbus::Result<()>;
/// SetSleepEnabled method
fn set_sleep_enabled(&self, enabled: bool) -> zbus::Result<()>;
/// NotifyLed signal
#[dbus_proxy(signal)]
fn notify_led(&self, data: &str) -> zbus::Result<()>;
@@ -85,6 +90,20 @@ impl<'a> LedProxy<'a> {
Ok(())
}
/// Set the keyboard LED to enabled while the device is awake
#[inline]
pub fn set_awake_enabled(&self, enabled: bool) -> Result<()> {
self.0.set_awake_enabled(enabled)?;
Ok(())
}
/// Set the keyboard LED suspend animation to enabled while the device is suspended
#[inline]
pub fn set_sleep_enabled(&self, enabled: bool) -> Result<()> {
self.0.set_sleep_enabled(enabled)?;
Ok(())
}
#[inline]
pub fn next_led_mode(&self) -> Result<()> {
self.0.next_led_mode()

View File

@@ -50,6 +50,21 @@ trait Daemon {
/// SetProfile method
fn set_profile(&self, profile: &str) -> zbus::Result<()>;
/// SetFanCurve method
fn set_fan_curve(&self, curve: &str) -> zbus::Result<()>;
/// SetFanPreset method
fn set_fan_preset(&self, preset: u8) -> zbus::Result<()>;
/// SetMaxFrequency method
fn set_max_frequency(&self, percentage: u8) -> zbus::Result<()>;
/// SetMinFrequency method
fn set_min_frequency(&self, percentage: u8) -> zbus::Result<()>;
/// SetTurbo method
fn set_turbo(&self, enable: bool) -> zbus::Result<()>;
/// NotifyProfile signal
#[dbus_proxy(signal)]
fn notify_profile(&self, profile: &str) -> zbus::Result<()>;
@@ -87,12 +102,44 @@ impl<'a> ProfileProxy<'a> {
self.0.next_profile()
}
/// SetFanCurve, set fan curve for active profile
#[inline]
pub fn set_fan_curve(&self, curve: &str) -> zbus::Result<()> {
self.0.set_fan_curve(curve)
}
/// SetFanPreset, set fan preset for active profile
#[inline]
pub fn set_fan_preset(&self, preset: u8) -> zbus::Result<()> {
self.0.set_fan_preset(preset)
}
/// SetMaxFrequency, set max percentage of frequency for active profile
#[inline]
pub fn set_max_frequency(&self, percentage: u8) -> zbus::Result<()> {
self.0.set_max_frequency(percentage)
}
/// SetMinFrequency, set min percentage of frequency for active profile
#[inline]
pub fn set_min_frequency(&self, percentage: u8) -> zbus::Result<()> {
self.0.set_min_frequency(percentage)
}
/// SetTurbo, set turbo enable for active profile
#[inline]
pub fn set_turbo(&self, enable: bool) -> zbus::Result<()> {
self.0.set_turbo(enable)
}
// TODO: remove
#[inline]
pub fn write_fan_mode(&self, level: u8) -> Result<()> {
self.0
.set_profile(&serde_json::to_string(&ProfileEvent::ChangeMode(level)).unwrap())
}
// TODO: remove
#[inline]
pub fn write_command(&self, cmd: &ProfileEvent) -> Result<()> {
self.0.set_profile(&serde_json::to_string(cmd).unwrap())