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
30 changes: 6 additions & 24 deletions packages/modules/common/hardware_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,11 @@
"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_VOLTAGES = "Die Spannungen des Zählers konnten nicht korrekt ausgelesen werden: {}V Der Zähler ist defekt."
METER_VOLTAGE = "Die Spannung des Zählers ist zu {}. Bitte prüfen Sie die Spannungsversorgung. Spannung: {}V."
METER_VOLTAGE_TOO_HIGH = METER_VOLTAGE.format("hoch", "{}")
METER_VOLTAGE_TOO_LOW = METER_VOLTAGE.format("niedrig", "{}")
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!")
EVSE_BROKEN = ("Auslesen der EVSE nicht möglich. Vermutlich ist die EVSE defekt oder hat eine unbekannte Modbus-ID. "
"(Fehlermeldung nur relevant, wenn diese auf der Startseite oder im Status angezeigt wird.)")
METER_IMPLAUSIBLE_VALUE = ("Der Zähler hat einen unplausiblen Wert zurückgegeben: Leistungen {}W, Ströme {}A, "
"Spannungen {}V.")


def check_meter_values(counter_state: CounterState, fault_state: Optional[FaultState] = None) -> None:
Expand All @@ -36,27 +31,14 @@ def check_meter_values(counter_state: CounterState, fault_state: Optional[FaultS


def _check_meter_values(counter_state: CounterState) -> Optional[str]:
VOLTAGE_HIGH_THRESHOLD = 260
VOLTAGE_LOW_THRESHOLD = 200
VOLTAGE_DETECTED_THRESHOLD = 50 # Phasenaufall detektieren

def valid_voltage(voltage) -> bool:
return VOLTAGE_LOW_THRESHOLD < voltage < VOLTAGE_HIGH_THRESHOLD
# Nur prüfen, dass keine Phase ausgefallen ist
# Es gibt einige Fälle, in denen die Normtoleranzen der Netzspannung nicht eingehalten werden, aber kein Defekt
# vorliegt und der Kunde nicht eingreifen muss. Dann soll keine Warnung angezeigt werden.
# Kona 1-phasig induziert auf L2 40V, Zoe auf L2 130V
# beim Ladestart sind Strom und Spannung nicht immer konsistent.
voltages = counter_state.voltages
# wenn ein Wert in voltages großer VOLTAGE_HIGH_THRESHOLD ist, gebe eine Fehlermeldung zurück
if any(v > VOLTAGE_HIGH_THRESHOLD and v > VOLTAGE_DETECTED_THRESHOLD for v in voltages):
return METER_VOLTAGE_TOO_HIGH.format(voltages)
elif any(v < VOLTAGE_LOW_THRESHOLD and v > VOLTAGE_DETECTED_THRESHOLD for v in voltages):
return METER_VOLTAGE_TOO_LOW.format(voltages)
if not ((valid_voltage(voltages[0]) and voltages[1] == 0 and voltages[2] == 0) or
# Zoe lädt einphasig an einphasiger Wallbox und erzeugt Spannung auf L2 (ca 126V)
(valid_voltage(voltages[0]) and 115 < voltages[1] < 135 and voltages[2] == 0) or
(valid_voltage(voltages[0]) and valid_voltage(voltages[1]) and voltages[2] == 0) or
(valid_voltage(voltages[0]) and valid_voltage(voltages[1]) and valid_voltage((voltages[2])))):
if (voltages[1] == 0 and voltages[2] > 30) or voltages[0] == 0:
return METER_BROKEN_VOLTAGES.format(voltages)
if ((sum(counter_state.currents) < 0.5 and counter_state.power > 230) or
(sum(counter_state.currents) > 1 and counter_state.power < 100)):
return METER_IMPLAUSIBLE_VALUE.format(counter_state.powers, counter_state.currents, counter_state.voltages)
return None


Expand Down
29 changes: 2 additions & 27 deletions packages/modules/common/hardware_check_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
from modules.common.component_state import CounterState, EvseState
from modules.common.evse import Evse
from modules.common.hardware_check import (
EVSE_BROKEN, LAN_ADAPTER_BROKEN, METER_BROKEN_VOLTAGES, METER_IMPLAUSIBLE_VALUE, METER_NO_SERIAL_NUMBER,
METER_PROBLEM, METER_VOLTAGE_TOO_HIGH, METER_VOLTAGE_TOO_LOW, OPEN_TICKET, USB_ADAPTER_BROKEN,
EVSE_BROKEN, LAN_ADAPTER_BROKEN, METER_BROKEN_VOLTAGES, METER_NO_SERIAL_NUMBER,
METER_PROBLEM, OPEN_TICKET, USB_ADAPTER_BROKEN,
SeriesHardwareCheckMixin, _check_meter_values)
from modules.common.modbus import NO_CONNECTION, ModbusSerialClient_, ModbusTcpClient_
from modules.conftest import SAMPLE_IP, SAMPLE_PORT
Expand Down Expand Up @@ -98,8 +98,6 @@ def test_hardware_check_succeeds(monkeypatch):
pytest.param([0, 230, 230], 0, METER_BROKEN_VOLTAGES.format([0, 230, 230]), id="dreiphasig, L1 defekt"),
pytest.param([230, 0, 230], 0, METER_BROKEN_VOLTAGES.format([230, 0, 230]), id="dreiphasig, L2 defekt"),
pytest.param([230]*3, 100, METER_PROBLEM, id="Phantom-Leistung"),
pytest.param([261, 230, 230], 0, METER_VOLTAGE_TOO_HIGH.format([261, 230, 230]), id="Spannung zu hoch"),
pytest.param([230, 230, 199], 0, METER_VOLTAGE_TOO_LOW.format([230, 230, 199]), id="Spannung zu niedrig"),
]
)
def test_check_meter_values_voltages(voltages, power, expected_msg, monkeypatch):
Expand All @@ -112,29 +110,6 @@ def test_check_meter_values_voltages(voltages, power, expected_msg, monkeypatch)
assert msg == expected_msg if expected_msg is None else expected_msg.format(voltages)


@pytest.mark.parametrize(
"currents, power, expected_msg",
[pytest.param([0.4, 0, 0], -80, None, id="Kriechströme"),
pytest.param([1, 0, 0], 0, METER_IMPLAUSIBLE_VALUE.format([0]*3, [1, 0, 0], [230]*3),
id="zu hoher positiver Strom"),
pytest.param([0, -1, 0], 0, METER_IMPLAUSIBLE_VALUE.format([0]*3, [0, -1, 0], [230]*3),
id="zu hoher negativer Strom"),
pytest.param([0.1, 0, 0], 120, METER_IMPLAUSIBLE_VALUE.format([40]*3, [0.1, 5, 0], [230]*3),
id="zu niedriger Strom bei Leistung"),
]
)
def test_check_meter_values_powers(currents, power, expected_msg, monkeypatch):
# setup
counter_state = Mock(spec=CounterState, voltages=[230]*3, currents=currents, powers=[power/3]*3, power=power)
# execution
msg = _check_meter_values(counter_state)

# assert
assert msg == expected_msg if expected_msg is None else expected_msg.format(counter_state.powers,
counter_state.currents,
counter_state.voltages)


@patch('modules.common.hardware_check.ClientHandlerProtocol')
@pytest.mark.parametrize("serial_number, voltages, expected",
[("0", [230]*3, (True, METER_NO_SERIAL_NUMBER, CounterState)),
Expand Down