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

View File

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

View File

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

View File

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

View File

@ -388,7 +388,7 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
else: else:
self.ems.set_ev_charge_hours(np.full(self.config.prediction_hours, 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.simulate(self.ems.start_datetime.hour)
def evaluate( def evaluate(
self, self,
@ -441,14 +441,14 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
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"],
parameters.eauto.min_soc_percentage - self.ems.eauto.current_soc_percentage() parameters.eauto.min_soc_percentage - self.ems.ev.current_soc_percentage()
if parameters.eauto and self.ems.eauto if parameters.eauto and self.ems.ev
else 0, else 0,
) )
# 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.battery.current_energy_content() * parameters.ems.preis_euro_pro_wh_akku
) )
gesamtbilanz += -restwert_akku gesamtbilanz += -restwert_akku
@ -456,8 +456,8 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
gesamtbilanz += max( gesamtbilanz += max(
0, 0,
( (
parameters.eauto.min_soc_percentage - self.ems.eauto.current_soc_percentage() parameters.eauto.min_soc_percentage - self.ems.ev.current_soc_percentage()
if parameters.eauto and self.ems.eauto if parameters.eauto and self.ems.ev
else 0 else 0
) )
* self.config.optimization_penalty, * self.config.optimization_penalty,
@ -565,7 +565,7 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
self.ems.set_parameters( self.ems.set_parameters(
parameters.ems, parameters.ems,
inverter=inverter, inverter=inverter,
eauto=eauto, ev=eauto,
home_appliance=dishwasher, home_appliance=dishwasher,
) )
self.ems.set_start_hour(start_hour) self.ems.set_start_hour(start_hour)
@ -606,7 +606,7 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
"discharge_allowed": discharge.tolist(), "discharge_allowed": discharge.tolist(),
"eautocharge_hours_float": eautocharge_hours_float, "eautocharge_hours_float": eautocharge_hours_float,
"result": o, "result": o,
"eauto_obj": self.ems.eauto.to_dict(), "eauto_obj": self.ems.ev.to_dict(),
"start_solution": start_solution, "start_solution": start_solution,
"spuelstart": washingstart_int, "spuelstart": washingstart_int,
"extra_data": extra_data, "extra_data": extra_data,
@ -622,7 +622,7 @@ class optimization_problem(ConfigMixin, DevicesMixin, EnergyManagementSystemMixi
"discharge_allowed": discharge, "discharge_allowed": discharge,
"eautocharge_hours_float": eautocharge_hours_float, "eautocharge_hours_float": eautocharge_hours_float,
"result": SimulationResult(**o), "result": SimulationResult(**o),
"eauto_obj": self.ems.eauto, "eauto_obj": self.ems.ev,
"start_solution": start_solution, "start_solution": start_solution,
"washingstart": washingstart_int, "washingstart": washingstart_int,
} }

View File

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

View File

@ -144,7 +144,7 @@ def create_ems_instance() -> EnergieManagementSystem:
gesamtlast=gesamtlast, gesamtlast=gesamtlast,
), ),
inverter=inverter, inverter=inverter,
eauto=eauto, ev=eauto,
home_appliance=home_appliance, home_appliance=home_appliance,
) )
@ -163,7 +163,7 @@ def test_simulation(create_ems_instance):
ems = create_ems_instance ems = create_ems_instance
# Simulate starting from hour 0 (this value can be adjusted) # 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! --- # --- Pls do not remove! ---
# visualisiere_ergebnisse( # visualisiere_ergebnisse(
@ -233,12 +233,12 @@ def test_simulation(create_ems_instance):
), "The length of 'akku_soc_pro_stunde' should be 48." ), "The length of 'akku_soc_pro_stunde' should be 48."
# Verfify DC and AC Charge Bins # 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 ( assert (
abs(result["akku_soc_pro_stunde"][10] - 10.0) < 1e-5 abs(result["akku_soc_pro_stunde"][10] - 10.0) < 1e-5
), "'akku_soc_pro_stunde[10]' should be 10." ), "'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 ( assert (
abs(result["Netzeinspeisung_Wh_pro_Stunde"][10] - 3946.93) < 1e-3 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." ), "'Netzeinspeisung_Wh_pro_Stunde[11]' should be 0.0."
assert ( assert (
abs(result["akku_soc_pro_stunde"][20] - 98) < 1e-5 abs(result["akku_soc_pro_stunde"][20] - 10) < 1e-5
), "'akku_soc_pro_stunde[11]' should be 98." ), "'akku_soc_pro_stunde[20]' should be 10."
assert ( assert (
abs(result["Last_Wh_pro_Stunde"][20] - 6050.98) < 1e-3 abs(result["Last_Wh_pro_Stunde"][20] - 6050.98) < 1e-3
), "'Netzeinspeisung_Wh_pro_Stunde[11]' should be 0.0." ), "'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.""" """Test optimierung_ems."""
# Assure configuration holds the correct values # Assure configuration holds the correct values
config_eos = get_config() 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 # Load input and output data
file = DIR_TESTDATA / fn_in file = DIR_TESTDATA / fn_in

View File

@ -25,7 +25,7 @@ def inverter(mock_battery):
/ "data" / "data"
/ "regular_grid_interpolator.pkl" / "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): def test_process_energy_excess_generation(inverter, mock_battery):

View File

@ -1,34 +1,162 @@
{ {
"ems": { "ems": {
"preis_euro_pro_wh_akku": 0.0001, "preis_euro_pro_wh_akku": 0.0,
"einspeiseverguetung_euro_pro_wh": 0.00007, "einspeiseverguetung_euro_pro_wh": 0.00007,
"gesamtlast": [ "gesamtlast": [
676.71, 876.19, 527.13, 468.88, 531.38, 517.95, 483.15, 472.28, 1011.68, 995.00, 676.71,
1053.07, 1063.91, 1320.56, 1132.03, 1163.67, 1176.82, 1216.22, 1103.78, 1129.12, 876.19,
1178.71, 1050.98, 988.56, 912.38, 704.61, 516.37, 868.05, 694.34, 608.79, 556.31, 527.13,
488.89, 506.91, 804.89, 1141.98, 1056.97, 992.46, 1155.99, 827.01, 1257.98, 1232.67, 468.88,
871.26, 860.88, 1158.03, 1222.72, 1221.04, 949.99, 987.01, 733.99, 592.97 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": [ "pv_prognose_wh": [
0, 0, 0, 0, 0, 0, 0, 8.05, 352.91, 728.51, 930.28, 1043.25, 1106.74, 1161.69, 0,
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, 0, 5.04, 335.59, 705.32, 1121.12, 1604.79, 2157.38, 1433.25, 5718.49, 0,
4553.96, 3027.55, 2574.46, 1720.4, 963.4, 383.3, 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": [ "strompreis_euro_pro_wh": [
0.0003384, 0.0003318, 0.0003284, 0.0003283, 0.0003289, 0.0003334, 0.0003290, 0.0003384,
0.0003302, 0.0003042, 0.0002430, 0.0002280, 0.0002212, 0.0002093, 0.0001879, 0.0003318,
0.0001838, 0.0002004, 0.0002198, 0.0002270, 0.0002997, 0.0003195, 0.0003081, 0.0003284,
0.0002969, 0.0002921, 0.0002780, 0.0003384, 0.0003318, 0.0003284, 0.0003283, 0.0003283,
0.0003289, 0.0003334, 0.0003290, 0.0003302, 0.0003042, 0.0002430, 0.0002280, 0.0003289,
0.0002212, 0.0002093, 0.0001879, 0.0001838, 0.0002004, 0.0002198, 0.0002270, 0.0003334,
0.0002997, 0.0003195, 0.0003081, 0.0002969, 0.0002921, 0.0002780 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": { "pv_akku": {
"capacity_wh": 26400, "capacity_wh": 26400,
"initial_soc_percentage": 80, "initial_soc_percentage": 80,
"min_soc_percentage": 15 "min_soc_percentage": 0
}, },
"eauto": { "eauto": {
"capacity_wh": 60000, "capacity_wh": 60000,
@ -37,15 +165,59 @@
"initial_soc_percentage": 5, "initial_soc_percentage": 5,
"min_soc_percentage": 80 "min_soc_percentage": 80
}, },
"dishwasher" :{ "dishwasher": {
"consumption_wh": 5000, "consumption_wh": 5000,
"duration_h": 2 "duration_h": 2
}, },
"temperature_forecast": [ "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.3,
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, 17.8,
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, 16.9,
22.7, 23.1, 23.1, 22.8, 21.8, 20.2, 19.1, 18.0, 17.4 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 "start_solution": null
} }

View File

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

View File

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

View File

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