mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Refactor to prepare splitting out aura for CLI effects
This commit is contained in:
@@ -1,23 +1,7 @@
|
||||
use daemon::aura::{Key, KeyColourArray};
|
||||
use daemon::daemon::{DBUS_IFACE, DBUS_NAME, DBUS_PATH};
|
||||
use dbus::Error as DbusError;
|
||||
use dbus::{ffidisp::Connection, Message};
|
||||
use std::{thread, time};
|
||||
|
||||
pub fn dbus_led_builtin_write(bytes: &[u8]) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let bus = Connection::new_system()?;
|
||||
let msg = Message::new_method_call(DBUS_NAME, DBUS_PATH, DBUS_IFACE, "ledmessage")?
|
||||
.append1(bytes.to_vec());
|
||||
let r = bus.send_with_reply_and_block(msg, 5000)?;
|
||||
if let Some(reply) = r.get1::<&str>() {
|
||||
println!("Success: {:x?}", reply);
|
||||
return Ok(());
|
||||
}
|
||||
Err(Box::new(DbusError::new_custom("name", "message")))
|
||||
}
|
||||
use daemon::aura::{AuraDbusWriter, Key, KeyColourArray};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let bus = Connection::new_system()?;
|
||||
let writer = AuraDbusWriter::new()?;
|
||||
|
||||
let mut per_key_led = Vec::new();
|
||||
let mut key_colours = KeyColourArray::new();
|
||||
@@ -43,37 +27,13 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
per_key_led.push(key_colours.clone());
|
||||
}
|
||||
|
||||
// It takes each interrupt at least 1ms. 10ms to write complete block.
|
||||
let time = time::Duration::from_millis(10); // aim for 100 per second
|
||||
|
||||
let row = KeyColourArray::get_init_msg();
|
||||
let msg =
|
||||
Message::new_method_call(DBUS_NAME, DBUS_PATH, DBUS_IFACE, "ledmessage")?.append1(row);
|
||||
bus.send(msg).unwrap();
|
||||
|
||||
writer.init_effect()?;
|
||||
loop {
|
||||
let now = std::time::Instant::now();
|
||||
thread::sleep(time);
|
||||
|
||||
for group in &per_key_led {
|
||||
let group = group.get();
|
||||
let msg = Message::new_method_call(DBUS_NAME, DBUS_PATH, DBUS_IFACE, "ledeffect")?
|
||||
.append1(&group[0].to_vec())
|
||||
.append1(&group[1].to_vec())
|
||||
.append1(&group[2].to_vec())
|
||||
.append1(&group[3].to_vec())
|
||||
.append1(&group[4].to_vec())
|
||||
.append1(&group[5].to_vec())
|
||||
.append1(&group[6].to_vec())
|
||||
.append1(&group[7].to_vec())
|
||||
.append1(&group[8].to_vec())
|
||||
.append1(&group[9].to_vec());
|
||||
bus.send(msg).unwrap();
|
||||
thread::sleep(time);
|
||||
writer.write_colour_block(group)?;
|
||||
}
|
||||
let after = std::time::Instant::now();
|
||||
let diff = after.duration_since(now);
|
||||
dbg!(diff.as_millis());
|
||||
dbg!(std::time::Instant::now().duration_since(now).as_millis());
|
||||
//return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
91
src/aura.rs
91
src/aura.rs
@@ -1,5 +1,9 @@
|
||||
pub static DBUS_NAME: &'static str = "org.rogcore.Daemon";
|
||||
pub static DBUS_PATH: &'static str = "/org/rogcore/Daemon";
|
||||
pub static DBUS_IFACE: &'static str = "org.rogcore.Daemon";
|
||||
pub const LED_MSG_LEN: usize = 17;
|
||||
|
||||
use crate::cli_options::*;
|
||||
use crate::core::LED_MSG_LEN;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
/// Writes aout the correct byte string for brightness
|
||||
@@ -111,8 +115,8 @@ pub fn aura_brightness_bytes(brightness: u8) -> [u8; 17] {
|
||||
/// ```
|
||||
///
|
||||
/// This descriptor is also used for the per-key LED settings
|
||||
impl From<SetAuraBuiltin> for [u8; LED_MSG_LEN] {
|
||||
fn from(mode: SetAuraBuiltin) -> Self {
|
||||
impl From<&SetAuraBuiltin> for [u8; LED_MSG_LEN] {
|
||||
fn from(mode: &SetAuraBuiltin) -> Self {
|
||||
let mut msg = [0u8; LED_MSG_LEN];
|
||||
msg[0] = 0x5d;
|
||||
msg[1] = 0xb3;
|
||||
@@ -178,6 +182,12 @@ impl From<SetAuraBuiltin> for [u8; LED_MSG_LEN] {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SetAuraBuiltin> for [u8; LED_MSG_LEN] {
|
||||
fn from(mode: SetAuraBuiltin) -> Self {
|
||||
<[u8; LED_MSG_LEN]>::from(&mode)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SetAuraBuiltin> for [[u8; LED_MSG_LEN]; 4] {
|
||||
fn from(mode: SetAuraBuiltin) -> Self {
|
||||
let mut msg = [[0u8; LED_MSG_LEN]; 4];
|
||||
@@ -627,3 +637,78 @@ pub enum Key {
|
||||
Right,
|
||||
RFn,
|
||||
}
|
||||
|
||||
use dbus::{ffidisp::Connection, Message};
|
||||
use std::error::Error;
|
||||
use std::{thread, time::Duration};
|
||||
|
||||
/// Simplified way to write a effect block
|
||||
pub struct AuraDbusWriter {
|
||||
connection: Connection,
|
||||
block_time: u64,
|
||||
}
|
||||
|
||||
impl AuraDbusWriter {
|
||||
pub fn new() -> Result<Self, Box<dyn Error>> {
|
||||
Ok(AuraDbusWriter {
|
||||
connection: Connection::new_system()?,
|
||||
block_time: 10,
|
||||
})
|
||||
}
|
||||
|
||||
/// This method must always be called before the very first write to initialise
|
||||
/// the keyboard LED EC in the correct mode
|
||||
pub fn init_effect(&self) -> Result<(), Box<dyn Error>> {
|
||||
let msg = Message::new_method_call(DBUS_NAME, DBUS_PATH, DBUS_IFACE, "ledmessage")?
|
||||
.append1(KeyColourArray::get_init_msg());
|
||||
self.connection.send(msg).unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Write a single colour block.
|
||||
///
|
||||
/// Intentionally blocks for 10ms after sending to allow the block to
|
||||
/// be written to the keyboard EC. This should not be async.
|
||||
pub fn write_colour_block(
|
||||
&self,
|
||||
key_colour_array: &KeyColourArray,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let group = key_colour_array.get();
|
||||
let msg = Message::new_method_call(DBUS_NAME, DBUS_PATH, DBUS_IFACE, "ledeffect")?
|
||||
.append1(&group[0].to_vec())
|
||||
.append1(&group[1].to_vec())
|
||||
.append1(&group[2].to_vec())
|
||||
.append1(&group[3].to_vec())
|
||||
.append1(&group[4].to_vec())
|
||||
.append1(&group[5].to_vec())
|
||||
.append1(&group[6].to_vec())
|
||||
.append1(&group[7].to_vec())
|
||||
.append1(&group[8].to_vec())
|
||||
.append1(&group[9].to_vec());
|
||||
self.connection.send(msg).unwrap();
|
||||
thread::sleep(Duration::from_millis(self.block_time));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn write_bytes(&self, bytes: &[u8]) -> Result<String, Box<dyn std::error::Error>> {
|
||||
let msg = Message::new_method_call(DBUS_NAME, DBUS_PATH, DBUS_IFACE, "ledmessage")?
|
||||
.append1(bytes.to_vec());
|
||||
let r = self.connection.send_with_reply_and_block(msg, 5000)?;
|
||||
if let Some(reply) = r.get1::<&str>() {
|
||||
return Ok(reply.to_owned());
|
||||
}
|
||||
Err(Box::new(dbus::Error::new_custom("name", "message")))
|
||||
}
|
||||
|
||||
pub fn write_builtin_mode(
|
||||
&self,
|
||||
mode: &SetAuraBuiltin,
|
||||
) -> Result<String, Box<dyn std::error::Error>> {
|
||||
let bytes = <[u8; LED_MSG_LEN]>::from(mode);
|
||||
self.write_bytes(&bytes)
|
||||
}
|
||||
|
||||
pub fn write_brightness(&self, level: u8) -> Result<String, Box<dyn std::error::Error>> {
|
||||
self.write_bytes(&aura_brightness_bytes(level))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ impl FromStr for Colour {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum Speed {
|
||||
Low = 0xe1,
|
||||
Med = 0xeb,
|
||||
@@ -52,7 +52,7 @@ impl FromStr for Speed {
|
||||
/// Used for Rainbow mode.
|
||||
///
|
||||
/// Enum corresponds to the required integer value
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum Direction {
|
||||
Right,
|
||||
Left,
|
||||
|
||||
@@ -19,7 +19,6 @@ use std::ptr::NonNull;
|
||||
use std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
|
||||
pub const LED_MSG_LEN: usize = 17;
|
||||
static LED_INIT1: [u8; 2] = [0x5d, 0xb9];
|
||||
static LED_INIT2: &str = "]ASUS Tech.Inc."; // ] == 0x5d
|
||||
static LED_INIT3: [u8; 6] = [0x5d, 0x05, 0x20, 0x31, 0, 0x08];
|
||||
@@ -314,6 +313,7 @@ where
|
||||
|
||||
/// UNSAFE
|
||||
unsafe impl<'d, C> Send for LedWriter<'d, C> where C: rusb::UsbContext {}
|
||||
unsafe impl<'d, C> Sync for LedWriter<'d, C> where C: rusb::UsbContext {}
|
||||
|
||||
impl<'d, C> LedWriter<'d, C>
|
||||
where
|
||||
@@ -524,6 +524,7 @@ impl FromStr for LedBrightness {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum FanLevel {
|
||||
Normal,
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
pub static DBUS_NAME: &'static str = "org.rogcore.Daemon";
|
||||
pub static DBUS_PATH: &'static str = "/org/rogcore/Daemon";
|
||||
pub static DBUS_IFACE: &'static str = "org.rogcore.Daemon";
|
||||
|
||||
use crate::{config::Config, core::*, laptops::match_laptop};
|
||||
use crate::{aura::*, config::Config, core::*, laptops::match_laptop};
|
||||
use dbus::{
|
||||
nonblock::Process,
|
||||
tree::{Factory, MTSync, Method, MethodErr, Tree},
|
||||
@@ -83,7 +79,7 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
let led_writer1 = led_writer.clone();
|
||||
let config1 = config.clone();
|
||||
// start the keyboard reader and laptop-action loop
|
||||
tokio::task::spawn(async move {
|
||||
let key_read_handle = tokio::spawn(async move {
|
||||
loop {
|
||||
let data = keyboard_reader.poll_keyboard().await;
|
||||
if let Some(bytes) = data {
|
||||
@@ -97,6 +93,7 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
});
|
||||
|
||||
// start the LED writer loop
|
||||
let led_write_handle = tokio::spawn(async move {
|
||||
let mut time_mark = Instant::now();
|
||||
loop {
|
||||
connection.process_all();
|
||||
@@ -139,6 +136,11 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
std::thread::sleep(Duration::from_millis(50));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
led_write_handle.await?;
|
||||
key_read_handle.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn dbus_create_ledmsg_method(msg: LedMsgType) -> Method<MTSync, ()> {
|
||||
|
||||
31
src/main.rs
31
src/main.rs
@@ -1,11 +1,9 @@
|
||||
use daemon::{
|
||||
aura::aura_brightness_bytes,
|
||||
aura::{AuraDbusWriter, LED_MSG_LEN},
|
||||
cli_options::SetAuraBuiltin,
|
||||
core::{LedBrightness, LED_MSG_LEN},
|
||||
daemon::{start_daemon, DBUS_IFACE, DBUS_NAME, DBUS_PATH},
|
||||
core::LedBrightness,
|
||||
daemon::start_daemon,
|
||||
};
|
||||
use dbus::Error as DbusError;
|
||||
use dbus::{ffidisp::Connection, Message};
|
||||
use env_logger::{Builder, Target};
|
||||
use gumdrop::Options;
|
||||
use log::LevelFilter;
|
||||
@@ -55,6 +53,8 @@ pub async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("Version: {}", VERSION);
|
||||
}
|
||||
|
||||
let writer = AuraDbusWriter::new()?;
|
||||
|
||||
if let Some(Command::LedMode(mode)) = parsed.command {
|
||||
if let Some(command) = mode.command {
|
||||
// Check for special modes here, eg, per-key or multi-zone
|
||||
@@ -62,32 +62,17 @@ pub async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
SetAuraBuiltin::MultiStatic(_) => {
|
||||
let byte_arr = <[[u8; LED_MSG_LEN]; 4]>::from(command);
|
||||
for arr in byte_arr.iter() {
|
||||
dbus_led_builtin_write(arr)?;
|
||||
writer.write_bytes(arr)?;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let mode = <[u8; LED_MSG_LEN]>::from(command);
|
||||
dbus_led_builtin_write(&mode)?;
|
||||
writer.write_builtin_mode(&command)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(brightness) = parsed.bright {
|
||||
let bytes = aura_brightness_bytes(brightness.level());
|
||||
dbus_led_builtin_write(&bytes)?;
|
||||
writer.write_brightness(brightness.level())?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn dbus_led_builtin_write(bytes: &[u8]) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let bus = Connection::new_system()?;
|
||||
//let proxy = bus.with_proxy(DBUS_IFACE, "/", Duration::from_millis(5000));
|
||||
let msg = Message::new_method_call(DBUS_NAME, DBUS_PATH, DBUS_IFACE, "ledmessage")?
|
||||
.append1(bytes.to_vec());
|
||||
let r = bus.send_with_reply_and_block(msg, 5000)?;
|
||||
if let Some(reply) = r.get1::<&str>() {
|
||||
println!("Success: {:x?}", reply);
|
||||
return Ok(());
|
||||
}
|
||||
Err(Box::new(DbusError::new_custom("name", "message")))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user