chore: eosdash improve plan display (#739)
Some checks failed
docker-build / platform-excludes (push) Has been cancelled
docker-build / build (push) Has been cancelled
docker-build / merge (push) Has been cancelled
pre-commit / pre-commit (push) Has been cancelled
Run Pytest on Pull Request / test (push) Has been cancelled
Close stale pull requests/issues / Find Stale issues and PRs (push) Has been cancelled

* chore: improve plan solution display

Add genetic optimization results to general solution provided by EOSdash plan display.

Add total results.

Signed-off-by: Bobby Noelte <b0661n0e17e@gmail.com>

* fix: genetic battery and home appliance device simulation

Fix genetic solution to make ac_charge, dc_charge, discharge, ev_charge or
home appliance start time reflect what the simulation was doing. Sometimes
the simulation decided to charge less or to start the appliance at another
time and this was not brought back to e.g. ac_charge.

Make home appliance simulation activate time window for the next day if it can not be
run today.

Improve simulation speed.

Signed-off-by: Bobby Noelte <b0661n0e17e@gmail.com>

---------

Signed-off-by: Bobby Noelte <b0661n0e17e@gmail.com>
This commit is contained in:
Bobby Noelte
2025-11-08 15:42:18 +01:00
committed by GitHub
parent c50cdd95cb
commit 3599088dce
18 changed files with 1769 additions and 1345 deletions

View File

@@ -6,20 +6,53 @@ from akkudoktoreos.devices.genetic.battery import Battery, SolarPanelBatteryPara
@pytest.fixture
def setup_pv_battery():
device_id="battery1"
capacity_wh=10000
initial_soc_percentage=50
charging_efficiency=0.88
discharging_efficiency=0.88
min_soc_percentage=20
max_soc_percentage=80
max_charge_power_w=8000
hours=24
params = SolarPanelBatteryParameters(
device_id="battery1",
capacity_wh=10000,
initial_soc_percentage=50,
min_soc_percentage=20,
max_soc_percentage=80,
max_charge_power_w=8000,
hours=24,
device_id=device_id,
capacity_wh=capacity_wh,
initial_soc_percentage=initial_soc_percentage,
charging_efficiency=charging_efficiency,
discharging_efficiency=discharging_efficiency,
min_soc_percentage=min_soc_percentage,
max_soc_percentage=max_soc_percentage,
max_charge_power_w=max_charge_power_w,
hours=hours,
)
battery = Battery(
params,
prediction_hours=48,
)
battery.reset()
assert battery.parameters.device_id==device_id
assert battery.capacity_wh==capacity_wh
assert battery.initial_soc_percentage==initial_soc_percentage
assert battery.charging_efficiency==charging_efficiency
assert battery.initial_soc_percentage==initial_soc_percentage
assert battery.discharging_efficiency==discharging_efficiency
assert battery.max_soc_percentage==max_soc_percentage
assert battery.max_charge_power_w==max_charge_power_w
assert battery.soc_wh==float((initial_soc_percentage / 100) * capacity_wh)
assert battery.min_soc_wh==float((min_soc_percentage / 100) * capacity_wh)
assert battery.max_soc_wh==float((max_soc_percentage / 100) * capacity_wh)
assert np.all(battery.charge_array == 0)
assert np.all(battery.discharge_array == 0)
# Init for test
battery.charge_array = np.full(battery.prediction_hours, 1)
battery.discharge_array = np.full(battery.prediction_hours, 1)
assert np.all(battery.charge_array == 1)
assert np.all(battery.discharge_array == 1)
return battery
@@ -164,17 +197,47 @@ def test_charge_energy_not_allowed_hour(setup_pv_battery):
), "SOC should remain unchanged"
def test_charge_energy_relative_power(setup_pv_battery):
@pytest.mark.parametrize(
"wh, charge_factor, expected_raises",
[
(None, 0.5, False), # Expected to work normally (if capacity allows)
(None, 1.0, False), # Often still OK, depending on fixture capacity
(None, 2.0, False), # Exceeds max charge → always ValueError
(1000, 0, False),
(1000, 1.0, True),
],
)
def test_charge_energy_with_charge_factor(setup_pv_battery, wh, charge_factor, expected_raises):
battery = setup_pv_battery
hour = 4
relative_power = 0.5 # 50% of max charge power
charged_wh, losses_wh = battery.charge_energy(wh=None, hour=4, relative_power=relative_power)
if wh is not None and charge_factor == 0.0: # mode 1
raw_request_wh = wh
else:
raw_request_wh = battery.max_charge_power_w * charge_factor
raw_capacity_wh = max(battery.max_soc_wh - battery.soc_wh, 0.0)
assert charged_wh > 0, "Charging should occur with relative power"
assert losses_wh >= 0, "Losses should not be negative"
assert charged_wh <= battery.max_charge_power_w * relative_power, (
"Charging should respect relative power limit"
if expected_raises:
# Should raise
with pytest.raises(ValueError):
battery.charge_energy(
wh=wh,
hour=hour,
charge_factor=charge_factor,
)
return
# Should NOT raise
charged_wh, losses_wh = battery.charge_energy(
wh=wh,
hour=hour,
charge_factor=charge_factor,
)
# Expectations
assert charged_wh > 0, "Charging should occur with charge factor"
assert losses_wh >= 0, "Losses must not be negative"
assert charged_wh <= raw_request_wh, "Charging must not exceed request"
assert battery.soc_wh > 0, "SOC should increase after charging"
@@ -198,6 +261,13 @@ def setup_car_battery():
prediction_hours=48,
)
battery.reset()
# Init for test
battery.charge_array = np.full(battery.prediction_hours, 1)
battery.discharge_array = np.full(battery.prediction_hours, 1)
assert np.all(battery.charge_array == 1)
assert np.all(battery.discharge_array == 1)
return battery

View File

@@ -3,11 +3,24 @@ from pathlib import Path
from typing import Any, Optional, Union
from unittest.mock import patch
import numpy as np
import pytest
from loguru import logger
from pydantic import IPvAnyAddress, ValidationError
from akkudoktoreos.config.config import ConfigEOS, GeneralSettings
from akkudoktoreos.devices.devices import BATTERY_DEFAULT_CHARGE_RATES
def assert_values_equal(actual, expected):
"""Compare values, handling lists and numpy arrays."""
if isinstance(actual, (list, np.ndarray)) or isinstance(expected, (list, np.ndarray)):
# Convert both to numpy arrays for comparison
actual_arr = np.array(actual)
expected_arr = np.array(expected)
assert np.array_equal(actual_arr, expected_arr), f"Expected {expected_arr}, but got {actual_arr}"
else:
assert actual == expected, f"Expected {expected}, but got {actual}"
# overwrite config_mixin fixture from conftest
@@ -352,7 +365,7 @@ def test_config_common_settings_timezone_none_when_coordinates_missing():
[
(
"devices.electric_vehicles[0].charge_rates",
[0.0, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0],
BATTERY_DEFAULT_CHARGE_RATES,
)
],
ValueError,
@@ -364,10 +377,10 @@ def test_config_common_settings_timezone_none_when_coordinates_missing():
[
(
"devices.electric_vehicles[0].charge_rates",
[0.0, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0],
BATTERY_DEFAULT_CHARGE_RATES,
)
],
TypeError,
KeyError,
),
# Invalid index (no number)
(
@@ -376,10 +389,10 @@ def test_config_common_settings_timezone_none_when_coordinates_missing():
[
(
"devices.electric_vehicles[0].charge_rates",
[0.0, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0],
BATTERY_DEFAULT_CHARGE_RATES,
)
],
IndexError,
KeyError,
),
# Unset value (set None)
(
@@ -388,7 +401,7 @@ def test_config_common_settings_timezone_none_when_coordinates_missing():
[
(
"devices.electric_vehicles[0].charge_rates",
None,
BATTERY_DEFAULT_CHARGE_RATES,
)
],
None,
@@ -400,17 +413,13 @@ def test_set_nested_key(path, value, expected, exception, config_eos):
config_eos.set_nested_value(path, value)
for expected_path, expected_value in expected:
actual_value = eval(f"config_eos.{expected_path}")
assert actual_value == expected_value, (
f"Expected {expected_value} at {expected_path}, but got {actual_value}"
)
assert_values_equal(actual_value, expected_value)
else:
try:
config_eos.set_nested_value(path, value)
for expected_path, expected_value in expected:
actual_value = eval(f"config_eos.{expected_path}")
assert actual_value == expected_value, (
f"Expected {expected_value} at {expected_path}, but got {actual_value}"
)
assert_values_equal(actual_value, expected_value)
pytest.fail(
f"Expected exception {exception} but none was raised. Set '{expected_path}' to '{actual_value}'"
)
@@ -508,19 +517,19 @@ def test_merge_settings_partial(config_eos):
config_eos.merge_settings_from_dict(partial_settings)
assert config_eos.devices.max_electric_vehicles == 1
assert len(config_eos.devices.electric_vehicles) == 1
assert config_eos.devices.electric_vehicles[0].charge_rates == [0.0, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0]
assert_values_equal(config_eos.devices.electric_vehicles[0].charge_rates, [0.0, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0])
# Assure re-apply generates the same config
config_eos.merge_settings_from_dict(partial_settings)
assert config_eos.devices.max_electric_vehicles == 1
assert len(config_eos.devices.electric_vehicles) == 1
assert config_eos.devices.electric_vehicles[0].charge_rates == [0.0, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0]
assert_values_equal(config_eos.devices.electric_vehicles[0].charge_rates, [0.0, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0])
# Assure update keeps same values
config_eos.update()
assert config_eos.devices.max_electric_vehicles == 1
assert len(config_eos.devices.electric_vehicles) == 1
assert config_eos.devices.electric_vehicles[0].charge_rates == [0.0, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0]
assert_values_equal(config_eos.devices.electric_vehicles[0].charge_rates, [0.0, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0])
def test_merge_settings_empty(config_eos):

View File

@@ -65,7 +65,6 @@ def genetic_simulation(config_eos) -> GeneticSimulation:
optimization_hours = config_eos.optimization.horizon_hours,
prediction_hours = config_eos.prediction.hours,
)
home_appliance.set_starting_time(2)
# Example initialization of electric car battery
eauto = Battery(
@@ -250,6 +249,17 @@ def genetic_simulation(config_eos) -> GeneticSimulation:
home_appliance=home_appliance,
)
# Init for test
assert simulation.ac_charge_hours is not None
assert simulation.dc_charge_hours is not None
assert simulation.bat_discharge_hours is not None
assert simulation.ev_charge_hours is not None
simulation.ac_charge_hours[start_hour] = 1.0
simulation.dc_charge_hours[start_hour] = 1.0
simulation.bat_discharge_hours[start_hour] = 1.0
simulation.ev_charge_hours[start_hour] = 1.0
simulation.home_appliance_start_hour = 2
return simulation
@@ -321,34 +331,34 @@ def test_simulation(genetic_simulation):
# Verify that the value at index 0 is 'None'
# Check that 'Netzeinspeisung_Wh_pro_Stunde' and 'Netzbezug_Wh_pro_Stunde' are consistent
assert result["Netzbezug_Wh_pro_Stunde"][1] == 0, (
"The value at index 1 of 'Netzbezug_Wh_pro_Stunde' should be 0."
assert result["Netzbezug_Wh_pro_Stunde"][1] == 1527.13, (
"The value at index 1 of 'Netzbezug_Wh_pro_Stunde' should be 1527.13."
)
# Verify the total balance
assert abs(result["Gesamtbilanz_Euro"] - 1.958185274567674) < 1e-5, (
"Total balance should be 1.958185274567674."
assert abs(result["Gesamtbilanz_Euro"] - 6.612835813556755) < 1e-5, (
"Total balance should be 6.612835813556755."
)
# Check total revenue and total costs
assert abs(result["Gesamteinnahmen_Euro"] - 1.168863124510214) < 1e-5, (
"Total revenue should be 1.168863124510214."
assert abs(result["Gesamteinnahmen_Euro"] - 1.964301131937134) < 1e-5, (
"Total revenue should be 1.964301131937134."
)
assert abs(result["Gesamtkosten_Euro"] - 3.127048399077888) < 1e-5, (
"Total costs should be 3.127048399077888 ."
assert abs(result["Gesamtkosten_Euro"] - 8.577136945493889) < 1e-5, (
"Total costs should be 8.577136945493889 ."
)
# Check the losses
assert abs(result["Gesamt_Verluste"] - 2871.5330639359036) < 1e-5, (
"Total losses should be 2871.5330639359036 ."
assert abs(result["Gesamt_Verluste"] - 1620.0) < 1e-5, (
"Total losses should be 1620.0 ."
)
# Check the values in 'akku_soc_pro_stunde'
assert result["akku_soc_pro_stunde"][-1] == 42.151590909090906, (
"The value at index -1 of 'akku_soc_pro_stunde' should be 42.151590909090906."
assert result["akku_soc_pro_stunde"][-1] == 98.0, (
"The value at index -1 of 'akku_soc_pro_stunde' should be 98.0."
)
assert result["akku_soc_pro_stunde"][1] == 60.08659090909091, (
"The value at index 1 of 'akku_soc_pro_stunde' should be 60.08659090909091."
assert result["akku_soc_pro_stunde"][1] == 98.0, (
"The value at index 1 of 'akku_soc_pro_stunde' should be 98.0."
)
# Check home appliances

View File

@@ -65,7 +65,6 @@ def genetic_simulation_2(config_eos) -> GeneticSimulation:
optimization_hours = config_eos.optimization.horizon_hours,
prediction_hours = config_eos.prediction.hours,
)
home_appliance.set_starting_time(2)
# Example initialization of electric car battery
eauto = Battery(
@@ -158,10 +157,11 @@ def genetic_simulation_2(config_eos) -> GeneticSimulation:
ac = np.full(config_eos.prediction.hours, 0.0)
ac[20] = 1
simulation.set_akku_ac_charge_hours(ac)
simulation.ac_charge_hours = ac
dc = np.full(config_eos.prediction.hours, 0.0)
dc[11] = 1
simulation.set_akku_dc_charge_hours(dc)
simulation.dc_charge_hours = dc
simulation.home_appliance_start_hour = 2
return simulation
@@ -242,26 +242,26 @@ def test_simulation(genetic_simulation_2):
)
# Verfify DC and AC Charge Bins
assert abs(result["akku_soc_pro_stunde"][2] - 44.70681818181818) < 1e-5, (
"'akku_soc_pro_stunde[2]' should be 44.70681818181818."
assert abs(result["akku_soc_pro_stunde"][2] - 80.0) < 1e-5, (
"'akku_soc_pro_stunde[2]' should be 80.0."
)
assert abs(result["akku_soc_pro_stunde"][10] - 10.0) < 1e-5, (
"'akku_soc_pro_stunde[10]' should be 10."
assert abs(result["akku_soc_pro_stunde"][10] - 80.0) < 1e-5, (
"'akku_soc_pro_stunde[10]' should be 80."
)
assert abs(result["Netzeinspeisung_Wh_pro_Stunde"][10] - 3946.93) < 1e-3, (
"'Netzeinspeisung_Wh_pro_Stunde[11]' should be 3946.93."
)
assert abs(result["Netzeinspeisung_Wh_pro_Stunde"][11] - 0.0) < 1e-3, (
"'Netzeinspeisung_Wh_pro_Stunde[11]' should be 0.0."
assert abs(result["Netzeinspeisung_Wh_pro_Stunde"][11] - 2799.7263636361786) < 1e-3, (
"'Netzeinspeisung_Wh_pro_Stunde[11]' should be 2799.7263636361786."
)
assert abs(result["akku_soc_pro_stunde"][20] - 10) < 1e-5, (
"'akku_soc_pro_stunde[20]' should be 10."
assert abs(result["akku_soc_pro_stunde"][20] - 100) < 1e-5, (
"'akku_soc_pro_stunde[20]' should be 100."
)
assert abs(result["Last_Wh_pro_Stunde"][20] - 6050.98) < 1e-3, (
"'Last_Wh_pro_Stunde[20]' should be 6050.98."
assert abs(result["Last_Wh_pro_Stunde"][20] - 1050.98) < 1e-3, (
"'Last_Wh_pro_Stunde[20]' should be 1050.98."
)
print("All tests passed successfully.")
@@ -280,46 +280,6 @@ def test_set_parameters(genetic_simulation_2):
)
def test_set_akku_discharge_hours(genetic_simulation_2):
"""Test the set_akku_discharge_hours method of EnergyManagement."""
simulation = genetic_simulation_2
discharge_hours = np.full(simulation.prediction_hours, 1.0)
simulation.set_akku_discharge_hours(discharge_hours)
assert np.array_equal(simulation.battery.discharge_array, discharge_hours), (
"Discharge hours should be set correctly"
)
def test_set_akku_ac_charge_hours(genetic_simulation_2):
"""Test the set_akku_ac_charge_hours method of EnergyManagement."""
simulation = genetic_simulation_2
ac_charge_hours = np.full(simulation.prediction_hours, 1.0)
simulation.set_akku_ac_charge_hours(ac_charge_hours)
assert np.array_equal(simulation.ac_charge_hours, ac_charge_hours), (
"AC charge hours should be set correctly"
)
def test_set_akku_dc_charge_hours(genetic_simulation_2):
"""Test the set_akku_dc_charge_hours method of EnergyManagement."""
simulation = genetic_simulation_2
dc_charge_hours = np.full(simulation.prediction_hours, 1.0)
simulation.set_akku_dc_charge_hours(dc_charge_hours)
assert np.array_equal(simulation.dc_charge_hours, dc_charge_hours), (
"DC charge hours should be set correctly"
)
def test_set_ev_charge_hours(genetic_simulation_2):
"""Test the set_ev_charge_hours method of EnergyManagement."""
simulation = genetic_simulation_2
ev_charge_hours = np.full(simulation.prediction_hours, 1.0)
simulation.set_ev_charge_hours(ev_charge_hours)
assert np.array_equal(simulation.ev_charge_hours, ev_charge_hours), (
"EV charge hours should be set correctly"
)
def test_reset(genetic_simulation_2):
"""Test the reset method of EnergyManagement."""
simulation = genetic_simulation_2

View File

@@ -2,14 +2,14 @@
"ac_charge": [
0.0,
0.0,
0.875,
0.0,
0.875,
0.0,
0.625,
0.75,
0.0,
0.375,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
@@ -50,16 +50,16 @@
0.0
],
"dc_charge": [
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
1.0,
1.0,
1.0,
@@ -103,9 +103,9 @@
0,
0,
0,
1,
0,
1,
0,
0,
0,
0,
0,
@@ -476,7 +476,6 @@
0.0
],
"akku_soc_pro_stunde": [
80.0,
80.0,
79.91107093663912,
79.91107093663912,
@@ -504,7 +503,7 @@
76.64231728537023,
77.71252293120729,
81.22045681594867,
87.86517878095492,
81.61517878095492,
100.0,
100.0,
100.0,
@@ -513,6 +512,7 @@
100.0,
100.0,
100.0,
96.84060778236915,
96.84060778236915
],
"Electricity_price": [
@@ -558,108 +558,108 @@
},
"eauto_obj": {
"device_id": "ev1",
"hours": 48,
"charge_array": [
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0
],
"discharge_array": [
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"discharging_efficiency": 1.0,
"hours": 48,
"capacity_wh": 60000,
"charging_efficiency": 0.95,
"max_charge_power_w": 11040,
@@ -717,4 +717,4 @@
5.0
],
"washingstart": null
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -3,13 +3,6 @@
0.0,
0.0,
0.0,
1.0,
1.0,
0.75,
0.0,
0.0,
0.0,
0.5,
0.0,
0.0,
0.0,
@@ -18,7 +11,14 @@
0.0,
0.0,
0.0,
0.5,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
@@ -50,16 +50,16 @@
0.0
],
"dc_charge": [
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
1.0,
1.0,
1.0,
@@ -101,7 +101,9 @@
],
"discharge_allowed": [
0,
1,
0,
0,
0,
0,
0,
0,
@@ -109,36 +111,12 @@
0,
0,
1,
0,
1,
1,
1,
0,
0,
0,
1,
1,
0,
1,
1,
0,
1,
1,
1,
1,
1,
1,
0,
1,
1,
0,
1,
1,
0,
1,
1,
1,
1,
0,
0,
1,
@@ -147,69 +125,91 @@
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1
],
"eautocharge_hours_float": [
0.5,
1.0,
0.625,
0.0,
1.0,
0.375,
0.375,
0.875,
0.0,
0.0,
0.375,
0.625,
0.375,
0.875,
1.0,
0.875,
0.375,
0.75,
1.0,
0.625,
0.625,
0.75,
0.375,
1.0,
0.375,
0.375,
1.0,
1.0,
0.0,
0.0,
0.375,
0.625,
0.5,
0.5,
0.375,
1.0,
0.875,
0.625,
0.625,
0.0,
0.0,
0.75,
0.375,
0.75,
0.0,
0.5,
0.375,
0.0,
0.0,
0.5,
0.5,
1.0,
0.625,
0.5,
0.5,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.375,
0.0,
0.0,
0.0,
0.375,
0.0,
0.0,
0.625,
0.0,
0.0,
0.0,
0.0,
0.0
0.875,
1.0
],
"result": {
"Last_Wh_pro_Stunde": [
4986.07,
1063.91,
1320.56,
8876.029999999999,
8907.67,
7731.82,
6460.22,
6347.78,
3629.12,
7618.91,
5253.5599999999995,
12809.029999999999,
14151.67,
10353.82,
5149.22,
8969.78,
2177.92,
1178.71,
1050.98,
988.56,
@@ -226,14 +226,14 @@
1141.98,
1056.97,
992.46,
5088.99,
1155.99,
827.01,
1257.98,
1232.67,
4804.26,
871.26,
860.88,
1158.03,
7777.72,
1222.72,
1221.04,
949.99,
987.01,
@@ -243,42 +243,42 @@
"EAuto_SoC_pro_Stunde": [
5.0,
11.555,
11.555,
11.555,
20.294999999999998,
22.48,
29.035,
39.96,
48.699999999999996,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
63.995000000000005,
63.995000000000005,
63.995000000000005,
63.995000000000005,
70.55,
70.55,
70.55,
81.475,
81.475,
81.475,
81.475,
81.475
44.330000000000005,
61.809999999999995,
77.105,
83.66,
96.77,
98.518,
98.518,
98.518,
98.518,
98.518,
98.518,
98.518,
98.518,
98.518,
98.518,
98.518,
98.518,
98.518,
98.518,
98.518,
98.518,
98.518,
98.518,
98.518,
98.518,
98.518,
98.518,
98.518,
98.518,
98.518,
98.518,
98.518,
98.518,
98.518
],
"Einnahmen_Euro_pro_Stunde": [
0.0,
@@ -320,10 +320,10 @@
0.0,
0.0
],
"Gesamt_Verluste": 7755.845910804702,
"Gesamtbilanz_Euro": 4.690157296412734,
"Gesamt_Verluste": 7633.823819992856,
"Gesamtbilanz_Euro": 7.648978330847156,
"Gesamteinnahmen_Euro": 0.0,
"Gesamtkosten_Euro": 4.690157296412734,
"Gesamtkosten_Euro": 7.648978330847156,
"Home_appliance_wh_per_hour": [
0.0,
0.0,
@@ -366,83 +366,83 @@
],
"Kosten_Euro_pro_Stunde": [
0.0,
0.48125599199999997,
0.8679294259999999,
2.1885351859999997,
1.4948178300000001,
0.9688838999999999,
0.0,
0.0,
1.4495244859999996,
0.53097063,
0.44343509999999997,
0.0,
0.0,
0.8107800974767518,
0.0,
0.0,
0.291163892,
1.3510631400000002,
0.07038454500000005,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.182970359,
0.0,
0.0,
0.26411047,
0.0,
0.0,
0.0,
0.0,
0.0,
0.12044799000000005,
0.08545095,
0.007989913613567745,
0.0,
0.002459704740224363,
0.0,
0.0,
0.05016012000000004,
0.0076430797975209205,
0.0,
0.31687880399999996,
0.012219458233588571,
0.0,
0.0,
0.0,
0.16722497978466921,
0.16484566
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0
],
"Netzbezug_Wh_pro_Stunde": [
0.0,
2175.66,
4146.82,
11647.339999999998,
8132.85,
4834.75,
0.0,
0.0,
7714.339999999998,
2888.8500000000004,
2212.75,
0.0,
0.0,
2705.305630553059,
0.0,
0.0,
980.68,
5951.820000000001,
234.85000000000014,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
556.31,
0.0,
0.0,
799.85,
0.0,
0.0,
0.0,
0.0,
0.0,
395.9500000000001,
351.65,
35.04348076126204,
0.0,
11.752053226107805,
0.0,
0.0,
250.30000000000018,
34.77288351920346,
0.0,
1057.3199999999997,
55.24167375040041,
0.0,
0.0,
0.0,
572.4922279516235,
592.97
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0
],
"Netzeinspeisung_Wh_pro_Stunde": [
0.0,
@@ -486,83 +486,83 @@
],
"Verluste_Pro_Stunde": [
760.062272727273,
2.817272727272737,
29.157272727272726,
276.0,
276.0,
345.0,
615.5918181818183,
730.0663636363638,
373.0373243336329,
945.0,
207.0,
483.0,
552.0,
483.0,
367.81909090909085,
414.0,
55.200000000000045,
23.391818181818195,
99.72409090909093,
0.0,
133.72909090909081,
124.41545454545451,
96.08318181818186,
70.41409090909087,
118.37045454545455,
94.68272727272722,
83.01681818181817,
0.0,
75.86045454545456,
66.66681818181814,
69.12409090909085,
109.0704545454546,
55.96909090909088,
0.0,
109.96227272727276,
47.952272727272714,
11.233982308648535,
682.1181818181817,
160.0271308670193,
48.41330768174522,
161.62968357967037,
21.962728535423857,
538.2984000000038,
207.0,
255.8276539776955,
441.95211196761403,
260.56941082122324,
171.99990368477063,
1026.818181818182,
62.214291413756285,
35.132727272727266,
77.27590909090907,
134.59227272727276,
22.022423461142267,
0.0
100.08954545454549,
80.85954545454547
],
"akku_soc_pro_stunde": [
80.0,
62.54222623966943,
62.45329717630854,
61.532928719008275,
61.532928719008275,
61.532928719008275,
61.532928719008275,
50.81349001377411,
36.480587121212125,
46.842735019368604,
46.10435692019505,
42.95650051523637,
42.95650051523637,
39.029245005594504,
35.996316286586236,
33.77364927556696,
30.03720815986448,
27.048485708073848,
24.428005336173022,
24.428005336173022,
22.32362344912068,
20.141676135071094,
20.141676135071094,
16.670644798982938,
15.156999826531148,
15.469054890660274,
0.471637535288375,
4.030157048585656,
4.180158754905081,
19.132892088236673,
19.132892088236673,
26.239215809839333,
30.01393669097958,
8.49189812348647,
7.382910520180684,
4.9436457130181495,
0.6951522557178741,
0.0
43.60283230027549,
43.60283230027549,
43.60283230027549,
43.60283230027549,
43.60283230027549,
38.52647210743802,
38.52647210743802,
38.52647210743802,
37.78809400826446,
34.64023760330579,
30.418991046831955,
26.49173553719008,
23.458806818181817,
21.236139807162534,
17.499698691460054,
14.510976239669422,
11.890495867768596,
9.495910812672175,
7.391528925619835,
5.209581611570248,
1.7667011019283745,
0.0,
0.0,
0.3120550641291261,
1.07020564583707,
4.578139530578446,
4.728141236897871,
19.68087457022947,
31.94341995234899,
38.90006700591099,
42.674787887051245,
43.17025540478875,
42.06126780148296,
39.622002994320425,
35.373509537020155,
32.214117319389295,
29.661732677516017
],
"Electricity_price": [
0.000228,
@@ -607,211 +607,211 @@
},
"eauto_obj": {
"device_id": "ev1",
"hours": 48,
"charge_array": [
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.375,
0.625,
0.375,
0.875,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0
0.875,
0.375,
0.75,
0.1,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0
],
"discharge_array": [
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"discharging_efficiency": 1.0,
"hours": 48,
"capacity_wh": 60000,
"charging_efficiency": 0.95,
"max_charge_power_w": 11040,
"soc_wh": 48885.0,
"soc_wh": 59110.8,
"initial_soc_percentage": 5
},
"start_solution": [
14.0,
13.0,
0.0,
20.0,
20.0,
19.0,
18.0,
18.0,
5.0,
3.0,
9.0,
16.0,
12.0,
13.0,
8.0,
4.0,
0.0,
14.0,
11.0,
9.0,
16.0,
8.0,
9.0,
5.0,
10.0,
13.0,
13.0,
8.0,
8.0,
9.0,
5.0,
10.0,
7.0,
5.0,
20.0,
17.0,
15.0,
4.0,
12.0,
13.0,
8.0,
5.0,
1.0,
1.0,
4.0,
9.0,
2.0,
5.0,
8.0,
10.0,
12.0,
10.0,
9.0,
13.0,
7.0,
8.0,
7.0,
9.0,
13.0,
7.0,
10.0,
8.0,
8.0,
12.0,
2.0,
9.0,
12.0,
7.0,
10.0,
13.0,
11.0,
11.0,
10.0,
11.0,
10.0,
13.0,
10.0,
10.0,
12.0,
2.0,
6.0,
3.0,
0.0,
6.0,
1.0,
12.0,
9.0,
12.0,
13.0,
10.0,
13.0,
11.0,
2.0,
1.0,
5.0,
0.0,
0.0,
1.0,
3.0,
1.0,
5.0,
6.0,
5.0,
1.0,
4.0,
6.0,
3.0,
3.0,
4.0,
1.0,
6.0,
1.0,
1.0,
6.0,
6.0,
0.0,
0.0,
1.0,
3.0,
2.0,
2.0,
1.0,
6.0,
5.0,
3.0,
3.0,
0.0,
0.0,
4.0,
1.0,
4.0,
0.0,
2.0,
1.0,
0.0,
0.0,
2.0,
2.0,
6.0,
3.0,
2.0,
2.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
3.0,
0.0,
0.0,
0.0,
0.0,
0.0,
5.0,
6.0,
13.0
],
"washingstart": 13