From 7b5020cdc645b869427b135c4df1a840a79256fe Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Fri, 6 Jun 2025 10:08:11 +0200 Subject: [PATCH 1/3] set output manual --- packages/helpermodules/setdata.py | 2 ++ packages/helpermodules/subdata.py | 2 ++ packages/modules/common/configurable_io.py | 13 ++++++++++++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/helpermodules/setdata.py b/packages/helpermodules/setdata.py index 2b54d3c7d2..bf6912e257 100644 --- a/packages/helpermodules/setdata.py +++ b/packages/helpermodules/setdata.py @@ -1029,6 +1029,8 @@ def process_system_topic(self, msg: mqtt.MQTTMessage): elif "io" in msg.topic: if "/config" in msg.topic: self._validate_value(msg, "json") + elif "/set/manual" in msg.topic: + self._validate_value(msg, bool) else: # hier kommen auch noch alte Topics ohne json-Format an. # log.error("Unbekanntes set-Topic: "+str(msg.topic)+", "+ diff --git a/packages/helpermodules/subdata.py b/packages/helpermodules/subdata.py index cb26297c36..2767d5ec08 100644 --- a/packages/helpermodules/subdata.py +++ b/packages/helpermodules/subdata.py @@ -980,6 +980,8 @@ def process_system_topic(self, client: mqtt.Client, var: dict, msg: mqtt.MQTTMes "modules") config = dataclass_from_dict(dev.device_descriptor.configuration_factory, io_config) var["io"+index] = dev.create_io(config) + elif re.search("^.+/io/[0-9]+/set/manual", msg.topic) is not None: + var["io"+index].set_manual.update({msg.topic: decode_payload(msg.payload)}) else: if "module_update_completed" in msg.topic: self.event_module_update_completed.set() diff --git a/packages/modules/common/configurable_io.py b/packages/modules/common/configurable_io.py index 6e450bd9f0..8492cb116a 100644 --- a/packages/modules/common/configurable_io.py +++ b/packages/modules/common/configurable_io.py @@ -1,3 +1,4 @@ +import logging from typing import Dict, Optional, TypeVar, Generic, Callable, Union from modules.common import store @@ -9,6 +10,7 @@ T_IO_CONFIG = TypeVar("T_IO_CONFIG") +log = logging.getLogger(__name__) class ConfigurableIo(Generic[T_IO_CONFIG], AbstractIoDevice): @@ -20,6 +22,7 @@ def __init__(self, self.fault_state = FaultState(ComponentInfo(self.config.id, self.config.name, ComponentType.IO.value)) self.store = store.get_io_value_store(self.config.id) + self.set_manual: Dict = {} with SingleComponentUpdateContext(self.fault_state): self.component_reader = component_reader self.component_writer = component_writer @@ -28,7 +31,15 @@ def read(self): if hasattr(self, "component_reader"): # Wenn beim Initialisieren etwas schief gelaufen ist, ursprüngliche Fehlermeldung beibehalten with SingleComponentUpdateContext(self.fault_state): - self.store.set(self.component_reader()) + io_state = self.component_reader() + if len(self.set_manual) > 0: + log.debug(f"Manuell gesetzte Ausgänge: {self.set_manual}") + for manual_output_topic, manual_output_payload in self.set_manual.items(): + splitted_topic = manual_output_topic.split("/") + output = io_state.getattr(splitted_topic[-2]) + output.setattr(splitted_topic[-1], manual_output_payload) + self.set_manual.clear() + self.store.set(io_state) def write(self, analog_output, digital_output): if hasattr(self, "component_writer"): From 1c5da0b4fb220d8d3f4bf4749b4c9dd4688c4029 Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Mon, 16 Jun 2025 09:50:56 +0200 Subject: [PATCH 2/3] fixes --- packages/helpermodules/setdata.py | 3 ++- packages/helpermodules/subdata.py | 8 ++++++-- packages/modules/common/configurable_io.py | 21 +++++++++++++-------- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/packages/helpermodules/setdata.py b/packages/helpermodules/setdata.py index bf6912e257..b67ee96899 100644 --- a/packages/helpermodules/setdata.py +++ b/packages/helpermodules/setdata.py @@ -1029,7 +1029,8 @@ def process_system_topic(self, msg: mqtt.MQTTMessage): elif "io" in msg.topic: if "/config" in msg.topic: self._validate_value(msg, "json") - elif "/set/manual" in msg.topic: + elif ("/set/manual/analog_output" in msg.topic or + "/set/manual/digital_output" in msg.topic): self._validate_value(msg, bool) else: # hier kommen auch noch alte Topics ohne json-Format an. diff --git a/packages/helpermodules/subdata.py b/packages/helpermodules/subdata.py index 2767d5ec08..fa58ead9f3 100644 --- a/packages/helpermodules/subdata.py +++ b/packages/helpermodules/subdata.py @@ -980,8 +980,12 @@ def process_system_topic(self, client: mqtt.Client, var: dict, msg: mqtt.MQTTMes "modules") config = dataclass_from_dict(dev.device_descriptor.configuration_factory, io_config) var["io"+index] = dev.create_io(config) - elif re.search("^.+/io/[0-9]+/set/manual", msg.topic) is not None: - var["io"+index].set_manual.update({msg.topic: decode_payload(msg.payload)}) + elif re.search("^.+/io/[0-9]+/set/manual/analog_output", msg.topic) is not None: + index = get_index(msg.topic) + self.set_json_payload(var["io"+index].set_manual["analog_output"], msg) + elif re.search("^.+/io/[0-9]+/set/manual/digital_output", msg.topic) is not None: + index = get_index(msg.topic) + self.set_json_payload(var["io"+index].set_manual["digital_output"], msg) else: if "module_update_completed" in msg.topic: self.event_module_update_completed.set() diff --git a/packages/modules/common/configurable_io.py b/packages/modules/common/configurable_io.py index 8492cb116a..fe1f2563f0 100644 --- a/packages/modules/common/configurable_io.py +++ b/packages/modules/common/configurable_io.py @@ -1,6 +1,7 @@ import logging from typing import Dict, Optional, TypeVar, Generic, Callable, Union +from helpermodules.pub import Pub from modules.common import store from modules.common.abstract_io import AbstractIoDevice from modules.common.component_context import SingleComponentUpdateContext @@ -22,7 +23,7 @@ def __init__(self, self.fault_state = FaultState(ComponentInfo(self.config.id, self.config.name, ComponentType.IO.value)) self.store = store.get_io_value_store(self.config.id) - self.set_manual: Dict = {} + self.set_manual: Dict = {"analog_output": {}, "digital_output": {}} with SingleComponentUpdateContext(self.fault_state): self.component_reader = component_reader self.component_writer = component_writer @@ -32,19 +33,23 @@ def read(self): # Wenn beim Initialisieren etwas schief gelaufen ist, ursprüngliche Fehlermeldung beibehalten with SingleComponentUpdateContext(self.fault_state): io_state = self.component_reader() - if len(self.set_manual) > 0: - log.debug(f"Manuell gesetzte Ausgänge: {self.set_manual}") - for manual_output_topic, manual_output_payload in self.set_manual.items(): - splitted_topic = manual_output_topic.split("/") - output = io_state.getattr(splitted_topic[-2]) - output.setattr(splitted_topic[-1], manual_output_payload) - self.set_manual.clear() self.store.set(io_state) + def update_manual_output(self, manual: Dict[str, bool], output: Dict[str, bool], string: str, topic_suffix: str): + if len(manual) > 0: + log.debug(f"Manuell gesetzte {string} Ausgänge: {manual}") + for manual_out_pin, manual_out_value in manual.items(): + output[manual_out_pin] = manual_out_value + # nur die in diesem Zyklus gesetzten manuellen Ausgänge setzen, für nächsten Zyklus zurücksetzen + Pub().pub(f"openWB/set/io/{self.config.id}/set/manual/{topic_suffix}/{manual_out_pin}", "") + def write(self, analog_output, digital_output): if hasattr(self, "component_writer"): # Wenn beim Initialisieren etwas schief gelaufen ist, ursprüngliche Fehlermeldung beibehalten with SingleComponentUpdateContext(self.fault_state): + self.update_manual_output(self.set_manual["analog_output"], analog_output, "analoge", "analog_output") + self.update_manual_output(self.set_manual["digital_output"], + digital_output, "digitale", "digital_output") if ((analog_output and self.store.delegate.state.analog_output != analog_output) or (digital_output and self.store.delegate.state.digital_output != digital_output)): io_state = self.component_writer(analog_output, digital_output) From 8b641f7500357f9b7b9b7050121c49b2a0953278 Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Mon, 23 Jun 2025 12:36:47 +0200 Subject: [PATCH 3/3] review --- packages/helpermodules/setdata.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/helpermodules/setdata.py b/packages/helpermodules/setdata.py index b67ee96899..69403d20ff 100644 --- a/packages/helpermodules/setdata.py +++ b/packages/helpermodules/setdata.py @@ -1029,8 +1029,9 @@ def process_system_topic(self, msg: mqtt.MQTTMessage): elif "io" in msg.topic: if "/config" in msg.topic: self._validate_value(msg, "json") - elif ("/set/manual/analog_output" in msg.topic or - "/set/manual/digital_output" in msg.topic): + elif "/set/manual/analog_output" in msg.topic: + self._validate_value(msg, float) + elif "/set/manual/digital_output" in msg.topic: self._validate_value(msg, bool) else: # hier kommen auch noch alte Topics ohne json-Format an.