Skip to content

Commit 5c66e2e

Browse files
authored
scheduled charging: increase buffer time by soc request interval after charge start (#3160)
* scheduled charging: increase buffer time by soc request interval after charge start * flake8 * pytest
1 parent e5839b1 commit 5c66e2e

4 files changed

Lines changed: 52 additions & 10 deletions

File tree

packages/control/chargepoint/chargepoint.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,8 @@ def update(self, ev_list: Dict[str, Ev]) -> None:
667667
self.hw_supports_phase_switch(),
668668
self.template.data.charging_type,
669669
self.data.set.log.imported_since_plugged,
670-
self.hw_bidi_capable())
670+
self.hw_bidi_capable(),
671+
self.data.get.charge_state)
671672
required_phases = self.get_phases_by_selected_chargemode(template_phases)
672673
required_phases = self.set_phases(required_phases, template_phases)
673674
self._pub_connected_vehicle(charging_ev)

packages/control/ev/charge_template.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,8 @@ def scheduled_charging(self,
373373
charging_type: str,
374374
control_parameter: ControlParameter,
375375
soc_request_interval_offset: int,
376-
bidi_state: BidiState) -> Optional[SelectedPlan]:
376+
bidi_state: BidiState,
377+
charge_state: bool) -> Optional[SelectedPlan]:
377378
if bidi_state == BidiState.BIDI_CAPABLE and soc is None:
378379
raise Exception("Für den Lademodis Bidi ist zwingend ein SoC-Modul erforderlich. Soll der "
379380
"SoC ausschließlich aus dem Fahrzeug ausgelesen werden, bitte auf "
@@ -402,7 +403,8 @@ def scheduled_charging(self,
402403
soc_request_interval_offset,
403404
charging_type,
404405
ev_template,
405-
bidi_state)
406+
bidi_state,
407+
charge_state)
406408

407409
def _calc_remaining_time(self,
408410
plan: ScheduledChargingPlan,
@@ -538,7 +540,8 @@ def scheduled_charging_calc_current(self,
538540
soc_request_interval_offset: int,
539541
charging_type: str,
540542
ev_template: EvTemplate,
541-
bidi_state: BidiState) -> Tuple[float, str, str, int]:
543+
bidi_state: BidiState,
544+
charge_state: bool) -> Tuple[float, str, str, int]:
542545
current = 0
543546
submode = "stop"
544547
if selected_plan is None:
@@ -555,7 +558,10 @@ def scheduled_charging_calc_current(self,
555558
else:
556559
plan_current = plan.dc_current
557560
max_current = ev_template.data.dc_max_current
558-
if plan.limit.selected != "soc":
561+
if plan.limit.selected != "soc" or charge_state is False:
562+
# das Abfrageintervall nur einbeziehen, wenn die Ladung bereits gestartet wurde und
563+
# SoC-basiertes Laden aktiv ist, sonst wird einfach alles
564+
# um das Abfrageintervall früher gestartet, und nicht die Pufferzeit um das Abfrageintervall erhöht.
559565
soc_request_interval_offset = 0
560566
log.debug("Verwendeter Plan: "+str(plan.name))
561567
if (limit.selected == "soc" and

packages/control/ev/charge_template_test.py

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ def test_scheduled_charging_calc_current(plan_data: SelectedPlan,
276276

277277
# execution
278278
ret = ct.scheduled_charging_calc_current(plan_data, soc, used_amount, 3, 3, 6,
279-
0, ChargingType.AC.value, EvTemplate(), BidiState.BIDI_CAPABLE)
279+
0, ChargingType.AC.value, EvTemplate(), BidiState.BIDI_CAPABLE, True)
280280

281281
# evaluation
282282
assert ret == expected
@@ -288,12 +288,45 @@ def test_scheduled_charging_calc_current_no_plans():
288288

289289
# execution
290290
ret = ct.scheduled_charging_calc_current(
291-
None, 63, 5, 3, 3, 6, 0, ChargingType.AC.value, EvTemplate(), BidiState.BIDI_CAPABLE)
291+
None, 63, 5, 3, 3, 6, 0, ChargingType.AC.value, EvTemplate(), BidiState.BIDI_CAPABLE, True)
292292

293293
# evaluation
294294
assert ret == (0, "stop", ChargeTemplate.SCHEDULED_CHARGING_NO_PLANS_CONFIGURED, 3)
295295

296296

297+
@pytest.mark.parametrize(
298+
"selected_limit, charge_state, expected",
299+
[
300+
pytest.param("soc", False,
301+
(6, "pv_charging", ChargeTemplate.SCHEDULED_CHARGING_USE_PV.format("um 8:50 Uhr"), 0),
302+
id="soc request interval not considered, use pv"),
303+
pytest.param("soc", True,
304+
(14, "instant_charging",
305+
ChargeTemplate.SCHEDULED_CHARGING_IN_TIME.format(14, 'einen SoC von 80%', "07:00"), 3),
306+
id="soc request interval considered"),
307+
pytest.param("amount", True,
308+
(6, "pv_charging", ChargeTemplate.SCHEDULED_CHARGING_USE_PV.format("um 8:50 Uhr"), 0),
309+
id="amount, charging, soc request interval not considered, no soc limit configured"),
310+
pytest.param("amount", False,
311+
(6, "pv_charging", ChargeTemplate.SCHEDULED_CHARGING_USE_PV.format("um 8:50 Uhr"), 0),
312+
id="amount, not charging, soc request interval not considered, no soc limit configured"),
313+
])
314+
def test_scheduled_charging_calc_current_consider_soc_request_interval_offset(
315+
selected_limit: str, charge_state: bool, expected: Tuple[float, str, str, int]):
316+
# setup
317+
ct = ChargeTemplate()
318+
plan = ScheduledChargingPlan()
319+
plan.limit.selected = selected_limit
320+
321+
# execution
322+
ret = ct.scheduled_charging_calc_current(
323+
SelectedPlan(plan=plan, remaining_time=601, phases=3, duration=3600),
324+
79, 0, 3, 3, 6, 800, ChargingType.AC.value, EvTemplate(), BidiState.BIDI_CAPABLE, charge_state)
325+
326+
# evaluation
327+
assert ret == expected
328+
329+
297330
LOADING_HOURS_TODAY = [datetime.datetime(
298331
year=2022, month=5, day=16, hour=8, minute=0).timestamp()]
299332

@@ -383,7 +416,7 @@ def test_scheduled_charging_calc_current_electricity_tariff(
383416
# execution
384417
ret = ct.scheduled_charging_calc_current(
385418
SelectedPlan(plan=plan, remaining_time=601, phases=3, duration=3600),
386-
current_soc, 0, 3, 3, 6, 0, ChargingType.AC.value, EvTemplate(), BidiState.BIDI_CAPABLE)
419+
current_soc, 0, 3, 3, 6, 0, ChargingType.AC.value, EvTemplate(), BidiState.BIDI_CAPABLE, True)
387420

388421
# evaluation
389422
assert ret == expected

packages/control/ev/ev.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,8 @@ def get_required_current(self,
121121
phase_switch_supported: bool,
122122
charging_type: str,
123123
imported_since_plugged: float,
124-
bidi: BidiState) -> Tuple[bool, Optional[str], str, float, int]:
124+
bidi: BidiState,
125+
charge_state: bool) -> Tuple[bool, Optional[str], str, float, int]:
125126
""" ermittelt, ob und mit welchem Strom das EV geladen werden soll (unabhängig vom Lastmanagement)
126127
127128
Parameter
@@ -166,7 +167,8 @@ def get_required_current(self,
166167
charging_type,
167168
control_parameter,
168169
soc_request_interval_offset,
169-
bidi)
170+
bidi,
171+
charge_state)
170172
message = f"{tmp_message or ''}".strip()
171173

172174
# Wenn Zielladen auf Überschuss wartet, prüfen, ob Zeitladen aktiv ist.

0 commit comments

Comments
 (0)