From 9d0496d607b731b69d501f81a8035feb2fa375a5 Mon Sep 17 00:00:00 2001
From: LKuemmel <lena.kuemmel@openwb.de>
Date: Fri, 16 Aug 2024 11:31:06 +0200
Subject: [PATCH 1/3] error timestamp for pro, external, satelllit and smartwb

---
 .../control/chargepoint/chargepoint_data.py   |  1 +
 packages/helpermodules/setdata.py             |  5 +--
 packages/helpermodules/subdata.py             | 31 +++++++++++--------
 packages/helpermodules/utils/error_counter.py | 26 +++++++++++-----
 .../external_openwb/chargepoint_module.py     | 20 ++++++------
 .../openwb_pro/chargepoint_module.py          | 27 ++++++++++------
 .../chargepoint_module.py                     | 17 +++++-----
 .../smartwb/chargepoint_module.py             | 18 +++++------
 8 files changed, 85 insertions(+), 60 deletions(-)

diff --git a/packages/control/chargepoint/chargepoint_data.py b/packages/control/chargepoint/chargepoint_data.py
index 15c9876330..489088db77 100644
--- a/packages/control/chargepoint/chargepoint_data.py
+++ b/packages/control/chargepoint/chargepoint_data.py
@@ -97,6 +97,7 @@ class Get:
     currents: List[float] = field(default_factory=currents_list_factory)
     daily_imported: float = 0
     daily_exported: float = 0
+    error_timestamp: int = 0
     evse_current: Optional[float] = None
     exported: float = 0
     fault_str: str = NO_ERROR
diff --git a/packages/helpermodules/setdata.py b/packages/helpermodules/setdata.py
index 27431294df..5bb7e7e897 100644
--- a/packages/helpermodules/setdata.py
+++ b/packages/helpermodules/setdata.py
@@ -618,8 +618,6 @@ def process_chargepoint_get_topics(self, msg):
             self._validate_value(msg, int, [(0, 2)])
         elif "/get/evse_current" in msg.topic:
             self._validate_value(msg, float, [(0, 0), (6, 32), (600, 3200)])
-        elif "/get/rfid_timestamp" in msg.topic:
-            self._validate_value(msg, float)
         elif ("/get/fault_str" in msg.topic or
                 "/get/state_str" in msg.topic or
                 "/get/heartbeat" in msg.topic or
@@ -627,6 +625,9 @@ def process_chargepoint_get_topics(self, msg):
                 "/get/vehicle_id" in msg.topic or
                 "/get/serial_number" in msg.topic):
             self._validate_value(msg, str)
+        elif ("/get/error_timestamp" in msg.topic or
+                "/get/rfid_timestamp" in msg.topic):
+            self._validate_value(msg, float)
         elif ("/get/soc" in msg.topic):
             self._validate_value(msg, float, [(0, 100)])
         elif "/get/rfid_timestamp" in msg.topic:
diff --git a/packages/helpermodules/subdata.py b/packages/helpermodules/subdata.py
index 728e2e3cab..b851c0a8d4 100644
--- a/packages/helpermodules/subdata.py
+++ b/packages/helpermodules/subdata.py
@@ -425,19 +425,24 @@ def process_chargepoint_topic(self, var: Dict[str, chargepoint.Chargepoint], msg
                     elif re.search("/chargepoint/[0-9]+/get/", msg.topic) is not None:
                         if re.search("/chargepoint/[0-9]+/get/connected_vehicle/", msg.topic) is not None:
                             self.set_json_payload_class(var["cp"+index].chargepoint.data.get.connected_vehicle, msg)
-                        elif (re.search("/chargepoint/[0-9]+/get/soc$", msg.topic) is not None and
-                              decode_payload(msg.payload) != var["cp"+index].chargepoint.data.get.soc):
-                            # Wenn das Auto noch nicht zugeordnet ist, wird der SoC nach der Zuordnung aktualisiert
-                            if var["cp"+index].chargepoint.data.set.charging_ev > -1:
-                                Pub().pub(f'openWB/set/vehicle/{var["cp"+index].chargepoint.data.set.charging_ev}'
-                                          '/get/force_soc_update', True)
-                            self.set_json_payload_class(var["cp"+index].chargepoint.data.get, msg)
-                        elif re.search("/chargepoint/[0-9]+/get/simulation$", msg.topic) is not None:
-                            var["cp"+index].chargepoint.chargepoint_module.sim_counter.data = dataclass_from_dict(
-                                SimCounterState,
-                                decode_payload(msg.payload))
-                        else:
-                            self.set_json_payload_class(var["cp"+index].chargepoint.data.get, msg)
+                        elif re.search("/chargepoint/[0-9]+/get/", msg.topic) is not None:
+                            if (re.search("/chargepoint/[0-9]+/get/soc$", msg.topic) is not None and
+                                    decode_payload(msg.payload) != var["cp"+index].chargepoint.data.get.soc):
+                                # Wenn das Auto noch nicht zugeordnet ist, wird der SoC nach der Zuordnung aktualisiert
+                                if var["cp"+index].chargepoint.data.set.charging_ev > -1:
+                                    Pub().pub(f'openWB/set/vehicle/{var["cp"+index].chargepoint.data.set.charging_ev}'
+                                              '/get/force_soc_update', True)
+                                self.set_json_payload_class(var["cp"+index].chargepoint.data.get, msg)
+                            elif re.search("/chargepoint/[0-9]+/get/error_timestamp$", msg.topic) is not None:
+                                var["cp" +
+                                    index].chargepoint.chargepoint_module.client_error_context.error_timestamp = (
+                                    decode_payload(msg.payload)
+                                )
+                                self.set_json_payload_class(var["cp"+index].chargepoint.data.get, msg)
+                            elif re.search("/chargepoint/[0-9]+/get/simulation$", msg.topic) is not None:
+                                var["cp"+index].chargepoint.chargepoint_module.sim_counter.data = dataclass_from_dict(
+                                    SimCounterState,
+                                    decode_payload(msg.payload))
                     elif re.search("/chargepoint/[0-9]+/config$", msg.topic) is not None:
                         self.process_chargepoint_config_topic(var, msg)
                     elif re.search("/chargepoint/[0-9]+/control_parameter/", msg.topic) is not None:
diff --git a/packages/helpermodules/utils/error_counter.py b/packages/helpermodules/utils/error_counter.py
index c72940258f..e6d1c0c423 100644
--- a/packages/helpermodules/utils/error_counter.py
+++ b/packages/helpermodules/utils/error_counter.py
@@ -1,14 +1,21 @@
 import logging
 
+from helpermodules import timecheck
+from helpermodules.pub import Pub
+
 
 log = logging.getLogger(__name__)
 
+CP_ERROR = ("Anhaltender Fehler beim Auslesen des Ladepunkts. Sollstromstärke, Lade- und Stecker-Status wird "
+            "zurückgesetzt.")
+
 
-class ErrorCounterContext:
-    def __init__(self, exceeded_msg: str, max_errors: int = 2, hide_exception: bool = False):
-        self.max_errors = max_errors
+class ErrorTimerContext:
+    def __init__(self, topic: str, exceeded_msg: str, timeout: int = 60, hide_exception: bool = False):
+        self.topic = topic
+        self.timeout = timeout
         self.hide_exception = hide_exception
-        self.__error_counter = 0
+        self.error_timestamp = None
         self.__exceeded_msg = exceeded_msg
 
     def __enter__(self):
@@ -16,18 +23,21 @@ def __enter__(self):
 
     def __exit__(self, exception_type, exception, exception_traceback) -> bool:
         if exception:
-            self.__error_counter += 1
+            if self.error_timestamp is None:
+                self.error_timestamp = timecheck.create_timestamp()
+                Pub().pub(self.topic, self.error_timestamp)
             log.error(exception)
-            if self.hide_exception is False or self.__error_counter >= self.max_errors:
+            if self.hide_exception is False or timecheck.check_timestamp(self.error_timestamp, self.timeout) is False:
                 raise exception
         return True
 
     def error_counter_exceeded(self) -> bool:
-        if self.__error_counter > self.max_errors:
+        if self.error_timestamp and timecheck.check_timestamp(self.error_timestamp, self.timeout):
             log.error(self.__exceeded_msg)
             return True
         else:
             return False
 
     def reset_error_counter(self):
-        self.__error_counter = 0
+        Pub().pub(self.topic, self.error_timestamp)
+        self.error_timestamp = None
diff --git a/packages/modules/chargepoints/external_openwb/chargepoint_module.py b/packages/modules/chargepoints/external_openwb/chargepoint_module.py
index 304171a0b7..f9b29f1bc1 100644
--- a/packages/modules/chargepoints/external_openwb/chargepoint_module.py
+++ b/packages/modules/chargepoints/external_openwb/chargepoint_module.py
@@ -2,7 +2,7 @@
 
 from control import data
 from helpermodules import pub, timecheck
-from helpermodules.utils.error_counter import ErrorCounterContext
+from helpermodules.utils.error_counter import CP_ERROR, ErrorTimerContext
 from modules.chargepoints.external_openwb.config import OpenWBSeries
 from modules.common.abstract_chargepoint import AbstractChargepoint
 from modules.common.abstract_device import DeviceDescriptor
@@ -16,14 +16,14 @@ def __init__(self, config: OpenWBSeries) -> None:
         self.fault_state = FaultState(ComponentInfo(
             self.config.id,
             "Ladepunkt", "chargepoint"))
-        self.__client_error_context = ErrorCounterContext(
-            "Anhaltender Fehler beim Auslesen des Ladepunkts. Soll-Stromstärke wird zurückgesetzt.")
+        self.client_error_context = ErrorTimerContext(
+            f"openWB/set/chargepoint/{self.config.id}/get/error_timestamp", CP_ERROR, hide_exception=True)
 
     def set_current(self, current: float) -> None:
-        if self.__client_error_context.error_counter_exceeded():
+        if self.client_error_context.error_counter_exceeded():
             current = 0
         with SingleComponentUpdateContext(self.fault_state, False):
-            with self.__client_error_context:
+            with self.client_error_context:
                 if self.config.configuration.duo_num == 0:
                     pub.pub_single("openWB/set/internal_chargepoint/0/data/set_current", current,
                                    hostname=self.config.configuration.ip_address)
@@ -37,7 +37,7 @@ def set_current(self, current: float) -> None:
 
     def get_values(self) -> None:
         with SingleComponentUpdateContext(self.fault_state, update_always=False):
-            with self.__client_error_context:
+            with self.client_error_context:
                 ip_address = self.config.configuration.ip_address
                 num = self.config.id
                 if ip_address == "localhost":
@@ -56,11 +56,11 @@ def get_values(self) -> None:
                 else:
                     pub.pub_single("openWB/set/internal_chargepoint/0/data/parent_cp", str(num), hostname=ip_address)
                     pub.pub_single("openWB/set/isss/parentCPlp1", str(num), hostname=ip_address)
-                self.__client_error_context.reset_error_counter()
+                self.client_error_context.reset_error_counter()
 
     def switch_phases(self, phases_to_use: int, duration: int) -> None:
         with SingleComponentUpdateContext(self.fault_state, False):
-            with self.__client_error_context:
+            with self.client_error_context:
                 pub.pub_single(
                     f"openWB/set/internal_chargepoint/{self.config.configuration.duo_num}/data/phases_to_use",
                     phases_to_use,
@@ -75,7 +75,7 @@ def switch_phases(self, phases_to_use: int, duration: int) -> None:
 
     def interrupt_cp(self, duration: int) -> None:
         with SingleComponentUpdateContext(self.fault_state, False):
-            with self.__client_error_context:
+            with self.client_error_context:
                 ip_address = self.config.configuration.ip_address
                 if (self.config.configuration.duo_num == 1):
                     pub.pub_single("openWB/set/internal_chargepoint/1/data/cp_interruption_duration",
@@ -89,7 +89,7 @@ def interrupt_cp(self, duration: int) -> None:
 
     def clear_rfid(self) -> None:
         with SingleComponentUpdateContext(self.fault_state):
-            with self.__client_error_context:
+            with self.client_error_context:
                 ip_address = self.config.configuration.ip_address
                 pub.pub_single("openWB/set/isss/ClearRfid", 1, hostname=ip_address)
                 pub.pub_single("openWB/set/internal_chargepoint/last_tag", None, hostname=ip_address)
diff --git a/packages/modules/chargepoints/openwb_pro/chargepoint_module.py b/packages/modules/chargepoints/openwb_pro/chargepoint_module.py
index 992199cc20..317c3a8515 100644
--- a/packages/modules/chargepoints/openwb_pro/chargepoint_module.py
+++ b/packages/modules/chargepoints/openwb_pro/chargepoint_module.py
@@ -2,7 +2,7 @@
 import logging
 import time
 
-from helpermodules.utils.error_counter import ErrorCounterContext
+from helpermodules.utils.error_counter import CP_ERROR, ErrorTimerContext
 from modules.chargepoints.openwb_pro.config import OpenWBPro
 from modules.common.abstract_chargepoint import AbstractChargepoint
 from modules.common.abstract_device import DeviceDescriptor
@@ -27,26 +27,27 @@ def __init__(self, config: OpenWBPro) -> None:
             self.config.id,
             "Ladepunkt", "chargepoint"))
         self.__session = req.get_http_session()
-        self.__client_error_context = ErrorCounterContext(
-            "Anhaltender Fehler beim Auslesen des Ladepunkts. Sollstromstärke wird zurückgesetzt.")
+        self.client_error_context = ErrorTimerContext(
+            f"openWB/set/chargepoint/{self.config.id}/get/error_timestamp", CP_ERROR, hide_exception=True)
+        self.old_chargepoint_state = ChargepointState()
 
         with SingleComponentUpdateContext(self.fault_state, False):
-            with self.__client_error_context:
+            with self.client_error_context:
                 self.__session.post(
                     'http://' + self.config.configuration.ip_address + '/connect.php',
                     data={'heartbeatenabled': '1'})
 
     def set_current(self, current: float) -> None:
-        if self.__client_error_context.error_counter_exceeded():
+        if self.client_error_context.error_counter_exceeded():
             current = 0
         with SingleComponentUpdateContext(self.fault_state, False):
-            with self.__client_error_context:
+            with self.client_error_context:
                 ip_address = self.config.configuration.ip_address
                 self.__session.post('http://'+ip_address+'/connect.php', data={'ampere': current})
 
     def get_values(self) -> None:
         with SingleComponentUpdateContext(self.fault_state):
-            with self.__client_error_context:
+            with self.client_error_context:
                 ip_address = self.config.configuration.ip_address
                 json_rsp = self.__session.get('http://'+ip_address+'/connect.php').json()
 
@@ -82,7 +83,15 @@ def get_values(self) -> None:
 
                 self.validate_values(chargepoint_state)
                 self.store.set(chargepoint_state)
-                self.__client_error_context.reset_error_counter()
+                self.old_chargepoint_state = chargepoint_state
+                self.client_error_context.reset_error_counter()
+            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
+                self.store.set(chargepoint_state)
 
     def validate_values(self, chargepoint_state: ChargepointState) -> None:
         if chargepoint_state.charge_state is False and max(chargepoint_state.currents) > 1:
@@ -92,7 +101,7 @@ def validate_values(self, chargepoint_state: ChargepointState) -> None:
 
     def switch_phases(self, phases_to_use: int, duration: int) -> None:
         with SingleComponentUpdateContext(self.fault_state, False):
-            with self.__client_error_context:
+            with self.client_error_context:
                 ip_address = self.config.configuration.ip_address
                 response = self.__session.get('http://'+ip_address+'/connect.php')
                 if response.json()["phases_target"] != phases_to_use:
diff --git a/packages/modules/chargepoints/openwb_series2_satellit/chargepoint_module.py b/packages/modules/chargepoints/openwb_series2_satellit/chargepoint_module.py
index 768bc0a93f..ed60b443dc 100644
--- a/packages/modules/chargepoints/openwb_series2_satellit/chargepoint_module.py
+++ b/packages/modules/chargepoints/openwb_series2_satellit/chargepoint_module.py
@@ -3,7 +3,7 @@
 import time
 from typing import Optional
 
-from helpermodules.utils.error_counter import ErrorCounterContext
+from helpermodules.utils.error_counter import CP_ERROR, ErrorTimerContext
 from modules.chargepoints.openwb_series2_satellit.config import OpenWBseries2Satellit
 from modules.common import modbus
 from modules.common.abstract_chargepoint import AbstractChargepoint
@@ -34,9 +34,8 @@ def __init__(self, config: OpenWBseries2Satellit) -> None:
         with SingleComponentUpdateContext(self.fault_state):
             self.delay_second_cp(self.CP0_DELAY_STARTUP)
             self.store = get_chargepoint_value_store(self.config.id)
-            self.__client_error_context = ErrorCounterContext(
-                "Anhaltender Fehler beim Auslesen des Ladepunkts. Soll-Stromstärke wird zurückgesetzt.",
-                hide_exception=True)
+            self.client_error_context = ErrorTimerContext(
+                f"openWB/set/chargepoint/{self.config.id}/get/error_timestamp", CP_ERROR, hide_exception=True)
             self._create_client()
             self._validate_version()
 
@@ -72,7 +71,7 @@ def _validate_version(self):
     def get_values(self) -> None:
         with SingleComponentUpdateContext(self.fault_state):
             if self.version is not None:
-                with self.__client_error_context:
+                with self.client_error_context:
                     try:
                         self.delay_second_cp(self.CP0_DELAY)
                         with self._client.client:
@@ -97,7 +96,7 @@ def get_values(self) -> None:
                                 serial_number=self._client.meter_client.get_serial_number()
                             )
                         self.store.set(chargepoint_state)
-                        self.__client_error_context.reset_error_counter()
+                        self.client_error_context.reset_error_counter()
                     except AttributeError:
                         self._create_client()
                         self._validate_version()
@@ -107,10 +106,10 @@ def get_values(self) -> None:
 
     def set_current(self, current: float) -> None:
         if self.version is not None:
-            if self.__client_error_context.error_counter_exceeded():
+            if self.client_error_context.error_counter_exceeded():
                 current = 0
             with SingleComponentUpdateContext(self.fault_state, update_always=False):
-                with self.__client_error_context:
+                with self.client_error_context:
                     try:
                         self.delay_second_cp(self.CP0_DELAY)
                         with self._client.client:
@@ -126,7 +125,7 @@ def set_current(self, current: float) -> None:
     def switch_phases(self, phases_to_use: int, duration: int) -> None:
         if self.version is not None:
             with SingleComponentUpdateContext(self.fault_state, update_always=False):
-                with self.__client_error_context:
+                with self.client_error_context:
                     try:
                         with self._client.client:
                             self._client.check_hardware(self.fault_state)
diff --git a/packages/modules/chargepoints/smartwb/chargepoint_module.py b/packages/modules/chargepoints/smartwb/chargepoint_module.py
index f3dcb335e2..25752b8ec3 100644
--- a/packages/modules/chargepoints/smartwb/chargepoint_module.py
+++ b/packages/modules/chargepoints/smartwb/chargepoint_module.py
@@ -1,6 +1,6 @@
 
 import time
-from helpermodules.utils.error_counter import ErrorCounterContext
+from helpermodules.utils.error_counter import CP_ERROR, ErrorTimerContext
 from modules.chargepoints.smartwb.config import SmartWB
 from modules.common.abstract_chargepoint import AbstractChargepoint
 from modules.common.abstract_device import DeviceDescriptor
@@ -18,16 +18,16 @@ def __init__(self, config: SmartWB) -> None:
         self.fault_state = FaultState(ComponentInfo(
             self.config.id,
             "Ladepunkt", "chargepoint"))
-        self.__client_error_context = ErrorCounterContext(
-            "Anhaltender Fehler beim Auslesen des Ladepunkts. Soll-Stromstärke wird zurückgesetzt.")
+        self.client_error_context = ErrorTimerContext(
+            f"openWB/set/chargepoint/{self.config.id}/get/error_timestamp", CP_ERROR, hide_exception=True)
         self.phases_in_use = 1
         self.session = req.get_http_session()
 
     def set_current(self, current: float) -> None:
-        if self.__client_error_context.error_counter_exceeded():
+        if self.client_error_context.error_counter_exceeded():
             current = 0
         with SingleComponentUpdateContext(self.fault_state, False):
-            with self.__client_error_context:
+            with self.client_error_context:
                 ip_address = self.config.configuration.ip_address
                 timeout = self.config.configuration.timeout
                 # Stromvorgabe in Hundertstel Ampere
@@ -36,7 +36,7 @@ def set_current(self, current: float) -> None:
 
     def get_values(self) -> None:
         with SingleComponentUpdateContext(self.fault_state):
-            with self.__client_error_context:
+            with self.client_error_context:
                 ip_address = self.config.configuration.ip_address
                 timeout = self.config.configuration.timeout
                 response = self.session.get('http://'+ip_address+'/getParameters', timeout=timeout)
@@ -91,18 +91,18 @@ def get_values(self) -> None:
                 )
 
                 self.store.set(chargepoint_state)
-                self.__client_error_context.reset_error_counter()
+                self.client_error_context.reset_error_counter()
 
     def clear_rfid(self) -> None:
         with SingleComponentUpdateContext(self.fault_state):
-            with self.__client_error_context:
+            with self.client_error_context:
                 ip_address = self.config.configuration.ip_address
                 timeout = self.config.configuration.timeout
                 req.get_http_session().get('http://'+ip_address+'/clearRfid', timeout=(timeout, None))
 
     def interrupt_cp(self, duration: int) -> None:
         with SingleComponentUpdateContext(self.fault_state, False):
-            with self.__client_error_context:
+            with self.client_error_context:
                 ip_address = self.config.configuration.ip_address
                 timeout = self.config.configuration.timeout
                 req.get_http_session().get(

From bca761ebc6cad9bcdfdc1c89f507658a72b9f463 Mon Sep 17 00:00:00 2001
From: LKuemmel <lena.kuemmel@openwb.de>
Date: Wed, 4 Sep 2024 12:19:08 +0200
Subject: [PATCH 2/3] fix rebase

---
 packages/helpermodules/subdata.py | 37 ++++++++++++++++---------------
 1 file changed, 19 insertions(+), 18 deletions(-)

diff --git a/packages/helpermodules/subdata.py b/packages/helpermodules/subdata.py
index b851c0a8d4..fb832842a0 100644
--- a/packages/helpermodules/subdata.py
+++ b/packages/helpermodules/subdata.py
@@ -425,24 +425,25 @@ def process_chargepoint_topic(self, var: Dict[str, chargepoint.Chargepoint], msg
                     elif re.search("/chargepoint/[0-9]+/get/", msg.topic) is not None:
                         if re.search("/chargepoint/[0-9]+/get/connected_vehicle/", msg.topic) is not None:
                             self.set_json_payload_class(var["cp"+index].chargepoint.data.get.connected_vehicle, msg)
-                        elif re.search("/chargepoint/[0-9]+/get/", msg.topic) is not None:
-                            if (re.search("/chargepoint/[0-9]+/get/soc$", msg.topic) is not None and
-                                    decode_payload(msg.payload) != var["cp"+index].chargepoint.data.get.soc):
-                                # Wenn das Auto noch nicht zugeordnet ist, wird der SoC nach der Zuordnung aktualisiert
-                                if var["cp"+index].chargepoint.data.set.charging_ev > -1:
-                                    Pub().pub(f'openWB/set/vehicle/{var["cp"+index].chargepoint.data.set.charging_ev}'
-                                              '/get/force_soc_update', True)
-                                self.set_json_payload_class(var["cp"+index].chargepoint.data.get, msg)
-                            elif re.search("/chargepoint/[0-9]+/get/error_timestamp$", msg.topic) is not None:
-                                var["cp" +
-                                    index].chargepoint.chargepoint_module.client_error_context.error_timestamp = (
-                                    decode_payload(msg.payload)
-                                )
-                                self.set_json_payload_class(var["cp"+index].chargepoint.data.get, msg)
-                            elif re.search("/chargepoint/[0-9]+/get/simulation$", msg.topic) is not None:
-                                var["cp"+index].chargepoint.chargepoint_module.sim_counter.data = dataclass_from_dict(
-                                    SimCounterState,
-                                    decode_payload(msg.payload))
+                        elif (re.search("/chargepoint/[0-9]+/get/soc$", msg.topic) is not None and
+                              decode_payload(msg.payload) != var["cp"+index].chargepoint.data.get.soc):
+                            # Wenn das Auto noch nicht zugeordnet ist, wird der SoC nach der Zuordnung aktualisiert
+                            if var["cp"+index].chargepoint.data.set.charging_ev > -1:
+                                Pub().pub(f'openWB/set/vehicle/{var["cp"+index].chargepoint.data.set.charging_ev}'
+                                          '/get/force_soc_update', True)
+                            self.set_json_payload_class(var["cp"+index].chargepoint.data.get, msg)
+                        elif re.search("/chargepoint/[0-9]+/get/error_timestamp$", msg.topic) is not None:
+                            var["cp" +
+                                index].chargepoint.chargepoint_module.client_error_context.error_timestamp = (
+                                decode_payload(msg.payload)
+                            )
+                            self.set_json_payload_class(var["cp"+index].chargepoint.data.get, msg)
+                        elif re.search("/chargepoint/[0-9]+/get/simulation$", msg.topic) is not None:
+                            var["cp"+index].chargepoint.chargepoint_module.sim_counter.data = dataclass_from_dict(
+                                SimCounterState,
+                                decode_payload(msg.payload))
+                        else:
+                            self.set_json_payload_class(var["cp"+index].chargepoint.data.get, msg)
                     elif re.search("/chargepoint/[0-9]+/config$", msg.topic) is not None:
                         self.process_chargepoint_config_topic(var, msg)
                     elif re.search("/chargepoint/[0-9]+/control_parameter/", msg.topic) is not None:

From ab508b7197123a0d56cc6e5839fa5cbbc8339838 Mon Sep 17 00:00:00 2001
From: LKuemmel <lena.kuemmel@openwb.de>
Date: Wed, 4 Sep 2024 12:23:09 +0200
Subject: [PATCH 3/3] fix pytest

---
 .../openwb_dc_adapter/chargepoint_module.py      | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/packages/modules/chargepoints/openwb_dc_adapter/chargepoint_module.py b/packages/modules/chargepoints/openwb_dc_adapter/chargepoint_module.py
index 3dcc7f4181..006e7d984c 100644
--- a/packages/modules/chargepoints/openwb_dc_adapter/chargepoint_module.py
+++ b/packages/modules/chargepoints/openwb_dc_adapter/chargepoint_module.py
@@ -3,7 +3,7 @@
 import logging
 
 from helpermodules import hardware_configuration
-from helpermodules.utils.error_counter import ErrorCounterContext
+from helpermodules.utils.error_counter import CP_ERROR, ErrorTimerContext
 from modules.chargepoints.openwb_dc_adapter.config import OpenWBDcAdapter
 from modules.common.abstract_chargepoint import AbstractChargepoint
 from modules.common.abstract_device import DeviceDescriptor
@@ -41,24 +41,24 @@ def __init__(self, config: OpenWBDcAdapter) -> None:
             "Ladepunkt", "chargepoint"))
         self.sim_counter = SimCounterChargepoint(self.config.id)
         self.__session = req.get_http_session()
-        self.__client_error_context = ErrorCounterContext(
-            "Anhaltender Fehler beim Auslesen des Ladepunkts. Sollstromstärke wird zurückgesetzt.")
+        self.client_error_context = ErrorTimerContext(
+            f"openWB/set/chargepoint/{self.config.id}/get/error_timestamp", CP_ERROR, hide_exception=True)
         if hardware_configuration.get_hardware_configuration_setting("openwb_dc_adapter") is False:
             raise Exception(
                 "DC-Laden muss durch den Support freigeschaltet werden. Bitte nehme Kontakt mit dem Support auf.")
         self.efficiency = None
 
         with SingleComponentUpdateContext(self.fault_state, False):
-            with self.__client_error_context:
+            with self.client_error_context:
                 self.__session.post(
                     'http://' + self.config.configuration.ip_address + '/connect.php',
                     data={'heartbeatenabled': '1'})
 
     def set_current(self, current: float) -> None:
-        if self.__client_error_context.error_counter_exceeded():
+        if self.client_error_context.error_counter_exceeded():
             current = 0
         with SingleComponentUpdateContext(self.fault_state, False):
-            with self.__client_error_context:
+            with self.client_error_context:
                 ip_address = self.config.configuration.ip_address
                 raw_current = self.subtract_conversion_loss_from_current(current)
                 raw_power = raw_current * 3 * 230
@@ -73,7 +73,7 @@ def add_conversion_loss_to_current(self, current: float) -> float:
 
     def get_values(self) -> None:
         with SingleComponentUpdateContext(self.fault_state):
-            with self.__client_error_context:
+            with self.client_error_context:
                 ip_address = self.config.configuration.ip_address
                 json_rsp = self.__session.get('http://'+ip_address+'/connect.php').json()
 
@@ -119,7 +119,7 @@ def get_values(self) -> None:
                         json_rsp["state"] == ChargingStatus.UNAVAILABLE_CONN_OBJ.value):
                     raise Exception(f"Ladepunkt nicht verfügbar. Status: {ChargingStatus(json_rsp['state'])}")
                 self.store.set(chargepoint_state)
-                self.__client_error_context.reset_error_counter()
+                self.client_error_context.reset_error_counter()
 
 
 chargepoint_descriptor = DeviceDescriptor(configuration_factory=OpenWBDcAdapter)
