Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/control/chargepoint/chargepoint_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions packages/helpermodules/setdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -618,15 +618,16 @@ 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
"/get/rfid" in msg.topic or
"/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:
Expand Down
6 changes: 6 additions & 0 deletions packages/helpermodules/subdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,12 @@ def process_chargepoint_topic(self, var: Dict[str, chargepoint.Chargepoint], msg
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,
Expand Down
26 changes: 18 additions & 8 deletions packages/helpermodules/utils/error_counter.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,43 @@
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):
return None

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
20 changes: 10 additions & 10 deletions packages/modules/chargepoints/external_openwb/chargepoint_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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":
Expand All @@ -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,
Expand All @@ -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",
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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()

Expand Down Expand Up @@ -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)
27 changes: 18 additions & 9 deletions packages/modules/chargepoints/openwb_pro/chargepoint_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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()

Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()

Expand Down Expand Up @@ -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:
Expand All @@ -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()
Expand All @@ -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:
Expand All @@ -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)
Expand Down
Loading