Skip to content

Latest commit

 

History

History
113 lines (94 loc) · 15.9 KB

Rule19-23.md

File metadata and controls

113 lines (94 loc) · 15.9 KB

Section 19 - Rule 19-23

Schema Version: 0.0.23
Mandatory Rule: True
Rule ID: 19-23
Rule Description: For cooling sizing runs, schedules for internal loads, including those used for infiltration, occupants, lighting, gas and electricity using equipment, shall be equal to the highest hourly value used in the annual simulation runs and applied to the entire design day. For heating sizing runs, schedules for internal loads, including those used for occupants, lighting, gas and electricity using equipment, shall be equal to the lowest hourly value used in the annual simulation runs, and schedules for infiltration shall be equal to the highest hourly value used in the annual simulation runs and applied to the entire design day.

Rule Assertion: Options are Pass/Fail/UNDETERMINED
Appendix G Section: G3.1.2.2.1 excluding exception
90.1 Section Reference: None

Data Lookup: None

Evaluation Context: Each Space

Applicability Checks:

  1. Does not apply to residential dwelling units cooling design schedules.

Function Calls: None

Rule Logic:

  • For each space in the B_RMI: for space in B_RMI...Space:

    • Reset is_dwelling_unit boolean variable: is_dwelling_unit = false

    • Reset is_space_type_defined boolean variable: is_space_type_defined = false

    • Reset the building area defined boolean variable to false: bldg_area_is_defined = false

    • Reset the building_area_is_MF boolean variable to false: building_area_is_MF = false

    • Loop through the building segments to determine which building segment the zone is apart of: for bldg_seg in B_RMI...Building.building_segments:

      • Check if the zone is in bldg_seg.zones, if yes then set the bldg_type to the building area lighting type associated with the building segment: if applicable_zone in bldg_seg.zones: bldg_type = bldg_seg.lighting_building_area_type
      • Check if the lighting building area type was defined: if bldg_type != Null: bldg_area_is_defined = true
      • Check if the lighting building area type is multifamily: if bldg_type in ["MULTIFAMILY"]: building_area_is_MF = true
    • Check if either the lighting or ventilation space type is defined: if space.lighting_space_type != Null or space.ventilation_space_type != Null:

      • Set the is_space_type_defined boolean to true: is_space_type_defined = true
      • Check if the lighting or ventilation space type is of a residential dwelling unit type: if space.lighting_space_type in ["DWELLING_UNIT"] or space._ventilation_space_type in ["TRANSIENT_RESIDENTIAL_DWELLING_UNIT"]: is_dwelling_unit = true
    • Get the zone that the space is part of start by looping through zones: for zone in B_RMI.Zone:

      • Check if the space is associated with the zone: if space in zone.spaces: applicable_zone = zone

    Conduct checks for infiltration:

    • Reset inf_pass_heating boolean variable: inf_pass_heating = true
    • Reset inf_pass_cooling boolean variable: inf_pass_cooling = true
    • Get the infiltration object associated with the zone: infiltration_obj = applicable_zone.infiltration
    • Get the multiplier schedule: inf_multiplier_sch = get_component_by_id(B_RMI,infiltration_obj.multiplier_schedule)
    • Get the design_heating_multiplier_schedule: inf_design_heating_multiplier_sch = inf_multiplier_sch.heating_design_day_sequence
    • Get the design_cooling_multiplier_schedule: inf_design_cooling_multiplier_sch = inf_multiplier_sch.cooling_design_day_sequence
    • Get the highest hourly value used in the infiltration multiplier schedule (not sure if the schedule needs to be transformed or anything, for example, what if it is an event schedule?): max_infiltration_value = max(inf_multiplier_sch.hourly_values)
    • Check if each value in the design_heating_multiplier_schedule aligns with the max_infiltration_value : for x in list(inf_design_heating_multiplier_sch):
      • Check if the hourly value does not equal the highest hourly value used in the multiplier schedule: if x != max_infiltration_value: inf_pass_heating = false
    • Check if each value in the design_cooling_multiplier_schedule aligns with the max_infiltration_value : for x in list(inf_design_cooling_multiplier_sch):
      • Check if the hourly value does not equal the highest hourly value used in the multiplier schedule: if x != max_infiltration_value: inf_pass_cooling = false

    Gather information for occupant checks:

    • Reset occ_pass_heating boolean variable: occ_pass_heating = true
    • Reset occ_pass_cooling boolean variable: occ_pass_cooling = true
    • Get the multiplier schedule: occ_multiplier_sch = get_component_by_id(B_RMI,space.occupant_multiplier_schedule)
    • Get the design_heating_multiplier_schedule: occ_design_heating_multiplier_sch = occ_multiplier_sch.heating_design_day_sequence
    • Get the design_cooling_multiplier_schedule: occ_design_cooling_multiplier_sch = occ_multiplier_sch.cooling_design_day_sequence
    • Get the highest hourly value used in the multiplier schedule (not sure if the schedule needs to be transformed or anything, for example, what if it is an event schedule?): occ_max_value = max(occ_multiplier_sch.hourly_values)
    • Get the lowest hourly value used in the multiplier schedule (not sure if the schedule needs to be transformed or anything, for example, what if it is an event schedule?): occ_min_value = min(occ_multiplier_sch.hourly_values)
    • Check if each value in the design_heating_multiplier_schedule aligns with the occ_min_value: for x in list(occ_design_heating_multiplier_sch):
      • Check if the hourly value does not equal the lowest hourly value used in the multiplier schedule: if x != occ_min_value: occ_pass_heating = false
    • Check if each value in the design_cooling_multiplier_schedule aligns with the occ_max_value: for x in list(occ_design_cooling_multiplier_sch):
      • Check if the hourly value does not equal the highest hourly value used in the multiplier schedule: if x != occ_max_value: occ_pass_cooling = false

    Conduct checks for the interior lighting objects:

    • Get list of interior lighting objects: lgting_obj_list = list(space.interior_lighting)
    • Reset int_lgt_pass_heating boolean variable: int_lgt_pass_heating = true
    • Reset int_lgt_pass_cooling boolean variable: int_lgt_pass_cooling = true
    • For each interior lighting object: for int_lgt in lgting_obj_list:
      • Get the multiplier schedule: int_lgt_multiplier_sch = get_component_by_id(B_RMI,int_lgt.lighting_multiplier_schedule)
      • Get the design_heating_multiplier_schedule: int_lgt_design_heating_multiplier_sch = int_lgt_multiplier_sch.heating_design_day_sequence
      • Get the design_cooling_multiplier_schedule: int_lgt_design_cooling_multiplier_sch = int_lgt_multiplier_sch.cooling_design_day_sequence
      • Get the highest hourly value used in the multiplier schedule (not sure if the schedule needs to be transformed or anything, for example, what if it is an event schedule?): int_lgt_max_value = max(int_lgt_multiplier_sch.hourly_values)
      • Get the lowest hourly value used in the multiplier schedule (not sure if the schedule needs to be transformed or anything, for example, what if it is an event schedule?): int_lgt_min_value = min(int_lgt_multiplier_sch.hourly_values)
      • Check if each value in the design_heating_multiplier_schedule aligns with the int_lgt_min_value: for x in list(int_lgt_design_heating_multiplier_sch):
        • Check if the hourly value does not equal the lowest hourly value used in the multiplier schedule: if x != int_lgt_min_value: int_lgt_pass_heating = false
      • Check if each value in the design_cooling_multiplier_schedule aligns with the int_lgt_max_value: for x in list(int_lgt_design_cooling_multiplier_sch):
        • Check if the hourly value does not equal the highest hourly value used in the multiplier schedule: if x != int_lgt_max_value: int_lgt_pass_cooling = false

    Conduct checks for the miscellaneous objects:

    • Get list of misc equipment objects: misc_obj_list = list(space.miscellaneous_equipment)

    • Reset misc_pass_heating boolean variable: misc_pass_heating = true

    • Reset misc_pass_cooling boolean variable: misc_pass_cooling = true

    • For each misc equipment object: for misc in misc_obj_list:

      • Get the multiplier schedule: misc_multiplier_sch = get_component_by_id(B_RMI,misc.multiplier_schedule)
      • Get the design_heating_multiplier_schedule: misc_design_heating_multiplier_sch = misc_multiplier_sch.heating_design_day_sequence
      • Get the design_cooling_multiplier_schedule: misc_design_cooling_multiplier_sch = misc_multiplier_sch.cooling_design_day_sequence
      • Get the highest hourly value used in the multiplier schedule (not sure if the schedule needs to be transformed or anything, for example, what if it is an event schedule?): misc_max_value = max(misc_multiplier_sch.hourly_values)
      • Get the lowest hourly value used in the multiplier schedule (not sure if the schedule needs to be transformed or anything, for example, what if it is an event schedule?): misc_min_value = min(misc_multiplier_sch.hourly_values)
      • Check if each value in the design_heating_multiplier_schedule aligns with the misc_min_value: for x in list(misc_design_heating_multiplier_sch):
        • Check if the hourly value does not equal the lowest hourly value used in the multiplier schedule: if x != misc_min_value: misc_pass_heating = false
      • Check if each value in the design_cooling_multiplier_schedule aligns with the misc_max_value: for x in list(misc_design_cooling_multiplier_sch):
        • Check if the hourly value does not equal the highest hourly value used in the multiplier schedule: if x != misc_max_value: misc_pass_cooling = false
    • Rule Assertion:

    • Case 1: If the space type is defined and is not a dwelling unit and all schedules pass per above then pass: if is_dwelling_unit == false and is_space_type_defined == true and all(inf_pass_heating, inf_pass_cooling,occ_pass_heating, occ_pass_cooling,int_lgt_pass_heating, int_lgt_pass_cooling,misc_pass_heating, misc_pass_cooling) == true: outcome = "PASS"

    • Case 2: Else if the space type is defined, the space type is not dwelling unit and one or more of the schedules does not pass per above then fail: elif is_dwelling_unit == false and is_space_type_defined == true and all(inf_pass_heating, inf_pass_cooling,occ_pass_heating, occ_pass_cooling,int_lgt_pass_heating, int_lgt_pass_cooling,misc_pass_heating, misc_pass_cooling) == false: outcome = "FAIL" and raise_message "<Insert space.id> does not appear to have followed this rule per Section G3.1.2.2.1 for one more more of the following heating or cooling design schedules: infiltration, occupants, lighting, gas and electricity using equipment"

    • Case 3: Else if the space type is not defined and the building type is multifamily and all heating schedules pass and all cooling schedules equal true then UNDETERMINED: elif is_dwelling_unit == false and is_space_type_defined == false and building_area_is_MF == true and all(inf_pass_heating, occ_pass_heating, int_lgt_pass_heating, misc_pass_heating) == true and all(inf_pass_cooling, occ_pass_cooling, int_lgt_pass_cooling, misc_pass_cooling) == true: outcome = UNDETERMINED and raise_message "The space type was not defined in the RMD and the building area type is multifamily. Heating design schedules were modeled per the rules of G3.1.2.2.1 and PASS; however, cooling design schedules may fall under the exception to Section G3.1.2.2.1 for dwelling units and could not be fully assessed for this check. Conduct manual check to determine if the space is a dwelling unit. If the space is not a dwelling unit then the cooling design schedules pass. If it is a dwelling unit then the cooling design schedules fail this check.

    • Case 4: Else if the space type is not defined and the building type is multifamily and all heating schedules pass and all cooling schedules do not equal true then UNDETERMINED: elif is_dwelling_unit == false and is_space_type_defined == false and building_area_is_MF == true and all(inf_pass_heating, occ_pass_heating, int_lgt_pass_heating, misc_pass_heating) == true and all(inf_pass_cooling, occ_pass_cooling, int_lgt_pass_cooling, misc_pass_cooling) == false: outcome = UNDETERMINED and raise_message "The space type was not defined in the RMD and the building area type is multifamily. Heating design schedules were modeled per the rules of G3.1.2.2.1 and PASS; however, cooling design schedules may fall under the exception to Section G3.1.2.2.1 for dwelling units and could not be fully assessed for this check. Conduct manual check to determine if the space is a dwelling unit. If the space is not a dwelling unit then the cooling design schedules fail. If it is a dwelling unit then conduct a manual check that the schedules meet the requirements under the exception to Section G3.1.2.2.1.

    • Case 5: Else if space type is dwelling unit and one or more of the design heating schedules fail per above then fail : elif is_dwelling_unit == true and all(inf_pass_heating, occ_pass_heating, int_lgt_pass_heating, misc_pass_heating) == false: outcome = "FAIL" and raise_message "<Insert space.id> appears to be a dwelling unit and does not appear to have followed this rule per Section G3.1.2.2.1 for one more more of the following heating design schedules (cooling design schedules fall under the exception to Section G3.1.2.2.1 and were not assessed for dwelling units in this check): infiltration, occupants, lighting, gas and electricity using equipment."

    • Case 6: Else if the space type is dwelling unit and all design heating schedules pass then the outcome is Pass: elif is_dwelling_unit == true and all(inf_pass_heating, occ_pass_heating, int_lgt_pass_heating, misc_pass_heating) == true: outcome = "PASS"

    • Case 7: Else if the space type is not defined and the building type is not multifamily and all schedules pass per above then pass: elif is_dwelling_unit == false and is_space_type_defined == false and building_area_is_MF == false and all(inf_pass_heating, inf_pass_cooling,occ_pass_heating, occ_pass_cooling,int_lgt_pass_heating, int_lgt_pass_cooling,misc_pass_heating, misc_pass_cooling) == true: outcome = "PASS" and raise_message "Pass unless the space type is dwelling unit (the space type was not defined in the RMD schema and was assumed not to be a dwelling unit). Dwelling units fall under the exception to Section G3.1.2.2.1.

    • Case 8: Else if the space type is not defined and the building type is not multifamily and all heating schedules pass and all cooling schedules do not equal true then Fail: elif is_dwelling_unit == false and is_space_type_defined == false and building_area_is_MF == false and all(inf_pass_heating, occ_pass_heating, int_lgt_pass_heating, misc_pass_heating) == true and all(inf_pass_cooling, occ_pass_cooling, int_lgt_pass_cooling, misc_pass_cooling) == false: outcome = FAIL and raise_message "The space type nor the building area type were defined in the RMD. The space type was assumed not to be a dwelling unit. Heating design schedules were modeled per the rules of G3.1.2.2.1 and PASS; however, cooling design schedules appear not to meet the requirements of Section G3.1.2.2.1. Fail for the cooling design schedules unless the space type is a dwelling unit. If the space type is a dwelling unit conduct a manual check for the cooling design schedules for compliance with the exception to Section G3.1.2.2.1.

    • Case 9: Else Fail: Else: outcome = "FAIL"

Notes/Questions:

  1. Jason is to add design heating and cooling multiplier schedules to the schema for occupants, infiltration, lighting, and miscellaneous. Implemented as discussed with Jason on Github.
  2. Update rule id from 19-26 to 19-23 on 10/23/2023

Back