use std::sync::{mpsc, Mutex};
use std::collections::HashMap;
use std::str::FromStr;
use std::sync::mpsc::{Receiver, Sender};
use std::thread;
use std::time::Duration;
use lazy_static::lazy_static;
use log::info;
use serialport::{available_ports, SerialPortType};
mod usb;
pub mod protocol;
lazy_static! {
pub static ref DEVICES: Mutex<HashMap<String,Device>> =Mutex::new(HashMap::new());
pub static ref BLACKLIST: Mutex<HashMap<String,String>> =Mutex::new(HashMap::new());
}
#[derive(Clone, Debug)]
pub struct Devices {}
impl Devices {
pub fn new() -> Receiver<SubDevice> {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
Devices::listen_device();
});
let tx2 = tx.clone();
thread::spawn(move || {
Devices::start(tx2.clone());
});
return rx;
}
pub fn listen_device() {
loop {
let mut devices = HashMap::new();
match available_ports() {
Ok(ports) => {
for p in ports {
match p.port_type {
SerialPortType::UsbPort(info) => {
let is_none = BLACKLIST.lock().unwrap().get(&*p.port_name.to_string()).is_none();
if !is_none {
continue;
}
devices.insert(p.port_name.to_string(), info);
continue;
}
_ => {}
}
}
}
Err(_) => {}
}
for (com, device) in devices.iter() {
let is_none = DEVICES.lock().unwrap().get(&*com.clone()).is_none();
if !is_none {
continue;
}
let uuid = format!("{}_{}", device.vid, device.pid);
info!("检测到设备: {}",uuid);
let device = Device {
uuid: uuid.clone(),
com: com.clone(),
supplier: "".to_string().clone(),
manufacturer: device.manufacturer.as_ref().map_or("", String::as_str).to_string(),
vid: device.vid,
pid: device.pid,
serial_number: device.serial_number.as_ref().map_or("", String::as_str).to_string(),
product_name: device.product.as_ref().map_or("", String::as_str).to_string(),
state: 0,
device_id: "".to_string(),
sub_device: HashMap::new(),
rate: 115200,
reconnect: 0,
};
DEVICES.lock().unwrap().insert(com.clone(), device.clone());
}
thread::sleep(Duration::from_secs(1));
}
}
pub fn start(sender: Sender<SubDevice>) {
loop {
let mut devices = DEVICES.lock().unwrap().clone();
let mut sub_devices = HashMap::new();
for (com, device) in devices.iter_mut() {
match device.state {
0 => {
usb::Usb { com: com.clone(), step: 0, tx: sender.clone() }.connect();
}
_ => {
for (x, y) in device.sub_device.iter() {
sub_devices.insert(x.clone(), y.clone());
}
}
}
}
thread::sleep(Duration::from_secs(1));
}
}
}
#[derive(Clone, Debug)]
pub struct Device {
pub device_id: String,
pub com: String,
pub uuid: String,
pub supplier: String,
pub manufacturer: String,
pub vid: u16,
pub pid: u16,
pub serial_number: String,
pub product_name: String,
pub state: usize,
pub sub_device: HashMap<String, SubDevice>,
pub rate: u32,
pub reconnect: usize,
}
impl Device {
pub fn save_data(&mut self) {
DEVICES.lock().unwrap().insert(self.com.clone(), self.clone());
}
}
#[derive(Clone, Debug)]
pub struct SubDevice {
pub mode: String,
pub id: String,
pub name: String,
pub state: i32,
pub device: bool,
pub device_id: String,
pub data_mode: String,
pub data_type: String,
pub value: f64,
}
impl FromStr for SubDevice {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
let sub = json::parse(s).unwrap();
Ok(SubDevice {
mode: "USB".to_string(),
id: sub["id"].to_string(),
name: sub["name"].to_string(),
state: sub["state"].as_i32().unwrap(),
device: sub["device"].as_bool().unwrap(),
device_id: sub["device_id"].to_string(),
data_mode: sub["data_mode"].to_string(),
data_type: sub["data_type"].to_string(),
value: sub["value"].as_f64().unwrap(),
})
}
}