use anyhow::{Context, Result}; use serde::{Serialize, Deserialize}; use serde_json; use std::io::{self, Read}; use std::time::Duration; use serialport; use actix_web::{web, App, HttpServer, HttpResponse}; use actix_cors::Cors; use std::fs; use std::path::PathBuf; use std::sync::Mutex; use once_cell::sync::Lazy; #[derive(Serialize, Deserialize)] struct WeightData { weight: String, timestamp: u64, is_read: bool, } #[derive(Serialize, Deserialize)] struct Config { scale_type: String, serial_port: String, baud_rate: u32, } // 读取配置文件 fn read_config() -> Result { let config_str = fs::read_to_string("config.json")?; let config: Config = serde_json::from_str(&config_str)?; Ok(config) } // 使用全局静态变量来存储重量数据 static WEIGHT_DATA: Lazy> = Lazy::new(|| { Mutex::new(WeightData { weight: "0".to_string(), timestamp: 0, is_read: false, }) }); // 获取MAC地址的HTTP处理函数 async fn get_mac() -> HttpResponse { let response = serde_json::json!({ "mac": "00:11:22:33:44:55" // 这里替换为实际的MAC地址获取逻辑 }); HttpResponse::Ok().json(response) } // 获取秤类型的HTTP处理函数 async fn get_scale() -> HttpResponse { let config = match read_config() { Ok(config) => config, Err(_) => return HttpResponse::InternalServerError().finish(), }; let response = serde_json::json!({ "scale_type": config.scale_type }); HttpResponse::Ok().json(response) } // 获取重量数据的HTTP处理函数 async fn get_weight() -> HttpResponse { let mut weight_data = WEIGHT_DATA.lock().unwrap(); if weight_data.is_read { // 如果数据已读,返回 null HttpResponse::Ok().json(serde_json::json!({"weight": null})) } else { // 标记为已读并返回数据 weight_data.is_read = true; HttpResponse::Ok().json(&*weight_data) } } // 串口数据处理函数 async fn run_serial() -> Result<()> { // 读取配置文件 let config = read_config()?; // 打开配置的串口 println!("正在尝试打开串口 {}...", config.serial_port); let mut port = serialport::new(&config.serial_port, config.baud_rate) .timeout(Duration::from_millis(1000)) .open() .with_context(|| format!("无法打开串口 {}", config.serial_port))?; println!("串口打开成功"); let mut buf = [0u8; 1024]; let mut accumulated_data = String::new(); loop { match port.read(&mut buf) { Ok(bytes_read) if bytes_read > 0 => { // 将读取的数据转换为字符串并添加到累积的数据中 if let Ok(data) = String::from_utf8(buf[..bytes_read].to_vec()) { accumulated_data.push_str(&data); // 检查是否有完整的行 if accumulated_data.contains('\n') { // 处理所有完整的行 for line in accumulated_data.lines() { let trimmed_data = line.trim(); if !trimmed_data.is_empty() { println!("收到串口数据: {}", trimmed_data); // 更新内存中的数据(直接覆盖) let mut weight_data = WEIGHT_DATA.lock().unwrap(); weight_data.weight = trimmed_data.to_string(); weight_data.timestamp = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs(); weight_data.is_read = false; // 新数据未读 } } // 清除已处理的数据 accumulated_data.clear(); } } } Err(ref e) if e.kind() == io::ErrorKind::TimedOut => { // 超时是正常的,继续尝试读取 continue; } Err(e) => { eprintln!("串口读取错误: {}", e); return Err(e.into()); } _ => {} } } } #[actix_web::main] async fn main() -> Result<()> { println!("程序启动..."); // 启动HTTP服务器 println!("正在启动HTTP服务器..."); // 创建HTTP服务器 let server = HttpServer::new(|| { // 配置CORS let cors = Cors::default() .allow_any_origin() // 允许所有来源 .allow_any_method() // 允许所有HTTP方法 .allow_any_header() // 允许所有请求头 .max_age(3600); // 设置预检请求的缓存时间(秒) App::new() .wrap(cors) // 添加CORS中间件 .route("/mac", web::get().to(get_mac)) .route("/scale", web::get().to(get_scale)) .route("/weight", web::get().to(get_weight)) }) .bind(("0.0.0.0", 8080))? .run(); println!("HTTP服务器已启动,监听在 http://127.0.0.1:8080"); // 在新线程中运行串口服务 let _serial_handle = tokio::spawn(async { if let Err(e) = run_serial().await { eprintln!("串口服务错误: {}", e); } }); // 等待HTTP服务器结束 server.await?; Ok(()) }