feat: refactor the cli battery interface

This commit is contained in:
Denis Benato
2026-01-14 01:45:56 +01:00
parent e85938b34d
commit d7ddee246a
2 changed files with 114 additions and 61 deletions

View File

@@ -10,16 +10,8 @@ use crate::slash_cli::SlashCommand;
#[derive(FromArgs, Default, Debug)] #[derive(FromArgs, Default, Debug)]
/// asusctl command-line options /// asusctl command-line options
pub struct CliStart { pub struct CliStart {
#[argh(switch, description = "show supported functions of this laptop")]
pub show_supported: bool,
#[argh(option, description = "set your battery charge limit <20-100>")]
pub chg_limit: Option<u8>,
#[argh(switch, description = "toggle one-shot battery charge to 100%")]
pub one_shot_chg: bool,
#[argh(subcommand)] #[argh(subcommand)]
pub command: Option<CliCommand>, pub command: CliCommand,
} }
/// Top-level subcommands for asusctl /// Top-level subcommands for asusctl
@@ -37,9 +29,16 @@ pub enum CliCommand {
Scsi(ScsiCommand), Scsi(ScsiCommand),
Armoury(ArmouryCommand), Armoury(ArmouryCommand),
Backlight(BacklightCommand), Backlight(BacklightCommand),
Battery(BatteryCommand),
Info(InfoCommand), Info(InfoCommand),
} }
impl Default for CliCommand {
fn default() -> Self {
CliCommand::Info(InfoCommand::default())
}
}
#[derive(FromArgs, Debug)] #[derive(FromArgs, Debug)]
#[argh(subcommand, name = "profile", description = "profile management")] #[argh(subcommand, name = "profile", description = "profile management")]
pub struct ProfileCommand { pub struct ProfileCommand {
@@ -195,13 +194,67 @@ pub struct BacklightCommand {
pub sync_screenpad_brightness: Option<bool>, pub sync_screenpad_brightness: Option<bool>,
} }
#[derive(FromArgs, Debug)]
#[argh(subcommand, name = "battery", description = "battery options")]
pub struct BatteryCommand {
#[argh(subcommand)]
pub command: BatterySubCommand,
}
#[derive(FromArgs, Debug)]
#[argh(subcommand)]
pub enum BatterySubCommand {
Limit(BatteryLimitCommand),
OneShot(BatteryOneShotCommand),
Info(BatteryInfoCommand),
}
impl Default for BatterySubCommand {
fn default() -> Self {
BatterySubCommand::OneShot(BatteryOneShotCommand::default())
}
}
#[derive(FromArgs, Debug)]
#[argh(
subcommand,
name = "limit",
description = "set battery charge limit <20-100>"
)]
pub struct BatteryLimitCommand {
#[argh(positional, description = "charge limit percentage 20-100")]
pub limit: u8,
}
#[derive(FromArgs, Debug, Default)]
#[argh(
subcommand,
name = "oneshot",
description = "one-shot full charge (optional percent)"
)]
pub struct BatteryOneShotCommand {
#[argh(positional, description = "optional target percent (defaults to 100)")]
pub percent: Option<u8>,
}
#[derive(FromArgs, Debug, Default)]
#[argh(
subcommand,
name = "info",
description = "show current battery charge limit"
)]
pub struct BatteryInfoCommand {}
#[derive(FromArgs, Debug, Default)] #[derive(FromArgs, Debug, Default)]
#[argh( #[argh(
subcommand, subcommand,
name = "info", name = "info",
description = "show program version and system info" description = "show program version and system info"
)] )]
pub struct InfoCommand {} pub struct InfoCommand {
#[argh(switch, description = "show supported functions of this laptop")]
pub show_supported: bool,
}
#[derive(FromArgs, Debug)] #[derive(FromArgs, Debug)]
#[argh(subcommand, name = "leds", description = "keyboard brightness control")] #[argh(subcommand, name = "leds", description = "keyboard brightness control")]

View File

@@ -187,64 +187,64 @@ fn do_parsed(
conn: Connection, conn: Connection,
) -> Result<(), Box<dyn std::error::Error>> { ) -> Result<(), Box<dyn std::error::Error>> {
match &parsed.command { match &parsed.command {
Some(CliCommand::Aura(mode)) => handle_led_mode(mode)?, CliCommand::Aura(mode) => handle_led_mode(mode)?,
Some(CliCommand::AuraPowerOld(pow)) => handle_led_power1(pow)?, CliCommand::AuraPowerOld(pow) => handle_led_power1(pow)?,
Some(CliCommand::AuraPower(pow)) => handle_led_power2(pow)?, CliCommand::AuraPower(pow) => handle_led_power2(pow)?,
Some(CliCommand::Brightness(cmd)) => handle_brightness(cmd)?, CliCommand::Brightness(cmd) => handle_brightness(cmd)?,
Some(CliCommand::Profile(cmd)) => { CliCommand::Profile(cmd) => handle_throttle_profile(&conn, supported_properties, cmd)?,
handle_throttle_profile(&conn, supported_properties, cmd)? CliCommand::FanCurve(cmd) => handle_fan_curve(&conn, cmd)?,
} CliCommand::Anime(cmd) => handle_anime(cmd)?,
Some(CliCommand::FanCurve(cmd)) => { CliCommand::Slash(cmd) => handle_slash(cmd)?,
handle_fan_curve(&conn, cmd)?; CliCommand::Scsi(cmd) => handle_scsi(cmd)?,
} CliCommand::Armoury(cmd) => handle_armoury_command(cmd)?,
Some(CliCommand::Anime(cmd)) => handle_anime(cmd)?, CliCommand::Backlight(cmd) => handle_backlight(cmd)?,
Some(CliCommand::Slash(cmd)) => handle_slash(cmd)?, CliCommand::Battery(cmd) => match &cmd.command {
Some(CliCommand::Scsi(cmd)) => handle_scsi(cmd)?, BatterySubCommand::Limit(l) => {
Some(CliCommand::Armoury(cmd)) => handle_armoury_command(cmd)?, let proxy = PlatformProxyBlocking::new(&conn)?;
Some(CliCommand::Backlight(cmd)) => handle_backlight(cmd)?, proxy.set_charge_control_end_threshold(l.limit)?;
Some(CliCommand::Info(_)) => { }
BatterySubCommand::OneShot(o) => {
let proxy = PlatformProxyBlocking::new(&conn)?;
if let Some(p) = o.percent {
proxy.set_charge_control_end_threshold(p)?;
}
proxy.one_shot_full_charge()?;
}
BatterySubCommand::Info(_) => {
let proxy = PlatformProxyBlocking::new(&conn)?;
let limit = proxy.charge_control_end_threshold()?;
println!("Current battery charge limit: {}%", limit);
}
},
CliCommand::Info(info_opt) => {
println!("asusctl v{}", env!("CARGO_PKG_VERSION")); println!("asusctl v{}", env!("CARGO_PKG_VERSION"));
println!(); println!();
print_info(); print_info();
} println!();
None => {
if !parsed.show_supported && parsed.chg_limit.is_none() && !parsed.one_shot_chg { if info_opt.show_supported {
println!("No command given. Run 'asusctl --help' for usage and 'asusctl <command> --help' for subcommands."); println!("Supported Core Functions:\n{:#?}", supported_interfaces);
println!(
"Supported Platform Properties:\n{:#?}",
supported_properties
);
if let Ok(aura) = find_iface::<AuraProxyBlocking>("xyz.ljones.Aura") {
// TODO: multiple RGB check
let bright = aura.first().unwrap().supported_brightness()?;
let modes = aura.first().unwrap().supported_basic_modes()?;
let zones = aura.first().unwrap().supported_basic_zones()?;
let power = aura.first().unwrap().supported_power_zones()?;
println!("Supported Keyboard Brightness:\n{:#?}", bright);
println!("Supported Aura Modes:\n{:#?}", modes);
println!("Supported Aura Zones:\n{:#?}", zones);
println!("Supported Aura Power Zones:\n{:#?}", power);
} else {
println!("No aura interface found");
}
} }
} }
} }
if parsed.show_supported {
println!("Supported Core Functions:\n{:#?}", supported_interfaces);
println!(
"Supported Platform Properties:\n{:#?}",
supported_properties
);
if let Ok(aura) = find_iface::<AuraProxyBlocking>("xyz.ljones.Aura") {
// TODO: multiple RGB check
let bright = aura.first().unwrap().supported_brightness()?;
let modes = aura.first().unwrap().supported_basic_modes()?;
let zones = aura.first().unwrap().supported_basic_zones()?;
let power = aura.first().unwrap().supported_power_zones()?;
println!("Supported Keyboard Brightness:\n{:#?}", bright);
println!("Supported Aura Modes:\n{:#?}", modes);
println!("Supported Aura Zones:\n{:#?}", zones);
println!("Supported Aura Power Zones:\n{:#?}", power);
} else {
println!("No aura interface found");
}
}
if let Some(chg_limit) = parsed.chg_limit {
let proxy = PlatformProxyBlocking::new(&conn)?;
proxy.set_charge_control_end_threshold(chg_limit)?;
}
if parsed.one_shot_chg {
let proxy = PlatformProxyBlocking::new(&conn)?;
proxy.one_shot_full_charge()?;
}
Ok(()) Ok(())
} }