diff --git a/packages/conftest.py b/packages/conftest.py index bb2cea597f..abfa8dc5ea 100644 --- a/packages/conftest.py +++ b/packages/conftest.py @@ -127,7 +127,12 @@ def data_() -> None: store=Mock(spec=LoggingValueStore, delegate=Mock(spec=LoggingValueStore, state=ChargepointState(currents=[30, 0, 0], - power=6900))))), + power=6900, + plug_state=False, + charge_state=False, + imported=None, + exported=None, + phases_in_use=0))))), "cp4": Mock(spec=Chargepoint, data=Mock(spec=ChargepointData, config=Mock(spec=Config, phase_1=2), get=Mock(spec=Get, currents=[0, 15, 15], power=6900, @@ -138,7 +143,12 @@ def data_() -> None: store=Mock(spec=LoggingValueStore, delegate=Mock(spec=LoggingValueStore, state=ChargepointState(currents=[0, 15, 15], - power=6900))))), + power=6900, + plug_state=False, + charge_state=False, + imported=None, + exported=None, + phases_in_use=0))))), "cp5": Mock(spec=Chargepoint, data=Mock(spec=ChargepointData, config=Mock(spec=Config, phase_1=3), get=Mock(spec=Get, currents=[10]*3, power=6900, @@ -149,7 +159,12 @@ def data_() -> None: store=Mock(spec=LoggingValueStore, delegate=Mock(spec=LoggingValueStore, state=ChargepointState(currents=[10]*3, - power=6900)))))} + power=6900, + plug_state=False, + charge_state=False, + imported=None, + exported=None, + phases_in_use=0)))))} data.data.bat_data.update({"bat2": Mock(spec=Bat, num=2, data=Mock(spec=BatData, get=Mock( spec=BatGet, power=-5000, daily_imported=7000, daily_exported=3000, imported=12000, exported=10000, currents=None, fault_state=0), diff --git a/packages/control/bat_all.py b/packages/control/bat_all.py index ff14e62cb3..ef33fedb79 100644 --- a/packages/control/bat_all.py +++ b/packages/control/bat_all.py @@ -113,7 +113,10 @@ def calc_power_for_all_components(self): for battery in data.data.bat_data.values(): try: if battery.data.get.fault_state < 2: - power += battery.data.get.power + try: + power += battery.data.get.power + except Exception: + log.exception(f"Fehler im Bat-Modul {battery.num}") imported += battery.data.get.imported exported += battery.data.get.exported soc_sum += battery.data.get.soc diff --git a/packages/control/chargepoint/chargepoint_all.py b/packages/control/chargepoint/chargepoint_all.py index d2fd2e5075..219227b039 100644 --- a/packages/control/chargepoint/chargepoint_all.py +++ b/packages/control/chargepoint/chargepoint_all.py @@ -69,13 +69,14 @@ def get_cp_sum(self): """ imported, exported, power = 0, 0, 0 try: - for cp in data.data.cp_data: + for cp in data.data.cp_data.values(): + try: + imported = imported + cp.data.get.imported + exported = exported + cp.data.get.exported + except Exception: + log.exception("Fehler in der allgemeinen Ladepunkt-Klasse für Ladepunkt "+cp) try: - if "cp" in cp: - chargepoint = data.data.cp_data[cp] - power = power + chargepoint.data.get.power - imported = imported + chargepoint.data.get.imported - exported = exported + chargepoint.data.get.exported + power = power + cp.data.get.power except Exception: log.exception("Fehler in der allgemeinen Ladepunkt-Klasse für Ladepunkt "+cp) self.data.get.power = power diff --git a/packages/control/pv_all.py b/packages/control/pv_all.py index 7250a32da2..e938636a4c 100644 --- a/packages/control/pv_all.py +++ b/packages/control/pv_all.py @@ -58,27 +58,28 @@ def calc_power_for_all_components(self) -> None: exported = 0 power = 0 fault_state = 0 - for module in data.data.pv_data: + for module in data.data.pv_data.values(): try: - if "pv" in module: - module_data = data.data.pv_data[module].data - if module_data.get.fault_state < 2: - power += module_data.get.power - exported += module_data.get.exported - else: - if fault_state < module_data.get.fault_state: - fault_state = module_data.get.fault_state - limit_value = data.data.io_actions.stepwise_control(data.data.pv_data[module].num) - if limit_value is not None and data.data.pv_data[module].data.get.fault_state == 0: - msg = ( - f"Leistung begrenzt auf {int(limit_value * 100)}%" - if limit_value < 1 - else "Keine Leistungsbegrenzung aktiv." - ) - data.data.pv_data[module].data.get.fault_str = msg - Pub().pub(f"openWB/set/pv/{data.data.pv_data[module].num}/get/fault_str", msg) + if module.data.get.fault_state < 2: + try: + power += module.data.get.power + except Exception: + log.exception(f"Fehler im allgemeinen PV-Modul für pv{module.num}") + exported += module.data.get.exported + else: + if fault_state < module.data.get.fault_state: + fault_state = module.data.get.fault_state + limit_value = data.data.io_actions.stepwise_control(module.num) + if limit_value is not None and module.data.get.fault_state == 0: + msg = ( + f"Leistung begrenzt auf {int(limit_value * 100)}%" + if limit_value < 1 + else "Keine Leistungsbegrenzung aktiv." + ) + module.data.get.fault_str = msg + Pub().pub(f"openWB/set/pv/{module.num}/get/fault_str", msg) except Exception: - log.exception("Fehler im allgemeinen PV-Modul für "+str(module)) + log.exception(f"Fehler im allgemeinen PV-Modul für pv{module.num}") if fault_state == 0: self.data.get.exported = exported Pub().pub("openWB/set/pv/get/exported", self.data.get.exported) diff --git a/packages/helpermodules/utils/__init__.py b/packages/helpermodules/utils/__init__.py index 7253bf39e9..15a1ee8103 100644 --- a/packages/helpermodules/utils/__init__.py +++ b/packages/helpermodules/utils/__init__.py @@ -1,2 +1,3 @@ +from helpermodules.utils._get_default import get_default from helpermodules.utils._thread_handler import joined_thread_handler, thread_handler from helpermodules.utils.processing_counter import ProcessingCounter diff --git a/packages/helpermodules/utils/_get_default.py b/packages/helpermodules/utils/_get_default.py new file mode 100644 index 0000000000..01e11f02f7 --- /dev/null +++ b/packages/helpermodules/utils/_get_default.py @@ -0,0 +1,6 @@ +import inspect + + +def get_default(cls, param): + sig = inspect.signature(cls.__init__) + return sig.parameters[param].default diff --git a/packages/modules/chargepoints/external_openwb/chargepoint_module.py b/packages/modules/chargepoints/external_openwb/chargepoint_module.py index 4babcb0ec9..7116b8a630 100644 --- a/packages/modules/chargepoints/external_openwb/chargepoint_module.py +++ b/packages/modules/chargepoints/external_openwb/chargepoint_module.py @@ -4,6 +4,7 @@ from control import data from helpermodules import pub, timecheck from helpermodules.broker import BrokerClient +from helpermodules.utils import get_default from helpermodules.utils.error_handling import CP_ERROR, ErrorTimerContext from helpermodules.utils.topic_parser import decode_payload from modules.chargepoints.external_openwb.config import OpenWBSeries @@ -44,6 +45,8 @@ def set_current(self, current: float) -> None: hostname=self.config.configuration.ip_address) def get_values(self) -> None: + def parse_received_topics(value: str): + return received_topics.get(f"{topic_prefix}{value}", get_default(ChargepointState, value)) with SingleComponentUpdateContext(self.fault_state): with self.client_error_context: ip_address = self.config.configuration.ip_address @@ -81,35 +84,38 @@ def on_message(client, userdata, message): if received_topics: log.debug(f"Empfange MQTT Daten für Ladepunkt {self.config.id}: {received_topics}") topic_prefix = f"openWB/internal_chargepoint/{self.config.configuration.duo_num}/get/" - chargepoint_state = ChargepointState( - power=received_topics.get(f"{topic_prefix}power"), - phases_in_use=received_topics.get(f"{topic_prefix}phases_in_use"), - imported=received_topics.get(f"{topic_prefix}imported"), - exported=received_topics.get(f"{topic_prefix}exported"), - serial_number=received_topics.get(f"{topic_prefix}serial_number"), - powers=received_topics.get(f"{topic_prefix}powers"), - voltages=received_topics.get(f"{topic_prefix}voltages"), - currents=received_topics.get(f"{topic_prefix}currents"), - power_factors=received_topics.get(f"{topic_prefix}power_factors"), - plug_state=received_topics.get(f"{topic_prefix}plug_state"), - charge_state=received_topics.get(f"{topic_prefix}charge_state"), - rfid=received_topics.get(f"{topic_prefix}rfid"), - rfid_timestamp=received_topics.get(f"{topic_prefix}rfid_timestamp"), - frequency=received_topics.get(f"{topic_prefix}frequency"), - soc=received_topics.get(f"{topic_prefix}soc"), - soc_timestamp=received_topics.get(f"{topic_prefix}soc_timestamp"), - vehicle_id=received_topics.get(f"{topic_prefix}vehicle_id"), - evse_current=received_topics.get(f"{topic_prefix}evse_current"), - max_evse_current=received_topics.get(f"{topic_prefix}max_evse_current"), - version=received_topics.get(f"{topic_prefix}version"), - current_branch=received_topics.get(f"{topic_prefix}current_branch"), - current_commit=received_topics.get(f"{topic_prefix}current_commit") - ) - self.store.set(chargepoint_state) - if received_topics.get(f"{topic_prefix}fault_state") == 2: - self.fault_state.error(received_topics.get(f"{topic_prefix}fault_str")) - elif received_topics.get(f"{topic_prefix}fault_state") == 1: - self.fault_state.warning(received_topics.get(f"{topic_prefix}fault_str")) + try: + chargepoint_state = ChargepointState( + power=received_topics[f"{topic_prefix}power"], + phases_in_use=received_topics[f"{topic_prefix}phases_in_use"], + imported=received_topics[f"{topic_prefix}imported"], + exported=received_topics[f"{topic_prefix}exported"], + serial_number=parse_received_topics("serial_number"), + powers=parse_received_topics("powers"), + voltages=parse_received_topics("voltages"), + currents=received_topics[f"{topic_prefix}currents"], + power_factors=parse_received_topics("power_factors"), + plug_state=received_topics[f"{topic_prefix}plug_state"], + charge_state=received_topics[f"{topic_prefix}charge_state"], + rfid=parse_received_topics("rfid"), + rfid_timestamp=parse_received_topics("rfid_timestamp"), + frequency=parse_received_topics("frequency"), + soc=parse_received_topics("soc"), + soc_timestamp=parse_received_topics("soc_timestamp"), + vehicle_id=parse_received_topics("vehicle_id"), + evse_current=parse_received_topics("evse_current"), + max_evse_current=parse_received_topics("max_evse_current"), + version=parse_received_topics("version"), + current_branch=parse_received_topics("current_branch"), + current_commit=parse_received_topics("current_commit") + ) + self.store.set(chargepoint_state) + if received_topics[f"{topic_prefix}fault_state"] == 2: + self.fault_state.error(received_topics[f"{topic_prefix}fault_str"]) + elif received_topics[f"{topic_prefix}fault_state"] == 1: + self.fault_state.warning(received_topics[f"{topic_prefix}fault_str"]) + except KeyError: + raise KeyError("Es wurden nicht alle notwendigen Daten empfangen.") else: self.fault_state.warning(f"Keine MQTT-Daten für Ladepunkt {self.config.name} empfangen. Noch keine " "Daten nach dem Start oder Ladepunkt nicht erreichbar.") diff --git a/packages/modules/chargepoints/mqtt/chargepoint_module.py b/packages/modules/chargepoints/mqtt/chargepoint_module.py index ec3cee60aa..d837b9c698 100644 --- a/packages/modules/chargepoints/mqtt/chargepoint_module.py +++ b/packages/modules/chargepoints/mqtt/chargepoint_module.py @@ -2,6 +2,7 @@ from helpermodules.broker import BrokerClient from helpermodules.pub import Pub +from helpermodules.utils._get_default import get_default from helpermodules.utils.topic_parser import decode_payload from modules.chargepoints.mqtt.config import Mqtt from modules.common.abstract_chargepoint import AbstractChargepoint @@ -45,6 +46,8 @@ def set_current(self, current: float) -> None: Pub().pub(f"openWB/mqtt/chargepoint/{self.config.id}/set/current", current) def get_values(self) -> None: + def parse_received_topics(value: str): + return received_topics.get(f"{topic_prefix}{value}", get_default(ChargepointState, value)) with SingleComponentUpdateContext(self.fault_state): def on_connect(client, userdata, flags, rc): client.subscribe(f"openWB/mqtt/chargepoint/{self.config.id}/get/#") @@ -59,28 +62,34 @@ def on_message(client, userdata, message): if received_topics: log.debug(f"Empfange MQTT Daten für Ladepunkt {self.config.id}: {received_topics}") topic_prefix = f"openWB/mqtt/chargepoint/{self.config.id}/get/" - chargepoint_state = ChargepointState( - power=received_topics.get(f"{topic_prefix}power"), - phases_in_use=received_topics.get(f"{topic_prefix}phases_in_use"), - imported=received_topics.get(f"{topic_prefix}imported"), - exported=received_topics.get(f"{topic_prefix}exported"), - serial_number=received_topics.get(f"{topic_prefix}serial_number"), - powers=received_topics.get(f"{topic_prefix}powers"), - voltages=received_topics.get(f"{topic_prefix}voltages"), - currents=received_topics.get(f"{topic_prefix}currents"), - power_factors=received_topics.get(f"{topic_prefix}power_factors"), - plug_state=received_topics.get(f"{topic_prefix}plug_state"), - charge_state=received_topics.get(f"{topic_prefix}charge_state"), - rfid=received_topics.get(f"{topic_prefix}rfid"), - rfid_timestamp=received_topics.get(f"{topic_prefix}rfid_timestamp"), - frequency=received_topics.get(f"{topic_prefix}frequency"), - soc=received_topics.get(f"{topic_prefix}soc"), - soc_timestamp=received_topics.get(f"{topic_prefix}soc_timestamp"), - vehicle_id=received_topics.get(f"{topic_prefix}vehicle_id"), - evse_current=received_topics.get(f"{topic_prefix}evse_current"), - max_evse_current=received_topics.get(f"{topic_prefix}max_evse_current") - ) - self.store.set(chargepoint_state) + try: + chargepoint_state = ChargepointState( + power=received_topics[f"{topic_prefix}power"], + phases_in_use=received_topics[f"{topic_prefix}phases_in_use"], + imported=received_topics[f"{topic_prefix}imported"], + exported=received_topics[f"{topic_prefix}exported"], + serial_number=parse_received_topics("serial_number"), + powers=parse_received_topics("powers"), + voltages=parse_received_topics("voltages"), + currents=received_topics[f"{topic_prefix}currents"], + power_factors=parse_received_topics("power_factors"), + plug_state=received_topics[f"{topic_prefix}plug_state"], + charge_state=received_topics[f"{topic_prefix}charge_state"], + rfid=parse_received_topics("rfid"), + rfid_timestamp=parse_received_topics("rfid_timestamp"), + frequency=parse_received_topics("frequency"), + soc=parse_received_topics("soc"), + soc_timestamp=parse_received_topics("soc_timestamp"), + vehicle_id=parse_received_topics("vehicle_id"), + evse_current=parse_received_topics("evse_current"), + max_evse_current=parse_received_topics("max_evse_current"), + version=parse_received_topics("version"), + current_branch=parse_received_topics("current_branch"), + current_commit=parse_received_topics("current_commit") + ) + self.store.set(chargepoint_state) + except KeyError: + raise KeyError("Es wurden nicht alle notwendigen Daten empfangen.") else: self.fault_state.warning(f"Keine MQTT-Daten für Ladepunkt {self.config.name} empfangen oder es werden " "veraltete, abwärtskompatible Topics verwendet. Bitte die Doku in den " diff --git a/packages/modules/chargepoints/openwb_pro/chargepoint_module_test.py b/packages/modules/chargepoints/openwb_pro/chargepoint_module_test.py index 81a2e43b63..f4ca737c38 100644 --- a/packages/modules/chargepoints/openwb_pro/chargepoint_module_test.py +++ b/packages/modules/chargepoints/openwb_pro/chargepoint_module_test.py @@ -116,10 +116,13 @@ def test_openwb_pro(sample_state: Dict, expected_state: Dict, monkeypatch, reque @pytest.mark.parametrize("chargepoint_state, expected_exception, expected_message", [ (ChargepointState(charge_state=False, currents=[0, 2, 0], plug_state=True, - power=0), ValueError, chargepoint_module.ChargepointModule.WRONG_CHARGE_STATE), + power=0, imported=None, exported=None, phases_in_use=0), + ValueError, chargepoint_module.ChargepointModule.WRONG_CHARGE_STATE), (ChargepointState(charge_state=True, currents=[0, 0, 0], plug_state=False, - power=30), ValueError, chargepoint_module.ChargepointModule.WRONG_PLUG_STATE), - (ChargepointState(charge_state=True, currents=[0, 2, 0], plug_state=True, power=30), None, None) + power=30, imported=None, exported=None, phases_in_use=0), + ValueError, chargepoint_module.ChargepointModule.WRONG_PLUG_STATE), + (ChargepointState(charge_state=True, currents=[0, 2, 0], plug_state=True, + power=30, imported=None, exported=None, phases_in_use=0), None, None) ]) def test_validate_values(chargepoint_state, expected_exception, expected_message): cp = chargepoint_module.ChargepointModule(OpenWBPro(configuration=OpenWBProConfiguration(ip_address=SAMPLE_IP))) diff --git a/packages/modules/chargepoints/smartwb/chargepoint_module.py b/packages/modules/chargepoints/smartwb/chargepoint_module.py index 6164256842..ac6f7b7b76 100644 --- a/packages/modules/chargepoints/smartwb/chargepoint_module.py +++ b/packages/modules/chargepoints/smartwb/chargepoint_module.py @@ -80,6 +80,7 @@ def get_values(self) -> None: power=json_rsp["actualPower"] * 1000, currents=currents, imported=json_rsp["meterReading"] * 1000, + exported=0, plug_state=plug_state, charge_state=charge_state, phases_in_use=phases_in_use, diff --git a/packages/modules/chargepoints/smartwb/smartwb_test.py b/packages/modules/chargepoints/smartwb/smartwb_test.py index 2ac20b1e20..396f36b8ae 100644 --- a/packages/modules/chargepoints/smartwb/smartwb_test.py +++ b/packages/modules/chargepoints/smartwb/smartwb_test.py @@ -25,6 +25,7 @@ class TestSmartWb: power=5790, currents=[8.54, 8.54, 8.54], imported=54350.0, + exported=0, plug_state=True, charge_state=False, phases_in_use=3, @@ -58,6 +59,7 @@ class TestSmartWb: currents=[9.78, 0, 0], voltages=[228.28, 231.85, 232.07], imported=54350.0, + exported=0, plug_state=True, charge_state=True, rfid="0a1b2c3d", @@ -96,6 +98,7 @@ class TestSmartWb: currents=[0, 0, 0], voltages=[228.28, 231.85, 232.07], imported=54350.0, + exported=0, plug_state=True, charge_state=True, rfid="0a1b2c3d", diff --git a/packages/modules/common/component_state.py b/packages/modules/common/component_state.py index 0df12c4c6f..969e1cbdd3 100644 --- a/packages/modules/common/component_state.py +++ b/packages/modules/common/component_state.py @@ -162,20 +162,20 @@ def __init__(self, soc: float, range: Optional[float] = None, soc_timestamp: Opt @auto_str class ChargepointState: def __init__(self, - phases_in_use: int = 0, - imported: float = 0, - exported: float = 0, - power: float = 0, + phases_in_use: int, + imported: float, + exported: float, + power: float, + currents: List[float], + charge_state: bool, + plug_state: bool, serial_number: str = "", charging_current: Optional[float] = 0, charging_voltage: Optional[float] = 0, charging_power: Optional[float] = 0, powers: Optional[List[Optional[float]]] = None, voltages: Optional[List[Optional[float]]] = None, - currents: Optional[List[Optional[float]]] = None, power_factors: Optional[List[Optional[float]]] = None, - charge_state: bool = False, - plug_state: bool = False, rfid: Optional[str] = None, rfid_timestamp: Optional[float] = None, frequency: float = 50, diff --git a/packages/modules/common/store/_battery.py b/packages/modules/common/store/_battery.py index 7ca0e9d1a9..da4bf72d57 100644 --- a/packages/modules/common/store/_battery.py +++ b/packages/modules/common/store/_battery.py @@ -33,8 +33,9 @@ def update(self): pub_to_broker("openWB/set/bat/"+str(self.num)+"/get/currents", self.state.currents, 2) pub_to_broker("openWB/set/bat/"+str(self.num)+"/get/power", self.state.power, 2) pub_to_broker("openWB/set/bat/"+str(self.num)+"/get/soc", self.state.soc, 0) - pub_to_broker("openWB/set/bat/"+str(self.num)+"/get/imported", self.state.imported, 2) - pub_to_broker("openWB/set/bat/"+str(self.num)+"/get/exported", self.state.exported, 2) + if self.state.imported is not None and self.state.exported is not None: + pub_to_broker("openWB/set/bat/"+str(self.num)+"/get/imported", self.state.imported, 2) + pub_to_broker("openWB/set/bat/"+str(self.num)+"/get/exported", self.state.exported, 2) except Exception as e: raise FaultState.from_exception(e) diff --git a/packages/modules/common/store/_counter_test.py b/packages/modules/common/store/_counter_test.py index 4617e1b107..b9e20cd649 100644 --- a/packages/modules/common/store/_counter_test.py +++ b/packages/modules/common/store/_counter_test.py @@ -47,7 +47,10 @@ def add_chargepoint(id: int): currents=[ 19.36, 19.36, 19.36], imported=0, - exported=0))))) + exported=0, + phases_in_use=3, + plug_state=True, + charge_state=True))))) def mock_data_standard(): diff --git a/packages/modules/devices/generic/mqtt/bat.py b/packages/modules/devices/generic/mqtt/bat.py index 0e3470c292..bbb1026387 100644 --- a/packages/modules/devices/generic/mqtt/bat.py +++ b/packages/modules/devices/generic/mqtt/bat.py @@ -2,6 +2,7 @@ from typing import Any, Dict, Optional, TypedDict from helpermodules.pub import Pub +from helpermodules.utils._get_default import get_default from modules.common.abstract_device import AbstractBat from modules.common.component_state import BatState from modules.common.fault_state import ComponentInfo, FaultState @@ -26,14 +27,17 @@ def initialize(self) -> None: self.store = get_bat_value_store(self.component_config.id) def update(self, received_topics: Dict) -> None: + def parse_received_topics(value: str): + return received_topics.get(f"{topic_prefix}{value}", get_default(BatState, value)) # [] für erforderliche Topics, .get() für optionale Topics - currents = received_topics.get(f"openWB/mqtt/bat/{self.component_config.id}/get/currents") - power = received_topics[f"openWB/mqtt/bat/{self.component_config.id}/get/power"] - soc = received_topics[f"openWB/mqtt/bat/{self.component_config.id}/get/soc"] - if (received_topics.get(f"openWB/mqtt/bat/{self.component_config.id}/get/imported") and - received_topics.get(f"openWB/mqtt/bat/{self.component_config.id}/get/exported")): - imported = received_topics.get(f"openWB/mqtt/bat/{self.component_config.id}/get/imported") - exported = received_topics.get(f"openWB/mqtt/bat/{self.component_config.id}/get/exported") + topic_prefix = f"openWB/mqtt/bat/{self.component_config.id}/get/" + currents = parse_received_topics("currents") + power = received_topics[f"{topic_prefix}power"] + soc = received_topics[f"{topic_prefix}soc"] + if (received_topics.get(f"{topic_prefix}imported") and + received_topics.get(f"{topic_prefix}exported")): + imported = received_topics[f"{topic_prefix}imported"] + exported = received_topics[f"{topic_prefix}exported"] else: imported, exported = self.sim_counter.sim_count(power) diff --git a/packages/modules/devices/generic/mqtt/counter.py b/packages/modules/devices/generic/mqtt/counter.py index d34dbb1b64..822e3e165d 100644 --- a/packages/modules/devices/generic/mqtt/counter.py +++ b/packages/modules/devices/generic/mqtt/counter.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 from typing import Any, Dict, TypedDict +from helpermodules.utils._get_default import get_default from modules.common.abstract_device import AbstractCounter from modules.common.component_state import CounterState from modules.common.fault_state import ComponentInfo, FaultState @@ -25,17 +26,20 @@ def initialize(self) -> None: self.store = get_counter_value_store(self.component_config.id) def update(self, received_topics: Dict) -> None: + def parse_received_topics(value: str): + return received_topics.get(f"{topic_prefix}{value}", get_default(CounterState, value)) # [] für erforderliche Topics, .get() für optionale Topics - currents = received_topics.get(f"openWB/mqtt/counter/{self.component_config.id}/get/currents") - power = received_topics[f"openWB/mqtt/counter/{self.component_config.id}/get/power"] - frequency = received_topics.get(f"openWB/mqtt/counter/{self.component_config.id}/get/frequency") - power_factors = received_topics.get(f"openWB/mqtt/counter/{self.component_config.id}/get/power_factors") - powers = received_topics.get(f"openWB/mqtt/counter/{self.component_config.id}/get/powers") - voltages = received_topics.get(f"openWB/mqtt/counter/{self.component_config.id}/get/voltages") - if (received_topics.get(f"openWB/mqtt/counter/{self.component_config.id}/get/imported") and - received_topics.get(f"openWB/mqtt/counter/{self.component_config.id}/get/exported")): - imported = received_topics.get(f"openWB/mqtt/counter/{self.component_config.id}/get/imported") - exported = received_topics.get(f"openWB/mqtt/counter/{self.component_config.id}/get/exported") + topic_prefix = f"openWB/mqtt/counter/{self.component_config.id}/get/" + currents = received_topics[f"{topic_prefix}currents"] + power = parse_received_topics("power") + frequency = parse_received_topics("frequency") + power_factors = parse_received_topics("power_factors") + powers = parse_received_topics("powers") + voltages = parse_received_topics("voltages") + if (received_topics.get(f"{topic_prefix}imported") and + received_topics.get(f"{topic_prefix}exported")): + imported = received_topics[f"{topic_prefix}imported"] + exported = received_topics[f"{topic_prefix}exported"] else: imported, exported = self.sim_counter.sim_count(power) diff --git a/packages/modules/devices/generic/mqtt/inverter.py b/packages/modules/devices/generic/mqtt/inverter.py index cd334449ad..26593035d4 100644 --- a/packages/modules/devices/generic/mqtt/inverter.py +++ b/packages/modules/devices/generic/mqtt/inverter.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 from typing import Any, Dict, TypedDict +from helpermodules.utils._get_default import get_default from modules.common.abstract_device import AbstractInverter from modules.common.component_state import InverterState from modules.common.fault_state import ComponentInfo, FaultState @@ -25,18 +26,23 @@ def initialize(self) -> None: self.store = get_inverter_value_store(self.component_config.id) def update(self, received_topics: Dict) -> None: + def parse_received_topics(value: str): + return received_topics.get(f"{topic_prefix}{value}", get_default(InverterState, value)) # [] für erforderliche Topics, .get() für optionale Topics - power = received_topics[f"openWB/mqtt/pv/{self.component_config.id}/get/power"] + topic_prefix = f"openWB/mqtt/pv/{self.component_config.id}/get/" + power = received_topics[f"{topic_prefix}power"] if received_topics.get(f"openWB/mqtt/pv/{self.component_config.id}/get/exported"): - exported = received_topics.get(f"openWB/mqtt/pv/{self.component_config.id}/get/exported") + exported = received_topics[f"{topic_prefix}exported"] else: exported = self.sim_counter.sim_count(power)[1] + currents = parse_received_topics("currents") + dc_power = parse_received_topics("dc_power") inverter_state = InverterState( - currents=received_topics.get(f"openWB/mqtt/pv/{self.component_config.id}/get/currents"), + currents=currents, power=power, exported=exported, - dc_power=received_topics.get(f"openWB/mqtt/pv/{self.component_config.id}/get/dc_power") + dc_power=dc_power ) self.store.set(inverter_state) diff --git a/packages/modules/devices/generic/virtual/counter_test.py b/packages/modules/devices/generic/virtual/counter_test.py index 3c5dd7dcff..a19c60436a 100644 --- a/packages/modules/devices/generic/virtual/counter_test.py +++ b/packages/modules/devices/generic/virtual/counter_test.py @@ -31,10 +31,22 @@ def init_data() -> None: {"id": 3, "type": "cp", "children": []}, {"id": 4, "type": "cp", "children": []}]}]}] data.data.cp_data["cp3"] = Chargepoint(3, None) data.data.cp_data["cp3"].chargepoint_module = ChargepointModule(Mqtt()) - data.data.cp_data["cp3"].chargepoint_module.store.delegate.state = ChargepointState(currents=[16, 16, 0]) + data.data.cp_data["cp3"].chargepoint_module.store.delegate.state = ChargepointState(currents=[16, 16, 0], + plug_state=False, + charge_state=False, + imported=None, + exported=None, + phases_in_use=0, + power=0) data.data.cp_data["cp4"] = Chargepoint(4, None) data.data.cp_data["cp4"].chargepoint_module = ChargepointModule(Mqtt()) - data.data.cp_data["cp4"].chargepoint_module.store.delegate.state = ChargepointState(currents=[16, 16, 16]) + data.data.cp_data["cp4"].chargepoint_module.store.delegate.state = ChargepointState(currents=[16, 16, 16], + plug_state=False, + charge_state=False, + imported=None, + exported=None, + phases_in_use=0, + power=0) def init_twisted_cp() -> None: diff --git a/packages/modules/internal_chargepoint_handler/chargepoint_module.py b/packages/modules/internal_chargepoint_handler/chargepoint_module.py index 4cb49cefe0..74eaf00d46 100644 --- a/packages/modules/internal_chargepoint_handler/chargepoint_module.py +++ b/packages/modules/internal_chargepoint_handler/chargepoint_module.py @@ -43,7 +43,13 @@ def __init__(self, local_charge_point_num: int, self.client_error_context.error_timestamp = internal_cp.get.error_timestamp self.old_plug_state = False self.old_phases_in_use = 0 - self.old_chargepoint_state = ChargepointState() + self.old_chargepoint_state = ChargepointState(plug_state=False, + charge_state=False, + imported=None, + exported=None, + currents=None, + phases_in_use=0, + power=0) self._client = client_handler version = self._client.evse_client.get_firmware_version() with ModifyLoglevelContext(log, logging.DEBUG): @@ -121,11 +127,13 @@ def store_state(chargepoint_state: ChargepointState) -> None: current_commit=self.current_commit ) if self.client_error_context.error_counter_exceeded(): - chargepoint_state = ChargepointState() - chargepoint_state.plug_state = False - chargepoint_state.charge_state = False - chargepoint_state.imported = self.old_chargepoint_state.imported - chargepoint_state.exported = self.old_chargepoint_state.exported + chargepoint_state = ChargepointState(plug_state=False, + charge_state=False, + imported=self.old_chargepoint_state.imported, + exported=self.old_chargepoint_state.exported, + currents=self.old_chargepoint_state.currents, + phases_in_use=self.old_chargepoint_state.phases_in_use, + power=self.old_chargepoint_state.power) store_state(chargepoint_state) self.old_chargepoint_state = chargepoint_state