"futures-core",
]
+[[package]]
+name = "async-recursion"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e97ce7de6cf12de5d7226c73f5ba9811622f4db3a5b91b55c53e987e5f91cba"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.18",
+]
+
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bef35ad55f9ef3a82a7a6724a4069e931a323f75cde270ad9780c2e1991371b"
dependencies = [
+ "async-recursion",
"hidapi",
"image",
+ "tokio",
]
[[package]]
[[package]]
name = "image"
-version = "0.24.6"
+version = "0.24.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "527909aa81e20ac3a44803521443a765550f09b5130c2c2fa1ea59c2f8f50a3a"
+checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711"
dependencies = [
"bytemuck",
"byteorder",
"elgato-streamdeck",
"paho-mqtt",
"rust-ini",
+ "tokio",
]
[[package]]
[[package]]
name = "tiff"
-version = "0.8.1"
+version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7449334f9ff2baf290d55d73983a7d6fa15e01198faef72af07e2a8db851e471"
+checksum = "6d172b0f4d3fba17ba89811858b9d3d97f928aece846475bbda076ca46736211"
dependencies = [
"flate2",
"jpeg-decoder",
"weezl",
]
+[[package]]
+name = "tokio"
+version = "1.28.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2"
+dependencies = [
+ "autocfg",
+ "num_cpus",
+ "pin-project-lite",
+ "tokio-macros",
+ "windows-sys",
+]
+
+[[package]]
+name = "tokio-macros"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.18",
+]
+
[[package]]
name = "unicode-ident"
version = "1.0.9"
// Copyright 2023 Jonathan McDowell <noodles@earth.li>
use clap::Parser;
-use elgato_streamdeck as streamdeck;
+use elgato_streamdeck::{list_devices, new_hidapi, AsyncStreamDeck, StreamDeckInput};
use ini::Ini;
use paho_mqtt as mqtt;
use std::process;
-use std::time::Duration;
#[derive(Parser)]
struct Args {
verbose: bool,
}
-fn main() {
+#[tokio::main]
+async fn main() {
let args = Args::parse();
let conf = Ini::load_from_file(&args.config).unwrap_or_else(|err| {
println!("Failed to load config file ({}): {}", args.config, err);
});
let host = format!("mqtts://{}:8883", &conf["MQTT"]["broker"]);
- let hid = streamdeck::new_hidapi().unwrap_or_else(|err| {
+ let hid = new_hidapi().unwrap_or_else(|err| {
println!("Failed to create HID API context: {}", err);
process::exit(1);
});
- let mut decks = streamdeck::list_devices(&hid);
+ let mut decks = list_devices(&hid);
if decks.len() == 0 {
println!("Failed to find Stream Deck device");
let (kind, serial) = decks.remove(0);
- let deck = streamdeck::StreamDeck::connect(&hid, kind, &serial).unwrap_or_else(|err| {
+ let deck = AsyncStreamDeck::connect(&hid, kind, &serial).unwrap_or_else(|err| {
println!("Failed to connect to Stream Deck: {}", err);
process::exit(1);
});
println!(
"Connected to '{:?}' ('{}') with version '{}'",
kind,
- deck.serial_number().unwrap(),
- deck.firmware_version().unwrap()
+ deck.serial_number().await.unwrap(),
+ deck.firmware_version().await.unwrap()
);
if args.verbose {
process::exit(1);
});
- let ssl_opts = mqtt::SslOptionsBuilder::new()
- .finalize();
+ let ssl_opts = mqtt::SslOptionsBuilder::new().finalize();
let lwt_topic = format!("{}/LWT", &conf["MQTT"]["prefix"]);
let quit = false;
while !quit {
- let input = deck.read_input(Some(Duration::new(5, 0))).unwrap();
+ let input = deck.read_input(5.0).await.unwrap();
if !input.is_empty() {
match input {
- streamdeck::StreamDeckInput::ButtonStateChange(keys) => {
- for key in 0..keys.len() {
- if keys[key] != keystates[key] {
-
- if args.verbose {
- println!("Button state change, key {} pressed -> {}", key, keys[key]);
+ StreamDeckInput::ButtonStateChange(keys) => {
+ for key in 0..keys.len() {
+ if keys[key] != keystates[key] {
+ if args.verbose {
+ println!(
+ "Button state change, key {} pressed -> {}",
+ key, keys[key]
+ );
+ }
+
+ let msg = mqtt::MessageBuilder::new()
+ .topic(format!("{}/button{}", &conf["MQTT"]["prefix"], key))
+ .payload(if keys[key] { "ON" } else { "OFF" })
+ .qos(1)
+ .finalize();
+
+ if let Err(e) = cli.publish(msg).wait() {
+ println!("Error sending key state update message: {:?}", e);
+ }
+
+ keystates[key] = keys[key];
}
-
- let msg = mqtt::MessageBuilder::new()
- .topic(format!("{}/button{}", &conf["MQTT"]["prefix"], key))
- .payload(if keys[key] { "ON" } else { "OFF"} )
- .qos(1)
- .finalize();
-
- if let Err(e) = cli.publish(msg).wait() {
- println!("Error sending key state update message: {:?}", e);
- }
-
- keystates[key] = keys[key];
}
}
- },
- _ => {
- if args.verbose {
- println!("Unexpected Stream Deck event: {:?}", input);
+ _ => {
+ if args.verbose {
+ println!("Unexpected Stream Deck event: {:?}", input);
+ }
}
- },
}
}
}
+ cli.remove_message_callback();
let tok = cli.disconnect(None);
tok.wait().unwrap();
}