diff --git a/README-DE.md b/README-DE.md index 670a8d85..c7880248 100644 --- a/README-DE.md +++ b/README-DE.md @@ -94,7 +94,7 @@ In diesem Projekt werden verschiedene Klassen verwendet, um die Komponenten eine - `Load`: Modelliert die Lastanforderungen des Haushalts oder Unternehmens, ermöglicht die Vorhersage des zukünftigen Energiebedarfs. -- `HeatPump`: Simuliert eine Wärmepumpe, einschließlich ihres Energieverbrauchs und ihrer Effizienz unter verschiedenen Betriebsbedingungen. +- `Heatpump`: Simuliert eine Wärmepumpe, einschließlich ihres Energieverbrauchs und ihrer Effizienz unter verschiedenen Betriebsbedingungen. - `Strompreis`: Bietet Informationen zu den Strompreisen, ermöglicht die Optimierung des Energieverbrauchs und der -erzeugung basierend auf Tarifinformationen. diff --git a/README.md b/README.md index 1a3f34c7..5fb35ac1 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ This project uses various classes to simulate and optimize the components of an - `Load`: Models the load requirements of a household or business, enabling the prediction of future energy demand. -- `HeatPump`: Simulates a heat pump, including its energy consumption and efficiency under various operating conditions. +- `Heatpump`: Simulates a heat pump, including its energy consumption and efficiency under various operating conditions. - `Strompreis`: Provides information on electricity prices, enabling optimization of energy consumption and generation based on tariff information. diff --git a/modules/class_heatpump.py b/modules/class_heatpump.py deleted file mode 100644 index 84d6ac2f..00000000 --- a/modules/class_heatpump.py +++ /dev/null @@ -1,88 +0,0 @@ -class Heatpump: - MAX_HEIZLEISTUNG = 5000 # Maximum heating power in watts - BASE_HEIZLEISTUNG = 235.0 # Base heating power value - TEMPERATURE_COEFFICIENT = -11.645 # Coefficient for temperature - COP_BASE = 3.0 # Base COP value - COP_COEFFICIENT = 0.1 # COP increase per degree - - def __init__(self, max_heizleistung, prediction_hours): - self.max_heizleistung = max_heizleistung - self.prediction_hours = prediction_hours - - def cop_berechnen(self, aussentemperatur): - """Calculate the coefficient of performance (COP) based on outside temperature.""" - cop = self.COP_BASE + (aussentemperatur * self.COP_COEFFICIENT) - return max(cop, 1) - - def heizleistung_berechnen(self, aussentemperatur): - """Calculate heating power based on outside temperature.""" - heizleistung = ( - (self.BASE_HEIZLEISTUNG + aussentemperatur * self.TEMPERATURE_COEFFICIENT) - * 1000 - ) / 24.0 - return min(self.max_heizleistung, heizleistung) - - def elektrische_leistung_berechnen(self, aussentemperatur): - """Calculate electrical power based on outside temperature.""" - return 1164 - 77.8 * aussentemperatur + 1.62 * aussentemperatur**2.0 - - def simulate_24h(self, temperaturen): - """Simulate power data for 24 hours based on provided temperatures.""" - leistungsdaten = [] - - if len(temperaturen) != self.prediction_hours: - raise ValueError( - "The temperature array must contain exactly " - + str(self.prediction_hours) - + " entries, one for each hour of the day." - ) - - for temp in temperaturen: - elektrische_leistung = self.elektrische_leistung_berechnen(temp) - leistungsdaten.append(elektrische_leistung) - return leistungsdaten - - -# Example usage of the class -if __name__ == "__main__": - max_heizleistung = 5000 # 5 kW heating power - 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 - - # Print COP for various outside temperatures - print(wp.cop_berechnen(-10), " ", wp.cop_berechnen(0), " ", wp.cop_berechnen(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, - ] - - # Calculate the 24-hour power data - leistungsdaten = wp.simulate_24h(temperaturen) - - print(leistungsdaten) diff --git a/modules/heatpump.py b/modules/heatpump.py new file mode 100644 index 00000000..d97378b2 --- /dev/null +++ b/modules/heatpump.py @@ -0,0 +1,142 @@ +import logging +from typing import List, Sequence + + +class Heatpump: + MAX_HEATOUTPUT = 5000 + """Maximum heating power in watts""" + + BASE_HEATPOWER = 235.0 + """Base heating power value""" + + TEMPERATURE_COEFFICIENT = -11.645 + """Coefficient for temperature""" + + COP_BASE = 3.0 + """Base COP value""" + + COP_COEFFICIENT = 0.1 + """COP increase per degree""" + + def __init__(self, max_heat_output, prediction_hours): + self.max_heat_output = max_heat_output + self.prediction_hours = prediction_hours + self.log = logging.getLogger(__name__) + + def __check_outside_temperature_range__(self, temp_celsius: float) -> bool: + """Check if temperature is in valid range between -100 and 100 degree Celsius. + + Args: + temp_celsius: Temperature in degree Celsius + + Returns: + bool: True if in range + """ + return temp_celsius > -100 and temp_celsius < 100 + + def calculate_cop(self, outside_temperature_celsius: float) -> float: + """Calculate the coefficient of performance (COP) based on outside temperature. Supported + temperate range -100 degree Celsius to 100 degree Celsius. + + Args: + outside_temperature_celsius: Outside temperature in degree Celsius + + Raise: + ValueError: If outside temperature isn't range. + + Return: + cop: Calculated COP based on temperature + """ + # TODO: Support for other temperature units (e.g Fahrenheit, Kelvin) + # Check for sensible temperature values + if self.__check_outside_temperature_range__(outside_temperature_celsius): + cop = self.COP_BASE + (outside_temperature_celsius * self.COP_COEFFICIENT) + return max(cop, 1) + else: + err_msg = f"Outside temperature '{outside_temperature_celsius}' not in range (min: -100 Celsius, max: 100 Celsius) " + self.log.error(err_msg) + raise ValueError(err_msg) + + def calculate_heating_output(self, outside_temperature_celsius: float) -> float: + """Calculate the heating output in Watts based on outside temperature in degree Celsius. + Temperature range must be between -100 and 100 degree Celsius. + + Args: + outside_temperature_celsius: Outside temperature in degree Celsius + + Raises: + ValueError: Raised if outside temperature isn't in described range. + + Returns: + heating output: Calculated heating output in Watts. + """ + if self.__check_outside_temperature_range__(outside_temperature_celsius): + heat_output = ( + ( + self.BASE_HEATPOWER + + outside_temperature_celsius * self.TEMPERATURE_COEFFICIENT + ) + * 1000 + ) / 24.0 + return min(self.max_heat_output, heat_output) + else: + err_msg = f"Outside temperature '{outside_temperature_celsius}' not in range (min: -100 Celsius, max: 100 Celsius) " + self.log.error(err_msg) + raise ValueError(err_msg) + + def calculate_heat_power(self, outside_temperature_celsius: float) -> float: + """Calculate electrical power based on outside temperature (degree Celsius). + + Args: + outside_temperature_celsius: Temperature in range -100 to 100 degree Celsius. + + Raises: + ValueError: Raised if temperature isn't in described range + + Returns: + power: Calculated electrical power in Watt. + """ + if self.__check_outside_temperature_range__(outside_temperature_celsius): + return ( + 1164 + - 77.8 * outside_temperature_celsius + + 1.62 * outside_temperature_celsius**2.0 + ) + else: + err_msg = f"Outside temperature '{outside_temperature_celsius}' not in range (min: -100 Celsius, max: 100 Celsius) " + self.log.error(err_msg) + raise ValueError(err_msg) + + def simulate_24h(self, temperatures: Sequence[float]) -> List[float]: + """Simulate power data for 24 hours based on provided temperatures.""" + power_data: List[float] = [] + + if len(temperatures) != self.prediction_hours: + raise ValueError( + f"The temperature array must contain exactly {self.prediction_hours} entries, one for each hour of the day." + ) + + for temp in temperatures: + power = self.calculate_heat_power(temp) + power_data.append(power) + return power_data + + +# Example usage of the class +if __name__ == "__main__": + max_heizleistung = 5000 # 5 kW heating power + 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 + + # Print COP for various outside temperatures + print(wp.calculate_cop(-10), " ", wp.calculate_cop(0), " ", wp.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) + + print(leistungsdaten) diff --git a/tests/conftest.py b/tests/conftest.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/test_heatpump.py b/tests/test_heatpump.py index 6d3c7a78..faecdef5 100644 --- a/tests/test_heatpump.py +++ b/tests/test_heatpump.py @@ -1,17 +1,36 @@ import pytest -from modules.class_heatpump import Heatpump +from modules.heatpump import Heatpump @pytest.fixture(scope="function") -def heatpump() -> Heatpump: +def hp_5kw_24h() -> Heatpump: """Heatpump with 5 kw heating power and 24 h prediction""" return Heatpump(5000, 24) class TestHeatpump: - def test_cop(self, heatpump): + def test_cop(self, hp_5kw_24h: Heatpump): """Testing calculate COP for variouse outside temperatures""" - assert heatpump.cop_berechnen(-10) == 2.0, "COP for -10 degree isn't correct" - assert heatpump.cop_berechnen(0) == 3.0, "COP for 0 degree isn't correct" - assert heatpump.cop_berechnen(10) == 4.0, "COP for 10 degree isn't correct" + assert hp_5kw_24h.calculate_cop(-10) == 2.0 + assert hp_5kw_24h.calculate_cop(0) == 3.0 + assert hp_5kw_24h.calculate_cop(10) == 4.0 + # Check edge case for outside temperature + out_temp_min = -100.1 + out_temp_max = 100.1 + with pytest.raises(ValueError, match=f"'{out_temp_min}' not in range"): + hp_5kw_24h.calculate_cop(out_temp_min) + with pytest.raises(ValueError, match=f"'{out_temp_max}' not in range"): + hp_5kw_24h.calculate_cop(out_temp_max) + + def test_heating_output(self, hp_5kw_24h: Heatpump): + """Testing calculate of heating output""" + assert hp_5kw_24h.calculate_heating_output(-10.0) == 5000 + assert hp_5kw_24h.calculate_heating_output(0.0) == 5000 + assert hp_5kw_24h.calculate_heating_output(10.0) == pytest.approx(4939.583) + + def test_heating_power(self, hp_5kw_24h: Heatpump): + """Testing calculation of heating power""" + assert hp_5kw_24h.calculate_heat_power(-10.0) == 2104 + assert hp_5kw_24h.calculate_heat_power(0.0) == 1164 + assert hp_5kw_24h.calculate_heat_power(10.0) == 548