diff --git a/packages/control/counter_all/hierarchy.py b/packages/control/counter_all/hierarchy.py index 25c0770b76..ebf8dacffa 100644 --- a/packages/control/counter_all/hierarchy.py +++ b/packages/control/counter_all/hierarchy.py @@ -364,12 +364,24 @@ def check_and_remove(name, type_name: ComponentType, data_structure): check_and_remove("consumer", ComponentType.CONSUMER, data.data.consumer_data) def _add_missing_entries(self: HierarchyProtocol): + linked_extra_meter_counter_ids = { + consumer.data.extra_meter + for consumer in data.data.consumer_data.values() + if consumer.data.extra_meter is not None + } + def check_and_add(type_name: ComponentType, data_structure): for entry in data_structure: break_flag = False re_result = re.search("[0-9]+", entry) if re_result is not None: entry_num = int(re_result.group()) + else: + continue + + if type_name == ComponentType.COUNTER and entry_num in linked_extra_meter_counter_ids: + continue + for level in self.get_list_of_elements_per_level(): for element in level: if entry_num == element["id"] and element["type"] == type_name.value: diff --git a/packages/control/counter_all/hierarchy_test.py b/packages/control/counter_all/hierarchy_test.py index 6cf5a1456d..2f0d73d418 100644 --- a/packages/control/counter_all/hierarchy_test.py +++ b/packages/control/counter_all/hierarchy_test.py @@ -1,7 +1,10 @@ from typing import Dict, List, Optional, Union from unittest.mock import Mock import pytest +from control.consumer.consumer import Consumer +from control.consumer.consumer_data import ConsumerData from packages.conftest import hierarchy_hybrid, hierarchy_nested, hierarchy_standard +from control import data from control.counter import Counter @@ -401,6 +404,43 @@ def test_add_missing_entries(hierarchy, expected_hierarchy, data_, monkeypatch): assert counter_all.data.get.hierarchy == expected_hierarchy +def test_add_missing_entries_re_adds_removed_linked_counter(monkeypatch): + # setup + data.data_init(Mock()) + data.data.counter_data = { + "counter0": Mock(spec=Counter, num=0), + "counter6": Mock(spec=Counter, num=6), + } + data.data.bat_data = {} + data.data.cp_data = {} + data.data.pv_data = {} + data.data.consumer_data = {"consumer7": Mock(spec=Consumer, data=Mock(spec=ConsumerData, extra_meter=6))} + + counter_all = CounterAll() + counter_all.data.get.hierarchy = [{ + "id": 0, + "type": "counter", + "children": [ + {"id": 7, "type": "consumer", "children": []}, + ] + }] + + c = Mock(spec=Counter, num=0) + monkeypatch.setattr(CounterAll, "get_evu_counter", Mock(return_value=c)) + + # execution + counter_all._add_missing_entries() + + # evaluation + assert counter_all.data.get.hierarchy == [{ + "id": 0, + "type": "counter", + "children": [ + {"id": 7, "type": "consumer", "children": []}, + ] + }] + + @pytest.mark.parametrize("hierarchy, expected_ids", [ pytest.param(hierarchy_hybrid(), [2], id="hybrid"), diff --git a/packages/helpermodules/command.py b/packages/helpermodules/command.py index a2f44cabb8..de117189df 100644 --- a/packages/helpermodules/command.py +++ b/packages/helpermodules/command.py @@ -7,7 +7,7 @@ import subprocess from threading import Event from time import sleep -from typing import Dict, Optional +from typing import Any, Dict, Optional import re import traceback from pathlib import Path @@ -81,12 +81,13 @@ class Command: def __init__(self, event_command_completed: Event): try: self.event_command_completed = event_command_completed - self._get_max_ids() - self._get_max_id_by_json_object("hierarchy", "counter/get/hierarchy/", -1) + max_id_received_topics = ProcessBrokerBranch("").get_max_id() + self._get_max_ids(max_id_received_topics) + self._get_max_id_hierarchy_by_topics(max_id_received_topics, -1) except Exception: log.exception("Fehler im Command-Modul") - def _get_max_ids(self) -> None: + def _get_max_ids(self, max_id_received_topics: Dict[str, Any]) -> None: """ ermittelt die maximale ID vom Broker """ plan_extractors = { "autolock_plan": lambda p: p.get("autolock", {}).get("plans", []), @@ -97,11 +98,10 @@ def _get_max_ids(self) -> None: "consumer_time_plan": lambda p: p.get("time_charging", {}).get("plans", []), } try: - received_topics = ProcessBrokerBranch("").get_max_id() for max_id_type in self.MAX_IDS.keys(): for id_topic, topic_str, default in self.MAX_IDS[max_id_type]: max_id = default - for topic, payload in received_topics.items(): + for topic, payload in max_id_received_topics.items(): try: if max_id_type == "nested payload": if re.search(topic_str, topic) is not None and payload is not None: @@ -125,13 +125,21 @@ def _get_max_ids(self) -> None: except Exception: log.exception("Fehler im Command-Modul") - def _get_max_id_by_json_object(self, id_topic: str, topic: str, default: int) -> None: - """ ermittelt die maximale ID vom Broker """ + def _get_max_id_hierarchy_by_topics(self, max_id_received_topics: Dict[str, Any], default: int) -> None: + """Ermittelt die maximale Hierarchie-ID ausschließlich aus Topics.""" try: - hierarchy = ProcessBrokerBranch(topic).get_payload() - max_id = counter_all.get_max_id_in_hierarchy(hierarchy, default) - setattr(self, f'max_id_{id_topic}', max_id) - Pub().pub(f'openWB/set/command/max_id/{id_topic}', max_id) + max_id = default + hierarchy_topic_pattern = re.compile(r"openWB/(counter|chargepoint|consumer|pv|bat)/[0-9]+(/|$)") + for topic in max_id_received_topics.keys(): + if hierarchy_topic_pattern.search(topic) is None: + continue + try: + max_id = max(max_id, int(get_index(topic))) + except ValueError: + continue + + self.max_id_hierarchy = max_id + Pub().pub("openWB/set/command/max_id/hierarchy", max_id) except Exception: log.exception("Fehler im Command-Modul") diff --git a/packages/helpermodules/command_test.py b/packages/helpermodules/command_test.py index d01f479802..ef2c35d72a 100644 --- a/packages/helpermodules/command_test.py +++ b/packages/helpermodules/command_test.py @@ -46,7 +46,7 @@ def subdata_fixture() -> None: def test_check_max_num_of_internal_chargepoints(additional_cp_mode, config, expected_msg, subdata_fixture, monkeypatch): # setup monkeypatch.setattr(Command, "_get_max_ids", Mock()) - monkeypatch.setattr(Command, "_get_max_id_by_json_object", Mock()) + monkeypatch.setattr(Command, "_get_max_id_hierarchy_by_topics", Mock()) if additional_cp_mode: SubData.cp_data.update( {"cp1": Mock(spec=ChargepointStateUpdate, chargepoint=Mock( @@ -107,3 +107,15 @@ def test_add_consumer_uses_module_default_usage_type(usage_type, mock_pub, monke if call.args[0] == "openWB/set/consumer/1/usage"] assert len(usage_calls) == 1 assert usage_calls[0].args[1]["type"] == usage_type.value + + +def test_get_max_id_hierarchy_by_topics(mock_pub, monkeypatch): + command_instance = Command.__new__(Command) + command_instance._get_max_id_hierarchy_by_topics({ + "openWB/counter/4/get/power": 500, + "openWB/chargepoint/9/config": {"id": 9}, + "openWB/consumer/5/module": {"type": "dummy"}, + }, -1) + + assert command_instance.max_id_hierarchy == 9 + mock_pub.pub.assert_any_call("openWB/set/command/max_id/hierarchy", 9)