|
|
@@ -30,42 +30,29 @@ struct ScaleTypeResponse { |
|
|
|
#[derive(Deserialize)] |
|
|
|
struct Config { |
|
|
|
scale_type: String, |
|
|
|
serial_port: String, |
|
|
|
baud_rate: u32, |
|
|
|
} |
|
|
|
|
|
|
|
fn get_mac_address() -> String { |
|
|
|
// let output = Command::new("getmac") |
|
|
|
// .arg("/fo") |
|
|
|
// .arg("csv") |
|
|
|
// .arg("/nh") |
|
|
|
// .output() |
|
|
|
// .expect("Failed to execute getmac command"); |
|
|
|
|
|
|
|
// let output_str = String::from_utf8_lossy(&output.stdout); |
|
|
|
// let first_line = output_str.lines().next().unwrap_or(""); |
|
|
|
// let mac = first_line.split(',').next().unwrap_or("").trim_matches('"'); |
|
|
|
// mac.replace('-', ":").to_lowercase() |
|
|
|
|
|
|
|
fn read_config() -> Result<Config> { |
|
|
|
let config_path = "config.json"; |
|
|
|
match fs::read_to_string(config_path) { |
|
|
|
Ok(content) => { |
|
|
|
match serde_json::from_str::<Config>(&content) { |
|
|
|
Ok(config) => config.scale_type, |
|
|
|
Err(_) => String::from("Unknown") |
|
|
|
} |
|
|
|
}, |
|
|
|
let content = fs::read_to_string(config_path) |
|
|
|
.with_context(|| format!("无法读取配置文件 {}", config_path))?; |
|
|
|
let config: Config = serde_json::from_str(&content) |
|
|
|
.with_context(|| format!("配置文件格式错误 {}", config_path))?; |
|
|
|
Ok(config) |
|
|
|
} |
|
|
|
|
|
|
|
fn get_mac_address() -> String { |
|
|
|
match read_config() { |
|
|
|
Ok(config) => config.scale_type, |
|
|
|
Err(_) => String::from("Unknown") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
fn get_scale_type() -> String { |
|
|
|
let config_path = "config.json"; |
|
|
|
match fs::read_to_string(config_path) { |
|
|
|
Ok(content) => { |
|
|
|
match serde_json::from_str::<Config>(&content) { |
|
|
|
Ok(config) => config.scale_type, |
|
|
|
Err(_) => String::from("Unknown") |
|
|
|
} |
|
|
|
}, |
|
|
|
match read_config() { |
|
|
|
Ok(config) => config.scale_type, |
|
|
|
Err(_) => String::from("Unknown") |
|
|
|
} |
|
|
|
} |
|
|
@@ -73,7 +60,7 @@ fn get_scale_type() -> String { |
|
|
|
// HTTP处理函数 |
|
|
|
async fn get_mac() -> HttpResponse { |
|
|
|
let mac = get_mac_address(); |
|
|
|
println!("HTTP请求:获取MAC地址 = {}", mac); // 添加日志 |
|
|
|
println!("HTTP请求:获取MAC地址 = {}", mac); |
|
|
|
let response = MacResponse { |
|
|
|
mac_address: mac, |
|
|
|
}; |
|
|
@@ -131,6 +118,9 @@ async fn main() -> Result<()> { |
|
|
|
|
|
|
|
// MQTT和串口处理函数 |
|
|
|
async fn run_mqtt_and_serial() -> Result<()> { |
|
|
|
// 读取配置 |
|
|
|
let config = read_config()?; |
|
|
|
|
|
|
|
// 创建 MQTT 客户端 |
|
|
|
let mut mqttopts = MqttOptions::new("weight_reader", "112.33.111.160", 1883); |
|
|
|
mqttopts.set_keep_alive(Duration::from_secs(5)); |
|
|
@@ -141,11 +131,7 @@ async fn run_mqtt_and_serial() -> Result<()> { |
|
|
|
thread::spawn(move || { |
|
|
|
for notification in connection.iter() { |
|
|
|
match notification { |
|
|
|
Ok(_) => { |
|
|
|
// if(!notification.contains("PingRe")) { |
|
|
|
// println!("MQTT事件: {:?}", notification); |
|
|
|
// } |
|
|
|
} |
|
|
|
Ok(_) => {} |
|
|
|
Err(e) => { |
|
|
|
eprintln!("MQTT连接错误: {:?}", e); |
|
|
|
break; |
|
|
@@ -154,82 +140,70 @@ async fn run_mqtt_and_serial() -> Result<()> { |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
// List available ports |
|
|
|
let ports = serialport::available_ports().context("未找到串口设备!")?; |
|
|
|
|
|
|
|
if ports.is_empty() { |
|
|
|
println!("错误:没有找到任何串口设备"); |
|
|
|
return Ok(()); |
|
|
|
} |
|
|
|
|
|
|
|
println!("可用的串口设备:"); |
|
|
|
for (i, port) in ports.iter().enumerate() { |
|
|
|
println!("{}: {}", i, port.port_name); |
|
|
|
} |
|
|
|
|
|
|
|
// Read port selection from user |
|
|
|
let port_idx = loop { |
|
|
|
println!("请输入要使用的串口编号 (0-{}):", ports.len() - 1); |
|
|
|
let mut input = String::new(); |
|
|
|
io::stdin().read_line(&mut input)?; |
|
|
|
|
|
|
|
match input.trim().parse::<usize>() { |
|
|
|
Ok(idx) if idx < ports.len() => break idx, |
|
|
|
Ok(_) => println!("错误:输入的编号超出范围,请重新输入"), |
|
|
|
Err(_) => println!("错误:请输入有效的数字"), |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
let port_name = &ports[port_idx].port_name; |
|
|
|
println!("正在尝试打开串口 {}...", port_name); |
|
|
|
|
|
|
|
// Configure and open the serial port |
|
|
|
let mut port = serialport::new(port_name, 9600) |
|
|
|
// 打开配置的串口 |
|
|
|
println!("正在尝试打开串口 {}...", config.serial_port); |
|
|
|
let mut port = serialport::new(&config.serial_port, config.baud_rate) |
|
|
|
.timeout(Duration::from_millis(1000)) |
|
|
|
.open() |
|
|
|
.with_context(|| format!("无法打开串口 {}", port_name))?; |
|
|
|
.with_context(|| format!("无法打开串口 {}", config.serial_port))?; |
|
|
|
|
|
|
|
println!("成功打开串口 {}!", port_name); |
|
|
|
println!("成功打开串口 {}!", config.serial_port); |
|
|
|
println!("正在读取数据... (按 Ctrl+C 退出)"); |
|
|
|
|
|
|
|
// Read data continuously |
|
|
|
let mut serial_buf: Vec<u8> = vec![0; 1000000]; |
|
|
|
// 增加缓冲区大小并使用String来累积数据 |
|
|
|
let mut serial_buf: Vec<u8> = vec![0; 1024]; |
|
|
|
let mut accumulated_data = String::new(); |
|
|
|
|
|
|
|
loop { |
|
|
|
match port.read(serial_buf.as_mut_slice()) { |
|
|
|
Ok(t) => { |
|
|
|
let data = String::from_utf8_lossy(&serial_buf[..t]); |
|
|
|
let trimmed_data = data.trim(); |
|
|
|
if !trimmed_data.is_empty() { |
|
|
|
println!("收到数据: {}", trimmed_data); |
|
|
|
|
|
|
|
// 创建权重数据结构 |
|
|
|
let weight_data = WeightData { |
|
|
|
weight: trimmed_data.to_string(), |
|
|
|
timestamp: std::time::SystemTime::now() |
|
|
|
.duration_since(std::time::UNIX_EPOCH) |
|
|
|
.unwrap() |
|
|
|
.as_secs(), |
|
|
|
}; |
|
|
|
|
|
|
|
// 开始循环发送数据 |
|
|
|
// loop { |
|
|
|
// 序列化数据 |
|
|
|
let json_data = serde_json::to_string(&weight_data)?; |
|
|
|
println!("当前JSON数据: {}", json_data); |
|
|
|
if t > 0 { |
|
|
|
// 将新数据添加到累积的字符串中 |
|
|
|
if let Ok(data) = String::from_utf8(serial_buf[..t].to_vec()) { |
|
|
|
accumulated_data.push_str(&data); |
|
|
|
|
|
|
|
// 获取MAC地址 |
|
|
|
let mac_address = get_mac_address(); |
|
|
|
println!("MAC地址: {}", mac_address); |
|
|
|
// 发布到 MQTT,主题中包含MAC地址 |
|
|
|
if let Err(e) = client.publish(format!("weight/data/{}", mac_address), QoS::AtLeastOnce, false, json_data) { |
|
|
|
eprintln!("MQTT发布错误: {:?}", e); |
|
|
|
} else { |
|
|
|
println!("成功发送数据到MQTT"); |
|
|
|
// 检查是否有完整的数据行(以换行符或回车符结束) |
|
|
|
if accumulated_data.contains('\n') || accumulated_data.contains('\r') { |
|
|
|
// 处理累积的数据 |
|
|
|
let lines: Vec<&str> = accumulated_data |
|
|
|
.split(|c| c == '\n' || c == '\r') |
|
|
|
.filter(|s| !s.is_empty()) |
|
|
|
.collect(); |
|
|
|
|
|
|
|
for line in lines { |
|
|
|
let trimmed_data = line.trim(); |
|
|
|
if !trimmed_data.is_empty() { |
|
|
|
println!("收到完整数据: {}", trimmed_data); |
|
|
|
|
|
|
|
// 创建权重数据结构 |
|
|
|
let weight_data = WeightData { |
|
|
|
weight: trimmed_data.to_string(), |
|
|
|
timestamp: std::time::SystemTime::now() |
|
|
|
.duration_since(std::time::UNIX_EPOCH) |
|
|
|
.unwrap() |
|
|
|
.as_secs(), |
|
|
|
}; |
|
|
|
|
|
|
|
// 序列化数据 |
|
|
|
let json_data = serde_json::to_string(&weight_data)?; |
|
|
|
println!("当前JSON数据: {}", json_data); |
|
|
|
|
|
|
|
// 获取MAC地址 |
|
|
|
let mac_address = get_mac_address(); |
|
|
|
println!("MAC地址: {}", mac_address); |
|
|
|
// 发布到 MQTT,主题中包含MAC地址 |
|
|
|
if let Err(e) = client.publish(format!("weight/data/{}", mac_address), QoS::AtLeastOnce, false, json_data) { |
|
|
|
eprintln!("MQTT发布错误: {:?}", e); |
|
|
|
} else { |
|
|
|
println!("成功发送数据到MQTT"); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 清空累积的数据 |
|
|
|
accumulated_data.clear(); |
|
|
|
} |
|
|
|
|
|
|
|
// 等待3秒 |
|
|
|
// thread::sleep(Duration::from_secs(1)); |
|
|
|
// } |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
Err(ref e) if e.kind() == io::ErrorKind::TimedOut => { |
|
|
|