Add extra models to ledmodes

- Configurable anime example
- Gfx power states as enum

Closes #72
This commit is contained in:
Luke D Jones
2021-03-29 19:36:30 +13:00
parent fbc248177a
commit 7ff01f12e9
52 changed files with 2983 additions and 564 deletions

View File

@@ -1,6 +1,6 @@
[package]
name = "asusctl"
version = "3.1.5"
version = "3.3.1"
authors = ["Luke D Jones <luke@ljones.dev>"]
edition = "2018"
@@ -9,13 +9,14 @@ edition = "2018"
[dependencies]
# serialisation
serde_json = "^1.0"
rog_anime = { path = "../rog-anime" }
rog_dbus = { path = "../rog-dbus" }
rog_types = { path = "../rog-types" }
daemon = { path = "../daemon" }
gumdrop = "^0.8"
yansi-term = "^0.1"
[dev-dependencies]
tinybmp = "^0.2.3"
glam = "*"
rog_dbus = { path = "../rog-dbus" }

View File

@@ -0,0 +1,26 @@
use rog_anime::{AniMeDataBuffer, AniMeGrid};
use rog_dbus::AuraDbusClient;
// In usable data:
// Top row start at 1, ends at 32
fn main() {
let (client, _) = AuraDbusClient::new().unwrap();
let mut matrix = AniMeGrid::new();
{
let tmp = matrix.get_mut();
for row in tmp.iter_mut() {
row[row.len() - 33] = 0xff;
row[row.len() - 22] = 0xff;
row[row.len() - 11] = 0xff;
row[row.len() - 1] = 0xff;
}
}
let matrix = <AniMeDataBuffer>::from(matrix);
client.proxies().anime().write(matrix).unwrap();
}

View File

@@ -0,0 +1,129 @@
use rog_anime::AniMeDataBuffer;
use rog_dbus::AuraDbusClient;
// In usable data:
// Top row start at 1, ends at 32
fn main() {
let (client, _) = AuraDbusClient::new().unwrap();
let mut matrix = AniMeDataBuffer::new();
matrix.get_mut()[1] = 100; // start = 1
for n in matrix.get_mut()[2..32].iter_mut() {
*n = 250;
}
matrix.get_mut()[32] = 100; // end
matrix.get_mut()[34] = 100; // start x = 0
matrix.get_mut()[66] = 100; // end
matrix.get_mut()[69] = 100; // start x = 1
matrix.get_mut()[101] = 100; // end
matrix.get_mut()[102] = 100; // start
matrix.get_mut()[134] = 100; // end
matrix.get_mut()[137] = 100; // start
matrix.get_mut()[169] = 100; // end
matrix.get_mut()[170] = 100; // start
matrix.get_mut()[202] = 100; // end
matrix.get_mut()[204] = 100; // start
matrix.get_mut()[236] = 100; // end
matrix.get_mut()[237] = 100; // start
matrix.get_mut()[268] = 100; // end
matrix.get_mut()[270] = 100; // start
matrix.get_mut()[301] = 100; // end
matrix.get_mut()[302] = 100; // start
matrix.get_mut()[332] = 100; // end
matrix.get_mut()[334] = 100; // start
matrix.get_mut()[364] = 100; // end
matrix.get_mut()[365] = 100; // start
matrix.get_mut()[394] = 100; // end
matrix.get_mut()[396] = 100; // start
matrix.get_mut()[425] = 100; // end
matrix.get_mut()[426] = 100; // start
matrix.get_mut()[454] = 100; // end
matrix.get_mut()[456] = 100; // start
matrix.get_mut()[484] = 100; // end
matrix.get_mut()[485] = 100; // start
matrix.get_mut()[512] = 100; // end
matrix.get_mut()[514] = 100; // start
matrix.get_mut()[541] = 100; // end
matrix.get_mut()[542] = 100; // start
matrix.get_mut()[568] = 100; // end
matrix.get_mut()[570] = 100; // start
matrix.get_mut()[596] = 100; // end
matrix.get_mut()[597] = 100; // start
matrix.get_mut()[622] = 100; // end
matrix.get_mut()[624] = 100; // start
matrix.get_mut()[649] = 100; // end
matrix.get_mut()[650] = 100; // start
matrix.get_mut()[674] = 100; // end
matrix.get_mut()[676] = 100; // start
matrix.get_mut()[700] = 100; // end
matrix.get_mut()[701] = 100; // start
matrix.get_mut()[724] = 100; // end
matrix.get_mut()[726] = 100; // start
matrix.get_mut()[749] = 100; // end
matrix.get_mut()[750] = 100; // start
matrix.get_mut()[772] = 100; // end
matrix.get_mut()[774] = 100; // start
matrix.get_mut()[796] = 100; // end
matrix.get_mut()[797] = 100; // start
matrix.get_mut()[818] = 100; // end
matrix.get_mut()[820] = 100; // start
matrix.get_mut()[841] = 100; // end
matrix.get_mut()[842] = 100; // start
matrix.get_mut()[862] = 100; // end
matrix.get_mut()[864] = 100; // start
matrix.get_mut()[884] = 100; // end
matrix.get_mut()[885] = 100; // start
matrix.get_mut()[904] = 100; // end
matrix.get_mut()[906] = 100; // start
matrix.get_mut()[925] = 100; // end
matrix.get_mut()[926] = 100; // start
matrix.get_mut()[944] = 100; // end
matrix.get_mut()[946] = 100; // start
matrix.get_mut()[964] = 100; // end
matrix.get_mut()[965] = 100; // start
matrix.get_mut()[982] = 100; // end
matrix.get_mut()[984] = 100; // start
matrix.get_mut()[1001] = 100; // end
matrix.get_mut()[1002] = 100; // start
matrix.get_mut()[1018] = 100; // end
matrix.get_mut()[1020] = 100; // start
matrix.get_mut()[1036] = 100; // end
matrix.get_mut()[1037] = 100; // start
matrix.get_mut()[1052] = 100; // end
matrix.get_mut()[1054] = 100; // start
matrix.get_mut()[1069] = 100; // end
matrix.get_mut()[1070] = 100; // start
matrix.get_mut()[1084] = 100; // end
matrix.get_mut()[1086] = 100; // start
matrix.get_mut()[1100] = 100; // end
matrix.get_mut()[1101] = 100; // start
matrix.get_mut()[1114] = 100; // end
matrix.get_mut()[1116] = 100; // start
matrix.get_mut()[1129] = 100; // end
matrix.get_mut()[1130] = 100; // start
matrix.get_mut()[1142] = 100; // end
matrix.get_mut()[1144] = 100; // start
matrix.get_mut()[1156] = 100; // end
matrix.get_mut()[1157] = 100; // start
matrix.get_mut()[1168] = 100; // end
matrix.get_mut()[1170] = 100; // start
matrix.get_mut()[1181] = 100; // end
matrix.get_mut()[1182] = 100; // start
matrix.get_mut()[1192] = 100; // end
matrix.get_mut()[1194] = 100; // start
matrix.get_mut()[1204] = 100; // end
matrix.get_mut()[1205] = 100; // start
matrix.get_mut()[1214] = 100; // end
matrix.get_mut()[1216] = 100; // start
matrix.get_mut()[1225] = 100; // end
matrix.get_mut()[1226] = 100; // start
matrix.get_mut()[1234] = 100; // end
matrix.get_mut()[1236] = 100; // start
for n in matrix.get_mut()[1237..1244].iter_mut() {
*n = 250;
}
matrix.get_mut()[1244] = 100; // end
println!("{:?}", &matrix);
client.proxies().anime().write(matrix).unwrap();
}

View File

@@ -0,0 +1,42 @@
use std::{env, error::Error, path::Path, process::exit};
use rog_anime::{
AniMeDataBuffer, {AnimeImage, Vec2},
};
use rog_dbus::AuraDbusClient;
fn main() -> Result<(), Box<dyn Error>> {
let (client, _) = AuraDbusClient::new().unwrap();
let args: Vec<String> = env::args().into_iter().collect();
if args.len() != 8 {
println!(
"Usage: <filepath> <x scale> <y scale> <angle> <x pos> <y pos> <fineness> <brightness>"
);
println!("e.g, asusctl/examples/doom_large.png 0.9 0.9 0.4 0.0 0.0, 0.8");
println!("All args except path and fineness are floats");
exit(-1);
}
let matrix = AnimeImage::from_png(
Path::new(&args[1]),
Vec2::new(
args[2].parse::<f32>().unwrap(),
args[3].parse::<f32>().unwrap(),
),
args[4].parse::<f32>().unwrap(),
Vec2::new(
args[5].parse::<f32>().unwrap(),
args[6].parse::<f32>().unwrap(),
),
args[7].parse::<f32>().unwrap(),
)?;
client
.proxies()
.anime()
.write(<AniMeDataBuffer>::from(&matrix))
.unwrap();
Ok(())
}

View File

@@ -0,0 +1,49 @@
use std::{
env, error::Error, f32::consts::PI, path::Path, process::exit, thread::sleep, time::Duration,
};
use rog_anime::{
AniMeDataBuffer, {AnimeImage, Vec2},
};
use rog_dbus::AuraDbusClient;
fn main() -> Result<(), Box<dyn Error>> {
let (client, _) = AuraDbusClient::new().unwrap();
let args: Vec<String> = env::args().into_iter().collect();
if args.len() != 8 {
println!("Usage: <filepath> <x scale> <y scale> <angle> <x pos> <y pos> <brightness>");
println!("e.g, asusctl/examples/doom_large.bmp 0.9 0.9 0.4 0.0 0.0, 0.8");
println!("All args except path and fineness are floats");
exit(-1);
}
let mut matrix = AnimeImage::from_png(
Path::new(&args[1]),
Vec2::new(
args[2].parse::<f32>().unwrap(),
args[3].parse::<f32>().unwrap(),
),
args[4].parse::<f32>().unwrap(),
Vec2::new(
args[5].parse::<f32>().unwrap(),
args[6].parse::<f32>().unwrap(),
),
args[7].parse::<f32>().unwrap(),
)?;
loop {
matrix.angle += 0.05;
if matrix.angle > PI * 2.0 {
matrix.angle = 0.0
}
matrix.update();
client
.proxies()
.anime()
.write(<AniMeDataBuffer>::from(&matrix))
.unwrap();
sleep(Duration::from_micros(500));
}
}

View File

@@ -1,44 +0,0 @@
use rog_dbus::AuraDbusClient;
use rog_types::anime_matrix::{AniMeImageBuffer, HEIGHT, WIDTH};
use tinybmp::{Bmp, Pixel};
fn main() {
let (client, _) = AuraDbusClient::new().unwrap();
let bmp = Bmp::from_slice(include_bytes!("rust.bmp")).expect("Failed to parse BMP image");
let pixels: Vec<Pixel> = bmp.into_iter().collect();
//assert_eq!(pixels.len(), 56 * 56);
// Try an outline, top and right
let mut matrix = AniMeImageBuffer::new();
// Aligned left
for (i, px) in pixels.iter().enumerate() {
if (px.x as usize / 2) < WIDTH && (px.y as usize) < HEIGHT && px.x % 2 == 0 {
let c = px.color as u32;
matrix.get_mut()[px.y as usize][px.x as usize / 2] = c as u8;
}
}
// Throw an alignment border up
{
let tmp = matrix.get_mut();
for x in tmp[0].iter_mut() {
*x = 0xff;
}
for (i, row) in tmp.iter_mut().enumerate() {
if i % 2 == 0 {
let l = row.len();
row[l - 1] = 0xff;
}
}
}
matrix.debug_print();
//let mut matrix: AniMePacketType = AniMePacketType::from(matrix);
// println!("{:?}", matrix[0].to_vec());
// println!("{:?}", matrix[1].to_vec());
client.proxies().anime().write_image(matrix).unwrap();
}

BIN
asusctl/examples/doom.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

BIN
asusctl/examples/ferris.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

BIN
asusctl/examples/nudoom.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

View File

@@ -10,7 +10,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
loop {
let count = 49;
for _ in 0..count {
*key_colours.key(Key::ROG).unwrap().0 += 5;
*key_colours.key(Key::Rog).unwrap().0 += 5;
*key_colours.key(Key::L).unwrap().0 += 5;
*key_colours.key(Key::I).unwrap().0 += 5;
*key_colours.key(Key::N).unwrap().0 += 5;
@@ -19,7 +19,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
dbus.proxies().led().set_per_key(&key_colours)?;
}
for _ in 0..count {
*key_colours.key(Key::ROG).unwrap().0 -= 5;
*key_colours.key(Key::Rog).unwrap().0 -= 5;
*key_colours.key(Key::L).unwrap().0 -= 5;
*key_colours.key(Key::I).unwrap().0 -= 5;
*key_colours.key(Key::N).unwrap().0 -= 5;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

BIN
asusctl/examples/rust.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

94
asusctl/src/anime_cli.rs Normal file
View File

@@ -0,0 +1,94 @@
use gumdrop::Options;
use rog_types::error::AuraError;
use std::str::FromStr;
#[derive(Copy, Clone, Debug)]
pub enum AniMeStatusValue {
On,
Off,
}
impl FromStr for AniMeStatusValue {
type Err = AuraError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let s = s.to_lowercase();
match s.as_str() {
"on" => Ok(AniMeStatusValue::On),
"off" => Ok(AniMeStatusValue::Off),
_ => {
print!("Invalid argument, must be one of: on, off");
Err(AuraError::ParseAnime)
}
}
}
}
impl From<AniMeStatusValue> for bool {
fn from(value: AniMeStatusValue) -> Self {
match value {
AniMeStatusValue::On => true,
AniMeStatusValue::Off => false,
}
}
}
#[derive(Options)]
pub struct AniMeLeds {
#[options(help = "print help message")]
help: bool,
#[options(
no_long,
required,
short = "b",
meta = "",
help = "set all leds brightness value"
)]
led_brightness: u8,
}
impl AniMeLeds {
pub fn led_brightness(&self) -> u8 {
self.led_brightness
}
}
#[derive(Options)]
pub struct AniMeCommand {
#[options(help = "print help message")]
pub help: bool,
#[options(
meta = "",
help = "turn on/off the panel (accept/reject write requests)"
)]
pub turn: Option<AniMeStatusValue>,
#[options(meta = "", help = "turn on/off the panel at boot (with Asus effect)")]
pub boot: Option<AniMeStatusValue>,
#[options(command)]
pub command: Option<AniMeActions>,
}
#[derive(Options)]
pub enum AniMeActions {
#[options(help = "change all leds brightness")]
Leds(AniMeLeds),
#[options(help = "display an 8bit greyscale png")]
Image(AniMeImage),
}
#[derive(Options)]
pub struct AniMeImage {
#[options(help = "print help message")]
pub help: bool,
#[options(meta = "", help = "full path to the png to display")]
pub path: String,
#[options(meta = "", default = "0.0", help = "x scale 0.0-1.0")]
pub x_scale: f32,
#[options(meta = "", default = "0.0", help = "y scale 0.0-1.0")]
pub y_scale: f32,
#[options(meta = "", default = "0.0", help = "x position (float)")]
pub x_pos: f32,
#[options(meta = "", default = "0.0", help = "y position (float)")]
pub y_pos: f32,
#[options(meta = "", default = "0.0", help = "the angle in radians")]
pub angle: f32,
#[options(meta = "", default = "1.0", help = "brightness 0.0-1.0")]
pub bright: f32,
}

View File

@@ -1,25 +1,29 @@
mod anime_cli;
mod aura_cli;
use crate::aura_cli::{LedBrightness, SetAuraBuiltin};
use anime_cli::{AniMeActions, AniMeCommand};
use daemon::{
ctrl_fan_cpu::FanCpuSupportedFunctions, ctrl_leds::LedSupportedFunctions,
ctrl_rog_bios::RogBiosSupportedFunctions, ctrl_supported::SupportedFunctions,
};
use gumdrop::{Opt, Options};
use rog_anime::{
AniMeDataBuffer, ANIME_DATA_LEN,
AnimeImage, Vec2,
};
use rog_dbus::AuraDbusClient;
use rog_types::{
anime_matrix::{AniMeDataBuffer, FULL_PANE_LEN},
aura_modes::{self, AuraEffect, AuraModeNum},
cli_options::{AniMeActions, AniMeStatusValue},
gfx_vendors::GfxVendors,
profile::{FanLevel, ProfileCommand, ProfileEvent},
};
use std::env::args;
use std::{env::args, path::Path};
use yansi_term::Colour::Green;
use yansi_term::Colour::Red;
#[derive(Default, Options)]
struct CLIStart {
struct CliStart {
#[options(help_flag, help = "print help message")]
help: bool,
#[options(help = "show program version number")]
@@ -82,21 +86,6 @@ struct GraphicsCommand {
force: bool,
}
#[derive(Options)]
struct AniMeCommand {
#[options(help = "print help message")]
help: bool,
#[options(
meta = "",
help = "turn on/off the panel (accept/reject write requests)"
)]
turn: Option<AniMeStatusValue>,
#[options(meta = "", help = "turn on/off the panel at boot (with Asus effect)")]
boot: Option<AniMeStatusValue>,
#[options(command)]
command: Option<AniMeActions>,
}
#[derive(Options, Debug)]
struct BiosCommand {
#[options(help = "print help message")]
@@ -118,14 +107,14 @@ struct BiosCommand {
fn main() -> Result<(), Box<dyn std::error::Error>> {
let args: Vec<String> = args().skip(1).collect();
let parsed: CLIStart;
let parsed: CliStart;
let missing_argument_k = gumdrop::Error::missing_argument(Opt::Short('k'));
match CLIStart::parse_args_default(&args) {
match CliStart::parse_args_default(&args) {
Ok(p) => {
parsed = p;
}
Err(err) if err.to_string() == missing_argument_k.to_string() => {
parsed = CLIStart {
parsed = CliStart {
kbd_bright: Some(LedBrightness::new(None)),
..Default::default()
};
@@ -175,9 +164,32 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
if let Some(action) = cmd.command {
match action {
AniMeActions::Leds(anime_leds) => {
let mut data = AniMeDataBuffer::new();
data.set([anime_leds.led_brightness(); FULL_PANE_LEN]);
dbus.proxies().anime().write_direct(data)?;
let data = AniMeDataBuffer::from_vec(
[anime_leds.led_brightness(); ANIME_DATA_LEN].to_vec(),
);
dbus.proxies().anime().write(data)?;
}
AniMeActions::Image(image) => {
if image.help_requested() {
println!("Missing arg or command\n\n{}", image.self_usage());
if let Some(lst) = image.self_command_list() {
println!("\n{}", lst);
}
std::process::exit(1);
}
let matrix = AnimeImage::from_png(
Path::new(&image.path),
Vec2::new(image.x_scale, image.y_scale),
image.angle,
Vec2::new(image.x_pos, image.y_pos),
image.bright,
)?;
dbus.proxies()
.anime()
.write(<AniMeDataBuffer>::from(&matrix))
.unwrap();
}
}
}
@@ -190,9 +202,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
&& parsed.chg_limit.is_none())
|| parsed.help
{
println!("{}", CLIStart::usage());
println!("{}", CliStart::usage());
println!();
println!("{}", CLIStart::command_list().unwrap());
println!("{}", CliStart::command_list().unwrap());
}
}
}
@@ -224,7 +236,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}
fn print_supported_help(supported: &SupportedFunctions, parsed: &CLIStart) {
fn print_supported_help(supported: &SupportedFunctions, parsed: &CliStart) {
// As help option don't work with `parse_args_default`
// we will call `parse_args_default_or_exit` instead
let usage: Vec<String> = parsed.self_usage().lines().map(|s| s.to_string()).collect();
@@ -311,10 +323,11 @@ fn do_gfx(
}
if command.pow {
let res = dbus.proxies().gfx().gfx_get_pwr()?;
if res.contains("active") {
println!("Current power status: {}", Red.paint(&res));
} else {
println!("Current power status: {}", Green.paint(&res));
match res {
rog_types::gfx_vendors::GfxPower::Active => {
println!("Current power status: {}", Red.paint(<&str>::from(&res)))
}
_ => println!("Current power status: {}", Green.paint(<&str>::from(&res))),
}
}
Ok(())