Rework ProntoKey device implementation

This commit is contained in:
ninjadev64 committed 2024-02-27 19:26:18 +00:00
1 parent 9f5fe482c7
commit d00a230496
2 files changed
+54 -56

No files matched your search

+52 -54
View File
@@ -2,104 +2,102 @@ use super::DeviceInfo;
use crate::events::outbound;
use std::thread;
use std::time::Duration;
use serde_json::Value;
use log::{warn, error};
#[derive(serde::Deserialize)]
#[serde(untagged)]
enum ProntoKeyMessage {
Registration { a: String },
Update { k: [u8; 9], s: [u16; 2] }
}
/// Attempt to open a serial connection with the device and handle incoming data.
pub async fn init(port: String) {
let mut initialised = false;
let mut device_id = "".to_owned();
let mut last_key: u8 = 0;
let mut last_sliders: Vec<i16> = vec![0; 2];
let mut last_keys: [u8; 9] = [0; 9];
let mut last_sliders: [u16; 2] = [0; 2];
let mut port = match
serialport::new(port, 57600)
serialport::new(port, 115200)
.timeout(Duration::from_millis(10))
.open()
{
Ok(p) => p,
Err(error) => {
error!("Failed to open serial port: {}", error);
panic!()
return;
}
};
let _ = port.write("register".as_bytes());
let _ = port.write("#".as_bytes());
let mut serial_buf: Vec<u8> = vec![0; 1024];
let serial_buf: &mut [u8] = &mut [0; 64];
let mut holding_string = String::from("");
loop {
match port.read(serial_buf.as_mut_slice()) {
match port.read(serial_buf) {
Ok(t) => {
match std::str::from_utf8(&serial_buf[..t]) {
Ok(data) => holding_string += data,
Err(_) => break
}
// Iterate through JSON objects received from device that are being held in the buffer.
while holding_string.contains('}') {
let index = holding_string.find('}').unwrap_or_default();
let chunk = holding_string[..=index].trim();
let j: Value = match serde_json::from_str(chunk) {
let data: ProntoKeyMessage = match serde_json::from_str(chunk) {
Ok(data) => data,
Err(_) => continue
};
holding_string = holding_string[(index + 1)..].to_owned();
// If the device is uninitialised, attempt to read its MAC address and initialise.
if !initialised {
if let Value::String(address) = &j["address"] {
initialised = true;
device_id = format!("pk-{}", address);
super::DEVICES.lock().await.insert(device_id.clone(), DeviceInfo {
id: device_id.clone(),
name: "ProntoKey".to_owned(),
rows: 3,
columns: 3,
sliders: 2,
r#type: 7
});
}
continue;
}
if let ProntoKeyMessage::Registration { a: address } = data {
// If the device is uninitialised, attempt to read its MAC address and initialise.
if initialised { continue }
initialised = true;
// Handle key presses and releases.
if let Value::Number(num) = &j["key"] {
match num.as_u64().unwrap_or_default() as u8 {
0 => {
let _ = outbound::keypad::key_up(&device_id, last_key - 1).await;
},
val => {
let _ = outbound::keypad::key_down(&device_id, val - 1).await;
last_key = val;
device_id = format!("pk-{}", address);
super::DEVICES.lock().await.insert(device_id.clone(), DeviceInfo {
id: device_id.clone(),
name: "ProntoKey".to_owned(),
rows: 3,
columns: 3,
sliders: 2,
r#type: 7
});
} else if let ProntoKeyMessage::Update { k: keys, s: sliders } = data {
if !initialised { continue }
// Handle key presses and releases.
for (index, value) in keys.iter().enumerate() {
if *value != last_keys[index] {
if *value == 0 {
let _ = outbound::keypad::key_up(&device_id, index as u8).await;
} else {
let _ = outbound::keypad::key_down(&device_id, index as u8).await;
}
last_keys[index] = *value;
}
}
}
// Handle slider value changes.
if let Value::Number(val) = &j["slider0"] {
let val: i16 = match val.as_i64() {
Some(v) => v as i16,
_ => last_sliders[0]
};
let _ = outbound::encoder::dial_rotate(&device_id, 0, val - last_sliders[0]).await;
last_sliders[0] = val;
}
if let Value::Number(val) = &j["slider1"] {
let val: i16 = match val.as_i64() {
Some(v) => v as i16,
_ => last_sliders[1]
};
let _ = outbound::encoder::dial_rotate(&device_id, 1, val - last_sliders[1]).await;
last_sliders[1] = val;
// Handle slider value changes.
for (index, value) in sliders.iter().enumerate() {
if *value != last_sliders[index] {
let change = ((*value as i32 - last_sliders[index] as i32) / (4095 / 192)) as i16;
last_sliders[index] = *value;
let _ = outbound::encoder::dial_rotate(&device_id, index as u8, change).await;
}
}
}
}
},
Err(ref error) if error.kind() == std::io::ErrorKind::TimedOut => (),
Err(error) => warn!("Failed to decode serial message from ProntoKey device: {}", error)
Err(error) => warn!("Failed to read serial message from ProntoKey device: {}", error)
}
thread::sleep(Duration::from_millis(10));
tokio::time::sleep(Duration::from_millis(10)).await;
}
}
+2 -2
View File
@@ -138,7 +138,7 @@ async fn initialise_plugin(path: &path::PathBuf) -> anyhow::Result<()> {
} else if use_wine {
// Start Wine with the appropriate arguments.
Command::new("wine")
.current_dir(&path)
.current_dir(path)
.args([
code_path,
String::from("-port"), 57116.to_string(),
@@ -153,7 +153,7 @@ async fn initialise_plugin(path: &path::PathBuf) -> anyhow::Result<()> {
} else {
// Run the plugin's executable natively.
Command::new(code_path)
.current_dir(&path)
.current_dir(path)
.args([
String::from("-port"), 57116.to_string(),
String::from("-pluginUUID"), plugin_uuid.to_owned(),