Self consumption predictor

* Inverter: Self consumption interpolator for better discharge_hour results
 * Small penalty when EV 100% and charge >0
 * Price Forceast (use mean of last 7 days instead of repeat)
 * Price Prediction as JSON simulation output, config fixed electricty fees configurable + MyPy & Ruff
This commit is contained in:
Andreas 2024-12-19 14:45:20 +01:00 committed by Dominique Lasserre
parent 1c75060d8a
commit 410a23e375
15 changed files with 1243 additions and 820 deletions

View File

@ -1072,6 +1072,19 @@
"description": "FastAPI server IP port number.", "description": "FastAPI server IP port number.",
"default": 8503 "default": 8503
}, },
"server_fastapi_verbose": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Server Fastapi Verbose",
"description": "Enable debug output",
"default": false
},
"server_fastapi_startup_server_fasthtml": { "server_fastapi_startup_server_fasthtml": {
"anyOf": [ "anyOf": [
{ {
@ -3712,6 +3725,19 @@
"description": "FastAPI server IP port number.", "description": "FastAPI server IP port number.",
"default": 8503 "default": 8503
}, },
"server_fastapi_verbose": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Server Fastapi Verbose",
"description": "Enable debug output",
"default": false
},
"server_fastapi_startup_server_fasthtml": { "server_fastapi_startup_server_fasthtml": {
"anyOf": [ "anyOf": [
{ {
@ -5775,6 +5801,21 @@
"type": "array", "type": "array",
"title": "Akku Soc Pro Stunde", "title": "Akku Soc Pro Stunde",
"description": "The state of charge of the battery (not the EV) in percentage per hour." "description": "The state of charge of the battery (not the EV) in percentage per hour."
},
"Electricity_price": {
"items": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
]
},
"type": "array",
"title": "Electricity Price",
"description": "Used Electricity Price, including predictions"
} }
}, },
"type": "object", "type": "object",
@ -5791,7 +5832,8 @@
"Netzbezug_Wh_pro_Stunde", "Netzbezug_Wh_pro_Stunde",
"Netzeinspeisung_Wh_pro_Stunde", "Netzeinspeisung_Wh_pro_Stunde",
"Verluste_Pro_Stunde", "Verluste_Pro_Stunde",
"akku_soc_pro_stunde" "akku_soc_pro_stunde",
"Electricity_price"
], ],
"title": "SimulationResult", "title": "SimulationResult",
"description": "This object contains the results of the simulation and provides insights into various parameters over the entire forecast period." "description": "This object contains the results of the simulation and provides insights into various parameters over the entire forecast period."

View File

@ -86,6 +86,9 @@ class SimulationResult(PydanticBaseModel):
akku_soc_pro_stunde: list[Optional[float]] = Field( akku_soc_pro_stunde: list[Optional[float]] = Field(
description="The state of charge of the battery (not the EV) in percentage per hour." description="The state of charge of the battery (not the EV) in percentage per hour."
) )
Electricity_price: list[Optional[float]] = Field(
description="Used Electricity Price, including predictions"
)
@field_validator( @field_validator(
"Last_Wh_pro_Stunde", "Last_Wh_pro_Stunde",
@ -97,6 +100,7 @@ class SimulationResult(PydanticBaseModel):
"EAuto_SoC_pro_Stunde", "EAuto_SoC_pro_Stunde",
"Verluste_Pro_Stunde", "Verluste_Pro_Stunde",
"Home_appliance_wh_per_hour", "Home_appliance_wh_per_hour",
"Electricity_price",
mode="before", mode="before",
) )
def convert_numpy(cls, field: Any) -> Any: def convert_numpy(cls, field: Any) -> Any:
@ -320,6 +324,7 @@ class EnergieManagementSystem(SingletonMixin, ConfigMixin, PredictionMixin, Pyda
eauto_soc_pro_stunde = np.full((total_hours), np.nan) eauto_soc_pro_stunde = np.full((total_hours), np.nan)
verluste_wh_pro_stunde = np.full((total_hours), np.nan) verluste_wh_pro_stunde = np.full((total_hours), np.nan)
home_appliance_wh_per_hour = np.full((total_hours), np.nan) home_appliance_wh_per_hour = np.full((total_hours), np.nan)
electricity_price_per_hour = np.full((total_hours), np.nan)
# Set initial state # Set initial state
if self.akku: if self.akku:
@ -377,6 +382,7 @@ class EnergieManagementSystem(SingletonMixin, ConfigMixin, PredictionMixin, Pyda
netzbezug_wh_pro_stunde[stunde_since_now] = netzbezug netzbezug_wh_pro_stunde[stunde_since_now] = netzbezug
verluste_wh_pro_stunde[stunde_since_now] += verluste verluste_wh_pro_stunde[stunde_since_now] += verluste
last_wh_pro_stunde[stunde_since_now] = verbrauch last_wh_pro_stunde[stunde_since_now] = verbrauch
electricity_price_per_hour[stunde_since_now] = self.strompreis_euro_pro_wh[stunde]
# Financial calculations # Financial calculations
kosten_euro_pro_stunde[stunde_since_now] = ( kosten_euro_pro_stunde[stunde_since_now] = (
@ -410,6 +416,7 @@ class EnergieManagementSystem(SingletonMixin, ConfigMixin, PredictionMixin, Pyda
"Verluste_Pro_Stunde": verluste_wh_pro_stunde, "Verluste_Pro_Stunde": verluste_wh_pro_stunde,
"Gesamt_Verluste": np.nansum(verluste_wh_pro_stunde), "Gesamt_Verluste": np.nansum(verluste_wh_pro_stunde),
"Home_appliance_wh_per_hour": home_appliance_wh_per_hour, "Home_appliance_wh_per_hour": home_appliance_wh_per_hour,
"Electricity_price": electricity_price_per_hour,
} }
return out return out

Binary file not shown.

View File

@ -10,6 +10,9 @@ from akkudoktoreos.devices.battery import Battery
from akkudoktoreos.devices.devicesabc import DevicesBase from akkudoktoreos.devices.devicesabc import DevicesBase
from akkudoktoreos.devices.generic import HomeAppliance from akkudoktoreos.devices.generic import HomeAppliance
from akkudoktoreos.devices.inverter import Inverter from akkudoktoreos.devices.inverter import Inverter
from akkudoktoreos.prediction.self_consumption_probability import (
self_consumption_probability_interpolator,
)
from akkudoktoreos.utils.datetimeutil import to_duration from akkudoktoreos.utils.datetimeutil import to_duration
from akkudoktoreos.utils.logutil import get_logger from akkudoktoreos.utils.logutil import get_logger
@ -162,7 +165,11 @@ class Devices(SingletonMixin, DevicesBase):
akku: ClassVar[Battery] = Battery(provider_id="GenericBattery") akku: ClassVar[Battery] = Battery(provider_id="GenericBattery")
eauto: ClassVar[Battery] = Battery(provider_id="GenericBEV") eauto: ClassVar[Battery] = Battery(provider_id="GenericBEV")
home_appliance: ClassVar[HomeAppliance] = HomeAppliance(provider_id="GenericDishWasher") home_appliance: ClassVar[HomeAppliance] = HomeAppliance(provider_id="GenericDishWasher")
inverter: ClassVar[Inverter] = Inverter(akku=akku, provider_id="GenericInverter") inverter: ClassVar[Inverter] = Inverter(
self_consumption_predictor=self_consumption_probability_interpolator,
akku=akku,
provider_id="GenericInverter",
)
def update_data(self) -> None: def update_data(self) -> None:
"""Update device simulation data.""" """Update device simulation data."""

View File

@ -1,6 +1,7 @@
from typing import Optional, Tuple from typing import Optional
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from scipy.interpolate import RegularGridInterpolator
from akkudoktoreos.devices.battery import Battery from akkudoktoreos.devices.battery import Battery
from akkudoktoreos.devices.devicesabc import DeviceBase from akkudoktoreos.devices.devicesabc import DeviceBase
@ -16,6 +17,7 @@ class InverterParameters(BaseModel):
class Inverter(DeviceBase): class Inverter(DeviceBase):
def __init__( def __init__(
self, self,
self_consumption_predictor: RegularGridInterpolator,
parameters: Optional[InverterParameters] = None, parameters: Optional[InverterParameters] = None,
akku: Optional[Battery] = None, akku: Optional[Battery] = None,
provider_id: Optional[str] = None, provider_id: Optional[str] = None,
@ -34,6 +36,7 @@ class Inverter(DeviceBase):
logger.error(error_msg) logger.error(error_msg)
raise NotImplementedError(error_msg) raise NotImplementedError(error_msg)
self.akku = akku # Connection to a battery object self.akku = akku # Connection to a battery object
self.self_consumption_predictor = self_consumption_predictor
self.initialised = False self.initialised = False
# Run setup if parameters are given, otherwise setup() has to be called later when the config is initialised. # Run setup if parameters are given, otherwise setup() has to be called later when the config is initialised.
@ -58,28 +61,60 @@ class Inverter(DeviceBase):
def process_energy( def process_energy(
self, generation: float, consumption: float, hour: int self, generation: float, consumption: float, hour: int
) -> Tuple[float, float, float, float]: ) -> tuple[float, float, float, float]:
losses = 0.0 losses = 0.0
grid_export = 0.0 grid_export = 0.0
grid_import = 0.0 grid_import = 0.0
self_consumption = 0.0 self_consumption = 0.0
if generation >= consumption: if generation >= consumption:
# Case 1: Sufficient or excess generation if consumption > self.max_power_wh:
actual_consumption = min(consumption, self.max_power_wh) # If consumption exceeds maximum inverter power
remaining_energy = generation - actual_consumption losses += generation - self.max_power_wh
remaining_power = self.max_power_wh - consumption
grid_import = -remaining_power # Negative indicates feeding into the grid
self_consumption = self.max_power_wh
else:
scr = self.self_consumption_predictor.calculate_self_consumption(
consumption, generation
)
# Charge battery with excess energy # Remaining power after consumption
charged_energy, charging_losses = self.akku.charge_energy(remaining_energy, hour) remaining_power = (generation - consumption) * scr # EVQ
losses += charging_losses # Remaining load Self Consumption not perfect
remaining_load_evq = (generation - consumption) * (1.0 - scr)
# Calculate remaining surplus after battery charge if remaining_load_evq > 0:
remaining_surplus = remaining_energy - (charged_energy + charging_losses) # Akku muss den Restverbrauch decken
grid_export = min(remaining_surplus, self.max_power_wh - actual_consumption) from_battery, discharge_losses = self.akku.discharge_energy(
remaining_load_evq, hour
)
remaining_load_evq -= from_battery # Restverbrauch nach Akkuentladung
losses += discharge_losses
# If any remaining surplus can't be fed to the grid, count as losses # Wenn der Akku den Restverbrauch nicht vollständig decken kann, wird der Rest ins Netz gezogen
losses += max(remaining_surplus - grid_export, 0) if remaining_load_evq > 0:
self_consumption = actual_consumption grid_import += remaining_load_evq
remaining_load_evq = 0
else:
from_battery = 0.0
if remaining_power > 0:
# Load battery with excess energy
charged_energie, charge_losses = self.akku.charge_energy(remaining_power, hour)
remaining_surplus = remaining_power - (charged_energie + charge_losses)
# Feed-in to the grid based on remaining capacity
if remaining_surplus > self.max_power_wh - consumption:
grid_export = self.max_power_wh - consumption
losses += remaining_surplus - grid_export
else:
grid_export = remaining_surplus
losses += charge_losses
self_consumption = (
consumption + from_battery
) # Self-consumption is equal to the load
else: else:
# Case 2: Insufficient generation, cover shortfall # Case 2: Insufficient generation, cover shortfall

View File

@ -1,5 +1,7 @@
import random import random
from typing import Any, Optional, Tuple import time
from pathlib import Path
from typing import Any, Optional
import numpy as np import numpy as np
from deap import algorithms, base, creator, tools from deap import algorithms, base, creator, tools
@ -20,6 +22,9 @@ from akkudoktoreos.devices.battery import (
) )
from akkudoktoreos.devices.generic import HomeAppliance, HomeApplianceParameters from akkudoktoreos.devices.generic import HomeAppliance, HomeApplianceParameters
from akkudoktoreos.devices.inverter import Inverter, InverterParameters from akkudoktoreos.devices.inverter import Inverter, InverterParameters
from akkudoktoreos.prediction.self_consumption_probability import (
self_consumption_probability_interpolator,
)
from akkudoktoreos.utils.utils import NumpyEncoder from akkudoktoreos.utils.utils import NumpyEncoder
@ -116,8 +121,8 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
random.seed(fixed_seed) random.seed(fixed_seed)
def decode_charge_discharge( def decode_charge_discharge(
self, discharge_hours_bin: list[float] self, discharge_hours_bin: np.ndarray
) -> Tuple[np.ndarray, np.ndarray, np.ndarray]: ) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
"""Decode the input array into ac_charge, dc_charge, and discharge arrays.""" """Decode the input array into ac_charge, dc_charge, and discharge arrays."""
discharge_hours_bin_np = np.array(discharge_hours_bin) discharge_hours_bin_np = np.array(discharge_hours_bin)
len_ac = len(self.config.optimization_ev_available_charge_rates_percent) len_ac = len(self.config.optimization_ev_available_charge_rates_percent)
@ -137,7 +142,7 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
# AC states # AC states
ac_mask = (discharge_hours_bin_np >= 2 * len_ac) & (discharge_hours_bin_np < 3 * len_ac) 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 ac_indices = (discharge_hours_bin_np[ac_mask] - 2 * len_ac).astype(int)
# DC states (if enabled) # DC states (if enabled)
if self.optimize_dc_charge: if self.optimize_dc_charge:
@ -217,28 +222,71 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
return creator.Individual(individual_components) return creator.Individual(individual_components)
def merge_individual(
self,
discharge_hours_bin: np.ndarray,
eautocharge_hours_index: Optional[np.ndarray],
washingstart_int: Optional[int],
) -> list[int]:
"""Merge the individual components back into a single solution list.
Parameters:
discharge_hours_bin (np.ndarray): Binary discharge hours.
eautocharge_hours_index (Optional[np.ndarray]): EV charge hours as integers, or None.
washingstart_int (Optional[int]): Dishwasher start time as integer, or None.
Returns:
list[int]: The merged individual solution as a list of integers.
"""
# Start with the discharge hours
individual = discharge_hours_bin.tolist()
# Add EV charge hours if applicable
if self.optimize_ev and eautocharge_hours_index is not None:
individual.extend(eautocharge_hours_index.tolist())
elif self.optimize_ev:
# Falls optimize_ev aktiv ist, aber keine EV-Daten vorhanden sind, fügen wir Nullen hinzu
individual.extend([0] * self.config.prediction_hours)
# Add dishwasher start time if applicable
if self.opti_param.get("home_appliance", 0) > 0 and washingstart_int is not None:
individual.append(washingstart_int)
elif self.opti_param.get("home_appliance", 0) > 0:
# Falls ein Haushaltsgerät optimiert wird, aber kein Startzeitpunkt vorhanden ist
individual.append(0)
return individual
def split_individual( def split_individual(
self, individual: list[float] self, individual: list[int]
) -> tuple[list[float], Optional[list[float]], Optional[int]]: ) -> tuple[np.ndarray, Optional[np.ndarray], Optional[int]]:
"""Split the individual solution into its components. """Split the individual solution into its components.
Components: Components:
1. Discharge hours (binary), 1. Discharge hours (binary as int NumPy array),
2. Electric vehicle charge hours (float), 2. Electric vehicle charge hours (float as int NumPy array, if applicable),
3. Dishwasher start time (integer if applicable). 3. Dishwasher start time (integer if applicable).
""" """
discharge_hours_bin = individual[: self.config.prediction_hours] # Discharge hours as a NumPy array of ints
discharge_hours_bin = np.array(individual[: self.config.prediction_hours], dtype=int)
# EV charge hours as a NumPy array of ints (if optimize_ev is True)
eautocharge_hours_index = ( eautocharge_hours_index = (
individual[self.config.prediction_hours : self.config.prediction_hours * 2] np.array(
individual[self.config.prediction_hours : self.config.prediction_hours * 2],
dtype=int,
)
if self.optimize_ev if self.optimize_ev
else None else None
) )
# Washing machine start time as an integer (if applicable)
washingstart_int = ( washingstart_int = (
int(individual[-1]) int(individual[-1])
if self.opti_param and self.opti_param.get("home_appliance", 0) > 0 if self.opti_param and self.opti_param.get("home_appliance", 0) > 0
else None else None
) )
return discharge_hours_bin, eautocharge_hours_index, washingstart_int return discharge_hours_bin, eautocharge_hours_index, washingstart_int
def setup_deap_environment(self, opti_param: dict[str, Any], start_hour: int) -> None: def setup_deap_environment(self, opti_param: dict[str, Any], start_hour: int) -> None:
@ -308,7 +356,7 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
self.toolbox.register("mutate", self.mutate) self.toolbox.register("mutate", self.mutate)
self.toolbox.register("select", tools.selTournament, tournsize=3) self.toolbox.register("select", tools.selTournament, tournsize=3)
def evaluate_inner(self, individual: list[float]) -> dict[str, Any]: def evaluate_inner(self, individual: list[int]) -> dict[str, Any]:
"""Simulates the energy management system (EMS) using the provided individual solution. """Simulates the energy management system (EMS) using the provided individual solution.
This is an internal function. This is an internal function.
@ -340,16 +388,17 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
) )
self.ems.set_ev_charge_hours(eautocharge_hours_float) self.ems.set_ev_charge_hours(eautocharge_hours_float)
else: else:
self.ems.set_ev_charge_hours(np.full(self.config.prediction_hours, 0.0)) self.ems.set_ev_charge_hours(np.full(self.config.prediction_hours, 0))
return self.ems.simuliere(self.ems.start_datetime.hour) return self.ems.simuliere(self.ems.start_datetime.hour)
def evaluate( def evaluate(
self, self,
individual: list[float], individual: list[int],
parameters: OptimizationParameters, parameters: OptimizationParameters,
start_hour: int, start_hour: int,
worst_case: bool, worst_case: bool,
) -> Tuple[float]: ) -> tuple[float]:
"""Evaluate the fitness of an individual solution based on the simulation results.""" """Evaluate the fitness of an individual solution based on the simulation results."""
try: try:
o = self.evaluate_inner(individual) o = self.evaluate_inner(individual)
@ -358,19 +407,39 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
gesamtbilanz = o["Gesamtbilanz_Euro"] * (-1.0 if worst_case else 1.0) gesamtbilanz = o["Gesamtbilanz_Euro"] * (-1.0 if worst_case else 1.0)
discharge_hours_bin, eautocharge_hours_index, _ = self.split_individual(individual) discharge_hours_bin, eautocharge_hours_index, washingstart_int = self.split_individual(
individual
# Small Penalty for not discharging
gesamtbilanz += sum(
0.01 for i in range(self.config.prediction_hours) if discharge_hours_bin[i] == 0.0
) )
# Penalty for not meeting the minimum SOC (State of Charge) requirement # EV 100% & charge not allowed
# if parameters.eauto_min_soc_prozent - ems.eauto.current_soc_percentage() <= 0.0 and self.optimize_ev: if self.optimize_ev:
# gesamtbilanz += sum( eauto_soc_per_hour = np.array(o.get("EAuto_SoC_pro_Stunde", [])) # Beispielkey
# self.config.optimization_penalty for ladeleistung in eautocharge_hours_float if ladeleistung != 0.0
# )
if eauto_soc_per_hour is None or eautocharge_hours_index is None:
raise ValueError("eauto_soc_per_hour or eautocharge_hours_index is None")
min_length = min(eauto_soc_per_hour.size, eautocharge_hours_index.size)
eauto_soc_per_hour_tail = eauto_soc_per_hour[-min_length:]
eautocharge_hours_index_tail = eautocharge_hours_index[-min_length:]
# Mask
invalid_charge_mask = (eauto_soc_per_hour_tail == 100) & (
eautocharge_hours_index_tail > 0
)
if np.any(invalid_charge_mask):
invalid_indices = np.where(invalid_charge_mask)[0]
if len(invalid_indices) > 1:
eautocharge_hours_index_tail[invalid_indices[1:]] = 0
eautocharge_hours_index[-min_length:] = eautocharge_hours_index_tail.tolist()
adjusted_individual = self.merge_individual(
discharge_hours_bin, eautocharge_hours_index, washingstart_int
)
individual[:] = adjusted_individual # Aktualisiere das ursprüngliche individual
# Berechnung weiterer Metriken
individual.extra_data = ( # type: ignore[attr-defined] individual.extra_data = ( # type: ignore[attr-defined]
o["Gesamtbilanz_Euro"], o["Gesamtbilanz_Euro"],
o["Gesamt_Verluste"], o["Gesamt_Verluste"],
@ -380,13 +449,11 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
) )
# Adjust total balance with battery value and penalties for unmet SOC # Adjust total balance with battery value and penalties for unmet SOC
restwert_akku = ( restwert_akku = (
self.ems.akku.current_energy_content() * parameters.ems.preis_euro_pro_wh_akku self.ems.akku.current_energy_content() * parameters.ems.preis_euro_pro_wh_akku
) )
# print(ems.akku.current_energy_content()," * ", parameters.ems.preis_euro_pro_wh_akku , " ", restwert_akku, " ", gesamtbilanz)
gesamtbilanz += -restwert_akku gesamtbilanz += -restwert_akku
# print(gesamtbilanz)
if self.optimize_ev: if self.optimize_ev:
gesamtbilanz += max( gesamtbilanz += max(
0, 0,
@ -401,8 +468,8 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
return (gesamtbilanz,) return (gesamtbilanz,)
def optimize( def optimize(
self, start_solution: Optional[list[float]] = None, ngen: int = 400 self, start_solution: Optional[list[float]] = None, ngen: int = 200
) -> Tuple[Any, dict[str, list[Any]]]: ) -> tuple[Any, dict[str, list[Any]]]:
"""Run the optimization process using a genetic algorithm.""" """Run the optimization process using a genetic algorithm."""
population = self.toolbox.population(n=300) population = self.toolbox.population(n=300)
hof = tools.HallOfFame(1) hof = tools.HallOfFame(1)
@ -414,7 +481,7 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
# Insert the start solution into the population if provided # Insert the start solution into the population if provided
if start_solution is not None: if start_solution is not None:
for _ in range(3): for _ in range(10):
population.insert(0, creator.Individual(start_solution)) population.insert(0, creator.Individual(start_solution))
# Run the evolutionary algorithm # Run the evolutionary algorithm
@ -446,7 +513,7 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
parameters: OptimizationParameters, parameters: OptimizationParameters,
start_hour: Optional[int] = None, start_hour: Optional[int] = None,
worst_case: bool = False, worst_case: bool = False,
ngen: int = 600, ngen: int = 400,
) -> OptimizeResponse: ) -> OptimizeResponse:
"""Perform EMS (Energy Management System) optimization and visualize results.""" """Perform EMS (Energy Management System) optimization and visualize results."""
if start_hour is None: if start_hour is None:
@ -456,6 +523,11 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
self.config.prediction_hours, parameters.ems.einspeiseverguetung_euro_pro_wh self.config.prediction_hours, parameters.ems.einspeiseverguetung_euro_pro_wh
) )
# 1h Load to Sub 1h Load Distribution -> SelfConsumptionRate
sc = self_consumption_probability_interpolator(
Path(__file__).parent.resolve() / ".." / "data" / "regular_grid_interpolator.pkl"
)
# Initialize PV and EV batteries # Initialize PV and EV batteries
akku = Battery( akku = Battery(
parameters.pv_akku, parameters.pv_akku,
@ -487,9 +559,14 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
) )
# Initialize the inverter and energy management system # Initialize the inverter and energy management system
inverter = Inverter(
sc,
parameters.inverter,
akku,
)
self.ems.set_parameters( self.ems.set_parameters(
parameters.ems, parameters.ems,
inverter=Inverter(parameters.inverter, akku), inverter=inverter,
eauto=eauto, eauto=eauto,
home_appliance=dishwasher, home_appliance=dishwasher,
) )
@ -501,8 +578,14 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
"evaluate", "evaluate",
lambda ind: self.evaluate(ind, parameters, start_hour, worst_case), lambda ind: self.evaluate(ind, parameters, start_hour, worst_case),
) )
if self.verbose:
start_time = time.time()
start_solution, extra_data = self.optimize(parameters.start_solution, ngen=ngen) start_solution, extra_data = self.optimize(parameters.start_solution, ngen=ngen)
if self.verbose:
elapsed_time = time.time() - start_time
print(f"Time evaluate inner: {elapsed_time:.4f} sec.")
# Perform final evaluation on the best solution # Perform final evaluation on the best solution
o = self.evaluate_inner(start_solution) o = self.evaluate_inner(start_solution)
discharge_hours_bin, eautocharge_hours_index, washingstart_int = self.split_individual( discharge_hours_bin, eautocharge_hours_index, washingstart_int = self.split_individual(

View File

@ -0,0 +1,72 @@
#!/usr/bin/env python
import pickle
from functools import lru_cache
from pathlib import Path
import numpy as np
from scipy.interpolate import RegularGridInterpolator
class self_consumption_probability_interpolator:
def __init__(self, filepath: str | Path):
self.filepath = filepath
# self.interpolator = None
# Load the RegularGridInterpolator
with open(self.filepath, "rb") as file:
self.interpolator: RegularGridInterpolator = pickle.load(file)
@lru_cache(maxsize=128)
def generate_points(
self, load_1h_power: float, pv_power: float
) -> tuple[np.ndarray, np.ndarray]:
"""Generate the grid points for interpolation."""
partial_loads = np.arange(0, pv_power + 50, 50)
points = np.array([np.full_like(partial_loads, load_1h_power), partial_loads]).T
return points, partial_loads
def calculate_self_consumption(self, load_1h_power: float, pv_power: float) -> float:
points, partial_loads = self.generate_points(load_1h_power, pv_power)
probabilities = self.interpolator(points)
return probabilities.sum()
# def calculate_self_consumption(self, load_1h_power: float, pv_power: float) -> float:
# """Calculate the PV self-consumption rate using RegularGridInterpolator.
# Args:
# - last_1h_power: 1h power levels (W).
# - pv_power: Current PV power output (W).
# Returns:
# - Self-consumption rate as a float.
# """
# # Generate the range of partial loads (0 to last_1h_power)
# partial_loads = np.arange(0, pv_power + 50, 50)
# # Get probabilities for all partial loads
# points = np.array([np.full_like(partial_loads, load_1h_power), partial_loads]).T
# if self.interpolator == None:
# return -1.0
# probabilities = self.interpolator(points)
# self_consumption_rate = probabilities.sum()
# # probabilities = probabilities / (np.sum(probabilities)) # / (pv_power / 3450))
# # # for i, w in enumerate(partial_loads):
# # # print(w, ": ", probabilities[i])
# # print(probabilities.sum())
# # # Ensure probabilities are within [0, 1]
# # probabilities = np.clip(probabilities, 0, 1)
# # # Mask: Only include probabilities where the load is <= PV power
# # mask = partial_loads <= pv_power
# # # Calculate the cumulative probability for covered loads
# # self_consumption_rate = np.sum(probabilities[mask]) / np.sum(probabilities)
# # print(self_consumption_rate)
# # sys.exit()
# return self_consumption_rate
# Test the function
# print(calculate_self_consumption(1000, 1200))

View File

@ -80,7 +80,7 @@ app = FastAPI(
) )
# That's the problem # That's the problem
opt_class = optimization_problem() opt_class = optimization_problem(verbose=bool(config_eos.server_fastapi_verbose))
server_dir = Path(__file__).parent.resolve() server_dir = Path(__file__).parent.resolve()

View File

@ -23,6 +23,7 @@ class ServerCommonSettings(SettingsBaseModel):
server_fastapi_port: Optional[int] = Field( server_fastapi_port: Optional[int] = Field(
default=8503, description="FastAPI server IP port number." default=8503, description="FastAPI server IP port number."
) )
server_fastapi_verbose: Optional[bool] = Field(default=False, description="Enable debug output")
server_fastapi_startup_server_fasthtml: Optional[bool] = Field( server_fastapi_startup_server_fasthtml: Optional[bool] = Field(
default=True, description="FastAPI server to startup application FastHTML server." default=True, description="FastAPI server to startup application FastHTML server."
) )

View File

@ -1,3 +1,5 @@
from pathlib import Path
import numpy as np import numpy as np
import pytest import pytest
@ -15,6 +17,9 @@ from akkudoktoreos.devices.battery import (
) )
from akkudoktoreos.devices.generic import HomeAppliance, HomeApplianceParameters from akkudoktoreos.devices.generic import HomeAppliance, HomeApplianceParameters
from akkudoktoreos.devices.inverter import Inverter, InverterParameters from akkudoktoreos.devices.inverter import Inverter, InverterParameters
from akkudoktoreos.prediction.self_consumption_probability import (
self_consumption_probability_interpolator,
)
start_hour = 1 start_hour = 1
@ -35,8 +40,19 @@ def create_ems_instance() -> EnergieManagementSystem:
), ),
hours=config_eos.prediction_hours, hours=config_eos.prediction_hours,
) )
# 1h Load to Sub 1h Load Distribution -> SelfConsumptionRate
sc = self_consumption_probability_interpolator(
Path(__file__).parent.resolve()
/ ".."
/ "src"
/ "akkudoktoreos"
/ "data"
/ "regular_grid_interpolator.pkl"
)
akku.reset() akku.reset()
inverter = Inverter(InverterParameters(max_power_wh=10000), akku) inverter = Inverter(sc, InverterParameters(max_power_wh=10000), akku)
# Household device (currently not used, set to None) # Household device (currently not used, set to None)
home_appliance = HomeAppliance( home_appliance = HomeAppliance(
@ -306,21 +322,21 @@ def test_simulation(create_ems_instance):
# Verify the total balance # Verify the total balance
assert ( assert (
abs(result["Gesamtbilanz_Euro"] - 1.7880374129090917) < 1e-5 abs(result["Gesamtbilanz_Euro"] - 1.958185274567674) < 1e-5
), "Total balance should be 1.7880374129090917." ), "Total balance should be 1.958185274567674."
# Check total revenue and total costs # Check total revenue and total costs
assert ( assert (
abs(result["Gesamteinnahmen_Euro"] - 1.3169784090909087) < 1e-5 abs(result["Gesamteinnahmen_Euro"] - 1.168863124510214) < 1e-5
), "Total revenue should be 1.3169784090909087." ), "Total revenue should be 1.168863124510214."
assert ( assert (
abs(result["Gesamtkosten_Euro"] - 3.1050158220000004) < 1e-5 abs(result["Gesamtkosten_Euro"] - 3.127048399077888) < 1e-5
), "Total costs should be 3.1050158220000004 ." ), "Total costs should be 3.127048399077888 ."
# Check the losses # Check the losses
assert ( assert (
abs(result["Gesamt_Verluste"] - 2615.222727272727) < 1e-5 abs(result["Gesamt_Verluste"] - 2871.5330639359036) < 1e-5
), "Total losses should be 2615.222727272727 ." ), "Total losses should be 2871.5330639359036 ."
# Check the values in 'akku_soc_pro_stunde' # Check the values in 'akku_soc_pro_stunde'
assert ( assert (

View File

@ -1,3 +1,5 @@
from pathlib import Path
import numpy as np import numpy as np
import pytest import pytest
@ -14,6 +16,9 @@ from akkudoktoreos.devices.battery import (
) )
from akkudoktoreos.devices.generic import HomeAppliance, HomeApplianceParameters from akkudoktoreos.devices.generic import HomeAppliance, HomeApplianceParameters
from akkudoktoreos.devices.inverter import Inverter, InverterParameters from akkudoktoreos.devices.inverter import Inverter, InverterParameters
from akkudoktoreos.prediction.self_consumption_probability import (
self_consumption_probability_interpolator,
)
start_hour = 0 start_hour = 0
@ -34,8 +39,19 @@ def create_ems_instance() -> EnergieManagementSystem:
), ),
hours=config_eos.prediction_hours, hours=config_eos.prediction_hours,
) )
# 1h Load to Sub 1h Load Distribution -> SelfConsumptionRate
sc = self_consumption_probability_interpolator(
Path(__file__).parent.resolve()
/ ".."
/ "src"
/ "akkudoktoreos"
/ "data"
/ "regular_grid_interpolator.pkl"
)
akku.reset() akku.reset()
inverter = Inverter(InverterParameters(max_power_wh=10000), akku) inverter = Inverter(sc, InverterParameters(max_power_wh=10000), akku)
# Household device (currently not used, set to None) # Household device (currently not used, set to None)
home_appliance = HomeAppliance( home_appliance = HomeAppliance(

View File

@ -1,8 +1,12 @@
from pathlib import Path
from unittest.mock import Mock from unittest.mock import Mock
import pytest import pytest
from akkudoktoreos.devices.inverter import Inverter, InverterParameters from akkudoktoreos.devices.inverter import Inverter, InverterParameters
from akkudoktoreos.prediction.self_consumption_probability import (
self_consumption_probability_interpolator,
)
@pytest.fixture @pytest.fixture
@ -15,25 +19,38 @@ def mock_battery():
@pytest.fixture @pytest.fixture
def inverter(mock_battery): def inverter(mock_battery):
return Inverter(InverterParameters(max_power_wh=500.0), akku=mock_battery) sc = self_consumption_probability_interpolator(
Path(__file__).parent.resolve()
/ ".."
/ "src"
/ "akkudoktoreos"
/ "data"
/ "regular_grid_interpolator.pkl"
)
return Inverter(sc, InverterParameters(max_power_wh=500.0), akku=mock_battery)
def test_process_energy_excess_generation(inverter, mock_battery): def test_process_energy_excess_generation(inverter, mock_battery):
# Battery charges 100 Wh with 10 Wh loss # Battery charges 100 Wh with 10 Wh loss
mock_battery.charge_energy.return_value = (100.0, 10.0)
generation = 600.0 generation = 600.0
consumption = 200.0 consumption = 200.0
hour = 12 hour = 12
mock_battery.charge_energy.return_value = (100.0, 10.0)
grid_export, grid_import, losses, self_consumption = inverter.process_energy( grid_export, grid_import, losses, self_consumption = inverter.process_energy(
generation, consumption, hour generation, consumption, hour
) )
assert grid_export == pytest.approx(290.0, rel=1e-2) # 290 Wh feed-in after battery charges assert grid_export == pytest.approx(
assert grid_import == 0.0 # No grid draw 286.1737223461208, rel=1e-2
) # 290 Wh feed-in after battery charges
assert grid_import == pytest.approx(3.826277653879151, rel=1e-2) # Little grid draw
assert losses == 10.0 # Battery charging losses assert losses == 10.0 # Battery charging losses
assert self_consumption == 200.0 # All consumption is met assert self_consumption == 200.0 # All consumption is met
mock_battery.charge_energy.assert_called_once_with(400.0, hour) mock_battery.charge_energy.assert_called_once_with(
pytest.approx(396.1737223461208, rel=1e-2), hour
)
def test_process_energy_generation_equals_consumption(inverter, mock_battery): def test_process_energy_generation_equals_consumption(inverter, mock_battery):
@ -50,7 +67,8 @@ def test_process_energy_generation_equals_consumption(inverter, mock_battery):
assert losses == 0.0 # No losses assert losses == 0.0 # No losses
assert self_consumption == 300.0 # All consumption is met with generation assert self_consumption == 300.0 # All consumption is met with generation
mock_battery.charge_energy.assert_called_once_with(0.0, hour) mock_battery.charge_energy.assert_not_called()
mock_battery.discharge_energy.assert_not_called()
def test_process_energy_battery_discharges(inverter, mock_battery): def test_process_energy_battery_discharges(inverter, mock_battery):
@ -103,12 +121,14 @@ def test_process_energy_battery_full_at_start(inverter, mock_battery):
) )
assert grid_export == pytest.approx( assert grid_export == pytest.approx(
300.0, rel=1e-2 296.39026480502736, rel=1e-2
) # All excess energy should be fed into the grid ) # All excess energy should be fed into the grid
assert grid_import == 0.0 # No grid draw assert grid_import == pytest.approx(3.609735194972663, rel=1e-2) # Almost no grid draw
assert losses == 0.0 # No losses assert losses == 0.0 # No losses
assert self_consumption == 200.0 # Only consumption is met assert self_consumption == 200.0 # Only consumption is met
mock_battery.charge_energy.assert_called_once_with(300.0, hour) mock_battery.charge_energy.assert_called_once_with(
pytest.approx(296.39026480502736, rel=1e-2), hour
)
def test_process_energy_insufficient_generation_no_battery(inverter, mock_battery): def test_process_energy_insufficient_generation_no_battery(inverter, mock_battery):
@ -185,10 +205,14 @@ def test_process_energy_zero_consumption(inverter, mock_battery):
) )
assert grid_export == pytest.approx(390.0, rel=1e-2) # Excess energy after battery charges assert grid_export == pytest.approx(390.0, rel=1e-2) # Excess energy after battery charges
assert grid_import == 0.0 # No grid draw as no consumption assert grid_import == pytest.approx(
0.022862368543430378, rel=1e-2
) # Almost no grid draw as no consumption
assert losses == 10.0 # Charging losses assert losses == 10.0 # Charging losses
assert self_consumption == 0.0 # Zero consumption assert self_consumption == 0.0 # Zero consumption
mock_battery.charge_energy.assert_called_once_with(500.0, hour) mock_battery.charge_energy.assert_called_once_with(
pytest.approx(499.97713763145657, rel=1e-2), hour
)
def test_process_energy_zero_generation_zero_consumption(inverter, mock_battery): def test_process_energy_zero_generation_zero_consumption(inverter, mock_battery):

View File

@ -1,52 +1,52 @@
{ {
"ac_charge": [ "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,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.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.875,
0.0, 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,
0.0, 0.0,
0.0, 0.0,
0.0,
1.0,
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,
0.375,
0.0,
0.0,
0.625,
0.0,
0.0,
0.375,
0.75,
1.0,
0.0,
0.0 0.0
], ],
"dc_charge": [ "dc_charge": [
@ -102,35 +102,6 @@
"discharge_allowed": [ "discharge_allowed": [
0, 0,
0, 0,
1,
1,
0,
1,
1,
1,
0,
1,
1,
1,
0,
1,
1,
1,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
1,
0,
1,
1,
0,
0, 0,
1, 1,
0, 0,
@ -138,8 +109,6 @@
0, 0,
0, 0,
0, 0,
1,
0,
0, 0,
0, 0,
1, 1,
@ -147,7 +116,38 @@
0, 0,
1, 1,
1, 1,
1 0,
0,
0,
0,
1,
1,
1,
0,
0,
1,
0,
1,
1,
0,
0,
0,
1,
0,
1,
0,
1,
0,
1,
1,
0,
1,
0,
0,
0,
0,
1,
0
], ],
"eautocharge_hours_float": null, "eautocharge_hours_float": null,
"result": { "result": {
@ -179,7 +179,7 @@
992.46, 992.46,
1155.99, 1155.99,
827.01, 827.01,
1257.98, 3132.98,
1232.67, 1232.67,
871.26, 871.26,
860.88, 860.88,
@ -237,10 +237,10 @@
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
0.212927386983471, 0.22334747537370364,
0.19275619999999996, 0.19016535126346096,
0.1339926, 0.12880892587597292,
0.0569765, 0.04260510586128589,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
@ -260,21 +260,21 @@
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
0.1512260012396691, 0.059176154400016855,
0.257789, 0.25751345302450973,
0.1516669, 0.14923279815365575,
0.09915009999999999, 0.07926913850394514,
0.0348376, 0.024174420063375994,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
0.0 0.0
], ],
"Gesamt_Verluste": 2071.900103305785, "Gesamt_Verluste": 2500.030611233429,
"Gesamtbilanz_Euro": 0.9349588927768602, "Gesamtbilanz_Euro": 1.4988843060949502,
"Gesamteinnahmen_Euro": 1.2913222882231399, "Gesamteinnahmen_Euro": 1.1542928225199272,
"Gesamtkosten_Euro": 2.226281181, "Gesamtkosten_Euro": 2.6531771286148773,
"Home_appliance_wh_per_hour": [ "Home_appliance_wh_per_hour": [
null, null,
null, null,
@ -316,84 +316,84 @@
null null
], ],
"Kosten_Euro_pro_Stunde": [ "Kosten_Euro_pro_Stunde": [
0.0, 0.027996119999999992,
0.0, 0.0,
0.04475252599999999, 0.04475252599999999,
0.0018232052307313393,
0.0, 0.0,
0.0, 0.0,
0.0, 0.008135265032732555,
0.0, 0.016809914659344942,
0.0, 0.061530097476751734,
0.0,
0.05480703000000003, 0.05480703000000003,
0.225316611, 0.0,
0.291163892, 0.0,
0.26650619799999997, 0.0,
0.19588158, 0.19588158,
0.174739608, 0.174739608,
0.0, 0.0,
0.0, 0.22802125600000003,
0.199865757,
0.0, 0.0,
0.0, 0.0,
0.162995926,
0.16677339, 0.16677339,
0.26411047, 0.26411047,
0.0, 0.0,
0.08545095, 0.08545095,
0.0, 0.0,
0.028255713342252034,
0.0,
0.3629952558325975,
0.0, 0.0,
0.0, 0.0,
0.0076430797975209205,
0.0, 0.0,
0.0, 0.04565364324294593,
0.0,
0.0,
0.0,
0.0,
0.08231598, 0.08231598,
0.174597189, 0.174597189,
0.293043269,
0.0, 0.0,
0.0, 0.16484566
0.0
], ],
"Netzbezug_Wh_pro_Stunde": [ "Netzbezug_Wh_pro_Stunde": [
0.0, 122.78999999999996,
0.0, 0.0,
213.81999999999994, 213.81999999999994,
9.703061366318996,
0.0, 0.0,
0.0, 0.0,
0.0, 37.01212480770043,
0.0, 74.05248748610107,
0.0, 205.30563055305882,
0.0,
171.54000000000008, 171.54000000000008,
731.31, 0.0,
980.68, 0.0,
912.38, 0.0,
704.61, 704.61,
516.37, 516.37,
0.0, 0.0,
0.0, 694.34,
608.79,
0.0, 0.0,
0.0, 0.0,
488.89,
506.91, 506.91,
799.85, 799.85,
0.0, 0.0,
351.65, 351.65,
0.0, 0.0,
127.73830624887898,
0.0,
1931.853410498124,
0.0, 0.0,
0.0, 0.0,
34.77288351920346,
0.0, 0.0,
0.0, 152.3311419517715,
0.0,
0.0,
0.0,
0.0,
257.64, 257.64,
566.69, 566.69,
987.01,
0.0, 0.0,
0.0, 592.97
0.0
], ],
"Netzeinspeisung_Wh_pro_Stunde": [ "Netzeinspeisung_Wh_pro_Stunde": [
0.0, 0.0,
@ -401,10 +401,10 @@
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
3041.819814049586, 3190.678219624338,
2753.66, 2716.6478751922996,
1914.18, 1840.127512513899,
813.95, 608.6443694469413,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
@ -424,11 +424,11 @@
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
2160.371446280987, 845.3736342859552,
3682.7, 3678.7636146358536,
2166.67, 2131.8971164807967,
1416.43, 1132.4162643420734,
497.68000000000006, 345.3488580482285,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
@ -436,51 +436,74 @@
0.0 0.0
], ],
"Verluste_Pro_Stunde": [ "Verluste_Pro_Stunde": [
16.744090909090914, 0.0,
2.817272727272737, 2.817272727272737,
0.0, 0.0,
3.5592000000000112, 2.3948326360417305,
582.6179999999995, 582.6180000000041,
156.0516223140496, 138.18861364508305,
0.0,
0.0,
0.0,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
99.72409090909093,
133.72909090909081,
124.41545454545451,
0.0, 0.0,
0.0, 0.0,
118.37045454545455, 118.37045454545455,
94.68272727272722,
0.0, 0.0,
83.01681818181817,
75.86045454545456, 75.86045454545456,
66.66681818181814, 0.0,
0.0, 0.0,
0.0, 0.0,
109.96227272727276, 109.96227272727276,
0.0, 0.0,
15.439199999999985, 16.01263877609336,
53.855999999999995, 38.52740325013451,
159.6443999999999, 161.62968357967037,
21.032399999999996, 239.20999074022512,
279.0538264462814, 436.85356388568886,
0.5004782113116364,
0.0,
36.109951963721926,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
0.0,
0.0,
134.59227272727276,
100.08954545454549, 100.08954545454549,
80.85954545454547 0.0
], ],
"akku_soc_pro_stunde": [ "akku_soc_pro_stunde": [
79.4714617768595, 80.0,
79.38253271349862, 79.91107093663912,
79.38253271349862, 79.91107093663912,
79.48139938016529, 79.97759406541806,
95.66523271349861, 96.1614273987495,
100.0,
100.0,
100.0,
100.0,
100.0,
96.85214359504131,
92.63089703856748,
88.7036415289256,
88.7036415289256,
88.7036415289256,
84.96720041322313,
84.96720041322313,
82.34672004132229,
79.95213498622587,
79.95213498622587,
79.95213498622587,
79.95213498622587,
76.48110365013771,
76.48110365013771,
76.64231728537023,
77.71252293120729,
81.22045681594867,
87.86517878095492,
100.0, 100.0,
100.0, 100.0,
100.0, 100.0,
@ -489,31 +512,48 @@
100.0, 100.0,
100.0, 100.0,
100.0, 100.0,
100.0, 96.84060778236915,
100.0, 96.84060778236915
96.26355888429752, ],
93.27483643250687, "Electricity_price": [
93.27483643250687, 0.000228,
90.88025137741046, 0.0002212,
88.7758694903581, 0.0002093,
88.7758694903581, 0.0001879,
88.7758694903581, 0.0001838,
85.30483815426996, 0.0002004,
85.30483815426996, 0.0002198,
85.73370482093662, 0.000227,
87.22970482093662, 0.0002997,
91.66427148760329, 0.0003195,
92.24850482093663, 0.0003081,
100.0, 0.0002969,
100.0, 0.0002921,
100.0, 0.000278,
100.0, 0.0003384,
100.0, 0.0003318,
100.0, 0.0003284,
100.0, 0.0003283,
95.75150654269973, 0.0003289,
92.59211432506888, 0.0003334,
90.0397296831956 0.000329,
0.0003302,
0.0003042,
0.000243,
0.000228,
0.0002212,
0.0002093,
0.0001879,
0.0001838,
0.0002004,
0.0002198,
0.000227,
0.0002997,
0.0003195,
0.0003081,
0.0002969,
0.0002921,
0.000278
] ]
}, },
"eauto_obj": { "eauto_obj": {
@ -626,54 +666,54 @@
"initial_soc_percentage": 54 "initial_soc_percentage": 54
}, },
"start_solution": [ "start_solution": [
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, 1.0,
6.0, 5.0,
19.0,
10.0, 10.0,
4.0, 19.0,
2.0,
7.0, 7.0,
17.0,
18.0,
3.0,
15.0,
4.0,
10.0,
2.0,
3.0,
11.0, 11.0,
10.0 10.0,
5.0,
20.0,
2.0,
20.0,
11.0,
13.0,
11.0,
0.0,
1.0,
8.0,
4.0,
11.0,
8.0,
3.0,
0.0,
1.0,
12.0,
14.0,
13.0,
0.0,
13.0,
15.0,
12.0,
11.0,
17.0,
12.0,
3.0,
15.0,
18.0,
20.0,
7.0,
5.0
], ],
"washingstart": null "washingstart": null
} }

View File

@ -1,47 +1,47 @@
{ {
"ac_charge": [ "ac_charge": [
0.5,
0.0,
0.0,
0.0,
0.0,
0.75,
0.0,
0.5,
0.0,
1.0,
0.0,
0.0,
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, 0.0,
0.0, 0.0,
0.0, 0.0,
0.625,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
0.625, 0.625,
0.0, 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,
0.0, 0.0,
0.0, 0.0,
@ -101,17 +101,15 @@
], ],
"discharge_allowed": [ "discharge_allowed": [
0, 0,
0, 1,
1, 1,
0, 0,
0, 0,
1,
1,
1,
0, 0,
1,
0, 0,
1, 0,
0,
0,
1, 1,
0, 0,
0, 0,
@ -124,15 +122,14 @@
1, 1,
1, 1,
1, 1,
1,
1,
0, 0,
1, 1,
1, 1,
0, 0,
0, 0,
0, 0,
1,
1,
1,
0, 0,
0, 0,
0, 0,
@ -141,76 +138,79 @@
0, 0,
0, 0,
1, 1,
1,
0,
0, 0,
1, 1,
0, 0,
0, 0,
0, 0,
1, 0,
0,
0 0
], ],
"eautocharge_hours_float": [ "eautocharge_hours_float": [
0.0,
0.5,
0.0,
0.5,
0.375,
1.0,
0.875,
0.375,
0.5,
1.0,
0.875,
0.875,
0.875,
0.75,
0.5,
0.625,
0.875,
0.75,
0.5,
0.0,
0.625,
0.5,
0.0,
1.0,
0.625,
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.875,
0.75, 0.75,
0.875, 0.875,
0.5, 0.5,
0.375,
0.75,
0.875,
0.625,
0.375,
0.5,
0.375,
0.0,
0.875,
0.5,
0.75,
0.625,
0.875, 0.875,
0.0, 0.0,
0.375, 0.5,
0.875, 0.625,
1.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,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0
], ],
"result": { "result": {
"Last_Wh_pro_Stunde": [ "Last_Wh_pro_Stunde": [
12105.07, 4986.07,
10240.91, 1063.91,
10497.56, 14247.56,
12748.03, 12626.029999999999,
8907.67, 11529.67,
13981.82, 7731.82,
10393.22, 10393.22,
1730.78, 1103.78,
1129.12, 6373.12,
1178.71, 7733.71,
1050.98, 1050.98,
988.56, 988.56,
912.38, 912.38,
@ -221,7 +221,7 @@
608.79, 608.79,
556.31, 556.31,
488.89, 488.89,
506.91, 4256.91,
804.89, 804.89,
1141.98, 1141.98,
1056.97, 1056.97,
@ -231,8 +231,8 @@
1257.98, 1257.98,
1232.67, 1232.67,
871.26, 871.26,
860.88, 3985.88,
4027.009545454555, 1158.03,
1222.72, 1222.72,
1221.04, 1221.04,
949.99, 949.99,
@ -241,44 +241,44 @@
592.97 592.97
], ],
"EAuto_SoC_pro_Stunde": [ "EAuto_SoC_pro_Stunde": [
20.294999999999998, 11.555,
11.555,
26.85,
35.589999999999996, 35.589999999999996,
50.885000000000005, 48.699999999999996,
63.995000000000005, 59.62499999999999,
72.735, 74.92,
74.92,
83.66, 83.66,
98.955, 94.585,
100.0, 94.585,
100.0, 94.585,
100.0, 94.585,
100.0, 94.585,
100.0, 94.585,
100.0, 94.585,
100.0, 94.585,
100.0, 94.585,
100.0, 94.585,
100.0, 94.585,
100.0, 94.585,
100.0, 94.585,
100.0, 94.585,
100.0, 94.585,
100.0, 94.585,
100.0, 94.585,
100.0, 94.585,
100.0, 94.585,
100.0, 94.585,
100.0, 94.585,
100.0, 94.585,
100.0, 94.585,
100.0, 94.585,
100.0, 94.585,
100.0, 94.585,
100.0, 94.585,
100.0, 94.585,
100.0, 94.585
100.0,
100.0,
100.0
], ],
"Einnahmen_Euro_pro_Stunde": [ "Einnahmen_Euro_pro_Stunde": [
0.0, 0.0,
@ -313,24 +313,24 @@
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
0.0348376, 0.0,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
0.0 0.0
], ],
"Gesamt_Verluste": 8823.859090909093, "Gesamt_Verluste": 9258.73062020124,
"Gesamtbilanz_Euro": 12.348447740818184, "Gesamtbilanz_Euro": 12.332782378812306,
"Gesamteinnahmen_Euro": 0.0348376, "Gesamteinnahmen_Euro": 0.0,
"Gesamtkosten_Euro": 12.383285340818183, "Gesamtkosten_Euro": 12.332782378812306,
"Home_appliance_wh_per_hour": [ "Home_appliance_wh_per_hour": [
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
2500.0,
2500.0,
0.0, 0.0,
2500.0,
2500.0,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
@ -365,16 +365,16 @@
0.0 0.0
], ],
"Kosten_Euro_pro_Stunde": [ "Kosten_Euro_pro_Stunde": [
2.54785212, 0.0,
0.928522392, 0.004569992000000018,
0.9189986259999999, 2.750373626,
2.1770732859999997, 2.1541494859999997,
0.53097063, 1.0128942300000001,
1.6959351, 0.0,
1.4118501319999999, 1.4118501319999999,
0.0, 0.0,
0.0, 0.0,
0.0, 0.55162953,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
@ -385,36 +385,36 @@
0.199865757, 0.199865757,
0.182970359, 0.182970359,
0.162995926, 0.162995926,
0.0, 1.4005233899999998,
0.0, 0.26411047,
0.0, 0.24530383800000005,
0.08545095, 0.08545095,
0.007989913613567745,
0.028255713342252034,
0.025392879919306634,
0.0, 0.0,
0.0, 0.0,
0.0003442778967139274,
0.6945180797975209,
0.0, 0.0,
0.0, 0.04565364324294593,
0.0,
0.0,
0.0,
0.651258356818184,
0.0,
0.08231598, 0.08231598,
0.174597189, 0.174597189,
0.293043269, 0.293043269,
0.0, 0.214398479,
0.16484566 0.16484566
], ],
"Netzbezug_Wh_pro_Stunde": [ "Netzbezug_Wh_pro_Stunde": [
11174.789999999999, 0.0,
4197.66, 20.660000000000082,
4390.82, 13140.82,
11586.34, 11464.339999999998,
2888.8500000000004, 5510.85,
8462.75, 0.0,
6423.339999999999, 6423.339999999999,
0.0, 0.0,
0.0, 0.0,
0.0, 1726.54,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
@ -425,23 +425,23 @@
608.79, 608.79,
556.31, 556.31,
488.89, 488.89,
0.0, 4256.91,
0.0, 799.85,
0.0, 806.3900000000001,
351.65, 351.65,
35.04348076126204,
127.73830624887898,
121.32288542430308,
0.0, 0.0,
0.0, 0.0,
1.7179535764168035,
3159.7728835192033,
0.0, 0.0,
0.0, 152.3311419517715,
0.0,
0.0,
0.0,
2868.979545454555,
0.0,
257.64, 257.64,
566.69, 566.69,
987.01, 987.01,
0.0, 733.99,
592.97 592.97
], ],
"Netzeinspeisung_Wh_pro_Stunde": [ "Netzeinspeisung_Wh_pro_Stunde": [
@ -477,7 +477,7 @@
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
497.68000000000006, 0.0,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
@ -485,16 +485,16 @@
0.0 0.0
], ],
"Verluste_Pro_Stunde": [ "Verluste_Pro_Stunde": [
708.0, 760.062272727273,
1164.818181818182, 0.0,
1164.818181818182, 933.0,
864.0, 726.0,
276.0, 414.0,
795.0, 646.7386363636365,
483.0, 483.0,
187.4616000000001, 230.91336797704525,
97.67399999999998, 880.0977272727268,
23.391818181818195, 1026.818181818182,
99.72409090909093, 99.72409090909093,
133.72909090909081, 133.72909090909081,
124.41545454545451, 124.41545454545451,
@ -505,64 +505,104 @@
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
69.12409090909085, 450.0,
109.0704545454546,
109.96227272727276,
0.0, 0.0,
15.439199999999985, 0.0,
53.855999999999995, 0.0,
159.6443999999999, 11.233982308648535,
21.032399999999996, 38.52740325013451,
538.2984000000001, 145.08565374908358,
441.924, 21.962728535423857,
260.0003999999999, 538.2984000000038,
514.2491454545468, 441.7178455708299,
630.8276539776955,
171.99990368477063,
41.441862965787436,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
100.08954545454549,
0.0 0.0
], ],
"akku_soc_pro_stunde": [ "akku_soc_pro_stunde": [
86.25, 62.54222623966943,
64.72796143250687, 62.54222623966943,
43.20592286501377, 75.04222623966943,
55.70592286501377, 87.54222623966943,
55.70592286501377, 87.54222623966943,
68.20592286501376, 78.01764807162535,
68.20592286501376, 78.01764807162535,
72.49652286501377, 83.83265434833275,
75.20968953168044, 64.76391295714818,
74.47131143250688, 43.24187438965506,
71.32345502754819, 40.094017984696386,
67.10220847107436, 35.87277142822256,
63.17495296143248, 31.945515918580686,
60.14202424242422, 28.912587199572425,
60.14202424242422, 28.912587199572425,
56.40558312672175, 25.176146083869945,
53.41686067493111, 22.187423632079316,
53.41686067493111, 22.187423632079316,
53.41686067493111, 22.187423632079316,
53.41686067493111, 22.187423632079316,
51.23491336088152, 34.68742363207931,
47.792032851239654, 34.68742363207931,
44.3210015151515, 34.68742363207931,
44.3210015151515, 34.68742363207931,
44.749868181818165, 34.99947869620843,
46.24586818181816, 36.0696843420455,
50.68043484848482, 40.099841390631155,
51.264668181818166, 40.249843096950585,
66.21740151515148, 55.20257643028218,
78.49306818181815, 67.47251658502745,
85.71530151515148, 84.99550697329678,
100.0, 88.77022785443704,
100.0, 89.9213907145978,
100.0, 89.9213907145978,
100.0, 89.9213907145978,
100.0, 89.9213907145978,
96.84060778236915, 89.9213907145978,
96.84060778236915 89.9213907145978
],
"Electricity_price": [
0.000228,
0.0002212,
0.0002093,
0.0001879,
0.0001838,
0.0002004,
0.0002198,
0.000227,
0.0002997,
0.0003195,
0.0003081,
0.0002969,
0.0002921,
0.000278,
0.0003384,
0.0003318,
0.0003284,
0.0003283,
0.0003289,
0.0003334,
0.000329,
0.0003302,
0.0003042,
0.000243,
0.000228,
0.0002212,
0.0002093,
0.0001879,
0.0001838,
0.0002004,
0.0002198,
0.000227,
0.0002997,
0.0003195,
0.0003081,
0.0002969,
0.0002921,
0.000278
] ]
}, },
"eauto_obj": { "eauto_obj": {
@ -671,107 +711,107 @@
"capacity_wh": 60000, "capacity_wh": 60000,
"charging_efficiency": 0.95, "charging_efficiency": 0.95,
"max_charge_power_w": 11040, "max_charge_power_w": 11040,
"soc_wh": 60000.0, "soc_wh": 56751.0,
"initial_soc_percentage": 5 "initial_soc_percentage": 5
}, },
"start_solution": [ "start_solution": [
0.0, 16.0,
4.0,
13.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,
4.0,
5.0,
14.0,
10.0,
18.0,
11.0, 11.0,
14.0,
2.0,
18.0,
3.0,
16.0,
4.0,
20.0,
12.0,
2.0,
18.0,
18.0,
1.0, 1.0,
0.0,
5.0,
13.0, 13.0,
1.0,
0.0,
2.0,
0.0,
2.0,
1.0,
6.0,
5.0,
1.0,
2.0,
6.0,
5.0,
5.0,
5.0,
4.0, 4.0,
7.0,
9.0,
8.0,
10.0,
12.0,
10.0,
10.0,
14.0,
8.0,
7.0,
2.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,
17.0,
11.0,
6.0,
14.0,
14.0,
14.0,
2.0, 2.0,
3.0, 3.0,
5.0, 5.0,
4.0, 4.0,
2.0,
0.0,
3.0,
2.0,
0.0,
6.0,
3.0,
0.0,
6.0,
3.0,
5.0, 5.0,
2.0,
1.0, 1.0,
6.0,
1.0,
3.0,
4.0,
4.0,
0.0,
2.0,
5.0,
5.0,
4.0, 4.0,
5.0, 5.0,
3.0,
1.0,
2.0, 2.0,
1.0,
0.0,
5.0,
2.0,
4.0,
3.0,
5.0, 5.0,
0.0, 0.0,
1.0,
5.0,
6.0,
2.0, 2.0,
14.0 3.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
13.0
], ],
"washingstart": 14 "washingstart": 13
} }

View File

@ -1,16 +1,16 @@
{ {
"ac_charge": [ "ac_charge": [
0.0,
0.0,
0.875,
0.0,
1.0,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
0.375,
0.0, 0.0,
0.875, 0.875,
0.0, 0.0,
0.375,
0.0,
0.0,
0.0,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
@ -102,21 +102,33 @@
"discharge_allowed": [ "discharge_allowed": [
1, 1,
0, 0,
0,
1, 1,
0, 0,
0,
0,
1,
1, 1,
0, 0,
1, 1,
0, 0,
0, 0,
1,
0, 0,
0, 0,
1, 1,
0, 0,
0,
1,
0,
0,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
0,
1, 1,
1, 1,
1, 1,
@ -134,46 +146,34 @@
1, 1,
1, 1,
1, 1,
0,
1,
0,
1,
1,
0,
1,
0,
1,
1,
1,
1,
1, 1,
1 1
], ],
"eautocharge_hours_float": [ "eautocharge_hours_float": [
0.75,
0.75,
0.5,
0.0,
1.0,
0.625, 0.625,
0.0,
0.875, 0.875,
0.75, 0.875,
1.0,
0.0,
0.75,
1.0,
1.0,
1.0,
0.375, 0.375,
0.0,
1.0,
0.75, 0.75,
0.5,
0.5,
1.0, 1.0,
0.625, 0.0,
0.875, 0.375,
0.5,
0.75,
0.375,
0.0,
0.5,
0.625, 0.625,
1.0, 1.0,
0.625,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
@ -201,15 +201,15 @@
], ],
"result": { "result": {
"Last_Wh_pro_Stunde": [ "Last_Wh_pro_Stunde": [
1053.07, 6297.07,
8929.91, 8929.91,
11808.56, 5253.5599999999995,
11620.03, 3632.0299999999997,
14151.67, 8907.67,
7609.82, 7731.82,
9082.22, 11704.22,
6347.78, 7658.78,
1756.12, 1129.12,
1178.71, 1178.71,
1050.98, 1050.98,
988.56, 988.56,
@ -241,44 +241,44 @@
592.97 592.97
], ],
"EAuto_SoC_pro_Stunde": [ "EAuto_SoC_pro_Stunde": [
5.0, 13.74,
18.11, 26.85,
35.589999999999996, 33.405,
33.405,
42.144999999999996,
53.06999999999999, 53.06999999999999,
70.55, 70.55,
77.105, 81.475,
90.215, 81.475,
98.955, 81.475,
100.0, 81.475,
100.0, 81.475,
100.0, 81.475,
100.0, 81.475,
100.0, 81.475,
100.0, 81.475,
100.0, 81.475,
100.0, 81.475,
100.0, 81.475,
100.0, 81.475,
100.0, 81.475,
100.0, 81.475,
100.0, 81.475,
100.0, 81.475,
100.0, 81.475,
100.0, 81.475,
100.0, 81.475,
100.0, 81.475,
100.0, 81.475,
100.0, 81.475,
100.0, 81.475,
100.0, 81.475,
100.0, 81.475,
100.0, 81.475,
100.0, 81.475,
100.0, 81.475,
100.0, 81.475,
100.0, 81.475
100.0,
100.0
], ],
"Einnahmen_Euro_pro_Stunde": [ "Einnahmen_Euro_pro_Stunde": [
0.0, 0.0,
@ -320,17 +320,17 @@
0.0, 0.0,
0.0 0.0
], ],
"Gesamt_Verluste": 7248.648818181819, "Gesamt_Verluste": 6757.733989740087,
"Gesamtbilanz_Euro": 8.568052366, "Gesamtbilanz_Euro": 6.952642478544519,
"Gesamteinnahmen_Euro": 0.0, "Gesamteinnahmen_Euro": 0.0,
"Gesamtkosten_Euro": 8.568052366, "Gesamtkosten_Euro": 6.952642478544519,
"Home_appliance_wh_per_hour": [ "Home_appliance_wh_per_hour": [
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
2500.0,
2500.0,
0.0, 0.0,
2500.0,
2500.0,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
@ -365,18 +365,14 @@
0.0 0.0
], ],
"Kosten_Euro_pro_Stunde": [ "Kosten_Euro_pro_Stunde": [
0.0, 1.22362812,
1.7445291920000001, 1.7445291920000001,
2.2398909259999997,
1.9651220859999998,
1.4948178300000001,
0.0,
1.1236923319999998,
0.0,
0.0,
0.0,
0.0,
0.0, 0.0,
0.4641768859999999,
0.53097063,
0.0,
1.7000079319999999,
1.0534661399999998,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
@ -387,10 +383,14 @@
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
0.182970359,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
0.0326838476973626,
0.007989913613567745,
0.012219458233588555,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
@ -405,18 +405,14 @@
0.0 0.0
], ],
"Netzbezug_Wh_pro_Stunde": [ "Netzbezug_Wh_pro_Stunde": [
0.0, 5366.79,
7886.66, 7886.66,
10701.82,
10458.34,
8132.85,
0.0,
5112.339999999999,
0.0,
0.0,
0.0,
0.0,
0.0, 0.0,
2470.3399999999997,
2888.8500000000004,
0.0,
7734.339999999999,
4640.82,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
@ -427,10 +423,14 @@
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
556.31,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
134.50143085334403,
35.04348076126204,
55.24167375040034,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
@ -485,15 +485,15 @@
0.0 0.0
], ],
"Verluste_Pro_Stunde": [ "Verluste_Pro_Stunde": [
16.744090909090914, 276.0,
414.0, 414.0,
772.4754545454543,
0.0,
276.0,
646.7386363636365,
552.0, 552.0,
552.0, 345.0,
552.0, 101.0335466817773,
492.1022727272725,
414.0,
730.0663636363638,
55.434,
23.391818181818195, 23.391818181818195,
99.72409090909093, 99.72409090909093,
133.72909090909081, 133.72909090909081,
@ -503,21 +503,21 @@
118.37045454545455, 118.37045454545455,
94.68272727272722, 94.68272727272722,
83.01681818181817, 83.01681818181817,
75.86045454545456, 0.0,
66.66681818181814, 66.66681818181814,
69.12409090909085, 69.12409090909085,
109.0704545454546, 109.0704545454546,
109.96227272727276, 109.96227272727276,
47.952272727272714, 29.61116851999853,
15.439199999999985, 11.233982308648535,
53.855999999999995, 48.41330768174524,
159.6443999999999, 161.62968357967037,
21.032399999999996, 21.962728535423857,
538.2984000000001, 538.2984000000038,
441.924, 441.95211196761403,
260.0003999999999, 260.56941082122324,
169.97160000000008, 171.99990368477063,
59.721600000000024, 62.214291413756285,
35.132727272727266, 35.132727272727266,
77.27590909090907, 77.27590909090907,
134.59227272727276, 134.59227272727276,
@ -525,44 +525,84 @@
80.85954545454547 80.85954545454547
], ],
"akku_soc_pro_stunde": [ "akku_soc_pro_stunde": [
79.4714617768595, 80.0,
79.4714617768595, 80.0,
79.4714617768595, 62.150396005509634,
79.4714617768595, 62.150396005509634,
79.4714617768595, 62.150396005509634,
70.47202134986226, 52.62581783746556,
70.47202134986226, 52.62581783746556,
56.13911845730028, 52.62581783746556,
56.76228512396694, 53.77091326251142,
56.02390702479339, 53.03253516333787,
52.876050619834714, 49.884678758379195,
48.654804063360885, 45.663432201905366,
44.72754855371902, 41.73617669226349,
41.69461983471075, 38.70324797325523,
39.47195282369147, 36.48058096223595,
35.73551170798899, 32.74413984653347,
32.746789256198355, 29.75541739474284,
30.126308884297526, 27.134937022842013,
27.731723829201112, 27.134937022842013,
25.627341942148767, 25.030555135789673,
23.445394628099184, 22.848607821740085,
20.002514118457306, 19.405727312098207,
16.531482782369153, 15.934695976010055,
15.017837809917364, 15.0,
15.446704476584031, 15.312055064129126,
16.94270447658403, 16.07020564583707,
21.377271143250695, 19.578139530578447,
21.961504476584032, 19.728141236897873,
36.91423780991737, 34.68087457022947,
49.189904476584026, 46.94341995234899,
56.41213780991736, 53.90006700591099,
61.133571143250684, 57.67478788705125,
62.79250447658402, 58.17025540478875,
61.68351687327823, 57.06126780148296,
59.2442520661157, 54.622002994320425,
54.99575860881543, 50.373509537020155,
51.836366391184576, 47.214117319389295,
49.28398174931129 44.661732677516014
],
"Electricity_price": [
0.000228,
0.0002212,
0.0002093,
0.0001879,
0.0001838,
0.0002004,
0.0002198,
0.000227,
0.0002997,
0.0003195,
0.0003081,
0.0002969,
0.0002921,
0.000278,
0.0003384,
0.0003318,
0.0003284,
0.0003283,
0.0003289,
0.0003334,
0.000329,
0.0003302,
0.0003042,
0.000243,
0.000228,
0.0002212,
0.0002093,
0.0001879,
0.0001838,
0.0002004,
0.0002198,
0.000227,
0.0002997,
0.0003195,
0.0003081,
0.0002969,
0.0002921,
0.000278
] ]
}, },
"eauto_obj": { "eauto_obj": {
@ -671,82 +711,76 @@
"capacity_wh": 60000, "capacity_wh": 60000,
"charging_efficiency": 0.95, "charging_efficiency": 0.95,
"max_charge_power_w": 11040, "max_charge_power_w": 11040,
"soc_wh": 60000.0, "soc_wh": 48885.0,
"initial_soc_percentage": 5 "initial_soc_percentage": 5
}, },
"start_solution": [ "start_solution": [
12.0, 7.0,
4.0, 4.0,
11.0,
15.0,
13.0,
19.0, 19.0,
9.0,
20.0,
14.0,
6.0,
9.0,
8.0, 8.0,
19.0, 15.0,
7.0, 5.0,
2.0,
2.0,
1.0,
3.0,
8.0,
14.0,
11.0, 11.0,
10.0, 1.0,
2.0,
8.0,
1.0,
2.0,
13.0,
14.0,
1.0,
9.0,
7.0,
9.0, 9.0,
10.0,
12.0, 12.0,
11.0, 12.0,
13.0,
11.0,
8.0, 8.0,
13.0,
13.0,
7.0,
7.0,
6.0,
13.0,
7.0,
7.0,
10.0, 10.0,
10.0, 11.0,
12.0,
9.0,
9.0, 9.0,
11.0, 11.0,
13.0, 11.0,
7.0, 9.0,
10.0,
10.0,
11.0,
10.0,
8.0, 8.0,
7.0, 13.0,
11.0,
8.0,
3.0,
5.0,
5.0,
1.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, 0.0,
6.0, 6.0,
3.0,
0.0,
5.0,
4.0, 4.0,
6.0, 6.0,
0.0, 0.0,
4.0,
6.0,
6.0,
6.0,
1.0, 1.0,
2.0,
4.0, 4.0,
1.0,
0.0,
2.0, 2.0,
2.0,
6.0,
3.0,
5.0,
3.0, 3.0,
6.0, 6.0,
3.0,
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
@ -771,7 +805,13 @@
0.0, 0.0,
0.0, 0.0,
0.0, 0.0,
14.0 0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
13.0
], ],
"washingstart": 14 "washingstart": 13
} }