Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
okaegi committed Jan 5, 2025
2 parents a279422 + be2e07e commit 63a707a
Show file tree
Hide file tree
Showing 434 changed files with 4,323 additions and 2,772 deletions.
12 changes: 12 additions & 0 deletions data/config/apache/apache-proplus.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# openwb-version:1
Listen 8080

<VirtualHost *:8080>
ProxyPreserveHost On

# Proxy for Pro:
ProxyPass / http://192.168.192.50:80/
ProxyPassReverse / http://192.168.192.50:80/

ServerName localhost
</VirtualHost>
8 changes: 8 additions & 0 deletions data/config/dhcpcd.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# openwb - begin
# openwb-version:1
# second interface connected to internal pro
interface eth1
static ip_address=192.168.192.150
# static routers=192.168.192.150
# static domain_name_servers=8.8.8.8
# openwb - end
9 changes: 9 additions & 0 deletions data/config/dnsmasq.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# openwb-version:2
# activate DHCP-Server on second interface only
interface=eth1

# IPv4 pool and lease time
dhcp-range=192.168.192.50,192.168.192.50,1m

# DNS
dhcp-option=option:dns-server,192.168.192.150
17 changes: 17 additions & 0 deletions docs/Manueller SoC.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# SoC-Modul des Fahrzeugs „Manueller SoC“

Stehen keine anderen SoC-Module für Dein Fahrzeug zur Verfügung, so kann das Modul „Manueller SoC“ genutzt werden.

Der Anfangs-SoC des Fahrzeugs muss hierbei manuell angegeben werden, z.B. über ein integriertes Display oder über das Webinterface. Während der Ladung wird anhand der Angaben aus dem Fahrzeugprofil zur Akkukapazität und des Wirkungsgrades der Ladeelektronik der aktuelle SoC berechnet.

Zunächst müssen also diese Angaben im Fahrzeugprofil (Angaben zur Batterie) erfasst werden:

![Fahrzeugprofil: Angaben zu Batterie](<pictures/Manueller SoC_Angaben zu Batterie.png>)

Dann wird im Fahrzeug das SoC Modul „Manueller SoC“ ausgewählt:

![Einstellungen Manueller SoC](<pictures/Manueller SoC_Einstellungen.png>)

Nun kann der Anfangs-SoC auf der Hauptseite angegeben werden:

![Eingabe manueller SoC](<pictures/Manueller SoC_Eingabe.png>)
1 change: 1 addition & 0 deletions docs/_Sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* [Grundkonzept](https://github.com/openWB/core/wiki/Grundkonzept)
* [Ladepunkte](https://github.com/openWB/core/wiki/Ladepunkte)
* [Fahrzeuge](https://github.com/openWB/core/wiki/Fahrzeuge)
* [Manueller SoC](https://github.com/openWB/core/wiki/Manueller-SoC)
* [Lademodi](https://github.com/openWB/core/wiki/Lademodi)
* Zähler
* [Grundsätzliches zu Zählern](https://github.com/openWB/core/wiki/Grundsätzliches-zu-Zählern)
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/pictures/Manueller SoC_Eingabe.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/pictures/Manueller SoC_Einstellungen.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 12 additions & 3 deletions docs/samples/sample_modbus/bat.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env python3
from typing import Optional
from dataclass_utils import dataclass_from_dict
from modules.common.abstract_device import AbstractBat
from modules.common.component_state import BatState
Expand All @@ -11,15 +12,16 @@


class SampleBat(AbstractBat):
def __init__(self, device_id: int, component_config: SampleBatSetup) -> None:
def __init__(self, device_id: int, component_config: SampleBatSetup, client: ModbusTcpClient_) -> None:
self.__device_id = device_id
self.component_config = dataclass_from_dict(SampleBatSetup, component_config)
self.sim_counter = SimCounter(self.__device_id, self.component_config.id, prefix="speicher")
self.store = get_bat_value_store(self.component_config.id)
self.fault_state = FaultState(ComponentInfo.from_component_config(self.component_config))
self.client = client

def update(self, client: ModbusTcpClient_) -> None:
power = client.read_holding_registers(reg, ModbusDataType.INT_32, unit=unit)
def update(self) -> None:
power = self.client.read_holding_registers(reg, ModbusDataType.INT_32, unit=unit)
imported, exported = self.sim_counter.sim_count(power)

bat_state = BatState(
Expand All @@ -30,5 +32,12 @@ def update(self, client: ModbusTcpClient_) -> None:
)
self.store.set(bat_state)

def set_power_limit(self, power_limit: Optional[int]) -> None:
# Methode entfernen, falls der Speicher keine Steuerung der Ladeleistung unterstützt
# Wenn der Speicher die Steuerung der Ladeleistung unterstützt, muss bei Übergabe einer Zahl auf aktive
# Speichersteurung umgeschaltet werden, sodass der Speicher mit der übergebenen Leistung lädt/entlädt. Wird
# None übergeben, muss der Speicher die Null-Punkt-Ausregelung selbst übernehmen.
self.client.write_registers(reg, power_limit)


component_descriptor = ComponentDescriptor(configuration_factory=SampleBatSetup)
7 changes: 4 additions & 3 deletions docs/samples/sample_modbus/counter.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@


class SampleCounter(AbstractCounter):
def __init__(self, device_id: int, component_config: SampleCounterSetup) -> None:
def __init__(self, device_id: int, component_config: SampleCounterSetup, client: ModbusTcpClient_) -> None:
self.__device_id = device_id
self.component_config = dataclass_from_dict(SampleCounterSetup, component_config)
self.sim_counter = SimCounter(self.__device_id, self.component_config.id, prefix="bezug")
self.store = get_counter_value_store(self.component_config.id)
self.fault_state = FaultState(ComponentInfo.from_component_config(self.component_config))
self.client = client

def update(self, client: ModbusTcpClient_):
power = client.read_holding_registers(reg, ModbusDataType.INT_32, unit=unit)
def update(self):
power = self.client.read_holding_registers(reg, ModbusDataType.INT_32, unit=unit)
imported, exported = self.sim_counter.sim_count(power)

counter_state = CounterState(
Expand Down
10 changes: 5 additions & 5 deletions docs/samples/sample_modbus/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@

def create_device(device_config: Sample):
def create_bat_component(component_config: SampleBatSetup):
return SampleBat(device_config.id, component_config, device_config.configuration.ip_address)
return SampleBat(device_config.id, component_config, device_config.configuration.ip_address, client)

def create_counter_component(component_config: SampleCounterSetup):
return SampleCounter(device_config.id, component_config, device_config.configuration.ip_address)
return SampleCounter(device_config.id, component_config, device_config.configuration.ip_address, client)

def create_inverter_component(component_config: SampleInverterSetup):
return SampleInverter(device_config.id, component_config, device_config.configuration.ip_address)
return SampleInverter(device_config.id, component_config, device_config.configuration.ip_address, client)

def update_components(components: Iterable[Union[SampleBat, SampleCounter, SampleInverter]]):
with client as c:
with client:
for component in components:
with SingleComponentUpdateContext(component.fault_state):
component.update(c)
component.update()

try:
client = ModbusTcpClient_(device_config.configuration.ip_address, device_config.configuration.port)
Expand Down
7 changes: 4 additions & 3 deletions docs/samples/sample_modbus/inverter.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@


class SampleInverter(AbstractInverter):
def __init__(self, device_id: int, component_config: SampleInverterSetup) -> None:
def __init__(self, device_id: int, component_config: SampleInverterSetup, client: ModbusTcpClient_) -> None:
self.__device_id = device_id
self.component_config = dataclass_from_dict(SampleInverterSetup, component_config)
self.sim_counter = SimCounter(self.__device_id, self.component_config.id, prefix="pv")
self.store = get_inverter_value_store(self.component_config.id)
self.fault_state = FaultState(ComponentInfo.from_component_config(self.component_config))
self.client = client

def update(self, client: ModbusTcpClient_) -> None:
power = client.read_holding_registers(reg, ModbusDataType.INT_32, unit=unit)
def update(self) -> None:
power = self.client.read_holding_registers(reg, ModbusDataType.INT_32, unit=unit)
exported = self.sim_counter.sim_count(power)[1]

inverter_state = InverterState(
Expand Down
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
3 changes: 2 additions & 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 Expand Up @@ -49,6 +49,7 @@ def test_set_current_counterdiff(diff: float,
cp.data.control_parameter.required_currents = required_currents
cp.data.set.charging_ev_data = ev
cp.data.set.current = 6
cp.data.get.currents = [10]*3
get_counters_to_check_mock = Mock(return_value=["cp0", "cp6"])
monkeypatch.setattr(CounterAll, "get_counters_to_check", get_counters_to_check_mock)
data.data.counter_data = {"cp0": Mock(spec=Counter), "cp6": Mock(spec=Counter)}
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
39 changes: 14 additions & 25 deletions packages/control/algorithm/integration_test/pv_charging_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ class ParamsPhaseSwitch(ParamsExpectedSetCurrent, ParamsExpectedCounterSet):
raw_power_left: float = 0
raw_currents_left_counter0: List[float] = field(default_factory=currents_list_factory)
raw_currents_left_counter6: List[float] = field(default_factory=currents_list_factory)
expected_timestamp_auto_phase_switch_cp3: Optional[str] = None
expected_timestamp_auto_phase_switch_cp4: Optional[str] = None
expected_timestamp_auto_phase_switch_cp5: Optional[str] = None
expected_timestamp_last_phase_switch_cp3: Optional[str] = None
expected_timestamp_last_phase_switch_cp4: Optional[str] = None
expected_timestamp_last_phase_switch_cp5: Optional[str] = None


def assert_counter_set(params: ParamsExpectedCounterSet):
Expand Down Expand Up @@ -243,9 +243,9 @@ def test_surplus(params: ParamsSurplus, all_cp_pv_charging_3p, all_cp_charging_3
raw_power_left=32580,
raw_currents_left_counter0=[40]*3,
raw_currents_left_counter6=[16]*3,
expected_timestamp_auto_phase_switch_cp3=1652683252.0,
expected_timestamp_auto_phase_switch_cp4=None,
expected_timestamp_auto_phase_switch_cp5=None,
expected_timestamp_last_phase_switch_cp3=1652683252.0,
expected_timestamp_last_phase_switch_cp4=None,
expected_timestamp_last_phase_switch_cp5=None,
expected_current_cp3=10,
expected_current_cp4=6,
expected_current_cp5=6,
Expand All @@ -257,9 +257,9 @@ def test_surplus(params: ParamsSurplus, all_cp_pv_charging_3p, all_cp_charging_3
raw_power_left=42580,
raw_currents_left_counter0=[40]*3,
raw_currents_left_counter6=[16]*3,
expected_timestamp_auto_phase_switch_cp3=1652683252.0,
expected_timestamp_auto_phase_switch_cp4=None,
expected_timestamp_auto_phase_switch_cp5=None,
expected_timestamp_last_phase_switch_cp3=1652683252.0,
expected_timestamp_last_phase_switch_cp4=None,
expected_timestamp_last_phase_switch_cp5=None,
expected_current_cp3=32,
expected_current_cp4=6,
expected_current_cp5=6,
Expand All @@ -281,21 +281,16 @@ def test_phase_switch(all_cp_pv_charging_3p, all_cp_charging_3p, monkeypatch):
monkeypatch.setattr(algorithm_data.data.general_data, "get_phases_chargemode", mockget_get_phases_chargemode)
data.data.cp_data[
"cp3"].data.control_parameter.state = ChargepointState.CHARGING_ALLOWED
data.data.cp_data[
"cp3"].data.control_parameter.timestamp_last_phase_switch = 1652682252

# execution
Algorithm().calc_current()

# evaluation
assert_expected_current(cases_phase_switch[0])
assert data.data.cp_data[
"cp3"].data.control_parameter.timestamp_auto_phase_switch == cases_phase_switch[
0].expected_timestamp_auto_phase_switch_cp3
assert data.data.cp_data[
"cp4"].data.control_parameter.timestamp_auto_phase_switch == cases_phase_switch[
0].expected_timestamp_auto_phase_switch_cp4
assert data.data.cp_data[
"cp5"].data.control_parameter.timestamp_auto_phase_switch == cases_phase_switch[
0].expected_timestamp_auto_phase_switch_cp5
"cp3"].data.control_parameter.state == ChargepointState.PHASE_SWITCH_DELAY
assert_counter_set(cases_phase_switch[0])


Expand All @@ -311,6 +306,7 @@ def test_phase_switch_1p_3p(all_cp_pv_charging_1p, monkeypatch):
monkeypatch.setattr(algorithm_data.data.general_data, "get_phases_chargemode", mockget_get_phases_chargemode)
data.data.cp_data["cp3"].data.get.currents = [32, 0, 0]
data.data.cp_data["cp3"].data.get.power = 7360
data.data.cp_data["cp3"].data.control_parameter.timestamp_last_phase_switch = 1652682252
data.data.cp_data["cp4"].data.get.currents = [0, 0, 0]
data.data.cp_data["cp5"].data.get.currents = [0, 0, 0]

Expand All @@ -320,11 +316,4 @@ def test_phase_switch_1p_3p(all_cp_pv_charging_1p, monkeypatch):
# evaluation
assert_counter_set(cases_phase_switch[1])
assert data.data.cp_data[
"cp3"].data.control_parameter.timestamp_auto_phase_switch == cases_phase_switch[
1].expected_timestamp_auto_phase_switch_cp3
assert data.data.cp_data[
"cp4"].data.control_parameter.timestamp_auto_phase_switch == cases_phase_switch[
1].expected_timestamp_auto_phase_switch_cp4
assert data.data.cp_data[
"cp5"].data.control_parameter.timestamp_auto_phase_switch == cases_phase_switch[
1].expected_timestamp_auto_phase_switch_cp5
"cp3"].data.control_parameter.state == ChargepointState.PHASE_SWITCH_DELAY
8 changes: 4 additions & 4 deletions packages/control/algorithm/surplus_controlled.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,15 @@ def _set(self,
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
dif_to_old_current = available_for_cp + cp.data.set.target_current - cp.set_current_prev
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 kommmt.
if (pv_charging.control_range[1] - pv_charging.control_range[0]) / 230 < abs(dif_to_old_current):
current = available_for_cp
else:
# Nicht mehr freigeben, wie das Lastmanagement vorgibt
current = min(cp.set_current_prev - cp.data.set.target_current, available_for_cp)
current = min(cp.data.set.current_prev - cp.data.set.target_current, available_for_cp)
else:
current = available_for_cp

Expand Down Expand Up @@ -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.data.set.charging_ev_data.chargemode_changed or chargepoint.data.get.charge_state is False:
return new_current
else:
# Um max. +/- 5A pro Zyklus regeln
Expand Down Expand Up @@ -141,7 +141,7 @@ def _fix_deviating_evse_current(self, chargepoint: Chargepoint) -> float:
man den EVSE-Strom auf, pendelt die Regelung um diesen 1A-Schritt."""
MAX_DEVIATION = 1.1
evse_current = chargepoint.data.get.evse_current
if evse_current and chargepoint.data.set.current != chargepoint.set_current_prev:
if evse_current and chargepoint.data.set.current != chargepoint.data.set.current_prev:
formatted_evse_current = evse_current if evse_current < 32 else evse_current / 100
offset = formatted_evse_current - max(chargepoint.data.get.currents)
if abs(offset) >= MAX_DEVIATION:
Expand Down
5 changes: 3 additions & 2 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
from control.ev.ev import Ev


@pytest.fixture(autouse=True)
Expand Down Expand Up @@ -63,7 +64,7 @@ def setup_cp(cp: Chargepoint, feed_in_limit: bool) -> Chargepoint:
def test_limit_adjust_current(new_current: float, expected_current: float, monkeypatch):
# setup
cp = Chargepoint(0, None)
cp.data = ChargepointData(get=Get(currents=[15]*3))
cp.data = ChargepointData(get=Get(charge_state=True, currents=[15]*3))
cp.template = CpTemplate()
monkeypatch.setattr(Chargepoint, "set_state_and_log", Mock())

Expand Down
Loading

0 comments on commit 63a707a

Please sign in to comment.