Skip to content
Open
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
1 change: 1 addition & 0 deletions packages/control/algorithm/integration_test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def data_() -> None:
data.data.counter_data["counter0"].data.config.max_total_power = 22000
data.data.counter_data["counter6"].data.get.currents = [0, 4, 2]
data.data.counter_data["counter6"].data.get.power = 1380
data.data.counter_data["counter6"].data.set.raw_power_left = None
data.data.counter_data["counter6"].data.config.max_currents = [16]*3
data.data.counter_data["counter6"].data.config.max_total_power = 11000
data.data.counter_all_data = CounterAll()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,9 @@ def test_pv_delay_expired(all_cp_pv_charging_3p, all_cp_not_charging, monkeypatc
raw_power_left=39650,
raw_currents_left_counter0=[40]*3,
raw_currents_left_counter6=[16]*3,
expected_current_cp3=16,
expected_current_cp4=7.8731884057971016,
expected_current_cp5=7.8731884057971016,
expected_current_cp3=11.248792270531402,
expected_current_cp4=7.248792270531401,
expected_current_cp5=7.2487922705314,
expected_raw_power_left=24470,
expected_surplus_power_left=1090,
expected_reserved_surplus=0,
Expand Down
2 changes: 1 addition & 1 deletion packages/control/algorithm/surplus_controlled.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def _fix_deviating_evse_current(self, chargepoint: Chargepoint) -> float:
nicht erreicht wird.
Wenn die Soll-Stromstärke nicht angepasst worden ist, nicht den ungenutzten EVSE-Strom aufschlagen."""
evse_current = chargepoint.data.get.evse_current
if evse_current and chargepoint.data.set.current != chargepoint.data.set.current_prev:
if evse_current is not None and chargepoint.data.set.current != chargepoint.data.set.current_prev:
offset = evse_current - get_medium_charging_current(chargepoint.data.get.currents)
offset = min(offset, MAX_EVSE_CURRENT_CHANGE)
current_with_offset = chargepoint.data.set.current + offset
Expand Down
6 changes: 3 additions & 3 deletions packages/control/counter.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class Set:
error_timer: Optional[float] = field(default=None, metadata={"topic": "set/error_timer"})
reserved_surplus: float = field(default=0, metadata={"topic": "set/reserved_surplus"})
released_surplus: float = field(default=0, metadata={"topic": "set/released_surplus"})
raw_power_left: float = 0
raw_power_left: Optional[float] = 0
raw_currents_left: List[float] = field(default_factory=currents_list_factory)
surplus_power_left: float = 0

Expand Down Expand Up @@ -198,14 +198,14 @@ def update_values_left(self, diffs, cp_voltage: float) -> None:
# Mittelwert der Spannungen verwenden, um Phasenverdrehung zu kompensieren
# (Probleme bei einphasig angeschlossenen Wallboxen)
self.data.set.raw_currents_left = list(map(operator.sub, self.data.set.raw_currents_left, diffs))
if self.data.set.raw_power_left:
if self.data.set.raw_power_left is not None:
self.data.set.raw_power_left -= sum([c * cp_voltage for c in diffs])
log.debug(f'Zähler {self.num}: {self.data.set.raw_currents_left}A verbleibende Ströme, '
f'{self.data.set.raw_power_left}W verbleibende Leistung')

def update_surplus_values_left(self, diffs, cp_voltage: float) -> None:
self.data.set.raw_currents_left = list(map(operator.sub, self.data.set.raw_currents_left, diffs))
if self.data.set.surplus_power_left:
if self.data.set.surplus_power_left is not None:
self.data.set.surplus_power_left -= sum([c * cp_voltage for c in diffs])
Comment on lines +208 to 209
log.debug(f'Zähler {self.num}: {self.data.set.raw_currents_left}A verbleibende Ströme, '
f'{self.data.set.surplus_power_left}W verbleibender Überschuss')
Expand Down
8 changes: 4 additions & 4 deletions packages/control/ev/charge_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ def time_charging(self,
current = plan.current if charging_type == ChargingType.AC.value else plan.dc_current
phases = plan.phases_to_use
id = plan.id
if plan.limit.selected == "soc" and soc and soc >= plan.limit.soc:
if plan.limit.selected == "soc" and soc is not None and soc >= plan.limit.soc:
# SoC-Limit erreicht
current = 0
sub_mode = "stop"
Expand Down Expand Up @@ -204,7 +204,7 @@ def instant_charging(self,
else:
current = instant_charging.dc_current

if instant_charging.limit.selected == "soc" and soc and soc >= instant_charging.limit.soc:
if instant_charging.limit.selected == "soc" and soc is not None and soc >= instant_charging.limit.soc:
current = 0
sub_mode = "stop"
message = self.SOC_REACHED
Expand Down Expand Up @@ -236,7 +236,7 @@ def pv_charging(self,
phases = pv_charging.phases_to_use
min_pv_current = (pv_charging.min_current if charging_type == ChargingType.AC.value
else pv_charging.dc_min_current)
if pv_charging.limit.selected == "soc" and soc and soc >= pv_charging.limit.soc:
if pv_charging.limit.selected == "soc" and soc is not None and soc >= pv_charging.limit.soc:
current = 0
sub_mode = "stop"
message = self.SOC_REACHED
Expand Down Expand Up @@ -282,7 +282,7 @@ def eco_charging(self,
phases = eco_charging.phases_to_use
current = eco_charging.current if charging_type == ChargingType.AC.value else eco_charging.dc_current

if eco_charging.limit.selected == "soc" and soc and soc >= eco_charging.limit.soc:
if eco_charging.limit.selected == "soc" and soc is not None and soc >= eco_charging.limit.soc:
current = 0
sub_mode = "stop"
message = self.SOC_REACHED
Expand Down
13 changes: 9 additions & 4 deletions packages/control/loadmanagement.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,10 @@ def _limit_by_power(self,
# (Probleme bei einphasig angeschlossenen Wallboxen)
currents = available_currents.copy()
limit = LoadmanagementLimit(None, None)
if raw_power_left:
if feed_in:
if raw_power_left is None:
return currents, limit
elif raw_power_left > 0:
if feed_in is not None:
raw_power_left = raw_power_left - feed_in
log.debug(f"Verbleibende Leistung unter Berücksichtigung der Einspeisegrenze: {raw_power_left}W")
if sum([c * cp_voltage for c in available_currents]) > raw_power_left:
Expand All @@ -117,7 +119,10 @@ def _limit_by_power(self,
log.debug(f"Leistungsüberschreitung auf {raw_power_left}W korrigieren: {available_currents}")
limit = LoadmanagementLimit(LimitingValue.POWER.value.format(get_component_name_by_id(counter.num)),
LimitingValue.POWER)
return currents, limit
return currents, limit
else:
return [0]*3, LoadmanagementLimit(LimitingValue.POWER.value.format(get_component_name_by_id(counter.num)),
LimitingValue.POWER)

# tested
def _limit_by_current(self,
Expand Down Expand Up @@ -152,7 +157,7 @@ def _limit_by_dimming(self,
available_currents: List[float],
cp: Chargepoint) -> Tuple[List[float], LoadmanagementLimit]:
dimming_power_left, limit = data.data.io_actions.dimming_get_import_power_left({"type": "cp", "id": cp.num})
if dimming_power_left:
if dimming_power_left is not None:
if sum(available_currents)*230 > dimming_power_left:
phases = 3-available_currents.count(0)
overload_per_phase = (sum(available_currents) - dimming_power_left/230)/phases
Expand Down
15 changes: 9 additions & 6 deletions packages/control/loadmanagement_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import List
from typing import List, Optional, Tuple
from unittest.mock import Mock

import pytest
Expand All @@ -12,28 +12,31 @@


@pytest.mark.parametrize(
"available_currents, raw_power_left, expected_currents",
"available_currents, raw_power_left, expected_ret",
[
pytest.param([5, 10, 15], 6900, ([5, 10, 15], LoadmanagementLimit(None, None))),
pytest.param([5, 10, 25], 1000, ([0.5434782608695652, 1.0869565217391304,
2.717391304347826], LoadmanagementLimit(LimitingValue.POWER.value.format(COUNTER_NAME),
LimitingValue.POWER))),
pytest.param([5, 10, 25], 0, ([0, 0, 0], LoadmanagementLimit(LimitingValue.POWER.value.format(COUNTER_NAME),
LimitingValue.POWER))),
pytest.param([5, 10, 25], None, ([5, 10, 25], LoadmanagementLimit(None, None))),
pytest.param([5, 10, 25], 5000, ([2.717391304347826, 5.434782608695652,
13.58695652173913], LoadmanagementLimit(LimitingValue.POWER.value.format(COUNTER_NAME),
LimitingValue.POWER))),
])
def test_limit_by_power(available_currents: List[float],
raw_power_left: float,
expected_currents: List[float],
raw_power_left: Optional[float],
expected_ret: Tuple[List[float], LoadmanagementLimit],
monkeypatch):
# setup
counter_name_mock = Mock(return_value=COUNTER_NAME)
monkeypatch.setattr(loadmanagement, "get_component_name_by_id", counter_name_mock)
# evaluation
currents = Loadmanagement()._limit_by_power(Counter(0), available_currents, 230, raw_power_left, None)
ret = Loadmanagement()._limit_by_power(Counter(0), available_currents, 230, raw_power_left, None)

# assertion
assert currents == expected_currents
assert ret == expected_ret


@pytest.mark.parametrize(
Expand Down
Loading