diff --git a/src/main.rs b/src/main.rs index 606aadd..f4568f5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -63,9 +63,17 @@ pub struct AppConfig { pub modbus_holding_register: Option>>, } +/// Werthaltung für berechnete Modbus-Werte +#[derive(Debug, Default, Clone)] +pub struct ModbusValueMaps { + pub modbus_coils_values: std::collections::HashMap, + pub modbus_input_register_values: std::collections::HashMap, + pub modbus_holding_register_values: std::collections::HashMap, +} struct AppState { config: Mutex, + value_maps: Mutex, templates: Tera, } @@ -74,6 +82,8 @@ impl AppState { let conf_str = std::fs::read_to_string(conf_path).expect("Config-Datei konnte nicht gelesen werden"); let config: AppConfig = serde_yaml::from_str(&conf_str).expect("Config-Deserialisierung fehlgeschlagen"); + let value_maps = Mutex::new(ModbusValueMaps::from_config(&config)); + let tera = match Tera::new("templates/**/*") { Ok(t) => t, Err(e) => { @@ -84,15 +94,50 @@ impl AppState { AppState { config: Mutex::new(config), + value_maps, templates: tera, } } } +impl ModbusValueMaps { + pub fn from_config(config: &AppConfig) -> Self { + let mut coils = HashMap::new(); + if let Some(ref vec) = config.modbus_coils { + for map in vec { + for key in map.keys() { + coils.entry(key.clone()).or_insert(0.0); + } + } + } + let mut input = HashMap::new(); + if let Some(ref vec) = config.modbus_input_register { + for map in vec { + for key in map.keys() { + input.entry(key.clone()).or_insert(0.0); + } + } + } + let mut holding = HashMap::new(); + if let Some(ref vec) = config.modbus_holding_register { + for map in vec { + for key in map.keys() { + holding.entry(key.clone()).or_insert(0.0); + } + } + } + ModbusValueMaps { + modbus_coils_values: coils, + modbus_input_register_values: input, + modbus_holding_register_values: holding, + } + } +} + async fn index(data: web::Data) -> Result { let config = data.config.lock().unwrap(); + let value_maps = data.value_maps.lock().unwrap(); let mut context = Context::new(); - // modbus_input_register als rows, sortiert nach addr let mut rows = config.modbus_input_register.clone().unwrap_or_default(); rows.sort_by(|a, b| { let addr_a = a.values().next().map(|v| v.addr).unwrap_or(0); @@ -102,6 +147,7 @@ async fn index(data: web::Data) -> Result { context.insert("rows", &rows); context.insert("table_id", "modbus_input_register"); context.insert("active_page", "modbus_input_register"); + context.insert("value_map", &value_maps.modbus_input_register_values); let html = data.templates.render("index.html", &context) .map_err(|e| { eprintln!("Template error: {}", e); @@ -113,22 +159,33 @@ async fn index(data: web::Data) -> Result { async fn table_page(data: web::Data, path: web::Path) -> Result { let table_id = path.into_inner(); let config = data.config.lock().unwrap(); - + let value_maps = data.value_maps.lock().unwrap(); let mut context = Context::new(); - let mut rows = match table_id.as_str() { - "modbus_input_register" => config.modbus_input_register.clone().unwrap_or_default(), - "modbus_holding_register" => config.modbus_holding_register.clone().unwrap_or_default(), - "modbus_coils" => config.modbus_coils.clone().unwrap_or_default(), + let (rows, value_map) = match table_id.as_str() { + "modbus_input_register" => ( + config.modbus_input_register.clone().unwrap_or_default(), + &value_maps.modbus_input_register_values + ), + "modbus_holding_register" => ( + config.modbus_holding_register.clone().unwrap_or_default(), + &value_maps.modbus_holding_register_values + ), + "modbus_coils" => ( + config.modbus_coils.clone().unwrap_or_default(), + &value_maps.modbus_coils_values + ), _ => return Ok(HttpResponse::NotFound().body("Table not found")), }; - rows.sort_by(|a, b| { + let mut sorted_rows = rows; + sorted_rows.sort_by(|a, b| { let addr_a = a.values().next().map(|v| v.addr).unwrap_or(0); let addr_b = b.values().next().map(|v| v.addr).unwrap_or(0); addr_a.cmp(&addr_b) }); - context.insert("rows", &rows); + context.insert("rows", &sorted_rows); context.insert("table_id", &table_id); context.insert("active_page", &table_id); + context.insert("value_map", value_map); let html = data.templates.render("index.html", &context) .map_err(|e| { eprintln!("Template error: {}", e); @@ -198,7 +255,11 @@ async fn save_settings( settings: web::Json, ) -> Result { let mut config = data.config.lock().unwrap(); - *config = settings.into_inner(); + let new_config = settings.into_inner(); + // Value-Maps neu initialisieren + let mut value_maps = data.value_maps.lock().unwrap(); + *value_maps = ModbusValueMaps::from_config(&new_config); + *config = new_config; let conf_path = "paramod.yaml"; let yaml_str = match serde_yaml::to_string(&*config) { Ok(s) => s, diff --git a/templates/index.html b/templates/index.html index de9dfc5..6ca3c45 100644 --- a/templates/index.html +++ b/templates/index.html @@ -33,6 +33,7 @@ Bezeichnung + Wert Adresse {% if table_id == "modbus_coils" %} Write @@ -53,6 +54,7 @@ {% for key, row in entry %} + {{ value_map[key] | default(value="-") }} {% if table_id == "modbus_coils" %}