mirror of
https://github.com/Akkudoktor-EOS/EOS.git
synced 2025-04-19 08:55:15 +00:00
Heat pump: Tests, Translation, Docstrings, Relocation (#89)
* Add first unit test for heatpump COP calculation * Translate to english, add type hints, improve unit tests. * Run pre-commit * Apply suggestions from code review Co-authored-by: Michael Osthege <michael.osthege@outlook.com> * Remove conftest file --------- Co-authored-by: Michael Osthege <michael.osthege@outlook.com>
This commit is contained in:
parent
75d87aa94a
commit
a1c071c1a8
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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)
|
142
modules/heatpump.py
Normal file
142
modules/heatpump.py
Normal file
@ -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)
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user