瀏覽代碼

【代码结构】重新调整代码结构

mikasa 2 周之前
父節點
當前提交
a036a04fd6

+ 2 - 2
src/cmd/config.rs

@@ -35,7 +35,7 @@ pub struct PcsConfig {
 pub struct BmsConfig {
     pub interval: u64,
     pub test_bms: TestBms,
-    pub gold_bms: GoldBms,
+    pub gold_bms: GoldBmsConfig,
 }
 
 #[derive(Serialize, Deserialize, Debug)]
@@ -44,7 +44,7 @@ pub struct TestBms {
 }
 /// 高特BMS配置
 #[derive(Serialize, Deserialize, Debug)]
-pub struct GoldBms {
+pub struct GoldBmsConfig {
     pub host: String,
     pub port: u16,
 }

+ 1 - 4
src/ems/bms/gold_bms.rs → src/ems/bms/gold/gold_bms.rs

@@ -4,8 +4,7 @@ use crate::ems::{Consumer, Producer, Service};
 use crate::internal::modbus::code::ModbusCode;
 use crate::internal::utils;
 use async_trait::async_trait;
-use log::{error, info};
-use std::cmp::min;
+use log::info;
 use std::net::SocketAddr;
 use std::sync::Arc;
 use std::time::Duration;
@@ -25,7 +24,6 @@ pub struct GoldBms {
 
 impl GoldBms {
     pub async fn new(producer: Producer, consumer: Consumer) -> anyhow::Result<Self> {
-        let config = &app_config().emu.bms.gold_bms;
         let id = utils::generate_random_str(12);
         utils::log::init_log("inpower_iot_mgc_rs::ems::bms::*", "bms/bms.log").await;
         let context = connect_modbus_tcp().await?;
@@ -51,7 +49,6 @@ impl GoldBms {
 #[async_trait]
 impl Service for GoldBms {
     async fn read_task(&self) {
-        let config = &app_config().emu.bms.gold_bms;
         loop {
             tokio::time::sleep(Duration::from_millis(app_config().emu.bms.interval)).await;
             match self.read_input_register().await {

+ 3 - 0
src/ems/bms/gold/mod.rs

@@ -0,0 +1,3 @@
+/// 模块针对高特的BMS
+///
+pub(crate) mod gold_bms;

+ 1 - 1
src/ems/bms/mod.rs

@@ -1,2 +1,2 @@
 pub mod bms;
-pub mod gold_bms;
+pub mod gold;

+ 1 - 1
src/ems/emu/emu.rs

@@ -1,5 +1,5 @@
 use crate::cmd::config::app_config;
-use crate::ems::bms::gold_bms::GoldBms;
+use crate::ems::bms::gold::gold_bms::GoldBms;
 use crate::ems::emu::device::{DevType, Device};
 use crate::ems::emu::BroadcastMessage;
 use crate::ems::pcs::pcs::Pcs;

+ 0 - 37
src/ems/pcs/mod.rs

@@ -1,38 +1 @@
-use crate::internal::modbus::code::ModbusCode;
-use serde::{Deserialize, Serialize};
-
 pub mod pcs;
-
-#[derive(Debug, Serialize, Deserialize)]
-pub(crate) struct PcsCsvData {
-    pub address: Option<u16>,
-    pub code: Option<u8>,
-    pub name: Option<String>,
-    pub rw: Option<u8>,
-    #[serde(rename = "type")]
-    pub t: Option<String>,
-    pub factor: Option<f32>,
-    pub unit: Option<String>,
-    pub note: Option<String>,
-    pub desc: Option<String>,
-}
-
-/// pcs config
-pub(crate) fn pcs_conf() -> anyhow::Result<Vec<ModbusCode>> {
-    let mut rdr = csv::Reader::from_path("./config/pcs.csv")?;
-    let mut vec = Vec::new();
-    for result in rdr.deserialize() {
-        let csv_data: PcsCsvData = result?;
-        let code: ModbusCode = csv_data.try_into()?;
-        vec.push(code);
-    }
-    Ok(vec)
-}
-
-mod test {
-
-    #[test]
-    fn test_pcs_conf() {
-        assert!(crate::ems::pcs::pcs_conf().is_ok());
-    }
-}

+ 8 - 22
src/ems/pcs/pcs.rs

@@ -1,11 +1,12 @@
 use crate::cmd::config::app_config;
-use crate::ems::pcs::pcs_conf;
+use crate::connect_or_retry;
 use crate::ems::{Consumer, Producer, Service};
 use crate::internal::modbus::code::ModbusCode;
-use crate::internal::modbus::slice_sequential;
+use crate::internal::modbus::{read_csv_to_code, slice_sequential};
 use crate::internal::utils;
 use anyhow::bail;
 use log::{error, info};
+use std::net::SocketAddr;
 use std::sync::Arc;
 use tokio::sync::Mutex;
 use tokio_modbus::client::Reader;
@@ -19,15 +20,10 @@ pub struct Pcs {
     pub ctx: Arc<Mutex<tokio_modbus::client::Context>>,
 }
 
-/// Modbus-TCP连接
-/// FIXME 考虑重连机制
 async fn connect_modbus_tcp() -> anyhow::Result<tokio_modbus::client::Context> {
-    let pcs_config = &app_config().emu.pcs;
-    let ctx = tokio_modbus::client::tcp::connect(
-        format!("{}:{}", pcs_config.host, pcs_config.port).parse()?,
-    )
-    .await?;
-    Ok(ctx)
+    let config = &app_config().emu.pcs;
+    let addr: SocketAddr = format!("{}:{}", config.host, config.port).parse()?;
+    connect_or_retry!(tokio_modbus::client::tcp::connect(addr), "ModbusTCP")
 }
 
 impl Pcs {
@@ -35,18 +31,8 @@ impl Pcs {
     pub async fn new(producer: Producer, consumer: Consumer) -> anyhow::Result<Self> {
         let id = utils::generate_random_str(12);
         utils::log::init_log("inpower_iot_mgc_rs::ems::pcs::*", "pcs/pcs.log").await;
-        let ctx = match connect_modbus_tcp().await {
-            Ok(c) => c,
-            Err(e) => {
-                error!(
-                    "【PCS】Modbus Tcp {}连接失败: {}",
-                    &app_config().emu.pcs.host,
-                    e.to_string()
-                );
-                return Err(e);
-            }
-        };
-        let modbus_code = match pcs_conf() {
+        let ctx = connect_modbus_tcp().await?;
+        let modbus_code = match read_csv_to_code("./config/pcs.csv") {
             Ok(c) => c,
             Err(e) => {
                 error!("【PCS】协议生成失败: {}", e.to_string());

+ 3 - 4
src/internal/modbus/code.rs

@@ -1,5 +1,4 @@
-use crate::ems::pcs::PcsCsvData;
-use crate::internal::modbus::{BaseModbusCode, ModbusDataType};
+use crate::internal::modbus::{BaseModbusCode, CsvData, ModbusDataType};
 use std::collections::HashMap;
 
 #[derive(Debug)]
@@ -29,10 +28,10 @@ impl BaseModbusCode for &mut ModbusCode {
     }
 }
 
-impl TryFrom<PcsCsvData> for ModbusCode {
+impl TryFrom<CsvData> for ModbusCode {
     type Error = anyhow::Error;
 
-    fn try_from(value: PcsCsvData) -> Result<Self, Self::Error> {
+    fn try_from(value: CsvData) -> Result<Self, Self::Error> {
         let addr = value.address;
         let code = value.code;
         let name = value.name;

+ 33 - 0
src/internal/modbus/mod.rs

@@ -1,5 +1,38 @@
+use crate::internal::modbus::code::ModbusCode;
+use serde::{Deserialize, Serialize};
+
 pub mod code;
 
+/// CSV对应的结构体
+#[derive(Debug, Serialize, Deserialize)]
+pub struct CsvData {
+    pub address: Option<u16>,
+    pub code: Option<u8>,
+    pub name: Option<String>,
+    pub rw: Option<u8>,
+    #[serde(rename = "type")]
+    pub t: Option<String>,
+    pub factor: Option<f32>,
+    pub unit: Option<String>,
+    pub note: Option<String>,
+    pub desc: Option<String>,
+}
+
+/// 从路径读取csv文档并解析为集合
+/// [path] 文件路径
+/// [Vec<ModbusCode>] 原始配置集合
+pub fn read_csv_to_code(path: &str) -> anyhow::Result<Vec<ModbusCode>> {
+    let mut rdr = csv::Reader::from_path(path)?;
+    let mut vec = Vec::new();
+    for result in rdr.deserialize() {
+        let csv_data: CsvData = result?;
+        let code: ModbusCode = csv_data.try_into()?;
+        vec.push(code);
+    }
+    Ok(vec)
+}
+
+/// 描述了基础ModbusCode
 pub trait BaseModbusCode {
     fn addr(&self) -> Option<u16>;
 }