#[macro_use] extern crate log;
extern crate simplelog;
use simplelog::{TermLogger, LevelFilter, TerminalMode, ColorChoice};
extern crate structopt;
use structopt::StructOpt;
extern crate humantime;
use humantime::Duration;
use streamdeck::{StreamDeck, Filter, Colour, ImageOptions, Error};
#[derive(StructOpt)]
#[structopt(name = "streamdeck-cli", about = "A CLI for the Elgato StreamDeck")]
struct Options {
#[structopt(subcommand)]
cmd: Commands,
#[structopt(flatten)]
filter: Filter,
#[structopt(long = "log-level", default_value = "info")]
level: LevelFilter,
}
#[derive(StructOpt)]
pub enum Commands {
Reset,
Version,
Probe,
SetBrightness{
brightness: u8,
},
GetButtons {
#[structopt(long)]
timeout: Option<Duration>,
#[structopt(long)]
continuous: bool,
},
SetColour {
key: u8,
#[structopt(flatten)]
colour: Colour,
},
SetImage {
key: u8,
file: String,
#[structopt(flatten)]
opts: ImageOptions,
}
}
fn main() {
let opts = Options::from_args();
let mut config = simplelog::ConfigBuilder::new();
config.set_time_level(LevelFilter::Off);
TermLogger::init(opts.level, config.build(), TerminalMode::Mixed, ColorChoice::Auto).unwrap();
let mut deck = match StreamDeck::connect(opts.filter.vid, opts.filter.pid, opts.filter.serial) {
Ok(d) => d,
Err(e) => {
error!("Error connecting to streamdeck: {:?}", e);
return
}
};
let serial = deck.serial().unwrap();
info!("Connected to device (vid: {:04x} pid: {:04x} serial: {})",
opts.filter.vid, opts.filter.pid, serial);
if let Err(e) = do_command(&mut deck, opts.cmd) {
error!("Command error: {:?}", e);
}
}
fn do_command(deck: &mut StreamDeck, cmd: Commands) -> Result<(), Error> {
match cmd {
Commands::Reset => {
deck.reset()?;
},
Commands::Version => {
let version = deck.version()?;
info!("Firmware version: {}", version);
}
Commands::SetBrightness{brightness} => {
deck.set_brightness(brightness)?;
},
Commands::GetButtons{timeout, continuous} => {
loop {
let buttons = deck.read_buttons(timeout.map(|t| *t ))?;
info!("buttons: {:?}", buttons);
if !continuous {
break
}
}
},
Commands::Probe => {
let results = StreamDeck::probe()?;
if results.is_empty() {
info!("No devices found");
return Ok(());
}
info!("Found {} devices", results.len());
for res in results {
match res {
Ok((device, pid)) => info!("Streamdeck: {:?} (pid: {:#x})", device, pid),
Err(_) => warn!("Found Elgato device with unsupported PID"),
}
}
}
Commands::SetColour{key, colour} => {
info!("Setting key {} colour to: ({:?})", key, colour);
deck.set_button_rgb(key, &colour)?;
},
Commands::SetImage{key, file, opts} => {
info!("Setting key {} to image: {}", key, file);
deck.set_button_file(key, &file, &opts)?;
}
}
Ok(())
}