Skip to content
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
25 changes: 15 additions & 10 deletions docs/ashrae_90p1_2019/section6/Rule6-5.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@
**Appendix G Section:** Section G3.1-6 Modeling Requirements for the Baseline building
**Appendix G Section Reference:** None

**Applicability:** All required data elements exist for B_RMR
**Applicability Checks:**

**Applicability:** All required data elements exist for B_RMD
**Applicability Checks:**
1. Building total area is more than 5,000sq.ft.

**Manual Check:** Yes
Expand All @@ -30,24 +29,30 @@
- **Applicability Check 1:**`if building_total_area_b > 5000:`

- For each space in building_b: `space_b in building_b...spaces:`
- Get total lighting power density in space: `total_space_LPD_b = sum(interior_lighting.power_per_area for interior_lighting in space_b.interior_lighting)`

- Skip evaluating plenums, crawlspaces, and interstitial spaces that have no lighting power: `if total_space_LPD_b ==0 and space_b.function in [PLENUM, CRAWL_SPACE, INTERSTITIAL_SPACE]: continue`

- Get normalized space lighting schedule: `normalized_schedule_b = normalize_interior_lighting_schedules(space_b.interior_lighting, false)`

- Get matching space in P_RMR: `space_p = match_data_element(P_RMR, Spaces, space_b.id)`
- Get matching space in P_RMD: `space_p = match_data_element(P_RMD, Spaces, space_b.id)`

- Get normalized space lighting schedule in P_RMR: `normalized_schedule_p = normalize_interior_lighting_schedules(space_p.interior_lighting, false)`
- Get normalized space lighting schedule in P_RMD: `normalized_schedule_p = normalize_interior_lighting_schedules(space_p.interior_lighting, false)`

- Check if automatic shutoff control is modeled in space during building closed hours (i.e. if lighting schedule hourly value in B_RMR is equal to P_RMR during building closed hours): `schedule_comparison_result = compare_schedules(normalized_schedule_b, normalized_schedule_p, inverse(building_open_schedule_b))`
- Check if automatic shutoff control is modeled in space during building closed hours (i.e. if lighting schedule hourly value in B_RMD is equal to P_RMD during building closed hours): `schedule_comparison_result = compare_schedules(normalized_schedule_b, normalized_schedule_p, inverse(building_open_schedule_b))`

**Rule Assertion:**

- Case 1: For building closed hours, if lighting schedule hourly value in B_RMR is equal to P_RMR: `if schedule_comparison_result["total_hours_compared"] == schedule_comparison_result["total_hours_matched"]: PASS`
- Case 1: If space has lighting power and is crawl space, interstitial space, or plenum: UNDETERMINED `if ( total_space_LPD_b > 0 ) AND ( space_function_b in [CRAWL_SPACE, INTERSTITIAL_SPACE, PLENUM] ): UNDETERMINED and raise_warning f"Space function is {space_function_b} and has lighting power modeled. Unable to determine whether this space should be included in the check."`

- Case 2: For building closed hours, if lighting schedule hourly value in B_RMD is equal to P_RMD: `if schedule_comparison_result["total_hours_compared"] == schedule_comparison_result["total_hours_matched"]: PASS`

- Case 2: Else: `else: Failed`
- Case 3: Else: `else: Failed`


**Notes:**
1. Updated the Rule ID from 6-9 to 6-6 on 6/3/2022
2. Updated the Rule ID from 6-6 to 6-5 on 6/8/2022
2. Updated the Rule ID from 6-6 to 6-5 on 6/8/2022
3. Updated to exclude crawl space, plenum or interstitial space on 9/29/2025.

**[Back](../_toc.md)**
**[Back](../_toc.md)**
44 changes: 41 additions & 3 deletions rct229/rulesets/ashrae9012019/section6/section6rule5.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,20 @@
normalize_interior_lighting_schedules,
)
from rct229.schema.config import ureg
from rct229.schema.schema_enums import SchemaEnums
from rct229.utils.assertions import getattr_
from rct229.utils.jsonpath_utils import find_all, find_exactly_one_with_field_value
from rct229.utils.masks import invert_mask
from rct229.utils.pint_utils import ZERO
from rct229.utils.pint_utils import ZERO, CalcQ

BUILDING_AREA_CUTTOFF = ureg("5000 ft2")
BUILDING_AREA_CUTTOFF = 5000 * ureg("ft2")
SPACE_FUNCTION = SchemaEnums.schema_enums["SpaceFunctionOptions"]

ACCEPTABLE_SPACE_FUNCTION = [
SPACE_FUNCTION.CRAWL_SPACE,
SPACE_FUNCTION.INTERSTITIAL_SPACE,
SPACE_FUNCTION.PLENUM,
]


class PRM9012019Rule08a45(RuleDefinitionListIndexedBase):
Expand Down Expand Up @@ -172,10 +180,40 @@ def get_calc_vals(self, context, data=None):
mask_schedule=invert_mask(hourly_building_open_schedule_b),
)

total_space_LPD_b = sum(
[
int_ltg.get("power_per_area", 0 * ureg("W/m2"))
for int_ltg in find_all(
"$.interior_lighting[*]", space_b
)
]
)
space_function_b = getattr_(space_b, "spaces", "function")

return {
"schedule_comparison_result": schedule_comparison_result
"schedule_comparison_result": schedule_comparison_result,
"total_space_LPD_b": CalcQ(
"power_density", total_space_LPD_b
),
"space_function_b": space_function_b,
}

def manual_check_required(self, context, calc_vals=None, data=None):
total_space_LPD_b = calc_vals["total_space_LPD_b"]
space_function_b = calc_vals["space_function_b"]

return (
total_space_LPD_b > 0 * ureg("W/m2")
and space_function_b in ACCEPTABLE_SPACE_FUNCTION
)

def get_manual_check_required_msg(
self, context, calc_vals=None, data=None
):
space_function_b = calc_vals["space_function_b"]

return f"Space function is {space_function_b} and has lighting power modeled. Unable to determine whether this space should be included in the check."

def rule_check(self, context, calc_vals=None, data=None):
schedule_comparison_result = calc_vals[
"schedule_comparison_result"
Expand Down
44 changes: 41 additions & 3 deletions rct229/rulesets/ashrae9012022/section6/section6rule5.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,20 @@
normalize_interior_lighting_schedules,
)
from rct229.schema.config import ureg
from rct229.schema.schema_enums import SchemaEnums
from rct229.utils.assertions import getattr_
from rct229.utils.jsonpath_utils import find_all, find_exactly_one_with_field_value
from rct229.utils.masks import invert_mask
from rct229.utils.pint_utils import ZERO
from rct229.utils.pint_utils import ZERO, CalcQ

BUILDING_AREA_CUTTOFF = ureg("5000 ft2")
BUILDING_AREA_CUTTOFF = 5000 * ureg("ft2")
SPACE_FUNCTION = SchemaEnums.schema_enums["SpaceFunctionOptions"]

ACCEPTABLE_SPACE_FUNCTION = [
SPACE_FUNCTION.CRAWL_SPACE,
SPACE_FUNCTION.INTERSTITIAL_SPACE,
SPACE_FUNCTION.PLENUM,
]


class PRM9012022Rule08a45(RuleDefinitionListIndexedBase):
Expand Down Expand Up @@ -172,10 +180,40 @@ def get_calc_vals(self, context, data=None):
mask_schedule=invert_mask(hourly_building_open_schedule_b),
)

total_space_LPD_b = sum(
[
int_ltg.get("power_per_area", 0 * ureg("W/m2"))
for int_ltg in find_all(
"$.interior_lighting[*]", space_b
)
]
)
space_function_b = getattr_(space_b, "spaces", "function")

return {
"schedule_comparison_result": schedule_comparison_result
"schedule_comparison_result": schedule_comparison_result,
"total_space_LPD_b": CalcQ(
"power_density", total_space_LPD_b
),
"space_function_b": space_function_b,
}

def manual_check_required(self, context, calc_vals=None, data=None):
total_space_LPD_b = calc_vals["total_space_LPD_b"]
space_function_b = calc_vals["space_function_b"]

return (
total_space_LPD_b > 0 * ureg("W/m2")
and space_function_b in ACCEPTABLE_SPACE_FUNCTION
)

def get_manual_check_required_msg(
self, context, calc_vals=None, data=None
):
space_function_b = calc_vals["space_function_b"]

return f"Space function is {space_function_b} and has lighting power modeled. Unable to determine whether this space should be included in the check."

def rule_check(self, context, calc_vals=None, data=None):
schedule_comparison_result = calc_vals[
"schedule_comparison_result"
Expand Down
Loading
Loading