Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rule 19-36 raised messaged fix #1562

Open
wants to merge 12 commits into
base: develop
Choose a base branch
from
4 changes: 2 additions & 2 deletions rct229/rulesets/ashrae9012019/section19/section19rule36.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ def get_calc_vals(self, context, data=None):
energy_recovery_b, "air_energy_recovery", "design_latent_effectiveness"
)
ERV_OA_airflow_b = getattr_(
energy_recovery_b, "air_energy_recovery", "outside_air_flow"
energy_recovery_b, "air_energy_recovery", "outdoor_airflow"
)
ERV_EA_airflow_b = getattr_(
energy_recovery_b, "air_energy_recovery", "exhaust_air_flow"
energy_recovery_b, "air_energy_recovery", "exhaust_airflow"
)
hvac_min_oa_flow_b = getattr_(
hvac_b, "HVAC", "fan_system", "minimum_outdoor_airflow"
Expand Down
11 changes: 6 additions & 5 deletions rct229/rulesets/ashrae9012019/section21/section21rule1.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,8 @@ def __init__(self):
standard_section="Section G3.1.1.3 Baseline HVAC System Requirements for Systems Utilizing Purchased "
"Chilled Water and/or Purchased Heat",
is_primary_rule=False,
list_path="ruleset_model_descriptions[0]",
manual_check_required_msg="Manual Check Required - Proposed is modeled with purchased hot water or steam. "
"Make sure the heating source in the baseline building is also purchased hot water or steam.",
not_applicable_msg="Rule 21-1 Not Applicable - the proposed is not modeled with Purchased Hot Water or "
"Steam",
list_path="ruleset_model_descriptions[0]"

)

class RulesetModelInstanceRule(PartialRuleDefinition):
Expand All @@ -40,6 +37,10 @@ def __init__(self):
rmds_used=produce_ruleset_model_description(
USER=False, BASELINE_0=False, PROPOSED=True
),
manual_check_required_msg="Manual Check Required - Proposed is modeled with purchased hot water or steam. "
"Make sure the heating source in the baseline building is also purchased hot water or steam.",
not_applicable_msg="Rule 21-1 Not Applicable - the proposed is not modeled with Purchased Hot Water or "
"Steam",
)

def applicability_check(self, context, calc_vals, data):
Expand Down
11 changes: 6 additions & 5 deletions rct229/rulesets/ashrae9012019/section21/section21rule2.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,8 @@ def __init__(self):
standard_section="Section G3.1.1.3 Baseline HVAC System Requirements for Systems Utilizing Purchased "
"Chilled Water and/or Purchased Heat",
is_primary_rule=False,
list_path="ruleset_model_descriptions[0]",
manual_check_required_msg="Manual Check Required - Proposed is modeled with purchased hot water or steam. "
"Make sure the baseline model uses the same number of pumps for the heating loop.",
not_applicable_msg="Rule 21-1 Not Applicable - the proposed is not modeled with Purchased Hot Water or "
"Steam",
list_path="ruleset_model_descriptions[0]"

)

class RulesetModelInstanceRule(PartialRuleDefinition):
Expand All @@ -37,6 +34,10 @@ def __init__(self):
rmds_used=produce_ruleset_model_description(
USER=False, BASELINE_0=False, PROPOSED=True
),
manual_check_required_msg="Manual Check Required - Proposed is modeled with purchased hot water or steam. "
"Make sure the baseline model uses the same number of pumps for the heating loop.",
not_applicable_msg="Rule 21-2 Not Applicable - the proposed is not modeled with Purchased Hot Water or "
"Steam"
)

def applicability_check(self, context, calc_vals, data):
Expand Down
10 changes: 5 additions & 5 deletions rct229/rulesets/ashrae9012019/section22/section22rule35.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,18 @@ def __init__(self):
ruleset_section_title="HVAC - Chiller",
standard_section="Section G3.1.3.10 Chilled-Water Pumps (Systems 7, 8, 11, 12, and 13)",
is_primary_rule=False,
list_path="ruleset_model_descriptions[0]",
manual_check_required_msg="Manual Check Required - Baseline is modeled with purchased chilled water. Make"
"sure baseline systems served by purchased chilled water are not modeled with chilled water reset.",
not_applicable_msg="Rule 22-35 Not Applicable - the baseline is not modeled with Purchased Chilled Water",
)
list_path="ruleset_model_descriptions[0]")

class RulesetModelInstanceRule(PartialRuleDefinition):
def __init__(self):
super(Section22Rule35.RulesetModelInstanceRule, self,).__init__(
rmds_used=produce_ruleset_model_description(
USER=False, BASELINE_0=True, PROPOSED=False
),
manual_check_required_msg="Manual Check Required - Baseline is modeled with purchased chilled water. Make "
"sure baseline systems served by purchased chilled water are not modeled with chilled water reset.",
not_applicable_msg="Rule 22-35 Not Applicable - the baseline is not modeled with Purchased Chilled Water",

)

def applicability_check(self, context, calc_vals, data):
Expand Down
10 changes: 5 additions & 5 deletions rct229/rulesets/ashrae9012019/section22/section22rule37.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,18 @@ def __init__(self):
ruleset_section_title="HVAC - Chiller",
standard_section="Section G3.1.3.10 Chilled-Water Pumps (Systems 7, 8, 11, 12, and 13)",
is_primary_rule=False,
list_path="ruleset_model_descriptions[0]",
manual_check_required_msg="Manual Check Required - Baseline is modeled with purchased chilled water. Make "
"sure baseline systems served by purchased chilled water are modeled with a variable speed drive pump.",
not_applicable_msg="Rule 22-37 Not Applicable - the baseline is not modeled with Purchased Chilled Water",
)
list_path="ruleset_model_descriptions[0]")

class RulesetModelInstanceRule(PartialRuleDefinition):
def __init__(self):
super(Section22Rule37.RulesetModelInstanceRule, self,).__init__(
rmds_used=produce_ruleset_model_description(
USER=False, BASELINE_0=True, PROPOSED=False
),
manual_check_required_msg="Manual Check Required - Baseline is modeled with purchased chilled water. Make "
"sure baseline systems served by purchased chilled water are modeled with a variable speed drive pump.",
not_applicable_msg="Rule 22-37 Not Applicable - the baseline is not modeled with Purchased Chilled Water",

)

def applicability_check(self, context, calc_vals, data):
Expand Down
13 changes: 7 additions & 6 deletions rct229/rulesets/ashrae9012019/section22/section22rule38.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,20 @@ def __init__(self):
ruleset_section_title="HVAC - Chiller",
standard_section="Section G3.1.3.10 Chilled-Water Pumps (Systems 7, 8, 11, 12, and 13)",
is_primary_rule=False,
list_path="ruleset_model_descriptions[0]",
manual_check_required_msg="Manual Check Required - Baseline is modeled with purchased chilled water. Make sure "
"baseline systems served by purchased chilled water are modeled with the purchased chilled water loop having "
"a minimum flow setpoint of 25%.",
not_applicable_msg="Rule 22-38 Not Applicable - the baseline is not modeled with Purchased Chilled Water",
)
list_path="ruleset_model_descriptions[0]"
)

class RulesetModelInstanceRule(PartialRuleDefinition):
def __init__(self):
super(Section22Rule38.RulesetModelInstanceRule, self,).__init__(
rmds_used=produce_ruleset_model_description(
USER=False, BASELINE_0=True, PROPOSED=False
),
manual_check_required_msg="Manual Check Required - Baseline is modeled with purchased chilled water. Make sure "
"baseline systems served by purchased chilled water are modeled with the purchased chilled water loop having "
"a minimum flow setpoint of 25%.",
not_applicable_msg="Rule 22-38 Not Applicable - the baseline is not modeled with Purchased Chilled Water",

)

def applicability_check(self, context, calc_vals, data):
Expand Down
9 changes: 5 additions & 4 deletions rct229/rulesets/ashrae9012019/section22/section22rule39.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@ def __init__(self):
ruleset_section_title="HVAC - Chiller",
standard_section="Section G3.1.3.10 Chilled-Water Pumps (Systems 7, 8, 11, 12, and 13)",
is_primary_rule=False,
list_path="ruleset_model_descriptions[0]",
manual_check_required_msg="Manual Check Required - Baseline is modeled with purchased chilled water. Make sure "
"baseline systems served by purchased chilled water are modeled with a distribution pump whose pump power is 16W/gpm.",
not_applicable_msg="Rule 22-39 Not Applicable - the baseline is not modeled with Purchased Chilled Water",
list_path="ruleset_model_descriptions[0]"
)

class RulesetModelInstanceRule(PartialRuleDefinition):
Expand All @@ -35,6 +32,10 @@ def __init__(self):
rmds_used=produce_ruleset_model_description(
USER=False, BASELINE_0=True, PROPOSED=False
),
manual_check_required_msg="Manual Check Required - Baseline is modeled with purchased chilled water. Make sure "
"baseline systems served by purchased chilled water are modeled with a distribution pump whose pump power is 16 W/gpm.",
not_applicable_msg="Rule 22-39 Not Applicable - the baseline is not modeled with Purchased Chilled Water",

)

def applicability_check(self, context, calc_vals, data):
Expand Down
2 changes: 1 addition & 1 deletion rct229/rulesets/ashrae9012019/section4/section4rule1.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
ZCC.CONDITIONED_RESIDENTIAL,
]
MANUAL_CHECK_MSG = (
"There is a temperature schedule mismatch between the baseline and proposed rmds. Fail unless "
"There is a temperature schedule mismatch between the baseline and proposed. Fail unless "
"Table G3.1 #4 baseline column exception #s 1 and/or 2 are applicable "
)

Expand Down
1 change: 1 addition & 0 deletions rct229/rulesets/ashrae9012019/section5/section5rule28.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ def __init__(self):
"unit": "",
}
},
manual_check_required_msg=MANUAL_CHECK_MSG,
)

def is_applicable(self, context, data=None):
Expand Down
4 changes: 2 additions & 2 deletions rct229/rulesets/ashrae9012019/section5/section5rule37.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ def __init__(self):
standard_section="Section G3.1-5(b) Building Envelope Modeling Requirements for the Proposed design",
is_primary_rule=True,
list_path="ruleset_model_descriptions[0].buildings[*]",
data_items={"climate_zone": (PROPOSED, "weather/climate_zone")},
manual_check_required_msg=MANUAL_CHECK_MSG,
data_items={"climate_zone": (PROPOSED, "weather/climate_zone")}
)

class BuildingRule(RuleDefinitionBase):
Expand All @@ -63,6 +62,7 @@ def __init__(self):
"unit": "cfm",
}
},
manual_check_required_msg=MANUAL_CHECK_MSG,
)

def get_calc_vals(self, context, data=None):
Expand Down
44 changes: 32 additions & 12 deletions rct229/ruletest_engine/ruletest_engine.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import glob
import json
from typing import Optional

# from jsonpointer import JsonPointer
import os
from copy import deepcopy
from typing import Optional

from pint import Quantity

from rct229.reports.ashrae9012019.ashrae901_2019_software_test_report import (
ASHRAE9012019SoftwareTestReport,
)
Expand Down Expand Up @@ -107,18 +106,22 @@ def evaluate_outcome_enumeration_str(outcome_enumeration_str):
return test_result


def process_test_result(test_result, test_dict, test_id):
def process_test_result(test_result, raised_message, test_dict, test_id):
"""Returns a string describing whether or not a test resulted in its expected outcome

Parameters
----------
test_result : str

String describing rule outcome. OPTIONS: 'pass', 'fail', 'undetermined'
String describing rule outcome. OPTIONS: 'pass', 'fail', 'undetermined', 'not_applicable'

raised_message : str

String describing any outcome or exception message from running the rule.

test_dict : dict

Python dictionary containing the a test's expected outcome and description
Python dictionary containing the test's expected outcome and description

test_id: str

Expand All @@ -145,13 +148,23 @@ def process_test_result(test_result, test_dict, test_id):
# Check if the test results agree with the expected outcome. Write an appropriate response based on their agreement
received_expected_outcome = test_result == test_dict["expected_rule_outcome"]

# TODO - ask about tests where a raised message exists but is not captured. Code written to catch those.

# Check for any raised message in the rule test. If none exists, return empty string ""
expected_raised_message = test_dict.get("expected_raised_message_includes", "")

# Check if the raised message is a substring in the expected raised message (tests often don't have the full
# message)
messages_matched = expected_raised_message in raised_message

# Success and failure tied to
overall_outcome = messages_matched and received_expected_outcome

# Check if the test results agree with the expected outcome. Write an appropriate response based on their agreement
if received_expected_outcome:
if test_result == "pass":
# f"SUCCESS: Test {test_id} passed as expected. The following condition was identified: {description}"
outcome_text = "PASS"
elif test_result == "fail":
# f"SUCCESS: Test {test_id} failed as expected. The following condition was identified: {description}"
outcome_text = "FAIL"
elif test_result == "undetermined":
outcome_text = "UNDETERMINED"
Expand All @@ -175,7 +188,14 @@ def process_test_result(test_result, test_dict, test_id):
f"FAILURE: Test {test_id} returned '{test_result}' unexpectedly"
)

return outcome_text, received_expected_outcome
# Check if exception messages matched. If not, append that to the outcome message.
if not messages_matched:
outcome_text += (
f"\rMessages did not match. Expected outcome message was '{expected_raised_message}' and "
f"instead received '{raised_message}'"
)

return outcome_text, overall_outcome


def run_section_tests(
Expand Down Expand Up @@ -345,9 +365,6 @@ def run_section_tests(

print("") # Buffer line

# Return whether or not all tests in this test JSON received their expected outcome as a boolean
all_tests_successful = all(test_result_dict["results"])

return all_tests_pass


Expand Down Expand Up @@ -660,9 +677,12 @@ def evaluate_outcome_object(outcome_dict, test_result_dict, test_dict, test_id):
# (e.g., "PASSED" => "pass")
test_result = evaluate_outcome_enumeration_str(outcome_enumeration_str)

# Check for any raised message in the outcome results. If none exists, return empty string ""
raised_message = outcome_dict.get("message", "")

# Write outcome text based and "receive_expected_outcome" boolean based on the test result
outcome_text, received_expected_outcome = process_test_result(
test_result, test_dict, test_id
test_result, raised_message, test_dict, test_id
)

# Append results if expected outcome not received
Expand Down
Loading
Loading