Skip to content
Closed
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
3 changes: 2 additions & 1 deletion packages/control/algorithm/additional_current_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
from control.chargepoint.chargepoint import Chargepoint, ChargepointData
from control.chargepoint.chargepoint_data import Set
from control.chargepoint.control_parameter import ControlParameter
from control.ev import ChargeTemplate, Ev
from control.ev.charge_template import ChargeTemplate
from control.ev.ev import Ev
from control.loadmanagement import LimitingValue


Expand Down
2 changes: 1 addition & 1 deletion packages/control/algorithm/common_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from control import data
from control.algorithm import common
from control.chargepoint.chargepoint import Chargepoint
from control.ev import Ev
from control.ev.ev import Ev
from control.counter import Counter
from control.counter_all import CounterAll

Expand Down
3 changes: 2 additions & 1 deletion packages/control/algorithm/filter_chargepoints_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
from control.chargemode import Chargemode
from control.chargepoint.chargepoint import Chargepoint, ChargepointData
from control.chargepoint.chargepoint_data import Log, Set
from control.chargepoint.control_parameter import ControlParameter
from control.counter_all import CounterAll
from control.ev import ControlParameter, Ev, EvData, Get
from control.ev.ev import Ev, EvData, Get


@dataclass
Expand Down
2 changes: 1 addition & 1 deletion packages/control/algorithm/integration_test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from control.chargepoint.chargepoint import Chargepoint
from control.counter_all import CounterAll
from control.counter import Counter
from control.ev import Ev
from control.ev.ev import Ev
from control.pv import Pv
from control.chargepoint.chargepoint_state import ChargepointState
from test_utils.default_hierarchies import NESTED_HIERARCHY
Expand Down
8 changes: 4 additions & 4 deletions packages/control/algorithm/surplus_controlled.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,9 @@ def _set_loadmangement_message(self,

# 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.charging_ev_data.charge_template.data.chargemode.
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.charging_ev_data.charge_template.data.chargemode.
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

Expand All @@ -110,7 +110,7 @@ def _limit_adjust_current(self, chargepoint: Chargepoint, new_current: float) ->
MAX_CURRENT = 30
msg = None
nominal_difference = chargepoint.data.set.charging_ev_data.ev_template.data.nominal_difference
if chargepoint.data.set.charging_ev_data.chargemode_changed:
if chargepoint.chargemode_changed:
return new_current
else:
# Um max. +/- 5A pro Zyklus regeln
Expand Down Expand Up @@ -158,7 +158,7 @@ def check_submode_pv_charging(self) -> None:
def phase_switch_necessary() -> bool:
return cp.cp_ev_chargemode_support_phase_switch() and cp.data.get.phases_in_use != 1
control_parameter = cp.data.control_parameter
if cp.data.set.charging_ev_data.chargemode_changed or cp.data.set.charging_ev_data.submode_changed:
if cp.chargemode_changed or cp.submode_changed:
if control_parameter.state == ChargepointState.CHARGING_ALLOWED:
if (cp.data.set.charging_ev_data.ev_template.data.prevent_charge_stop is False and
phase_switch_necessary() is False):
Expand Down
9 changes: 4 additions & 5 deletions packages/control/algorithm/surplus_controlled_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
from control.chargepoint.chargepoint_data import Get, Set
from control.chargepoint.chargepoint_template import CpTemplate
from control.chargepoint.control_parameter import ControlParameter
from control.ev import ChargeTemplate, Ev
from control.ev.charge_template import ChargeTemplate

Check failure on line 14 in packages/control/algorithm/surplus_controlled_test.py

View workflow job for this annotation

GitHub Actions / build

'control.ev.charge_template.ChargeTemplate' imported but unused

Check failure on line 14 in packages/control/algorithm/surplus_controlled_test.py

View workflow job for this annotation

GitHub Actions / build

'control.ev.charge_template.ChargeTemplate' imported but unused
from control.ev.ev import Ev


@pytest.fixture(autouse=True)
Expand Down Expand Up @@ -39,10 +40,8 @@
expected_sorted: int):
# setup
def setup_cp(cp: Chargepoint, feed_in_limit: bool) -> Chargepoint:
ev = Ev(0)
ev.charge_template = ChargeTemplate(0)
ev.charge_template.data.chargemode.pv_charging.feed_in_limit = feed_in_limit
cp.data = ChargepointData(set=Set(charging_ev_data=ev))
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)
Expand Down
2 changes: 1 addition & 1 deletion packages/control/auto_phase_switch_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from control.pv_all import PvAll
from control.bat_all import BatAll
from control.general import General
from control.ev import Ev
from control.ev.ev import Ev
from control import data
from control.chargepoint.chargepoint_state import ChargepointState

Expand Down
71 changes: 54 additions & 17 deletions packages/control/chargepoint/chargepoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
Tag-Liste: Tags, mit denen der Ladepunkt freigeschaltet werden kann. Ist diese leer, kann mit jedem Tag der Ladepunkt
freigeschaltet werden.
"""
import copy
from dataclasses import asdict
import dataclasses
import logging
Expand All @@ -29,9 +30,10 @@
from control.chargepoint.control_parameter import ControlParameter, control_parameter_factory
from control.chargepoint.charging_type import ChargingType
from control.chargepoint.rfid import ChargepointRfidMixin
from control.ev import Ev
from control.ev.ev import Ev
from control import phase_switch
from control.chargepoint.chargepoint_state import ChargepointState
from helpermodules.broker import InternalBrokerClient
from helpermodules.phase_mapping import convert_single_evu_phase_to_cp_phase
from helpermodules.pub import Pub
from helpermodules import timecheck
Expand Down Expand Up @@ -73,6 +75,8 @@ def __init__(self, index: int, event: Optional[threading.Event]):
# set current aus dem vorherigen Zyklus, um zu wissen, ob am Ende des Zyklus die Ladung freigegeben wird
# (für Control-Pilot-Unterbrechung)
self.set_current_prev = 0.0
self.chargemode_changed = False
self.submode_changed = False
# bestehende Daten auf dem Broker nicht zurücksetzen, daher nicht veröffentlichen
self.data: ChargepointData = ChargepointData()
self.data.set_event(event)
Expand Down Expand Up @@ -224,14 +228,16 @@ def _process_charge_stop(self) -> None:
if not self.data.get.plug_state:
self.data.control_parameter = control_parameter_factory()
# Standardprofil nach Abstecken laden
if data.data.ev_data["ev"+str(self.data.set.charging_ev_prev)].charge_template.data.load_default:
if self.data.set.charge_template.data.load_default:
self.data.config.ev = 0
Pub().pub("openWB/set/chargepoint/"+str(self.num)+"/config/ev", 0)
# Ladepunkt nach Abstecken sperren
if self.template.data.disable_after_unplug:
self.data.set.manual_lock = True
Pub().pub("openWB/set/chargepoint/"+str(self.num)+"/set/manual_lock", True)
# Ev wurde noch nicht aktualisiert.
# Ladeprofil aus den Einstellungen laden.
self._update_charge_template(self.data.set.charging_ev_data)
chargelog.save_and_reset_data(self, data.data.ev_data["ev"+str(self.data.set.charging_ev_prev)])
self.data.set.charging_ev_prev = -1
Pub().pub("openWB/set/chargepoint/"+str(self.num)+"/set/charging_ev_prev",
Expand Down Expand Up @@ -277,8 +283,8 @@ def set_control_parameter(self, submode: str, required_current: float):
self.data.control_parameter.chargemode = Chargemode.TIME_CHARGING
else:
self.data.control_parameter.chargemode = Chargemode(
self.data.set.charging_ev_data.charge_template.data.chargemode.selected)
self.data.control_parameter.prio = self.data.set.charging_ev_data.charge_template.data.prio
self.data.set.charge_template.data.chargemode.selected)
self.data.control_parameter.prio = self.data.set.charge_template.data.prio
self.data.control_parameter.required_current = required_current
if self.template.data.charging_type == ChargingType.AC.value:
self.data.control_parameter.min_current = self.data.set.charging_ev_data.ev_template.data.min_current
Expand Down Expand Up @@ -502,7 +508,7 @@ def get_phases_by_selected_chargemode(self) -> int:
if self.data.control_parameter.submode == "time_charging":
mode = "time_charging"
else:
mode = charging_ev.charge_template.data.chargemode.selected
mode = self.data.set.charge_template.data.chargemode.selected
chargemode = data.data.general_data.get_phases_chargemode(mode, self.data.control_parameter.submode)

if (chargemode is None or
Expand Down Expand Up @@ -607,6 +613,18 @@ def set_required_currents(self, required_current: float) -> None:
"was ggf eine unnötige Reduktion der Ladeleistung zur Folge hat.")
self.data.set.required_power = sum(control_parameter.required_currents) * 230

def set_chargemode_changed(self, submode: str) -> None:
if ((submode == "time_charging" and self.data.control_parameter.chargemode != "time_charging") or
(submode != "time_charging" and
self.data.control_parameter.chargemode != self.data.set.charge_template.data.chargemode.selected)):
self.chargemode_changed = True
log.debug("Änderung des Lademodus")
else:
self.chargemode_changed = False

def set_submode_changed(self, submode: str) -> None:
self.submode_changed = (submode != self.data.control_parameter.submode)

def handle_less_power(self):
if self.data.set.current != 0 and self.data.control_parameter.state == ChargepointState.CHARGING_ALLOWED:
nominal_difference = self.data.set.charging_ev_data.ev_template.data.nominal_difference
Expand Down Expand Up @@ -655,6 +673,7 @@ def update(self, ev_list: Dict[str, Ev]) -> None:
self.data.control_parameter.phases = min(
self.get_phases_by_selected_chargemode(), max_phase_hw)
state, message_ev, submode, required_current, phases = charging_ev.get_required_current(
self.data.set.charge_template,
self.data.control_parameter,
self.data.get.imported,
max_phase_hw,
Expand All @@ -667,21 +686,21 @@ def update(self, ev_list: Dict[str, Ev]) -> None:
required_current = self.check_min_max_current(
required_current, self.data.control_parameter.phases)
required_current = self.chargepoint_module.add_conversion_loss_to_current(required_current)
charging_ev.set_chargemode_changed(self.data.control_parameter, submode)
charging_ev.set_submode_changed(self.data.control_parameter, submode)
self.set_chargemode_changed(submode)
self.set_submode_changed(submode)
self.set_control_parameter(submode, required_current)
self.set_required_currents(required_current)
self.handle_less_power()
self.check_phase_switch_completed()

if charging_ev.chargemode_changed:
if self.chargemode_changed:
data.data.counter_all_data.get_evu_counter().reset_switch_on_off(
self, charging_ev)
charging_ev.reset_phase_switch(self.data.control_parameter)
message = message_ev if message_ev else message
# Ein Eintrag muss nur erstellt werden, wenn vorher schon geladen wurde und auch danach noch
# geladen werden soll.
if charging_ev.chargemode_changed and self.data.set.log.imported_since_mode_switch != 0 and state:
if self.chargemode_changed and self.data.set.log.imported_since_mode_switch != 0 and state:
chargelog.save_interim_data(self, charging_ev)

# Wenn die Nachrichten gesendet wurden, EV wieder löschen, wenn das EV im Algorithmus nicht
Expand All @@ -697,7 +716,7 @@ def update(self, ev_list: Dict[str, Ev]) -> None:
str(self.num)+"/set/charging_ev", -1)
log.debug(f'LP {self.num}, EV: {self.data.set.charging_ev_data.data.name}'
f' (EV-Nr.{vehicle}): Lademodus '
f'{charging_ev.charge_template.data.chargemode.selected}, Submodus: '
f'{self.data.set.charge_template.data.chargemode.selected}, Submodus: '
f'{self.data.control_parameter.submode}')
else:
if (self.data.control_parameter.state == ChargepointState.SWITCH_ON_DELAY and
Expand All @@ -707,10 +726,10 @@ def update(self, ev_list: Dict[str, Ev]) -> None:
log.info(
f"LP {self.num}, EV: {self.data.set.charging_ev_data.data.name} (EV-Nr.{vehicle}): "
f"Theoretisch benötigter Strom {required_current}A, Lademodus "
f"{charging_ev.charge_template.data.chargemode.selected}, Submodus: "
f"{self.data.set.charge_template.data.chargemode.selected}, Submodus: "
f"{self.data.control_parameter.submode}, Phasen: "
f"{self.data.control_parameter.phases}"
f", Priorität: {charging_ev.charge_template.data.prio}"
f", Priorität: {self.data.control_parameter.prio}"
f", max. Ist-Strom: {max(self.data.get.currents)}")
except Exception:
log.exception("Fehler im Prepare-Modul für Ladepunkt "+str(self.num))
Expand Down Expand Up @@ -763,13 +782,31 @@ def _get_charging_ev(self, vehicle: int, ev_list: Dict[str, Ev]) -> Ev:
if self.data.set.charging_ev != vehicle and self.data.set.charging_ev_prev != vehicle:
Pub().pub(f"openWB/set/vehicle/{charging_ev.num}/get/force_soc_update", True)
log.debug("SoC nach EV-Wechsel")
self._update_charge_template(charging_ev)
self.data.set.charging_ev_data = charging_ev
self.data.set.charging_ev = vehicle
Pub().pub("openWB/set/chargepoint/"+str(self.num)+"/set/charging_ev", vehicle)
self.data.set.charging_ev_prev = vehicle
Pub().pub("openWB/set/chargepoint/"+str(self.num)+"/set/charging_ev_prev", vehicle)
return charging_ev

def _update_charge_template(self, charging_ev_data: Ev) -> None:
def on_connect(client, userdata, flags, rc):
client.subscribe(f'openWB/chargepoint/{self.num}/set/charge_temlate/#', 2)

def __get_payload(client, userdata, msg):
Pub().pub(msg.topic, "")
InternalBrokerClient("processBrokerBranch", on_connect, __get_payload).start_finite_loop()
self.data.set.charge_template = copy.deepcopy(charging_ev_data.charge_template)
Pub().pub(f"openWB/set/chargepoint/{self.num}/set/charge_template",
dataclasses.asdict(self.data.set.charge_template))
for id, plan in self.data.set.charge_template.data.time_charging.plans.items():
Pub().pub(f"openWB/set/chargepoint/{self.num}/set/charge_template/time_charging/plans/{id}",
dataclasses.asdict(plan))
for id, plan in self.data.set.charge_template.data.chargemode.scheduled_charging.plans.items():
Pub().pub(f"openWB/set/chargepoint/{self.num}/set/charge_template/scheduled_charging/plans/{id}",
dataclasses.asdict(plan))

def _pub_connected_vehicle(self, vehicle: Ev):
""" published die Daten, die zur Anzeige auf der Hauptseite benötigt werden.

Expand All @@ -793,16 +830,16 @@ def _pub_connected_vehicle(self, vehicle: Ev):
soc_obj.range = vehicle.data.get.range
info_obj = ConnectedInfo(id=vehicle.num,
name=vehicle.data.name)
if (vehicle.charge_template.data.chargemode.selected == "time_charging" or
vehicle.charge_template.data.chargemode.selected == "scheduled_charging"):
if (self.data.set.charge_template.data.chargemode.selected == "time_charging" or
self.data.set.charge_template.data.chargemode.selected == "scheduled_charging"):
current_plan = self.data.control_parameter.current_plan
else:
current_plan = None
config_obj = ConnectedConfig(
charge_template=vehicle.charge_template.ct_num,
charge_template=self.data.set.charge_template.ct_num,
ev_template=vehicle.ev_template.et_num,
chargemode=vehicle.charge_template.data.chargemode.selected,
priority=vehicle.charge_template.data.prio,
chargemode=self.data.set.charge_template.data.chargemode.selected,
priority=self.data.set.charge_template.data.prio,
current_plan=current_plan,
average_consumption=vehicle.ev_template.data.average_consump,
time_charging_in_use=True if (self.data.control_parameter.submode ==
Expand Down
8 changes: 7 additions & 1 deletion packages/control/chargepoint/chargepoint_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
from control.chargepoint.chargepoint_template import CpTemplate

from control.chargepoint.control_parameter import ControlParameter, control_parameter_factory
from control.ev import Ev
from control.ev.charge_template import ChargeTemplate
from control.ev.ev import Ev
from dataclass_utils.factories import currents_list_factory, empty_dict_factory, voltages_list_factory
from helpermodules.constants import NO_ERROR
from modules.common.abstract_chargepoint import AbstractChargepoint
Expand Down Expand Up @@ -116,6 +117,10 @@ class Get:
voltages: List[float] = field(default_factory=voltages_list_factory)


def charge_template_factory() -> ChargeTemplate:
return ChargeTemplate(None)


def ev_factory() -> Ev:
return Ev(0)

Expand All @@ -128,6 +133,7 @@ def log_factory() -> Log:
class Set:
charging_ev: int = -1
charging_ev_prev: int = -1
charge_template: ChargeTemplate = field(default_factory=charge_template_factory)
current: float = 0
energy_to_charge: float = 0
loadmanagement_available: bool = True
Expand Down
2 changes: 1 addition & 1 deletion packages/control/chargepoint/chargepoint_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from typing import Dict, List

from control import data
from control import ev as ev_module
from control.ev import ev as ev_module
from control.chargepoint.charging_type import ChargingType
from dataclass_utils.factories import empty_dict_factory, empty_list_factory
from helpermodules.abstract_plans import AutolockPlan
Expand Down
2 changes: 1 addition & 1 deletion packages/control/chargepoint/chargepoint_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from control.chargepoint.chargepoint import Chargepoint
from control.chargepoint.chargepoint_template import CpTemplate
from control.ev import Ev
from control.ev.ev import Ev


@pytest.mark.parametrize("phase_1, phases, expected_required_currents",
Expand Down
2 changes: 1 addition & 1 deletion packages/control/chargepoint/get_phases_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from control.chargepoint.chargepoint import Chargepoint
from control.chargepoint.chargepoint_template import CpTemplate, get_chargepoint_template_default
from control.ev import Ev
from control.ev.ev import Ev
from control.general import General
from control import data

Expand Down
Loading
Loading