Soc 1 hour shift fixed + some german -> english translations in ems

This commit is contained in:
Andreas 2024-12-22 12:03:48 +01:00 committed by Dominique Lasserre
parent 053e60aca4
commit 54eae5a871
14 changed files with 703 additions and 517 deletions

View File

@ -315,7 +315,7 @@ def run_optimization(real_world: bool = False, start_hour: int = 0, verbose: boo
# Initialize the optimization problem using the default configuration
config_eos = get_config()
config_eos.merge_settings_from_dict({"prediction_hours": 48, "optimization_hours": 24})
config_eos.merge_settings_from_dict({"prediction_hours": 48, "optimization_hours": 48})
opt_class = optimization_problem(verbose=verbose, fixed_seed=42)
# Perform the optimisation based on the provided parameters and start hour

View File

@ -135,19 +135,19 @@ class EnergieManagementSystem(SingletonMixin, ConfigMixin, PredictionMixin, Pyda
# TODO: Take from prediction
# -------------------------
gesamtlast: Optional[NDArray[Shape["*"], float]] = Field(
load_energy_array: Optional[NDArray[Shape["*"], float]] = Field(
default=None,
description="An array of floats representing the total load (consumption) in watts for different time intervals.",
)
pv_prognose_wh: Optional[NDArray[Shape["*"], float]] = Field(
pv_prediction_wh: Optional[NDArray[Shape["*"], float]] = Field(
default=None,
description="An array of floats representing the forecasted photovoltaic output in watts for different time intervals.",
)
strompreis_euro_pro_wh: Optional[NDArray[Shape["*"], float]] = Field(
elect_price_hourly: Optional[NDArray[Shape["*"], float]] = Field(
default=None,
description="An array of floats representing the electricity price in euros per watt-hour for different time intervals.",
)
einspeiseverguetung_euro_pro_wh_arr: Optional[NDArray[Shape["*"], float]] = Field(
elect_revenue_per_hour_arr: Optional[NDArray[Shape["*"], float]] = Field(
default=None,
description="An array of floats representing the feed-in compensation in euros per watt-hour.",
)
@ -156,8 +156,8 @@ class EnergieManagementSystem(SingletonMixin, ConfigMixin, PredictionMixin, Pyda
# TODO: Move to devices
# -------------------------
akku: Optional[Battery] = Field(default=None, description="TBD.")
eauto: Optional[Battery] = Field(default=None, description="TBD.")
battery: Optional[Battery] = Field(default=None, description="TBD.")
ev: Optional[Battery] = Field(default=None, description="TBD.")
home_appliance: Optional[HomeAppliance] = Field(default=None, description="TBD.")
inverter: Optional[Inverter] = Field(default=None, description="TBD.")
@ -172,23 +172,25 @@ class EnergieManagementSystem(SingletonMixin, ConfigMixin, PredictionMixin, Pyda
def set_parameters(
self,
parameters: EnergieManagementSystemParameters,
eauto: Optional[Battery] = None,
ev: Optional[Battery] = None,
home_appliance: Optional[HomeAppliance] = None,
inverter: Optional[Inverter] = None,
) -> None:
self.gesamtlast = np.array(parameters.gesamtlast, float)
self.pv_prognose_wh = np.array(parameters.pv_prognose_wh, float)
self.strompreis_euro_pro_wh = np.array(parameters.strompreis_euro_pro_wh, float)
self.einspeiseverguetung_euro_pro_wh_arr = (
self.load_energy_array = np.array(parameters.gesamtlast, float)
self.pv_prediction_wh = np.array(parameters.pv_prognose_wh, float)
self.elect_price_hourly = np.array(parameters.strompreis_euro_pro_wh, float)
self.elect_revenue_per_hour_arr = (
parameters.einspeiseverguetung_euro_pro_wh
if isinstance(parameters.einspeiseverguetung_euro_pro_wh, list)
else np.full(len(self.gesamtlast), parameters.einspeiseverguetung_euro_pro_wh, float)
else np.full(
len(self.load_energy_array), parameters.einspeiseverguetung_euro_pro_wh, float
)
)
if inverter is not None:
self.akku = inverter.akku
self.battery = inverter.battery
else:
self.akku = None
self.eauto = eauto
self.battery = None
self.ev = ev
self.home_appliance = home_appliance
self.inverter = inverter
self.ac_charge_hours = np.full(self.config.prediction_hours, 0.0)
@ -196,8 +198,8 @@ class EnergieManagementSystem(SingletonMixin, ConfigMixin, PredictionMixin, Pyda
self.ev_charge_hours = np.full(self.config.prediction_hours, 0.0)
def set_akku_discharge_hours(self, ds: np.ndarray) -> None:
if self.akku is not None:
self.akku.set_discharge_per_hour(ds)
if self.battery is not None:
self.battery.set_discharge_per_hour(ds)
def set_akku_ac_charge_hours(self, ds: np.ndarray) -> None:
self.ac_charge_hours = ds
@ -213,10 +215,10 @@ class EnergieManagementSystem(SingletonMixin, ConfigMixin, PredictionMixin, Pyda
self.home_appliance.set_starting_time(ds, global_start_hour=global_start_hour)
def reset(self) -> None:
if self.eauto:
self.eauto.reset()
if self.akku:
self.akku.reset()
if self.ev:
self.ev.reset()
if self.battery:
self.battery.reset()
def run(
self,
@ -269,12 +271,11 @@ class EnergieManagementSystem(SingletonMixin, ConfigMixin, PredictionMixin, Pyda
start_datetime = to_datetime().set(hour=start_hour, minute=0, second=0, microsecond=0)
self.set_start_datetime(start_datetime)
def simuliere_ab_jetzt(self) -> dict[str, Any]:
jetzt = to_datetime().now()
start_stunde = jetzt.hour
return self.simuliere(start_stunde)
def simulate_start_now(self) -> dict[str, Any]:
start_hour = to_datetime().now().hour
return self.simulate(start_hour)
def simuliere(self, start_stunde: int) -> dict[str, Any]:
def simulate(self, start_hour: int) -> dict[str, Any]:
"""hour.
akku_soc_pro_stunde begin of the hour, initial hour state!
@ -282,139 +283,150 @@ class EnergieManagementSystem(SingletonMixin, ConfigMixin, PredictionMixin, Pyda
"""
# Check for simulation integrity
if (
self.gesamtlast is None
or self.pv_prognose_wh is None
or self.strompreis_euro_pro_wh is None
self.load_energy_array is None
or self.pv_prediction_wh is None
or self.elect_price_hourly is None
or self.ev_charge_hours is None
or self.ac_charge_hours is None
or self.dc_charge_hours is None
or self.einspeiseverguetung_euro_pro_wh_arr is None
or self.elect_revenue_per_hour_arr is None
):
error_msg = (
f"Mandatory data missing - "
f"Load Curve: {self.gesamtlast}, "
f"PV Forecast: {self.pv_prognose_wh}, "
f"Electricity Price: {self.strompreis_euro_pro_wh}, "
f"Load Curve: {self.load_energy_array}, "
f"PV Forecast: {self.pv_prediction_wh}, "
f"Electricity Price: {self.elect_price_hourly}, "
f"EV Charge Hours: {self.ev_charge_hours}, "
f"AC Charge Hours: {self.ac_charge_hours}, "
f"DC Charge Hours: {self.dc_charge_hours}, "
f"Feed-in tariff: {self.einspeiseverguetung_euro_pro_wh_arr}"
f"Feed-in tariff: {self.elect_revenue_per_hour_arr}"
)
logger.error(error_msg)
raise ValueError(error_msg)
lastkurve_wh = self.gesamtlast
load_energy_array = self.load_energy_array
if not (len(lastkurve_wh) == len(self.pv_prognose_wh) == len(self.strompreis_euro_pro_wh)):
error_msg = f"Array sizes do not match: Load Curve = {len(lastkurve_wh)}, PV Forecast = {len(self.pv_prognose_wh)}, Electricity Price = {len(self.strompreis_euro_pro_wh)}"
if not (
len(load_energy_array) == len(self.pv_prediction_wh) == len(self.elect_price_hourly)
):
error_msg = f"Array sizes do not match: Load Curve = {len(load_energy_array)}, PV Forecast = {len(self.pv_prediction_wh)}, Electricity Price = {len(self.elect_price_hourly)}"
logger.error(error_msg)
raise ValueError(error_msg)
# Optimized total hours calculation
ende = len(lastkurve_wh)
total_hours = ende - start_stunde
end_hour = len(load_energy_array)
total_hours = end_hour - start_hour
# Pre-allocate arrays for the results, optimized for speed
last_wh_pro_stunde = np.full((total_hours), np.nan)
netzeinspeisung_wh_pro_stunde = np.full((total_hours), np.nan)
netzbezug_wh_pro_stunde = np.full((total_hours), np.nan)
kosten_euro_pro_stunde = np.full((total_hours), np.nan)
einnahmen_euro_pro_stunde = np.full((total_hours), np.nan)
akku_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)
loads_energy_per_hour = np.full((total_hours), np.nan)
feedin_energy_per_hour = np.full((total_hours), np.nan)
consumption_energy_per_hour = np.full((total_hours), np.nan)
costs_per_hour = np.full((total_hours), np.nan)
revenue_per_hour = np.full((total_hours), np.nan)
soc_per_hour = np.full((total_hours), np.nan) # Hour End State
soc_ev_per_hour = np.full((total_hours), np.nan)
losses_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
if self.akku:
akku_soc_pro_stunde[0] = self.akku.current_soc_percentage()
if self.eauto:
eauto_soc_pro_stunde[0] = self.eauto.current_soc_percentage()
if self.battery:
soc_per_hour[0] = self.battery.current_soc_percentage()
if self.ev:
soc_ev_per_hour[0] = self.ev.current_soc_percentage()
for stunde in range(start_stunde, ende):
stunde_since_now = stunde - start_stunde
for hour in range(start_hour, end_hour):
hour_since_now = hour - start_hour
# save begin states
if self.battery:
soc_per_hour[hour_since_now] = self.battery.current_soc_percentage()
else:
soc_per_hour[hour_since_now] = 0.0
if self.ev:
soc_ev_per_hour[hour_since_now] = self.ev.current_soc_percentage()
# Accumulate loads and PV generation
verbrauch = self.gesamtlast[stunde]
verluste_wh_pro_stunde[stunde_since_now] = 0.0
consumption = self.load_energy_array[hour]
losses_wh_per_hour[hour_since_now] = 0.0
# Home appliances
if self.home_appliance:
ha_load = self.home_appliance.get_load_for_hour(stunde)
verbrauch += ha_load
home_appliance_wh_per_hour[stunde_since_now] = ha_load
ha_load = self.home_appliance.get_load_for_hour(hour)
consumption += ha_load
home_appliance_wh_per_hour[hour_since_now] = ha_load
# E-Auto handling
if self.eauto:
if self.ev_charge_hours[stunde] > 0:
geladene_menge_eauto, verluste_eauto = self.eauto.charge_energy(
None, stunde, relative_power=self.ev_charge_hours[stunde]
if self.ev:
if self.ev_charge_hours[hour] > 0:
loaded_energy_ev, verluste_eauto = self.ev.charge_energy(
None, hour, relative_power=self.ev_charge_hours[hour]
)
verbrauch += geladene_menge_eauto
verluste_wh_pro_stunde[stunde_since_now] += verluste_eauto
eauto_soc_pro_stunde[stunde_since_now] = self.eauto.current_soc_percentage()
consumption += loaded_energy_ev
losses_wh_per_hour[hour_since_now] += verluste_eauto
# Process inverter logic
netzeinspeisung, netzbezug, verluste, eigenverbrauch = (0.0, 0.0, 0.0, 0.0)
if self.akku:
self.akku.set_charge_allowed_for_hour(self.dc_charge_hours[stunde], stunde)
energy_feedin_grid_actual, energy_consumption_grid_actual, losses, eigenverbrauch = (
0.0,
0.0,
0.0,
0.0,
)
if self.battery:
self.battery.set_charge_allowed_for_hour(self.dc_charge_hours[hour], hour)
if self.inverter:
erzeugung = self.pv_prognose_wh[stunde]
netzeinspeisung, netzbezug, verluste, eigenverbrauch = self.inverter.process_energy(
erzeugung, verbrauch, stunde
)
energy_produced = self.pv_prediction_wh[hour]
(
energy_feedin_grid_actual,
energy_consumption_grid_actual,
losses,
eigenverbrauch,
) = self.inverter.process_energy(energy_produced, consumption, hour)
# AC PV Battery Charge
if self.akku and self.ac_charge_hours[stunde] > 0.0:
self.akku.set_charge_allowed_for_hour(1, stunde)
geladene_menge, verluste_wh = self.akku.charge_energy(
None, stunde, relative_power=self.ac_charge_hours[stunde]
if self.battery and self.ac_charge_hours[hour] > 0.0:
self.battery.set_charge_allowed_for_hour(1, hour)
battery_charged_energy_actual, battery_losses_actual = self.battery.charge_energy(
None, hour, relative_power=self.ac_charge_hours[hour]
)
# print(stunde, " ", geladene_menge, " ",self.ac_charge_hours[stunde]," ",self.akku.current_soc_percentage())
verbrauch += geladene_menge
verbrauch += verluste_wh
netzbezug += geladene_menge
netzbezug += verluste_wh
verluste_wh_pro_stunde[stunde_since_now] += verluste_wh
# print(hour, " ", battery_charged_energy_actual, " ",self.ac_charge_hours[hour]," ",self.battery.current_soc_percentage())
consumption += battery_charged_energy_actual
consumption += battery_losses_actual
energy_consumption_grid_actual += battery_charged_energy_actual
energy_consumption_grid_actual += battery_losses_actual
losses_wh_per_hour[hour_since_now] += battery_losses_actual
netzeinspeisung_wh_pro_stunde[stunde_since_now] = netzeinspeisung
netzbezug_wh_pro_stunde[stunde_since_now] = netzbezug
verluste_wh_pro_stunde[stunde_since_now] += verluste
last_wh_pro_stunde[stunde_since_now] = verbrauch
electricity_price_per_hour[stunde_since_now] = self.strompreis_euro_pro_wh[stunde]
feedin_energy_per_hour[hour_since_now] = energy_feedin_grid_actual
consumption_energy_per_hour[hour_since_now] = energy_consumption_grid_actual
losses_wh_per_hour[hour_since_now] += losses
loads_energy_per_hour[hour_since_now] = consumption
electricity_price_per_hour[hour_since_now] = self.elect_price_hourly[hour]
# Financial calculations
kosten_euro_pro_stunde[stunde_since_now] = (
netzbezug * self.strompreis_euro_pro_wh[stunde]
costs_per_hour[hour_since_now] = (
energy_consumption_grid_actual * self.elect_price_hourly[hour]
)
einnahmen_euro_pro_stunde[stunde_since_now] = (
netzeinspeisung * self.einspeiseverguetung_euro_pro_wh_arr[stunde]
revenue_per_hour[hour_since_now] = (
energy_feedin_grid_actual * self.elect_revenue_per_hour_arr[hour]
)
# Akku SOC tracking
if self.akku:
akku_soc_pro_stunde[stunde_since_now] = self.akku.current_soc_percentage()
else:
akku_soc_pro_stunde[stunde_since_now] = 0.0
# Total cost and return
gesamtkosten_euro = np.nansum(kosten_euro_pro_stunde) - np.nansum(einnahmen_euro_pro_stunde)
gesamtkosten_euro = np.nansum(costs_per_hour) - np.nansum(revenue_per_hour)
# Prepare output dictionary
out: Dict[str, Union[np.ndarray, float]] = {
"Last_Wh_pro_Stunde": last_wh_pro_stunde,
"Netzeinspeisung_Wh_pro_Stunde": netzeinspeisung_wh_pro_stunde,
"Netzbezug_Wh_pro_Stunde": netzbezug_wh_pro_stunde,
"Kosten_Euro_pro_Stunde": kosten_euro_pro_stunde,
"akku_soc_pro_stunde": akku_soc_pro_stunde,
"Einnahmen_Euro_pro_Stunde": einnahmen_euro_pro_stunde,
"Last_Wh_pro_Stunde": loads_energy_per_hour,
"Netzeinspeisung_Wh_pro_Stunde": feedin_energy_per_hour,
"Netzbezug_Wh_pro_Stunde": consumption_energy_per_hour,
"Kosten_Euro_pro_Stunde": costs_per_hour,
"akku_soc_pro_stunde": soc_per_hour,
"Einnahmen_Euro_pro_Stunde": revenue_per_hour,
"Gesamtbilanz_Euro": gesamtkosten_euro,
"EAuto_SoC_pro_Stunde": eauto_soc_pro_stunde,
"Gesamteinnahmen_Euro": np.nansum(einnahmen_euro_pro_stunde),
"Gesamtkosten_Euro": np.nansum(kosten_euro_pro_stunde),
"Verluste_Pro_Stunde": verluste_wh_pro_stunde,
"Gesamt_Verluste": np.nansum(verluste_wh_pro_stunde),
"EAuto_SoC_pro_Stunde": soc_ev_per_hour,
"Gesamteinnahmen_Euro": np.nansum(revenue_per_hour),
"Gesamtkosten_Euro": np.nansum(costs_per_hour),
"Verluste_Pro_Stunde": losses_wh_per_hour,
"Gesamt_Verluste": np.nansum(losses_wh_per_hour),
"Home_appliance_wh_per_hour": home_appliance_wh_per_hour,
"Electricity_price": electricity_price_per_hour,
}

View File

@ -15,7 +15,7 @@
"loadakkudoktor_year_energy": null,
"longitude": null,
"optimization_ev_available_charge_rates_percent": [],
"optimization_hours": 24,
"optimization_hours": 48,
"optimization_penalty": null,
"prediction_historic_hours": 48,
"prediction_hours": 48,

View File

@ -160,20 +160,20 @@ class Devices(SingletonMixin, DevicesBase):
# Devices
# TODO: Make devices class a container of device simulation providers.
# Device simulations to be used are then enabled in the configuration.
akku: ClassVar[Battery] = Battery(provider_id="GenericBattery")
eauto: ClassVar[Battery] = Battery(provider_id="GenericBEV")
battery: ClassVar[Battery] = Battery(provider_id="GenericBattery")
ev: ClassVar[Battery] = Battery(provider_id="GenericBEV")
home_appliance: ClassVar[HomeAppliance] = HomeAppliance(provider_id="GenericDishWasher")
inverter: ClassVar[Inverter] = Inverter(
self_consumption_predictor=SelfConsumptionPropabilityInterpolator,
akku=akku,
battery=battery,
provider_id="GenericInverter",
)
def update_data(self) -> None:
"""Update device simulation data."""
# Assure devices are set up
self.akku.setup()
self.eauto.setup()
self.battery.setup()
self.ev.setup()
self.home_appliance.setup()
self.inverter.setup()
@ -190,10 +190,10 @@ class Devices(SingletonMixin, DevicesBase):
# Set initial state
simulation_step = to_duration("1 hour")
if self.akku:
self.akku_soc_pro_stunde[0] = self.akku.current_soc_percentage()
if self.eauto:
self.eauto_soc_pro_stunde[0] = self.eauto.current_soc_percentage()
if self.battery:
self.akku_soc_pro_stunde[0] = self.battery.current_soc_percentage()
if self.ev:
self.eauto_soc_pro_stunde[0] = self.ev.current_soc_percentage()
# Get predictions for full device simulation time range
# gesamtlast[stunde]
@ -235,19 +235,19 @@ class Devices(SingletonMixin, DevicesBase):
self.home_appliance_wh_per_hour[stunde_since_now] = ha_load
# E-Auto handling
if self.eauto:
if self.ev:
if self.ev_charge_hours[hour] > 0:
geladene_menge_eauto, verluste_eauto = self.eauto.charge_energy(
geladene_menge_eauto, verluste_eauto = self.ev.charge_energy(
None, hour, relative_power=self.ev_charge_hours[hour]
)
consumption += geladene_menge_eauto
self.verluste_wh_pro_stunde[stunde_since_now] += verluste_eauto
self.eauto_soc_pro_stunde[stunde_since_now] = self.eauto.current_soc_percentage()
self.eauto_soc_pro_stunde[stunde_since_now] = self.ev.current_soc_percentage()
# Process inverter logic
grid_export, grid_import, losses, self_consumption = (0.0, 0.0, 0.0, 0.0)
if self.akku:
self.akku.set_charge_allowed_for_hour(self.dc_charge_hours[hour], hour)
if self.battery:
self.battery.set_charge_allowed_for_hour(self.dc_charge_hours[hour], hour)
if self.inverter:
generation = pvforecast_ac_power[hour]
grid_export, grid_import, losses, self_consumption = self.inverter.process_energy(
@ -255,12 +255,12 @@ class Devices(SingletonMixin, DevicesBase):
)
# AC PV Battery Charge
if self.akku and self.ac_charge_hours[hour] > 0.0:
self.akku.set_charge_allowed_for_hour(1, hour)
geladene_menge, verluste_wh = self.akku.charge_energy(
if self.battery and self.ac_charge_hours[hour] > 0.0:
self.battery.set_charge_allowed_for_hour(1, hour)
geladene_menge, verluste_wh = self.battery.charge_energy(
None, hour, relative_power=self.ac_charge_hours[hour]
)
# print(stunde, " ", geladene_menge, " ",self.ac_charge_hours[stunde]," ",self.akku.current_soc_percentage())
# print(stunde, " ", geladene_menge, " ",self.ac_charge_hours[stunde]," ",self.battery.current_soc_percentage())
consumption += geladene_menge
grid_import += geladene_menge
self.verluste_wh_pro_stunde[stunde_since_now] += verluste_wh
@ -278,9 +278,9 @@ class Devices(SingletonMixin, DevicesBase):
grid_export * self.einspeiseverguetung_euro_pro_wh_arr[hour]
)
# Akku SOC tracking
if self.akku:
self.akku_soc_pro_stunde[stunde_since_now] = self.akku.current_soc_percentage()
# battery SOC tracking
if self.battery:
self.akku_soc_pro_stunde[stunde_since_now] = self.battery.current_soc_percentage()
else:
self.akku_soc_pro_stunde[stunde_since_now] = 0.0

View File

@ -19,7 +19,7 @@ class Inverter(DeviceBase):
self,
self_consumption_predictor: RegularGridInterpolator,
parameters: Optional[InverterParameters] = None,
akku: Optional[Battery] = None,
battery: Optional[Battery] = None,
provider_id: Optional[str] = None,
):
# Configuration initialisation
@ -29,13 +29,13 @@ class Inverter(DeviceBase):
self.prefix = "inverter"
# Parameter initialisiation
self.parameters = parameters
if akku is None:
if battery is None:
# For the moment raise exception
# TODO: Make akku configurable by config
# TODO: Make battery configurable by config
error_msg = "Battery for PV inverter is mandatory."
logger.error(error_msg)
raise NotImplementedError(error_msg)
self.akku = akku # Connection to a battery object
self.battery = battery # Connection to a battery object
self.self_consumption_predictor = self_consumption_predictor
self.initialised = False
@ -86,7 +86,7 @@ class Inverter(DeviceBase):
if remaining_load_evq > 0:
# Akku muss den Restverbrauch decken
from_battery, discharge_losses = self.akku.discharge_energy(
from_battery, discharge_losses = self.battery.discharge_energy(
remaining_load_evq, hour
)
remaining_load_evq -= from_battery # Restverbrauch nach Akkuentladung
@ -101,7 +101,9 @@ class Inverter(DeviceBase):
if remaining_power > 0:
# Load battery with excess energy
charged_energie, charge_losses = self.akku.charge_energy(remaining_power, hour)
charged_energie, charge_losses = self.battery.charge_energy(
remaining_power, hour
)
remaining_surplus = remaining_power - (charged_energie + charge_losses)
# Feed-in to the grid based on remaining capacity
@ -122,7 +124,7 @@ class Inverter(DeviceBase):
available_ac_power = max(self.max_power_wh - generation, 0)
# Discharge battery to cover shortfall, if possible
battery_discharge, discharge_losses = self.akku.discharge_energy(
battery_discharge, discharge_losses = self.battery.discharge_energy(
min(shortfall, available_ac_power), hour
)
losses += discharge_losses

View File

@ -388,7 +388,7 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
else:
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.simulate(self.ems.start_datetime.hour)
def evaluate(
self,
@ -441,14 +441,14 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
individual.extra_data = ( # type: ignore[attr-defined]
o["Gesamtbilanz_Euro"],
o["Gesamt_Verluste"],
parameters.eauto.min_soc_percentage - self.ems.eauto.current_soc_percentage()
if parameters.eauto and self.ems.eauto
parameters.eauto.min_soc_percentage - self.ems.ev.current_soc_percentage()
if parameters.eauto and self.ems.ev
else 0,
)
# Adjust total balance with battery value and penalties for unmet SOC
restwert_akku = (
self.ems.akku.current_energy_content() * parameters.ems.preis_euro_pro_wh_akku
self.ems.battery.current_energy_content() * parameters.ems.preis_euro_pro_wh_akku
)
gesamtbilanz += -restwert_akku
@ -456,8 +456,8 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
gesamtbilanz += max(
0,
(
parameters.eauto.min_soc_percentage - self.ems.eauto.current_soc_percentage()
if parameters.eauto and self.ems.eauto
parameters.eauto.min_soc_percentage - self.ems.ev.current_soc_percentage()
if parameters.eauto and self.ems.ev
else 0
)
* self.config.optimization_penalty,
@ -565,7 +565,7 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
self.ems.set_parameters(
parameters.ems,
inverter=inverter,
eauto=eauto,
ev=eauto,
home_appliance=dishwasher,
)
self.ems.set_start_hour(start_hour)
@ -606,7 +606,7 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
"discharge_allowed": discharge.tolist(),
"eautocharge_hours_float": eautocharge_hours_float,
"result": o,
"eauto_obj": self.ems.eauto.to_dict(),
"eauto_obj": self.ems.ev.to_dict(),
"start_solution": start_solution,
"spuelstart": washingstart_int,
"extra_data": extra_data,
@ -622,7 +622,7 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
"discharge_allowed": discharge,
"eautocharge_hours_float": eautocharge_hours_float,
"result": SimulationResult(**o),
"eauto_obj": self.ems.eauto,
"eauto_obj": self.ems.ev,
"start_solution": start_solution,
"washingstart": washingstart_int,
}

View File

@ -239,7 +239,7 @@ def create_ems_instance() -> EnergieManagementSystem:
gesamtlast=gesamtlast,
),
inverter=inverter,
eauto=eauto,
ev=eauto,
home_appliance=home_appliance,
)
@ -252,7 +252,7 @@ def test_simulation(create_ems_instance):
# Simulate starting from hour 1 (this value can be adjusted)
result = ems.simuliere(start_stunde=start_hour)
result = ems.simulate(start_hour=start_hour)
# visualisiere_ergebnisse(
# ems.gesamtlast,
@ -338,11 +338,11 @@ def test_simulation(create_ems_instance):
# Check the values in 'akku_soc_pro_stunde'
assert (
result["akku_soc_pro_stunde"][-1] == 28.675
), "The value at index -1 of 'akku_soc_pro_stunde' should be 28.675."
result["akku_soc_pro_stunde"][-1] == 42.151590909090906
), "The value at index -1 of 'akku_soc_pro_stunde' should be 42.151590909090906."
assert (
result["akku_soc_pro_stunde"][1] == 25.379090909090905
), "The value at index 1 of 'akku_soc_pro_stunde' should be 25.379090909090905."
result["akku_soc_pro_stunde"][1] == 60.08659090909091
), "The value at index 1 of 'akku_soc_pro_stunde' should be 60.08659090909091."
# Check home appliances
assert (

View File

@ -144,7 +144,7 @@ def create_ems_instance() -> EnergieManagementSystem:
gesamtlast=gesamtlast,
),
inverter=inverter,
eauto=eauto,
ev=eauto,
home_appliance=home_appliance,
)
@ -163,7 +163,7 @@ def test_simulation(create_ems_instance):
ems = create_ems_instance
# Simulate starting from hour 0 (this value can be adjusted)
result = ems.simuliere(start_stunde=start_hour)
result = ems.simulate(start_hour=start_hour)
# --- Pls do not remove! ---
# visualisiere_ergebnisse(
@ -233,12 +233,12 @@ def test_simulation(create_ems_instance):
), "The length of 'akku_soc_pro_stunde' should be 48."
# Verfify DC and AC Charge Bins
assert (
abs(result["akku_soc_pro_stunde"][2] - 44.70681818181818) < 1e-5
), "'akku_soc_pro_stunde[2]' should be 44.70681818181818."
assert (
abs(result["akku_soc_pro_stunde"][10] - 10.0) < 1e-5
), "'akku_soc_pro_stunde[10]' should be 10."
assert (
abs(result["akku_soc_pro_stunde"][11] - 79.275184) < 1e-5
), "'akku_soc_pro_stunde[11]' should be 79.275184."
assert (
abs(result["Netzeinspeisung_Wh_pro_Stunde"][10] - 3946.93) < 1e-3
@ -249,8 +249,8 @@ def test_simulation(create_ems_instance):
), "'Netzeinspeisung_Wh_pro_Stunde[11]' should be 0.0."
assert (
abs(result["akku_soc_pro_stunde"][20] - 98) < 1e-5
), "'akku_soc_pro_stunde[11]' should be 98."
abs(result["akku_soc_pro_stunde"][20] - 10) < 1e-5
), "'akku_soc_pro_stunde[20]' should be 10."
assert (
abs(result["Last_Wh_pro_Stunde"][20] - 6050.98) < 1e-3
), "'Netzeinspeisung_Wh_pro_Stunde[11]' should be 0.0."

View File

@ -44,7 +44,7 @@ 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()
config_eos.merge_settings_from_dict({"prediction_hours": 48, "optimization_hours": 24})
config_eos.merge_settings_from_dict({"prediction_hours": 48, "optimization_hours": 48})
# Load input and output data
file = DIR_TESTDATA / fn_in

View File

@ -25,7 +25,7 @@ def inverter(mock_battery):
/ "data"
/ "regular_grid_interpolator.pkl"
)
return Inverter(sc, InverterParameters(max_power_wh=500.0), akku=mock_battery)
return Inverter(sc, InverterParameters(max_power_wh=500.0), battery=mock_battery)
def test_process_energy_excess_generation(inverter, mock_battery):

View File

@ -1,34 +1,162 @@
{
"ems": {
"preis_euro_pro_wh_akku": 0.0001,
"preis_euro_pro_wh_akku": 0.0,
"einspeiseverguetung_euro_pro_wh": 0.00007,
"gesamtlast": [
676.71, 876.19, 527.13, 468.88, 531.38, 517.95, 483.15, 472.28, 1011.68, 995.00,
1053.07, 1063.91, 1320.56, 1132.03, 1163.67, 1176.82, 1216.22, 1103.78, 1129.12,
1178.71, 1050.98, 988.56, 912.38, 704.61, 516.37, 868.05, 694.34, 608.79, 556.31,
488.89, 506.91, 804.89, 1141.98, 1056.97, 992.46, 1155.99, 827.01, 1257.98, 1232.67,
871.26, 860.88, 1158.03, 1222.72, 1221.04, 949.99, 987.01, 733.99, 592.97
676.71,
876.19,
527.13,
468.88,
531.38,
517.95,
483.15,
472.28,
1011.68,
995.0,
1053.07,
1063.91,
1320.56,
1132.03,
1163.67,
1176.82,
1216.22,
1103.78,
1129.12,
1178.71,
1050.98,
988.56,
912.38,
704.61,
516.37,
868.05,
694.34,
608.79,
556.31,
488.89,
506.91,
804.89,
1141.98,
1056.97,
992.46,
1155.99,
827.01,
1257.98,
1232.67,
871.26,
860.88,
1158.03,
1222.72,
1221.04,
949.99,
987.01,
733.99,
592.97
],
"pv_prognose_wh": [
0, 0, 0, 0, 0, 0, 0, 8.05, 352.91, 728.51, 930.28, 1043.25, 1106.74, 1161.69,
6018.82, 5519.07, 3969.88, 3017.96, 1943.07, 1007.17, 319.67, 7.88, 0, 0, 0, 0,
0, 0, 0, 0, 0, 5.04, 335.59, 705.32, 1121.12, 1604.79, 2157.38, 1433.25, 5718.49,
4553.96, 3027.55, 2574.46, 1720.4, 963.4, 383.3, 0, 0, 0
0,
0,
0,
0,
0,
0,
0,
8.05,
352.91,
728.51,
930.28,
1043.25,
1106.74,
1161.69,
6018.82,
5519.07,
3969.88,
3017.96,
1943.07,
1007.17,
319.67,
7.88,
0,
0,
0,
0,
0,
0,
0,
0,
0,
5.04,
335.59,
705.32,
1121.12,
1604.79,
2157.38,
1433.25,
5718.49,
4553.96,
3027.55,
2574.46,
1720.4,
963.4,
383.3,
0,
0,
0
],
"strompreis_euro_pro_wh": [
0.0003384, 0.0003318, 0.0003284, 0.0003283, 0.0003289, 0.0003334, 0.0003290,
0.0003302, 0.0003042, 0.0002430, 0.0002280, 0.0002212, 0.0002093, 0.0001879,
0.0001838, 0.0002004, 0.0002198, 0.0002270, 0.0002997, 0.0003195, 0.0003081,
0.0002969, 0.0002921, 0.0002780, 0.0003384, 0.0003318, 0.0003284, 0.0003283,
0.0003289, 0.0003334, 0.0003290, 0.0003302, 0.0003042, 0.0002430, 0.0002280,
0.0002212, 0.0002093, 0.0001879, 0.0001838, 0.0002004, 0.0002198, 0.0002270,
0.0002997, 0.0003195, 0.0003081, 0.0002969, 0.0002921, 0.0002780
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,
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
]
},
"pv_akku": {
"capacity_wh": 26400,
"initial_soc_percentage": 80,
"min_soc_percentage": 15
"min_soc_percentage": 0
},
"eauto": {
"capacity_wh": 60000,
@ -37,15 +165,59 @@
"initial_soc_percentage": 5,
"min_soc_percentage": 80
},
"dishwasher" :{
"dishwasher": {
"consumption_wh": 5000,
"duration_h": 2
},
"temperature_forecast": [
18.3, 17.8, 16.9, 16.2, 15.6, 15.1, 14.6, 14.2, 14.3, 14.8, 15.7, 16.7, 17.4,
18.0, 18.6, 19.2, 19.1, 18.7, 18.5, 17.7, 16.2, 14.6, 13.6, 13.0, 12.6, 12.2,
11.7, 11.6, 11.3, 11.0, 10.7, 10.2, 11.4, 14.4, 16.4, 18.3, 19.5, 20.7, 21.9,
22.7, 23.1, 23.1, 22.8, 21.8, 20.2, 19.1, 18.0, 17.4
18.3,
17.8,
16.9,
16.2,
15.6,
15.1,
14.6,
14.2,
14.3,
14.8,
15.7,
16.7,
17.4,
18.0,
18.6,
19.2,
19.1,
18.7,
18.5,
17.7,
16.2,
14.6,
13.6,
13.0,
12.6,
12.2,
11.7,
11.6,
11.3,
11.0,
10.7,
10.2,
11.4,
14.4,
16.4,
18.3,
19.5,
20.7,
21.9,
22.7,
23.1,
23.1,
22.8,
21.8,
20.2,
19.1,
18.0,
17.4
],
"start_solution": null
}

View File

@ -476,6 +476,7 @@
0.0
],
"akku_soc_pro_stunde": [
80.0,
80.0,
79.91107093663912,
79.91107093663912,
@ -512,7 +513,6 @@
100.0,
100.0,
100.0,
96.84060778236915,
96.84060778236915
],
"Electricity_price": [

View File

@ -170,7 +170,7 @@
0.0,
0.5,
0.625,
0.0,
0.75,
0.0,
0.0,
0.0,
@ -211,7 +211,7 @@
1103.78,
6373.12,
7733.71,
1050.98,
4299.98,
988.56,
912.38,
704.61,
@ -241,6 +241,7 @@
592.97
],
"EAuto_SoC_pro_Stunde": [
5.0,
11.555,
11.555,
26.85,
@ -251,34 +252,33 @@
74.92,
83.66,
94.585,
94.585,
94.585,
94.585,
94.585,
94.585,
94.585,
94.585,
94.585,
94.585,
94.585,
94.585,
94.585,
94.585,
94.585,
94.585,
94.585,
94.585,
94.585,
94.585,
94.585,
94.585,
94.585,
94.585,
94.585,
94.585,
94.585,
94.585,
94.585
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
],
"Einnahmen_Euro_pro_Stunde": [
0.0,
@ -320,7 +320,7 @@
0.0,
0.0
],
"Gesamt_Verluste": 9258.73062020124,
"Gesamt_Verluste": 9872.776074746695,
"Gesamtbilanz_Euro": 12.332782378812306,
"Gesamteinnahmen_Euro": 0.0,
"Gesamtkosten_Euro": 12.332782378812306,
@ -495,7 +495,7 @@
230.91336797704525,
880.0977272727268,
1026.818181818182,
99.72409090909093,
713.7695454545456,
133.72909090909081,
124.41545454545451,
96.08318181818186,
@ -525,6 +525,7 @@
0.0
],
"akku_soc_pro_stunde": [
80.0,
62.54222623966943,
62.54222623966943,
75.04222623966943,
@ -535,34 +536,33 @@
83.83265434833275,
64.76391295714818,
43.24187438965506,
40.094017984696386,
35.87277142822256,
31.945515918580686,
28.912587199572425,
28.912587199572425,
25.176146083869945,
22.187423632079316,
22.187423632079316,
22.187423632079316,
22.187423632079316,
34.68742363207931,
34.68742363207931,
34.68742363207931,
34.68742363207931,
34.99947869620843,
36.0696843420455,
40.099841390631155,
40.249843096950585,
55.20257643028218,
67.47251658502745,
84.99550697329678,
88.77022785443704,
89.9213907145978,
89.9213907145978,
89.9213907145978,
89.9213907145978,
89.9213907145978,
89.9213907145978
26.108997323539356,
21.88775076706553,
17.96049525742366,
14.927566538415393,
14.927566538415393,
11.191125422712915,
8.20240297092228,
8.20240297092228,
8.20240297092228,
8.20240297092228,
20.70240297092228,
20.70240297092228,
20.70240297092228,
20.70240297092228,
21.014458035051405,
22.08466368088848,
26.114820729474133,
26.264822435793555,
41.217555769125156,
53.48749592387043,
71.01048631213975,
74.78520719328002,
75.93637005344077,
75.93637005344077,
75.93637005344077,
75.93637005344077,
75.93637005344077
],
"Electricity_price": [
0.000228,
@ -711,7 +711,7 @@
"capacity_wh": 60000,
"charging_efficiency": 0.95,
"max_charge_power_w": 11040,
"soc_wh": 56751.0,
"soc_wh": 60000.0,
"initial_soc_percentage": 5
},
"start_solution": [
@ -783,7 +783,7 @@
0.0,
2.0,
3.0,
0.0,
4.0,
0.0,
0.0,
0.0,

View File

@ -3,15 +3,14 @@
0.0,
0.0,
0.0,
0.375,
0.0,
0.875,
0.0,
0.375,
0.0,
1.0,
1.0,
0.75,
0.0,
0.0,
0.0,
0.5,
0.0,
0.0,
0.0,
0.0,
@ -19,6 +18,7 @@
0.0,
0.0,
0.0,
0.5,
0.0,
0.0,
0.0,
@ -100,32 +100,25 @@
1.0
],
"discharge_allowed": [
1,
0,
1,
0,
1,
0,
1,
0,
0,
1,
0,
0,
0,
0,
1,
0,
0,
1,
1,
1,
0,
0,
0,
1,
1,
1,
1,
1,
1,
1,
1,
0,
1,
1,
0,
@ -135,12 +128,19 @@
1,
1,
1,
0,
1,
1,
0,
1,
1,
0,
1,
1,
1,
1,
1,
1,
0,
0,
1,
1,
1,
@ -150,66 +150,66 @@
1
],
"eautocharge_hours_float": [
0.5,
0.375,
0.625,
0.875,
0.875,
0.375,
0.0,
1.0,
0.75,
1.0,
0.0,
0.375,
0.625,
0.5,
0.5,
0.75,
0.375,
0.0,
0.5,
0.375,
0.0,
0.0,
0.5,
0.5,
0.625,
1.0,
0.5,
0.5,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.375,
0.0,
0.0,
0.0,
0.375,
0.0,
0.0,
0.625,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
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": {
"Last_Wh_pro_Stunde": [
6297.07,
8929.91,
5253.5599999999995,
3632.0299999999997,
4986.07,
1063.91,
1320.56,
8876.029999999999,
8907.67,
7731.82,
11704.22,
7658.78,
1129.12,
6460.22,
6347.78,
3629.12,
1178.71,
1050.98,
988.56,
@ -226,14 +226,14 @@
1141.98,
1056.97,
992.46,
1155.99,
5088.99,
827.01,
1257.98,
1232.67,
871.26,
4804.26,
860.88,
1158.03,
1222.72,
7777.72,
1221.04,
949.99,
987.01,
@ -241,39 +241,39 @@
592.97
],
"EAuto_SoC_pro_Stunde": [
13.74,
26.85,
33.405,
33.405,
42.144999999999996,
53.06999999999999,
5.0,
11.555,
11.555,
11.555,
20.294999999999998,
29.035,
39.96,
48.699999999999996,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
57.440000000000005,
63.995000000000005,
63.995000000000005,
63.995000000000005,
63.995000000000005,
70.55,
70.55,
70.55,
81.475,
81.475,
81.475,
81.475,
81.475,
81.475,
81.475,
81.475,
81.475,
81.475,
81.475,
81.475,
81.475,
81.475,
81.475,
81.475,
81.475,
81.475,
81.475,
81.475,
81.475,
81.475,
81.475,
81.475,
81.475,
81.475,
81.475,
81.475,
81.475,
@ -320,10 +320,10 @@
0.0,
0.0
],
"Gesamt_Verluste": 6757.733989740087,
"Gesamtbilanz_Euro": 6.952642478544519,
"Gesamt_Verluste": 7755.845910804702,
"Gesamtbilanz_Euro": 4.690157296412734,
"Gesamteinnahmen_Euro": 0.0,
"Gesamtkosten_Euro": 6.952642478544519,
"Gesamtkosten_Euro": 4.690157296412734,
"Home_appliance_wh_per_hour": [
0.0,
0.0,
@ -365,18 +365,18 @@
0.0
],
"Kosten_Euro_pro_Stunde": [
1.22362812,
1.7445291920000001,
0.0,
0.4641768859999999,
0.0,
0.0,
1.4495244859999996,
0.53097063,
0.0,
1.7000079319999999,
1.0534661399999998,
0.44343509999999997,
0.0,
0.0,
0.8107800974767518,
0.0,
0.0,
0.291163892,
0.0,
0.0,
0.0,
@ -386,37 +386,37 @@
0.182970359,
0.0,
0.0,
0.26411047,
0.0,
0.0,
0.0326838476973626,
0.007989913613567745,
0.012219458233588555,
0.0,
0.002459704740224363,
0.0,
0.0,
0.05016012000000004,
0.0076430797975209205,
0.0,
0.31687880399999996,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0
0.16722497978466921,
0.16484566
],
"Netzbezug_Wh_pro_Stunde": [
5366.79,
7886.66,
0.0,
2470.3399999999997,
0.0,
0.0,
7714.339999999998,
2888.8500000000004,
0.0,
7734.339999999999,
4640.82,
2212.75,
0.0,
0.0,
2705.305630553059,
0.0,
0.0,
980.68,
0.0,
0.0,
0.0,
@ -426,23 +426,23 @@
556.31,
0.0,
0.0,
799.85,
0.0,
0.0,
134.50143085334403,
35.04348076126204,
55.24167375040034,
0.0,
11.752053226107805,
0.0,
0.0,
250.30000000000018,
34.77288351920346,
0.0,
1057.3199999999997,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0
572.4922279516235,
592.97
],
"Netzeinspeisung_Wh_pro_Stunde": [
0.0,
@ -485,18 +485,18 @@
0.0
],
"Verluste_Pro_Stunde": [
760.062272727273,
2.817272727272737,
29.157272727272726,
276.0,
414.0,
772.4754545454543,
0.0,
276.0,
646.7386363636365,
552.0,
345.0,
101.0335466817773,
615.5918181818183,
730.0663636363638,
373.0373243336329,
23.391818181818195,
99.72409090909093,
133.72909090909081,
0.0,
124.41545454545451,
96.08318181818186,
70.41409090909087,
@ -506,63 +506,63 @@
0.0,
66.66681818181814,
69.12409090909085,
109.0704545454546,
0.0,
109.96227272727276,
29.61116851999853,
47.952272727272714,
11.233982308648535,
48.41330768174524,
161.62968357967037,
682.1181818181817,
160.0271308670193,
21.962728535423857,
538.2984000000038,
441.95211196761403,
260.56941082122324,
207.0,
255.8276539776955,
171.99990368477063,
62.214291413756285,
1026.818181818182,
35.132727272727266,
77.27590909090907,
134.59227272727276,
100.08954545454549,
80.85954545454547
22.022423461142267,
0.0
],
"akku_soc_pro_stunde": [
80.0,
80.0,
62.150396005509634,
62.150396005509634,
62.150396005509634,
52.62581783746556,
52.62581783746556,
52.62581783746556,
53.77091326251142,
53.03253516333787,
49.884678758379195,
45.663432201905366,
41.73617669226349,
38.70324797325523,
36.48058096223595,
32.74413984653347,
29.75541739474284,
27.134937022842013,
27.134937022842013,
25.030555135789673,
22.848607821740085,
19.405727312098207,
15.934695976010055,
15.0,
15.312055064129126,
16.07020564583707,
19.578139530578447,
19.728141236897873,
34.68087457022947,
46.94341995234899,
53.90006700591099,
57.67478788705125,
58.17025540478875,
57.06126780148296,
54.622002994320425,
50.373509537020155,
47.214117319389295,
44.661732677516014
62.54222623966943,
62.45329717630854,
61.532928719008275,
61.532928719008275,
61.532928719008275,
61.532928719008275,
50.81349001377411,
36.480587121212125,
46.842735019368604,
46.10435692019505,
42.95650051523637,
42.95650051523637,
39.029245005594504,
35.996316286586236,
33.77364927556696,
30.03720815986448,
27.048485708073848,
24.428005336173022,
24.428005336173022,
22.32362344912068,
20.141676135071094,
20.141676135071094,
16.670644798982938,
15.156999826531148,
15.469054890660274,
0.471637535288375,
4.030157048585656,
4.180158754905081,
19.132892088236673,
19.132892088236673,
26.239215809839333,
30.01393669097958,
8.49189812348647,
7.382910520180684,
4.9436457130181495,
0.6951522557178741,
0.0
],
"Electricity_price": [
0.000228,
@ -715,103 +715,103 @@
"initial_soc_percentage": 5
},
"start_solution": [
7.0,
4.0,
11.0,
15.0,
13.0,
19.0,
8.0,
15.0,
5.0,
11.0,
1.0,
2.0,
8.0,
1.0,
2.0,
13.0,
14.0,
1.0,
9.0,
7.0,
9.0,
12.0,
12.0,
8.0,
13.0,
13.0,
7.0,
7.0,
6.0,
13.0,
7.0,
7.0,
10.0,
11.0,
12.0,
9.0,
9.0,
11.0,
11.0,
9.0,
10.0,
10.0,
11.0,
10.0,
8.0,
13.0,
11.0,
8.0,
0.0,
20.0,
20.0,
18.0,
5.0,
3.0,
5.0,
5.0,
1.0,
0.0,
6.0,
9.0,
16.0,
12.0,
13.0,
8.0,
4.0,
6.0,
0.0,
14.0,
11.0,
9.0,
16.0,
8.0,
9.0,
5.0,
10.0,
13.0,
13.0,
8.0,
8.0,
9.0,
5.0,
10.0,
7.0,
2.0,
8.0,
12.0,
2.0,
9.0,
11.0,
10.0,
10.0,
6.0,
1.0,
12.0,
9.0,
12.0,
13.0,
10.0,
13.0,
11.0,
2.0,
1.0,
3.0,
4.0,
3.0,
2.0,
2.0,
4.0,
1.0,
0.0,
2.0,
1.0,
0.0,
0.0,
2.0,
2.0,
3.0,
6.0,
2.0,
2.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
3.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
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": 13
}
}