mirror of
https://github.com/Akkudoktor-EOS/EOS.git
synced 2025-08-25 06:52:23 +00:00
renamed haushaltsgeräte to home appliance (#196)
* * rename Haushaltsgeraete to home appliance * renamed strafe to penalty (optimization problem) Signed-off-by: Jürgen Eckel <juergen.eckel@gmail.com> * removed penalty renaming Signed-off-by: Jürgen Eckel <juergen.eckel@gmail.com> * renamed one variable Signed-off-by: Jürgen Eckel <juergen.eckel@gmail.com> * * renamed variable names and methods of the home appliance class * renamed missed method names * fixed renamed variable * renamed object * adjusted to latest repo changes * renamed file to class_home_applianc.py * renamed method --------- Signed-off-by: Jürgen Eckel <juergen.eckel@gmail.com> Signed-off-by: Jürgen Eckel <juergen@riddleandcode.com>
This commit is contained in:
64
src/akkudoktoreos/class_home_appliance.py
Normal file
64
src/akkudoktoreos/class_home_appliance.py
Normal file
@@ -0,0 +1,64 @@
|
||||
import numpy as np
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class HomeApplianceParameters(BaseModel):
|
||||
consumption_wh: int = Field(
|
||||
gt=0,
|
||||
description="An integer representing the energy consumption of a household device in watt-hours.",
|
||||
)
|
||||
duration_h: int = Field(
|
||||
gt=0,
|
||||
description="An integer representing the usage duration of a household device in hours.",
|
||||
)
|
||||
|
||||
|
||||
class HomeAppliance:
|
||||
def __init__(self, parameters: HomeApplianceParameters, hours=None):
|
||||
self.hours = hours # Total duration for which the planning is done
|
||||
self.consumption_wh = (
|
||||
parameters.consumption_wh
|
||||
) # Total energy consumption of the device in kWh
|
||||
self.duration_h = parameters.duration_h # Duration of use in hours
|
||||
self.load_curve = np.zeros(self.hours) # Initialize the load curve with zeros
|
||||
|
||||
def set_starting_time(self, start_hour, global_start_hour=0):
|
||||
"""Sets the start time of the device and generates the corresponding load curve.
|
||||
|
||||
:param start_hour: The hour at which the device should start.
|
||||
"""
|
||||
self.reset()
|
||||
# Check if the duration of use is within the available time frame
|
||||
if start_hour + self.duration_h > self.hours:
|
||||
raise ValueError("The duration of use exceeds the available time frame.")
|
||||
if start_hour < global_start_hour:
|
||||
raise ValueError("The start time is earlier than the available time frame.")
|
||||
|
||||
# Calculate power per hour based on total consumption and duration
|
||||
power_per_hour = self.consumption_wh / self.duration_h # Convert to watt-hours
|
||||
|
||||
# Set the power for the duration of use in the load curve array
|
||||
self.load_curve[start_hour : start_hour + self.duration_h] = power_per_hour
|
||||
|
||||
def reset(self):
|
||||
"""Resets the load curve."""
|
||||
self.load_curve = np.zeros(self.hours)
|
||||
|
||||
def get_load_curve(self):
|
||||
"""Returns the current load curve."""
|
||||
return self.load_curve
|
||||
|
||||
def get_load_for_hour(self, hour):
|
||||
"""Returns the load for a specific hour.
|
||||
|
||||
:param hour: The hour for which the load is queried.
|
||||
:return: The load in watts for the specified hour.
|
||||
"""
|
||||
if hour < 0 or hour >= self.hours:
|
||||
raise ValueError("The specified hour is outside the available time frame.")
|
||||
|
||||
return self.load_curve[hour]
|
||||
|
||||
def get_latest_starting_point(self):
|
||||
"""Returns the latest possible start time at which the device can still run completely."""
|
||||
return self.hours - self.duration_h
|
@@ -2,53 +2,53 @@ import numpy as np
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class HaushaltsgeraetParameters(BaseModel):
|
||||
verbrauch_wh: int = Field(
|
||||
class HomeApplianceParameters(BaseModel):
|
||||
consumption_wh: int = Field(
|
||||
gt=0,
|
||||
description="An integer representing the energy consumption of a household device in watt-hours.",
|
||||
)
|
||||
dauer_h: int = Field(
|
||||
duration_h: int = Field(
|
||||
gt=0,
|
||||
description="An integer representing the usage duration of a household device in hours.",
|
||||
)
|
||||
|
||||
|
||||
class Haushaltsgeraet:
|
||||
def __init__(self, parameters: HaushaltsgeraetParameters, hours=24):
|
||||
class HomeAppliance:
|
||||
def __init__(self, parameters: HomeApplianceParameters, hours=None):
|
||||
self.hours = hours # Total duration for which the planning is done
|
||||
self.verbrauch_wh = (
|
||||
parameters.verbrauch_wh # Total energy consumption of the device in kWh
|
||||
)
|
||||
self.dauer_h = parameters.dauer_h # Duration of use in hours
|
||||
self.lastkurve = np.zeros(self.hours) # Initialize the load curve with zeros
|
||||
self.consumption_wh = (
|
||||
parameters.consumption_wh
|
||||
) # Total energy consumption of the device in kWh
|
||||
self.duration_h = parameters.duration_h # Duration of use in hours
|
||||
self.load_curve = np.zeros(self.hours) # Initialize the load curve with zeros
|
||||
|
||||
def set_startzeitpunkt(self, start_hour, global_start_hour=0):
|
||||
def set_starting_time(self, start_hour, global_start_hour=0):
|
||||
"""Sets the start time of the device and generates the corresponding load curve.
|
||||
|
||||
:param start_hour: The hour at which the device should start.
|
||||
"""
|
||||
self.reset()
|
||||
# Check if the duration of use is within the available time frame
|
||||
if start_hour + self.dauer_h > self.hours:
|
||||
if start_hour + self.duration_h > self.hours:
|
||||
raise ValueError("The duration of use exceeds the available time frame.")
|
||||
if start_hour < global_start_hour:
|
||||
raise ValueError("The start time is earlier than the available time frame.")
|
||||
|
||||
# Calculate power per hour based on total consumption and duration
|
||||
leistung_pro_stunde = self.verbrauch_wh / self.dauer_h # Convert to watt-hours
|
||||
power_per_hour = self.consumption_wh / self.duration_h # Convert to watt-hours
|
||||
|
||||
# Set the power for the duration of use in the load curve array
|
||||
self.lastkurve[start_hour : start_hour + self.dauer_h] = leistung_pro_stunde
|
||||
self.load_curve[start_hour : start_hour + self.duration_h] = power_per_hour
|
||||
|
||||
def reset(self):
|
||||
"""Resets the load curve."""
|
||||
self.lastkurve = np.zeros(self.hours)
|
||||
self.load_curve = np.zeros(self.hours)
|
||||
|
||||
def get_lastkurve(self):
|
||||
def get_load_curve(self):
|
||||
"""Returns the current load curve."""
|
||||
return self.lastkurve
|
||||
return self.load_curve
|
||||
|
||||
def get_last_fuer_stunde(self, hour):
|
||||
def get_load_for_hour(self, hour):
|
||||
"""Returns the load for a specific hour.
|
||||
|
||||
:param hour: The hour for which the load is queried.
|
||||
@@ -57,8 +57,8 @@ class Haushaltsgeraet:
|
||||
if hour < 0 or hour >= self.hours:
|
||||
raise ValueError("The specified hour is outside the available time frame.")
|
||||
|
||||
return self.lastkurve[hour]
|
||||
return self.load_curve[hour]
|
||||
|
||||
def spaetestmoeglicher_startzeitpunkt(self):
|
||||
def get_latest_starting_point(self):
|
||||
"""Returns the latest possible start time at which the device can still run completely."""
|
||||
return self.hours - self.dauer_h
|
||||
return self.hours - self.duration_h
|
||||
|
@@ -125,15 +125,15 @@ if __name__ == "__main__":
|
||||
start_innentemperatur = 15 # Initial indoor temperature
|
||||
isolationseffizienz = 0.8 # Insulation efficiency
|
||||
gewuenschte_innentemperatur = 20 # Desired indoor temperature
|
||||
wp = Heatpump(max_heizleistung, 24) # Initialize heat pump with prediction hours
|
||||
hp = Heatpump(max_heizleistung, 24) # Initialize heat pump with prediction hours
|
||||
|
||||
# Print COP for various outside temperatures
|
||||
print(wp.calculate_cop(-10), " ", wp.calculate_cop(0), " ", wp.calculate_cop(10))
|
||||
print(hp.calculate_cop(-10), " ", hp.calculate_cop(0), " ", hp.calculate_cop(10))
|
||||
|
||||
# 24 hours of outside temperatures (example values)
|
||||
temperaturen = [ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -5, -2, 5, ] # fmt: skip
|
||||
|
||||
# Calculate the 24-hour power data
|
||||
leistungsdaten = wp.simulate_24h(temperaturen)
|
||||
leistungsdaten = hp.simulate_24h(temperaturen)
|
||||
|
||||
print(leistungsdaten)
|
||||
|
@@ -8,7 +8,7 @@ from typing_extensions import Self
|
||||
|
||||
from akkudoktoreos.config import AppConfig
|
||||
from akkudoktoreos.devices.battery import EAutoParameters, PVAkku, PVAkkuParameters
|
||||
from akkudoktoreos.devices.generic import Haushaltsgeraet, HaushaltsgeraetParameters
|
||||
from akkudoktoreos.devices.generic import HomeAppliance, HomeApplianceParameters
|
||||
from akkudoktoreos.devices.inverter import Wechselrichter, WechselrichterParameters
|
||||
from akkudoktoreos.prediction.ems import (
|
||||
EnergieManagementSystem,
|
||||
@@ -22,7 +22,7 @@ class OptimizationParameters(BaseModel):
|
||||
pv_akku: PVAkkuParameters
|
||||
wechselrichter: WechselrichterParameters = WechselrichterParameters()
|
||||
eauto: EAutoParameters
|
||||
spuelmaschine: Optional[HaushaltsgeraetParameters] = None
|
||||
dishwasher: Optional[HomeApplianceParameters] = None
|
||||
temperature_forecast: list[float] = Field(
|
||||
"An array of floats representing the temperature forecast in degrees Celsius for different time intervals."
|
||||
)
|
||||
@@ -86,7 +86,7 @@ class SimulationResult(BaseModel):
|
||||
)
|
||||
Gesamteinnahmen_Euro: float = Field(description="The total revenues in euros.")
|
||||
Gesamtkosten_Euro: float = Field(description="The total costs in euros.")
|
||||
Haushaltsgeraet_wh_pro_stunde: list[Optional[float]] = Field(
|
||||
Home_appliance_wh_per_hour: list[Optional[float]] = Field(
|
||||
description="The energy consumption of a household appliance in watt-hours per hour."
|
||||
)
|
||||
Kosten_Euro_pro_Stunde: list[Optional[float]] = Field(
|
||||
@@ -120,7 +120,7 @@ class SimulationResult(BaseModel):
|
||||
# Gesamtbilanz_Euro: float = Field(description="The total simulated balance in euros.")
|
||||
# Gesamteinnahmen_Euro: float = Field(description="The total simulated income in euros.")
|
||||
# Gesamtkosten_Euro: float = Field(description="The total simulated costs in euros.")
|
||||
# Haushaltsgeraet_wh_pro_stunde: list[Optional[float]] = Field(
|
||||
# Home_appliance_wh_per_hour: list[Optional[float]] = Field(
|
||||
# description="An array of floats representing the simulated energy consumption of a household appliance in watt-hours per hour."
|
||||
# )
|
||||
# Kosten_Euro_pro_Stunde: list[Optional[float]] = Field(
|
||||
@@ -158,7 +158,7 @@ class OptimizeResponse(BaseModel):
|
||||
None,
|
||||
description="An array of binary values (0 or 1) representing a possible starting solution for the simulation.",
|
||||
)
|
||||
spuelstart: Optional[int] = Field(
|
||||
washingstart: Optional[int] = Field(
|
||||
None,
|
||||
description="Can be `null` or contain an object representing the start of washing (if applicable).",
|
||||
)
|
||||
@@ -285,7 +285,7 @@ class optimization_problem:
|
||||
individual[self.prediction_hours : self.prediction_hours * 2] = ev_charge_part_mutated
|
||||
|
||||
# Step 3: Mutate appliance start times if household appliances are part of the optimization
|
||||
if self.opti_param["haushaltsgeraete"] > 0:
|
||||
if self.opti_param["home_appliance"] > 0:
|
||||
# Extract the appliance part (typically a single value for the start hour)
|
||||
appliance_part = [individual[-1]]
|
||||
|
||||
@@ -311,7 +311,7 @@ class optimization_problem:
|
||||
]
|
||||
|
||||
# Add the start time of the household appliance if it's being optimized
|
||||
if self.opti_param["haushaltsgeraete"] > 0:
|
||||
if self.opti_param["home_appliance"] > 0:
|
||||
individual_components += [self.toolbox.attr_int()]
|
||||
|
||||
return creator.Individual(individual_components)
|
||||
@@ -333,12 +333,12 @@ class optimization_problem:
|
||||
else None
|
||||
)
|
||||
|
||||
spuelstart_int = (
|
||||
washingstart_int = (
|
||||
individual[-1]
|
||||
if self.opti_param and self.opti_param.get("haushaltsgeraete", 0) > 0
|
||||
if self.opti_param and self.opti_param.get("home_appliance", 0) > 0
|
||||
else None
|
||||
)
|
||||
return discharge_hours_bin, eautocharge_hours_float, spuelstart_int
|
||||
return discharge_hours_bin, eautocharge_hours_float, washingstart_int
|
||||
|
||||
def setup_deap_environment(self, opti_param: dict[str, Any], start_hour: int) -> None:
|
||||
"""Set up the DEAP environment with fitness and individual creation rules."""
|
||||
@@ -410,11 +410,11 @@ class optimization_problem:
|
||||
This is an internal function.
|
||||
"""
|
||||
ems.reset()
|
||||
discharge_hours_bin, eautocharge_hours_index, spuelstart_int = self.split_individual(
|
||||
discharge_hours_bin, eautocharge_hours_index, washingstart_int = self.split_individual(
|
||||
individual
|
||||
)
|
||||
if self.opti_param.get("haushaltsgeraete", 0) > 0:
|
||||
ems.set_haushaltsgeraet_start(spuelstart_int, global_start_hour=start_hour)
|
||||
if self.opti_param.get("home_appliance", 0) > 0:
|
||||
ems.set_home_appliance_start(washingstart_int, global_start_hour=start_hour)
|
||||
|
||||
ac, dc, discharge = self.decode_charge_discharge(discharge_hours_bin)
|
||||
|
||||
@@ -557,12 +557,12 @@ class optimization_problem:
|
||||
eauto.set_charge_per_hour(np.full(self.prediction_hours, 1))
|
||||
|
||||
# Initialize household appliance if applicable
|
||||
spuelmaschine = (
|
||||
Haushaltsgeraet(
|
||||
parameters=parameters.spuelmaschine,
|
||||
dishwasher = (
|
||||
HomeAppliance(
|
||||
parameters=parameters.dishwasher,
|
||||
hours=self.prediction_hours,
|
||||
)
|
||||
if parameters.spuelmaschine is not None
|
||||
if parameters.dishwasher is not None
|
||||
else None
|
||||
)
|
||||
|
||||
@@ -572,12 +572,12 @@ class optimization_problem:
|
||||
self._config.eos,
|
||||
parameters.ems,
|
||||
eauto=eauto,
|
||||
haushaltsgeraet=spuelmaschine,
|
||||
home_appliance=dishwasher,
|
||||
wechselrichter=wr,
|
||||
)
|
||||
|
||||
# Setup the DEAP environment and optimization process
|
||||
self.setup_deap_environment({"haushaltsgeraete": 1 if spuelmaschine else 0}, start_hour)
|
||||
self.setup_deap_environment({"home_appliance": 1 if dishwasher else 0}, start_hour)
|
||||
self.toolbox.register(
|
||||
"evaluate",
|
||||
lambda ind: self.evaluate(ind, ems, parameters, start_hour, worst_case),
|
||||
@@ -586,7 +586,7 @@ class optimization_problem:
|
||||
|
||||
# Perform final evaluation on the best solution
|
||||
o = self.evaluate_inner(start_solution, ems, start_hour)
|
||||
discharge_hours_bin, eautocharge_hours_float, spuelstart_int = self.split_individual(
|
||||
discharge_hours_bin, eautocharge_hours_float, washingstart_int = self.split_individual(
|
||||
start_solution
|
||||
)
|
||||
if self.optimize_ev:
|
||||
@@ -622,7 +622,7 @@ class optimization_problem:
|
||||
"Einnahmen_Euro_pro_Stunde",
|
||||
"EAuto_SoC_pro_Stunde",
|
||||
"Verluste_Pro_Stunde",
|
||||
"Haushaltsgeraet_wh_pro_stunde",
|
||||
"Home_appliance_wh_per_hour",
|
||||
]
|
||||
|
||||
# Loop through each key in the list
|
||||
@@ -649,6 +649,6 @@ class optimization_problem:
|
||||
"result": o,
|
||||
"eauto_obj": ems.eauto.to_dict(),
|
||||
"start_solution": start_solution,
|
||||
"spuelstart": spuelstart_int,
|
||||
"washingstart": washingstart_int,
|
||||
# "simulation_data": o,
|
||||
}
|
||||
|
@@ -7,7 +7,7 @@ from typing_extensions import Self
|
||||
|
||||
from akkudoktoreos.config import EOSConfig
|
||||
from akkudoktoreos.devices.battery import PVAkku
|
||||
from akkudoktoreos.devices.generic import Haushaltsgeraet
|
||||
from akkudoktoreos.devices.generic import HomeAppliance
|
||||
from akkudoktoreos.devices.inverter import Wechselrichter
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ class EnergieManagementSystem:
|
||||
config: EOSConfig,
|
||||
parameters: EnergieManagementSystemParameters,
|
||||
eauto: Optional[PVAkku] = None,
|
||||
haushaltsgeraet: Optional[Haushaltsgeraet] = None,
|
||||
home_appliance: Optional[HomeAppliance] = None,
|
||||
wechselrichter: Optional[Wechselrichter] = None,
|
||||
):
|
||||
self.akku = wechselrichter.akku
|
||||
@@ -60,7 +60,7 @@ class EnergieManagementSystem:
|
||||
else np.full(len(self.gesamtlast), parameters.einspeiseverguetung_euro_pro_wh, float)
|
||||
)
|
||||
self.eauto = eauto
|
||||
self.haushaltsgeraet = haushaltsgeraet
|
||||
self.home_appliance = home_appliance
|
||||
self.wechselrichter = wechselrichter
|
||||
self.ac_charge_hours = np.full(config.prediction_hours, 0)
|
||||
self.dc_charge_hours = np.full(config.prediction_hours, 1)
|
||||
@@ -78,8 +78,8 @@ class EnergieManagementSystem:
|
||||
def set_ev_charge_hours(self, ds: List[int]) -> None:
|
||||
self.ev_charge_hours = ds
|
||||
|
||||
def set_haushaltsgeraet_start(self, ds: List[int], global_start_hour: int = 0) -> None:
|
||||
self.haushaltsgeraet.set_startzeitpunkt(ds, global_start_hour=global_start_hour)
|
||||
def set_home_appliance_start(self, ds: List[int], global_start_hour: int = 0) -> None:
|
||||
self.home_appliance.set_starting_time(ds, global_start_hour=global_start_hour)
|
||||
|
||||
def reset(self) -> None:
|
||||
self.eauto.reset()
|
||||
@@ -114,7 +114,7 @@ class EnergieManagementSystem:
|
||||
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)
|
||||
haushaltsgeraet_wh_pro_stunde = np.full((total_hours), np.nan)
|
||||
home_appliance_wh_per_hour = np.full((total_hours), np.nan)
|
||||
|
||||
# Set initial state
|
||||
akku_soc_pro_stunde[0] = self.akku.ladezustand_in_prozent()
|
||||
@@ -127,10 +127,10 @@ class EnergieManagementSystem:
|
||||
# Accumulate loads and PV generation
|
||||
verbrauch = self.gesamtlast[stunde]
|
||||
verluste_wh_pro_stunde[stunde_since_now] = 0.0
|
||||
if self.haushaltsgeraet:
|
||||
ha_load = self.haushaltsgeraet.get_last_fuer_stunde(stunde)
|
||||
if self.home_appliance:
|
||||
ha_load = self.home_appliance.get_load_for_hour(stunde)
|
||||
verbrauch += ha_load
|
||||
haushaltsgeraet_wh_pro_stunde[stunde_since_now] = ha_load
|
||||
home_appliance_wh_per_hour[stunde_since_now] = ha_load
|
||||
|
||||
# E-Auto handling
|
||||
if self.eauto and self.ev_charge_hours[stunde] > 0:
|
||||
@@ -193,7 +193,7 @@ class EnergieManagementSystem:
|
||||
"Gesamtkosten_Euro": np.nansum(kosten_euro_pro_stunde),
|
||||
"Verluste_Pro_Stunde": verluste_wh_pro_stunde,
|
||||
"Gesamt_Verluste": np.nansum(verluste_wh_pro_stunde),
|
||||
"Haushaltsgeraet_wh_pro_stunde": haushaltsgeraet_wh_pro_stunde,
|
||||
"Home_appliance_wh_per_hour": home_appliance_wh_per_hour,
|
||||
}
|
||||
|
||||
return out
|
||||
|
@@ -112,7 +112,7 @@ def visualisiere_ergebnisse(
|
||||
)
|
||||
plt.plot(
|
||||
hours,
|
||||
ergebnisse["Haushaltsgeraet_wh_pro_stunde"],
|
||||
ergebnisse["Home_appliance_wh_per_hour"],
|
||||
label="Household Device (Wh)",
|
||||
marker="o",
|
||||
linestyle="--",
|
||||
|
Reference in New Issue
Block a user