]> the.earth.li Git - mqttdeck.git/commitdiff
Add initial async framework
authorJonathan McDowell <noodles@earth.li>
Mon, 4 Sep 2023 18:35:22 +0000 (19:35 +0100)
committerJonathan McDowell <noodles@earth.li>
Mon, 4 Sep 2023 19:07:09 +0000 (20:07 +0100)
To move to being able to accept commands controlling button images move
to using the async version of streamdeck.

Cargo.lock
Cargo.toml
src/main.rs

index 3e8565f45da7b74d4b9f1239710659056913053a..089f3825b230c1c41879e0686a91dbf6b6a71943 100644 (file)
@@ -30,6 +30,17 @@ dependencies = [
  "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"
@@ -215,8 +226,10 @@ version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0bef35ad55f9ef3a82a7a6724a4069e931a323f75cde270ad9780c2e1991371b"
 dependencies = [
+ "async-recursion",
  "hidapi",
  "image",
+ "tokio",
 ]
 
 [[package]]
@@ -465,9 +478,9 @@ dependencies = [
 
 [[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",
@@ -590,6 +603,7 @@ dependencies = [
  "elgato-streamdeck",
  "paho-mqtt",
  "rust-ini",
+ "tokio",
 ]
 
 [[package]]
@@ -944,15 +958,39 @@ dependencies = [
 
 [[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"
index 5d075747122b1e292ab7a32c1f48754e5da052f4..1ae32153891625f9af45371a0db867adf1972393 100644 (file)
@@ -5,6 +5,7 @@ edition = "2021"
 
 [dependencies]
 clap = { version = "4.0.32", features = ["derive"] }
-elgato-streamdeck = "0.3.5"
+elgato-streamdeck = { version = "0.3.5", features = ["async"] }
 paho-mqtt = "0.12.1"
 rust-ini = "0.18.0"
+tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
index 95ae7b0b76a98bd1d9e152ff27836bacacf578bf..89fc007fd70fcbe1948a9878da7e38a17ae71575 100644 (file)
@@ -4,11 +4,10 @@
 // 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 {
@@ -19,7 +18,8 @@ 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);
@@ -27,11 +27,11 @@ fn main() {
     });
     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");
@@ -40,7 +40,7 @@ fn main() {
 
     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);
     });
@@ -48,8 +48,8 @@ fn main() {
     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 {
@@ -61,8 +61,7 @@ fn main() {
         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"]);
 
@@ -100,41 +99,44 @@ fn main() {
     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();
 }