diff --git a/rct229/rulesets/ashrae9012019/section23/__init__.py b/rct229/rulesets/ashrae9012019/section23/__init__.py index 3565395446..33fdb8a12a 100644 --- a/rct229/rulesets/ashrae9012019/section23/__init__.py +++ b/rct229/rulesets/ashrae9012019/section23/__init__.py @@ -18,6 +18,7 @@ "section23rule14", "section23rule15", "section23rule16", + "section23rule17", ] diff --git a/rct229/rulesets/ashrae9012019/section23/section23rule17.py b/rct229/rulesets/ashrae9012019/section23/section23rule17.py new file mode 100644 index 0000000000..4e2e67f3b6 --- /dev/null +++ b/rct229/rulesets/ashrae9012019/section23/section23rule17.py @@ -0,0 +1,115 @@ +from rct229.rule_engine.rule_base import RuleDefinitionBase +from rct229.rule_engine.rule_list_indexed_base import RuleDefinitionListIndexedBase +from rct229.rule_engine.ruleset_model_factory import produce_ruleset_model_description +from rct229.rulesets.ashrae9012019 import BASELINE_0 +from rct229.rulesets.ashrae9012019.ruleset_functions.baseline_system_type_compare import ( + baseline_system_type_compare, +) +from rct229.rulesets.ashrae9012019.ruleset_functions.baseline_systems.baseline_system_util import ( + HVAC_SYS, +) +from rct229.rulesets.ashrae9012019.ruleset_functions.get_baseline_system_types import ( + get_baseline_system_types, +) +from rct229.schema.config import ureg +from rct229.utils.assertions import getattr_ +from rct229.utils.pint_utils import CalcQ + +APPLICABLE_SYS_TYPES = [ + HVAC_SYS.SYS_2, + HVAC_SYS.SYS_4, +] + + +class Section23Rule17(RuleDefinitionListIndexedBase): + """Rule 17 of ASHRAE 90.1-2019 Appendix G Section 23 (Air-side)""" + + def __init__(self): + super(Section23Rule17, self).__init__( + rmds_used=produce_ruleset_model_description( + USER=False, BASELINE_0=True, PROPOSED=False + ), + each_rule=Section23Rule17.HVACRule(), + index_rmd=BASELINE_0, + id="23-17", + description="System 2 and 4 - Electric air-source heat pumps shall shall be modeled to continue to operate while auxiliary heat is energized.", + ruleset_section_title="HVAC - Airside", + standard_section="G3.1.3.1 Heat Pumps (Systems 2 and 4)", + is_primary_rule=True, + rmd_context="ruleset_model_descriptions/0", + list_path="$.buildings[*].building_segments[*].heating_ventilating_air_conditioning_systems[*]", + ) + + def is_applicable(self, context, data=None): + rmd_b = context.BASELINE_0 + baseline_system_types_dict = get_baseline_system_types(rmd_b) + + return any( + [ + baseline_system_types_dict[system_type] + and baseline_system_type_compare( + system_type, applicable_sys_type, False + ) + for system_type in baseline_system_types_dict + for applicable_sys_type in APPLICABLE_SYS_TYPES + ] + ) + + def create_data(self, context, data): + rmd_b = context.BASELINE_0 + baseline_system_types_dict = get_baseline_system_types(rmd_b) + applicable_hvac_sys_ids = [ + hvac_id + for sys_type in baseline_system_types_dict + for target_sys_type in APPLICABLE_SYS_TYPES + if baseline_system_type_compare(sys_type, target_sys_type, False) + for hvac_id in baseline_system_types_dict[sys_type] + ] + + return { + "applicable_hvac_sys_ids": applicable_hvac_sys_ids, + "baseline_system_types_dict": baseline_system_types_dict, + } + + def list_filter(self, context_item, data): + hvac_sys_b = context_item.BASELINE_0 + applicable_hvac_sys_ids = data["applicable_hvac_sys_ids"] + + return hvac_sys_b["id"] in applicable_hvac_sys_ids + + class HVACRule(RuleDefinitionBase): + def __init__(self): + super(Section23Rule17.HVACRule, self).__init__( + rmds_used=produce_ruleset_model_description( + USER=False, BASELINE_0=True, PROPOSED=False + ), + required_fields={ + "$": ["heating_system"], + }, + precision={ + "heatpump_low_shutoff_b": { + "precision": 0.1, + "unit": "K", + }, + }, + ) + + def get_calc_vals(self, context, data=None): + hvac_b = context.BASELINE_0 + baseline_system_types_dict = data["baseline_system_types_dict"] + + heating_system_b = hvac_b["heating_system"] + heatpump_low_shutoff_b = getattr_( + heating_system_b, "HeatingSystem", "heatpump_low_shutoff_temperature" + ) + return { + "heatpump_low_shutoff_temperature": CalcQ( + "temperature", heatpump_low_shutoff_b + ), + } + + def rule_check(self, context, calc_vals=None, data=None): + heatpump_low_shutoff_b = calc_vals["heatpump_low_shutoff_temperature"] + # The heat pump low shutoff temperature equal to the flag of -999, which indicates that there is no low-temperature shutoff for the heatpump + # The minimum temperature is not finalized and is up for discussion. Must coordinate with the note provided in the schema element: HeatingSystem.heatpump_low_shutoff_temperature + return heatpump_low_shutoff_b <= -999 * ureg("F") diff --git a/rct229/ruletest_engine/ruletest_jsons/ashrae9012019/section23/rule_23_17.json b/rct229/ruletest_engine/ruletest_jsons/ashrae9012019/section23/rule_23_17.json new file mode 100644 index 0000000000..f8bc4ba4fa --- /dev/null +++ b/rct229/ruletest_engine/ruletest_jsons/ashrae9012019/section23/rule_23_17.json @@ -0,0 +1,307 @@ +{ + "rule-23-17-a": { + "Section": 23, + "Rule": 17, + "Test": "a", + "test_description": "The project has one building segment with one zone served by baseline system type 4. The heat pump low shutoff temperature equal to the flag of -999, which indicates that there is no low-temperature shutoff for the heatpump", + "expected_rule_outcome": "pass", + "standard": { + "rule_id": "23-17", + "ruleset_reference": "G3.1.3.1 Heat Pumps (Systems 2 and 4)", + "rule_description": "System 2 and 4 - Electric air-source heat pumps shall shall be modeled to continue to operate while auxiliary heat is energized.", + "applicable_rmr": "Baseline Model", + "rule_assertion": "=", + "comparison_value": "Expected Value", + "rule_dependency": 0, + "mandatory_rule": "Full", + "schema_version": "0.0.37" + }, + "rmd_transformations": { + "baseline": { + "id": "ASHRAE229 1", + "data_timestamp": "2024-02-12T09:00Z", + "ruleset_model_descriptions": [ + { + "id": "RMD 1", + "buildings": [ + { + "id": "Building 1", + "building_segments": [ + { + "id": "Building Segment 1", + "zones": [ + { + "id": "Thermal Zone 1", + "terminals": [ + { + "id": "Air Terminal", + "is_supply_ducted": true, + "type": "CONSTANT_AIR_VOLUME", + "served_by_heating_ventilating_air_conditioning_system": "System Type 4" + } + ] + } + ], + "heating_ventilating_air_conditioning_systems": [ + { + "id": "System Type 4", + "cooling_system": { + "id": "DX Coil 1", + "type": "DIRECT_EXPANSION" + }, + "heating_system": { + "id": "HP Coil 1", + "type": "HEAT_PUMP", + "heatpump_low_shutoff_temperature": -999.0 + }, + "fan_system": { + "id": "CAV Fan System 1", + "fan_control": "CONSTANT", + "supply_fans": [ + { + "id": "Supply Fan 1" + } + ], + "return_fans": [ + { + "id": "Return Fan 1" + } + ] + } + } + ] + } + ] + } + ], + "type": "BASELINE_0" + } + ] + } + } + }, + "rule-23-17-b": { + "Section": 23, + "Rule": 17, + "Test": "b", + "test_description": "The project has one building segment with one zone served by baseline system type 4. The heat pump low shutoff temperature does not equal -999, thereby not indicating that there is no low-temperature shutoff for the heatpump", + "expected_rule_outcome": "fail", + "standard": { + "rule_id": "23-17", + "ruleset_reference": "G3.1.3.1 Heat Pumps (Systems 2 and 4)", + "rule_description": "System 2 and 4 - Electric air-source heat pumps shall shall be modeled to continue to operate while auxiliary heat is energized.", + "applicable_rmr": "Baseline Model", + "rule_assertion": "=", + "comparison_value": "Expected Value", + "rule_dependency": 0, + "mandatory_rule": "Full", + "schema_version": "0.0.37" + }, + "rmd_transformations": { + "baseline": { + "id": "ASHRAE229 1", + "data_timestamp": "2024-02-12T09:00Z", + "ruleset_model_descriptions": [ + { + "id": "RMD 1", + "buildings": [ + { + "id": "Building 1", + "building_segments": [ + { + "id": "Building Segment 1", + "zones": [ + { + "id": "Thermal Zone 1", + "terminals": [ + { + "id": "Air Terminal", + "is_supply_ducted": true, + "type": "CONSTANT_AIR_VOLUME", + "served_by_heating_ventilating_air_conditioning_system": "System Type 4" + } + ] + } + ], + "heating_ventilating_air_conditioning_systems": [ + { + "id": "System Type 4", + "cooling_system": { + "id": "DX Coil 1", + "type": "DIRECT_EXPANSION" + }, + "heating_system": { + "id": "HP Coil 1", + "type": "HEAT_PUMP", + "heatpump_low_shutoff_temperature": 1.6666666666666856 + }, + "fan_system": { + "id": "CAV Fan System 1", + "fan_control": "CONSTANT", + "supply_fans": [ + { + "id": "Supply Fan 1" + } + ], + "return_fans": [ + { + "id": "Return Fan 1" + } + ] + } + } + ] + } + ] + } + ], + "type": "BASELINE_0" + } + ] + } + } + }, + "rule-23-17-c": { + "Section": 23, + "Rule": 17, + "Test": "c", + "test_description": "The project has one building segment with two zones served by baseline system type 7. This rule is for system types 2 and 4 so this is not applicable.", + "expected_rule_outcome": "not_applicable", + "standard": { + "rule_id": "23-17", + "ruleset_reference": "G3.1.3.1 Heat Pumps (Systems 2 and 4)", + "rule_description": "System 2 and 4 - Electric air-source heat pumps shall shall be modeled to continue to operate while auxiliary heat is energized.", + "applicable_rmr": "Baseline Model", + "rule_assertion": "=", + "comparison_value": "Expected Value", + "rule_dependency": 0, + "mandatory_rule": "Full", + "schema_version": "0.0.37" + }, + "rmd_transformations": { + "baseline": { + "id": "ASHRAE229 1", + "data_timestamp": "2024-02-12T09:00Z", + "ruleset_model_descriptions": [ + { + "id": "RMD 1", + "buildings": [ + { + "id": "Building 1", + "building_segments": [ + { + "id": "Building Segment 1", + "zones": [ + { + "id": "Thermal Zone 1", + "terminals": [ + { + "id": "VAV Air Terminal 1", + "is_supply_ducted": true, + "type": "VARIABLE_AIR_VOLUME", + "served_by_heating_ventilating_air_conditioning_system": "System 7", + "heating_source": "HOT_WATER", + "heating_from_loop": "Boiler Loop 1" + } + ] + }, + { + "id": "Thermal Zone 2", + "terminals": [ + { + "id": "VAV Air Terminal 2", + "is_supply_ducted": true, + "type": "VARIABLE_AIR_VOLUME", + "served_by_heating_ventilating_air_conditioning_system": "System 7", + "heating_source": "HOT_WATER", + "heating_from_loop": "Boiler Loop 1" + } + ] + } + ], + "heating_ventilating_air_conditioning_systems": [ + { + "id": "System 7", + "cooling_system": { + "id": "CHW Coil 1", + "type": "FLUID_LOOP", + "chilled_water_loop": "Secondary CHW Loop 1" + }, + "preheat_system": { + "id": "Preheat Coil 1", + "type": "FLUID_LOOP", + "hot_water_loop": "Boiler Loop 1" + }, + "fan_system": { + "id": "VAV Fan System 1", + "fan_control": "VARIABLE_SPEED_DRIVE", + "supply_fans": [ + { + "id": "Supply Fan 1" + } + ], + "return_fans": [ + { + "id": "Return Fan 1" + } + ] + } + } + ] + } + ] + } + ], + "boilers": [ + { + "id": "Boiler 1", + "loop": "Boiler Loop 1", + "energy_source_type": "NATURAL_GAS" + } + ], + "chillers": [ + { + "id": "Chiller 1", + "cooling_loop": "Chiller Loop 1" + } + ], + "pumps": [ + { + "id": "Boiler Pump 1", + "loop_or_piping": "Boiler Loop 1", + "speed_control": "FIXED_SPEED" + }, + { + "id": "Chiller Pump 1", + "loop_or_piping": "Chiller Loop 1", + "speed_control": "FIXED_SPEED" + }, + { + "id": "Secondary CHW Pump", + "loop_or_piping": "Secondary CHW Loop 1", + "speed_control": "VARIABLE_SPEED" + } + ], + "fluid_loops": [ + { + "id": "Boiler Loop 1", + "type": "HEATING" + }, + { + "id": "Chiller Loop 1", + "type": "COOLING", + "child_loops": [ + { + "id": "Secondary CHW Loop 1", + "type": "COOLING" + } + ] + } + ], + "type": "BASELINE_0" + } + ] + } + } + } +} \ No newline at end of file