diff --git a/data/config/mosquitto/public/default-dynamic-security.json b/data/config/mosquitto/public/default-dynamic-security.json
index 10ed378e2f..422e796189 100644
--- a/data/config/mosquitto/public/default-dynamic-security.json
+++ b/data/config/mosquitto/public/default-dynamic-security.json
@@ -1045,49 +1045,55 @@
"acls": [
{
"acltype": "publishClientSend",
- "topic": "openWB/set/general/chargemode_config/pv_charging/control_range",
+ "topic": "openWB/set/general/chargemode_config/surplus/control_range",
"priority": 0,
"allow": true
},
{
"acltype": "publishClientSend",
- "topic": "openWB/set/general/chargemode_config/pv_charging/feed_in_yield",
+ "topic": "openWB/set/general/chargemode_config/surplus/feed_in_limit",
"priority": 0,
"allow": true
},
{
"acltype": "publishClientSend",
- "topic": "openWB/set/general/chargemode_config/pv_charging/phase_switch_delay",
+ "topic": "openWB/set/general/chargemode_config/surplus/feed_in_yield",
"priority": 0,
"allow": true
},
{
"acltype": "publishClientSend",
- "topic": "openWB/set/general/chargemode_config/pv_charging/switch_on_threshold",
+ "topic": "openWB/set/general/chargemode_config/surplus/vehicle/phase_switch_delay",
"priority": 0,
"allow": true
},
{
"acltype": "publishClientSend",
- "topic": "openWB/set/general/chargemode_config/pv_charging/retry_failed_phase_switches",
+ "topic": "openWB/set/general/chargemode_config/surplus/vehicle/switch_on_threshold",
"priority": 0,
"allow": true
},
{
"acltype": "publishClientSend",
- "topic": "openWB/set/general/chargemode_config/pv_charging/switch_on_delay",
+ "topic": "openWB/set/general/chargemode_config/surplus/vehicle/retry_failed_phase_switches",
"priority": 0,
"allow": true
},
{
"acltype": "publishClientSend",
- "topic": "openWB/set/general/chargemode_config/pv_charging/switch_off_threshold",
+ "topic": "openWB/set/general/chargemode_config/surplus/vehicle/switch_on_delay",
"priority": 0,
"allow": true
},
{
"acltype": "publishClientSend",
- "topic": "openWB/set/general/chargemode_config/pv_charging/switch_off_delay",
+ "topic": "openWB/set/general/chargemode_config/surplus/vehicle/switch_off_threshold",
+ "priority": 0,
+ "allow": true
+ },
+ {
+ "acltype": "publishClientSend",
+ "topic": "openWB/set/general/chargemode_config/surplus/vehicle/switch_off_delay",
"priority": 0,
"allow": true
},
@@ -1099,49 +1105,55 @@
},
{
"acltype": "publishClientReceive",
- "topic": "openWB/general/chargemode_config/pv_charging/control_range",
+ "topic": "openWB/general/chargemode_config/surplus/control_range",
+ "priority": 0,
+ "allow": true
+ },
+ {
+ "acltype": "publishClientReceive",
+ "topic": "openWB/general/chargemode_config/surplus/feed_in_limit",
"priority": 0,
"allow": true
},
{
"acltype": "publishClientReceive",
- "topic": "openWB/general/chargemode_config/pv_charging/feed_in_yield",
+ "topic": "openWB/general/chargemode_config/surplus/feed_in_yield",
"priority": 0,
"allow": true
},
{
"acltype": "publishClientReceive",
- "topic": "openWB/general/chargemode_config/pv_charging/phase_switch_delay",
+ "topic": "openWB/general/chargemode_config/surplus/vehicle/phase_switch_delay",
"priority": 0,
"allow": true
},
{
"acltype": "publishClientReceive",
- "topic": "openWB/general/chargemode_config/pv_charging/switch_on_threshold",
+ "topic": "openWB/general/chargemode_config/surplus/vehicle/switch_on_threshold",
"priority": 0,
"allow": true
},
{
"acltype": "publishClientReceive",
- "topic": "openWB/general/chargemode_config/pv_charging/retry_failed_phase_switches",
+ "topic": "openWB/general/chargemode_config/surplus/vehicle/retry_failed_phase_switches",
"priority": 0,
"allow": true
},
{
"acltype": "publishClientReceive",
- "topic": "openWB/general/chargemode_config/pv_charging/switch_on_delay",
+ "topic": "openWB/general/chargemode_config/surplus/vehicle/switch_on_delay",
"priority": 0,
"allow": true
},
{
"acltype": "publishClientReceive",
- "topic": "openWB/general/chargemode_config/pv_charging/switch_off_threshold",
+ "topic": "openWB/general/chargemode_config/surplus/vehicle/switch_off_threshold",
"priority": 0,
"allow": true
},
{
"acltype": "publishClientReceive",
- "topic": "openWB/general/chargemode_config/pv_charging/switch_off_delay",
+ "topic": "openWB/general/chargemode_config/surplus/vehicle/switch_off_delay",
"priority": 0,
"allow": true
}
@@ -1226,43 +1238,43 @@
},
{
"acltype": "publishClientSend",
- "topic": "openWB/set/general/chargemode_config/pv_charging/bat_mode",
+ "topic": "openWB/set/general/chargemode_config/bat/mode",
"priority": 0,
"allow": true
},
{
"acltype": "publishClientSend",
- "topic": "openWB/set/general/chargemode_config/pv_charging/bat_power_discharge",
+ "topic": "openWB/set/general/chargemode_config/bat/power_discharge",
"priority": 0,
"allow": true
},
{
"acltype": "publishClientSend",
- "topic": "openWB/set/general/chargemode_config/pv_charging/bat_power_discharge_active",
+ "topic": "openWB/set/general/chargemode_config/bat/power_discharge_active",
"priority": 0,
"allow": true
},
{
"acltype": "publishClientSend",
- "topic": "openWB/set/general/chargemode_config/pv_charging/bat_power_reserve",
+ "topic": "openWB/set/general/chargemode_config/bat/power_reserve",
"priority": 0,
"allow": true
},
{
"acltype": "publishClientSend",
- "topic": "openWB/set/general/chargemode_config/pv_charging/bat_power_reserve_active",
+ "topic": "openWB/set/general/chargemode_config/bat/power_reserve_active",
"priority": 0,
"allow": true
},
{
"acltype": "publishClientSend",
- "topic": "openWB/set/general/chargemode_config/pv_charging/max_bat_soc",
+ "topic": "openWB/set/general/chargemode_config/bat/max_soc",
"priority": 0,
"allow": true
},
{
"acltype": "publishClientSend",
- "topic": "openWB/set/general/chargemode_config/pv_charging/min_bat_soc",
+ "topic": "openWB/set/general/chargemode_config/bat/min_soc",
"priority": 0,
"allow": true
},
@@ -1358,43 +1370,43 @@
},
{
"acltype": "publishClientReceive",
- "topic": "openWB/general/chargemode_config/pv_charging/bat_mode",
+ "topic": "openWB/general/chargemode_config/bat/mode",
"priority": 0,
"allow": true
},
{
"acltype": "publishClientReceive",
- "topic": "openWB/general/chargemode_config/pv_charging/bat_power_discharge",
+ "topic": "openWB/general/chargemode_config/bat/power_discharge",
"priority": 0,
"allow": true
},
{
"acltype": "publishClientReceive",
- "topic": "openWB/general/chargemode_config/pv_charging/bat_power_discharge_active",
+ "topic": "openWB/general/chargemode_config/bat/power_discharge_active",
"priority": 0,
"allow": true
},
{
"acltype": "publishClientReceive",
- "topic": "openWB/general/chargemode_config/pv_charging/bat_power_reserve",
+ "topic": "openWB/general/chargemode_config/bat/power_reserve",
"priority": 0,
"allow": true
},
{
"acltype": "publishClientReceive",
- "topic": "openWB/general/chargemode_config/pv_charging/bat_power_reserve_active",
+ "topic": "openWB/general/chargemode_config/bat/power_reserve_active",
"priority": 0,
"allow": true
},
{
"acltype": "publishClientReceive",
- "topic": "openWB/general/chargemode_config/pv_charging/max_bat_soc",
+ "topic": "openWB/general/chargemode_config/bat/max_soc",
"priority": 0,
"allow": true
},
{
"acltype": "publishClientReceive",
- "topic": "openWB/general/chargemode_config/pv_charging/min_bat_soc",
+ "topic": "openWB/general/chargemode_config/bat/min_soc",
"priority": 0,
"allow": true
},
@@ -2794,7 +2806,7 @@
},
{
"acltype": "publishClientReceive",
- "topic": "openWB/general/chargemode_config/pv_charging/bat_mode",
+ "topic": "openWB/general/chargemode_config/bat/mode",
"priority": 0,
"allow": true
}
diff --git a/packages/control/algorithm/algorithm.py b/packages/control/algorithm/algorithm.py
index 2bfbeeb2a5..fa4b01ed8c 100644
--- a/packages/control/algorithm/algorithm.py
+++ b/packages/control/algorithm/algorithm.py
@@ -68,7 +68,6 @@ def _check_auto_phase_switch_delay(self) -> None:
# wurden, wieder zurückgegeben.
log.debug(f"Ladepunkt {cp.num}: Prüfen, ob Phasenumschaltung durchgeführt werden soll.")
phases, current, message = charging_ev.auto_phase_switch(
- cp.data.set.charge_template,
cp.data.control_parameter,
cp.num,
cp.data.get.evse_current,
diff --git a/packages/control/algorithm/integration_test/conftest.py b/packages/control/algorithm/integration_test/conftest.py
index cbc98f72ff..6b6072c603 100644
--- a/packages/control/algorithm/integration_test/conftest.py
+++ b/packages/control/algorithm/integration_test/conftest.py
@@ -52,7 +52,7 @@ def data_() -> None:
data.data.counter_all_data.data.get.hierarchy = NESTED_HIERARCHY
data.data.counter_all_data.data.config.consider_less_charging = True
data.data.io_actions = IoActions()
- data.data.general_data.data.chargemode_config.pv_charging.retry_failed_phase_switches = True
+ data.data.general_data.data.chargemode_config.surplus.vehicle.retry_failed_phase_switches = True
@dataclass
diff --git a/packages/control/algorithm/surplus_controlled.py b/packages/control/algorithm/surplus_controlled.py
index 1a39d27678..41669486a3 100644
--- a/packages/control/algorithm/surplus_controlled.py
+++ b/packages/control/algorithm/surplus_controlled.py
@@ -33,12 +33,7 @@ def set_surplus_current(self) -> None:
for mode_tuple, counter in common.mode_and_counter_generator(CONSIDERED_CHARGE_MODES_SURPLUS):
preferenced_chargepoints, preferenced_cps_without_set_current = get_preferenced_chargepoint_charging(
get_chargepoints_by_mode_and_counter(mode_tuple, f"counter{counter.num}"))
- cp_with_feed_in, cp_without_feed_in = self.filter_by_feed_in_limit(preferenced_chargepoints)
- if cp_without_feed_in:
- self._set(cp_without_feed_in, 0, mode_tuple, counter)
- feed_in_yield = data.data.general_data.data.chargemode_config.pv_charging.feed_in_yield
- if cp_with_feed_in:
- self._set(cp_with_feed_in, feed_in_yield, mode_tuple, counter)
+ self._set(preferenced_chargepoints, mode_tuple, counter)
if preferenced_cps_without_set_current:
for cp in preferenced_cps_without_set_current:
cp.data.set.current = cp.data.set.target_current
@@ -48,7 +43,6 @@ def set_surplus_current(self) -> None:
def _set(self,
chargepoints: List[Chargepoint],
- feed_in_yield: Optional[int],
mode_tuple: Tuple[Optional[str], str, bool],
counter: Counter) -> None:
log.info(f"Mode-Tuple {mode_tuple[0]} - {mode_tuple[1]} - {mode_tuple[2]}, Zähler {counter.num}")
@@ -60,20 +54,19 @@ def _set(self,
missing_currents,
voltages_mean(cp.data.get.voltages),
counter,
- cp,
- feed_in=feed_in_yield
+ cp
)
# im PV-Laden wird der Strom immer durch die Leistung begrenzt
if limit.limiting_value is not None and limit.limiting_value != LimitingValue.POWER:
cp.data.control_parameter.limit = limit
available_for_cp = common.available_current_for_cp(cp, counts, available_currents, missing_currents)
- if counter.get_control_range_state(feed_in_yield) == ControlRangeState.MIDDLE:
- pv_charging = data.data.general_data.data.chargemode_config.pv_charging
+ if counter.get_control_range_state() == ControlRangeState.MIDDLE:
+ surplus = data.data.general_data.data.chargemode_config.surplus
dif_to_old_current = available_for_cp + cp.data.set.target_current - cp.data.set.current_prev
# Wenn die Differenz zwischen altem und neuem Soll-Strom größer als der Regelbereich ist, trotzdem
# nachregeln, auch wenn der Regelbereich eingehalten wird. Sonst würde zB nicht berücksichtigt werden,
# wenn noch ein Fahrzeug dazu kommt.
- if ((pv_charging.control_range[1] - pv_charging.control_range[0]) /
+ if ((surplus.control_range[1] - surplus.control_range[0]) /
(sum(counter.data.get.voltages) / len(counter.data.get.voltages)) < abs(dif_to_old_current)):
current = available_for_cp
else:
@@ -105,14 +98,6 @@ def _set_loadmangement_message(self,
chargepoint.set_state_and_log(f"Es kann nicht mit der vorgegebenen Stromstärke geladen werden"
f"{limit.message}")
- # tested
- def filter_by_feed_in_limit(self, chargepoints: List[Chargepoint]) -> Tuple[List[Chargepoint], List[Chargepoint]]:
- cp_with_feed_in = list(filter(lambda cp: cp.data.set.charge_template.data.chargemode.
- pv_charging.feed_in_limit is True, chargepoints))
- cp_without_feed_in = list(filter(lambda cp: cp.data.set.charge_template.data.chargemode.
- pv_charging.feed_in_limit is False, chargepoints))
- return cp_with_feed_in, cp_without_feed_in
-
def _fix_deviating_evse_current(self, chargepoint: Chargepoint) -> float:
"""Wenn Autos nicht die volle Ladeleistung nutzen, wird unnötig eingespeist. Dann kann um den noch nicht
genutzten Soll-Strom hochgeregelt werden. Wenn Fahrzeuge entgegen der Norm mehr Ladeleistung beziehen, als
diff --git a/packages/control/algorithm/surplus_controlled_test.py b/packages/control/algorithm/surplus_controlled_test.py
index a77060c8b0..5e2d26fa03 100644
--- a/packages/control/algorithm/surplus_controlled_test.py
+++ b/packages/control/algorithm/surplus_controlled_test.py
@@ -15,6 +15,11 @@
from control.ev.ev import Ev
+@pytest.fixture(autouse=True)
+def init_data_store():
+ data.data_init(Mock())
+
+
@pytest.fixture(autouse=True)
def mock_cp1() -> Chargepoint:
return Chargepoint(1, None)
@@ -30,29 +35,6 @@ def mock_cp3() -> Chargepoint:
return Chargepoint(3, None)
-@pytest.mark.parametrize("feed_in_limit_1, feed_in_limit_2, feed_in_limit_3, expected_sorted",
- [pytest.param(True, True, True, ([mock_cp1, mock_cp2, mock_cp3], [])),
- pytest.param(True, False, True, ([mock_cp1, mock_cp3], [mock_cp2])),
- pytest.param(False, False, False, ([], [mock_cp1, mock_cp2, mock_cp3]))])
-def test_filter_by_feed_in_limit(feed_in_limit_1: bool,
- feed_in_limit_2: bool,
- feed_in_limit_3: bool,
- expected_sorted: int):
- # setup
- def setup_cp(cp: Chargepoint, feed_in_limit: bool) -> Chargepoint:
- cp.data = ChargepointData()
- cp.data.set.charge_template.data.chargemode.pv_charging.feed_in_limit = feed_in_limit
- return cp
-
- cp1 = setup_cp(mock_cp1, feed_in_limit_1)
- cp2 = setup_cp(mock_cp2, feed_in_limit_2)
- cp3 = setup_cp(mock_cp3, feed_in_limit_3)
- # execution
- cp_with_feed_in, cp_without_feed_in = SurplusControlled().filter_by_feed_in_limit([cp1, cp2, cp3])
- # evaluation
- assert (cp_with_feed_in, cp_without_feed_in) == expected_sorted
-
-
@pytest.mark.parametrize("new_current, expected_current",
[
pytest.param(7, 10),
@@ -134,24 +116,28 @@ def test_add_unused_evse_current(evse_current: float,
@pytest.mark.parametrize(
- "submode_1, submode_2, expected_chargepoints",
+ "submode_1, submode_2, expected_cp_keys",
[
- pytest.param(Chargemode.PV_CHARGING, Chargemode.PV_CHARGING, [mock_cp1, mock_cp2]),
- pytest.param(Chargemode.INSTANT_CHARGING, Chargemode.PV_CHARGING, [mock_cp2]),
+ pytest.param(Chargemode.PV_CHARGING, Chargemode.PV_CHARGING, ["cp1", "cp2"]),
+ pytest.param(Chargemode.INSTANT_CHARGING, Chargemode.PV_CHARGING, ["cp2"]),
pytest.param(Chargemode.INSTANT_CHARGING, Chargemode.INSTANT_CHARGING, []),
])
def test_get_chargepoints_submode_pv_charging(submode_1: Chargemode,
submode_2: Chargemode,
- expected_chargepoints: List[Chargepoint]):
+ expected_cp_keys: List[str],
+ mock_cp1: Chargepoint,
+ mock_cp2: Chargepoint):
# setup
def setup_cp(cp: Chargepoint, submode: str) -> Chargepoint:
+ cp.data = ChargepointData()
cp.data.set.charging_ev_data = Ev(0)
cp.data.control_parameter.chargemode = Chargemode.PV_CHARGING
cp.data.control_parameter.submode = submode
cp.data.control_parameter.required_current = 6
return cp
- data.Data.cp_data = {"cp1": setup_cp(mock_cp1, submode_1),
+ data.data.cp_data = {"cp1": setup_cp(mock_cp1, submode_1),
"cp2": setup_cp(mock_cp2, submode_2)}
+ expected_chargepoints = [data.data.cp_data[key] for key in expected_cp_keys]
# evaluation
chargepoints = get_chargepoints_with_required_current_by_chargemode(CONSIDERED_CHARGE_MODES_PV_ONLY)
diff --git a/packages/control/auto_phase_switch_test.py b/packages/control/auto_phase_switch_test.py
index 1c2a887b2c..d69eebad74 100644
--- a/packages/control/auto_phase_switch_test.py
+++ b/packages/control/auto_phase_switch_test.py
@@ -6,7 +6,6 @@
from control.counter import Counter, CounterData, Set
from control.limiting_value import LimitingValue, LoadmanagementLimit
-from control.ev.charge_template import ChargeTemplate
from control.pv_all import PvAll
from control.bat_all import BatAll
from control.general import General
@@ -135,8 +134,7 @@ def test_auto_phase_switch(monkeypatch: pytest.MonkeyPatch, vehicle: Ev, params:
control_parameter.state = params.state
# execution
- phases_to_use, current, message = vehicle.auto_phase_switch(ChargeTemplate(),
- control_parameter,
+ phases_to_use, current, message = vehicle.auto_phase_switch(control_parameter,
0,
max(params.get_currents),
params.get_currents,
diff --git a/packages/control/bat_all.py b/packages/control/bat_all.py
index d553be7509..cd846d5f89 100644
--- a/packages/control/bat_all.py
+++ b/packages/control/bat_all.py
@@ -325,10 +325,10 @@ def get_charging_power_left_diff(self):
die zum Laden der EV verwendet werden darf.
"""
try:
- config = data.data.general_data.data.chargemode_config.pv_charging
+ config = data.data.general_data.data.chargemode_config.bat
self.data.set.regulate_up = False
- if config.bat_mode == BatConsiderationMode.BAT_MODE.value:
+ if config.mode == BatConsiderationMode.BAT_MODE.value:
if self.data.get.power < 0:
# Wenn der Speicher entladen wird, darf diese Leistung nicht zum Laden der Fahrzeuge genutzt werden.
# Wenn der Speicher schneller regelt als die LP, würde sonst der Speicher reduziert werden.
@@ -337,7 +337,7 @@ def get_charging_power_left_diff(self):
charging_power_left = 0
self.data.set.regulate_up = True if self.data.get.soc < 100 else False
# ev wird nach Speicher geladen
- elif config.bat_mode == BatConsiderationMode.EV_MODE.value:
+ elif config.mode == BatConsiderationMode.EV_MODE.value:
# Speicher sollte weder ge- noch entladen werden.
# wenn aktive Speichersteuerung in Höhe PV-Leistung lädt
# hat Speicher Priorität vor EV-Ladung
@@ -349,7 +349,7 @@ def get_charging_power_left_diff(self):
else:
absolute_bat_discharge_power = self._absolute_bat_discharge_power()
# Speicher soll geladen werden um min SoC zu erreichen
- if self.data.get.soc < config.min_bat_soc:
+ if self.data.get.soc < config.min_soc:
self.data.set.hysteresis_discharge = False
if self.data.get.power < 0:
# Wenn der Speicher entladen wird, darf diese Leistung nicht zum Laden der Fahrzeuge
@@ -359,10 +359,10 @@ def get_charging_power_left_diff(self):
self.data.set.regulate_up = True
else:
# Speicher-Vorrang bis zum Min-Soc
- if config.bat_power_reserve_active:
+ if config.power_reserve_active:
# Die Differenz zwischen aktueller Batterie-Leistung und Reserveleistung bestimmt,
# was fuer EV-Ladung verbleibt (positiv) oder zusaetzlich benoetigt wird (negativ).
- charging_power_left = self.data.get.power - config.bat_power_reserve
+ charging_power_left = self.data.get.power - config.power_reserve
if charging_power_left < 0:
self.data.set.regulate_up = True
else:
@@ -370,12 +370,12 @@ def get_charging_power_left_diff(self):
charging_power_left = 0
self.data.set.regulate_up = True
# Speicher zwischen min und max SoC
- elif int(self.data.get.soc) >= config.min_bat_soc and int(self.data.get.soc) < config.max_bat_soc:
+ elif int(self.data.get.soc) >= config.min_soc and int(self.data.get.soc) < config.max_soc:
# Speicher soll aktiv weder ge- noch entladen werden.
# Mindest-SoC wird gehalten oder der Speicher mit weiterem vorhanden Überschuss geladen.
if self.data.set.hysteresis_discharge is False:
charging_power_left = self.data.get.power
- # Speicher darf wegen Hysterese bis min_bat_soc entladen werden.
+ # Speicher darf wegen Hysterese bis min_soc entladen werden.
else:
if self.data.set.power_limit is None:
# set allowed power
@@ -393,10 +393,10 @@ def get_charging_power_left_diff(self):
(self.data.config.power_limit_condition ==
BatPowerLimitCondition.PRICE_LIMIT.value and
self.data.set.power_limit is None))
- if config.bat_power_discharge_active and power_discharge_allowed:
+ if config.power_discharge_active and power_discharge_allowed:
# max Entladeleistung auf max Ausgangsleistung des WR begrenzen
required_absolut_discharge_power = min(
- config.bat_power_discharge, absolute_bat_discharge_power)
+ config.power_discharge, absolute_bat_discharge_power)
# Differenz zwischen erlaubter Entladeleistung und aktueller Speicherleistung bestimmen.
# Wenn der Speicher lädt, darf die freigegebene Entladeleistung nicht die max
# Ausgangsleistung des WR überschreiten.
@@ -430,10 +430,10 @@ def get_charging_power_left_diff(self):
(self.data.config.power_limit_condition ==
BatPowerLimitCondition.PRICE_LIMIT.value and
self.data.set.power_limit is None))
- if config.bat_power_discharge_active and power_discharge_allowed:
+ if config.power_discharge_active and power_discharge_allowed:
# max Entladeleistung auf max Ausgangsleistung des WR begrenzen
required_absolut_discharge_power = min(
- config.bat_power_discharge, absolute_bat_discharge_power)
+ config.power_discharge, absolute_bat_discharge_power)
# Differenz zwischen erlaubter Entladeleistung und aktueller Speicherleistung bestimmen.
# Wenn der Speicher lädt, darf die freigegebene Entladeleistung nicht die max
# Ausgangsleistung des WR überschreiten.
@@ -514,8 +514,8 @@ def get_charge_mode_vehicle_charge(self):
charge_mode = BatChargeMode.BAT_SELF_REGULATION
# Debug Informationen
- control_range_low = data.data.general_data.data.chargemode_config.pv_charging.control_range[0]
- control_range_high = data.data.general_data.data.chargemode_config.pv_charging.control_range[1]
+ control_range_low = data.data.general_data.data.chargemode_config.surplus.control_range[0]
+ control_range_high = data.data.general_data.data.chargemode_config.surplus.control_range[1]
control_range_center = control_range_high - (control_range_high - control_range_low) / 2
if len(chargepoint_by_chargemodes) == 0:
log.debug("Speicher-Leistung nicht begrenzen, da keine Ladepunkte in einem aktiven Lademodus sind.")
diff --git a/packages/control/bat_all_test.py b/packages/control/bat_all_test.py
index 38863ccb92..cd83b18d59 100644
--- a/packages/control/bat_all_test.py
+++ b/packages/control/bat_all_test.py
@@ -10,7 +10,7 @@
from control import data
from control.chargepoint.chargepoint import Chargepoint
from control.chargepoint.chargepoint_all import AllChargepointData, AllChargepoints, AllGet
-from control.general import General, PvCharging
+from control.general import ChargemodeConfigBat, General
from control.pv import Config, Get, Pv, PvData
from modules.devices.generic.mqtt.bat import MqttBat
from modules.devices.generic.mqtt.config import MqttBatSetup
@@ -44,9 +44,9 @@ def test_get_charging_power_left_diff_hybrid(bat_power: int,
data.data.bat_data["bat1"] = Bat(1)
data.data.bat_data["bat1"].data.get.power = bat_power
data.data.bat_data["bat1"].data.get.soc = 71
- data.data.general_data.data.chargemode_config.pv_charging.bat_mode = BatConsiderationMode.MIN_SOC_BAT.value
- data.data.general_data.data.chargemode_config.pv_charging.bat_power_discharge = 5000
- data.data.general_data.data.chargemode_config.pv_charging.bat_power_discharge_active = True
+ data.data.general_data.data.chargemode_config.bat.mode = BatConsiderationMode.MIN_SOC_BAT.value
+ data.data.general_data.data.chargemode_config.bat.power_discharge = 5000
+ data.data.general_data.data.chargemode_config.bat.power_discharge_active = True
monkeypatch.setattr(data.data.counter_all_data, "get_hybrid_bat_ids", Mock(return_value=[1]))
monkeypatch.setattr(data.data.counter_all_data, "get_non_hybrid_bat_ids", Mock(return_value=[]))
monkeypatch.setattr(data.data.counter_all_data, "get_hybrid_inverter_ids", Mock(return_value=[2]))
@@ -99,7 +99,7 @@ def test__absolute_bat_discharge_power(hybrid_bat_ids: List[int],
@dataclass
class Params:
name: str
- config: PvCharging
+ config: ChargemodeConfigBat
power: float
soc: float
expected_charging_power_left: float
@@ -109,58 +109,60 @@ class Params:
cases = [
- Params("Speicher, Speicher lädt", PvCharging(bat_mode="bat_mode"), 500, 90, -100, True),
- Params("Speicher, Speicher entlädt", PvCharging(bat_mode="bat_mode"), -500, 90, -600, True),
- Params("Speicher, Speicher ist voll", PvCharging(bat_mode="bat_mode"), 0, 100, 0, False),
- Params("EV, Speicher lädt", PvCharging(bat_mode="ev_mode"), 500, 90, 500, False),
- Params("EV, Speicher entlädt", PvCharging(bat_mode="ev_mode"), -500, 90, -500, False),
- Params("EV, Speicher ist voll", PvCharging(bat_mode="ev_mode"), 0, 100, 0, False),
+ Params("Speicher, Speicher lädt", ChargemodeConfigBat(mode="bat_mode"), 500, 90, -100, True),
+ Params("Speicher, Speicher entlädt", ChargemodeConfigBat(mode="bat_mode"), -500, 90, -600, True),
+ Params("Speicher, Speicher ist voll", ChargemodeConfigBat(mode="bat_mode"), 0, 100, 0, False),
+ Params("EV, Speicher lädt", ChargemodeConfigBat(mode="ev_mode"), 500, 90, 500, False),
+ Params("EV, Speicher entlädt", ChargemodeConfigBat(mode="ev_mode"), -500, 90, -500, False),
+ Params("EV, Speicher ist voll", ChargemodeConfigBat(mode="ev_mode"), 0, 100, 0, False),
Params("Mindest-SoC, SoC nicht erreicht, Speicher entlädt",
- PvCharging(bat_mode="min_soc_bat_mode"), -500, 40, -600, True),
+ ChargemodeConfigBat(mode="min_soc_bat_mode"), -500, 40, -600, True),
Params("Mindest-SoC, SoC nicht erreicht, Speicher lädt",
- PvCharging(bat_mode="min_soc_bat_mode"), 500, 40, -100, True),
+ ChargemodeConfigBat(mode="min_soc_bat_mode"), 500, 40, -100, True),
Params("Mindest-SoC, SoC nicht erreicht, Speicher-Reserve, Speicher entlädt",
- PvCharging(bat_mode="min_soc_bat_mode", bat_power_reserve=2000, bat_power_reserve_active=True),
+ ChargemodeConfigBat(mode="min_soc_bat_mode", power_reserve=2000, power_reserve_active=True),
-500, 40, -600, True),
Params("Mindest-SoC, SoC nicht erreicht, Speicher-Reserve nicht ausgenutzt, Speicher lädt",
- PvCharging(bat_mode="min_soc_bat_mode", bat_power_reserve=2000, bat_power_reserve_active=True),
+ ChargemodeConfigBat(mode="min_soc_bat_mode", power_reserve=2000, power_reserve_active=True),
1600, 40, -500, True),
Params("Mindest-SoC, SoC nicht erreicht, Speicher-Reserve ausgenutzt, Speicher lädt",
- PvCharging(bat_mode="min_soc_bat_mode", bat_power_reserve=2000, bat_power_reserve_active=True),
+ ChargemodeConfigBat(mode="min_soc_bat_mode", power_reserve=2000, power_reserve_active=True),
2200, 40, 200, False),
- Params("Mindest-SoC, SoC erreicht, Speicher entlädt", PvCharging(bat_mode="min_soc_bat_mode"), -500, 90, -500,
+ Params("Mindest-SoC, SoC erreicht, Speicher entlädt", ChargemodeConfigBat(mode="min_soc_bat_mode"), -500, 90, -500,
False),
- Params("Mindest-SoC, SoC erreicht, Speicher lädt", PvCharging(bat_mode="min_soc_bat_mode"), 500, 90, 500, False),
- Params("Mindest-SoC, SoC erreicht, Speicher ist voll", PvCharging(bat_mode="min_soc_bat_mode"), 0, 100, 0, False),
+ Params("Mindest-SoC, SoC erreicht, Speicher lädt",
+ ChargemodeConfigBat(mode="min_soc_bat_mode"), 500, 90, 500, False),
+ Params("Mindest-SoC, SoC erreicht, Speicher ist voll",
+ ChargemodeConfigBat(mode="min_soc_bat_mode"), 0, 100, 0, False),
Params("Mindest-SoC, SoC erreicht, Entladung in Auto, Speicher entlädt, Entladeleistung nicht erreicht",
- PvCharging(bat_mode="min_soc_bat_mode", bat_power_discharge=500, bat_power_discharge_active=True),
+ ChargemodeConfigBat(mode="min_soc_bat_mode", power_discharge=500, power_discharge_active=True),
-400, 90, 100, False),
Params("Mindest-SoC, SoC erreicht, Entladung in Auto, Speicher entlädt, mehr als Entladeleistung",
- PvCharging(bat_mode="min_soc_bat_mode", bat_power_discharge=500, bat_power_discharge_active=True),
+ ChargemodeConfigBat(mode="min_soc_bat_mode", power_discharge=500, power_discharge_active=True),
-600, 90, -100, False),
Params("Mindest-SoC, SoC erreicht, Entladung in Auto, Speicher entlädt, Entladeleistung erreicht",
- PvCharging(bat_mode="min_soc_bat_mode", bat_power_discharge=500, bat_power_discharge_active=True),
+ ChargemodeConfigBat(mode="min_soc_bat_mode", power_discharge=500, power_discharge_active=True),
-500, 90, 0, False),
Params("Mindest-SoC, SoC erreicht, Entladung in Auto, Speicher lädt mit mehr als Entladeleistung",
- PvCharging(bat_mode="min_soc_bat_mode", bat_power_discharge=500, bat_power_discharge_active=True),
+ ChargemodeConfigBat(mode="min_soc_bat_mode", power_discharge=500, power_discharge_active=True),
650, 90, 1150, False),
Params("Mindest-SoC, SoC erreicht, Entladung in Auto, Speicher lädt mit weniger als Entladeleistung",
- PvCharging(bat_mode="min_soc_bat_mode", bat_power_discharge=500, bat_power_discharge_active=True),
+ ChargemodeConfigBat(mode="min_soc_bat_mode", power_discharge=500, power_discharge_active=True),
400, 90, 900, False),
Params("Mindest-SoC, SoC erreicht, Entladung in Auto, Speicher voll",
- PvCharging(bat_mode="min_soc_bat_mode", bat_power_reserve=500, bat_power_reserve_active=True,
- min_bat_soc=100), 0, 100, 0, False),
+ ChargemodeConfigBat(mode="min_soc_bat_mode", power_reserve=500, power_reserve_active=True,
+ min_soc=100), 0, 100, 0, False),
Params(("Mindest-SoC, SoC erreicht, Entladung in Auto, Speicher lädt mit weniger als Entladeleistung, "
"Speicher-Sperre aktiv"),
- PvCharging(bat_mode="min_soc_bat_mode", bat_power_discharge=500, bat_power_discharge_active=True),
+ ChargemodeConfigBat(mode="min_soc_bat_mode", power_discharge=500, power_discharge_active=True),
400, 90, 0, False, 600),
Params(("Mindest-SoC, Hysterese, EV-Vorrang, keine Speichernutzung"),
- PvCharging(bat_mode="min_soc_bat_mode"), 400, 60, 400, False, hysteresis_discharge=False),
+ ChargemodeConfigBat(mode="min_soc_bat_mode"), 400, 60, 400, False, hysteresis_discharge=False),
Params(("Mindest-SoC, Hysterese, Speicherentladung, Speichernutzung erlaubt"),
- PvCharging(bat_mode="min_soc_bat_mode", bat_power_discharge=500, bat_power_discharge_active=True),
+ ChargemodeConfigBat(mode="min_soc_bat_mode", power_discharge=500, power_discharge_active=True),
400, 60, 900, False, hysteresis_discharge=True),
Params(("Mindest-SoC, Hysterese, Speicherentladung, Speichernutzung erlaubt, Speicher-Sperre aktiv"),
- PvCharging(bat_mode="min_soc_bat_mode", bat_power_discharge=500, bat_power_discharge_active=True),
+ ChargemodeConfigBat(mode="min_soc_bat_mode", power_discharge=500, power_discharge_active=True),
400, 60, 0, False, 600, hysteresis_discharge=True),
]
@@ -176,7 +178,7 @@ def test_get_charging_power_left(params: Params, caplog, data_, monkeypatch):
b = Bat(0)
b.data.get.power = params.power
data.data.bat_data["bat0"] = b
- data.data.general_data.data.chargemode_config.pv_charging = params.config
+ data.data.general_data.data.chargemode_config.bat = params.config
mock_absolute_bat_discharge_power = MagicMock(return_value=10000)
monkeypatch.setattr(BatAll, "_absolute_bat_discharge_power", mock_absolute_bat_discharge_power)
@@ -196,12 +198,12 @@ def test_get_charging_power_left_uses_limited_bat_discharge_in_hysteresis(
b_all.data.get.soc = 60
b_all.data.set.hysteresis_discharge = True
b_all.data.set.power_limit = None
- data.data.general_data.data.chargemode_config.pv_charging = PvCharging(
- bat_mode="min_soc_bat_mode",
- min_bat_soc=40,
- max_bat_soc=80,
- bat_power_discharge=8000,
- bat_power_discharge_active=True,
+ data.data.general_data.data.chargemode_config.bat = ChargemodeConfigBat(
+ mode="min_soc_bat_mode",
+ min_soc=40,
+ max_soc=80,
+ power_discharge=8000,
+ power_discharge_active=True,
)
# Hybrid-Setup fuer reale Berechnung in _limit_bat_power_discharge
diff --git a/packages/control/chargepoint/chargepoint.py b/packages/control/chargepoint/chargepoint.py
index e435f7d9f6..e4122267c8 100644
--- a/packages/control/chargepoint/chargepoint.py
+++ b/packages/control/chargepoint/chargepoint.py
@@ -839,14 +839,14 @@ def hw_supports_phase_switch(self) -> bool:
self.data.set.log.imported_since_plugged == 0))
def failed_phase_switches_reached(self) -> bool:
- if (data.data.general_data.data.chargemode_config.pv_charging.retry_failed_phase_switches and
+ if (data.data.general_data.data.chargemode_config.surplus.vehicle.retry_failed_phase_switches and
self.data.control_parameter.failed_phase_switches > self.MAX_FAILED_PHASE_SWITCHES):
# bei deaktiverter Wiederholung der Umschaltung nur den gewünschten Umschaltvorgang durchführen,
# keinen Korrekturversuch
self.set_state_and_log(
"Keine Phasenumschaltung, da die maximale Anzahl an Fehlversuchen erreicht wurde. ")
return True
- elif (data.data.general_data.data.chargemode_config.pv_charging.retry_failed_phase_switches is False and
+ elif (data.data.general_data.data.chargemode_config.surplus.vehicle.retry_failed_phase_switches is False and
self.data.control_parameter.failed_phase_switches > 0):
return True
else:
diff --git a/packages/control/chargepoint/chargepoint_test.py b/packages/control/chargepoint/chargepoint_test.py
index 3ea9c9e622..57a746649b 100644
--- a/packages/control/chargepoint/chargepoint_test.py
+++ b/packages/control/chargepoint/chargepoint_test.py
@@ -147,7 +147,7 @@ def test_is_phase_switch_required(params: Params):
cp.data.get.charge_state = params.charge_state
cp.data.control_parameter.failed_phase_switches = params.failed_phase_switches
data.data_init(Mock())
- data.data.general_data.data.chargemode_config.pv_charging.retry_failed_phase_switches = (
+ data.data.general_data.data.chargemode_config.surplus.vehicle.retry_failed_phase_switches = (
params.retry_failed_phase_switches
)
diff --git a/packages/control/chargepoint/get_phases_test.py b/packages/control/chargepoint/get_phases_test.py
index b8bec247e0..e4bf1283f4 100644
--- a/packages/control/chargepoint/get_phases_test.py
+++ b/packages/control/chargepoint/get_phases_test.py
@@ -219,7 +219,7 @@ def test_failed_phase_switches_reached(cp: Chargepoint,
failed_phase_switches: int,
expected: bool):
# setup
- data.data.general_data.data.chargemode_config.pv_charging.retry_failed_phase_switches = (
+ data.data.general_data.data.chargemode_config.surplus.vehicle.retry_failed_phase_switches = (
retry_failed_phase_switches
)
cp.data.control_parameter.failed_phase_switches = failed_phase_switches
diff --git a/packages/control/counter.py b/packages/control/counter.py
index e7351b3cef..ab121626ac 100644
--- a/packages/control/counter.py
+++ b/packages/control/counter.py
@@ -231,10 +231,11 @@ def calc_raw_surplus(self):
ranged_surplus = surplus + self._control_range_offset()
return ranged_surplus
- def get_control_range_state(self, feed_in_yield: int) -> ControlRangeState:
- control_range_low = data.data.general_data.data.chargemode_config.pv_charging.control_range[0]
- control_range_high = data.data.general_data.data.chargemode_config.pv_charging.control_range[1]
- surplus = data.data.counter_all_data.get_evu_counter().data.get.power + feed_in_yield
+ def get_control_range_state(self) -> ControlRangeState:
+ control_range_low = data.data.general_data.data.chargemode_config.surplus.control_range[0]
+ control_range_high = data.data.general_data.data.chargemode_config.surplus.control_range[1]
+ surplus = (data.data.counter_all_data.get_evu_counter().data.get.power
+ + data.data.general_data.get_feed_in_yield())
if control_range_low > surplus:
return ControlRangeState.BELOW
elif surplus > control_range_high:
@@ -246,17 +247,17 @@ def _control_range_offset(self):
if data.data.bat_all_data.data.set.regulate_up:
# Regelmodus ignorieren, denn mit Regelmodus Bezug kann keine Einspeisung für den Speicher erzeugt werden.
return 0
- control_range_low = data.data.general_data.data.chargemode_config.pv_charging.control_range[0]
- control_range_high = data.data.general_data.data.chargemode_config.pv_charging.control_range[1]
+ control_range_low = data.data.general_data.data.chargemode_config.surplus.control_range[0]
+ control_range_high = data.data.general_data.data.chargemode_config.surplus.control_range[1]
control_range_center = control_range_high - (control_range_high - control_range_low) / 2
range_offset = control_range_center
log.debug(f"Anpassen des Regelbereichs {range_offset}W")
return range_offset
- def get_usable_surplus(self, feed_in_yield: float) -> float:
+ def get_usable_surplus(self) -> 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)
+ self.data.set.reserved_surplus - data.data.general_data.get_feed_in_yield())
SWITCH_ON_FALLEN_BELOW = "Einschaltschwelle während der Wartezeit unterschritten."
SWITCH_ON_WAITING = "Die Ladung wird gestartet, sobald in {} die Wartezeit abgelaufen ist."
@@ -268,25 +269,23 @@ def get_usable_surplus(self, feed_in_yield: float) -> float:
def calc_switch_on_power(self, chargepoint: Chargepoint) -> Tuple[float, float]:
surplus = self.calc_raw_surplus() - self.data.set.reserved_surplus
control_parameter = chargepoint.data.control_parameter
- pv_config = data.data.general_data.data.chargemode_config.pv_charging
+ surplus_config = data.data.general_data.data.chargemode_config.surplus
- if chargepoint.data.set.charge_template.data.chargemode.pv_charging.feed_in_limit:
- threshold = pv_config.feed_in_yield
+ if surplus_config.feed_in_limit:
+ threshold = surplus_config.feed_in_yield
else:
- threshold = pv_config.switch_on_threshold*control_parameter.phases
+ threshold = surplus_config.vehicle.switch_on_threshold*control_parameter.phases
return surplus, threshold
def switch_on_threshold_reached(self, chargepoint: Chargepoint) -> None:
try:
message = None
control_parameter = chargepoint.data.control_parameter
- feed_in_limit = chargepoint.data.set.charge_template.data.chargemode.pv_charging.\
- feed_in_limit
- pv_config = data.data.general_data.data.chargemode_config.pv_charging
+ surplus_config = data.data.general_data.data.chargemode_config.surplus
timestamp_switch_on_off = control_parameter.timestamp_switch_on_off
surplus, threshold = self.calc_switch_on_power(chargepoint)
- power_to_reserve = pv_config.switch_on_threshold*control_parameter.phases
+ power_to_reserve = surplus_config.vehicle.switch_on_threshold*control_parameter.phases
if control_parameter.state == ChargepointState.SWITCH_ON_DELAY:
# Wurde die Einschaltschwelle erreicht? Reservierte Leistung aus all_surplus herausrechnen,
# da diese Leistung ja schon reserviert wurde, als die Einschaltschwelle erreicht wurde.
@@ -294,22 +293,22 @@ def switch_on_threshold_reached(self, chargepoint: Chargepoint) -> None:
# Einschaltschwelle wurde unterschritten, Timer zurücksetzen
timestamp_switch_on_off = None
self.data.set.reserved_surplus -= power_to_reserve
- message = self.SWITCH_ON_FALLEN_BELOW.format(pv_config.switch_on_threshold)
+ message = self.SWITCH_ON_FALLEN_BELOW.format(surplus_config.vehicle.switch_on_threshold)
control_parameter.state = ChargepointState.NO_CHARGING_ALLOWED
else:
# Timer starten
- if (surplus >= threshold) and ((feed_in_limit and self.data.set.reserved_surplus == 0) or
- not feed_in_limit):
+ if (surplus >= threshold) and ((surplus_config.feed_in_limit and self.data.set.reserved_surplus == 0) or
+ not surplus_config.feed_in_limit):
timestamp_switch_on_off = timecheck.create_timestamp()
self.data.set.reserved_surplus += power_to_reserve
message = self.SWITCH_ON_WAITING.format(timecheck.convert_timestamp_delta_to_time_string(
- timestamp_switch_on_off, pv_config.switch_on_delay))
- if feed_in_limit:
- message += "Die Einspeisegrenze wird berücksichtigt."
+ timestamp_switch_on_off, surplus_config.vehicle.switch_on_delay))
+ if surplus_config.feed_in_limit:
+ message += " Die Einspeisegrenze wird berücksichtigt."
control_parameter.state = ChargepointState.SWITCH_ON_DELAY
else:
# Einschaltschwelle nicht erreicht
- message = self.SWITCH_ON_NOT_EXCEEDED.format(pv_config.switch_on_threshold)
+ message = self.SWITCH_ON_NOT_EXCEEDED.format(surplus_config.vehicle.switch_on_threshold)
if timestamp_switch_on_off != control_parameter.timestamp_switch_on_off:
control_parameter.timestamp_switch_on_off = timestamp_switch_on_off
@@ -328,31 +327,29 @@ def switch_on_timer_expired(self, chargepoint: Chargepoint) -> None:
"""
try:
msg = None
- pv_config = data.data.general_data.data.chargemode_config.pv_charging
+ surplus_config = data.data.general_data.data.chargemode_config.surplus
control_parameter = chargepoint.data.control_parameter
charging_ev_data = chargepoint.data.set.charging_ev_data
# Timer ist noch nicht abgelaufen
if timecheck.check_timestamp(control_parameter.timestamp_switch_on_off,
- pv_config.switch_on_delay):
+ surplus_config.vehicle.switch_on_delay):
msg = self.SWITCH_ON_WAITING.format(timecheck.convert_timestamp_delta_to_time_string(
- control_parameter.timestamp_switch_on_off, pv_config.switch_on_delay))
+ control_parameter.timestamp_switch_on_off, surplus_config.vehicle.switch_on_delay))
# Timer abgelaufen
else:
control_parameter.timestamp_switch_on_off = 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)
+ self.data.set.reserved_surplus -= (
+ surplus_config.vehicle.switch_on_threshold*control_parameter.phases
+ )
+ msg = self.SWITCH_ON_EXPIRED.format(surplus_config.vehicle.switch_on_threshold)
control_parameter.state = ChargepointState.WAIT_FOR_USING_PHASES
- if chargepoint.data.set.charge_template.data.chargemode.pv_charging.feed_in_limit:
- feed_in_yield = pv_config.feed_in_yield
- else:
- feed_in_yield = 0
ev_template = charging_ev_data.ev_template
max_phases_power = ev_template.data.min_current * ev_template.data.max_phases * 230
if (control_parameter.submode == Chargemode.PV_CHARGING and
chargepoint.data.set.charge_template.data.chargemode.pv_charging.phases_to_use == 0 and
chargepoint.hw_supports_phase_switch() and
- self.get_usable_surplus(feed_in_yield) > max_phases_power):
+ self.get_usable_surplus() > 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)
@@ -370,35 +367,35 @@ def switch_on_timer_expired(self, chargepoint: Chargepoint) -> None:
def switch_off_check_timer(self, chargepoint: Chargepoint) -> None:
try:
msg = None
- pv_config = data.data.general_data.data.chargemode_config.pv_charging
+ surplus_config = data.data.general_data.data.chargemode_config.surplus
control_parameter = chargepoint.data.control_parameter
if control_parameter.timestamp_switch_on_off is not None:
if not timecheck.check_timestamp(
control_parameter.timestamp_switch_on_off,
- pv_config.switch_off_delay):
+ surplus_config.vehicle.switch_off_delay):
control_parameter.timestamp_switch_on_off = None
self.data.set.released_surplus -= chargepoint.data.set.required_power
msg = self.SWITCH_OFF_STOP
control_parameter.state = ChargepointState.NO_CHARGING_ALLOWED
else:
msg = self.SWITCH_OFF_WAITING.format(timecheck.convert_timestamp_delta_to_time_string(
- control_parameter.timestamp_switch_on_off, pv_config.switch_off_delay))
+ control_parameter.timestamp_switch_on_off, surplus_config.vehicle.switch_off_delay))
chargepoint.set_state_and_log(msg)
except Exception:
log.exception("Fehler im allgemeinen PV-Modul")
def calc_switch_off_threshold(self, chargepoint: Chargepoint) -> float:
- pv_config = data.data.general_data.data.chargemode_config.pv_charging
+ surplus_config = data.data.general_data.data.chargemode_config.surplus
control_parameter = chargepoint.data.control_parameter
- if chargepoint.data.set.charge_template.data.chargemode.pv_charging.feed_in_limit:
+ if surplus_config.feed_in_limit:
# Der EVU-Überschuss muss ggf um die Einspeisegrenze bereinigt werden.
# Wnn die Leistung nicht Einspeisegrenze + Einschaltschwelle erreicht, darf die Ladung nicht pulsieren.
# Abschaltschwelle um Einschaltschwelle reduzieren.
- threshold = (-data.data.general_data.data.chargemode_config.pv_charging.feed_in_yield
- + pv_config.switch_on_threshold*control_parameter.phases)
+ threshold = (-surplus_config.feed_in_yield
+ + surplus_config.vehicle.switch_on_threshold*control_parameter.phases)
else:
- threshold = pv_config.switch_off_threshold
+ threshold = surplus_config.vehicle.switch_off_threshold
return threshold
def calc_switch_off(self, chargepoint: Chargepoint) -> Tuple[float, float]:
@@ -464,7 +461,7 @@ def switch_off_check_threshold(self, chargepoint: Chargepoint) -> bool:
self.data.set.released_surplus += chargepoint.data.set.required_power
msg = self.SWITCH_OFF_WAITING.format(timecheck.convert_timestamp_delta_to_time_string(
timestamp_switch_on_off,
- data.data.general_data.data.chargemode_config.pv_charging.switch_off_delay))
+ data.data.general_data.data.chargemode_config.surplus.vehicle.switch_off_delay))
control_parameter.state = ChargepointState.SWITCH_OFF_DELAY
# Die Abschaltschwelle wird immer noch überschritten und es sollten weitere LP abgeschaltet
# werden.
@@ -483,12 +480,12 @@ def reset_switch_on_off(self, chargepoint: Chargepoint):
# Wenn bereits geladen wird, lief die Abschaltverzögerung -> Leistung, die nach Abschalten frei
# geworden wäre, nicht mehr zum zur Verfügung stehenden Überschuss zählen.
# Wenn nicht geladen wird, reservierte Leistung freigeben.
- pv_config = data.data.general_data.data.chargemode_config.pv_charging
+ surplus_config = data.data.general_data.data.chargemode_config.surplus
if not chargepoint.data.get.charge_state:
- evu_counter.data.set.reserved_surplus -= (pv_config.switch_on_threshold
+ evu_counter.data.set.reserved_surplus -= (surplus_config.vehicle.switch_on_threshold
* chargepoint.data.set.phases_to_use)
else:
- evu_counter.data.set.released_surplus -= (pv_config.switch_on_threshold
+ evu_counter.data.set.released_surplus -= (surplus_config.vehicle.switch_on_threshold
* chargepoint.data.control_parameter.phases)
chargepoint.data.control_parameter.state = ChargepointState.NO_CHARGING_ALLOWED
except Exception:
diff --git a/packages/control/counter_test.py b/packages/control/counter_test.py
index 4b3e59466a..06509b89a5 100644
--- a/packages/control/counter_test.py
+++ b/packages/control/counter_test.py
@@ -122,7 +122,8 @@ class Params:
-681, 15000, 1652683250.0, ChargepointState.SWITCH_ON_DELAY,
Counter.SWITCH_ON_FALLEN_BELOW.format(1500), None, 0),
Params("Feed_in_limit, Timer starten", True, 0, 15001, 15000, None, ChargepointState.NO_CHARGING_ALLOWED,
- Counter.SWITCH_ON_WAITING.format("30 Sek."), 1652683252.0, 1500),
+ Counter.SWITCH_ON_WAITING.format("30 Sek.") + " Die Einspeisegrenze wird berücksichtigt.",
+ 1652683252.0, 1500),
Params("Feed_in_limit, Einschaltschwelle nicht erreicht", True, 0, 14999,
15000, None, ChargepointState.NO_CHARGING_ALLOWED, Counter.SWITCH_ON_NOT_EXCEEDED.format(1500), None, 0),
Params("Feed_in_limit, Einschaltschwelle läuft", True, 1500, 15001,
@@ -141,7 +142,7 @@ def test_switch_on_threshold_reached(params: Params, caplog, general_data_fixtur
cp.data.control_parameter.state = params.state
cp.data.control_parameter.timestamp_switch_on_off = params.timestamp_switch_on_off
ev.data.charge_template = ChargeTemplate()
- ev.data.charge_template.data.chargemode.pv_charging.feed_in_limit = params.feed_in_limit
+ data.data.general_data.data.chargemode_config.surplus.feed_in_limit = params.feed_in_limit
cp.data.set.charging_ev_data = ev
mock_calc_switch_on_power = Mock(return_value=[params.surplus, params.threshold])
monkeypatch.setattr(Counter, "calc_switch_on_power", mock_calc_switch_on_power)
@@ -170,7 +171,7 @@ def test_control_range(control_range, evu_power, expected_range_offset, general_
get_evu_counter_mock = Mock(return_value=Mock(spec=Counter, data=Mock(
spec=CounterData, get=Mock(spec=Get, power=evu_power))))
monkeypatch.setattr(data.data.counter_all_data, "get_evu_counter", get_evu_counter_mock)
- data.data.general_data.data.chargemode_config.pv_charging.control_range = control_range
+ data.data.general_data.data.chargemode_config.surplus.control_range = control_range
c = Counter(0)
# execution
diff --git a/packages/control/ev/charge_template.py b/packages/control/ev/charge_template.py
index 20f7ba88bb..655b07a24f 100644
--- a/packages/control/ev/charge_template.py
+++ b/packages/control/ev/charge_template.py
@@ -64,7 +64,6 @@ class InstantCharging:
class PvCharging:
dc_min_current: float = 145
dc_min_soc_current: float = 145
- feed_in_limit: bool = False
limit: Limit = field(default_factory=limit_factory)
min_current: int = 0
min_soc_current: int = 10
diff --git a/packages/control/ev/ev.py b/packages/control/ev/ev.py
index fab9167328..88ef507868 100644
--- a/packages/control/ev/ev.py
+++ b/packages/control/ev/ev.py
@@ -302,7 +302,6 @@ def _check_phase_switch_conditions(self,
PHASE_SWITCH_DELAY_TEXT = '{} Phasen in {}.'
def auto_phase_switch(self,
- charge_template: ChargeTemplate,
control_parameter: ControlParameter,
cp_num: int,
evse_current: float,
@@ -315,12 +314,8 @@ def auto_phase_switch(self,
current = control_parameter.required_current
phases_to_use = control_parameter.phases
phases_in_use = control_parameter.phases
- pv_config = data.data.general_data.data.chargemode_config.pv_charging
- if charge_template.data.chargemode.pv_charging.feed_in_limit:
- feed_in_yield = pv_config.feed_in_yield
- else:
- feed_in_yield = 0
- delay = pv_config.phase_switch_delay * 60
+ surplus_config = data.data.general_data.data.chargemode_config.surplus
+ delay = surplus_config.vehicle.phase_switch_delay * 60
if phases_in_use == 1:
direction_str = f"Umschaltung von 1 auf {max_phases}"
required_reserved_power = (control_parameter.min_current * max_phases * 230 -
@@ -328,15 +323,15 @@ def auto_phase_switch(self,
new_phase = max_phases
new_current = control_parameter.min_current
- waiting_time = pv_config.switch_on_delay
+ waiting_time = surplus_config.vehicle.switch_on_delay
else:
direction_str = f"Umschaltung von {max_phases} auf 1"
# Es kann einphasig mit entsprechend niedriger Leistung gestartet werden.
required_reserved_power = 0
new_phase = 1
new_current = self.ev_template.data.max_current_single_phase
- waiting_time = pv_config.switch_off_delay
- all_surplus = data.data.counter_all_data.get_evu_counter().get_usable_surplus(feed_in_yield)
+ waiting_time = surplus_config.vehicle.switch_off_delay
+ all_surplus = data.data.counter_all_data.get_evu_counter().get_usable_surplus()
if control_parameter.state == ChargepointState.PHASE_SWITCH_DELAY:
# eigene reservierte Leistung addieren, wenn die Verzögerung für die Umschaltung läuft,
# da diese Leistung bereits für die Umschaltung reserviert ist.
diff --git a/packages/control/general.py b/packages/control/general.py
index 80941ead81..a76b2a0a75 100644
--- a/packages/control/general.py
+++ b/packages/control/general.py
@@ -12,56 +12,65 @@
log = logging.getLogger(__name__)
-def control_range_factory() -> List:
+def control_range_factory() -> List[int]:
return [0, 230]
@dataclass
-class PvCharging:
- bat_power_reserve: int = field(default=2000, metadata={
- "topic": "chargemode_config/pv_charging/bat_power_reserve"})
- bat_power_reserve_active: bool = field(default=False, metadata={
- "topic": "chargemode_config/pv_charging/bat_power_reserve_active"})
- control_range: List = field(default_factory=control_range_factory, metadata={
- "topic": "chargemode_config/pv_charging/control_range"})
- feed_in_yield: int = field(default=15000, metadata={
- "topic": "chargemode_config/pv_charging/feed_in_yield"})
+class ChargemodeConfigBat:
+ power_reserve: int = field(default=2000, metadata={
+ "topic": "chargemode_config/bat/power_reserve"})
+ power_reserve_active: bool = field(default=False, metadata={
+ "topic": "chargemode_config/bat/power_reserve_active"})
+ power_discharge: int = field(default=1500, metadata={
+ "topic": "chargemode_config/bat/power_discharge"})
+ power_discharge_active: bool = field(default=False, metadata={
+ "topic": "chargemode_config/bat/power_discharge_active"})
+ min_soc: int = field(default=50, metadata={
+ "topic": "chargemode_config/bat/min_soc"})
+ max_soc: int = field(default=70, metadata={
+ "topic": "chargemode_config/bat/max_soc"})
+ mode: str = field(default=BatConsiderationMode.EV_MODE.value, metadata={
+ "topic": "chargemode_config/bat/mode"})
+
+
+@dataclass
+class ChargemodeConfigSurplusVehicle:
phase_switch_delay: int = field(default=7, metadata={
- "topic": "chargemode_config/pv_charging/phase_switch_delay"})
- bat_power_discharge: int = field(default=1500, metadata={
- "topic": "chargemode_config/pv_charging/bat_power_discharge"})
- bat_power_discharge_active: bool = field(default=False, metadata={
- "topic": "chargemode_config/pv_charging/bat_power_discharge_active"})
- min_bat_soc: int = field(default=50, metadata={
- "topic": "chargemode_config/pv_charging/min_bat_soc"})
- max_bat_soc: int = field(default=70, metadata={
- "topic": "chargemode_config/pv_charging/max_bat_soc"})
- bat_mode: BatConsiderationMode = field(default=BatConsiderationMode.EV_MODE.value, metadata={
- "topic": "chargemode_config/pv_charging/bat_mode"})
+ "topic": "chargemode_config/surplus/vehicle/phase_switch_delay"})
retry_failed_phase_switches: bool = field(
default=False,
- metadata={"topic": "chargemode_config/pv_charging/retry_failed_phase_switches"})
+ metadata={"topic": "chargemode_config/surplus/vehicle/retry_failed_phase_switches"})
switch_off_delay: int = field(default=60, metadata={
- "topic": "chargemode_config/pv_charging/switch_off_delay"})
+ "topic": "chargemode_config/surplus/vehicle/switch_off_delay"})
switch_off_threshold: int = field(default=0, metadata={
- "topic": "chargemode_config/pv_charging/switch_off_threshold"})
+ "topic": "chargemode_config/surplus/vehicle/switch_off_threshold"})
switch_on_delay: int = field(default=30, metadata={
- "topic": "chargemode_config/pv_charging/switch_on_delay"})
+ "topic": "chargemode_config/surplus/vehicle/switch_on_delay"})
switch_on_threshold: int = field(default=1500, metadata={
- "topic": "chargemode_config/pv_charging/switch_on_threshold"})
+ "topic": "chargemode_config/surplus/vehicle/switch_on_threshold"})
-def pv_charging_factory() -> PvCharging:
- return PvCharging()
+@dataclass
+class ChargemodeConfigSurplus:
+ control_range: List = field(default_factory=control_range_factory, metadata={
+ "topic": "chargemode_config/surplus/control_range"})
+ feed_in_limit: bool = field(default=False, metadata={
+ "topic": "chargemode_config/surplus/feed_in_limit"})
+ feed_in_yield: int = field(default=15000, metadata={
+ "topic": "chargemode_config/surplus/feed_in_yield"})
+ vehicle: ChargemodeConfigSurplusVehicle = field(
+ default_factory=lambda: ChargemodeConfigSurplusVehicle())
@dataclass
class ChargemodeConfig:
- pv_charging: PvCharging = field(default_factory=pv_charging_factory)
unbalanced_load_limit: int = field(
default=18, metadata={"topic": "chargemode_config/unbalanced_load_limit"})
unbalanced_load: bool = field(default=False, metadata={
"topic": "chargemode_config/unbalanced_load"})
+ surplus: ChargemodeConfigSurplus = field(default_factory=lambda: ChargemodeConfigSurplus())
+ bat: ChargemodeConfigBat = field(default_factory=lambda: ChargemodeConfigBat())
def chargemode_config_factory() -> ChargemodeConfig:
@@ -146,3 +155,10 @@ def grid_protection(self):
self.data.grid_protection_random_stop = 0
except Exception:
log.exception("Fehler im General-Modul")
+
+ def get_feed_in_yield(self) -> int:
+ """ Liefert den aktuellen Feed-In-Ertrag in Watt zurück. """
+ if self.data.chargemode_config.surplus.feed_in_limit:
+ return self.data.chargemode_config.surplus.feed_in_yield
+ else:
+ return 0
diff --git a/packages/control/loadmanagement.py b/packages/control/loadmanagement.py
index ce7ed4e8db..e3fae86d76 100644
--- a/packages/control/loadmanagement.py
+++ b/packages/control/loadmanagement.py
@@ -17,8 +17,7 @@ class Loadmanagement:
def get_available_currents(self,
missing_currents: List[float],
counter: Counter,
- cp: Chargepoint,
- feed_in: int = 0) -> Tuple[List[float], LoadmanagementLimit]:
+ cp: Chargepoint) -> Tuple[List[float], LoadmanagementLimit]:
raw_currents_left = counter.data.set.raw_currents_left
try:
available_currents, limit = self._limit_by_dimming_via_direct_control(missing_currents, cp)
@@ -39,7 +38,7 @@ def get_available_currents(self,
limit = new_limit if new_limit.limiting_value is not None else limit
available_currents, new_limit = self._limit_by_power(
- counter, available_currents, voltages_mean(cp.data.get.voltages), counter.data.set.raw_power_left, feed_in)
+ counter, available_currents, voltages_mean(cp.data.get.voltages), counter.data.set.raw_power_left)
limit = new_limit if new_limit.limiting_value is not None else limit
if f"counter{counter.num}" == data.data.counter_all_data.get_evu_counter_str():
@@ -53,8 +52,7 @@ def get_available_currents_surplus(self,
missing_currents: List[float],
cp_voltage: float,
counter: Counter,
- cp: Chargepoint,
- feed_in: int = 0) -> Tuple[List[float], LoadmanagementLimit]:
+ cp: Chargepoint) -> Tuple[List[float], LoadmanagementLimit]:
raw_currents_left = counter.data.set.raw_currents_left
available_currents, limit = self._limit_by_dimming_via_direct_control(missing_currents, cp)
@@ -65,7 +63,7 @@ def get_available_currents_surplus(self,
limit = new_limit if new_limit.limiting_value is not None else limit
available_currents, new_limit = self._limit_by_power(
- counter, available_currents, cp_voltage, counter.data.set.surplus_power_left, feed_in)
+ counter, available_currents, cp_voltage, counter.data.set.surplus_power_left)
limit = new_limit if new_limit.limiting_value is not None else limit
if f"counter{counter.num}" == data.data.counter_all_data.get_evu_counter_str():
@@ -99,8 +97,7 @@ def _limit_by_power(self,
counter: Counter,
available_currents: List[float],
cp_voltage: float,
- raw_power_left: Optional[float],
- feed_in: Optional[float]) -> Tuple[List[float], LoadmanagementLimit]:
+ raw_power_left: Optional[float]) -> Tuple[List[float], LoadmanagementLimit]:
# Mittelwert der Spannungen verwenden, um Phasenverdrehung zu kompensieren
# (Probleme bei einphasig angeschlossenen Wallboxen)
currents = available_currents.copy()
@@ -108,8 +105,9 @@ def _limit_by_power(self,
if raw_power_left is None:
return currents, limit
elif raw_power_left > 0:
- if feed_in is not None:
- raw_power_left = max(raw_power_left - feed_in, 0)
+ surplus_config = data.data.general_data.data.chargemode_config.surplus
+ if surplus_config.feed_in_limit:
+ raw_power_left = max(raw_power_left - surplus_config.feed_in_yield, 0)
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:
for i in range(0, 3):
diff --git a/packages/control/loadmanagement_test.py b/packages/control/loadmanagement_test.py
index 48de9d41e9..9c75fae169 100644
--- a/packages/control/loadmanagement_test.py
+++ b/packages/control/loadmanagement_test.py
@@ -33,7 +33,7 @@ def test_limit_by_power(available_currents: List[float],
counter_name_mock = Mock(return_value=COUNTER_NAME)
monkeypatch.setattr(loadmanagement, "get_component_name_by_id", counter_name_mock)
# evaluation
- ret = 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)
# assertion
assert ret == expected_ret
diff --git a/packages/helpermodules/create_debug.py b/packages/helpermodules/create_debug.py
index cb032927a5..d835225a62 100644
--- a/packages/helpermodules/create_debug.py
+++ b/packages/helpermodules/create_debug.py
@@ -35,8 +35,8 @@ def get_common_data():
ip_address = None
try:
updateAvailable = subdata.SubData.system_data["system"].data["current_branch_commit"] and \
- subdata.SubData.system_data["system"].data["current_branch_commit"] != \
- subdata.SubData.system_data["system"].data["current_commit"]
+ subdata.SubData.system_data["system"].data["current_branch_commit"] != \
+ subdata.SubData.system_data["system"].data["current_commit"]
except Exception:
updateAvailable = False
@@ -113,20 +113,20 @@ def config_and_state():
chargemode_config = data.data.general_data.data.chargemode_config
parsed_data += (
"\n## General Charge Config/ PV ##\n"
- f"Phase_Switch_Delay: {chargemode_config.pv_charging.phase_switch_delay} min\n"
- f"Retry_Failed_Phase_Switches: {chargemode_config.pv_charging.retry_failed_phase_switches}\n"
- f"Control_Range: {chargemode_config.pv_charging.control_range}W\n"
- f"Switch_On_Threshold: {chargemode_config.pv_charging.switch_on_threshold}W\n"
- f"Switch_On_Delay: {chargemode_config.pv_charging.switch_on_delay}s\n"
- f"Switch_Off_Threshold: {chargemode_config.pv_charging.switch_off_threshold}W\n"
- f"Switch_Off_Delay: {chargemode_config.pv_charging.switch_off_delay}s\n"
- f"Feed_In_Yield: {chargemode_config.pv_charging.feed_in_yield}W\n"
- f"Bat_Mode: {chargemode_config.pv_charging.bat_mode}\n"
- f"Min_Bat_SoC: {chargemode_config.pv_charging.min_bat_soc}%\n"
- f"Bat_Power_Reserve_Active: {chargemode_config.pv_charging.bat_power_reserve_active}\n"
- f"Bat_Power_Reserve: {chargemode_config.pv_charging.bat_power_reserve}W\n"
- f"Bat_Power_Discharge_Active: {chargemode_config.pv_charging.bat_power_discharge_active}\n"
- f"Bat_Power_Discharge: {chargemode_config.pv_charging.bat_power_discharge}W\n")
+ f"Phase_Switch_Delay: {chargemode_config.surplus.vehicle.phase_switch_delay} min\n"
+ f"Retry_Failed_Phase_Switches: {chargemode_config.surplus.vehicle.retry_failed_phase_switches}\n"
+ f"Control_Range: {chargemode_config.surplus.control_range}W\n"
+ f"Switch_On_Threshold: {chargemode_config.surplus.vehicle.switch_on_threshold}W\n"
+ f"Switch_On_Delay: {chargemode_config.surplus.vehicle.switch_on_delay}s\n"
+ f"Switch_Off_Threshold: {chargemode_config.surplus.vehicle.switch_off_threshold}W\n"
+ f"Switch_Off_Delay: {chargemode_config.surplus.vehicle.switch_off_delay}s\n"
+ f"Feed_In_Yield: {chargemode_config.surplus.feed_in_yield}W\n"
+ f"Bat_Mode: {chargemode_config.bat.mode}\n"
+ f"Min_Bat_SoC: {chargemode_config.bat.min_soc}%\n"
+ f"Bat_Power_Reserve_Active: {chargemode_config.bat.power_reserve_active}\n"
+ f"Bat_Power_Reserve: {chargemode_config.bat.power_reserve}W\n"
+ f"Bat_Power_Discharge_Active: {chargemode_config.bat.power_discharge_active}\n"
+ f"Bat_Power_Discharge: {chargemode_config.bat.power_discharge}W\n")
if secondary is False:
with ErrorHandlingContext():
parsed_data += f"\n## Hierarchy ##\n{get_hierarchy(data.data.counter_all_data.data.get.hierarchy)}\n"
@@ -461,9 +461,9 @@ def write_to_file(file_handler, func, default: Optional[Any] = None):
json_rsp = req.get_http_session().put("https://debughandler.wb-solution.de",
data=data,
params={
- 'debugemail': debug_email,
- 'ticketnumber': ticketnumber,
- 'subject': subject
+ 'debugemail': debug_email,
+ 'ticketnumber': ticketnumber,
+ 'subject': subject
},
timeout=10).json()
diff --git a/packages/helpermodules/setdata.py b/packages/helpermodules/setdata.py
index 7c03072896..a6314f615c 100644
--- a/packages/helpermodules/setdata.py
+++ b/packages/helpermodules/setdata.py
@@ -763,28 +763,29 @@ def process_general_topic(self, msg: mqtt.MQTTMessage):
elif "openWB/set/general/chargemode_config/unbalanced_load_limit" in msg.topic:
self._validate_value(msg, int, [(10, 32)])
elif ("openWB/set/general/chargemode_config/unbalanced_load" in msg.topic or
- "openWB/set/general/chargemode_config/pv_charging/retry_failed_phase_switches" in msg.topic or
- "openWB/set/general/chargemode_config/pv_charging/bat_power_discharge_active" in msg.topic or
- "openWB/set/general/chargemode_config/pv_charging/bat_power_reserve_active" in msg.topic):
+ "openWB/set/general/chargemode_config/surplus/feed_in_limit" in msg.topic or
+ "openWB/set/general/chargemode_config/surplus/vehicle/retry_failed_phase_switches" in msg.topic or
+ "openWB/set/general/chargemode_config/bat/power_discharge_active" in msg.topic or
+ "openWB/set/general/chargemode_config/bat/power_reserve_active" in msg.topic):
self._validate_value(msg, bool)
- elif ("openWB/set/general/chargemode_config/pv_charging/feed_in_yield" in msg.topic or
- "openWB/set/general/chargemode_config/pv_charging/switch_on_threshold" in msg.topic or
- "openWB/set/general/chargemode_config/pv_charging/switch_on_delay" in msg.topic or
- "openWB/set/general/chargemode_config/pv_charging/switch_off_delay" in msg.topic):
+ elif ("openWB/set/general/chargemode_config/surplus/feed_in_yield" in msg.topic or
+ "openWB/set/general/chargemode_config/surplus/vehicle/switch_on_threshold" in msg.topic or
+ "openWB/set/general/chargemode_config/surplus/vehicle/switch_on_delay" in msg.topic or
+ "openWB/set/general/chargemode_config/surplus/vehicle/switch_off_delay" in msg.topic):
self._validate_value(msg, int, [(0, float("inf"))])
- elif "openWB/set/general/chargemode_config/pv_charging/switch_off_threshold" in msg.topic:
+ elif "openWB/set/general/chargemode_config/surplus/vehicle/switch_off_threshold" in msg.topic:
self._validate_value(msg, float)
- elif "openWB/set/general/chargemode_config/pv_charging/phase_switch_delay" in msg.topic:
+ elif "openWB/set/general/chargemode_config/surplus/vehicle/phase_switch_delay" in msg.topic:
self._validate_value(msg, int, [(5, 180)])
- elif "openWB/set/general/chargemode_config/pv_charging/control_range" in msg.topic:
+ elif "openWB/set/general/chargemode_config/surplus/control_range" in msg.topic:
self._validate_value(msg, int, collection=list)
- elif ("openWB/set/general/chargemode_config/pv_charging/min_bat_soc" in msg.topic or
- "openWB/set/general/chargemode_config/pv_charging/max_bat_soc" in msg.topic):
+ elif ("openWB/set/general/chargemode_config/bat/min_soc" in msg.topic or
+ "openWB/set/general/chargemode_config/bat/max_soc" in msg.topic):
self._validate_value(msg, int, [(0, 100)])
- elif ("openWB/set/general/chargemode_config/pv_charging/bat_power_discharge" in msg.topic or
- "openWB/set/general/chargemode_config/pv_charging/bat_power_reserve" in msg.topic):
+ elif ("openWB/set/general/chargemode_config/bat/power_discharge" in msg.topic or
+ "openWB/set/general/chargemode_config/bat/power_reserve" in msg.topic):
self._validate_value(msg, float, [(0, float("inf"))])
- elif "openWB/set/general/chargemode_config/pv_charging/bat_mode" in msg.topic:
+ elif "openWB/set/general/chargemode_config/bat/mode" in msg.topic:
self._validate_value(msg, str)
elif "openWB/set/general/chargemode_config/" in msg.topic and "/phases_to_use" in msg.topic:
self._validate_value(msg, int, [(1, 1), (3, 3)])
diff --git a/packages/helpermodules/update_config.py b/packages/helpermodules/update_config.py
index 48d2f72b1e..788b453235 100644
--- a/packages/helpermodules/update_config.py
+++ b/packages/helpermodules/update_config.py
@@ -41,7 +41,7 @@
from control.ev.charge_template import EcoCharging, get_charge_template_default
from control.ev import ev
from control.ev.ev_template import EvTemplateData
-from control.general import Prices, PvCharging
+from control.general import ChargemodeConfigSurplusVehicle, Prices
from control.optional_data import OcppConfig
from modules.common.abstract_vehicle import GeneralVehicleConfig
from modules.common.component_type import ComponentType
@@ -58,7 +58,7 @@
class UpdateConfig:
- DATASTORE_VERSION = 137
+ DATASTORE_VERSION = 138
valid_topic = [
"^openWB/bat/config/bat_control_activated$",
@@ -229,21 +229,22 @@ class UpdateConfig:
"^openWB/general/temporary_charge_templates_active$",
"^openWB/general/chargemode_config/unbalanced_load_limit$",
"^openWB/general/chargemode_config/unbalanced_load$",
- "^openWB/general/chargemode_config/pv_charging/bat_mode$",
- "^openWB/general/chargemode_config/pv_charging/feed_in_yield$",
- "^openWB/general/chargemode_config/pv_charging/switch_on_threshold$",
- "^openWB/general/chargemode_config/pv_charging/switch_on_delay$",
- "^openWB/general/chargemode_config/pv_charging/switch_off_threshold$",
- "^openWB/general/chargemode_config/pv_charging/switch_off_delay$",
- "^openWB/general/chargemode_config/pv_charging/phase_switch_delay$",
- "^openWB/general/chargemode_config/pv_charging/control_range$",
- "^openWB/general/chargemode_config/pv_charging/min_bat_soc$",
- "^openWB/general/chargemode_config/pv_charging/max_bat_soc$",
- "^openWB/general/chargemode_config/pv_charging/bat_power_discharge$",
- "^openWB/general/chargemode_config/pv_charging/bat_power_discharge_active$",
- "^openWB/general/chargemode_config/pv_charging/bat_power_reserve$",
- "^openWB/general/chargemode_config/pv_charging/bat_power_reserve_active$",
- "^openWB/general/chargemode_config/pv_charging/retry_failed_phase_switches$",
+ "^openWB/general/chargemode_config/surplus/feed_in_limit$",
+ "^openWB/general/chargemode_config/bat/mode$",
+ "^openWB/general/chargemode_config/surplus/feed_in_yield$",
+ "^openWB/general/chargemode_config/surplus/vehicle/switch_on_threshold$",
+ "^openWB/general/chargemode_config/surplus/vehicle/switch_on_delay$",
+ "^openWB/general/chargemode_config/surplus/vehicle/switch_off_threshold$",
+ "^openWB/general/chargemode_config/surplus/vehicle/switch_off_delay$",
+ "^openWB/general/chargemode_config/surplus/vehicle/phase_switch_delay$",
+ "^openWB/general/chargemode_config/surplus/control_range$",
+ "^openWB/general/chargemode_config/bat/min_soc$",
+ "^openWB/general/chargemode_config/bat/max_soc$",
+ "^openWB/general/chargemode_config/bat/power_discharge$",
+ "^openWB/general/chargemode_config/bat/power_discharge_active$",
+ "^openWB/general/chargemode_config/bat/power_reserve$",
+ "^openWB/general/chargemode_config/bat/power_reserve_active$",
+ "^openWB/general/chargemode_config/surplus/vehicle/retry_failed_phase_switches$",
# obsolet, Daten hieraus müssen nach prices/ überführt werden
"^openWB/general/price_kwh$",
"^openWB/general/prices/bat$",
@@ -603,22 +604,23 @@ class UpdateConfig:
("openWB/vehicle/template/charge_template/0", get_charge_template_default()),
("openWB/general/allow_unencrypted_access", True),
("openWB/general/charge_log_data_config", get_default_charge_log_columns()),
- ("openWB/general/chargemode_config/pv_charging/bat_mode", BatConsiderationMode.EV_MODE.value),
- ("openWB/general/chargemode_config/pv_charging/bat_power_discharge", 1000),
- ("openWB/general/chargemode_config/pv_charging/bat_power_discharge_active", True),
- ("openWB/general/chargemode_config/pv_charging/min_bat_soc", 50),
- ("openWB/general/chargemode_config/pv_charging/max_bat_soc", 70),
- ("openWB/general/chargemode_config/pv_charging/bat_power_reserve", 200),
- ("openWB/general/chargemode_config/pv_charging/bat_power_reserve_active", True),
- ("openWB/general/chargemode_config/pv_charging/control_range", [0, 230]),
- ("openWB/general/chargemode_config/pv_charging/switch_off_threshold", 0),
- ("openWB/general/chargemode_config/pv_charging/switch_off_delay", 60),
- ("openWB/general/chargemode_config/pv_charging/switch_on_delay", 30),
- ("openWB/general/chargemode_config/pv_charging/switch_on_threshold", 1500),
- ("openWB/general/chargemode_config/pv_charging/feed_in_yield", 0),
- ("openWB/general/chargemode_config/pv_charging/phase_switch_delay", 7),
- ("openWB/general/chargemode_config/pv_charging/retry_failed_phase_switches",
- PvCharging().retry_failed_phase_switches),
+ ("openWB/general/chargemode_config/bat/mode", BatConsiderationMode.EV_MODE.value),
+ ("openWB/general/chargemode_config/bat/power_discharge", 1000),
+ ("openWB/general/chargemode_config/bat/power_discharge_active", True),
+ ("openWB/general/chargemode_config/bat/min_soc", 50),
+ ("openWB/general/chargemode_config/bat/max_soc", 70),
+ ("openWB/general/chargemode_config/bat/power_reserve", 200),
+ ("openWB/general/chargemode_config/bat/power_reserve_active", True),
+ ("openWB/general/chargemode_config/surplus/control_range", [0, 230]),
+ ("openWB/general/chargemode_config/surplus/feed_in_limit", False),
+ ("openWB/general/chargemode_config/surplus/vehicle/switch_off_threshold", 0),
+ ("openWB/general/chargemode_config/surplus/vehicle/switch_off_delay", 60),
+ ("openWB/general/chargemode_config/surplus/vehicle/switch_on_delay", 30),
+ ("openWB/general/chargemode_config/surplus/vehicle/switch_on_threshold", 1500),
+ ("openWB/general/chargemode_config/surplus/feed_in_yield", 0),
+ ("openWB/general/chargemode_config/surplus/vehicle/phase_switch_delay", 7),
+ ("openWB/general/chargemode_config/surplus/vehicle/retry_failed_phase_switches",
+ ChargemodeConfigSurplusVehicle().retry_failed_phase_switches),
("openWB/general/chargemode_config/unbalanced_load", False),
("openWB/general/chargemode_config/unbalanced_load_limit", 18),
("openWB/general/control_interval", 10),
@@ -3481,3 +3483,44 @@ def upgrade(topic: str, payload) -> Optional[dict]:
return {topic: payload}
self._loop_all_received_topics(upgrade)
self._append_datastore_version(137)
+
+ def upgrade_datastore_138(self) -> None:
+ feed_in_limit = False
+ for topic, payload in self.all_received_topics.items():
+ if re.search("^openWB/vehicle/[0-9]+/template/charge_template$", topic) is not None:
+ config = decode_payload(payload)
+ if config.get("chargemode", {}).get("pv_charging", {}).get("feed_in_limit") is True:
+ feed_in_limit = True
+ config["chargemode"]["pv_charging"].pop("feed_in_limit")
+ self.__update_topic("openWB/vehicle/template/charge_template", config)
+ self.__update_topic("openWB/general/chargemode_config/surplus/feed_in_limit", feed_in_limit)
+
+ def move_topic(new_topic: str, old_topic: str) -> None:
+ if old_topic in self.all_received_topics:
+ payload = decode_payload(self.all_received_topics[old_topic])
+ self.__update_topic(new_topic, payload)
+ self.all_received_topics.pop(old_topic)
+ log.debug(f"Moved topic '{old_topic}' to '{new_topic}' with value: {payload}")
+
+ chargemode_config_prefix = "openWB/general/chargemode_config"
+ old_prefix = "openWB/general/chargemode_config/pv_charging"
+ move_topic(f"{chargemode_config_prefix}/bat/mode", f"{old_prefix}/bat_mode")
+ move_topic(f"{chargemode_config_prefix}/surplus/feed_in_yield", f"{old_prefix}/feed_in_yield")
+ move_topic(f"{chargemode_config_prefix}/surplus/vehicle/switch_on_threshold",
+ f"{old_prefix}/switch_on_threshold")
+ move_topic(f"{chargemode_config_prefix}/surplus/vehicle/switch_on_delay", f"{old_prefix}/switch_on_delay")
+ move_topic(f"{chargemode_config_prefix}/surplus/vehicle/switch_off_threshold",
+ f"{old_prefix}/switch_off_threshold")
+ move_topic(f"{chargemode_config_prefix}/surplus/vehicle/switch_off_delay", f"{old_prefix}/switch_off_delay")
+ move_topic(f"{chargemode_config_prefix}/surplus/vehicle/phase_switch_delay", f"{old_prefix}/phase_switch_delay")
+ move_topic(f"{chargemode_config_prefix}/surplus/control_range", f"{old_prefix}/control_range")
+ move_topic(f"{chargemode_config_prefix}/bat/min_soc", f"{old_prefix}/min_bat_soc")
+ move_topic(f"{chargemode_config_prefix}/bat/max_soc", f"{old_prefix}/max_bat_soc")
+ move_topic(f"{chargemode_config_prefix}/bat/power_discharge", f"{old_prefix}/bat_power_discharge")
+ move_topic(f"{chargemode_config_prefix}/bat/power_discharge_active", f"{old_prefix}/bat_power_discharge_active")
+ move_topic(f"{chargemode_config_prefix}/bat/power_reserve", f"{old_prefix}/bat_power_reserve")
+ move_topic(f"{chargemode_config_prefix}/bat/power_reserve_active", f"{old_prefix}/bat_power_reserve_active")
+ move_topic(f"{chargemode_config_prefix}/surplus/vehicle/retry_failed_phase_switches",
+ f"{old_prefix}/retry_failed_phase_switches")
+
+ self._append_datastore_version(138)
diff --git a/packages/modules/display_themes/cards/source/src/App.vue b/packages/modules/display_themes/cards/source/src/App.vue
index 6058e5320e..4c315126f4 100644
--- a/packages/modules/display_themes/cards/source/src/App.vue
+++ b/packages/modules/display_themes/cards/source/src/App.vue
@@ -63,7 +63,7 @@ export default {
"openWB/counter/+/get/power",
"openWB/counter/get/hierarchy",
"openWB/counter/set/home_consumption",
- "openWB/general/chargemode_config/pv_charging/bat_mode",
+ "openWB/general/chargemode_config/bat/mode",
"openWB/optional/ep/configured",
"openWB/optional/ep/get/prices",
"openWB/optional/int_display/only_local_charge_points",
diff --git a/packages/modules/display_themes/cards/source/src/components/Battery/BatteryModeModal.vue b/packages/modules/display_themes/cards/source/src/components/Battery/BatteryModeModal.vue
index ac813fe499..5c99374478 100644
--- a/packages/modules/display_themes/cards/source/src/components/Battery/BatteryModeModal.vue
+++ b/packages/modules/display_themes/cards/source/src/components/Battery/BatteryModeModal.vue
@@ -99,8 +99,8 @@ export default {
methods: {
setBatteryMode(mode) {
if(mode !== this.mqttStore.getBatteryMode) {
- this.mqttStore.updateState("openWB/general/chargemode_config/pv_charging/bat_mode", mode);
- this.$root.sendTopicToBroker("openWB/general/chargemode_config/pv_charging/bat_mode", mode);
+ this.mqttStore.updateState("openWB/general/chargemode_config/bat/mode", mode);
+ this.$root.sendTopicToBroker("openWB/general/chargemode_config/bat/mode", mode);
}
},
},
diff --git a/packages/modules/display_themes/cards/source/src/stores/mqtt.js b/packages/modules/display_themes/cards/source/src/stores/mqtt.js
index aa4c0218ba..8bbc97166c 100644
--- a/packages/modules/display_themes/cards/source/src/stores/mqtt.js
+++ b/packages/modules/display_themes/cards/source/src/stores/mqtt.js
@@ -397,7 +397,7 @@ export const useMqttStore = defineStore("mqtt", {
return state.getChartData("openWB/bat/get/soc");
},
getBatteryMode(state) {
- return state.topics["openWB/general/chargemode_config/pv_charging/bat_mode"];
+ return state.topics["openWB/general/chargemode_config/bat/mode"];
},
getPvConfigured(state) {
return state.getValueBool("openWB/pv/config/configured");
@@ -776,16 +776,6 @@ export const useMqttStore = defineStore("mqtt", {
return undefined;
};
},
- getChargePointConnectedVehiclePvChargingFeedInLimit(state) {
- return (chargePointId) => {
- if (state.getChargePointConnectedVehicleChargeTemplate(chargePointId)) {
- return state.getChargePointConnectedVehicleChargeTemplate(
- chargePointId,
- ).chargemode.pv_charging.feed_in_limit;
- }
- return undefined;
- };
- },
getChargePointConnectedVehiclePvChargingMinCurrent(state) {
return (chargePointId) => {
if (state.getChargePointConnectedVehicleChargeTemplate(chargePointId)) {
diff --git a/packages/modules/display_themes/cards/source/src/views/ChargePointsView.vue b/packages/modules/display_themes/cards/source/src/views/ChargePointsView.vue
index dffaf783bd..2ba286e972 100644
--- a/packages/modules/display_themes/cards/source/src/views/ChargePointsView.vue
+++ b/packages/modules/display_themes/cards/source/src/views/ChargePointsView.vue
@@ -217,14 +217,6 @@ export default {
this.updateChargePointChargeTemplate(id, event, "chargemode.instant_charging.limit.amount");
}
},
- setChargePointConnectedVehiclePvChargingFeedInLimit(id, event) {
- if (
- event !=
- this.mqttStore.getChargePointConnectedVehiclePvChargingFeedInLimit(id)
- ) {
- this.updateChargePointChargeTemplate(id, event, "chargemode.pv_charging.feed_in_limit");
- }
- },
setChargePointConnectedVehiclePvChargingMinCurrent(id, event) {
let previous_value =
this.mqttStore.getChargePointConnectedVehiclePvChargingMinCurrent(id);
@@ -1026,45 +1018,6 @@ export default {
-