optimization states for AC, DC and IDLE now similar probab. Also AC states taken from config. Maybe a single config option for AC and E-Auto States is sensefull. (#242)

* optimization states for AC, DC and IDLE now similar probab. Also AC states taken from config. Maybe a single config option for AC and E-Auto States is sensefull.
 * test_class_optimize: Update testdata
 * Write pdf and json to test/testdata/new.... so it can be analyzed
   manually or just copied as new expected result.
 * workflow: Upload pytest optimization result artifacts (pdf, json)
This commit is contained in:
Andreas 2024-12-15 15:32:58 +01:00 committed by GitHub
parent aa334d0b61
commit 763926d8e8
8 changed files with 813 additions and 865 deletions

View File

@ -27,3 +27,9 @@ jobs:
run: |
pip install -e .
python -m pytest --full-run -vs --cov src --cov-report term-missing
- name: Upload test artifacts
uses: actions/upload-artifact@v4
with:
name: optimize-results
path: tests/testdata/new_optimize_result*

1
.gitignore vendored
View File

@ -259,3 +259,4 @@ visualize_output_*.pdf
# Test files
openapi-new.json
tests/testdata/new_optimize_result*

View File

@ -3161,7 +3161,7 @@
"eauto_obj"
],
"title": "OptimizeResponse",
"description": "**Note**: The first value of \"Last_Wh_pro_Stunde\", \"Netzeinspeisung_Wh_pro_Stunde\" and \"Netzbezug_Wh_pro_Stunde\", will be set to null in the JSON output and represented as NaN or None in the corresponding classes' data returns. This approach is adopted to ensure that the current hour's processing remains unchanged."
"description": "**Note**: The first value of \"Last_Wh_per_hour\", \"Netzeinspeisung_Wh_per_hour\", and \"Netzbezug_Wh_per_hour\", will be set to null in the JSON output and represented as NaN or None in the corresponding classes' data returns. This approach is adopted to ensure that the current hour's processing remains unchanged."
},
"PVAkkuParameters": {
"properties": {

View File

@ -42,7 +42,7 @@ class OptimizationParameters(BaseModel):
def validate_list_length(self) -> Self:
arr_length = len(self.ems.pv_prognose_wh)
if self.temperature_forecast is not None and arr_length != len(self.temperature_forecast):
raise ValueError("Input lists have different lenghts")
raise ValueError("Input lists have different lengths")
return self
@field_validator("start_solution")
@ -55,7 +55,7 @@ class OptimizationParameters(BaseModel):
class OptimizeResponse(BaseModel):
"""**Note**: The first value of "Last_Wh_pro_Stunde", "Netzeinspeisung_Wh_pro_Stunde" and "Netzbezug_Wh_pro_Stunde", will be set to null in the JSON output and represented as NaN or None in the corresponding classes' data returns. This approach is adopted to ensure that the current hour's processing remains unchanged."""
"""**Note**: The first value of "Last_Wh_per_hour", "Netzeinspeisung_Wh_per_hour", and "Netzbezug_Wh_per_hour", will be set to null in the JSON output and represented as NaN or None in the corresponding classes' data returns. This approach is adopted to ensure that the current hour's processing remains unchanged."""
ac_charge: list[float] = Field(
description="Array with AC charging values as relative power (0-1), other values set to 0."
@ -119,114 +119,82 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
def decode_charge_discharge(
self, discharge_hours_bin: list[float]
) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
"""Decode the input array `discharge_hours_bin` into three separate arrays for AC charging, DC charging, and discharge.
The function maps AC and DC charging values to relative power levels (0 to 1), while the discharge remains binary (0 or 1).
Parameters:
- discharge_hours_bin (np.ndarray): Input array with integer values representing the different states.
The states are:
0: No action ("idle")
1: Discharge ("discharge")
2-6: AC charging with different power levels ("ac_charge")
7-8: DC charging Dissallowed/allowed ("dc_charge")
Returns:
- ac_charge (np.ndarray): Array with AC charging values as relative power (0-1), other values set to 0.
- dc_charge (np.ndarray): Array with DC charging values as relative power (0-1), other values set to 0.
- discharge (np.ndarray): Array with discharge values (1 for discharge, 0 otherwise).
"""
# Convert the input list to a NumPy array, if it's not already
"""Decode the input array into ac_charge, dc_charge, and discharge arrays."""
discharge_hours_bin_np = np.array(discharge_hours_bin)
len_ac = len(self.config.optimization_ev_available_charge_rates_percent)
# Create ac_charge array: Only consider values between 2 and 6 (AC charging power levels), set the rest to 0
ac_charge = np.where(
(discharge_hours_bin_np >= 2) & (discharge_hours_bin_np <= 6),
discharge_hours_bin_np - 1,
0,
)
ac_charge = ac_charge / 5.0 # Normalize AC charge to range between 0 and 1
# Categorization:
# Idle: 0 .. len_ac-1
# Discharge: len_ac .. 2*len_ac - 1
# AC Charge: 2*len_ac .. 3*len_ac - 1
# DC optional: 3*len_ac (not allowed), 3*len_ac + 1 (allowed)
# Create dc_charge array: 7 = Not allowed (mapped to 0), 8 = Allowed (mapped to 1)
# Create dc_charge array: Only if DC charge optimization is enabled
# Idle has no charge, Discharge has binary 1, AC Charge has corresponding values
# Idle states
idle_mask = (discharge_hours_bin_np >= 0) & (discharge_hours_bin_np < len_ac)
# Discharge states
discharge_mask = (discharge_hours_bin_np >= len_ac) & (discharge_hours_bin_np < 2 * len_ac)
# AC states
ac_mask = (discharge_hours_bin_np >= 2 * len_ac) & (discharge_hours_bin_np < 3 * len_ac)
ac_indices = discharge_hours_bin_np[ac_mask] - 2 * len_ac
# DC states (if enabled)
if self.optimize_dc_charge:
dc_charge = np.where(discharge_hours_bin_np == 8, 1, 0)
dc_not_allowed_state = 3 * len_ac
dc_allowed_state = 3 * len_ac + 1
dc_charge = np.where(discharge_hours_bin_np == dc_allowed_state, 1, 0)
else:
dc_charge = np.ones_like(
discharge_hours_bin_np
) # Set DC charge to 0 if optimization is disabled
dc_charge = np.ones_like(discharge_hours_bin_np, dtype=float)
# Create discharge array: Only consider value 1 (Discharge), set the rest to 0 (binary output)
discharge = np.where(discharge_hours_bin_np == 1, 1, 0)
# Generate the result arrays
discharge = np.zeros_like(discharge_hours_bin_np, dtype=int)
discharge[discharge_mask] = 1 # Set Discharge states to 1
ac_charge = np.zeros_like(discharge_hours_bin_np, dtype=float)
ac_charge[ac_mask] = [
self.config.optimization_ev_available_charge_rates_percent[i] for i in ac_indices
]
# Idle is just 0, already default.
return ac_charge, dc_charge, discharge
# Custom mutation function that applies type-specific mutations
def mutate(self, individual: list[int]) -> tuple[list[int]]:
"""Custom mutation function for the individual.
"""Custom mutation function for the individual."""
# Calculate the number of states
len_ac = len(self.config.optimization_ev_available_charge_rates_percent)
if self.optimize_dc_charge:
total_states = 3 * len_ac + 2
else:
total_states = 3 * len_ac
This function mutates different parts of the individual:
- Mutates the discharge and charge states (AC, DC, idle) using the split_charge_discharge method.
- Mutates the EV charging schedule if EV optimization is enabled.
- Mutates appliance start times if household appliances are part of the optimization.
Parameters:
- individual (list): The individual being mutated, which includes different optimization parameters.
Returns:
- (tuple): The mutated individual as a tuple (required by DEAP).
"""
# Step 1: Mutate the charge/discharge states (idle, discharge, AC charge, DC charge)
# Extract the relevant part of the individual for prediction hours, which represents the charge/discharge behavior.
# 1. Mutating the charge_discharge part
charge_discharge_part = individual[: self.config.prediction_hours]
# Apply the mutation to the charge/discharge part
(charge_discharge_mutated,) = self.toolbox.mutate_charge_discharge(charge_discharge_part)
# Ensure that no invalid states are introduced during mutation (valid values: 0-8)
if self.optimize_dc_charge:
charge_discharge_mutated = np.clip(charge_discharge_mutated, 0, 8)
else:
charge_discharge_mutated = np.clip(charge_discharge_mutated, 0, 6)
# Use split_charge_discharge to split the mutated array into AC charge, DC charge, and discharge components
# ac_charge, dc_charge, discharge = self.split_charge_discharge(charge_discharge_mutated)
# Optionally: You can process the split arrays further if needed, for example,
# applying additional constraints or penalties, or keeping track of charging limits.
# Reassign the mutated values back to the individual
# Instead of a fixed clamping to 0..8 or 0..6 dynamically:
charge_discharge_mutated = np.clip(charge_discharge_mutated, 0, total_states - 1)
individual[: self.config.prediction_hours] = charge_discharge_mutated
# Step 2: Mutate EV charging schedule if enabled
# 2. Mutating the EV charge part, if active
if self.optimize_ev:
# Extract the relevant part for EV charging schedule
ev_charge_part = individual[
self.config.prediction_hours : self.config.prediction_hours * 2
]
# Apply mutation on the EV charging schedule
(ev_charge_part_mutated,) = self.toolbox.mutate_ev_charge_index(ev_charge_part)
# Ensure the EV does not charge during fixed hours (set those hours to 0)
ev_charge_part_mutated[self.config.prediction_hours - self.fixed_eauto_hours :] = [
0
] * self.fixed_eauto_hours
# Reassign the mutated EV charging part back to the individual
individual[self.config.prediction_hours : self.config.prediction_hours * 2] = (
ev_charge_part_mutated
)
# Step 3: Mutate appliance start times if household appliances are part of the optimization
# 3. Mutating the appliance start time, if applicable
if self.opti_param["home_appliance"] > 0:
# Extract the appliance part (typically a single value for the start hour)
appliance_part = [individual[-1]]
# Apply mutation on the appliance start hour
(appliance_part_mutated,) = self.toolbox.mutate_hour(appliance_part)
# Reassign the mutated appliance part back to the individual
individual[-1] = appliance_part_mutated[0]
return (individual,)
@ -278,62 +246,67 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
"""Set up the DEAP environment with fitness and individual creation rules."""
self.opti_param = opti_param
# Remove existing FitnessMin and Individual classes from creator if present
# Remove existing definitions if any
for attr in ["FitnessMin", "Individual"]:
if attr in creator.__dict__:
del creator.__dict__[attr]
# Create new FitnessMin and Individual classes
creator.create("FitnessMin", base.Fitness, weights=(-1.0,))
creator.create("Individual", list, fitness=creator.FitnessMin)
# Initialize toolbox with attributes and operations
self.toolbox = base.Toolbox()
if self.optimize_dc_charge:
self.toolbox.register("attr_discharge_state", random.randint, 0, 8)
else:
self.toolbox.register("attr_discharge_state", random.randint, 0, 6)
len_ac = len(self.config.optimization_ev_available_charge_rates_percent)
# Total number of states without DC:
# Idle: len_ac states
# Discharge: len_ac states
# AC-Charge: len_ac states
# Total without DC: 3 * len_ac
# With DC: + 2 states
if self.optimize_dc_charge:
total_states = 3 * len_ac + 2
else:
total_states = 3 * len_ac
# State space: 0 .. (total_states - 1)
self.toolbox.register("attr_discharge_state", random.randint, 0, total_states - 1)
# EV attributes
if self.optimize_ev:
self.toolbox.register(
"attr_ev_charge_index",
random.randint,
0,
len(self.config.optimization_ev_available_charge_rates_percent) - 1,
len_ac - 1,
)
# Household appliance start time
self.toolbox.register("attr_int", random.randint, start_hour, 23)
# Register individual creation function
self.toolbox.register("individual", self.create_individual)
# Register population, mating, mutation, and selection functions
self.toolbox.register("population", tools.initRepeat, list, self.toolbox.individual)
self.toolbox.register("mate", tools.cxTwoPoint)
# self.toolbox.register("mutate", tools.mutFlipBit, indpb=0.1)
# Register separate mutation functions for each type of value:
# - Discharge state mutation (-5, 0, 1)
if self.optimize_dc_charge:
self.toolbox.register(
"mutate_charge_discharge", tools.mutUniformInt, low=0, up=8, indpb=0.2
)
else:
self.toolbox.register(
"mutate_charge_discharge", tools.mutUniformInt, low=0, up=6, indpb=0.2
)
# - Float mutation for EV charging values
# Mutation operator for charge/discharge states
self.toolbox.register(
"mutate_charge_discharge", tools.mutUniformInt, low=0, up=total_states - 1, indpb=0.2
)
# Mutation operator for EV states
self.toolbox.register(
"mutate_ev_charge_index",
tools.mutUniformInt,
low=0,
up=len(self.config.optimization_ev_available_charge_rates_percent) - 1,
up=len_ac - 1,
indpb=0.2,
)
# - Start hour mutation for household devices
# Mutation for household appliance
self.toolbox.register("mutate_hour", tools.mutUniformInt, low=start_hour, up=23, indpb=0.2)
# Register custom mutation function
# Custom mutate function remains unchanged
self.toolbox.register("mutate", self.mutate)
self.toolbox.register("select", tools.selTournament, tournsize=3)
def evaluate_inner(self, individual: list[float]) -> dict[str, Any]:

View File

@ -37,10 +37,7 @@ def compare_dict(actual: dict[str, Any], expected: dict[str, Any]):
("optimize_input_2.json", "optimize_result_2_full.json", 400),
],
)
@patch("akkudoktoreos.optimization.genetic.visualisiere_ergebnisse")
def test_optimize(
visualisiere_ergebnisse_patch, fn_in: str, fn_out: str, ngen: int, is_full_run: bool
):
def test_optimize(fn_in: str, fn_out: str, ngen: int, is_full_run: bool):
"""Test optimierung_ems."""
# Assure configuration holds the correct values
config_eos = get_config()
@ -52,8 +49,12 @@ def test_optimize(
input_data = OptimizationParameters(**json.load(f_in))
file = DIR_TESTDATA / fn_out
with file.open("r") as f_out:
expected_result = OptimizeResponse(**json.load(f_out))
# In case a new test case is added, we don't want to fail here, so the new output is written to disk before
try:
with file.open("r") as f_out:
expected_result = OptimizeResponse(**json.load(f_out))
except FileNotFoundError:
pass
opt_class = optimization_problem(fixed_seed=42)
start_hour = 10
@ -61,15 +62,34 @@ def test_optimize(
if ngen > 10 and not is_full_run:
pytest.skip()
# Call the optimization function
ergebnis = opt_class.optimierung_ems(parameters=input_data, start_hour=start_hour, ngen=ngen)
# with open(f"new_{fn_out}", "w") as f_out:
# f_out.write(ergebnis.model_dump_json(indent=4, exclude_unset=True))
visualize_filename = str((DIR_TESTDATA / f"new_{fn_out}").with_suffix(".pdf"))
# Assert that the output contains all expected entries.
# This does not assert that the optimization always gives the same result!
# Reproducibility and mathematical accuracy should be tested on the level of individual components.
compare_dict(ergebnis.model_dump(), expected_result.model_dump())
def visualize_to_file(*args, **kwargs):
from akkudoktoreos.visualize import visualisiere_ergebnisse
# The function creates a visualization result PDF as a side-effect.
visualisiere_ergebnisse_patch.assert_called_once()
# Write test output pdf to file, so we can look at it manually
kwargs["filename"] = visualize_filename
return visualisiere_ergebnisse(*args, **kwargs)
with patch(
"akkudoktoreos.optimization.genetic.visualisiere_ergebnisse", side_effect=visualize_to_file
) as visualisiere_ergebnisse_patch:
# Call the optimization function
ergebnis = opt_class.optimierung_ems(
parameters=input_data, start_hour=start_hour, ngen=ngen
)
# Write test output to file, so we can take it as new data on intended change
with open(DIR_TESTDATA / f"new_{fn_out}", "w") as f_out:
f_out.write(ergebnis.model_dump_json(indent=4, exclude_unset=True))
assert ergebnis.result.Gesamtbilanz_Euro == pytest.approx(
expected_result.result.Gesamtbilanz_Euro
)
# Assert that the output contains all expected entries.
# This does not assert that the optimization always gives the same result!
# Reproducibility and mathematical accuracy should be tested on the level of individual components.
compare_dict(ergebnis.model_dump(), expected_result.model_dump())
# The function creates a visualization result PDF as a side-effect.
visualisiere_ergebnisse_patch.assert_called_once()

View File

@ -1,5 +1,24 @@
{
"ac_charge": [
0.75,
0.75,
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.75,
0.0,
0.0,
0.0,
@ -20,26 +39,7 @@
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.875,
0.0,
0.0,
0.0,
@ -100,30 +100,21 @@
1.0
],
"discharge_allowed": [
1,
1,
1,
1,
0,
0,
1,
0,
1,
0,
1,
1,
1,
0,
1,
0,
1,
1,
0,
1,
0,
1,
0,
1,
0,
1,
0,
1,
0,
0,
@ -132,22 +123,31 @@
0,
0,
0,
0,
0,
1,
1,
0,
1,
1,
0,
0,
1,
0,
1,
0,
0,
0,
1,
0,
0,
0,
1,
0,
1,
0,
1,
0,
1,
0,
1,
0,
1,
0
1
],
"eautocharge_hours_float": null,
"result": {
@ -237,7 +237,7 @@
0.0,
0.0,
0.0,
0.19546715971074372,
0.212927386983471,
0.19275619999999996,
0.1339926,
0.0569765,
@ -260,7 +260,7 @@
0.0,
0.0,
0.0,
0.19167938450413202,
0.1512260012396691,
0.257789,
0.1516669,
0.09915009999999999,
@ -271,10 +271,10 @@
0.0,
0.0
],
"Gesamt_Verluste": 1859.6205371900821,
"Gesamtbilanz_Euro": 1.3505190567851246,
"Gesamteinnahmen_Euro": 1.3143154442148755,
"Gesamtkosten_Euro": 2.664834501,
"Gesamt_Verluste": 2071.900103305785,
"Gesamtbilanz_Euro": 0.9349588927768602,
"Gesamteinnahmen_Euro": 1.2913222882231399,
"Gesamtkosten_Euro": 2.226281181,
"Home_appliance_wh_per_hour": [
null,
null,
@ -317,8 +317,8 @@
],
"Kosten_Euro_pro_Stunde": [
0.0,
0.004569992000000018,
0.0,
0.04475252599999999,
0.0,
0.0,
0.0,
@ -326,16 +326,16 @@
0.0,
0.0,
0.05480703000000003,
0.0,
0.225316611,
0.291163892,
0.0,
0.26650619799999997,
0.19588158,
0.174739608,
0.0,
0.0,
0.28801899,
0.22802125600000003,
0.199865757,
0.182970359,
0.162995926,
0.0,
0.0,
0.16677339,
0.26411047,
0.0,
@ -350,15 +350,15 @@
0.0,
0.0,
0.08231598,
0.174597189,
0.0,
0.293043269,
0.0,
0.16484566
0.0
],
"Netzbezug_Wh_pro_Stunde": [
0.0,
20.660000000000082,
0.0,
213.81999999999994,
0.0,
0.0,
0.0,
@ -366,16 +366,16 @@
0.0,
0.0,
171.54000000000008,
0.0,
731.31,
980.68,
0.0,
912.38,
704.61,
516.37,
0.0,
0.0,
868.05,
694.34,
608.79,
556.31,
488.89,
0.0,
0.0,
506.91,
799.85,
0.0,
@ -390,10 +390,10 @@
0.0,
0.0,
257.64,
566.69,
0.0,
987.01,
0.0,
592.97
0.0
],
"Netzeinspeisung_Wh_pro_Stunde": [
0.0,
@ -401,7 +401,7 @@
0.0,
0.0,
0.0,
2792.3879958677676,
3041.819814049586,
2753.66,
1914.18,
813.95,
@ -424,7 +424,7 @@
0.0,
0.0,
0.0,
2738.2769214876007,
2160.371446280987,
3682.7,
2166.67,
1416.43,
@ -437,20 +437,11 @@
],
"Verluste_Pro_Stunde": [
16.744090909090914,
2.817272727272737,
0.0,
29.157272727272726,
3.5592000000000112,
582.6179999999995,
185.98344049586785,
0.0,
0.0,
0.0,
0.0,
99.72409090909093,
0.0,
124.41545454545451,
0.0,
70.41409090909087,
156.0516223140496,
0.0,
0.0,
0.0,
@ -458,62 +449,71 @@
0.0,
0.0,
0.0,
0.0,
0.0,
118.37045454545455,
94.68272727272722,
0.0,
75.86045454545456,
66.66681818181814,
0.0,
0.0,
109.96227272727276,
0.0,
15.439199999999985,
53.855999999999995,
159.6443999999999,
21.032399999999996,
209.70516942148788,
279.0538264462814,
0.0,
0.0,
0.0,
0.0,
0.0,
77.27590909090907,
0.0,
134.59227272727276,
100.08954545454549,
0.0
80.85954545454547
],
"akku_soc_pro_stunde": [
79.4714617768595,
79.4714617768595,
78.55109331955923,
78.6499599862259,
94.83379331955922,
100.0,
100.0,
100.0,
100.0,
100.0,
96.85214359504131,
96.85214359504131,
92.92488808539943,
92.92488808539943,
90.70222107438015,
90.70222107438015,
90.70222107438015,
90.70222107438015,
90.70222107438015,
90.70222107438015,
90.70222107438015,
90.70222107438015,
87.231189738292,
87.231189738292,
87.66005640495867,
89.15605640495866,
93.59062307162533,
94.17485640495867,
79.38253271349862,
79.38253271349862,
79.48139938016529,
95.66523271349861,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
97.56073519283747,
97.56073519283747,
94.40134297520663,
94.40134297520663
100.0,
100.0,
100.0,
100.0,
96.26355888429752,
93.27483643250687,
93.27483643250687,
90.88025137741046,
88.7758694903581,
88.7758694903581,
88.7758694903581,
85.30483815426996,
85.30483815426996,
85.73370482093662,
87.22970482093662,
91.66427148760329,
92.24850482093663,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
95.75150654269973,
92.59211432506888,
90.0397296831956
]
},
"eauto_obj": {
@ -626,106 +626,54 @@
"start_soc_prozent": 54
},
"start_solution": [
1.0,
1.0,
1.0,
1.0,
18.0,
18.0,
9.0,
13.0,
4.0,
7.0,
9.0,
8.0,
0.0,
12.0,
10.0,
10.0,
14.0,
8.0,
7.0,
11.0,
6.0,
4.0,
18.0,
3.0,
4.0,
3.0,
5.0,
14.0,
14.0,
10.0,
13.0,
3.0,
7.0,
11.0,
6.0,
14.0,
9.0,
14.0,
8.0,
3.0,
2.0,
5.0,
9.0,
19.0,
1.0,
0.0,
0.0,
1.0,
1.0,
1.0,
0.0,
1.0,
0.0,
1.0,
0.0,
1.0,
0.0,
1.0,
0.0,
1.0,
0.0,
1.0,
0.0,
1.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,
1.0,
0.0,
1.0,
0.0,
1.0,
0.0,
1.0,
0.0,
1.0,
0.0,
1.0,
0.0,
1.0,
0.0,
1.0,
0.0,
1.0,
0.0,
1.0,
0.0,
1.0,
0.0,
1.0,
0.0,
1.0,
0.0,
1.0,
0.0,
1.0,
0.0,
1.0,
0.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
6.0,
10.0,
4.0,
2.0,
7.0,
11.0,
10.0
],
"washingstart": null
}

View File

@ -2,50 +2,50 @@
"ac_charge": [
0.0,
0.0,
0.2,
0.4,
0.0,
0.4,
0.625,
0.0,
0.8,
1.0,
0.6,
0.0,
0.8,
1.0,
0.6,
1.0,
0.0,
0.4,
1.0,
0.8,
0.2,
0.0,
1.0,
0.8,
0.8,
0.4,
0.6,
0.2,
0.6,
0.2,
0.8,
0.2,
0.625,
0.0,
0.375,
0.0,
0.0,
0.75,
0.0,
0.75,
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.75,
0.0,
0.0,
1.0,
0.8,
0.4,
0.0,
1.0,
1.0,
0.2,
0.0,
1.0,
0.4,
0.6,
0.2,
1.0,
0.6,
0.0,
0.0
],
@ -100,6 +100,42 @@
1.0
],
"discharge_allowed": [
0,
0,
1,
0,
0,
1,
1,
1,
0,
1,
0,
1,
1,
0,
0,
0,
0,
1,
0,
1,
1,
1,
1,
1,
0,
1,
1,
0,
0,
0,
1,
1,
1,
0,
0,
0,
0,
0,
0,
@ -111,104 +147,68 @@
0,
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,
1,
1
0
],
"eautocharge_hours_float": [
0.0,
0.5,
0.0,
0.5,
0.375,
1.0,
0.875,
0.375,
0.5,
0.75,
1.0,
1.0,
0.875,
0.0,
1.0,
0.375,
0.875,
0.875,
0.75,
1.0,
1.0,
0.5,
0.625,
0.875,
0.75,
0.5,
0.0,
0.625,
0.5,
1.0,
1.0,
0.375,
0.375,
0.375,
0.75,
0.5,
1.0,
0.875,
0.875,
0.5,
0.75,
0.0,
0.875,
0.875,
0.5,
0.75,
0.75,
0.375,
0.75,
0.375,
1.0,
1.0,
0.625,
0.75,
0.5,
0.0,
1.0,
0.625,
0.875,
0.375,
1.0,
0.375,
0.625,
0.75,
0.75,
0.0,
0.5,
0.875,
0.875,
0.75,
0.875,
0.5,
0.875,
0.0,
0.0
0.375,
0.875,
1.0,
0.5
],
"result": {
"Last_Wh_pro_Stunde": [
11541.07,
8996.91,
14186.56,
17120.03,
14608.281570247937,
7731.82,
6460.22,
3041.7799999999997,
12105.07,
10240.91,
10497.56,
12748.03,
8907.67,
13981.82,
10393.22,
1730.78,
1129.12,
1178.71,
1050.98,
@ -232,7 +232,7 @@
1232.67,
871.26,
860.88,
1158.03,
4027.009545454555,
1222.72,
1221.04,
949.99,
@ -241,13 +241,13 @@
592.97
],
"EAuto_SoC_pro_Stunde": [
22.48,
29.035,
42.144999999999996,
59.62499999999999,
77.105,
88.03,
96.77,
20.294999999999998,
35.589999999999996,
50.885000000000005,
63.995000000000005,
72.735,
83.66,
98.955,
100.0,
100.0,
100.0,
@ -289,7 +289,6 @@
0.0,
0.0,
0.0,
0.0569765,
0.0,
0.0,
0.0,
@ -305,14 +304,15 @@
0.0,
0.0,
0.0,
0.009006199999999989,
0.03141599999999999,
0.0931259,
0.012268899999999998,
0.31400739999999994,
0.257789,
0.1516669,
0.09915009999999999,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0348376,
0.0,
0.0,
@ -320,17 +320,17 @@
0.0,
0.0
],
"Gesamt_Verluste": 5357.560661157026,
"Gesamtbilanz_Euro": 13.87138792561157,
"Gesamteinnahmen_Euro": 1.0602444999999998,
"Gesamtkosten_Euro": 14.93163242561157,
"Gesamt_Verluste": 8823.859090909093,
"Gesamtbilanz_Euro": 12.348447740818184,
"Gesamteinnahmen_Euro": 0.0348376,
"Gesamtkosten_Euro": 12.383285340818183,
"Home_appliance_wh_per_hour": [
0.0,
0.0,
0.0,
2500.0,
2500.0,
0.0,
2500.0,
2500.0,
0.0,
0.0,
0.0,
@ -365,29 +365,29 @@
0.0
],
"Kosten_Euro_pro_Stunde": [
1.2792601199999998,
1.759349592,
2.737606326,
2.9985720859999994,
1.5787430366115707,
0.44343509999999997,
0.547376732,
0.005407139999999934,
2.54785212,
0.928522392,
0.9189986259999999,
2.1770732859999997,
0.53097063,
1.6959351,
1.4118501319999999,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.05480703000000003,
0.225316611,
0.291163892,
0.26650619799999997,
0.19588158,
0.174739608,
0.28801899,
0.22802125600000003,
0.0,
0.0,
0.199865757,
0.182970359,
0.162995926,
0.16677339,
0.26411047,
0.24530383800000005,
0.0,
0.0,
0.0,
0.08545095,
0.0,
0.0,
@ -396,38 +396,38 @@
0.0,
0.0,
0.0,
0.0,
0.651258356818184,
0.0,
0.08231598,
0.174597189,
0.293043269,
0.0,
0.0
0.16484566
],
"Netzbezug_Wh_pro_Stunde": [
5610.789999999999,
7953.66,
13079.82,
15958.339999999998,
8589.461570247937,
2212.75,
2490.34,
23.81999999999971,
11174.789999999999,
4197.66,
4390.82,
11586.34,
2888.8500000000004,
8462.75,
6423.339999999999,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
171.54000000000008,
731.31,
980.68,
912.38,
704.61,
516.37,
868.05,
694.34,
0.0,
0.0,
608.79,
556.31,
488.89,
506.91,
799.85,
806.3900000000001,
0.0,
0.0,
0.0,
351.65,
0.0,
0.0,
@ -436,13 +436,13 @@
0.0,
0.0,
0.0,
0.0,
2868.979545454555,
0.0,
257.64,
566.69,
987.01,
0.0,
0.0
592.97
],
"Netzeinspeisung_Wh_pro_Stunde": [
0.0,
@ -453,7 +453,6 @@
0.0,
0.0,
0.0,
813.95,
0.0,
0.0,
0.0,
@ -469,14 +468,15 @@
0.0,
0.0,
0.0,
128.65999999999985,
448.79999999999995,
1330.3700000000001,
175.26999999999998,
4485.82,
3682.7,
2166.67,
1416.43,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
497.68000000000006,
0.0,
0.0,
@ -485,84 +485,84 @@
0.0
],
"Verluste_Pro_Stunde": [
1233.818181818182,
687.0,
1014.0,
912.0,
606.7933884297523,
345.0,
708.0,
1164.818181818182,
1164.818181818182,
864.0,
276.0,
102.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,
795.0,
483.0,
187.4616000000001,
97.67399999999998,
23.391818181818195,
99.72409090909093,
133.72909090909081,
124.41545454545451,
96.08318181818186,
0.0,
118.37045454545455,
94.68272727272722,
0.0,
0.0,
0.0,
69.12409090909085,
109.0704545454546,
109.96227272727276,
0.0,
15.439199999999985,
53.855999999999995,
159.6443999999999,
21.032399999999996,
538.2984000000001,
441.924,
260.0003999999999,
514.2491454545468,
0.0,
0.0,
0.0,
0.0,
100.08954545454549,
80.85954545454547
0.0
],
"akku_soc_pro_stunde": [
58.47796143250689,
71.81129476584022,
88.47796143250687,
98.47796143250687,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
86.25,
64.72796143250687,
43.20592286501377,
55.70592286501377,
55.70592286501377,
68.20592286501376,
68.20592286501376,
72.49652286501377,
75.20968953168044,
74.47131143250688,
71.32345502754819,
67.10220847107436,
63.17495296143248,
60.14202424242422,
60.14202424242422,
56.40558312672175,
53.41686067493111,
53.41686067493111,
53.41686067493111,
53.41686067493111,
51.23491336088152,
47.792032851239654,
44.3210015151515,
44.3210015151515,
44.749868181818165,
46.24586818181816,
50.68043484848482,
51.264668181818166,
66.21740151515148,
78.49306818181815,
85.71530151515148,
100.0,
100.0,
100.0,
100.0,
100.0,
96.84060778236915,
94.28822314049587
96.84060778236915
]
},
"eauto_obj": {
@ -676,102 +676,102 @@
},
"start_solution": [
0.0,
4.0,
13.0,
17.0,
14.0,
12.0,
9.0,
9.0,
17.0,
13.0,
15.0,
12.0,
9.0,
18.0,
14.0,
18.0,
14.0,
9.0,
2.0,
8.0,
10.0,
12.0,
10.0,
10.0,
14.0,
8.0,
7.0,
2.0,
6.0,
4.0,
7.0,
10.0,
8.0,
2.0,
5.0,
0.0,
2.0,
3.0,
4.0,
5.0,
14.0,
10.0,
18.0,
11.0,
1.0,
3.0,
0.0,
5.0,
13.0,
1.0,
5.0,
6.0,
4.0,
0.0,
2.0,
0.0,
2.0,
1.0,
5.0,
6.0,
4.0,
6.0,
0.0,
3.0,
6.0,
5.0,
1.0,
2.0,
0.0,
6.0,
5.0,
5.0,
3.0,
5.0,
4.0,
2.0,
3.0,
5.0,
4.0,
2.0,
5.0,
2.0,
0.0,
6.0,
5.0,
3.0,
0.0,
6.0,
6.0,
2.0,
0.0,
6.0,
3.0,
4.0,
2.0,
6.0,
4.0,
1.0,
1.0,
0.0,
1.0,
5.0,
1.0,
2.0,
4.0,
6.0,
6.0,
5.0,
0.0,
6.0,
1.0,
4.0,
6.0,
6.0,
3.0,
2.0,
6.0,
6.0,
1.0,
1.0,
1.0,
4.0,
2.0,
6.0,
5.0,
5.0,
2.0,
4.0,
0.0,
5.0,
5.0,
2.0,
4.0,
4.0,
1.0,
4.0,
1.0,
6.0,
6.0,
1.0,
3.0,
4.0,
4.0,
0.0,
2.0,
5.0,
5.0,
4.0,
5.0,
2.0,
5.0,
0.0,
1.0,
3.0,
0.0,
0.0,
0.0,
13.0
5.0,
6.0,
2.0,
14.0
],
"washingstart": 13
"washingstart": 14
}

View File

@ -1,30 +1,34 @@
{
"ac_charge": [
0.2,
0.6,
0.0,
0.0,
0.875,
0.0,
1.0,
0.8,
0.6,
0.0,
0.6,
0.0,
0.6,
0.0,
0.0,
0.0,
0.2,
1.0,
0.4,
0.4,
0.4,
0.8,
1.0,
0.6,
0.8,
0.8,
0.6,
0.4,
0.0,
0.875,
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,
@ -38,11 +42,7 @@
0.0,
0.0,
0.0,
0.6,
0.0,
1.0,
0.2,
0.4,
0.0,
0.0,
0.0,
@ -100,6 +100,7 @@
1.0
],
"discharge_allowed": [
1,
0,
0,
1,
@ -107,7 +108,6 @@
0,
0,
1,
0,
1,
0,
1,
@ -115,16 +115,12 @@
0,
0,
0,
1,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
1,
1,
1,
1,
1,
1,
@ -141,39 +137,43 @@
0,
1,
0,
1,
1,
0,
1,
0,
1,
1,
1,
1,
1,
1
],
"eautocharge_hours_float": [
0.625,
0.875,
1.0,
0.0,
0.875,
0.375,
0.875,
1.0,
0.375,
1.0,
0.0,
0.0,
1.0,
1.0,
1.0,
1.0,
0.75,
0.75,
0.5,
0.0,
1.0,
0.625,
0.0,
0.875,
0.75,
1.0,
0.0,
0.75,
1.0,
1.0,
1.0,
0.375,
0.75,
0.5,
0.5,
1.0,
0.625,
0.875,
0.625,
1.0,
0.875,
0.375,
0.625,
0.375,
0.375,
0.0,
0.0,
0.0,
@ -202,13 +202,13 @@
"result": {
"Last_Wh_pro_Stunde": [
1053.07,
1063.91,
8929.91,
11808.56,
15120.029999999999,
19151.67,
11823.38146694215,
11620.03,
14151.67,
7609.82,
9082.22,
7658.78,
6347.78,
1756.12,
1178.71,
1050.98,
@ -229,7 +229,7 @@
1155.99,
827.01,
1257.98,
1999.9845041322394,
1232.67,
871.26,
860.88,
1158.03,
@ -242,12 +242,12 @@
],
"EAuto_SoC_pro_Stunde": [
5.0,
5.0,
22.48,
39.96,
57.440000000000005,
74.92,
88.03,
18.11,
35.589999999999996,
53.06999999999999,
70.55,
77.105,
90.215,
98.955,
100.0,
100.0,
@ -289,7 +289,6 @@
0.0,
0.0,
0.0,
0.013086500000000003,
0.0,
0.0,
0.0,
@ -310,27 +309,28 @@
0.0,
0.0,
0.0,
0.257789,
0.1516669,
0.09915009999999999,
0.0348376,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0
],
"Gesamt_Verluste": 5838.775971074382,
"Gesamtbilanz_Euro": 11.51451054883471,
"Gesamteinnahmen_Euro": 0.5565300999999999,
"Gesamtkosten_Euro": 12.07104064883471,
"Gesamt_Verluste": 7248.648818181819,
"Gesamtbilanz_Euro": 8.568052366,
"Gesamteinnahmen_Euro": 0.0,
"Gesamtkosten_Euro": 8.568052366,
"Home_appliance_wh_per_hour": [
0.0,
0.0,
0.0,
2500.0,
2500.0,
0.0,
2500.0,
2500.0,
0.0,
0.0,
0.0,
@ -366,20 +366,12 @@
],
"Kosten_Euro_pro_Stunde": [
0.0,
0.004569992000000018,
1.7445291920000001,
2.2398909259999997,
2.6227720859999994,
2.41381783,
1.263384017975207,
1.9651220859999998,
1.4948178300000001,
0.0,
1.1236923319999998,
1.0534661399999998,
0.0,
0.05480703000000003,
0.225316611,
0.291163892,
0.26650619799999997,
0.19588158,
0.174739608,
0.0,
0.0,
0.0,
@ -393,7 +385,15 @@
0.0,
0.0,
0.0,
0.14103240585950558,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
@ -406,20 +406,12 @@
],
"Netzbezug_Wh_pro_Stunde": [
0.0,
20.660000000000082,
7886.66,
10701.82,
13958.339999999998,
13132.85,
6304.31146694215,
10458.34,
8132.85,
0.0,
5112.339999999999,
4640.82,
0.0,
171.54000000000008,
731.31,
980.68,
912.38,
704.61,
516.37,
0.0,
0.0,
0.0,
@ -433,7 +425,15 @@
0.0,
0.0,
0.0,
767.3145041322393,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
@ -453,7 +453,6 @@
0.0,
0.0,
0.0,
186.95000000000005,
0.0,
0.0,
0.0,
@ -474,10 +473,11 @@
0.0,
0.0,
0.0,
3682.7,
2166.67,
1416.43,
497.68000000000006,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
@ -486,20 +486,20 @@
],
"Verluste_Pro_Stunde": [
16.744090909090914,
0.0,
552.0,
672.0,
1152.0,
571.027376033058,
414.0,
345.0,
33.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
552.0,
552.0,
552.0,
492.1022727272725,
414.0,
730.0663636363638,
55.434,
23.391818181818195,
99.72409090909093,
133.72909090909081,
124.41545454545451,
96.08318181818186,
70.41409090909087,
118.37045454545455,
94.68272727272722,
83.01681818181817,
@ -513,11 +513,11 @@
53.855999999999995,
159.6443999999999,
21.032399999999996,
630.3761404958689,
0.0,
0.0,
0.0,
0.0,
538.2984000000001,
441.924,
260.0003999999999,
169.97160000000008,
59.721600000000024,
35.132727272727266,
77.27590909090907,
134.59227272727276,
@ -528,41 +528,41 @@
79.4714617768595,
79.4714617768595,
79.4714617768595,
82.80479511019283,
99.4714617768595,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
100.0,
96.26355888429752,
93.27483643250687,
90.65435606060605,
88.25977100550962,
86.15538911845726,
83.97344180440768,
80.5305612947658,
77.05952995867766,
75.54588498622586,
75.97475165289252,
77.47075165289253,
81.9053183195592,
82.48955165289253,
100.0,
100.0,
100.0,
100.0,
100.0,
98.89101239669421,
96.45174758953168,
92.20325413223141,
89.04386191460057,
86.4914772727273
79.4714617768595,
79.4714617768595,
70.47202134986226,
70.47202134986226,
56.13911845730028,
56.76228512396694,
56.02390702479339,
52.876050619834714,
48.654804063360885,
44.72754855371902,
41.69461983471075,
39.47195282369147,
35.73551170798899,
32.746789256198355,
30.126308884297526,
27.731723829201112,
25.627341942148767,
23.445394628099184,
20.002514118457306,
16.531482782369153,
15.017837809917364,
15.446704476584031,
16.94270447658403,
21.377271143250695,
21.961504476584032,
36.91423780991737,
49.189904476584026,
56.41213780991736,
61.133571143250684,
62.79250447658402,
61.68351687327823,
59.2442520661157,
54.99575860881543,
51.836366391184576,
49.28398174931129
]
},
"eauto_obj": {
@ -675,78 +675,78 @@
"start_soc_prozent": 5
},
"start_solution": [
2.0,
12.0,
4.0,
1.0,
19.0,
9.0,
20.0,
14.0,
6.0,
9.0,
8.0,
19.0,
7.0,
2.0,
2.0,
1.0,
3.0,
8.0,
14.0,
11.0,
10.0,
9.0,
10.0,
12.0,
11.0,
13.0,
11.0,
8.0,
10.0,
10.0,
9.0,
11.0,
13.0,
7.0,
8.0,
7.0,
1.0,
7.0,
2.0,
11.0,
11.0,
14.0,
11.0,
5.0,
10.0,
9.0,
13.0,
10.0,
9.0,
8.0,
4.0,
4.0,
2.0,
0.0,
6.0,
3.0,
0.0,
5.0,
4.0,
6.0,
0.0,
4.0,
6.0,
6.0,
6.0,
1.0,
4.0,
1.0,
4.0,
1.0,
0.0,
0.0,
2.0,
2.0,
6.0,
3.0,
3.0,
3.0,
5.0,
6.0,
4.0,
5.0,
5.0,
4.0,
3.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,
4.0,
1.0,
6.0,
2.0,
3.0,
1.0,
1.0,
1.0,
1.0,
1.0,
3.0,
5.0,
6.0,
0.0,
5.0,
1.0,
5.0,
6.0,
1.0,
6.0,
0.0,
0.0,
6.0,
6.0,
6.0,
6.0,
4.0,
3.0,
6.0,
5.0,
1.0,
3.0,
1.0,
1.0,
0.0,
0.0,
0.0,
@ -771,7 +771,7 @@
0.0,
0.0,
0.0,
13.0
14.0
],
"washingstart": 13
"washingstart": 14
}