Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pv phases automatic: directly start with max phases #1620

Merged
merged 1 commit into from
Jun 13, 2024
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
24 changes: 11 additions & 13 deletions packages/control/auto_phase_switch_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ def __init__(self,
phases_to_use: int,
required_current: float,
evu_surplus: int,
reserved_evu_overhang: int,
get_currents: List[float],
get_power: float,
state: ChargepointState,
Expand All @@ -50,7 +49,6 @@ def __init__(self,
self.phases_to_use = phases_to_use
self.required_current = required_current
self.available_power = evu_surplus
self.reserved_evu_overhang = reserved_evu_overhang
self.get_currents = get_currents
self.get_power = get_power
self.state = state
Expand All @@ -63,60 +61,60 @@ def __init__(self,

cases = [
Params("1to3, enough power, start timer", max_current_single_phase=16, timestamp_auto_phase_switch=None,
phases_to_use=1, required_current=6, evu_surplus=-800, reserved_evu_overhang=0, get_currents=[15.6, 0, 0],
phases_to_use=1, required_current=6, evu_surplus=800, get_currents=[15.6, 0, 0],
get_power=3450, state=ChargepointState.CHARGING_ALLOWED, expected_phases_to_use=1, expected_current=6,
expected_message=Ev.PHASE_SWITCH_DELAY_TEXT.format("Umschaltung von 1 auf 3", "7 Min. 0 Sek."),
expected_timestamp_auto_phase_switch=1652683252.0,
expected_state=ChargepointState.PHASE_SWITCH_DELAY),
Params("1to3, not enough power, start timer", max_current_single_phase=16, timestamp_auto_phase_switch=None,
phases_to_use=1, required_current=6, evu_surplus=-300, reserved_evu_overhang=0, get_currents=[15.6, 0, 0],
phases_to_use=1, required_current=6, evu_surplus=300, get_currents=[15.6, 0, 0],
get_power=3450, state=ChargepointState.CHARGING_ALLOWED, expected_phases_to_use=1, expected_current=6,
expected_state=ChargepointState.CHARGING_ALLOWED),
Params("1to3, enough power, timer not expired", max_current_single_phase=16,
timestamp_auto_phase_switch=1652682952.0, phases_to_use=1, required_current=6,
evu_surplus=-1200, reserved_evu_overhang=460, get_currents=[15.6, 0, 0], get_power=3450,
evu_surplus=1460, get_currents=[15.6, 0, 0], get_power=3450,
state=ChargepointState.PHASE_SWITCH_DELAY, expected_phases_to_use=1, expected_current=6,
expected_message=Ev.PHASE_SWITCH_DELAY_TEXT.format("Umschaltung von 1 auf 3", "2 Min. 0 Sek."),
expected_timestamp_auto_phase_switch=1652683252.0,
expected_state=ChargepointState.PHASE_SWITCH_DELAY),
Params("1to3, not enough power, timer not expired", max_current_single_phase=16,
timestamp_auto_phase_switch=1652682952.0, phases_to_use=1, required_current=6,
evu_surplus=0, reserved_evu_overhang=460, get_currents=[15.6, 0, 0], get_power=3450,
evu_surplus=460, get_currents=[15.6, 0, 0], get_power=3450,
state=ChargepointState.PHASE_SWITCH_DELAY, expected_phases_to_use=1, expected_current=6,
expected_message=f"Verzögerung für die Umschaltung von 1 auf 3 Phasen abgebrochen{Ev.NOT_ENOUGH_POWER}",
expected_timestamp_auto_phase_switch=1652683252.0,
expected_state=ChargepointState.CHARGING_ALLOWED),
Params("1to3, enough power, timer expired", max_current_single_phase=16,
timestamp_auto_phase_switch=1652682772.0, phases_to_use=1, required_current=6,
evu_surplus=-1200, reserved_evu_overhang=460, get_currents=[15.6, 0, 0], get_power=3450,
evu_surplus=1640, get_currents=[15.6, 0, 0], get_power=3450,
state=ChargepointState.PHASE_SWITCH_DELAY,
expected_phases_to_use=3, expected_current=6, expected_state=ChargepointState.PHASE_SWITCH_DELAY_EXPIRED),

Params("3to1, not enough power, start timer", max_current_single_phase=16, timestamp_auto_phase_switch=None,
phases_to_use=3, required_current=6, evu_surplus=0, reserved_evu_overhang=0,
phases_to_use=3, required_current=6, evu_surplus=0,
get_currents=[4.5, 4.4, 5.8], get_power=3381, state=ChargepointState.CHARGING_ALLOWED,
expected_phases_to_use=3, expected_current=6,
expected_message="Umschaltung von 3 auf 1 Phasen in 9 Min. 0 Sek..",
expected_timestamp_auto_phase_switch=1652683252.0,
expected_state=ChargepointState.PHASE_SWITCH_DELAY),
Params("3to1, not enough power, timer not expired", max_current_single_phase=16,
timestamp_auto_phase_switch=1652682952.0,
phases_to_use=3, required_current=6, evu_surplus=0, reserved_evu_overhang=-460,
phases_to_use=3, required_current=6, evu_surplus=-460,
get_currents=[4.5, 4.4, 5.8], get_power=3381, state=ChargepointState.PHASE_SWITCH_DELAY,
expected_phases_to_use=3, expected_current=6,
expected_message="Umschaltung von 3 auf 1 Phasen in 4 Min. 0 Sek..",
expected_timestamp_auto_phase_switch=1652683252.0,
expected_state=ChargepointState.PHASE_SWITCH_DELAY),
Params("3to1, enough power, timer not expired", max_current_single_phase=16,
timestamp_auto_phase_switch=1652682952.0, phases_to_use=3, required_current=6,
evu_surplus=-860, reserved_evu_overhang=0, get_currents=[4.5, 4.4, 5.8],
evu_surplus=860, get_currents=[4.5, 4.4, 5.8],
get_power=3381, state=ChargepointState.PHASE_SWITCH_DELAY, expected_phases_to_use=3, expected_current=6,
expected_message=f"Verzögerung für die Umschaltung von 3 auf 1 Phasen abgebrochen{Ev.ENOUGH_POWER}",
expected_timestamp_auto_phase_switch=1652683252.0,
expected_state=ChargepointState.CHARGING_ALLOWED),
Params("3to1, not enough power, timer expired", max_current_single_phase=16,
timestamp_auto_phase_switch=1652682592.0, phases_to_use=3, required_current=6,
evu_surplus=0, reserved_evu_overhang=-460, get_currents=[4.5, 4.4, 5.8],
evu_surplus=-460, get_currents=[4.5, 4.4, 5.8],
get_power=3381, state=ChargepointState.PHASE_SWITCH_DELAY, expected_phases_to_use=1, expected_current=16,
expected_state=ChargepointState.PHASE_SWITCH_DELAY_EXPIRED),
]
Expand All @@ -126,12 +124,12 @@ def __init__(self,
def test_auto_phase_switch(monkeypatch, vehicle: Ev, params: Params):
# setup
mock_evu = Mock(spec=Counter, data=Mock(spec=CounterData,
set=Mock(spec=Set, reserved_surplus=params.reserved_evu_overhang,
set=Mock(spec=Set, reserved_surplus=0,
released_surplus=0)))
mock_get_evu_counter = Mock(name="power_for_bat_charging", return_value=mock_evu)
monkeypatch.setattr(data.data.counter_all_data, "get_evu_counter", mock_get_evu_counter)
mock_evu_counter_surplus = Mock(return_value=params.available_power)
monkeypatch.setattr(mock_evu, "calc_surplus", mock_evu_counter_surplus)
monkeypatch.setattr(mock_evu, "get_usable_surplus", mock_evu_counter_surplus)

vehicle.ev_template.data.max_current_single_phase = params.max_current_single_phase
control_parameter = ControlParameter()
Expand Down
19 changes: 19 additions & 0 deletions packages/control/counter.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from typing import List, Tuple

from control import data
from control.chargemode import Chargemode
from control.ev import Ev
from control.chargepoint.chargepoint import Chargepoint
from control.chargepoint.chargepoint_state import ChargepointState
Expand Down Expand Up @@ -249,11 +250,17 @@ def _control_range_offset(self):
log.debug(f"Anpassen des Regelbereichs {range_offset}W")
return range_offset

def get_usable_surplus(self, feed_in_yield: float) -> float:
# verbleibender EVU-Überschuss unter Berücksichtigung der Einspeisegrenze und Speicherleistung
return (-self.calc_surplus() - self.data.set.released_surplus +
self.data.set.reserved_surplus - feed_in_yield)

SWITCH_ON_FALLEN_BELOW = "Einschaltschwelle während der Einschaltverzögerung unterschritten."
SWITCH_ON_WAITING = "Die Ladung wird gestartet, sobald in {} die Einschaltverzögerung abgelaufen ist."
SWITCH_ON_NOT_EXCEEDED = ("Die Ladung kann nicht gestartet werden, da die Einschaltschwelle nicht erreicht "
"wird.")
SWITCH_ON_EXPIRED = "Einschaltschwelle für die Dauer der Einschaltverzögerung überschritten."
SWITCH_ON_MAX_PHASES = "Der Überschuss ist ausreichend, um direkt mit {} Phasen zu laden."

def calc_switch_on_power(self, chargepoint: Chargepoint) -> Tuple[float, float]:
surplus = self.data.set.surplus_power_left - self.data.set.reserved_surplus
Expand Down Expand Up @@ -329,6 +336,18 @@ def switch_on_timer_expired(self, chargepoint: Chargepoint) -> None:
self.data.set.reserved_surplus -= pv_config.switch_on_threshold*control_parameter.phases
msg = self.SWITCH_ON_EXPIRED.format(pv_config.switch_on_threshold)
control_parameter.state = ChargepointState.CHARGING_ALLOWED

if chargepoint.data.set.charging_ev_data.charge_template.data.chargemode.pv_charging.feed_in_limit:
feed_in_yield = pv_config.feed_in_yield
else:
feed_in_yield = 0
ev_template = chargepoint.data.set.charging_ev_data.ev_template
max_phases_power = ev_template.data.min_current * ev_template.data.max_phases * 230
if (data.data.general_data.get_phases_chargemode(Chargemode.PV_CHARGING.value) == 0 and
chargepoint.cp_ev_support_phase_switch() and
self.get_usable_surplus(feed_in_yield) > max_phases_power):
control_parameter.phases = ev_template.data.max_phases
msg += self.SWITCH_ON_MAX_PHASES.format(ev_template.data.max_phases)
chargepoint.set_state_and_log(msg)
except Exception:
log.exception("Fehler im allgemeinen PV-Modul")
Expand Down
10 changes: 2 additions & 8 deletions packages/control/ev.py
Original file line number Diff line number Diff line change
Expand Up @@ -398,10 +398,7 @@ def _check_phase_switch_conditions(self,
feed_in_yield = pv_config.feed_in_yield
else:
feed_in_yield = 0
evu_counter = data.data.counter_all_data.get_evu_counter()
# verbleibender EVU-Überschuss unter Berücksichtigung der Einspeisegrenze und Speicherleistung
all_surplus = (-evu_counter.calc_surplus() - evu_counter.data.set.released_surplus +
evu_counter.data.set.reserved_surplus - feed_in_yield)
all_surplus = data.data.counter_all_data.get_evu_counter().get_usable_surplus(feed_in_yield)
condition_1_to_3 = (((max(get_currents) > max_current and
all_surplus > self.ev_template.data.min_current * max_phases_ev * 230
- get_power) or limit == LimitingValue.UNBALANCED_LOAD.value) and
Expand Down Expand Up @@ -439,10 +436,7 @@ def auto_phase_switch(self,
feed_in_yield = pv_config.feed_in_yield
else:
feed_in_yield = 0
evu_counter = data.data.counter_all_data.get_evu_counter()
# verbleibender EVU-Überschuss unter Berücksichtigung der Einspeisegrenze und Speicherleistung
all_surplus = (-evu_counter.calc_surplus() - evu_counter.data.set.released_surplus +
evu_counter.data.set.reserved_surplus - feed_in_yield)
all_surplus = data.data.counter_all_data.get_evu_counter().get_usable_surplus(feed_in_yield)
if phases_in_use == 1:
direction_str = f"Umschaltung von 1 auf {max_phases}"
delay = pv_config.phase_switch_delay * 60
Expand Down