Adding Anime commands to asusctl

This commit is contained in:
Luke Jones
2020-10-11 22:46:06 +00:00
6 changed files with 111 additions and 36 deletions

View File

@@ -1,6 +1,7 @@
use asus_nb::{ use asus_nb::{
cli_options::{LedBrightness, SetAuraBuiltin}, cli_options::{LedBrightness, SetAuraBuiltin, AniMeActions},
core_dbus::AuraDbusClient, core_dbus::AuraDbusClient,
anime_dbus::AniMeDbusWriter,
profile::{ProfileCommand, ProfileEvent}, profile::{ProfileCommand, ProfileEvent},
}; };
use ctrl_gfx::vendors::GfxVendors; use ctrl_gfx::vendors::GfxVendors;
@@ -36,6 +37,8 @@ enum CliCommand {
Profile(ProfileCommand), Profile(ProfileCommand),
#[options(help = "Set the graphics mode")] #[options(help = "Set the graphics mode")]
Graphics(GraphicsCommand), Graphics(GraphicsCommand),
#[options(name = "anime", help = "Manage AniMe Matrix")]
AniMe(AniMeCommand),
} }
#[derive(Options)] #[derive(Options)]
@@ -60,6 +63,14 @@ struct GraphicsCommand {
force: bool, force: bool,
} }
#[derive(Debug, Options)]
struct AniMeCommand {
#[options(help = "print help message")]
help: bool,
#[options(command, required)]
command: Option<AniMeActions>,
}
fn main() -> Result<(), Box<dyn std::error::Error>> { fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut logger = env_logger::Builder::new(); let mut logger = env_logger::Builder::new();
logger logger
@@ -75,6 +86,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
} }
let writer = AuraDbusClient::new()?; let writer = AuraDbusClient::new()?;
let anime = AniMeDbusWriter::new()?;
match parsed.command { match parsed.command {
Some(CliCommand::LedMode(mode)) => { Some(CliCommand::LedMode(mode)) => {
@@ -86,7 +98,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
writer.write_profile_command(&ProfileEvent::Cli(command))? writer.write_profile_command(&ProfileEvent::Cli(command))?
} }
Some(CliCommand::Graphics(command)) => do_gfx(command, &writer)?, Some(CliCommand::Graphics(command)) => do_gfx(command, &writer)?,
None => (), Some(CliCommand::AniMe(
AniMeCommand {
command: Some(AniMeActions::Leds(anime_leds)), ..
})) => {
anime.set_leds_brightness(anime_leds.led_brightness())?;
},
Some(CliCommand::AniMe(_))
| None => (),
} }
if let Some(brightness) = parsed.kbd_bright { if let Some(brightness) = parsed.kbd_bright {

View File

@@ -1,16 +1,18 @@
use crate::anime_matrix::AniMePacketType; const DBUS_ANIME_PATH : &str = "/org/asuslinux/Anime";
use crate::{DBUS_IFACE, DBUS_NAME}; pub const ANIME_PANE1_PREFIX: [u8; 7] =
use dbus::channel::Sender; [0x5e, 0xc0, 0x02, 0x01, 0x00, 0x73, 0x02];
use dbus::{blocking::Connection, Message}; pub const ANIME_PANE2_PREFIX: [u8; 7] =
[0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02];
use crate::anime_matrix::{AniMeMatrix, AniMePacketType};
use crate::DBUS_NAME;
use dbus::blocking::Connection;
use std::error::Error; use std::error::Error;
use std::sync::{
atomic::{AtomicBool, Ordering},
Arc,
};
use std::{thread, time::Duration}; use std::{thread, time::Duration};
pub const ANIME_PANE1_PREFIX: [u8; 7] = [0x5e, 0xc0, 0x02, 0x01, 0x00, 0x73, 0x02]; use crate::dbus_anime::{
pub const ANIME_PANE2_PREFIX: [u8; 7] = [0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02]; OrgAsuslinuxDaemon as OrgAsuslinuxDaemonAniMe,
};
/// Interface for the AniMe dot-matrix display /// Interface for the AniMe dot-matrix display
/// ///
@@ -23,7 +25,6 @@ pub const ANIME_PANE2_PREFIX: [u8; 7] = [0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x0
pub struct AniMeDbusWriter { pub struct AniMeDbusWriter {
connection: Box<Connection>, connection: Box<Connection>,
block_time: u64, block_time: u64,
stop: Arc<AtomicBool>,
} }
impl AniMeDbusWriter { impl AniMeDbusWriter {
@@ -33,47 +34,60 @@ impl AniMeDbusWriter {
Ok(AniMeDbusWriter { Ok(AniMeDbusWriter {
connection: Box::new(connection), connection: Box::new(connection),
block_time: 25, block_time: 25,
stop: Arc::new(AtomicBool::new(false)),
}) })
} }
/// Create D-Bus proxy and send the message
#[inline]
fn write_anime(&self, input: Vec<Vec<u8>>)
-> Result<(), Box<dyn Error>> {
let proxy = 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]) { pub fn write_image_to_buf(_buf: &mut AniMePacketType, _image_data: &[u8]) {
unimplemented!("Image format is in progress of being worked out") unimplemented!("Image format is in progress of being worked out")
} }
/// Write an Animatrix image /// Write an Animatrix image
/// ///
/// The expected input here is *two* Vectors, 640 bytes in length. The two vectors /// The expected input here is *two* Vectors, 640 bytes in length.
/// are each one half of the full image write. /// The two vectors are each one half of the full image write.
/// ///
/// After each write a flush is written, it is assumed that this tells the device to /// After each write a flush is written, it is assumed that this tells the
/// go ahead and display the written bytes /// device to go ahead and display the written bytes
/// ///
/// # Note: /// # Note: The vectors are expected to contain the full sequence of bytes
/// The vectors are expected to contain the full sequence of bytes as follows /// as follows
/// ///
/// - Write packet 1: 0x5e 0xc0 0x02 0x01 0x00 0x73 0x02 .. <led brightness> /// - Write packet 1: 0x5e 0xc0 0x02 0x01 0x00 0x73 0x02 .. <led brightness>
/// - Write packet 2: 0x5e 0xc0 0x02 0x74 0x02 0x73 0x02 .. <led brightness> /// - Write packet 2: 0x5e 0xc0 0x02 0x74 0x02 0x73 0x02 .. <led brightness>
/// ///
/// Where led brightness is 0..255, low to high /// Where led brightness is 0..255, low to high
#[inline] #[inline]
pub fn write_image(&mut self, image: &mut AniMePacketType) -> Result<(), Box<dyn Error>> { pub fn write_image(&self, image: &mut AniMePacketType)
if image[0][0] != ANIME_PANE1_PREFIX[0] && image[0][6] != ANIME_PANE1_PREFIX[6] { -> Result<(), Box<dyn Error>> {
image[0][..7].copy_from_slice(&ANIME_PANE1_PREFIX); image[0][..7].copy_from_slice(&ANIME_PANE1_PREFIX);
} image[1][..7].copy_from_slice(&ANIME_PANE2_PREFIX);
if image[1][0] != ANIME_PANE2_PREFIX[0] && image[1][6] != ANIME_PANE2_PREFIX[6] { self.write_anime(vec![image[0].to_vec(), image[1].to_vec()])?;
image[1][..7].copy_from_slice(&ANIME_PANE2_PREFIX); Ok(())
} }
let mut msg = #[inline]
Message::new_method_call(DBUS_NAME, "/org/asuslinux/Anime", DBUS_IFACE, "SetAnime")? pub fn set_leds_brightness(&self, led_brightness: u8)
.append2(image[0].to_vec(), image[1].to_vec()); -> Result<(), Box<dyn Error>> {
msg.set_no_reply(true); let mut anime_matrix = AniMeMatrix::new();
self.connection.send(msg).unwrap();
thread::sleep(Duration::from_millis(self.block_time)); anime_matrix.fill_with(led_brightness);
if self.stop.load(Ordering::Relaxed) { self.write_image(&mut AniMePacketType::from(anime_matrix))?;
panic!("Got signal to stop!");
}
Ok(()) Ok(())
} }
} }

View File

@@ -213,3 +213,26 @@ impl Default for SetAuraBuiltin {
}) })
} }
} }
#[derive(Debug, Options)]
pub struct AniMeLeds {
#[options(help = "print help message")]
help: bool,
#[options(no_long, required,
short = "b", meta = "BYTE",
help = "set all leds brightness value")]
led_brightness: u8,
}
impl AniMeLeds {
pub fn led_brightness(&self) -> u8 {
self.led_brightness
}
}
#[derive(Debug, Options)]
pub enum AniMeActions {
#[options(help = "change all leds brightness")]
Leds(AniMeLeds)
}

16
asus-nb/src/dbus_anime.rs Normal file
View File

@@ -0,0 +1,16 @@
// This code was autogenerated with `dbus-codegen-rust -s -d org.asuslinux.Daemon -p /org/asuslinux/Anime -m None -f org.asuslinux.Daemon -c blocking`, see https://github.com/diwic/dbus-rs
use dbus as dbus;
#[allow(unused_imports)]
use dbus::arg;
use dbus::blocking;
pub trait OrgAsuslinuxDaemon {
fn set_anime(&self, input: Vec<Vec<u8>>) -> Result<(), dbus::Error>;
}
impl<'a, T: blocking::BlockingSender, C: ::std::ops::Deref<Target=T>> OrgAsuslinuxDaemon for blocking::Proxy<'a, C> {
fn set_anime(&self, input: Vec<Vec<u8>>) -> Result<(), dbus::Error> {
self.method_call("org.asuslinux.Daemon", "SetAnime", (input, ))
}
}

View File

@@ -7,6 +7,7 @@ pub enum AuraError {
ParseSpeed, ParseSpeed,
ParseDirection, ParseDirection,
ParseBrightness, ParseBrightness,
ParseAnime,
} }
impl fmt::Display for AuraError { impl fmt::Display for AuraError {
@@ -17,6 +18,7 @@ impl fmt::Display for AuraError {
AuraError::ParseSpeed => write!(f, "Could not parse speed"), AuraError::ParseSpeed => write!(f, "Could not parse speed"),
AuraError::ParseDirection => write!(f, "Could not parse direction"), AuraError::ParseDirection => write!(f, "Could not parse direction"),
AuraError::ParseBrightness => write!(f, "Could not parse brightness"), AuraError::ParseBrightness => write!(f, "Could not parse brightness"),
AuraError::ParseAnime => write!(f, "Could not parse anime"),
} }
} }
} }

View File

@@ -27,6 +27,7 @@ pub mod dbus_gfx;
pub mod dbus_ledmode; pub mod dbus_ledmode;
pub mod dbus_profile; pub mod dbus_profile;
pub mod dbus_charge; pub mod dbus_charge;
pub mod dbus_anime;
pub mod error; pub mod error;