Modbus Werte werden nun ausgelesen

This commit is contained in:
eneuber committed 2026-02-16 22:33:27 +01:00
1 parent c499f1b97c
commit 459b97d95c
4 files changed
+99 -48

No files matched your search

+70 -38
View File
@@ -5,63 +5,95 @@ use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
use tokio_modbus::prelude::*;
use tokio_modbus::client::tcp;
use std::net::SocketAddr;
/// Startet einen Thread, der zyklisch Modbus-Register abfragt und ModbusValueMaps aktualisiert
pub fn start_modbus_polling_thread(
_modbus_config: &ModbusConfig,
modbus_config: &ModbusConfig,
input_registers: &Option<Vec<HashMap<String, ModbusRegisterConfig>>>,
holding_registers: &Option<Vec<HashMap<String, ModbusRegisterConfig>>>,
coils: &Option<Vec<HashMap<String, ModbusCoilsConfig>>>,
value_maps: Arc<Mutex<ModbusValueMaps>>,
poll_interval: Duration,
) {
let host = modbus_config.host.clone();
let port = modbus_config.port;
let input_registers = input_registers.clone();
let holding_registers = holding_registers.clone();
let coils = coils.clone();
thread::spawn(move || {
let addr: SocketAddr = format!("{}:{}", host, port).parse().unwrap();
let rt = tokio::runtime::Runtime::new().unwrap();
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);
// Verbindungsaufbau
let connect_result = rt.block_on(async {
tcp::connect_slave(addr, 1u8.into()).await
});
match connect_result {
Ok(mut client) => {
// Werte abfragen
// Input Register
if let Some(ref vec) = input_registers {
for map in vec {
for (key, reg) in map {
let addr = reg.addr;
let typ = reg.r#type.as_deref().unwrap_or("");
let factor = reg.factor.unwrap_or(1.0);
let value = rt.block_on(async {
match typ {
"INT16" | "UINT16" => client.read_input_registers(addr, 1).await.ok().map(|v| v[0] as f64 * factor),
"UINT32" => client.read_input_registers(addr, 2).await.ok().map(|v| ((v[0] as u32) << 16 | (v[1] as u32)) as f64 * factor),
_ => Some(0.0),
}
}).unwrap_or(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);
// Holding Register
if let Some(ref vec) = holding_registers {
for map in vec {
for (key, reg) in map {
let addr = reg.addr;
let typ = reg.r#type.as_deref().unwrap_or("");
let factor = reg.factor.unwrap_or(1.0);
let value = rt.block_on(async {
match typ {
"INT16" | "UINT16" => client.read_holding_registers(addr, 1).await.ok().map(|v| v[0] as f64 * factor),
"UINT32" => client.read_holding_registers(addr, 2).await.ok().map(|v| ((v[0] as u32) << 16 | (v[1] as u32)) as f64 * factor),
_ => Some(0.0),
}
}).unwrap_or(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);
// Coils
if let Some(ref vec) = coils {
for map in vec {
for (key, reg) in map {
let addr = reg.addr;
let value = rt.block_on(async {
client.read_coils(addr, 1).await.ok().map(|v| if v[0] { 1.0 } else { 0.0 })
}).unwrap_or(0.0);
if let Ok(mut maps) = value_maps.lock() {
maps.modbus_coils_values.insert(key.clone(), value);
}
}
}
}
},
Err(_) => {
eprintln!("Modbus: Verbindung fehlgeschlagen, retry in {:?}", poll_interval);
thread::sleep(poll_interval);
continue;
}
}
thread::sleep(poll_interval);