Skip to content

Commit

Permalink
Add wave effect
Browse files Browse the repository at this point in the history
  • Loading branch information
R1tschY committed Dec 19, 2020
1 parent 90b5d54 commit 70ab74c
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 9 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ hex = "^0.4.2"
structopt = "^0.2.10"
dbus = "^0.8.2"
log = "^0.4.8"
simple_logger = { version="^1.6.0", default_features=false }
simple_logger = { version = "^1.6.0", default_features = false }
rust-ini = "^0.15"
quick-error = "^1.2.3"
53 changes: 49 additions & 4 deletions src/bin/g213ctl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,29 @@ enum Cli {
/// Hex string for color
color: String,
/// sector index
sector: u8,
sector: Option<u8>,
},
/* Breathe {
/// Apply breathe effect
Breathe {
/// Hex string for color
color: String,
/// speed inverse (must be greater than 31; default is 1000)
speed: u16,
},
/// Apply cycle effect
Cycle {
/// speed inverse (must be greater than 31; default is 1000)
speed: u16,
},
/// Apply wave effect
Wave {
/// direction of effect (left-to-right, right-to-left, center-to-edge, edge-to-center;
/// default is left-to-right)
direction: String,
/// speed inverse (must be greater than 31, default is 1000)
speed: u16,
},*/
},
/// Reapply saved effect
Refresh,
}

Expand All @@ -39,13 +53,44 @@ fn main() -> std::result::Result<(), Box<dyn Error>> {
);

match Cli::from_args() {
Cli::Color { color, sector } => {
Cli::Color {
color,
sector: Some(sector),
} => {
devices.method_call(
"de.richardliebscher.g213d.GDeviceManager",
"color_sector",
(&color as &str, sector),
)?;
}
Cli::Color { color, sector: _ } => {
devices.method_call(
"de.richardliebscher.g213d.GDeviceManager",
"color_sectors",
(&color as &str,),
)?;
}
Cli::Breathe { color, speed } => {
devices.method_call(
"de.richardliebscher.g213d.GDeviceManager",
"breathe",
(color, speed),
)?;
}
Cli::Cycle { speed } => {
devices.method_call(
"de.richardliebscher.g213d.GDeviceManager",
"cycle",
(speed,),
)?;
}
Cli::Wave { direction, speed } => {
devices.method_call(
"de.richardliebscher.g213d.GDeviceManager",
"wave",
(&direction as &str, speed),
)?;
}
Cli::Refresh => {
devices.method_call("de.richardliebscher.g213d.GDeviceManager", "refresh", ())?;
}
Expand Down
23 changes: 21 additions & 2 deletions src/bin/g213d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ use dbus::blocking::LocalConnection;
use dbus::tree;
use dbus::tree::{Factory, Interface, MTFn, MethodErr};

use g213d::Command::{Breathe, ColorSector, Cycle};
use g213d::Command::{Breathe, ColorSector, Cycle, Wave};
use g213d::{GDeviceManager, RgbColor};
use std::cell::RefCell;
use std::convert::TryInto;

#[derive(Copy, Clone, Default, Debug)]
struct TreeData;
Expand Down Expand Up @@ -83,7 +84,25 @@ fn create_interface() -> Interface<MTFn<TreeData>, TreeData> {

Ok(vec![m.msg.method_return()])
})
.inarg::<&str, _>("speed"),
.inarg::<u16, _>("speed"),
)
.add_m(
f.method("wave", (), move |m| {
let mut manager = m.path.get_data().borrow_mut();
let (direction, speed): (&str, u16) = m.msg.read2()?;

info!("Set wave with {} in {:?}", speed, direction);
manager.send_command(Wave(
direction
.try_into()
.map_err(|_err| MethodErr::invalid_arg("direction"))?,
speed.into(),
));

Ok(vec![m.msg.method_return()])
})
.inarg::<&str, _>("direction")
.inarg::<u16, _>("speed"),
)
.add_m(f.method("refresh", (), move |m| {
let mut manager = m.path.get_data().borrow_mut();
Expand Down
42 changes: 41 additions & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::{Command, GDeviceModel, RgbColor, Speed};
use crate::{Command, Direction, GDeviceModel, RgbColor, Speed};
use ini::ini::Properties;
use ini::Ini;
use std::convert::TryInto;

const CONFIG_PATH: &str = "/etc/g213d.conf";

Expand Down Expand Up @@ -48,6 +49,10 @@ impl Config {
self.parse_speed(props, model, "speed"),
)],
Some("cycle") => vec![Command::Cycle(self.parse_speed(props, model, "speed"))],
Some("wave") => vec![Command::Wave(
self.parse_direction(props, model, "direction"),
self.parse_speed(props, model, "speed"),
)],
Some(unknown) => {
warn!("Unknown color mode `{}` for {}", unknown, model_name);
vec![]
Expand Down Expand Up @@ -95,6 +100,27 @@ impl Config {
Speed(65535 / 2)
}

fn parse_direction(
&self,
props: &Properties,
model: &dyn GDeviceModel,
key: &str,
) -> Direction {
if let Some(direction) = props.get(key) {
direction.try_into().unwrap_or_else(|_err| {
warn!(
"Invalid direction {} for {}.{} ignored",
direction,
model.get_name(),
key
);
Direction::LeftToRight
})
} else {
Direction::LeftToRight
}
}

pub fn save_command(&mut self, model: &dyn GDeviceModel, cmd: Command) {
let mut section = self.0.with_section(Some(model.get_name()));

Expand All @@ -121,6 +147,20 @@ impl Config {
.set("type", "cycle")
.set("speed", speed.0.to_string());
}
Command::Wave(direction, speed) => {
section
.set("type", "wave")
.set(
"direction",
match direction {
Direction::LeftToRight => "left-to-right",
Direction::RightToLeft => "right-to-left",
Direction::CenterToEdge => "center-to-edge",
Direction::EdgeToCenter => "edge-to-center",
},
)
.set("speed", speed.0.to_string());
}
}
self.0.write_to_file(CONFIG_PATH).unwrap_or_else(|err| {
error!("Failed to write config file {}: {:?}", CONFIG_PATH, err);
Expand Down
29 changes: 28 additions & 1 deletion src/g213.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::usb_ext::DetachedHandle;
use crate::{Command, CommandError, CommandResult, GDevice, GDeviceModel, RgbColor, Speed};
use crate::{
Command, CommandError, CommandResult, Direction, GDevice, GDeviceModel, RgbColor, Speed,
};
use quick_error::ResultExt;
use rusb::{Context, Device, DeviceHandle, DeviceList, UsbContext};
use std::time::Duration;
Expand Down Expand Up @@ -196,6 +198,27 @@ impl UsbCommand {
])
}

pub fn for_wave(direction: Direction, speed: Speed) -> Self {
Self::new(&[
0x11,
0xff,
0x0c,
0x3a,
0,
0x04,
0x00,
0x00,
0x00,
0,
0,
0,
(speed.0 >> 0) as u8,
direction as u8,
0x64,
(speed.0 >> 8) as u8,
])
}

pub fn new(b: &[u8]) -> Self {
let mut bytes = [0; 20];
bytes[0..b.len()].copy_from_slice(b);
Expand Down Expand Up @@ -238,6 +261,10 @@ impl GDevice for G213Device {
check_speed(speed)?;
Self::send_data(&mut handle, &UsbCommand::for_cycle(speed))
}
Wave(direction, speed) => {
check_speed(speed)?;
Self::send_data(&mut handle, &UsbCommand::for_wave(direction, speed))
}
}
}
}
24 changes: 24 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::g213::G213Model;
use hex::FromHexError;
use quick_error::ResultExt;
use std::collections::HashMap;
use std::convert::TryFrom;
use std::hash::{Hash, Hasher};
use std::ops::Deref;

Expand Down Expand Up @@ -49,6 +50,28 @@ impl RgbColor {
}
}

#[derive(PartialEq, Debug, Copy, Clone)]
pub enum Direction {
LeftToRight = 1,
RightToLeft = 6,
CenterToEdge = 3,
EdgeToCenter = 8,
}

impl TryFrom<&str> for Direction {
type Error = ();

fn try_from(value: &str) -> Result<Self, Self::Error> {
match value {
"left-to-right" => Ok(Direction::LeftToRight),
"right-to-left" => Ok(Direction::RightToLeft),
"center-to-edge" => Ok(Direction::CenterToEdge),
"edge-to-center" => Ok(Direction::EdgeToCenter),
_ => Err(()),
}
}
}

/// speed of effect
#[derive(Copy, Clone, Debug, PartialOrd, PartialEq)]
pub struct Speed(u16);
Expand All @@ -65,6 +88,7 @@ pub enum Command {
ColorSector(RgbColor, Option<u8>),
Breathe(RgbColor, Speed),
Cycle(Speed),
Wave(Direction, Speed),
}

/// model series
Expand Down

0 comments on commit 70ab74c

Please sign in to comment.