Modbus Werte werden nun ausgelesen
This commit is contained in:
1 parent
c499f1b97c
commit
459b97d95c
4 files changed
+99
-48
No files matched your search
+70
-38
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user