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

RCT/YJ/Updating report file names #1365

Merged
merged 1 commit into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion rct229/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def run_test(ruleset, section=None):
Run ruleset checking. arguments are \n
--ruleset or -rs: ruleset name. Default is ashrae9012019, available options include: ashrae9012019 \n
--rpds or -f: rpd file directory. accept multiple entries, example: -f ../example/user_model.rpd \n
--reports or -r: reports. Default is RAW_OUTPUT, accept multiple entries, available options include: RAW_OUTPUT, RAW_SUMMARY, ASHRAE9012019_DETAIL, ASHRAE9012019_SUMMARY. \n
--reports or -r: reports. Default is RAW_OUTPUT, accept multiple entries, available options include: EngineRawOutput, EngineRawSummary, ASHRAE9012019SummaryReport, ASHRAE9012019DetailReport. \n
--reports_directory or -rd: directory to save the output reports. \n
"""
help_text = short_help_text
Expand Down
10 changes: 5 additions & 5 deletions rct229/reports/ashrae9012019/ashrae901_2019_detail_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ def __init__(self):
self.title = "ASHRAE STD 229P RULESET CHECKING TOOL"
self.purpose = "Project Testing Report"
self.ruleset = "ASHRAE 90.1-2019 Performance Rating Method (Appendix G)"
self.ruleset_report_file = "ashrae901_2019_detail_report.json"
self.ruleset_report_file = f"{self.__class__.__name__}.json"

def initialize_ruleset_report(self, rule_outcome=None):
report_json = dict()
report_json = {}
report_json["title"] = self.title
report_json["purpose"] = self.purpose
report_json["tool_name"] = self.tool
Expand All @@ -28,9 +28,9 @@ def initialize_ruleset_report(self, rule_outcome=None):
return report_json

def generate_rule_report(self, rule_outcome, outcome_dict):
# set up the rule meta data
# set up the rule metadata
rule_id = rule_outcome["id"]
rule_report = dict()
rule_report = {}
rule_report["rule_id"] = rule_id
rule_report["description"] = rule_outcome["description"]
rule_report["evaluation_type"] = (
Expand All @@ -54,7 +54,7 @@ def save_ruleset_report(self, ruleset_report, report_dir):
def _rule_outcome_helper(self, results, eval_list, outcome_dict):
def output_node(output_result, output_eval_list, output_outcome_dict):
# in this case, it is the rule checking component
evaluation_outcome = dict()
evaluation_outcome = {}
if any(
[
key.startswith("INVALID_") and key.endswith("_CONTEXT")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import json
from copy import deepcopy
from datetime import datetime
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deleted b/c it's not in use.


from rct229 import __version__ as version
from rct229.report_engine.rct_report import RCTReport
from rct229.reports.utils import test_evaluation_converter
from rct229.schema import config


class ASHRAE9012019SoftwareTestReport(RCTReport):
Expand All @@ -14,10 +12,10 @@ def __init__(self):
self.title = "ASHRAE STD 229P RULESET CHECKING TOOL"
self.purpose = "RCT Ruleset Software Testing Report"
self.ruleset = "ASHRAE 90.1-2019 Performance Rating Method (Appendix G)"
self.ruleset_report_file = "ashrae901_2019_software_testing_report.json"
self.ruleset_report_file = f"{self.__class__.__name__}.json"

def initialize_ruleset_report(self, rule_outcome=None):
report_json = dict()
report_json = {}
report_json["title"] = self.title
report_json["purpose"] = self.purpose
report_json["tool_name"] = self.tool
Expand Down
61 changes: 45 additions & 16 deletions rct229/reports/ashrae9012019/ashrae901_2019_summary_report.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import re

from pydash import find

from rct229.report_engine.rct_report import RCTReport
from rct229.rule_engine.rct_outcome_label import RCTOutcomeLabel

Expand All @@ -12,24 +11,30 @@ def __init__(self):
self.title = "ASHRAE STD 229P RULESET CHECKING TOOL"
self.purpose = "Summary Report"
self.ruleset = "ASHRAE 90.1-2019 Performance Rating Method (Appendix G)"
self.ruleset_report_file = "ashrae901_2019_summary_report.md"
self.ruleset_report_file = f"{self.__class__.__name__}.md"

def initialize_ruleset_report(self, rule_outcome=None):
self.section_list = [
"All",
"Performance Calculations",
"Schedules Setpoints",
"Envelope",
"Lighting",
"HVAC General",
"Receptacles",
"Transformers",
"HVAC-Baseline",
"HVAC-General",
"HVAC-HotWaterSide",
"HVAC-ChilledWaterSide",
"HVAC-AirSide",
]
] # TODO: need to expand as more sections are developed
self.section_dict = {
"1": "Performance Calculations",
"4": "Schedules Setpoints",
"5": "Envelope",
"6": "Lighting",
"10": "HVAC General",
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@weilixu Both sections 10 and 19 have the same section name. Should we update one of these section names?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yunjoonjung-PNNL There are several things happening here. Section 19 and Section 10 are sort of mixed. I know there are some discussions on moving the unmet load hours check to section 10 but we currently put this on hold until everything becomes more stable.
A rule renumbering will be conducted, we just need to wait longer to get everything sort out first.

For now, using HVAC - General for section 19 and HVAC General for section 10.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds great! I'll move the rules when they are reorganized.

"12": "Receptacles",
"15": "Transformers",
"18": "HVAC-Baseline",
Expand Down Expand Up @@ -73,16 +78,16 @@ def initialize_ruleset_report(self, rule_outcome=None):
##### Date: {self.date_run}

### RMD Files
- user: {user_match["file_name"] if user_match else ""}
- proposed: {proposed_match["file_name"] if proposed_match else ""}
- baseline_0: {baseline_0_match["file_name"] if baseline_0_match else ""}
- user: {user_match["file_name"] if user_match else "N/A"}
- proposed: {proposed_match["file_name"] if proposed_match else "N/A"}
- baseline_0: {baseline_0_match["file_name"] if baseline_0_match else "N/A"}
- baseline_90: {baseline_90_match["file_name"] if baseline_90_match else ""}
- baseline_180: {baseline_180_match["file_name"] if baseline_180_match else ""}
- baseline_270: {baseline_270_match["file_name"] if baseline_270_match else ""}
- baseline_180: {baseline_180_match["file_name"] if baseline_180_match else "N/A"}
- baseline_270: {baseline_270_match["file_name"] if baseline_270_match else "N/A"}

### Summary: All Primary Rules
| | All | Envelope | Lighting | Receptacles | Transformers | HVAC-HotWaterSide | HVAC - ChilledWaterSide | HVAC-AirSide | HVAC-General| HVAC-Baseline
|:----------------------------:|:---:|:--------:|:--------:|:-----------:|:------------:|:--------------:|:--------------:|:--------------:|:--------------:|:-----------:|
| | All | Performance Calculations | Schedules Setpoints | Envelope | Lighting | HVAC General | Receptacles | Transformers | HVAC-HotWaterSide | HVAC - ChilledWaterSide | HVAC-AirSide | HVAC-General| HVAC-Baseline
|:----------------------------:|:---:|:--------:|:--------:|:--------:|:--------:|:-----------:|:------------:|:------------:|:--------------:|:--------------:|:--------------:|:--------------:|:-----------:|
Replace-Rules
Replace-Pass
Replace-Fail
Expand Down Expand Up @@ -155,7 +160,7 @@ def add_rule_to_ruleset_report(self, ruleset_report, rule_report, rule_outcome):
def save_ruleset_report(self, ruleset_report, report_dir):
overall_rules_count = {name: 0 for name in self.section_list}

for key in self.ruleset_outcome.keys():
for key in self.ruleset_outcome:
for outcome in [
RCTOutcomeLabel.PASS,
RCTOutcomeLabel.FAILED,
Expand All @@ -164,11 +169,13 @@ def save_ruleset_report(self, ruleset_report, report_dir):
]:
overall_rules_count[key] += self.ruleset_outcome[key][outcome]

rules_line = f"|Rules|{overall_rules_count['All']}|{overall_rules_count['Envelope']}|{overall_rules_count['Lighting']}|{overall_rules_count['Receptacles']}|{overall_rules_count['Transformers']}|{overall_rules_count['HVAC-HotWaterSide']}|{overall_rules_count['HVAC-ChilledWaterSide']}|{overall_rules_count['HVAC-AirSide']}|{overall_rules_count['HVAC-General']}|{overall_rules_count['HVAC-Baseline']}|"
pass_line = f"|Pass|{self.ruleset_outcome['All'][RCTOutcomeLabel.PASS]}|{self.ruleset_outcome['Envelope'][RCTOutcomeLabel.PASS]}|{self.ruleset_outcome['Lighting'][RCTOutcomeLabel.PASS]}|{self.ruleset_outcome['Receptacles'][RCTOutcomeLabel.PASS]}|{self.ruleset_outcome['Transformers'][RCTOutcomeLabel.PASS]}|{self.ruleset_outcome['HVAC-HotWaterSide'][RCTOutcomeLabel.PASS]}|{self.ruleset_outcome['HVAC-ChilledWaterSide'][RCTOutcomeLabel.PASS]}|{self.ruleset_outcome['HVAC-AirSide'][RCTOutcomeLabel.PASS]}|{self.ruleset_outcome['HVAC-General'][RCTOutcomeLabel.PASS]}|{self.ruleset_outcome['HVAC-Baseline'][RCTOutcomeLabel.PASS]}|"
fail_line = f"|Fail|{self.ruleset_outcome['All'][RCTOutcomeLabel.FAILED]}|{self.ruleset_outcome['Envelope'][RCTOutcomeLabel.FAILED]}|{self.ruleset_outcome['Lighting'][RCTOutcomeLabel.FAILED]}|{self.ruleset_outcome['Receptacles'][RCTOutcomeLabel.FAILED]}|{self.ruleset_outcome['Transformers'][RCTOutcomeLabel.FAILED]}|{self.ruleset_outcome['HVAC-HotWaterSide'][RCTOutcomeLabel.FAILED]}|{self.ruleset_outcome['HVAC-ChilledWaterSide'][RCTOutcomeLabel.FAILED]}|{self.ruleset_outcome['HVAC-AirSide'][RCTOutcomeLabel.FAILED]}|{self.ruleset_outcome['HVAC-General'][RCTOutcomeLabel.FAILED]}|{self.ruleset_outcome['HVAC-Baseline'][RCTOutcomeLabel.FAILED]}|"
not_applicable_line = f"|Not Applicable|{self.ruleset_outcome['All'][RCTOutcomeLabel.NOT_APPLICABLE]}|{self.ruleset_outcome['Envelope'][RCTOutcomeLabel.NOT_APPLICABLE]}|{self.ruleset_outcome['Lighting'][RCTOutcomeLabel.NOT_APPLICABLE]}|{self.ruleset_outcome['Receptacles'][RCTOutcomeLabel.NOT_APPLICABLE]}|{self.ruleset_outcome['Transformers'][RCTOutcomeLabel.NOT_APPLICABLE]}|{self.ruleset_outcome['HVAC-HotWaterSide'][RCTOutcomeLabel.NOT_APPLICABLE]}|{self.ruleset_outcome['HVAC-ChilledWaterSide'][RCTOutcomeLabel.NOT_APPLICABLE]}|{self.ruleset_outcome['HVAC-AirSide'][RCTOutcomeLabel.NOT_APPLICABLE]}|{self.ruleset_outcome['HVAC-General'][RCTOutcomeLabel.NOT_APPLICABLE]}|{self.ruleset_outcome['HVAC-Baseline'][RCTOutcomeLabel.NOT_APPLICABLE]}|"
undetermined_line = f"|Undetermined (manual review)|{self.ruleset_outcome['All'][RCTOutcomeLabel.UNDETERMINED]}|{self.ruleset_outcome['Envelope'][RCTOutcomeLabel.UNDETERMINED]}|{self.ruleset_outcome['Lighting'][RCTOutcomeLabel.UNDETERMINED]}|{self.ruleset_outcome['Receptacles'][RCTOutcomeLabel.UNDETERMINED]}|{self.ruleset_outcome['Transformers'][RCTOutcomeLabel.UNDETERMINED]}|{self.ruleset_outcome['HVAC-HotWaterSide'][RCTOutcomeLabel.UNDETERMINED]}|{self.ruleset_outcome['HVAC-ChilledWaterSide'][RCTOutcomeLabel.UNDETERMINED]}|{self.ruleset_outcome['HVAC-AirSide'][RCTOutcomeLabel.UNDETERMINED]}|{self.ruleset_outcome['HVAC-General'][RCTOutcomeLabel.UNDETERMINED]}|{self.ruleset_outcome['HVAC-Baseline'][RCTOutcomeLabel.UNDETERMINED]}|"
(
Copy link
Collaborator Author

@yunjoonjung-PNNL yunjoonjung-PNNL May 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part was simplified with the private function (_generate_line) because as we have more and more sections, it's hard to list all the column values.

rules_line,
pass_line,
fail_line,
not_applicable_line,
undetermined_line,
) = self._generate_line(self.ruleset_outcome, overall_rules_count)

self.summary_report = re.sub("Replace-Rules", rules_line, self.summary_report)
self.summary_report = re.sub("Replace-Pass", pass_line, self.summary_report)
Expand All @@ -191,3 +198,25 @@ def _section_name_helper(self, rule_outcome):
"""
else:
return None

def _generate_line(self, outcome_data, overall_rules_count):
rule_line = "|Rules|"
pass_line = "|Pass|"
fail_line = "|fail|"
not_applicable_line = f"|Not Applicable|"
undetermined_line = f"|Undetermined (manual review)|"

for section_name, count in overall_rules_count.items():
rule_line += f"{overall_rules_count[section_name]}|"

for section in self.section_list:
pass_line += f"{outcome_data[section][RCTOutcomeLabel.PASS]}|"
fail_line += f"{outcome_data[section][RCTOutcomeLabel.FAILED]}|"
not_applicable_line += (
f"{outcome_data[section][RCTOutcomeLabel.NOT_APPLICABLE]}|"
)
undetermined_line += (
f"{outcome_data[section][RCTOutcomeLabel.UNDETERMINED]}|"
)

return rule_line, pass_line, fail_line, not_applicable_line, undetermined_line
4 changes: 2 additions & 2 deletions rct229/reports/general/engine_raw_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
class EngineRawOutput(RCTReport):
def __init__(self):
super(EngineRawOutput, self).__init__()
self.ruleset_report_file = "raw_output.json"
self.ruleset_report_file = f"{self.__class__.__name__}.json"

def generate_rule_report(self, rule_outcome, outcome_dict):
def rule_report_helper(rule_outcomes, outcomes_dict):
Expand All @@ -28,7 +28,7 @@ def rule_report_helper(rule_outcomes, outcomes_dict):
outcomes_dict[RCTOutcomeLabel.UNDETERMINED] += 1
else:
outcomes_dict[rule_outcome_str] += 1
if "calc_vals" in rule_outcomes.keys():
if "calc_vals" in rule_outcomes:
rule_outcomes["calc_vals"] = calc_vals_converter(
rule_outcomes["calc_vals"]
)
Expand Down
2 changes: 1 addition & 1 deletion rct229/reports/general/engine_raw_summary.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
class EngineRawSummary(RCTReport):
def __init__(self):
super(EngineRawSummary, self).__init__()
self.ruleset_report_file = "raw_summary.txt"
self.ruleset_report_file = f"{self.__class__.__name__}.txt"
self.num_evaluation = 0

def generate_rule_report(self, rule_outcome, outcome_dict):
Expand Down
1 change: 0 additions & 1 deletion rct229/reports/project_report.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import json
import os

from rct229.reports.utils import aggregate_outcomes

Expand Down
2 changes: 1 addition & 1 deletion rct229/rulesets/ashrae9012019/section10/section10rule14.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def __init__(self):
"Baseline shall be modeled with the heating HVAC system efficiency per Tables G3.5.1-G3.5.6 (applies only to the heating efficiency of baseline furnaces and heat pumps). Where multiple HVAC zones or residential spaces are combined into a single thermal block the heating efficiencies (for baseline HVAC System Types 3 and 4) shall be based on the equipment capacity of the thermal block divided by the number of HVAC zones or residential spaces."
),
ruleset_section_title="HVAC General",
standard_section="",
standard_section="Section G3.1.2.1 Equipment Efficiencies",
is_primary_rule=True,
list_path="$.buildings[*].building_segments[*].heating_ventilating_air_conditioning_systems[*]",
rmd_context="ruleset_model_descriptions/0",
Expand Down
21 changes: 10 additions & 11 deletions rct229/rulesets/ashrae9012019/section4/section4rule1.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@


class Section4Rule1(RuleDefinitionListIndexedBase):
"""Rule 1 of ASHRAE 90.1-2019 Appendix G Section 4 (Airside System)"""
"""Rule 1 of ASHRAE 90.1-2019 Appendix G Section 4 (Schedules Setpoints)"""

def __init__(self):
super(Section4Rule1, self).__init__(
Expand All @@ -40,17 +40,16 @@ def __init__(self):
index_rmd=BASELINE_0,
id="4-1",
description="Temperature Control Setpoints shall be the same for proposed design and baseline building design.",
ruleset_section_title="Airside System",
ruleset_section_title="Schedules Setpoints",
standard_section="Section G3.1-4 Schedule Modeling Requirements for the Proposed design and Baseline building",
is_primary_rule=True,
list_path="ruleset_model_descriptions[0]",
data_items={"is_leap_year_b": (BASELINE_0, "calendar/is_leap_year")},
data_items={
"climate_zone_b": (BASELINE_0, "weather/climate_zone"),
"is_leap_year_b": (BASELINE_0, "calendar/is_leap_year"),
},
)

def create_data(self, context, data=None):
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deleted since this can be integrated into data_items.

rmr_b = context.BASELINE_0
return {"climate_zone": rmr_b["weather"]["climate_zone"]}

class RuleSetModelInstanceRule(RuleDefinitionListIndexedBase):
def __init__(self):
super(Section4Rule1.RuleSetModelInstanceRule, self).__init__(
Expand All @@ -59,7 +58,7 @@ def __init__(self):
),
each_rule=Section4Rule1.RuleSetModelInstanceRule.ZoneRule(),
index_rmd=BASELINE_0,
list_path="$.buildings[*].zones[*]",
list_path="$.buildings[*].building_segments[*].zones[*]",
required_fields={"$": ["schedules"]},
)

Expand All @@ -70,7 +69,7 @@ def create_data(self, context, data=None):
"schedules_b": rmd_b["schedules"],
"schedules_p": rmd_p["schedules"],
"zcc_dict_b": get_zone_conditioning_category_rmi_dict(
data["climate_zone"], rmd_b
data["climate_zone_b"], rmd_b
),
}

Expand Down Expand Up @@ -127,8 +126,8 @@ def get_calc_vals(self, context, data=None):
)
if thermostat_cooling_stpt_sch_id_b
else [
zone_b.getattr_(
zone_b, "design_thermostat_cooling_setpoint"
getattr_(
zone_b, "zones", "design_thermostat_cooling_setpoint"
).magnitude
]
* number_of_hours
Expand Down
7 changes: 3 additions & 4 deletions rct229/rulesets/ashrae9012019/section4/section4rule11.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@


class Section4Rule11(RuleDefinitionListIndexedBase):
"""Rule 11 of ASHRAE 90.1-2019 Appendix G Section 4 (Airside System)"""
"""Rule 11 of ASHRAE 90.1-2019 Appendix G Section 4 (Schedules Setpoints)"""

def __init__(self):
super(Section4Rule11, self).__init__(
Expand All @@ -70,10 +70,10 @@ def __init__(self):
index_rmd=BASELINE_0,
id="4-11",
description="Fan schedules shall be modeled identically in the baseline and proposed unless Table G3.1 Section 4 baseline exceptions are applicable. Fan Schedules may be allowed to differ when Section 4 Baseline Column Exceptions #1, #2 Or #3 are applicable.",
ruleset_section_title="Airside System",
ruleset_section_title="Schedules Setpoints",
standard_section="Section G3.1-4 Schedule Modeling Requirements for the Proposed design and Baseline building",
is_primary_rule=True,
list_path="ruleset_model_descriptions[0]",
list_path="$.ruleset_model_descriptions[0]",
data_items={
"climate_zone": (BASELINE_0, "weather/climate_zone"),
"is_leap_year": (BASELINE_0, "calendar/is_leap_year"),
Expand All @@ -92,7 +92,6 @@ def __init__(self):
)

def create_data(self, context, data=None):

rmd_b = context.BASELINE_0
rmd_p = context.PROPOSED
is_leap_year = data["is_leap_year"]
Expand Down
4 changes: 2 additions & 2 deletions rct229/rulesets/ashrae9012019/section4/section4rule14.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@


class Section4Rule14(RuleDefinitionListIndexedBase):
"""Rule 14 of ASHRAE 90.1-2019 Appendix G Section 4 (Schedule-Setpoints)"""
"""Rule 14 of ASHRAE 90.1-2019 Appendix G Section 4 (Schedules Setpoints)"""

def __init__(self):
super(Section4Rule14, self).__init__(
Expand All @@ -26,7 +26,7 @@ def __init__(self):
index_rmd=PROPOSED,
id="4-14",
description="A computer room is defined as a room whose primary function is to house equipment for the processing and storage of electronic data and that has a design electronic data equipment power density exceeding 20 W/ft2 of conditioned floor area.",
ruleset_section_title="Schedule - Setpoints",
ruleset_section_title="Schedules Setpoints",
standard_section="Section 3 Definitions",
is_primary_rule=True,
rmd_context="ruleset_model_descriptions/0",
Expand Down
4 changes: 2 additions & 2 deletions rct229/rulesets/ashrae9012019/section4/section4rule2.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@


class Section4Rule2(RuleDefinitionListIndexedBase):
"""Rule 2 of ASHRAE 90.1-2019 Appendix G Section 4 (Airside System)"""
"""Rule 2 of ASHRAE 90.1-2019 Appendix G Section 4 (Schedules Setpoints)"""

def __init__(self):
super(Section4Rule2, self).__init__(
Expand All @@ -41,7 +41,7 @@ def __init__(self):
index_rmd=BASELINE_0,
id="4-2",
description="Humidity Control Setpoints shall be the same for proposed design and baseline building design.",
ruleset_section_title="Airside System",
ruleset_section_title="Schedules Setpoints",
standard_section="Section G3.1-4 Schedule Modeling Requirements for the Proposed design and Baseline building",
is_primary_rule=True,
list_path="ruleset_model_descriptions[0]",
Expand Down
Loading