rust称重到mqtt
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

179 lignes
5.6KB

  1. use anyhow::{Context, Result};
  2. use serde::{Serialize, Deserialize};
  3. use serde_json;
  4. use std::io::{self, Read};
  5. use std::time::Duration;
  6. use serialport;
  7. use actix_web::{web, App, HttpServer, HttpResponse};
  8. use actix_cors::Cors;
  9. use std::fs;
  10. use std::path::PathBuf;
  11. use std::sync::Mutex;
  12. use once_cell::sync::Lazy;
  13. #[derive(Serialize, Deserialize)]
  14. struct WeightData {
  15. weight: String,
  16. timestamp: u64,
  17. is_read: bool,
  18. }
  19. #[derive(Serialize, Deserialize)]
  20. struct Config {
  21. scale_type: String,
  22. serial_port: String,
  23. baud_rate: u32,
  24. }
  25. // 读取配置文件
  26. fn read_config() -> Result<Config> {
  27. let config_str = fs::read_to_string("config.json")?;
  28. let config: Config = serde_json::from_str(&config_str)?;
  29. Ok(config)
  30. }
  31. // 使用全局静态变量来存储重量数据
  32. static WEIGHT_DATA: Lazy<Mutex<WeightData>> = Lazy::new(|| {
  33. Mutex::new(WeightData {
  34. weight: "0".to_string(),
  35. timestamp: 0,
  36. is_read: false,
  37. })
  38. });
  39. // 获取MAC地址的HTTP处理函数
  40. async fn get_mac() -> HttpResponse {
  41. let response = serde_json::json!({
  42. "mac": "00:11:22:33:44:55" // 这里替换为实际的MAC地址获取逻辑
  43. });
  44. HttpResponse::Ok().json(response)
  45. }
  46. // 获取秤类型的HTTP处理函数
  47. async fn get_scale() -> HttpResponse {
  48. let config = match read_config() {
  49. Ok(config) => config,
  50. Err(_) => return HttpResponse::InternalServerError().finish(),
  51. };
  52. let response = serde_json::json!({
  53. "scale_type": config.scale_type
  54. });
  55. HttpResponse::Ok().json(response)
  56. }
  57. // 获取重量数据的HTTP处理函数
  58. async fn get_weight() -> HttpResponse {
  59. let mut weight_data = WEIGHT_DATA.lock().unwrap();
  60. if weight_data.is_read {
  61. // 如果数据已读,返回 null
  62. HttpResponse::Ok().json(serde_json::json!({"weight": null}))
  63. } else {
  64. // 标记为已读并返回数据
  65. weight_data.is_read = true;
  66. HttpResponse::Ok().json(&*weight_data)
  67. }
  68. }
  69. // 串口数据处理函数
  70. async fn run_serial() -> Result<()> {
  71. // 读取配置文件
  72. let config = read_config()?;
  73. // 打开配置的串口
  74. println!("正在尝试打开串口 {}...", config.serial_port);
  75. let mut port = serialport::new(&config.serial_port, config.baud_rate)
  76. .timeout(Duration::from_millis(1000))
  77. .open()
  78. .with_context(|| format!("无法打开串口 {}", config.serial_port))?;
  79. println!("串口打开成功");
  80. let mut buf = [0u8; 1024];
  81. let mut accumulated_data = String::new();
  82. loop {
  83. match port.read(&mut buf) {
  84. Ok(bytes_read) if bytes_read > 0 => {
  85. // 将读取的数据转换为字符串并添加到累积的数据中
  86. if let Ok(data) = String::from_utf8(buf[..bytes_read].to_vec()) {
  87. accumulated_data.push_str(&data);
  88. // 检查是否有完整的行
  89. if accumulated_data.contains('\n') {
  90. // 处理所有完整的行
  91. for line in accumulated_data.lines() {
  92. let trimmed_data = line.trim();
  93. if !trimmed_data.is_empty() {
  94. println!("收到串口数据: {}", trimmed_data);
  95. // 更新内存中的数据(直接覆盖)
  96. let mut weight_data = WEIGHT_DATA.lock().unwrap();
  97. weight_data.weight = trimmed_data.to_string();
  98. weight_data.timestamp = std::time::SystemTime::now()
  99. .duration_since(std::time::UNIX_EPOCH)
  100. .unwrap()
  101. .as_secs();
  102. weight_data.is_read = false; // 新数据未读
  103. }
  104. }
  105. // 清除已处理的数据
  106. accumulated_data.clear();
  107. }
  108. }
  109. }
  110. Err(ref e) if e.kind() == io::ErrorKind::TimedOut => {
  111. // 超时是正常的,继续尝试读取
  112. continue;
  113. }
  114. Err(e) => {
  115. eprintln!("串口读取错误: {}", e);
  116. return Err(e.into());
  117. }
  118. _ => {}
  119. }
  120. }
  121. }
  122. #[actix_web::main]
  123. async fn main() -> Result<()> {
  124. println!("程序启动...");
  125. // 启动HTTP服务器
  126. println!("正在启动HTTP服务器...");
  127. // 创建HTTP服务器
  128. let server = HttpServer::new(|| {
  129. // 配置CORS
  130. let cors = Cors::default()
  131. .allow_any_origin() // 允许所有来源
  132. .allow_any_method() // 允许所有HTTP方法
  133. .allow_any_header() // 允许所有请求头
  134. .max_age(3600); // 设置预检请求的缓存时间(秒)
  135. App::new()
  136. .wrap(cors) // 添加CORS中间件
  137. .route("/mac", web::get().to(get_mac))
  138. .route("/scale", web::get().to(get_scale))
  139. .route("/weight", web::get().to(get_weight))
  140. })
  141. .bind(("0.0.0.0", 8080))?
  142. .run();
  143. println!("HTTP服务器已启动,监听在 http://127.0.0.1:8080");
  144. // 在新线程中运行串口服务
  145. let _serial_handle = tokio::spawn(async {
  146. if let Err(e) = run_serial().await {
  147. eprintln!("串口服务错误: {}", e);
  148. }
  149. });
  150. // 等待HTTP服务器结束
  151. server.await?;
  152. Ok(())
  153. }