Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
38 changes: 21 additions & 17 deletions packages/control/consumer/consumer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from typing import Callable, Dict, List, Optional, Tuple

from control import data
from control.consumer.usage import NOT_CONTROLLED
from control.consumer.usage import NOT_CONTROLLED, ON_OFF
from control.algorithm.utils import get_medium_charging_current
from control.chargemode import Chargemode
from control.chargepoint.chargepoint_state import CHARGING_STATES, ChargepointState
Expand Down Expand Up @@ -60,11 +60,11 @@ def update(self):
self.data.get.charge_state = True if self.data.get.power > 0 else False
self.reset_chargemode_at_time()
self.is_switch_interval_elapsed()
min_current, required_current, message, mode, submode = self.get_parameter()
required_current, message, mode, submode = self.get_parameter()
self.set_mode_changed(submode, mode)
if self.chargemode_changed or self.submode_changed:
data.data.counter_all_data.get_evu_counter().reset_switch_on_off(self)
self.set_control_parameter(min_current, required_current,
self.set_control_parameter(required_current,
self.data.config.connected_phases, submode, mode)
self.set_state_and_log(message)
self.process_on_time()
Expand All @@ -74,6 +74,15 @@ def update(self):
except Exception:
log.exception(f"Fehler bei Verbraucher {self.num}")

def _get_min_current(self):
if self.data.usage.type == ConsumerUsage.SUSPENDABLE_TUNABLE:
return self.data.config.min_current
else:
if self.data.get.charge_state:
return get_medium_charging_current(self.data.get.currents)
else:
return self._convert_power_to_current(self.data.config.max_power)
Comment on lines +82 to +85

def process_on_time(self):
if self.data.get.charge_state:
now = timecheck.create_timestamp()
Expand Down Expand Up @@ -105,7 +114,7 @@ def is_switch_interval_elapsed(self):
SURPLUS_CONTINOUS_STILL_RUNNING = ("Verbraucher läuft ggf auch ohne ausreichend Überschuss weiter, da der "
"Verbraucher nicht abgeschaltet werden darf.")

def get_parameter(self) -> Tuple[float, float, Optional[str], Optional[Chargemode], Chargemode]:
def get_parameter(self) -> Tuple[float, Optional[str], Optional[Chargemode], Chargemode]:
Comment thread
Copilot marked this conversation as resolved.
if self.data.set.switch_interval_elapsed is False:
log.debug("Intervall für neuen Schaltbefehl nicht abgelaufen.")
return (0,
Expand All @@ -114,10 +123,6 @@ def get_parameter(self) -> Tuple[float, float, Optional[str], Optional[Chargemod
self.data.control_parameter.chargemode,
self.data.control_parameter.submode)

if self.data.usage.type == ConsumerUsage.SUSPENDABLE_TUNABLE:
min_current = self.data.config.min_current
else:
min_current = self._convert_power_to_current(self.data.config.max_power)
required_current = 0
submode = Chargemode.STOP
mode = self.data.usage.chargemode
Expand All @@ -144,10 +149,10 @@ def get_parameter(self) -> Tuple[float, float, Optional[str], Optional[Chargemod
message = f"{message or ''} {tmp_message or ''}".strip()
if self.data.usage.chargemode == Chargemode.STOP:
required_current, message, submode = self.stop()
return min_current, required_current, message, mode, submode
return required_current, message, mode, submode

def _parse_required_current_by_usage(self, required_current: float) -> float:
if self.data.usage.type in [ConsumerUsage.CONTINUOUS, ConsumerUsage.SUSPENDABLE_ONOFF]:
if self.data.usage.type in ON_OFF:
if self.data.get.charge_state:
return get_medium_charging_current(self.data.get.currents)
else:
Expand Down Expand Up @@ -306,7 +311,7 @@ def convert_loading_hours_to_string(hour_list: List[datetime.datetime]) -> str:
else:
message = self.SCHEDULED_CHARGING_EXPENSIVE_HOUR.format(get_hours_message())
submode = Chargemode.PV_CHARGING
required_current = self._parse_required_current_by_usage(self.data.config.min_current)
required_current = self._parse_required_current_by_usage(self._get_min_current())
else:
now = datetime.datetime.today()
start_time = now + datetime.timedelta(seconds=remaining_time)
Expand All @@ -317,7 +322,7 @@ def convert_loading_hours_to_string(hour_list: List[datetime.datetime]) -> str:
message = self.SCHEDULED_CHARGING_USE_PV.format(
f"am {start_time.strftime('%d.%m')} um {start_time.strftime('%-H:%M')} Uhr")
submode = Chargemode.PV_CHARGING
required_current = self._parse_required_current_by_usage(self.data.config.min_current)
required_current = self._parse_required_current_by_usage(self._get_min_current())
return required_current, message, submode

TIME_CHARGING_MIN_BAT_SOC_REACHED = ("Betrieb mit Zeitladen nach Speicher-SoC nicht möglich, da der SoC des"
Expand Down Expand Up @@ -380,18 +385,18 @@ def eco_charging(self) -> Tuple[float, Optional[str], Chargemode]:
message = self.CHARGING_PRICE_LOW
submode = Chargemode.INSTANT_CHARGING
else:
required_current = self._parse_required_current_by_usage(self.data.config.min_current)
required_current = self._parse_required_current_by_usage(self._get_min_current())
message = self.CHARGING_PRICE_EXCEEDED
if self.data.control_parameter.state in CHARGING_STATES:
message += "Lädt mit Überschuss. "
submode = Chargemode.PV_CHARGING
else:
required_current = self._parse_required_current_by_usage(self.data.config.min_current)
required_current = self._parse_required_current_by_usage(self._get_min_current())
submode = Chargemode.PV_CHARGING
return required_current, message, submode

def pv_charging(self) -> Tuple[float, Optional[str], Chargemode]:
required_current = self._parse_required_current_by_usage(self.data.config.min_current)
required_current = self._parse_required_current_by_usage(self._get_min_current())
message = None
submode = Chargemode.PV_CHARGING
return required_current, message, submode
Expand Down Expand Up @@ -481,12 +486,11 @@ def reset_chargemode_at_time(self):
self.data.usage.chargemode = self.data.usage.reset_chargemode.chargemode

def set_control_parameter(self,
min_current: float,
required_current: float,
phases: int,
submode: Chargemode,
mode: Optional[Chargemode]):
self.data.control_parameter.min_current = min_current
self.data.control_parameter.min_current = self._get_min_current()
self.data.control_parameter.required_current = required_current
self.data.control_parameter.phases = phases
self.data.control_parameter.submode = submode
Expand Down
32 changes: 32 additions & 0 deletions packages/control/consumer/consumer_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,38 @@ def test_pv_charging(consumer: Consumer):
assert ret == (10, None, Chargemode.PV_CHARGING)


@pytest.mark.parametrize(
"usage_type, charge_state, currents, expected_min_current",
[
pytest.param(ConsumerUsage.CONTINUOUS, True, [13, 13, 13], 13, id="continuous-while-running"),
pytest.param(ConsumerUsage.CONTINUOUS, False, [13, 13, 13], 10, id="continuous-while-stopped"),
pytest.param(ConsumerUsage.SUSPENDABLE_TUNABLE, True, [13, 13, 13], 6, id="tunable-while-running"),
pytest.param(ConsumerUsage.SUSPENDABLE_TUNABLE, False, [13, 13, 13], 6, id="tunable-while-stopped"),
],
)
def test_set_control_parameter_sets_min_current_by_usage_and_charge_state(
consumer: Consumer,
usage_type: ConsumerUsage,
charge_state: bool,
currents: List[float],
expected_min_current: float):
# setup
consumer.data.usage.type = usage_type
consumer.data.get.charge_state = charge_state
consumer.data.get.currents = currents

# execution
consumer.set_control_parameter(
required_current=11,
phases=1,
submode=Chargemode.PV_CHARGING,
mode=Chargemode.PV_CHARGING,
)

# evaluation
assert consumer.data.control_parameter.min_current == expected_min_current


@pytest.mark.parametrize(
"on_time, plan_duration, diff_end_date, expected",
[
Expand Down
1 change: 1 addition & 0 deletions packages/control/consumer/usage.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ class ConsumerUsage(Enum):


NOT_CONTROLLED = (ConsumerUsage.METER_ONLY, ConsumerUsage.SELF_CONTROLLED)
ON_OFF = (ConsumerUsage.SUSPENDABLE_ONOFF, ConsumerUsage.CONTINUOUS)
Loading