Skip to content

Commit

Permalink
fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
LKuemmel committed Sep 19, 2024
1 parent cfcb380 commit 4fdc237
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def get_values(self) -> None:
with self.client_error_context:
try:
self.delay_second_cp(self.CP1_DELAY)
evse_state, counter_state = self._client.request_and_check_hardware()
evse_state, counter_state = self._client.request_and_check_hardware(self.fault_state)
if self.version is False:
raise ValueError(
"Firmware des openWB Satellit ist nicht mit openWB 2 kompatibel. "
Expand Down
2 changes: 2 additions & 0 deletions packages/modules/common/component_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ def __init__(
powers: Optional[List[Optional[float]]] = None,
power_factors: Optional[List[Optional[float]]] = None,
frequency: float = 50,
serial_number: str = "",
):
"""Args:
imported: total imported energy in Wh
Expand All @@ -100,6 +101,7 @@ def __init__(
self.exported = exported
self.power = power
self.frequency = frequency
self.serial_number = serial_number


@auto_str
Expand Down
14 changes: 10 additions & 4 deletions packages/modules/common/hardware_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@
"Bitte den openWB series2 satellit stromlos machen.")
METER_PROBLEM = "Der Zähler konnte nicht ausgelesen werden. Vermutlich ist der Zähler falsch konfiguriert oder defekt."
METER_BROKEN = "Die Spannungen des Zählers konnten nicht korrekt ausgelesen werden: {}V Der Zähler ist defekt."
METER_BROKEN_VOLTAGES = ("Die Spannungen des Zählers konnten nicht korrekt ausgelesen werden. "
f"Der Zähler ist defekt.")
METER_BROKEN_VOLTAGES = "Die Spannungen des Zählers konnten nicht korrekt ausgelesen werden. Der Zähler ist defekt."
METER_NO_SERIAL_NUMBER = ("Die Seriennummer des Zählers für das Ladelog kann nicht ausgelesen werden. Wenn Sie die "
"Seriennummer für Abrechnungszwecke benötigen, wenden Sie sich bitte an unseren Support. Die "
"Funktionalität wird dadurch nicht beeinträchtigt!")
Expand Down Expand Up @@ -52,6 +51,12 @@ def evse_client(self) -> Evse: ...
def meter_client(self) -> Any: ...
@property
def read_error(self) -> int: ...
@property
def handle_exception(self, exception: Exception) -> bool: ...
@property
def request_and_check_hardware(self, fault_state: FaultState) -> Tuple[EvseState, CounterState]: ...
@property
def check_meter(self) -> Tuple[bool, Optional[str], CounterState]: ...


class SeriesHardwareCheckMixin:
Expand All @@ -66,7 +71,8 @@ def handle_exception(self: ClientHandlerProtocol, exception: Exception):
else:
return False

def request_and_check_hardware(self: ClientHandlerProtocol, fault_state: FaultState) -> Tuple[EvseState, CounterState]:
def request_and_check_hardware(self: ClientHandlerProtocol,
fault_state: FaultState) -> Tuple[EvseState, CounterState]:
try:
with self.client:
evse_state = self.evse_client.get_evse_state()
Expand Down Expand Up @@ -106,7 +112,7 @@ def check_meter(self: ClientHandlerProtocol) -> Tuple[bool, Optional[str], Count
with self.client:
counter_state = self.meter_client.get_counter_state()
if counter_state.serial_number == "0" or counter_state.serial_number is None:
return True, METER_NO_SERIAL_NUMBER
return True, METER_NO_SERIAL_NUMBER, counter_state
return True, check_meter_values(counter_state), counter_state
except Exception:
return False, METER_PROBLEM, None
44 changes: 28 additions & 16 deletions packages/modules/common/hardware_check_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import pytest
from modules.common import sdm
from modules.common import hardware_check
from modules.common.component_state import CounterState, EvseState
from modules.common.evse import Evse
from modules.common.hardware_check import (
Expand All @@ -19,7 +20,7 @@
[pytest.param(Exception("Modbus"), None, None, [230]*3, None, False, ModbusSerialClient_, EVSE_BROKEN,
id="EVSE defekt"),
pytest.param(Exception("Modbus"), None, None, [230, 0, 230], None, False, ModbusSerialClient_,
EVSE_BROKEN + " " + METER_BROKEN.format([230, 0, 230]) + OPEN_TICKET,
EVSE_BROKEN + " " + METER_BROKEN_VOLTAGES.format([230, 0, 230]) + OPEN_TICKET,
id="EVSE defekt und Zähler eine Phase defekt"),
pytest.param(None, 18, Exception("Modbus"), None, None, None,
ModbusSerialClient_, METER_PROBLEM, id="Zähler falsch konfiguriert"),
Expand Down Expand Up @@ -48,7 +49,11 @@ def test_hardware_check_fails(evse_side_effect,
monkeypatch.setattr(ClientHandler, "_evse_factory", mock_evse_facotry)

counter_state_mock = Mock(spec=CounterState, side_effect=meter_side_effect,
voltages=meter_return_value, currents=[0, 0, 0], powers=[0, 0, 0], power=0)
voltages=meter_return_value,
currents=[0, 0, 0],
powers=[0, 0, 0],
power=0,
serial_number="1234")
mock_meter_client = Mock(spec=sdm.Sdm630_72, get_counter_state=Mock(return_value=counter_state_mock))
mock_find_meter_client = Mock(spec=sdm.Sdm630_72, return_value=mock_meter_client)
monkeypatch.setattr(ClientHandler, "find_meter_client", mock_find_meter_client)
Expand All @@ -72,7 +77,8 @@ def test_hardware_check_succeeds(monkeypatch):
mock_evse_facotry = Mock(spec=Evse, return_value=mock_evse_client)
monkeypatch.setattr(ClientHandler, "_evse_factory", mock_evse_facotry)

counter_state_mock = Mock(spec=CounterState, voltages=[230]*3, currents=[0, 0, 0], powers=[0, 0, 0], power=0)
counter_state_mock = Mock(spec=CounterState, voltages=[
230]*3, currents=[0, 0, 0], powers=[0, 0, 0], power=0, serial_number="1234")
mock_meter_client = Mock(spec=sdm.Sdm630_72, get_counter_state=Mock(return_value=counter_state_mock))
mock_find_meter_client = Mock(spec=sdm.Sdm630_72, return_value=mock_meter_client)
monkeypatch.setattr(ClientHandler, "find_meter_client", mock_find_meter_client)
Expand All @@ -98,7 +104,7 @@ def test_hardware_check_succeeds(monkeypatch):
pytest.param([230]*3, 100, METER_BROKEN, id="Phantom-Leistung"),
]
)
def test_check_meter(voltages, power, expected_msg, monkeypatch):
def test_check_meter_values(voltages, power, expected_msg, monkeypatch):
# setup
counter_state = Mock(voltages=voltages, currents=[0, 0, 0], powers=[0, 0, 0], power=power)
# execution
Expand All @@ -109,28 +115,34 @@ def test_check_meter(voltages, power, expected_msg, monkeypatch):


@patch('modules.common.hardware_check.ClientHandlerProtocol')
@pytest.mark.parametrize("serial_number_return, voltages_return, expected",
[("0", [230]*3, (True, METER_NO_SERIAL_NUMBER)),
(12345, [230]*3, (True, None)),
(Exception(), [230]*3, (False, METER_PROBLEM))])
@pytest.mark.parametrize("serial_number, voltages, expected",
[("0", [230]*3, (True, METER_NO_SERIAL_NUMBER, CounterState)),
(12345, [230]*3, (True, None, CounterState)),
(Exception(), [230]*3, (False, METER_PROBLEM, None))])
def test_check_meter(
MockClientHandlerProtocol: Mock,
serial_number_return: Union[int, Exception],
voltages_return: List[int],
serial_number: Union[int, Exception],
voltages: List[int],
expected: Tuple[bool, Optional[str]],
monkeypatch,
):
# Arrange
mock_meter_client = Mock()
if isinstance(serial_number_return, Exception):
mock_meter_client.get_serial_number.side_effect = serial_number_return

if isinstance(serial_number, Exception):
counter_state_mock = Mock(spec=CounterState, side_effect=serial_number)
else:
mock_meter_client.get_serial_number.return_value = serial_number_return
mock_meter_client.get_voltages.return_value = voltages_return
counter_state_mock = Mock(spec=CounterState, serial_number=serial_number, voltages=voltages)
mock_meter_client = Mock()
mock_meter_client.get_counter_state.return_value = counter_state_mock
MockClientHandlerProtocol.meter_client = mock_meter_client
mixin = SeriesHardwareCheckMixin
mock_check_meter_values = Mock(return_value=expected[1])
monkeypatch.setattr(hardware_check, "check_meter_values", mock_check_meter_values)

# Act
result = mixin.check_meter(MockClientHandlerProtocol)

# Assert
assert result == expected
assert result[0] == expected[0]
assert result[1] == expected[1]
assert isinstance(result[2], expected[2] if expected[2] is not None else type(result[2]))
6 changes: 4 additions & 2 deletions packages/modules/common/sdm.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ def get_counter_state(self) -> CounterState:
currents=self.get_currents(),
powers=powers,
power_factors=self.get_power_factors(),
frequency=self.get_frequency()
frequency=self.get_frequency(),
serial_number=self.get_serial_number()
)


Expand All @@ -79,5 +80,6 @@ def get_counter_state(self) -> CounterState:
power=power,
currents=self.get_currents(),
powers=powers,
frequency=self.get_frequency()
frequency=self.get_frequency(),
serial_number=self.get_serial_number()
)
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def store_state(chargepoint_state: ChargepointState) -> None:
self.store_internal.set(chargepoint_state)
self.store_internal.update()
try:
evse_state, counter_state = self._client.request_and_check_hardware()
evse_state, counter_state = self._client.request_and_check_hardware(self.fault_state)
power = counter_state.power
if counter_state.power < self.PLUG_STANDBY_POWER_THRESHOLD:
power = 0
Expand Down
2 changes: 1 addition & 1 deletion packages/modules/internal_chargepoint_handler/clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def __init__(self,
self.evse_client = self._evse_factory(client, evse_ids)
self.meter_client = self.find_meter_client(CP0_METERS if self.local_charge_point_num == 0 else CP1_METERS,
client)
self.request_and_check_hardware()
self.request_and_check_hardware(fault_state)
self.read_error = 0

def _evse_factory(self, client: Union[ModbusSerialClient_, ModbusTcpClient_], evse_ids: List[int]) -> evse.Evse:
Expand Down

0 comments on commit 4fdc237

Please sign in to comment.