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
4 changes: 4 additions & 0 deletions packages/control/chargepoint/chargepoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,10 @@ def check_min_max_current(self, required_current: float, phases: int) -> float:
required_current = self.data.get.max_discharge_power / phases / 230
msg = f"Die vom Auto übertragene Entladeleistung begrenzt den Strom auf " \
f"maximal {round(required_current, 2)} A."
# eigene Hardware-Stromgrenze des Ladepunkts auch beim Entladen durchsetzen, nicht nur
# beim Laden - check_cp_max_current() behandelt negative Werte bereits korrekt
# (Vorzeichen wird ueber abs()/sign wieder hergestellt).
required_current = self.check_cp_max_current(required_current, phases)
else:
if self.data.get.max_charge_power / phases / 230 < required_current:
required_current = self.data.get.max_charge_power / phases / 230
Expand Down
29 changes: 29 additions & 0 deletions packages/control/chargepoint/chargepoint_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

from control import data
from control.chargelog import chargelog
from control.chargemode import Chargemode
from control.chargepoint.charging_type import ChargingType
from control.chargepoint.chargepoint import Chargepoint
from control.chargepoint.chargepoint_state import ChargepointState
from control.chargepoint.chargepoint_template import CpTemplate
Expand Down Expand Up @@ -66,6 +68,33 @@ def test_check_min_max_current(required_current, phases, expected_required_curre
assert ret == expected_required_current


@pytest.mark.parametrize("required_current, max_discharge_power, dc_max_current, expected_required_current",
[
pytest.param(-50, -30000, 25, -25,
id="Entladung durch CP-Hardwaregrenze begrenzt"),
pytest.param(-10, -30000, 25, -10,
id="Entladung innerhalb der CP-Hardwaregrenze"),
])
def test_check_min_max_current_bidi_discharge_respects_cp_hardware_limit(
required_current, max_discharge_power, dc_max_current, expected_required_current):
""" Beim Entladen (BIDI_CHARGING, required_current < 0) muss die eigene Hardware-Stromgrenze des
Ladepunkts (dc_max_current) genauso durchgesetzt werden wie beim Laden - vor diesem Fix wurde
check_cp_max_current() im Entlade-Zweig gar nicht aufgerufen (siehe #3795). """
# setup
cp = Chargepoint(0, None)
cp.template = CpTemplate()
cp.template.data.charging_type = ChargingType.DC.value
cp.template.data.dc_max_current = dc_max_current
cp.data.control_parameter.submode = Chargemode.BIDI_CHARGING
cp.data.get.max_discharge_power = max_discharge_power

# evaluation
ret = cp.check_min_max_current(required_current, 1)

# assertion
assert ret == expected_required_current


@dataclass
class Params:
name: str
Expand Down
7 changes: 6 additions & 1 deletion packages/control/counter.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,12 @@ def _set_current_left(self, loadmanagement_available: bool) -> None:
load.data.get.currents)
except KeyError:
element_current = [get_medium_charging_current(load.data.get.currents)]*3
if min(element_current) < 0:
# Vorzeichen anhand der Gesamtleistung entscheiden, nicht anhand einzelner Phasenströme
# (min(element_current) < 0): bei ein-/zweiphasigem Laden zeigen ungenutzte Phasen oft ein
# geringes negatives Messrauschen (zB -0.05A), das sonst den ganzen Load faelschlich als
# Einspeisung einordnet - der eigene Ladestrom wird dann nirgends von currents_raw
# abgezogen und das Lastmanagement haelt die eigene Ladung faelschlich fuer Fremdlast.
if load.data.get.power < 0:
# nur Hausverbraucher ohne Einspeisung
currents_exported_raw = list(map(operator.sub, currents_exported_raw, element_current))
else:
Expand Down
24 changes: 24 additions & 0 deletions packages/control/counter_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,30 @@ def test_set_current_left(loadmanagement_available: bool,
assert counter.data.set.raw_currents_left == expected_raw_currents_left


def test_set_current_left_nets_out_own_current_despite_noise_on_unused_phase(monkeypatch, data_):
""" Ein einphasig ladender Ladepunkt zeigt auf ungenutzten Phasen oft ein geringes negatives
Messrauschen (zB -0.05A). min(element_current) < 0 hat das faelschlich als Einspeisung eingeordnet,
wodurch der eigene Ladestrom nirgends von currents_raw abgezogen wurde - das Lastmanagement hielt
die eigene Ladung dann faelschlich fuer Fremdlast (siehe Matts Log in Discussion #3908)."""
# setup
get_loads_of_counter_mock = Mock(return_value=["cp4"])
monkeypatch.setattr(data.data.counter_all_data, "get_loads_of_counter", get_loads_of_counter_mock)
data.data.cp_data["cp4"].data.config.phase_1 = 1
data.data.cp_data["cp4"].data.get.currents = [20, 0.05, -0.05]
data.data.cp_data["cp4"].data.get.power = 4600
counter = Counter(0)
counter.data.config.max_currents = [35]*3
counter.data.config.max_total_power = 35*3*230
counter.data.config.max_power_errorcase = 7000
counter.data.get.currents = [10, -5, -3]

# execution
counter._set_current_left(True)

# evaluation
assert counter.data.set.raw_currents_left == [45, 40.05, 37.95]


@dataclass
class Params:
name: str
Expand Down
Loading