diff --git a/asusctl/src/cli_opts.rs b/asusctl/src/cli_opts.rs index bbef427e..55687562 100644 --- a/asusctl/src/cli_opts.rs +++ b/asusctl/src/cli_opts.rs @@ -10,16 +10,8 @@ use crate::slash_cli::SlashCommand; #[derive(FromArgs, Default, Debug)] /// asusctl command-line options 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, - - #[argh(switch, description = "toggle one-shot battery charge to 100%")] - pub one_shot_chg: bool, - #[argh(subcommand)] - pub command: Option, + pub command: CliCommand, } /// Top-level subcommands for asusctl @@ -37,9 +29,16 @@ pub enum CliCommand { Scsi(ScsiCommand), Armoury(ArmouryCommand), Backlight(BacklightCommand), + Battery(BatteryCommand), Info(InfoCommand), } +impl Default for CliCommand { + fn default() -> Self { + CliCommand::Info(InfoCommand::default()) + } +} + #[derive(FromArgs, Debug)] #[argh(subcommand, name = "profile", description = "profile management")] pub struct ProfileCommand { @@ -195,13 +194,67 @@ pub struct BacklightCommand { pub sync_screenpad_brightness: Option, } +#[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, +} + +#[derive(FromArgs, Debug, Default)] +#[argh( + subcommand, + name = "info", + description = "show current battery charge limit" +)] +pub struct BatteryInfoCommand {} + #[derive(FromArgs, Debug, Default)] #[argh( subcommand, name = "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)] #[argh(subcommand, name = "leds", description = "keyboard brightness control")] diff --git a/asusctl/src/main.rs b/asusctl/src/main.rs index 31d2b856..10f1ae70 100644 --- a/asusctl/src/main.rs +++ b/asusctl/src/main.rs @@ -187,64 +187,64 @@ fn do_parsed( conn: Connection, ) -> Result<(), Box> { match &parsed.command { - Some(CliCommand::Aura(mode)) => handle_led_mode(mode)?, - Some(CliCommand::AuraPowerOld(pow)) => handle_led_power1(pow)?, - Some(CliCommand::AuraPower(pow)) => handle_led_power2(pow)?, - Some(CliCommand::Brightness(cmd)) => handle_brightness(cmd)?, - Some(CliCommand::Profile(cmd)) => { - handle_throttle_profile(&conn, supported_properties, cmd)? - } - Some(CliCommand::FanCurve(cmd)) => { - handle_fan_curve(&conn, cmd)?; - } - Some(CliCommand::Anime(cmd)) => handle_anime(cmd)?, - Some(CliCommand::Slash(cmd)) => handle_slash(cmd)?, - Some(CliCommand::Scsi(cmd)) => handle_scsi(cmd)?, - Some(CliCommand::Armoury(cmd)) => handle_armoury_command(cmd)?, - Some(CliCommand::Backlight(cmd)) => handle_backlight(cmd)?, - Some(CliCommand::Info(_)) => { + CliCommand::Aura(mode) => handle_led_mode(mode)?, + CliCommand::AuraPowerOld(pow) => handle_led_power1(pow)?, + CliCommand::AuraPower(pow) => handle_led_power2(pow)?, + CliCommand::Brightness(cmd) => handle_brightness(cmd)?, + CliCommand::Profile(cmd) => handle_throttle_profile(&conn, supported_properties, cmd)?, + CliCommand::FanCurve(cmd) => handle_fan_curve(&conn, cmd)?, + CliCommand::Anime(cmd) => handle_anime(cmd)?, + CliCommand::Slash(cmd) => handle_slash(cmd)?, + CliCommand::Scsi(cmd) => handle_scsi(cmd)?, + CliCommand::Armoury(cmd) => handle_armoury_command(cmd)?, + CliCommand::Backlight(cmd) => handle_backlight(cmd)?, + CliCommand::Battery(cmd) => match &cmd.command { + BatterySubCommand::Limit(l) => { + let proxy = PlatformProxyBlocking::new(&conn)?; + proxy.set_charge_control_end_threshold(l.limit)?; + } + 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!(); print_info(); - } - None => { - if !parsed.show_supported && parsed.chg_limit.is_none() && !parsed.one_shot_chg { - println!("No command given. Run 'asusctl --help' for usage and 'asusctl --help' for subcommands."); + println!(); + + if info_opt.show_supported { + println!("Supported Core Functions:\n{:#?}", supported_interfaces); + println!( + "Supported Platform Properties:\n{:#?}", + supported_properties + ); + if let Ok(aura) = find_iface::("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::("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(()) }