From 356c4b14a6d14a100392e913d1484f24540e390f Mon Sep 17 00:00:00 2001 From: hannesdiedrich Date: Mon, 18 Aug 2025 13:40:25 +0200 Subject: [PATCH 1/2] GSYE-906: Adapt HeatPumpValidator in order to be able to validate PCM storages parameters too --- gsy_framework/constants_limits.py | 2 +- .../validators/heat_pump_validator.py | 61 +++++++++++++++---- 2 files changed, 51 insertions(+), 12 deletions(-) diff --git a/gsy_framework/constants_limits.py b/gsy_framework/constants_limits.py index c34177ba..26994619 100644 --- a/gsy_framework/constants_limits.py +++ b/gsy_framework/constants_limits.py @@ -196,7 +196,7 @@ class HeatPumpSettings: # range limits MAX_POWER_RATING_KW_LIMIT = RangeLimit(0, sys.maxsize) - TEMP_C_LIMIT = RangeLimit(0.0, 200.0) + TEMP_C_LIMIT = RangeLimit(0.0, 100.0) TANK_VOLUME_L_LIMIT = RangeLimit(0, sys.maxsize) BUYING_RATE_LIMIT = RateRange(0, 10000) diff --git a/gsy_framework/validators/heat_pump_validator.py b/gsy_framework/validators/heat_pump_validator.py index 5b9f59ee..75de7cc3 100644 --- a/gsy_framework/validators/heat_pump_validator.py +++ b/gsy_framework/validators/heat_pump_validator.py @@ -1,12 +1,23 @@ +from dataclasses import dataclass, fields + from gsy_framework.constants_limits import ConstSettings +from gsy_framework.enums import HeatPumpSourceType from gsy_framework.exceptions import GSyDeviceException from gsy_framework.validators.base_validator import BaseValidator from gsy_framework.validators.utils import validate_range_limit -from gsy_framework.enums import HeatPumpSourceType HeatPumpSettings = ConstSettings.HeatPumpSettings +@dataclass +class TempArgNames: + """Class for passing argument names for the temperature validation""" + + minimal: str = "min_temp_C" + maximal: str = "max_temp_C" + initial: str = "initial_temp_C" + + class HeatPumpValidator(BaseValidator): """Validator class for HeatPump assets.""" @@ -18,6 +29,14 @@ def validate(cls, **kwargs): cls._validate_tank_volume(**kwargs) cls._validate_profiles(**kwargs) cls._validate_max_power(**kwargs) + cls._validate_pcm_related_parameters(**kwargs) + + @classmethod + def _validate_pcm_related_parameters(cls, **kwargs): + if "min_temp_pcm_C" not in kwargs: + return + assert kwargs.get("mass_flow_rate") > 0 + assert kwargs.get("number_of_plates") > 0 @classmethod def _validate_profiles(cls, **kwargs): @@ -57,19 +76,38 @@ def _validate_max_power(cls, **kwargs): @classmethod def _validate_temp(cls, **kwargs): """Validate temperature related arguments.""" - temperature_arg_names = ["min_temp_C", "max_temp_C", "initial_temp_C"] - for temperature_arg_name in temperature_arg_names: - if kwargs.get(temperature_arg_name): + if "min_temp_pcm_C" in kwargs: + cls._validate_pcm_tank_temps(**kwargs) + else: + cls._validate_water_tank_temps(**kwargs) + + @classmethod + def _validate_water_tank_temps(cls, **kwargs): + cls._validate_temperature_ranges(TempArgNames(), **kwargs) + + @classmethod + def _validate_pcm_tank_temps(cls, **kwargs): + cls._validate_temperature_ranges( + TempArgNames("min_temp_pcm_C", "max_temp_pcm_C"), **kwargs + ) + cls._validate_temperature_ranges( + TempArgNames("min_temp_htf_C", "max_temp_htf_C"), **kwargs + ) + + @classmethod + def _validate_temperature_ranges(cls, temp_arg_names: TempArgNames, **kwargs): + for temp_arg_name in [f.name for f in fields(temp_arg_names)]: + if kwargs.get(temp_arg_name): cls._check_range( - name=temperature_arg_name, - value=kwargs[temperature_arg_name], + name=temp_arg_name, + value=kwargs[temp_arg_name], min_value=HeatPumpSettings.TEMP_C_LIMIT.min, max_value=HeatPumpSettings.TEMP_C_LIMIT.max, ) - min_temp_c = kwargs.get("min_temp_C") - max_temp_c = kwargs.get("max_temp_C") - initial_temp_c = kwargs.get("initial_temp_C") + min_temp_c = kwargs.get(temp_arg_names.minimal) + max_temp_c = kwargs.get(temp_arg_names.maximal) + initial_temp_c = kwargs.get(temp_arg_names.initial) if min_temp_c is None: min_temp_c = HeatPumpSettings.MIN_TEMP_C if max_temp_c is None: @@ -81,14 +119,15 @@ def _validate_temp(cls, **kwargs): raise GSyDeviceException( { "misconfiguration": [ - "Requirement 'min_temp_C <= initial_temp_C <= max_temp_C' is not met." + f"Requirement 'min_temp <= initial_temp <= max_temp' is not met. " + f"({temp_arg_names})" ] } ) if min_temp_c == max_temp_c: raise GSyDeviceException( - {"misconfiguration": ["min_temp_C should not be equal to max_temp_C"]} + {"misconfiguration": ["min_temp should not be equal to max_temp_C"]} ) @classmethod From 3f916c4f700455ce7325360c9b559b76b9d09b4d Mon Sep 17 00:00:00 2001 From: hannesdiedrich Date: Tue, 19 Aug 2025 10:35:39 +0200 Subject: [PATCH 2/2] GSYE-906: Fix tests --- gsy_framework/validators/heat_pump_validator.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gsy_framework/validators/heat_pump_validator.py b/gsy_framework/validators/heat_pump_validator.py index 75de7cc3..8a05ef21 100644 --- a/gsy_framework/validators/heat_pump_validator.py +++ b/gsy_framework/validators/heat_pump_validator.py @@ -1,4 +1,4 @@ -from dataclasses import dataclass, fields +from dataclasses import dataclass, asdict from gsy_framework.constants_limits import ConstSettings from gsy_framework.enums import HeatPumpSourceType @@ -35,7 +35,7 @@ def validate(cls, **kwargs): def _validate_pcm_related_parameters(cls, **kwargs): if "min_temp_pcm_C" not in kwargs: return - assert kwargs.get("mass_flow_rate") > 0 + assert kwargs.get("volume_flow_rate_l_min") > 0 assert kwargs.get("number_of_plates") > 0 @classmethod @@ -96,7 +96,7 @@ def _validate_pcm_tank_temps(cls, **kwargs): @classmethod def _validate_temperature_ranges(cls, temp_arg_names: TempArgNames, **kwargs): - for temp_arg_name in [f.name for f in fields(temp_arg_names)]: + for temp_arg_name in asdict(temp_arg_names).values(): if kwargs.get(temp_arg_name): cls._check_range( name=temp_arg_name,