Modbus Werte werden nun ausgelesen
This commit is contained in:
parent
c499f1b97c
commit
459b97d95c
24
Cargo.lock
generated
24
Cargo.lock
generated
@ -355,6 +355,12 @@ version = "3.19.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytes"
|
name = "bytes"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
@ -688,6 +694,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
|
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
"futures-task",
|
"futures-task",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"pin-utils",
|
"pin-utils",
|
||||||
@ -1732,6 +1739,7 @@ dependencies = [
|
|||||||
"serde_yaml",
|
"serde_yaml",
|
||||||
"tera",
|
"tera",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tokio-modbus",
|
||||||
"toml",
|
"toml",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1835,6 +1843,22 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-modbus"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e82dfb1a3265ca939b7a76103c89ad770f8cc0ea8de76c83d352e7c1fc5b2c8b"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"byteorder",
|
||||||
|
"bytes",
|
||||||
|
"futures-util",
|
||||||
|
"log",
|
||||||
|
"smallvec",
|
||||||
|
"tokio",
|
||||||
|
"tokio-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-util"
|
name = "tokio-util"
|
||||||
version = "0.7.17"
|
version = "0.7.17"
|
||||||
|
|||||||
@ -16,3 +16,4 @@ tera = "1.19"
|
|||||||
config = "0.14"
|
config = "0.14"
|
||||||
toml = "0.8"
|
toml = "0.8"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
|
tokio-modbus = "0.7"
|
||||||
|
|||||||
14
paramod.yaml
14
paramod.yaml
@ -1,14 +1,12 @@
|
|||||||
default:
|
default:
|
||||||
loglevel: DEBUG
|
loglevel: DEBUG
|
||||||
darkmode: false
|
darkmode: true
|
||||||
|
|
||||||
mqtt:
|
mqtt:
|
||||||
broker: 192.168.178.2
|
broker: 192.168.178.2
|
||||||
button_circulation: zigbee2mqtt/WirelessButton
|
|
||||||
password: 97sm3pHNSMZ4M5qUj0x8
|
|
||||||
port: 1883
|
port: 1883
|
||||||
user: admin
|
user: admin
|
||||||
|
password: 97sm3pHNSMZ4M5qUj0x8
|
||||||
|
button_circulation: zigbee2mqtt/WirelessButton
|
||||||
influxdb:
|
influxdb:
|
||||||
bucket: Paradigma
|
bucket: Paradigma
|
||||||
location: Radebeul
|
location: Radebeul
|
||||||
@ -16,14 +14,12 @@ influxdb:
|
|||||||
org: skaville
|
org: skaville
|
||||||
token: i-sXFQbEkSC1XVzqFEaFwXwzasbsEIciVlK4SaAUOEvk0VjQPkD3fr8d7_3SPeyseTZkqj7ZMZU78b3n2F6_SQ==
|
token: i-sXFQbEkSC1XVzqFEaFwXwzasbsEIciVlK4SaAUOEvk0VjQPkD3fr8d7_3SPeyseTZkqj7ZMZU78b3n2F6_SQ==
|
||||||
url: 192.168.178.2:8086
|
url: 192.168.178.2:8086
|
||||||
|
|
||||||
modbus:
|
modbus:
|
||||||
host: 192.168.178.10
|
host: 192.168.178.10
|
||||||
|
port: 502
|
||||||
max_coils_addr: 8
|
max_coils_addr: 8
|
||||||
max_holding_addr: 61
|
max_holding_addr: 61
|
||||||
max_input_addr: 45
|
max_input_addr: 45
|
||||||
port: 502
|
|
||||||
|
|
||||||
modbus_coils:
|
modbus_coils:
|
||||||
- MgtSystem: {addr: 0, write: false, mqtt: false, influxdb: false, comment: Leitsystem aktiv}
|
- MgtSystem: {addr: 0, write: false, mqtt: false, influxdb: false, comment: Leitsystem aktiv}
|
||||||
- HK1pres: {addr: 1, write: false, mqtt: false, influxdb: false, comment: HK1 vorhanden}
|
- HK1pres: {addr: 1, write: false, mqtt: false, influxdb: false, comment: HK1 vorhanden}
|
||||||
@ -34,7 +30,6 @@ modbus_coils:
|
|||||||
- Zrelease: {addr: 6, write: true, mqtt: false, influxdb: false, comment: Zirkulation freigegeben}
|
- Zrelease: {addr: 6, write: true, mqtt: false, influxdb: false, comment: Zirkulation freigegeben}
|
||||||
- Zlock: {addr: 7, write: true, mqtt: false, influxdb: false, comment: Zirkulation gesperrt}
|
- Zlock: {addr: 7, write: true, mqtt: false, influxdb: false, comment: Zirkulation gesperrt}
|
||||||
- SHKpres: {addr: 8, write: false, mqtt: false, influxdb: false, comment: Schwimmbadheizkrei vorhanden}
|
- SHKpres: {addr: 8, write: false, mqtt: false, influxdb: false, comment: Schwimmbadheizkrei vorhanden}
|
||||||
|
|
||||||
modbus_input_register:
|
modbus_input_register:
|
||||||
- TA: {addr: 0, type: INT16, factor: 0.1, mqtt: true, influxdb: true}
|
- TA: {addr: 0, type: INT16, factor: 0.1, mqtt: true, influxdb: true}
|
||||||
- TV: {addr: 1, type: INT16, factor: 0.1, mqtt: false, influxdb: true}
|
- TV: {addr: 1, type: INT16, factor: 0.1, mqtt: false, influxdb: true}
|
||||||
@ -81,7 +76,6 @@ modbus_input_register:
|
|||||||
- TKW: {addr: 42, type: INT16, factor: 0.1, mqtt: false, influxdb: true}
|
- TKW: {addr: 42, type: INT16, factor: 0.1, mqtt: false, influxdb: true}
|
||||||
- VKW: {addr: 43, type: INT16, factor: 0.1, mqtt: false, influxdb: true}
|
- VKW: {addr: 43, type: INT16, factor: 0.1, mqtt: false, influxdb: true}
|
||||||
- VSPm: {addr: 44, type: INT16, factor: 0.1, mqtt: false, influxdb: true}
|
- VSPm: {addr: 44, type: INT16, factor: 0.1, mqtt: false, influxdb: true}
|
||||||
|
|
||||||
modbus_holding_register:
|
modbus_holding_register:
|
||||||
- nothing: {addr: 0, type: UINT16, factor: 1, mqtt: false, influxdb: false}
|
- nothing: {addr: 0, type: UINT16, factor: 1, mqtt: false, influxdb: false}
|
||||||
- ErrLS: {addr: 1, type: UINT16, factor: 1, mqtt: false, influxdb: true}
|
- ErrLS: {addr: 1, type: UINT16, factor: 1, mqtt: false, influxdb: true}
|
||||||
|
|||||||
@ -5,31 +5,50 @@ use std::sync::{Arc, Mutex};
|
|||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
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
|
/// Startet einen Thread, der zyklisch Modbus-Register abfragt und ModbusValueMaps aktualisiert
|
||||||
pub fn start_modbus_polling_thread(
|
pub fn start_modbus_polling_thread(
|
||||||
_modbus_config: &ModbusConfig,
|
modbus_config: &ModbusConfig,
|
||||||
input_registers: &Option<Vec<HashMap<String, ModbusRegisterConfig>>>,
|
input_registers: &Option<Vec<HashMap<String, ModbusRegisterConfig>>>,
|
||||||
holding_registers: &Option<Vec<HashMap<String, ModbusRegisterConfig>>>,
|
holding_registers: &Option<Vec<HashMap<String, ModbusRegisterConfig>>>,
|
||||||
coils: &Option<Vec<HashMap<String, ModbusCoilsConfig>>>,
|
coils: &Option<Vec<HashMap<String, ModbusCoilsConfig>>>,
|
||||||
value_maps: Arc<Mutex<ModbusValueMaps>>,
|
value_maps: Arc<Mutex<ModbusValueMaps>>,
|
||||||
poll_interval: Duration,
|
poll_interval: Duration,
|
||||||
) {
|
) {
|
||||||
|
let host = modbus_config.host.clone();
|
||||||
|
let port = modbus_config.port;
|
||||||
|
|
||||||
let input_registers = input_registers.clone();
|
let input_registers = input_registers.clone();
|
||||||
let holding_registers = holding_registers.clone();
|
let holding_registers = holding_registers.clone();
|
||||||
let coils = coils.clone();
|
let coils = coils.clone();
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
|
let addr: SocketAddr = format!("{}:{}", host, port).parse().unwrap();
|
||||||
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
loop {
|
loop {
|
||||||
|
// 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
|
// Input Register
|
||||||
if let Some(ref vec) = input_registers {
|
if let Some(ref vec) = input_registers {
|
||||||
for map in vec {
|
for map in vec {
|
||||||
for (key, reg) in map {
|
for (key, reg) in map {
|
||||||
|
let addr = reg.addr;
|
||||||
let typ = reg.r#type.as_deref().unwrap_or("");
|
let typ = reg.r#type.as_deref().unwrap_or("");
|
||||||
let value = match typ {
|
let factor = reg.factor.unwrap_or(1.0);
|
||||||
"INT16" => { let raw: i16 = 0; raw as f64 },
|
let value = rt.block_on(async {
|
||||||
"UINT16" => { let raw: u16 = 0; raw as f64 },
|
match typ {
|
||||||
"UINT32" => { let raw1: u16 = 0; let raw2: u16 = 0; let raw32: u32 = ((raw1 as u32) << 16) | (raw2 as u32); raw32 as f64 },
|
"INT16" | "UINT16" => client.read_input_registers(addr, 1).await.ok().map(|v| v[0] as f64 * factor),
|
||||||
_ => 0.0,
|
"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() {
|
if let Ok(mut maps) = value_maps.lock() {
|
||||||
maps.modbus_input_register_values.insert(key.clone(), value);
|
maps.modbus_input_register_values.insert(key.clone(), value);
|
||||||
}
|
}
|
||||||
@ -40,13 +59,16 @@ pub fn start_modbus_polling_thread(
|
|||||||
if let Some(ref vec) = holding_registers {
|
if let Some(ref vec) = holding_registers {
|
||||||
for map in vec {
|
for map in vec {
|
||||||
for (key, reg) in map {
|
for (key, reg) in map {
|
||||||
|
let addr = reg.addr;
|
||||||
let typ = reg.r#type.as_deref().unwrap_or("");
|
let typ = reg.r#type.as_deref().unwrap_or("");
|
||||||
let value = match typ {
|
let factor = reg.factor.unwrap_or(1.0);
|
||||||
"INT16" => { let raw: i16 = 0; raw as f64 },
|
let value = rt.block_on(async {
|
||||||
"UINT16" => { let raw: u16 = 0; raw as f64 },
|
match typ {
|
||||||
"UINT32" => { let raw1: u16 = 0; let raw2: u16 = 0; let raw32: u32 = ((raw1 as u32) << 16) | (raw2 as u32); raw32 as f64 },
|
"INT16" | "UINT16" => client.read_holding_registers(addr, 1).await.ok().map(|v| v[0] as f64 * factor),
|
||||||
_ => 0.0,
|
"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() {
|
if let Ok(mut maps) = value_maps.lock() {
|
||||||
maps.modbus_holding_register_values.insert(key.clone(), value);
|
maps.modbus_holding_register_values.insert(key.clone(), value);
|
||||||
}
|
}
|
||||||
@ -56,14 +78,24 @@ pub fn start_modbus_polling_thread(
|
|||||||
// Coils
|
// Coils
|
||||||
if let Some(ref vec) = coils {
|
if let Some(ref vec) = coils {
|
||||||
for map in vec {
|
for map in vec {
|
||||||
for (key, _reg) in map {
|
for (key, reg) in map {
|
||||||
let value = 0.0; // Hier Coil-Wert abfragen
|
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() {
|
if let Ok(mut maps) = value_maps.lock() {
|
||||||
maps.modbus_coils_values.insert(key.clone(), value);
|
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);
|
thread::sleep(poll_interval);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user