diff --git a/asus-nb-ctrl/src/ctrl_anime.rs b/asus-nb-ctrl/src/ctrl_anime.rs index c54d0595..9aa36d02 100644 --- a/asus-nb-ctrl/src/ctrl_anime.rs +++ b/asus-nb-ctrl/src/ctrl_anime.rs @@ -9,6 +9,10 @@ const INIT: u8 = 0xc2; const APPLY: u8 = 0xc3; const SET: u8 = 0xc4; +// Used to turn the panel on and off +// The next byte can be 0x03 for "on" and 0x00 for "off" +const ON_OFF : u8 = 0x04; + use asus_nb::error::AuraError; use log::{error, info, warn}; use rusb::{Device, DeviceHandle}; @@ -22,6 +26,7 @@ use zbus::dbus_interface; pub enum AnimatrixCommand { Apply, Set, + Write(Vec), WriteImage(Vec>), //ReloadLast, } @@ -34,6 +39,8 @@ pub struct CtrlAnimeDisplay { //AnimatrixWrite pub trait Dbus { fn set_anime(&mut self, input: Vec>); + + fn set_on_off(&mut self, status: bool); } impl crate::ZbusAdd for CtrlAnimeDisplay { @@ -54,6 +61,26 @@ impl Dbus for CtrlAnimeDisplay { self.do_command(AnimatrixCommand::WriteImage(input)) .unwrap_or_else(|err| warn!("{}", err)); } + + fn set_on_off(&mut self, status: bool) { + let mut activity : Vec = vec![0; PACKET_SIZE]; + activity[0] = DEV_PAGE; + activity[1] = WRITE; + activity[2] = ON_OFF; + + let status_str; + if status { + activity[3] = 0x03; + status_str = "on"; + } else { + activity[3] = 0x00; + status_str = "off"; + } + info!("Turning {} the AniMe", status_str); + + self.do_command(AnimatrixCommand::Write(activity)) + .unwrap_or_else(|err| warn!("{}", err)); + } } impl CtrlAnimeDisplay { @@ -99,9 +126,10 @@ impl CtrlAnimeDisplay { } match command { - AnimatrixCommand::WriteImage(effect) => self.write_image(effect)?, - AnimatrixCommand::Set => self.do_set()?, AnimatrixCommand::Apply => self.do_apply()?, + AnimatrixCommand::Set => self.do_set()?, + AnimatrixCommand::Write(bytes) => self.write_bytes(&bytes)?, + AnimatrixCommand::WriteImage(effect) => self.write_image(effect)?, //AnimatrixCommand::ReloadLast => self.reload_last_builtin(&config).await?, } Ok(()) diff --git a/asus-nb-ctrl/src/main.rs b/asus-nb-ctrl/src/main.rs index 84a8f7c1..f6e00f66 100644 --- a/asus-nb-ctrl/src/main.rs +++ b/asus-nb-ctrl/src/main.rs @@ -1,5 +1,9 @@ use asus_nb::{ - cli_options::{LedBrightness, SetAuraBuiltin, AniMeActions}, + cli_options::{ + LedBrightness, + SetAuraBuiltin, + AniMeActions, + }, core_dbus::AuraDbusClient, anime_dbus::AniMeDbusWriter, profile::{ProfileCommand, ProfileEvent}, @@ -63,11 +67,17 @@ struct GraphicsCommand { force: bool, } -#[derive(Debug, Options)] +#[derive(Options)] struct AniMeCommand { #[options(help = "print help message")] help: bool, - #[options(command, required)] + #[options(help = "turn on the panel (and accept write requests)", + no_short)] + on: bool, + #[options(help = "turn off the panel (and reject write requests)", + no_short)] + off: bool, + #[options(command)] command: Option, } @@ -86,7 +96,7 @@ fn main() -> Result<(), Box> { } let writer = AuraDbusClient::new()?; - let anime = AniMeDbusWriter::new()?; + let anime_writer = AniMeDbusWriter::new()?; match parsed.command { Some(CliCommand::LedMode(mode)) => { @@ -98,14 +108,21 @@ fn main() -> Result<(), Box> { writer.write_profile_command(&ProfileEvent::Cli(command))? } Some(CliCommand::Graphics(command)) => do_gfx(command, &writer)?, - Some(CliCommand::AniMe( - AniMeCommand { - command: Some(AniMeActions::Leds(anime_leds)), .. - })) => { - anime.set_leds_brightness(anime_leds.led_brightness())?; - }, - Some(CliCommand::AniMe(_)) - | None => (), + Some(CliCommand::AniMe(anime)) => { + if anime.on { + anime_writer.turn_on()?; + } else if anime.off { + anime_writer.turn_off()?; + } else if let Some(action) = anime.command { + match action { + AniMeActions::Leds(anime_leds) => { + let led_brightness = anime_leds.led_brightness(); + anime_writer.set_leds_brightness(led_brightness)?; + } + } + } + } + None => () } if let Some(brightness) = parsed.kbd_bright { diff --git a/asus-nb/src/anime_dbus.rs b/asus-nb/src/anime_dbus.rs index cdf74cb9..e1534404 100644 --- a/asus-nb/src/anime_dbus.rs +++ b/asus-nb/src/anime_dbus.rs @@ -6,7 +6,7 @@ pub const ANIME_PANE2_PREFIX: [u8; 7] = use crate::anime_matrix::{AniMeMatrix, AniMePacketType}; use crate::DBUS_NAME; -use dbus::blocking::Connection; +use dbus::blocking::{Connection, Proxy}; use std::error::Error; use std::{thread, time::Duration}; @@ -37,20 +37,13 @@ impl AniMeDbusWriter { }) } - /// Create D-Bus proxy and send the message - #[inline] - fn write_anime(&self, input: Vec>) - -> Result<(), Box> { - let proxy = self.connection.with_proxy( + // Create D-Bus proxy + fn new_proxy(&self) -> Proxy<&Connection>{ + self.connection.with_proxy( DBUS_NAME, DBUS_ANIME_PATH, Duration::from_millis(200), - ); - - proxy.set_anime(input)?; - thread::sleep(Duration::from_millis(self.block_time)); - - Ok(()) + ) } pub fn write_image_to_buf(_buf: &mut AniMePacketType, _image_data: &[u8]) { @@ -75,9 +68,14 @@ impl AniMeDbusWriter { #[inline] pub fn write_image(&self, image: &mut AniMePacketType) -> Result<(), Box> { + let proxy = self.new_proxy(); + image[0][..7].copy_from_slice(&ANIME_PANE1_PREFIX); image[1][..7].copy_from_slice(&ANIME_PANE2_PREFIX); - self.write_anime(vec![image[0].to_vec(), image[1].to_vec()])?; + + proxy.set_anime(vec![image[0].to_vec(), image[1].to_vec()])?; + thread::sleep(Duration::from_millis(self.block_time)); + Ok(()) } @@ -88,6 +86,28 @@ impl AniMeDbusWriter { anime_matrix.fill_with(led_brightness); self.write_image(&mut AniMePacketType::from(anime_matrix))?; + + Ok(()) + } + + fn turn_on_off(&self, status : bool) -> Result<(), Box> { + let proxy = self.new_proxy(); + + proxy.set_on_off(status)?; + thread::sleep(Duration::from_millis(self.block_time)); + + Ok(()) + } + + #[inline] + pub fn turn_on(&self) -> Result<(), Box> { + self.turn_on_off(true)?; + Ok(()) + } + + #[inline] + pub fn turn_off(&self) -> Result<(), Box> { + self.turn_on_off(false)?; Ok(()) } } diff --git a/asus-nb/src/cli_options.rs b/asus-nb/src/cli_options.rs index d1b175ad..ca7672c6 100644 --- a/asus-nb/src/cli_options.rs +++ b/asus-nb/src/cli_options.rs @@ -214,8 +214,7 @@ impl Default for SetAuraBuiltin { } } - -#[derive(Debug, Options)] +#[derive(Options)] pub struct AniMeLeds { #[options(help = "print help message")] help: bool, @@ -231,8 +230,8 @@ impl AniMeLeds { } } -#[derive(Debug, Options)] +#[derive(Options)] pub enum AniMeActions { #[options(help = "change all leds brightness")] - Leds(AniMeLeds) + Leds(AniMeLeds), } diff --git a/asus-nb/src/dbus_anime.rs b/asus-nb/src/dbus_anime.rs index a7b655ba..0fe3b015 100644 --- a/asus-nb/src/dbus_anime.rs +++ b/asus-nb/src/dbus_anime.rs @@ -6,6 +6,7 @@ use dbus::blocking; pub trait OrgAsuslinuxDaemon { fn set_anime(&self, input: Vec>) -> Result<(), dbus::Error>; + fn set_on_off(&self, status: bool) -> Result<(), dbus::Error>; } impl<'a, T: blocking::BlockingSender, C: ::std::ops::Deref> OrgAsuslinuxDaemon for blocking::Proxy<'a, C> { @@ -13,4 +14,8 @@ impl<'a, T: blocking::BlockingSender, C: ::std::ops::Deref> OrgAsuslin fn set_anime(&self, input: Vec>) -> Result<(), dbus::Error> { self.method_call("org.asuslinux.Daemon", "SetAnime", (input, )) } + + fn set_on_off(&self, status: bool) -> Result<(), dbus::Error> { + self.method_call("org.asuslinux.Daemon", "SetOnOff", (status, )) + } }