Rearrange mappings/actions, swap fmt for tracing

Some mappings made more sense as actions. This clears the way for
triggering multiple actions.
This commit is contained in:
Sam W 2022-07-08 13:22:11 +01:00
parent 4515e8d15d
commit c3361915a4
5 changed files with 131 additions and 106 deletions

155
Cargo.lock generated
View File

@ -23,15 +23,6 @@ dependencies = [
"pretty", "pretty",
] ]
[[package]]
name = "aho-corasick"
version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "annotate-snippets" name = "annotate-snippets"
version = "0.9.1" version = "0.9.1"
@ -41,6 +32,15 @@ dependencies = [
"unicode-width", "unicode-width",
] ]
[[package]]
name = "ansi_term"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
dependencies = [
"winapi",
]
[[package]] [[package]]
name = "arrayvec" name = "arrayvec"
version = "0.5.2" version = "0.5.2"
@ -58,17 +58,6 @@ dependencies = [
"futures-core", "futures-core",
] ]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.1.0" version = "1.1.0"
@ -290,19 +279,6 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "env_logger"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3"
dependencies = [
"atty",
"humantime",
"log",
"regex",
"termcolor",
]
[[package]] [[package]]
name = "event-listener" name = "event-listener"
version = "2.5.2" version = "2.5.2"
@ -528,12 +504,6 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
[[package]]
name = "humantime"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]] [[package]]
name = "hyper" name = "hyper"
version = "0.14.18" version = "0.14.18"
@ -742,9 +712,9 @@ dependencies = [
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.10.0" version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
[[package]] [[package]]
name = "opaque-debug" name = "opaque-debug"
@ -940,23 +910,6 @@ dependencies = [
"bitflags", "bitflags",
] ]
[[package]]
name = "regex"
version = "1.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]] [[package]]
name = "remove_dir_all" name = "remove_dir_all"
version = "0.5.3" version = "0.5.3"
@ -1066,12 +1019,12 @@ name = "sampad"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bitvec", "bitvec",
"env_logger",
"hidapi", "hidapi",
"log",
"rumqttc", "rumqttc",
"serde", "serde",
"serde_dhall", "serde_dhall",
"tracing",
"tracing-subscriber",
] ]
[[package]] [[package]]
@ -1208,12 +1161,27 @@ dependencies = [
"opaque-debug 0.3.0", "opaque-debug 0.3.0",
] ]
[[package]]
name = "sharded-slab"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31"
dependencies = [
"lazy_static",
]
[[package]] [[package]]
name = "slab" name = "slab"
version = "0.4.6" version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32"
[[package]]
name = "smallvec"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1"
[[package]] [[package]]
name = "socket2" name = "socket2"
version = "0.4.5" version = "0.4.5"
@ -1273,15 +1241,6 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "termcolor"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
dependencies = [
"winapi-util",
]
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.31" version = "1.0.31"
@ -1302,6 +1261,15 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "thread_local"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180"
dependencies = [
"once_cell",
]
[[package]] [[package]]
name = "tinyvec" name = "tinyvec"
version = "1.6.0" version = "1.6.0"
@ -1389,9 +1357,9 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
[[package]] [[package]]
name = "tracing" name = "tracing"
version = "0.1.34" version = "0.1.35"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"pin-project-lite", "pin-project-lite",
@ -1412,11 +1380,37 @@ dependencies = [
[[package]] [[package]]
name = "tracing-core" name = "tracing-core"
version = "0.1.26" version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f" checksum = "7b7358be39f2f274f322d2aaed611acc57f382e8eb1e5b48cb9ae30933495ce7"
dependencies = [
"once_cell",
"valuable",
]
[[package]]
name = "tracing-log"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"
dependencies = [ dependencies = [
"lazy_static", "lazy_static",
"log",
"tracing-core",
]
[[package]]
name = "tracing-subscriber"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a713421342a5a666b7577783721d3117f1b69a393df803ee17bb73b1e122a59"
dependencies = [
"ansi_term",
"sharded-slab",
"smallvec",
"thread_local",
"tracing-core",
"tracing-log",
] ]
[[package]] [[package]]
@ -1488,6 +1482,12 @@ dependencies = [
"percent-encoding", "percent-encoding",
] ]
[[package]]
name = "valuable"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[package]] [[package]]
name = "vcpkg" name = "vcpkg"
version = "0.2.15" version = "0.2.15"
@ -1618,15 +1618,6 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
]
[[package]] [[package]]
name = "winapi-x86_64-pc-windows-gnu" name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0" version = "0.4.0"

View File

@ -9,5 +9,5 @@ rumqttc = "0.12"
bitvec = "1" bitvec = "1"
serde = "1" serde = "1"
serde_dhall = "0.11" serde_dhall = "0.11"
log = "*" tracing = "0.1.35"
env_logger = "*" tracing-subscriber = "0.3.14"

View File

@ -2,20 +2,34 @@ use serde::Deserialize;
use serde_dhall::StaticType; use serde_dhall::StaticType;
use std::collections::HashMap; use std::collections::HashMap;
use std::error::Error; use std::error::Error;
use std::fmt;
use std::path::Path; use std::path::Path;
#[derive(Deserialize, StaticType, Debug)] #[derive(Deserialize, StaticType, Debug)]
pub enum Action { pub enum Action {
MQTTPub { topic: String, payload: String }, // Publish something (server, topic, payload) ActivateLayer(String), // Activate a layer
Print(String), // Print a string to console
MQTTPub { topic: String, payload: String }, // Publish payload on topic via MQTT
}
impl fmt::Display for Action {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self {
Action::ActivateLayer(layer) => write!(f, "ActivateLayer({})", layer),
Action::Print(p) => write!(f, "Print({})", p),
Action::MQTTPub { topic, payload } => {
write!(f, "MQTTPub(topic={},payload={})", topic, payload)
}
}
}
} }
#[derive(Deserialize, StaticType, Debug)] #[derive(Deserialize, StaticType, Debug)]
pub enum Mapping { pub enum Mapping {
NOP, // Do nothing. NOP, // Do nothing.
Passthrough, // Passthrough to the layer below Passthrough, // Passthrough to the layer below
ActivateLayer(String), // Activate a layer Trigger(Action), // Trigger an action
Print(String), // Print a string to console TriggerMulti(Vec<Action>), // Trigger multiple actions in sequence
Trigger(Action), // Trigger an action
} }
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]

View File

@ -2,6 +2,8 @@ use bitvec::prelude::*;
use hidapi::{DeviceInfo, HidApi, HidDevice}; use hidapi::{DeviceInfo, HidApi, HidDevice};
use std::collections::VecDeque; use std::collections::VecDeque;
use std::error::Error; use std::error::Error;
use std::fmt;
use tracing::{event, Level};
const HID_USAGE_PAGE: u16 = 0xFF; const HID_USAGE_PAGE: u16 = 0xFF;
const HID_USAGE: u16 = 0x1; const HID_USAGE: u16 = 0x1;
@ -37,6 +39,16 @@ pub enum ButtonEvent {
KeyUp(u8), KeyUp(u8),
} }
impl fmt::Display for ButtonEvent {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let vals = match *self {
Self::KeyDown(key) => ("KeyDown", key),
Self::KeyUp(key) => ("KeyUp", key),
};
write!(f, "{}(key={})", vals.0, vals.1)
}
}
type State = u16; type State = u16;
pub struct ButtonPad<'a> { pub struct ButtonPad<'a> {
@ -67,7 +79,7 @@ impl Iterator for ButtonPad<'_> {
// Read from the device, blocking until the next report // Read from the device, blocking until the next report
let mut buf: [u8; 2] = [0; 2]; let mut buf: [u8; 2] = [0; 2];
self.dev.read(&mut buf).expect("error reading"); self.dev.read(&mut buf).expect("error reading");
log::info!("{:?}", buf); event!(Level::INFO, ?buf, "Read from device");
let new: u16 = buf[0] as u16 | (buf[1] as u16) << 8; let new: u16 = buf[0] as u16 | (buf[1] as u16) << 8;

View File

@ -1,23 +1,23 @@
use env_logger::Env; mod config;
mod device;
use config::{Action, Config};
use hidapi::HidApi; use hidapi::HidApi;
use log::info;
use rumqttc::{Client, MqttOptions, QoS}; use rumqttc::{Client, MqttOptions, QoS};
use std::collections::HashMap; use std::collections::HashMap;
use std::error::Error; use std::error::Error;
use std::path::Path; use std::path::Path;
use std::thread; use std::thread;
use tracing::{event, Level};
mod config;
mod device;
struct State<'a> { struct State<'a> {
mqtt_servers: HashMap<String, Client>, mqtt_servers: HashMap<String, Client>,
conf: &'a config::Config, conf: &'a Config,
key_state: [bool; 16], key_state: [bool; 16],
} }
impl<'a> State<'a> { impl<'a> State<'a> {
fn init(c: &'a config::Config) -> Self { fn init(c: &'a Config) -> Self {
let mut s = State { let mut s = State {
mqtt_servers: HashMap::new(), mqtt_servers: HashMap::new(),
conf: &c, conf: &c,
@ -71,10 +71,9 @@ impl<'a> State<'a> {
} }
} }
fn execute_mapping(&mut self, m: &config::Mapping) { fn execute_action(&mut self, action: &Action) {
match m { match action {
config::Mapping::Print(s) => println!("{}", s), Action::MQTTPub { topic, payload } => {
config::Mapping::Trigger(config::Action::MQTTPub { topic, payload }) => {
let mut topic = topic.to_owned(); let mut topic = topic.to_owned();
let srv = &self.conf.mqtt_servers["default"]; let srv = &self.conf.mqtt_servers["default"];
if let Some(prefix) = &srv.topic_prefix { if let Some(prefix) = &srv.topic_prefix {
@ -84,6 +83,14 @@ impl<'a> State<'a> {
cli.publish(topic, QoS::AtLeastOnce, false, payload.as_bytes()) cli.publish(topic, QoS::AtLeastOnce, false, payload.as_bytes())
.unwrap(); .unwrap();
} }
Action::Print(s) => println!("{}", s),
_ => event!(Level::WARN, %action, "Ignoring unimplemented action"),
}
}
fn execute_mapping(&mut self, m: &config::Mapping) {
match m {
config::Mapping::Trigger(t) => self.execute_action(t),
_ => {} _ => {}
} }
} }
@ -100,8 +107,9 @@ impl<'a> State<'a> {
} }
fn main() -> Result<(), Box<dyn Error>> { fn main() -> Result<(), Box<dyn Error>> {
env_logger::Builder::from_env(Env::default().default_filter_or("info")).init(); tracing_subscriber::fmt::init();
let conf = config::Config::from_file(Path::new("./config.dhall"))?; event!(Level::INFO, "Starting...");
let conf = Config::from_file(Path::new("./config.dhall"))?;
let mut state = State::init(&conf); let mut state = State::init(&conf);
@ -117,12 +125,12 @@ fn main() -> Result<(), Box<dyn Error>> {
let pad = device::ButtonPad::new(&device); let pad = device::ButtonPad::new(&device);
for ev in pad { for ev in pad {
if let Ok(ev) = ev { if let Ok(ev) = ev {
info!("{:?}", ev); event!(Level::INFO, ?ev, "Got event");
state.handle_button(&ev); state.handle_button(&ev);
let mut data = state.get_led_data().to_vec(); let mut data = state.get_led_data().to_vec();
data.insert(0, 0x0); data.insert(0, 0x0);
data.insert(0, 0x0); data.insert(0, 0x0);
log::info!("{:?}", data); event!(Level::INFO, ?data, "Sending LED data");
device.write(data.as_slice())?; device.write(data.as_slice())?;
} }
} }