paramod-rust/src/modbus.rs

70 lines
3.0 KiB
Rust

use crate::config::{ModbusValueMaps, ModbusRegisterConfig, ModbusConfig};
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
/// Startet einen Thread, der zyklisch Modbus-Register abfragt und ModbusValueMaps aktualisiert
pub fn start_modbus_polling_thread(
modbus_config: &ModbusConfig,
input_registers: &Option<Vec<HashMap<String, ModbusRegisterConfig>>>,
holding_registers: &Option<Vec<HashMap<String, ModbusRegisterConfig>>>,
coils: &Option<Vec<HashMap<String, ModbusRegisterConfig>>>,
value_maps: Arc<Mutex<ModbusValueMaps>>,
poll_interval: Duration,
) {
let input_registers = input_registers.clone();
let holding_registers = holding_registers.clone();
let coils = coils.clone();
thread::spawn(move || {
loop {
// Input Register
if let Some(ref vec) = input_registers {
for map in vec {
for (key, reg) in map {
let typ = reg.r#type.as_deref().unwrap_or("");
let value = match typ {
"INT16" => { let raw: i16 = 0; raw as f64 },
"UINT16" => { let raw: u16 = 0; raw as f64 },
"UINT32" => { let raw1: u16 = 0; let raw2: u16 = 0; let raw32: u32 = ((raw1 as u32) << 16) | (raw2 as u32); raw32 as f64 },
_ => 0.0,
};
if let Ok(mut maps) = value_maps.lock() {
maps.modbus_input_register_values.insert(key.clone(), value);
}
}
}
}
// Holding Register
if let Some(ref vec) = holding_registers {
for map in vec {
for (key, reg) in map {
let typ = reg.r#type.as_deref().unwrap_or("");
let value = match typ {
"INT16" => { let raw: i16 = 0; raw as f64 },
"UINT16" => { let raw: u16 = 0; raw as f64 },
"UINT32" => { let raw1: u16 = 0; let raw2: u16 = 0; let raw32: u32 = ((raw1 as u32) << 16) | (raw2 as u32); raw32 as f64 },
_ => 0.0,
};
if let Ok(mut maps) = value_maps.lock() {
maps.modbus_holding_register_values.insert(key.clone(), value);
}
}
}
}
// Coils
if let Some(ref vec) = coils {
for map in vec {
for (key, _reg) in map {
let value = 0.0; // Hier Coil-Wert abfragen
if let Ok(mut maps) = value_maps.lock() {
maps.modbus_coils_values.insert(key.clone(), value);
}
}
}
}
thread::sleep(poll_interval);
}
});
}