toos-halloween/toos-dashboard/src-tauri/src/serial.rs

104 lines
3.5 KiB
Rust
Raw Normal View History

2023-10-24 22:12:52 +02:00
use std::io::ErrorKind;
use std::time::Duration;
use std::collections::HashMap;
use std::sync::Mutex;
use tauri::Manager;
use once_cell::sync::Lazy;
use crate::animation;
#[derive(Default)]
pub struct PortMap(Mutex<HashMap<String, Box<dyn serialport::SerialPort>>>);
static PORT_MAP: Mutex<Lazy<HashMap<String, Box<dyn serialport::SerialPort>>>> = Mutex::new(Lazy::new(|| HashMap::new()));
static PORT_NAME: Mutex<Lazy<String>> = Mutex::new(Lazy::new(|| String::from("/dev/ttyUSB0")));
#[derive(Clone, serde::Serialize)]
pub struct PayloadPortState {
open: bool,
}
#[tauri::command]
pub fn write_serial(input: &str) -> Result<(), String> {
let port_name = PORT_NAME.lock().unwrap().to_string();
match PORT_MAP.lock().unwrap().get(&port_name) {
Some(port) => {
let mut clone = port.try_clone().expect("Failed to clone");
match clone.write(input.as_bytes()) {
Ok(_) => {
Ok(())
},
Err(err) => Err(err.to_string()),
}
}
None => {
Err(String::from("Port is closed"))
}
}
}
#[tauri::command]
pub fn get_serial_ports() -> Vec<String> {
let ports = serialport::available_ports().expect("No ports found");
let mut vec: Vec<String> = Vec::new();
for p in ports {
vec.push(p.port_name);
}
vec
}
#[tauri::command]
pub fn close_port(app_handle: tauri::AppHandle) {
let port_name = PORT_NAME.lock().unwrap().to_string();
match PORT_MAP.lock().unwrap().remove(&port_name) {
Some(_) => {
println!("Port {:?} closed", port_name);
app_handle.emit_all("port-state", PayloadPortState { open: false }).unwrap();
},
None => println!("Port {:?} was already closed", port_name),
}
}
#[tauri::command]
pub async fn open_port(app_handle: tauri::AppHandle, baud: u32) -> Result<(), String> {
let port_name = PORT_NAME.lock().unwrap().to_string();
match serialport::new(&port_name, baud).timeout(Duration::from_millis(10)).open() {
Ok(port) => {
// port_map.0.lock().unwrap().insert(port_name.to_string(), port.try_clone().expect("Error cloning"));
PORT_MAP.lock().unwrap().insert(port_name.clone(), port.try_clone().expect("Error cloning port"));
let mut clone = port.try_clone().expect("Failed to clone");
let mut buffer: Vec<u8> = vec![0; 1024];
println!("Port {:?} is open", port_name);
app_handle.emit_all("port-state", PayloadPortState { open: true }).unwrap();
loop {
match clone.read(buffer.as_mut_slice()) {
Ok(bytes_read) => {
if bytes_read > 0 {
let data = &buffer[..bytes_read];
let data = String::from_utf8_lossy(data).to_string();
if !data.trim().is_empty() {
println!("{}", data.trim());
if data.trim() == "1" {
animation::start();
app_handle.emit_all("button-on", PayloadPortState { open: true }).unwrap();
}
}
}
},
Err(ref e) if e.kind() == ErrorKind::TimedOut => (),
Err(e) => return Err(e.to_string()),
};
}
},
Err(err) => return Err(err.to_string()),
}
}