Skip to content

Commit c0911c9

Browse files
committed
move feed_in_limit and feed_in_yield
1 parent 91b8c3a commit c0911c9

File tree

12 files changed

+74
-82
lines changed

12 files changed

+74
-82
lines changed

packages/control/algorithm/surplus_controlled.py

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,7 @@ def set_surplus_current(self) -> None:
3131
for mode_tuple, counter in common.mode_and_counter_generator(CONSIDERED_CHARGE_MODES_SURPLUS):
3232
preferenced_chargepoints, preferenced_cps_without_set_current = get_preferenced_chargepoint_charging(
3333
get_chargepoints_by_mode_and_counter(mode_tuple, f"counter{counter.num}"))
34-
cp_with_feed_in, cp_without_feed_in = self.filter_by_feed_in_limit(preferenced_chargepoints)
35-
if cp_without_feed_in:
36-
self._set(cp_without_feed_in, 0, mode_tuple, counter)
37-
feed_in_yield = data.data.general_data.data.chargemode_config.pv_charging.feed_in_yield
38-
if cp_with_feed_in:
39-
self._set(cp_with_feed_in, feed_in_yield, mode_tuple, counter)
34+
self._set(preferenced_chargepoints, mode_tuple, counter)
4035
if preferenced_cps_without_set_current:
4136
for cp in preferenced_cps_without_set_current:
4237
cp.data.set.current = cp.data.set.target_current
@@ -46,7 +41,6 @@ def set_surplus_current(self) -> None:
4641

4742
def _set(self,
4843
chargepoints: List[Chargepoint],
49-
feed_in_yield: Optional[int],
5044
mode_tuple: Tuple[Optional[str], str, bool],
5145
counter: Counter) -> None:
5246
log.info(f"Mode-Tuple {mode_tuple[0]} - {mode_tuple[1]} - {mode_tuple[2]}, Zähler {counter.num}")
@@ -58,12 +52,11 @@ def _set(self,
5852
missing_currents,
5953
voltages_mean(cp.data.get.voltages),
6054
counter,
61-
cp,
62-
feed_in=feed_in_yield
55+
cp
6356
)
6457
cp.data.control_parameter.limit = limit
6558
available_for_cp = common.available_current_for_cp(cp, counts, available_currents, missing_currents)
66-
if counter.get_control_range_state(feed_in_yield) == ControlRangeState.MIDDLE:
59+
if counter.get_control_range_state() == ControlRangeState.MIDDLE:
6760
pv_charging = data.data.general_data.data.chargemode_config.pv_charging
6861
dif_to_old_current = available_for_cp + cp.data.set.target_current - cp.data.set.current_prev
6962
# Wenn die Differenz zwischen altem und neuem Soll-Strom größer als der Regelbereich ist, trotzdem
@@ -101,14 +94,6 @@ def _set_loadmangement_message(self,
10194
chargepoint.set_state_and_log(f"Es kann nicht mit der vorgegebenen Stromstärke geladen werden"
10295
f"{limit.message}")
10396

104-
# tested
105-
def filter_by_feed_in_limit(self, chargepoints: List[Chargepoint]) -> Tuple[List[Chargepoint], List[Chargepoint]]:
106-
cp_with_feed_in = list(filter(lambda cp: cp.data.set.charge_template.data.chargemode.
107-
pv_charging.feed_in_limit is True, chargepoints))
108-
cp_without_feed_in = list(filter(lambda cp: cp.data.set.charge_template.data.chargemode.
109-
pv_charging.feed_in_limit is False, chargepoints))
110-
return cp_with_feed_in, cp_without_feed_in
111-
11297
def _fix_deviating_evse_current(self, chargepoint: Chargepoint) -> float:
11398
"""Wenn Autos nicht die volle Ladeleistung nutzen, wird unnötig eingespeist. Dann kann um den noch nicht
11499
genutzten Soll-Strom hochgeregelt werden. Wenn Fahrzeuge entgegen der Norm mehr Ladeleistung beziehen, als

packages/control/algorithm/surplus_controlled_test.py

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -30,29 +30,6 @@ def mock_cp3() -> Chargepoint:
3030
return Chargepoint(3, None)
3131

3232

33-
@pytest.mark.parametrize("feed_in_limit_1, feed_in_limit_2, feed_in_limit_3, expected_sorted",
34-
[pytest.param(True, True, True, ([mock_cp1, mock_cp2, mock_cp3], [])),
35-
pytest.param(True, False, True, ([mock_cp1, mock_cp3], [mock_cp2])),
36-
pytest.param(False, False, False, ([], [mock_cp1, mock_cp2, mock_cp3]))])
37-
def test_filter_by_feed_in_limit(feed_in_limit_1: bool,
38-
feed_in_limit_2: bool,
39-
feed_in_limit_3: bool,
40-
expected_sorted: int):
41-
# setup
42-
def setup_cp(cp: Chargepoint, feed_in_limit: bool) -> Chargepoint:
43-
cp.data = ChargepointData()
44-
cp.data.set.charge_template.data.chargemode.pv_charging.feed_in_limit = feed_in_limit
45-
return cp
46-
47-
cp1 = setup_cp(mock_cp1, feed_in_limit_1)
48-
cp2 = setup_cp(mock_cp2, feed_in_limit_2)
49-
cp3 = setup_cp(mock_cp3, feed_in_limit_3)
50-
# execution
51-
cp_with_feed_in, cp_without_feed_in = SurplusControlled().filter_by_feed_in_limit([cp1, cp2, cp3])
52-
# evaluation
53-
assert (cp_with_feed_in, cp_without_feed_in) == expected_sorted
54-
55-
5633
@pytest.mark.parametrize("new_current, expected_current",
5734
[
5835
pytest.param(7, 10),
@@ -129,16 +106,21 @@ def test_add_unused_evse_current(evse_current: float,
129106

130107

131108
@pytest.mark.parametrize(
132-
"submode_1, submode_2, expected_chargepoints",
109+
"submode_1, submode_2, expected_cp_indices",
133110
[
134-
pytest.param(Chargemode.PV_CHARGING, Chargemode.PV_CHARGING, [mock_cp1, mock_cp2]),
135-
pytest.param(Chargemode.INSTANT_CHARGING, Chargemode.PV_CHARGING, [mock_cp2]),
111+
pytest.param(Chargemode.PV_CHARGING, Chargemode.PV_CHARGING, [1, 2]),
112+
pytest.param(Chargemode.INSTANT_CHARGING, Chargemode.PV_CHARGING, [2]),
136113
pytest.param(Chargemode.INSTANT_CHARGING, Chargemode.INSTANT_CHARGING, []),
137114
])
138115
def test_get_chargepoints_submode_pv_charging(submode_1: Chargemode,
139116
submode_2: Chargemode,
140-
expected_chargepoints: List[Chargepoint]):
117+
expected_cp_indices: List[int],
118+
mock_cp1: Chargepoint,
119+
mock_cp2: Chargepoint):
141120
# setup
121+
cp_mapping = {1: mock_cp1, 2: mock_cp2}
122+
expected_chargepoints = [cp_mapping[i] for i in expected_cp_indices]
123+
142124
def setup_cp(cp: Chargepoint, submode: str) -> Chargepoint:
143125
cp.data.set.charging_ev_data = Ev(0)
144126
cp.data.control_parameter.chargemode = Chargemode.PV_CHARGING

packages/control/counter.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,13 @@ def calc_raw_surplus(self):
231231
ranged_surplus = surplus + self._control_range_offset()
232232
return ranged_surplus
233233

234-
def get_control_range_state(self, feed_in_yield: int) -> ControlRangeState:
234+
def get_control_range_state(self) -> ControlRangeState:
235235
control_range_low = data.data.general_data.data.chargemode_config.pv_charging.control_range[0]
236236
control_range_high = data.data.general_data.data.chargemode_config.pv_charging.control_range[1]
237+
if data.data.general_data.data.chargemode_config.pv_charging.feed_in_limit:
238+
feed_in_yield = data.data.general_data.data.chargemode_config.feed_in_yield
239+
else:
240+
feed_in_yield = 0
237241
surplus = data.data.counter_all_data.get_evu_counter().data.get.power + feed_in_yield
238242
if control_range_low > surplus:
239243
return ControlRangeState.BELOW
@@ -270,8 +274,8 @@ def calc_switch_on_power(self, chargepoint: Chargepoint) -> Tuple[float, float]:
270274
control_parameter = chargepoint.data.control_parameter
271275
pv_config = data.data.general_data.data.chargemode_config.pv_charging
272276

273-
if chargepoint.data.set.charge_template.data.chargemode.pv_charging.feed_in_limit:
274-
threshold = pv_config.feed_in_yield
277+
if data.data.general_data.data.chargemode_config.pv_charging.feed_in_limit:
278+
threshold = data.data.general_data.data.chargemode_config.feed_in_yield
275279
else:
276280
threshold = pv_config.switch_on_threshold*control_parameter.phases
277281
return surplus, threshold
@@ -280,8 +284,7 @@ def switch_on_threshold_reached(self, chargepoint: Chargepoint) -> None:
280284
try:
281285
message = None
282286
control_parameter = chargepoint.data.control_parameter
283-
feed_in_limit = chargepoint.data.set.charge_template.data.chargemode.pv_charging.\
284-
feed_in_limit
287+
feed_in_limit = data.data.general_data.data.chargemode_config.pv_charging.feed_in_limit
285288
pv_config = data.data.general_data.data.chargemode_config.pv_charging
286289
timestamp_switch_on_off = control_parameter.timestamp_switch_on_off
287290

@@ -305,7 +308,7 @@ def switch_on_threshold_reached(self, chargepoint: Chargepoint) -> None:
305308
message = self.SWITCH_ON_WAITING.format(timecheck.convert_timestamp_delta_to_time_string(
306309
timestamp_switch_on_off, pv_config.switch_on_delay))
307310
if feed_in_limit:
308-
message += "Die Einspeisegrenze wird berücksichtigt."
311+
message += " Die Einspeisegrenze wird berücksichtigt."
309312
control_parameter.state = ChargepointState.SWITCH_ON_DELAY
310313
else:
311314
# Einschaltschwelle nicht erreicht
@@ -343,8 +346,8 @@ def switch_on_timer_expired(self, chargepoint: Chargepoint) -> None:
343346
msg = self.SWITCH_ON_EXPIRED.format(pv_config.switch_on_threshold)
344347
control_parameter.state = ChargepointState.WAIT_FOR_USING_PHASES
345348

346-
if chargepoint.data.set.charge_template.data.chargemode.pv_charging.feed_in_limit:
347-
feed_in_yield = pv_config.feed_in_yield
349+
if pv_config.feed_in_limit:
350+
feed_in_yield = data.data.general_data.data.chargemode_config.feed_in_yield
348351
else:
349352
feed_in_yield = 0
350353
ev_template = charging_ev_data.ev_template
@@ -391,11 +394,11 @@ def switch_off_check_timer(self, chargepoint: Chargepoint) -> None:
391394
def calc_switch_off_threshold(self, chargepoint: Chargepoint) -> float:
392395
pv_config = data.data.general_data.data.chargemode_config.pv_charging
393396
control_parameter = chargepoint.data.control_parameter
394-
if chargepoint.data.set.charge_template.data.chargemode.pv_charging.feed_in_limit:
397+
if pv_config.feed_in_limit:
395398
# Der EVU-Überschuss muss ggf um die Einspeisegrenze bereinigt werden.
396399
# Wnn die Leistung nicht Einspeisegrenze + Einschaltschwelle erreicht, darf die Ladung nicht pulsieren.
397400
# Abschaltschwelle um Einschaltschwelle reduzieren.
398-
threshold = (-data.data.general_data.data.chargemode_config.pv_charging.feed_in_yield
401+
threshold = (-data.data.general_data.data.chargemode_config.feed_in_yield
399402
+ pv_config.switch_on_threshold*control_parameter.phases)
400403
else:
401404
threshold = pv_config.switch_off_threshold

packages/control/counter_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ class Params:
122122
-681, 15000, 1652683250.0, ChargepointState.SWITCH_ON_DELAY,
123123
Counter.SWITCH_ON_FALLEN_BELOW.format(1500), None, 0),
124124
Params("Feed_in_limit, Timer starten", True, 0, 15001, 15000, None, ChargepointState.NO_CHARGING_ALLOWED,
125-
Counter.SWITCH_ON_WAITING.format("30 Sek."), 1652683252.0, 1500),
125+
Counter.SWITCH_ON_WAITING.format("30 Sek.")+" Die Einspeisegrenze wird berücksichtigt.", 1652683252.0, 1500),
126126
Params("Feed_in_limit, Einschaltschwelle nicht erreicht", True, 0, 14999,
127127
15000, None, ChargepointState.NO_CHARGING_ALLOWED, Counter.SWITCH_ON_NOT_EXCEEDED.format(1500), None, 0),
128128
Params("Feed_in_limit, Einschaltschwelle läuft", True, 1500, 15001,
@@ -141,7 +141,7 @@ def test_switch_on_threshold_reached(params: Params, caplog, general_data_fixtur
141141
cp.data.control_parameter.state = params.state
142142
cp.data.control_parameter.timestamp_switch_on_off = params.timestamp_switch_on_off
143143
ev.data.charge_template = ChargeTemplate()
144-
ev.data.charge_template.data.chargemode.pv_charging.feed_in_limit = params.feed_in_limit
144+
data.data.general_data.data.chargemode_config.pv_charging.feed_in_limit = params.feed_in_limit
145145
cp.data.set.charging_ev_data = ev
146146
mock_calc_switch_on_power = Mock(return_value=[params.surplus, params.threshold])
147147
monkeypatch.setattr(Counter, "calc_switch_on_power", mock_calc_switch_on_power)

packages/control/ev/charge_template.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ class InstantCharging:
6464
class PvCharging:
6565
dc_min_current: float = 145
6666
dc_min_soc_current: float = 145
67-
feed_in_limit: bool = False
6867
limit: Limit = field(default_factory=limit_factory)
6968
min_current: int = 0
7069
min_soc_current: int = 10

packages/control/ev/ev.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,8 @@ def _check_phase_switch_conditions(self,
267267
phases_in_use = control_parameter.phases
268268
pv_config = data.data.general_data.data.chargemode_config.pv_charging
269269
max_phases_ev = self.ev_template.data.max_phases
270-
if charge_template.data.chargemode.pv_charging.feed_in_limit:
271-
feed_in_yield = pv_config.feed_in_yield
270+
if pv_config.feed_in_limit:
271+
feed_in_yield = data.data.general_data.data.chargemode_config.feed_in_yield
272272
else:
273273
feed_in_yield = 0
274274
all_surplus = data.data.counter_all_data.get_evu_counter().get_usable_surplus(feed_in_yield)
@@ -311,8 +311,8 @@ def auto_phase_switch(self,
311311
phases_to_use = control_parameter.phases
312312
phases_in_use = control_parameter.phases
313313
pv_config = data.data.general_data.data.chargemode_config.pv_charging
314-
if charge_template.data.chargemode.pv_charging.feed_in_limit:
315-
feed_in_yield = pv_config.feed_in_yield
314+
if pv_config.feed_in_limit:
315+
feed_in_yield = data.data.general_data.data.chargemode_config.feed_in_yield
316316
else:
317317
feed_in_yield = 0
318318
all_surplus = data.data.counter_all_data.get_evu_counter().get_usable_surplus(feed_in_yield)

packages/control/general.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ class PvCharging:
2424
"topic": "chargemode_config/pv_charging/bat_power_reserve_active"})
2525
control_range: List = field(default_factory=control_range_factory, metadata={
2626
"topic": "chargemode_config/pv_charging/control_range"})
27-
feed_in_yield: int = field(default=15000, metadata={
28-
"topic": "chargemode_config/pv_charging/feed_in_yield"})
27+
feed_in_limit: bool = field(default=False, metadata={
28+
"topic": "chargemode_config/pv_charging/feed_in_limit"})
2929
phase_switch_delay: int = field(default=7, metadata={
3030
"topic": "chargemode_config/pv_charging/phase_switch_delay"})
3131
bat_power_discharge: int = field(default=1500, metadata={
@@ -57,6 +57,8 @@ def pv_charging_factory() -> PvCharging:
5757

5858
@dataclass
5959
class ChargemodeConfig:
60+
feed_in_yield: int = field(default=15000, metadata={
61+
"topic": "chargemode_config/feed_in_yield"})
6062
pv_charging: PvCharging = field(default_factory=pv_charging_factory)
6163
unbalanced_load_limit: int = field(
6264
default=18, metadata={"topic": "chargemode_config/unbalanced_load_limit"})

packages/control/loadmanagement.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ class Loadmanagement:
1717
def get_available_currents(self,
1818
missing_currents: List[float],
1919
counter: Counter,
20-
cp: Chargepoint,
21-
feed_in: int = 0) -> Tuple[List[float], LoadmanagementLimit]:
20+
cp: Chargepoint) -> Tuple[List[float], LoadmanagementLimit]:
2221
raw_currents_left = counter.data.set.raw_currents_left
2322
try:
2423
available_currents, limit = self._limit_by_dimming_via_direct_control(missing_currents, cp)
@@ -36,7 +35,7 @@ def get_available_currents(self,
3635
limit = new_limit if new_limit.limiting_value is not None else limit
3736

3837
available_currents, new_limit = self._limit_by_power(
39-
counter, available_currents, voltages_mean(cp.data.get.voltages), counter.data.set.raw_power_left, feed_in)
38+
counter, available_currents, voltages_mean(cp.data.get.voltages), counter.data.set.raw_power_left)
4039
limit = new_limit if new_limit.limiting_value is not None else limit
4140

4241
if f"counter{counter.num}" == data.data.counter_all_data.get_evu_counter_str():
@@ -50,8 +49,7 @@ def get_available_currents_surplus(self,
5049
missing_currents: List[float],
5150
cp_voltage: float,
5251
counter: Counter,
53-
cp: Chargepoint,
54-
feed_in: int = 0) -> Tuple[List[float], LoadmanagementLimit]:
52+
cp: Chargepoint) -> Tuple[List[float], LoadmanagementLimit]:
5553
raw_currents_left = counter.data.set.raw_currents_left
5654
available_currents, limit = self._limit_by_dimming_via_direct_control(missing_currents, cp)
5755

@@ -62,7 +60,7 @@ def get_available_currents_surplus(self,
6260
limit = new_limit if new_limit.limiting_value is not None else limit
6361

6462
available_currents, new_limit = self._limit_by_power(
65-
counter, available_currents, cp_voltage, counter.data.set.surplus_power_left, feed_in)
63+
counter, available_currents, cp_voltage, counter.data.set.surplus_power_left)
6664
limit = new_limit if new_limit.limiting_value is not None else limit
6765

6866
if f"counter{counter.num}" == data.data.counter_all_data.get_evu_counter_str():
@@ -96,15 +94,14 @@ def _limit_by_power(self,
9694
counter: Counter,
9795
available_currents: List[float],
9896
cp_voltage: float,
99-
raw_power_left: Optional[float],
100-
feed_in: Optional[float]) -> Tuple[List[float], LoadmanagementLimit]:
97+
raw_power_left: Optional[float]) -> Tuple[List[float], LoadmanagementLimit]:
10198
# Mittelwert der Spannungen verwenden, um Phasenverdrehung zu kompensieren
10299
# (Probleme bei einphasig angeschlossenen Wallboxen)
103100
currents = available_currents.copy()
104101
limit = LoadmanagementLimit(None, None)
105102
if raw_power_left:
106-
if feed_in:
107-
raw_power_left = raw_power_left - feed_in
103+
if data.data.general_data.data.chargemode_config.pv_charging.feed_in_limit:
104+
raw_power_left = raw_power_left - data.data.general_data.data.chargemode_config.feed_in_yield
108105
log.debug(f"Verbleibende Leistung unter Berücksichtigung der Einspeisegrenze: {raw_power_left}W")
109106
if sum([c * cp_voltage for c in available_currents]) > raw_power_left:
110107
for i in range(0, 3):

packages/control/loadmanagement_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def test_limit_by_power(available_currents: List[float],
3030
counter_name_mock = Mock(return_value=COUNTER_NAME)
3131
monkeypatch.setattr(loadmanagement, "get_component_name_by_id", counter_name_mock)
3232
# evaluation
33-
currents = Loadmanagement()._limit_by_power(Counter(0), available_currents, 230, raw_power_left, None)
33+
currents = Loadmanagement()._limit_by_power(Counter(0), available_currents, 230, raw_power_left)
3434

3535
# assertion
3636
assert currents == expected_currents

0 commit comments

Comments
 (0)