diff --git a/packages/conftest.py b/packages/conftest.py index fb6cfc8d44..d41c6d822e 100644 --- a/packages/conftest.py +++ b/packages/conftest.py @@ -224,8 +224,7 @@ def data_hc_counter_() -> None: config=Mock(spec=Config, phase_1=1), get=Mock(spec=Get, currents=[30, 0, 0], power=6900, daily_imported=10000, daily_exported=0, imported=56000, - fault_state=0), - set=Mock(spec=Set, loadmanagement_available=True)))} + fault_state=0)))} data.data.pv_data.update({"pv1": Mock(spec=Pv, data=Mock( spec=PvData, get=Mock(spec=PvGet, power=-10000, daily_exported=6000, exported=27000, currents=None, fault_state=0)))}) diff --git a/packages/control/consumer/consumer_data.py b/packages/control/consumer/consumer_data.py index 2d530fa4b9..e7212a1ae9 100644 --- a/packages/control/consumer/consumer_data.py +++ b/packages/control/consumer/consumer_data.py @@ -4,7 +4,7 @@ from control.chargemode import Chargemode from control.chargepoint.control_parameter import ControlParameter, control_parameter_factory from control.consumer.usage import ConsumerUsage -from dataclass_utils.factories import empty_list_factory +from dataclass_utils.factories import empty_list_factory, voltages_list_factory from helpermodules.abstract_plans import ScheduledPlanConsumer, TimeChargingPlanConsumer from helpermodules.constants import NO_ERROR from modules.common.consumer_setup import ConsumerSetup @@ -82,13 +82,12 @@ class Get: set_power: Optional[float] = None state: Optional[bool] = False state_str: Optional[str] = field(default=None, metadata={"topic": "get/state_str"}) - voltages: Optional[List[Optional[float]]] = None + voltages: List[float] = field(default_factory=voltages_list_factory) @dataclass class Set: current: float = field(default=0, metadata={"topic": "set/current"}) - loadmanagement_available: bool = field(default=False) phases_to_use: int = field(default=1, metadata={"topic": "set/phases_to_use"}) plug_time: Optional[float] = field(default=None, metadata={"topic": "set/plug_time"}) required_power: float = field(default=0) diff --git a/packages/control/load_protocol.py b/packages/control/load_protocol.py index 5a6b33de45..f53807574b 100644 --- a/packages/control/load_protocol.py +++ b/packages/control/load_protocol.py @@ -26,7 +26,6 @@ class LoadGet: @dataclass class LoadSet: current: float - loadmanagement_available: bool phases_to_use: int plug_time: Optional[float] required_power: float diff --git a/packages/helpermodules/command.py b/packages/helpermodules/command.py index e7531c7880..be0cb0c5f9 100644 --- a/packages/helpermodules/command.py +++ b/packages/helpermodules/command.py @@ -1,4 +1,5 @@ import copy +from dataclasses import fields import importlib import json import logging @@ -176,6 +177,15 @@ def on_message(self, client: mqtt.Client, userdata, msg: mqtt.MQTTMessage): except Exception: log.exception("Fehler im Command-Modul") + def _publish_default_metadata_fields(self, topic_prefix: str, data_obj: object) -> None: + data_dict = asdict(data_obj) + for data_field in fields(data_obj): + topic = data_field.metadata.get("topic") + if not topic: + continue + field_value = data_dict.get(data_field.name) + Pub().pub(f"{topic_prefix}/{topic}", field_value) + def addDevice(self, connection_id: str, payload: dict) -> None: """ sendet das Topic, zu dem ein neues Device erstellt werden soll. """ @@ -1190,10 +1200,8 @@ def addConsumer(self, connection_id: str, payload: dict) -> None: MessageType.ERROR) Pub().pub(f'openWB/set/consumer/{new_id}/module', consumer_default) Pub().pub(f"openWB/set/consumer/{new_id}/config", asdict(ConsumerConfig())) - for (k, v) in asdict(ConsumerGet()).items(): - Pub().pub(f"openWB/set/consumer/{new_id}/get/"+k, v) - for (k, v) in asdict(ConsumerSet()).items(): - Pub().pub(f"openWB/set/consumer/{new_id}/set/"+k, v) + 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())) self.max_id_hierarchy = new_id diff --git a/packages/helpermodules/subdata.py b/packages/helpermodules/subdata.py index 0ec99c453c..b994423d23 100644 --- a/packages/helpermodules/subdata.py +++ b/packages/helpermodules/subdata.py @@ -1241,40 +1241,38 @@ def process_legacy_smarthome_topic(self, client: mqtt.Client, var: counter_all.C def process_consumer_topic(self, client: mqtt.Client, var: Dict[str, Consumer], msg: mqtt.MQTTMessage): try: index = get_index(msg.topic) - if re.search("openWB/consumer/[0-9]+/module", msg.topic) is not None: + if re.search("openWB/consumer/[0-9]+/", msg.topic) is not None: if decode_payload(msg.payload) == "": if "consumer"+index in var: var.pop("consumer"+index) - else: - log.error("Es konnte kein Verbraucher mit der ID " + - str(index)+" gefunden werden.") else: if f"consumer{index}" not in var: var[f"consumer{index}"] = Consumer(int(index)) - consumer_config = decode_payload(msg.payload) - con = importlib.import_module( - f".consumers.{consumer_config['vendor']}.{consumer_config['type']}.consumer", - "modules") - config = dataclass_from_dict(con.device_descriptor.configuration_factory, consumer_config) - var["consumer"+index].module = con.create_consumer(config) - var["consumer"+index].data.module = config - elif re.search("openWB/consumer/[0-9]+/config", msg.topic) is not None: - self.set_json_payload_class(var["consumer"+index].data.config, msg) - elif re.search("openWB/consumer/[0-9]+/get", msg.topic) is not None: - self.set_json_payload_class(var["consumer"+index].data.get, msg) - elif re.search("openWB/consumer/[0-9]+/set", msg.topic) is not None: - self.set_json_payload_class(var["consumer"+index].data.set, msg) - elif re.search("openWB/consumer/[0-9]+/extra_meter", msg.topic) is not None: - self.set_json_payload_class(var[f"consumer{index}"].data, msg) - elif re.search("openWB/consumer/[0-9]+/usage$", msg.topic) is not None: - var[f"consumer{index}"].data.usage = dataclass_from_dict(Usage, decode_payload(msg.payload)) - elif re.search("openWB/consumer/[0-9]+/control_parameter/", msg.topic) is not None: - if re.search("openWB/consumer/[0-9]+/control_parameter/limit", msg.topic) is not None: - payload = decode_payload(msg.payload) - var[f"consumer{index}"].data.control_parameter.limit = dataclass_from_dict( - LoadmanagementLimit, payload) - else: - self.set_json_payload_class(var[f"consumer{index}"].data.control_parameter, msg) + if re.search("openWB/consumer/[0-9]+/module", msg.topic) is not None: + consumer_config = decode_payload(msg.payload) + con = importlib.import_module( + f".consumers.{consumer_config['vendor']}.{consumer_config['type']}.consumer", + "modules") + config = dataclass_from_dict(con.device_descriptor.configuration_factory, consumer_config) + var["consumer"+index].module = con.create_consumer(config) + var["consumer"+index].data.module = config + elif re.search("openWB/consumer/[0-9]+/config", msg.topic) is not None: + self.set_json_payload_class(var["consumer"+index].data.config, msg) + elif re.search("openWB/consumer/[0-9]+/get", msg.topic) is not None: + self.set_json_payload_class(var["consumer"+index].data.get, msg) + elif re.search("openWB/consumer/[0-9]+/set", msg.topic) is not None: + self.set_json_payload_class(var["consumer"+index].data.set, msg) + elif re.search("openWB/consumer/[0-9]+/extra_meter", msg.topic) is not None: + self.set_json_payload_class(var[f"consumer{index}"].data, msg) + elif re.search("openWB/consumer/[0-9]+/usage$", msg.topic) is not None: + var[f"consumer{index}"].data.usage = dataclass_from_dict(Usage, decode_payload(msg.payload)) + elif re.search("openWB/consumer/[0-9]+/control_parameter/", msg.topic) is not None: + if re.search("openWB/consumer/[0-9]+/control_parameter/limit", msg.topic) is not None: + payload = decode_payload(msg.payload) + var[f"consumer{index}"].data.control_parameter.limit = dataclass_from_dict( + LoadmanagementLimit, payload) + else: + self.set_json_payload_class(var[f"consumer{index}"].data.control_parameter, msg) elif re.search("/consumer/get/", msg.topic) is not None: self.set_json_payload_class(self.consumer_all_data.data.get, msg) except Exception: