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
23 changes: 13 additions & 10 deletions packages/control/ev/charge_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,23 +322,26 @@ def scheduled_charging_recent_plan(self,
raise ValueError("Um Zielladen mit SoC-Ziel nutzen zu können, bitte ein SoC-Modul konfigurieren "
f"oder im Plan {p.name} als Begrenzung Energie einstellen.")
try:
if ((p.limit.selected == "amount" and used_amount >= p.limit.amount) or
((p.limit.selected == "soc" and soc >= p.limit.soc_scheduled) and
(p.limit.selected == "soc" and soc >= p.limit.soc_limit))):
plan_fulfilled = True
else:
plan_fulfilled = False
plans_diff_end_date.append(
{p.id: timecheck.check_end_time(p, chargemode_switch_timestamp, plan_fulfilled)})
log.debug(f"Verbleibende Zeit bis zum Zieltermin [s]: {plans_diff_end_date}, "
f"Plan erfüllt: {plan_fulfilled}")
{p.id: timecheck.check_end_time(p, chargemode_switch_timestamp)})
log.debug(f"Verbleibende Zeit bis zum Zieltermin [s]: {plans_diff_end_date}")
except Exception:
log.exception("Fehler im ev-Modul "+str(self.data.id))
if plans_diff_end_date:
# ermittle den Key vom kleinsten value in plans_diff_end_date
filtered_plans = [d for d in plans_diff_end_date if list(d.values())[0] is not None]
if filtered_plans:
plan_dict = min(filtered_plans, key=lambda x: list(x.values())[0])
sorted_plans = sorted(filtered_plans, key=lambda x: list(x.values())[0])
if len(sorted_plans) == 1:
plan_dict = sorted_plans[0]
elif (len(sorted_plans) > 1 and
list(sorted_plans[0].values())[0] < 0 and
list(sorted_plans[1].values())[0] < 43200):
# wenn der erste Plan in der Liste in der Vergangenheit liegt, dann den zweiten nehmen, wenn dessen
# Zielzeit weniger als 12 h entfernt ist.
plan_dict = sorted_plans[1]
else:
plan_dict = sorted_plans[0]
if plan_dict:
plan_id = list(plan_dict.keys())[0]
plan_end_time = list(plan_dict.values())[0]
Expand Down
40 changes: 5 additions & 35 deletions packages/control/ev/charge_template_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,11 @@ def test_calculate_duration(selected: str, phases: int, expected_duration: float
@pytest.mark.parametrize(
"end_time_mock, expected_plan_num",
[
pytest.param([1000, 1500, 2000], 0, id="1st plan"),
pytest.param([1500, 1000, 2000], 1, id="2nd plan"),
pytest.param([1500, 2000, 1000], 2, id="3rd plan"),
pytest.param([None]*3, 0, id="no plan"),
pytest.param([1000, 1500, 2000], 0, id="nächster Zieltermin Plan 0"),
pytest.param([-100, 1000, 2000], 1, id="Plan 0 abgelaufen, Plan 1 innerhalb der nächsten 12h"),
pytest.param([-100, 45000, 50000], 0, id="Plan 0 abgelaufen, Plan 1 nicht innerhalb der nächsten 12h"),
pytest.param([1500, 2000, 1000], 2, id="nächster Zieltermin Plan 2"),
pytest.param([None]*3, 0, id="kein Plan"),
])
def test_scheduled_charging_recent_plan(end_time_mock,
expected_plan_num: Optional[int],
Expand All @@ -212,37 +213,6 @@ def test_scheduled_charging_recent_plan(end_time_mock,
assert selected_plan is None


@pytest.mark.parametrize("end_time_mock, expected_plan_num",
[
pytest.param([-10000, 1500, 2000], 0, id="1st plan"),
pytest.param([None, -100, 2000], 1, id="1st plan fulfilled, 2nd plan"),
pytest.param([None, -50, -100], 2, id="1st plan fulfilled, 3rd plan"),
pytest.param([None]*3, None, id="no plan"),
])
def test_scheduled_charging_recent_plan_fulfilled(end_time_mock, expected_plan_num, monkeypatch):
# setup
# der erste PLan ist erfüllt, der zweite wird ausgewählt
calculate_duration_mock = Mock(return_value=(100, 3000, 3, 500))
monkeypatch.setattr(ChargeTemplate, "_calc_remaining_time", calculate_duration_mock)
check_end_time_mock = Mock(side_effect=end_time_mock)
monkeypatch.setattr(timecheck, "check_end_time", check_end_time_mock)
ct = ChargeTemplate()
plan_mock_0 = Mock(spec=ScheduledChargingPlan, active=True, current=14, id=0, limit=Limit(selected="amount"))
plan_mock_1 = Mock(spec=ScheduledChargingPlan, active=True, current=14, id=1, limit=Limit(selected="amount"))
plan_mock_2 = Mock(spec=ScheduledChargingPlan, active=True, current=14, id=2, limit=Limit(selected="amount"))
ct.data.chargemode.scheduled_charging.plans = [plan_mock_0, plan_mock_1, plan_mock_2]

# execution
selected_plan = ct.scheduled_charging_recent_plan(
60, EvTemplate(), 3, 1200, 3, True, ChargingType.AC.value, 1652688000, Mock(spec=ControlParameter), 0)

# evaluation
if selected_plan:
assert selected_plan.plan.id == expected_plan_num
else:
assert selected_plan is expected_plan_num


@pytest.mark.parametrize(
"plan_data, soc, used_amount, selected, expected",
[
Expand Down
7 changes: 2 additions & 5 deletions packages/helpermodules/timecheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,8 @@ def is_timeframe_valid(now: datetime.datetime, begin: datetime.datetime, end: da


def check_end_time(plan: ScheduledChargingPlan,
chargemode_switch_timestamp: Optional[float],
plan_fulfilled: bool) -> Optional[float]:
chargemode_switch_timestamp: Optional[float]) -> Optional[float]:
""" prüft, ob der in angegebene Zeitpunkt abzüglich der Dauer jetzt ist.
Um etwas Puffer zu haben, werden bei Überschreiten des Zeitpunkts die nachfolgenden 20 Min auch noch als Ladezeit
zurückgegeben.

Return
------
Expand Down Expand Up @@ -154,7 +151,7 @@ def missed_date_still_active(remaining_time: float) -> bool:
remaining_time = end - now
else:
raise TypeError(f'Unbekannte Häufigkeit {plan.frequency.selected}')
if chargemode_switch_timestamp and (end.timestamp() < chargemode_switch_timestamp or plan_fulfilled):
if chargemode_switch_timestamp and end.timestamp() < chargemode_switch_timestamp:
# Als auf Zielladen umgeschaltet wurde, war der Termin schon vorbei
return None
else:
Expand Down
25 changes: 10 additions & 15 deletions packages/helpermodules/timecheck_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,24 @@ def __init__(self, name: str,
self.second_time = second_time


@pytest.mark.parametrize("time, selected, date, plan_fulfilled, expected_remaining_time",
[pytest.param("9:00", "once", "2022-05-16", False, 1148, id="once"),
pytest.param("7:55", "once", "2022-05-16", False, None, id="missed date, plugged before"),
pytest.param("8:05", "once", "2022-05-16", False, -
@pytest.mark.parametrize("time, selected, date, expected_remaining_time",
[pytest.param("9:00", "once", "2022-05-16", 1148, id="once"),
pytest.param("7:55", "once", "2022-05-16", None, id="missed date, plugged before"),
pytest.param("8:05", "once", "2022-05-16", -
2152, id="once missed date, plugged after"),
pytest.param("12:00", "daily", [], False, 11948, id="daily today"),
pytest.param("2:00", "daily", [], False, 62348, id="daily missed today, use next day"),
pytest.param("12:00", "daily", [], 11948, id="daily today"),
pytest.param("2:00", "daily", [], 62348, id="daily missed today, use next day"),
pytest.param("7:55", "weekly", [True, False, False, False,
False, False, False], False, 602048, id="weekly missed today"),
False, False, False], 602048, id="weekly missed today"),
pytest.param("2:00", "weekly", [False, False, True, False, False, False, False],
False, 148748,
id="weekly missed today's date, no date on next day"),
148748, id="weekly missed today's date, no date on next day"),
pytest.param("2:00", "weekly", [True, True, False, False, False, False, False],
False, 62348,
id="weekly missed today's date, date on next day"),
pytest.param("8:05", "once", "2022-05-16", True, None, id="once missed date, plugged after"),
62348, id="weekly missed today's date, date on next day"),
]
)
def test_check_end_time(time: str,
selected: str,
date: List,
plan_fulfilled: bool,
expected_remaining_time: float):
# setup
plan = Mock(spec=ScheduledChargingPlan, time=time, frequency=Mock(spec=FrequencyDate, selected=selected,))
Expand All @@ -51,8 +47,7 @@ def test_check_end_time(time: str,
# execution
remaining_time = timecheck.check_end_time(
plan,
chargemode_switch_timestamp=datetime.datetime.strptime("5/16/2022 8:00", "%m/%d/%Y %H:%M").timestamp(),
plan_fulfilled=plan_fulfilled)
chargemode_switch_timestamp=datetime.datetime.strptime("5/16/2022 8:00", "%m/%d/%Y %H:%M").timestamp())

# evaluation
assert remaining_time == expected_remaining_time
Expand Down