Werte in den MQTT Broker übermitteln

This commit is contained in:
eneuber committed 2026-02-17 21:01:10 +01:00
1 parent 483d27750b
commit 58bacd2f6d
6 files changed
+310 -8

No files matched your search

+5 -4
View File
@@ -3,7 +3,7 @@ use tera::Tera;
use crate::config::{AppConfig, ModbusValueMaps};
pub struct AppState {
pub config: Mutex<AppConfig>,
pub config: Arc<Mutex<AppConfig>>,
pub value_maps: Arc<Mutex<ModbusValueMaps>>,
pub templates: Tera,
}
@@ -11,9 +11,10 @@ pub struct AppState {
impl AppState {
pub fn load_from_conf(conf_path: &str) -> Self {
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 = Arc::new(Mutex::new(ModbusValueMaps::from_config(&config)));
let config: AppConfig = serde_yaml::from_str(&conf_str).expect("Config-Deserialisierung fehlgeschlagen");
let config = Arc::new(Mutex::new(config));
let value_maps = Arc::new(Mutex::new(ModbusValueMaps::from_config(&config.lock().unwrap())));
let tera = match Tera::new("templates/**/*") {
Ok(t) => t,
@@ -24,7 +25,7 @@ impl AppState {
};
AppState {
config: Mutex::new(config),
config,
value_maps,
templates: tera,
}
+7
View File
@@ -9,6 +9,7 @@ use serde::{Serialize, Deserialize};
mod config;
mod modbus;
mod app_state;
mod mqtt;
pub mod modbus_types;
use crate::config::{AppConfig, ModbusValueMaps};
use crate::modbus_types::{ModbusInputRegisterConfig, ModbusHoldingRegisterConfig, ModbusCoilsConfig};
@@ -247,6 +248,12 @@ async fn main() -> std::io::Result<()> {
);
}
// Starte MQTT-Thread
{
let value_maps = Arc::clone(&app_state.value_maps);
mqtt::start_mqtt_thread(Arc::clone(&app_state.config), value_maps);
}
println!("Server läuft auf http://0.0.0.0:8080");
HttpServer::new(move || {
+101
View File
@@ -0,0 +1,101 @@
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
use crate::config::{AppConfig, ModbusValueMaps};
use rumqttc::{MqttOptions, Client, QoS};
pub fn start_mqtt_thread(config: Arc<Mutex<AppConfig>>, values: Arc<Mutex<ModbusValueMaps>>) {
let mqtt_config = {
let cfg = config.lock().unwrap();
cfg.mqtt.clone()
};
let broker = if mqtt_config.broker.is_empty() { "localhost".to_string() } else { mqtt_config.broker.clone() };
let port = if mqtt_config.port == 0 { 1883 } else { mqtt_config.port };
let path = if let Some(ref p) = mqtt_config.path { p.clone() } else { "paramod/values".to_string() };
let user = mqtt_config.user.clone().unwrap_or_default();
let password = mqtt_config.password.clone().unwrap_or_default();
let user_is_empty = user.is_empty();
thread::spawn(move || {
let mut mqttoptions = MqttOptions::new("paramod-client", broker, port);
if !user_is_empty {
mqttoptions.set_credentials(user, password);
}
let (mut client, mut connection) = Client::new(mqttoptions, 10);
loop {
{
let values = values.lock().unwrap();
// Input Register
for (name, val) in &values.modbus_input_register_values {
if let Some(v) = val {
if should_publish(&config, name, "input_register") {
let topic = format!("{}/{}", path, name);
let payload = format!("{}", v);
let _ = client.publish(topic, QoS::AtLeastOnce, false, payload);
}
}
}
// Holding Register
for (name, val) in &values.modbus_holding_register_values {
if let Some(v) = val {
if should_publish(&config, name, "holding_register") {
let topic = format!("{}/{}", path, name);
let payload = format!("{}", v);
let _ = client.publish(topic, QoS::AtLeastOnce, false, payload);
}
}
}
// Coils
for (name, val) in &values.modbus_coils_values {
if let Some(v) = val {
if should_publish(&config, name, "coils") {
let topic = format!("{}/{}", path, name);
let payload = format!("{}", v);
let _ = client.publish(topic, QoS::AtLeastOnce, false, payload);
}
}
}
}
// Handle MQTT connection events
for _event in connection.iter().take(1) {
// Optionally log or handle events
}
thread::sleep(Duration::from_secs(5));
}
});
}
fn should_publish(config: &Arc<Mutex<AppConfig>>, name: &str, reg_type: &str) -> bool {
let cfg = config.lock().unwrap();
match reg_type {
"input_register" => {
if let Some(regs) = &cfg.modbus_input_register {
for map in regs {
if let Some(reg) = map.get(name) {
return reg.mqtt.unwrap_or(false);
}
}
}
}
"holding_register" => {
if let Some(regs) = &cfg.modbus_holding_register {
for map in regs {
if let Some(reg) = map.get(name) {
return reg.mqtt.unwrap_or(false);
}
}
}
}
"coils" => {
if let Some(coils) = &cfg.modbus_coils {
for map in coils {
if let Some(coil) = map.get(name) {
return coil.mqtt.unwrap_or(false);
}
}
}
}
_ => {}
}
false
}