Skip to content
4 changes: 2 additions & 2 deletions data/config/mosquitto/openwb_local.conf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# openwb-version:19
# openwb-version:20
listener 1886 localhost
allow_anonymous true

Expand Down Expand Up @@ -52,7 +52,7 @@ topic openWB/optional/# out 2

topic openWB/counter/config/# out 2
topic openWB/counter/set/# out 2
topic openWB/counter/get/hierarchy out 2
topic openWB/counter/get/# out 2
topic openWB/counter/+/module/# out 2
topic openWB/counter/+/config/# out 2
topic openWB/counter/+/get/# out 2
Expand Down
16 changes: 10 additions & 6 deletions packages/control/algorithm/additional_current.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import logging
from typing import List

from control.algorithm import common
from control.algorithm.chargemodes import CONSIDERED_CHARGE_MODES_ADDITIONAL_CURRENT
from control.limiting_value import LoadmanagementLimit
from control.loadmanagement import Loadmanagement
from control.chargepoint.chargepoint import Chargepoint
from control.algorithm.filter_chargepoints import (get_chargepoints_by_mode_and_counter,
from control.algorithm.filter_chargepoints import (get_chargepoints_by_mode_and_counter_and_lm_prio,
get_preferenced_chargepoint_charging)

log = logging.getLogger(__name__)
Expand All @@ -16,14 +17,17 @@ class AdditionalCurrent:
def __init__(self) -> None:
pass

def set_additional_current(self) -> None:
common.reset_current_by_chargemode(CONSIDERED_CHARGE_MODES_ADDITIONAL_CURRENT)
for mode_tuple, counter in common.mode_and_counter_generator(CONSIDERED_CHARGE_MODES_ADDITIONAL_CURRENT):
def set_additional_current(self, cp_prio_group: List[Chargepoint]) -> None:
log.info("**Soll-Strom setzen**")
common.reset_current_to_target_current(cp_prio_group)
common.reset_current_by_chargemode(CONSIDERED_CHARGE_MODES_ADDITIONAL_CURRENT, cp_prio_group)
for counter in common.counter_generator():
preferenced_chargepoints, preferenced_cps_without_set_current = get_preferenced_chargepoint_charging(
get_chargepoints_by_mode_and_counter(mode_tuple, f"counter{counter.num}"))
get_chargepoints_by_mode_and_counter_and_lm_prio(CONSIDERED_CHARGE_MODES_ADDITIONAL_CURRENT,
f"counter{counter.num}", cp_prio_group))
if preferenced_chargepoints:
common.update_raw_data(preferenced_chargepoints)
log.info(f"Mode-Tuple {mode_tuple[0]} - {mode_tuple[1]} - {mode_tuple[2]}, Zähler {counter.num}")
log.info(f"Zähler {counter.num}, Verbraucher {[f'LP{cp.num}' for cp in preferenced_chargepoints]}")
while len(preferenced_chargepoints):
cp = preferenced_chargepoints[0]
missing_currents, counts = common.get_missing_currents_left(preferenced_chargepoints)
Expand Down
55 changes: 26 additions & 29 deletions packages/control/algorithm/algorithm.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import logging
from typing import List

from control import counter
from control import data
from control.algorithm import common
from control.algorithm.additional_current import AdditionalCurrent
from control.algorithm.bidi_charging import Bidi
from control.algorithm.min_current import MinCurrent
from control.algorithm.no_current import NoCurrent
from control.algorithm.surplus_controlled import SurplusControlled
from control.chargepoint.chargepoint import Chargepoint

log = logging.getLogger(__name__)

Expand All @@ -23,39 +24,35 @@ def __init__(self):
def calc_current(self) -> None:
""" Einstiegspunkt in den Regel-Algorithmus
"""
try:
log.info("# Algorithmus")
self.evu_counter = data.data.counter_all_data.get_evu_counter()
self._check_auto_phase_switch_delay()
self.surplus_controlled.check_submode_pv_charging()
common.reset_current()
log.info("**Mindestrom setzen**")
self.min_current.set_min_current()
log.info("**Soll-Strom setzen**")
common.reset_current_to_target_current()
self.additional_current.set_additional_current()
self.surplus_controlled.set_required_current_to_max()
log.info("**PV-geführten Strom setzen**")
counter.limit_raw_power_left_to_surplus(self.evu_counter.calc_raw_surplus())
if self.evu_counter.data.set.surplus_power_left > 0:
common.reset_current_to_target_current()
self.surplus_controlled.set_surplus_current()
else:
log.info("Keine Leistung für PV-geführtes Laden übrig.")
log.info("**Bidi-(Ent-)Lade-Strom setzen**")
counter.set_raw_surplus_power_left()
self.bidi.set_bidi()
self.no_current.set_no_current()
self.no_current.set_none_current()
except Exception:
log.exception("Fehler im Algorithmus-Modul")
log.info("# Algorithmus")
common.reset_current()
for next_low_power_group, next_full_power_group in data.data.counter_all_data.prio_groups_generator():
try:
if next_low_power_group is not None:
self._check_auto_phase_switch_delay(next_low_power_group)
self.surplus_controlled.check_submode_pv_charging(next_low_power_group)
self.min_current.set_min_current(next_low_power_group)
if next_full_power_group is not None:
self._check_auto_phase_switch_delay(next_full_power_group)
self.surplus_controlled.check_submode_pv_charging(next_full_power_group)
self.min_current.set_min_current(next_full_power_group)
self.additional_current.set_additional_current(next_full_power_group)
self.surplus_controlled.set_surplus_current(next_full_power_group)
if next_low_power_group is not None:
self.additional_current.set_additional_current(next_low_power_group)
self.surplus_controlled.set_surplus_current(next_low_power_group)
except Exception:
log.exception("Fehler im Algorithmus-Modul")
self.bidi.set_bidi()
self.no_current.set_no_current()
self.no_current.set_none_current()

def _check_auto_phase_switch_delay(self) -> None:
def _check_auto_phase_switch_delay(self, cps: List[Chargepoint]) -> None:
""" geht alle LP durch und prüft, ob eine Ladung aktiv ist, ob automatische Phasenumschaltung
möglich ist und ob ob ein Timer gestartet oder gestoppt werden muss oder ob
ein Timer abgelaufen ist.
"""
for cp in data.data.cp_data.values():
for cp in cps:
try:
if cp.data.control_parameter.required_current != 0:
charging_ev = cp.data.set.charging_ev_data
Expand Down
59 changes: 31 additions & 28 deletions packages/control/algorithm/bidi_charging.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from control import data
from control.algorithm.chargemodes import CONSIDERED_CHARGE_MODES_BIDI_DISCHARGE
from control.algorithm.filter_chargepoints import get_chargepoints_by_mode
from control.counter import set_raw_surplus_power_left
from helpermodules.phase_handling import voltages_mean

log = logging.getLogger(__name__)
Expand All @@ -12,35 +13,37 @@ def __init__(self):
pass

def set_bidi(self):
log.info("**Bidi-(Ent-)Lade-Strom setzen**")
set_raw_surplus_power_left()
grid_counter = data.data.counter_all_data.get_evu_counter()
log.debug(f"Nullpunktanpassung {grid_counter.data.set.surplus_power_left}W")
zero_point_adjustment = grid_counter
for mode_tuple in CONSIDERED_CHARGE_MODES_BIDI_DISCHARGE:
preferenced_cps = get_chargepoints_by_mode(mode_tuple)
if preferenced_cps:
log.info(
f"Mode-Tuple {mode_tuple[0]} - {mode_tuple[1]} - {mode_tuple[2]}, Zähler {grid_counter.num}")
while len(preferenced_cps):
cp = preferenced_cps[0]
zero_point_adjustment = grid_counter.data.set.surplus_power_left / len(preferenced_cps)
log.debug(f"Nullpunktanpassung für LP{cp.num}: verbleibende Leistung {zero_point_adjustment}W")
missing_currents = [zero_point_adjustment / cp.data.get.phases_in_use /
230 for i in range(0, cp.data.get.phases_in_use)]
missing_currents += [0] * (3 - len(missing_currents))
if zero_point_adjustment > 0:
if cp.data.set.charging_ev_data.charge_template.bidi_charging_allowed(
cp.data.control_parameter.current_plan, cp.data.set.charging_ev_data.data.get.soc):
for index in range(0, 3):
missing_currents[index] = min(cp.data.control_parameter.required_current,
missing_currents[index])
else:
log.info(f"LP{cp.num}: Nur bidirektional entladen erlaubt, da SoC-Limit erreicht.")
missing_currents = [0, 0, 0]
else:
preferenced_cps = get_chargepoints_by_mode(CONSIDERED_CHARGE_MODES_BIDI_DISCHARGE)
if preferenced_cps:
log.info(f"Verbraucher {preferenced_cps}")
while len(preferenced_cps):
cp = preferenced_cps[0]
zero_point_adjustment = grid_counter.data.set.surplus_power_left / len(preferenced_cps)
log.debug(f"Nullpunktanpassung für LP{cp.num}: verbleibende Leistung {zero_point_adjustment}W")
missing_currents = [zero_point_adjustment / cp.data.get.phases_in_use /
230 for i in range(0, cp.data.get.phases_in_use)]
missing_currents += [0] * (3 - len(missing_currents))
if zero_point_adjustment > 0:
if cp.data.set.charging_ev_data.charge_template.bidi_charging_allowed(
cp.data.control_parameter.current_plan, cp.data.set.charging_ev_data.data.get.soc):
for index in range(0, 3):
missing_currents[index] = cp.check_min_max_current(missing_currents[index],
cp.data.get.phases_in_use)
grid_counter.update_surplus_values_left(missing_currents, voltages_mean(cp.data.get.voltages))
cp.data.set.current = missing_currents[0]
log.info(f"LP{cp.num}: Stromstärke {missing_currents}A")
preferenced_cps.pop(0)
missing_currents[index] = min(cp.data.control_parameter.required_current,
missing_currents[index])
else:
log.info(f"LP{cp.num}: Nur bidirektional entladen erlaubt, da SoC-Limit erreicht.")
missing_currents = [0, 0, 0]
else:
for index in range(0, 3):
missing_currents[index] = cp.check_min_max_current(missing_currents[index],
cp.data.get.phases_in_use)
grid_counter.update_surplus_values_left(missing_currents, voltages_mean(cp.data.get.voltages))
grid_counter.update_values_left(missing_currents, voltages_mean(cp.data.get.voltages))
grid_counter.update_currents_left(missing_currents)
cp.data.set.current = missing_currents[0]
log.info(f"LP{cp.num}: Stromstärke {missing_currents}A")
preferenced_cps.pop(0)
44 changes: 17 additions & 27 deletions packages/control/algorithm/chargemodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,22 @@

# Lademodi in absteigender Priorität
# Tupel-Inhalt:(eingestellter Modus, tatsächlich genutzter Modus, Priorität)
CHARGEMODES = ((Chargemode.SCHEDULED_CHARGING, Chargemode.INSTANT_CHARGING, True),
(Chargemode.SCHEDULED_CHARGING, Chargemode.INSTANT_CHARGING, False),
(None, Chargemode.TIME_CHARGING, True),
(None, Chargemode.TIME_CHARGING, False),
(Chargemode.INSTANT_CHARGING, Chargemode.INSTANT_CHARGING, True),
(Chargemode.INSTANT_CHARGING, Chargemode.INSTANT_CHARGING, False),
(Chargemode.ECO_CHARGING, Chargemode.INSTANT_CHARGING, True),
(Chargemode.ECO_CHARGING, Chargemode.INSTANT_CHARGING, False),
(Chargemode.PV_CHARGING, Chargemode.INSTANT_CHARGING, True),
(Chargemode.PV_CHARGING, Chargemode.INSTANT_CHARGING, False),
(Chargemode.SCHEDULED_CHARGING, Chargemode.PV_CHARGING, True),
(Chargemode.SCHEDULED_CHARGING, Chargemode.PV_CHARGING, False),
(Chargemode.ECO_CHARGING, Chargemode.PV_CHARGING, True),
(Chargemode.ECO_CHARGING, Chargemode.PV_CHARGING, False),
(Chargemode.PV_CHARGING, Chargemode.PV_CHARGING, True),
(Chargemode.PV_CHARGING, Chargemode.PV_CHARGING, False),
CHARGEMODES = ((Chargemode.SCHEDULED_CHARGING, Chargemode.INSTANT_CHARGING),
(None, Chargemode.TIME_CHARGING),
(Chargemode.INSTANT_CHARGING, Chargemode.INSTANT_CHARGING),
(Chargemode.ECO_CHARGING, Chargemode.INSTANT_CHARGING),
(Chargemode.PV_CHARGING, Chargemode.INSTANT_CHARGING),
(Chargemode.SCHEDULED_CHARGING, Chargemode.PV_CHARGING),
(Chargemode.ECO_CHARGING, Chargemode.PV_CHARGING),
(Chargemode.PV_CHARGING, Chargemode.PV_CHARGING),
# niedrigere Priorität soll nachrangig geladen, aber zuerst entladen werden
(Chargemode.SCHEDULED_CHARGING, Chargemode.BIDI_CHARGING, False),
(Chargemode.SCHEDULED_CHARGING, Chargemode.BIDI_CHARGING, True),
(None, Chargemode.STOP, True),
(None, Chargemode.STOP, False))
(Chargemode.SCHEDULED_CHARGING, Chargemode.BIDI_CHARGING),
(None, Chargemode.STOP),)

CONSIDERED_CHARGE_MODES_SURPLUS = CHARGEMODES[0:2] + CHARGEMODES[6:16]
CONSIDERED_CHARGE_MODES_PV_ONLY = CHARGEMODES[10:16]
CONSIDERED_CHARGE_MODES_ADDITIONAL_CURRENT = CHARGEMODES[0:10]
CONSIDERED_CHARGE_MODES_MIN_CURRENT = CHARGEMODES[0:-4]
CONSIDERED_CHARGE_MODES_NO_CURRENT = CHARGEMODES[18:20]
CONSIDERED_CHARGE_MODES_BIDI_DISCHARGE = CHARGEMODES[16:18]
CONSIDERED_CHARGE_MODES_CHARGING = CHARGEMODES[0:16]
CONSIDERED_CHARGE_MODES_SURPLUS = (CHARGEMODES[0], *CHARGEMODES[3:8])
CONSIDERED_CHARGE_MODES_PV_ONLY = CHARGEMODES[5:8]
CONSIDERED_CHARGE_MODES_ADDITIONAL_CURRENT = CHARGEMODES[0:5]
CONSIDERED_CHARGE_MODES_MIN_CURRENT = CHARGEMODES[0:-2]
CONSIDERED_CHARGE_MODES_NO_CURRENT = (CHARGEMODES[9],)
CONSIDERED_CHARGE_MODES_BIDI_DISCHARGE = (CHARGEMODES[8],)
CONSIDERED_CHARGE_MODES_CHARGING = CHARGEMODES[0:8]
Loading