From d0a133bdb8aedec0a3b8d3e9ba7fad864f873468 Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Mon, 19 Oct 2026 14:18:19 +0200 Subject: [PATCH 1/3] Consumer: fix set data validation --- packages/helpermodules/command.py | 8 +-- packages/helpermodules/setdata.py | 89 ++++++++++++++++--------------- 2 files changed, 51 insertions(+), 46 deletions(-) diff --git a/packages/helpermodules/command.py b/packages/helpermodules/command.py index de117189df..06f5edb1dc 100644 --- a/packages/helpermodules/command.py +++ b/packages/helpermodules/command.py @@ -1206,12 +1206,12 @@ def addConsumer(self, connection_id: str, payload: dict) -> None: pub_user_message(payload, connection_id, str(e), MessageType.ERROR) - Pub().pub(f'openWB/set/consumer/{new_id}/module', consumer_default) - Pub().pub(f"openWB/set/consumer/{new_id}/config", asdict(ConsumerConfig())) + Pub().pub(f'openWB/consumer/{new_id}/module', consumer_default) + Pub().pub(f"openWB/consumer/{new_id}/config", asdict(ConsumerConfig())) self._publish_default_metadata_fields(f"openWB/set/consumer/{new_id}", ConsumerGet()) self._publish_default_metadata_fields(f"openWB/set/consumer/{new_id}", ConsumerSet()) - Pub().pub(f"openWB/set/consumer/{new_id}/extra_meter", None) - Pub().pub(f"openWB/set/consumer/{new_id}/usage", asdict(Usage(type=consumer_default["usage"][0]))) + Pub().pub(f"openWB/consumer/{new_id}/extra_meter", None) + Pub().pub(f"openWB/consumer/{new_id}/usage", asdict(Usage(type=consumer_default["usage"][0]))) self.max_id_hierarchy = new_id Pub().pub("openWB/set/command/max_id/hierarchy", new_id) # add ACL roles for consumer access, if user management is active diff --git a/packages/helpermodules/setdata.py b/packages/helpermodules/setdata.py index 659dbb26f3..3a4f49a48e 100644 --- a/packages/helpermodules/setdata.py +++ b/packages/helpermodules/setdata.py @@ -1260,50 +1260,55 @@ def process_consumer_topic(self, msg): "openWB/set/consumer/get/daily_imported" in msg.topic or "openWB/set/consumer/get/daily_exported" in msg.topic): self._validate_value(msg, float) - elif (re.search("openWB/set/consumer/[0-9]+/module$", msg.topic) is not None or - re.search("openWB/set/consumer/[0-9]+/module/simulation$", msg.topic) is not None or - re.search("openWB/set/consumer/[0-9]+/config$", msg.topic) is not None or - re.search("openWB/set/consumer/[0-9]+/usage$", msg.topic) is not None): + elif re.search("openWB/set/consumer/[0-9]+/config$", msg.topic) is not None: self._validate_value(msg, "json") - elif re.search("openWB/set/consumer/[0-9]+/extra_meter$", msg.topic) is not None: - self._validate_value(msg, int) - elif (re.search("consumer/[0-9]+/get/power$", msg.topic) is not None or - re.search("consumer/[0-9]+/set/power$", msg.topic) is not None or - re.search("consumer/[0-9]+/set/current$", msg.topic) is not None or - re.search("consumer/[0-9]+/set/on_time$", msg.topic) is not None or - re.search("consumer/[0-9]+/set/plug_time$", msg.topic) is not None or - re.search("consumer/[0-9]+/set/timestamp_last_current_set$", msg.topic) is not None or - re.search("consumer/[0-9]+/set/timestamp_wrote_last_on_time$", msg.topic) is not None or - re.search("consumer/[0-9]+/get/set_power$", msg.topic) is not None): - self._validate_value(msg, float) - elif (re.search("consumer/[0-9]+/get/currents$", msg.topic) is not None or - re.search("consumer/[0-9]+/get/voltages$", msg.topic) is not None or - re.search("consumer/[0-9]+/get/powers$", msg.topic) is not None or - re.search("consumer/[0-9]+/get/temperatures$", msg.topic) is not None): - self._validate_value(msg, float, collection=list) - elif (re.search("consumer/[0-9]+/get/exported$", msg.topic) is not None or - re.search("consumer/[0-9]+/get/imported$", msg.topic) is not None or - re.search("consumer/[0-9]+/get/daily_exported$", msg.topic) is not None or - re.search("consumer/[0-9]+/get/daily_imported$", msg.topic) is not None): - self._validate_value(msg, float, [(0, float("inf"))]) - elif (re.search("consumer/[0-9]+/get/fault_state$", msg.topic) is not None or - re.search("consumer/get/fault_state$", msg.topic) is not None): - self._validate_value(msg, int, [(0, 2)]) - elif (re.search("consumer/get/fault_str$", msg.topic) is not None or - re.search("consumer/[0-9]+/get/fault_str$", msg.topic) is not None or - re.search("consumer/[0-9]+/get/state_str$", msg.topic) is not None or - re.search("consumer/[0-9]+/set/wait_for_start_state$", msg.topic) is not None): - self._validate_value(msg, str) - elif (re.search("consumer/[0-9]+/get/charge_state$", msg.topic) is not None or - re.search("consumer/[0-9]+/get/plug_state$", msg.topic) is not None or - re.search("consumer/[0-9]+/get/state$", msg.topic) is not None): - self._validate_value(msg, bool) - elif re.search("consumer/[0-9]+/set/phases_to_use$", msg.topic) is not None: - self._validate_value(msg, int, [(0, 3)]) - elif re.search("consumer/[0-9]+/control_parameter/", msg.topic) is not None: - self.process_control_parameter_topics(msg) + elif subdata.SubData.consumer_data.get(f"consumer{get_index(msg.topic)}"): + if (re.search("openWB/set/consumer/[0-9]+/module$", msg.topic) is not None or + re.search("openWB/set/consumer/[0-9]+/module/simulation$", msg.topic) is not None or + re.search("openWB/set/consumer/[0-9]+/config$", msg.topic) is not None or + re.search("openWB/set/consumer/[0-9]+/usage$", msg.topic) is not None): + self._validate_value(msg, "json") + elif re.search("openWB/set/consumer/[0-9]+/extra_meter$", msg.topic) is not None: + self._validate_value(msg, int) + elif (re.search("consumer/[0-9]+/get/power$", msg.topic) is not None or + re.search("consumer/[0-9]+/set/power$", msg.topic) is not None or + re.search("consumer/[0-9]+/set/current$", msg.topic) is not None or + re.search("consumer/[0-9]+/set/on_time$", msg.topic) is not None or + re.search("consumer/[0-9]+/set/plug_time$", msg.topic) is not None or + re.search("consumer/[0-9]+/set/timestamp_last_current_set$", msg.topic) is not None or + re.search("consumer/[0-9]+/set/timestamp_wrote_last_on_time$", msg.topic) is not None or + re.search("consumer/[0-9]+/get/set_power$", msg.topic) is not None): + self._validate_value(msg, float) + elif (re.search("consumer/[0-9]+/get/currents$", msg.topic) is not None or + re.search("consumer/[0-9]+/get/voltages$", msg.topic) is not None or + re.search("consumer/[0-9]+/get/powers$", msg.topic) is not None or + re.search("consumer/[0-9]+/get/temperatures$", msg.topic) is not None): + self._validate_value(msg, float, collection=list) + elif (re.search("consumer/[0-9]+/get/exported$", msg.topic) is not None or + re.search("consumer/[0-9]+/get/imported$", msg.topic) is not None or + re.search("consumer/[0-9]+/get/daily_exported$", msg.topic) is not None or + re.search("consumer/[0-9]+/get/daily_imported$", msg.topic) is not None): + self._validate_value(msg, float, [(0, float("inf"))]) + elif (re.search("consumer/[0-9]+/get/fault_state$", msg.topic) is not None or + re.search("consumer/get/fault_state$", msg.topic) is not None): + self._validate_value(msg, int, [(0, 2)]) + elif (re.search("consumer/get/fault_str$", msg.topic) is not None or + re.search("consumer/[0-9]+/get/fault_str$", msg.topic) is not None or + re.search("consumer/[0-9]+/get/state_str$", msg.topic) is not None or + re.search("consumer/[0-9]+/set/wait_for_start_state$", msg.topic) is not None): + self._validate_value(msg, str) + elif (re.search("consumer/[0-9]+/get/charge_state$", msg.topic) is not None or + re.search("consumer/[0-9]+/get/plug_state$", msg.topic) is not None or + re.search("consumer/[0-9]+/get/state$", msg.topic) is not None): + self._validate_value(msg, bool) + elif re.search("consumer/[0-9]+/set/phases_to_use$", msg.topic) is not None: + self._validate_value(msg, int, [(0, 3)]) + elif re.search("consumer/[0-9]+/control_parameter/", msg.topic) is not None: + self.process_control_parameter_topics(msg) + else: + self.__unknown_topic(msg) else: - self.__unknown_topic(msg) + self.__unknown_id(msg) except Exception: log.exception(f"Fehler im setdata-Modul: Topic {msg.topic}, Value: {msg.payload}") From cf48887ca7d86042b19d9da876e6fcc5ff6d3d54 Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Mon, 19 Oct 2026 14:23:22 +0200 Subject: [PATCH 2/3] fix pytest --- packages/helpermodules/command_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/helpermodules/command_test.py b/packages/helpermodules/command_test.py index ef2c35d72a..95dd27d88c 100644 --- a/packages/helpermodules/command_test.py +++ b/packages/helpermodules/command_test.py @@ -104,7 +104,7 @@ def test_add_consumer_uses_module_default_usage_type(usage_type, mock_pub, monke command_instance.addConsumer("test", {"data": {"vendor": "test", "type": "test_consumer"}}) usage_calls = [call for call in mock_pub.pub.call_args_list - if call.args[0] == "openWB/set/consumer/1/usage"] + if call.args[0] == "openWB/consumer/1/usage"] assert len(usage_calls) == 1 assert usage_calls[0].args[1]["type"] == usage_type.value From bfd5129b249ea763fbc710b3746a0cf35971a732 Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Mon, 19 Oct 2026 14:32:29 +0200 Subject: [PATCH 3/3] Review --- packages/helpermodules/command.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/helpermodules/command.py b/packages/helpermodules/command.py index 06f5edb1dc..34486c9324 100644 --- a/packages/helpermodules/command.py +++ b/packages/helpermodules/command.py @@ -1208,8 +1208,8 @@ def addConsumer(self, connection_id: str, payload: dict) -> None: MessageType.ERROR) Pub().pub(f'openWB/consumer/{new_id}/module', consumer_default) Pub().pub(f"openWB/consumer/{new_id}/config", asdict(ConsumerConfig())) - self._publish_default_metadata_fields(f"openWB/set/consumer/{new_id}", ConsumerGet()) - self._publish_default_metadata_fields(f"openWB/set/consumer/{new_id}", ConsumerSet()) + self._publish_default_metadata_fields(f"openWB/consumer/{new_id}", ConsumerGet()) + self._publish_default_metadata_fields(f"openWB/consumer/{new_id}", ConsumerSet()) Pub().pub(f"openWB/consumer/{new_id}/extra_meter", None) Pub().pub(f"openWB/consumer/{new_id}/usage", asdict(Usage(type=consumer_default["usage"][0]))) self.max_id_hierarchy = new_id