diff --git a/resources/hpxml-measures/BuildResidentialHPXML/README.md b/resources/hpxml-measures/BuildResidentialHPXML/README.md index c322c00d0e..0c76275dc2 100644 --- a/resources/hpxml-measures/BuildResidentialHPXML/README.md +++ b/resources/hpxml-measures/BuildResidentialHPXML/README.md @@ -101,7 +101,7 @@ Specifies the unavailable period date ranges. Enter a date range like "Dec 15 - **Schedules: Unavailable Period Window Natural Ventilation Availabilities** -The availability of the natural ventilation schedule during unavailable periods. Valid choices are: regular schedule, always available, always unavailable. If multiple periods, use a comma-separated list. If not provided, the OS-HPXML default (see HPXML Unavailable Periods) is used. +The availability of the natural ventilation schedule during unavailable periods. Valid choices are: regular schedule, always available, always unavailable. If multiple periods, use a comma-separated list. If not provided, the OS-HPXML default (see HPXML Unavailable Periods) is used. - **Name:** ``schedules_unavailable_period_window_natvent_availabilities`` - **Type:** ``String`` @@ -112,7 +112,7 @@ The availability of the natural ventilation schedule during unavailable periods. **Simulation Control: Timestep** -Value must be a divisor of 60. If not provided, the OS-HPXML default (see HPXML Simulation Control) is used. +Value must be a divisor of 60. If not provided, the OS-HPXML default (see HPXML Simulation Control) is used. - **Name:** ``simulation_control_timestep`` - **Type:** ``Integer`` @@ -125,7 +125,7 @@ Value must be a divisor of 60. If not provided, the OS-HPXML default (see HPXML Simulation Control) is used. +Enter a date range like 'Jan 1 - Dec 31'. If not provided, the OS-HPXML default (see HPXML Simulation Control) is used. - **Name:** ``simulation_control_run_period`` - **Type:** ``String`` @@ -136,7 +136,7 @@ Enter a date range like 'Jan 1 - Dec 31'. If not provided, the OS-HPXML default **Simulation Control: Run Period Calendar Year** -This numeric field should contain the calendar year that determines the start day of week. If you are running simulations using AMY weather files, the value entered for calendar year will not be used; it will be overridden by the actual year found in the AMY weather file. If not provided, the OS-HPXML default (see HPXML Simulation Control) is used. +This numeric field should contain the calendar year that determines the start day of week. If you are running simulations using AMY weather files, the value entered for calendar year will not be used; it will be overridden by the actual year found in the AMY weather file. If not provided, the OS-HPXML default (see HPXML Simulation Control) is used. - **Name:** ``simulation_control_run_period_calendar_year`` - **Type:** ``Integer`` @@ -149,7 +149,7 @@ This numeric field should contain the calendar year that determines the start da **Simulation Control: Daylight Saving Enabled** -Whether to use daylight saving. If not provided, the OS-HPXML default (see HPXML Building Site) is used. +Whether to use daylight saving. If not provided, the OS-HPXML default (see HPXML Building Site) is used. - **Name:** ``simulation_control_daylight_saving_enabled`` - **Type:** ``Boolean`` @@ -160,7 +160,7 @@ Whether to use daylight saving. If not provided, the OS-HPXML default (see HPXML Building Site) is used. +Enter a date range like 'Mar 15 - Dec 15'. If not provided, the OS-HPXML default (see HPXML Building Site) is used. - **Name:** ``simulation_control_daylight_saving_period`` - **Type:** ``String`` @@ -171,7 +171,7 @@ Enter a date range like 'Mar 15 - Dec 15'. If not provided, the OS-HPXML default **Simulation Control: Temperature Capacitance Multiplier** -Affects the transient calculation of indoor air temperatures. If not provided, the OS-HPXML default (see HPXML Simulation Control) is used. +Affects the transient calculation of indoor air temperatures. If not provided, the OS-HPXML default (see HPXML Simulation Control) is used. - **Name:** ``simulation_control_temperature_capacitance_multiplier`` - **Type:** ``String`` @@ -182,7 +182,7 @@ Affects the transient calculation of indoor air temperatures. If not provided, t **Simulation Control: Defrost Model Type** -Research feature to select the type of defrost model. Use standard for default E+ defrost setting. Use advanced for an improved model that better accounts for load and energy use during defrost; using advanced may impact simulation runtime. If not provided, the OS-HPXML default (see HPXML Simulation Control) is used. +Research feature to select the type of defrost model. Use standard for default E+ defrost setting. Use advanced for an improved model that better accounts for load and energy use during defrost; using advanced may impact simulation runtime. If not provided, the OS-HPXML default (see HPXML Simulation Control) is used. - **Name:** ``simulation_control_defrost_model_type`` - **Type:** ``Choice`` @@ -221,7 +221,7 @@ Research feature to model capacity increment of multi-stage heat pump backup sys **Site: Type** -The type of site. If not provided, the OS-HPXML default (see HPXML Site) is used. +The type of site. If not provided, the OS-HPXML default (see HPXML Site) is used. - **Name:** ``site_type`` - **Type:** ``Choice`` @@ -234,7 +234,7 @@ The type of site. If not provided, the OS-HPXML default (see HPXML Site) is used. +Presence of nearby buildings, trees, obstructions for infiltration model. If not provided, the OS-HPXML default (see HPXML Site) is used. - **Name:** ``site_shielding_of_home`` - **Type:** ``Choice`` @@ -247,7 +247,7 @@ Presence of nearby buildings, trees, obstructions for infiltration model. If not **Site: Soil and Moisture Type** -Type of soil and moisture. This is used to inform ground conductivity and diffusivity. If not provided, the OS-HPXML default (see HPXML Site) is used. +Type of soil and moisture. This is used to inform ground conductivity and diffusivity. If not provided, the OS-HPXML default (see HPXML Site) is used. - **Name:** ``site_soil_and_moisture_type`` - **Type:** ``Choice`` @@ -310,7 +310,7 @@ City/municipality of the home address. **Site: State Code** -State code of the home address. If not provided, the OS-HPXML default (see HPXML Site) is used. +State code of the home address. If not provided, the OS-HPXML default (see HPXML Site) is used. - **Name:** ``site_state_code`` - **Type:** ``Choice`` @@ -334,7 +334,7 @@ Zip code of the home address. Either this or the Weather Station: EnergyPlus Wea **Site: Time Zone UTC Offset** -Time zone UTC offset of the home address. Must be between -12 and 14. If not provided, the OS-HPXML default (see HPXML Site) is used. +Time zone UTC offset of the home address. Must be between -12 and 14. If not provided, the OS-HPXML default (see HPXML Site) is used. - **Name:** ``site_time_zone_utc_offset`` - **Type:** ``Double`` @@ -347,7 +347,7 @@ Time zone UTC offset of the home address. Must be between -12 and 14. If not pro **Site: Elevation** -Elevation of the home address. If not provided, the OS-HPXML default (see HPXML Site) is used. +Elevation of the home address. If not provided, the OS-HPXML default (see HPXML Site) is used. - **Name:** ``site_elevation`` - **Type:** ``Double`` @@ -360,7 +360,7 @@ Elevation of the home address. If not provided, the OS-HPXML default (see HPXML Site) is used. +Latitude of the home address. Must be between -90 and 90. Use negative values for southern hemisphere. If not provided, the OS-HPXML default (see HPXML Site) is used. - **Name:** ``site_latitude`` - **Type:** ``Double`` @@ -373,7 +373,7 @@ Latitude of the home address. Must be between -90 and 90. Use negative values fo **Site: Longitude** -Longitude of the home address. Must be between -180 and 180. Use negative values for the western hemisphere. If not provided, the OS-HPXML default (see HPXML Site) is used. +Longitude of the home address. Must be between -180 and 180. Use negative values for the western hemisphere. If not provided, the OS-HPXML default (see HPXML Site) is used. - **Name:** ``site_longitude`` - **Type:** ``Double`` @@ -541,7 +541,7 @@ The number of bedrooms in the unit. **Geometry: Unit Number of Bathrooms** -The number of bathrooms in the unit. If not provided, the OS-HPXML default (see HPXML Building Construction) is used. +The number of bathrooms in the unit. If not provided, the OS-HPXML default (see HPXML Building Construction) is used. - **Name:** ``geometry_unit_num_bathrooms`` - **Type:** ``Integer`` @@ -554,7 +554,7 @@ The number of bathrooms in the unit. If not provided, the OS-HPXML default (see **Geometry: Unit Number of Occupants** -The number of occupants in the unit. If not provided, an *asset* calculation is performed assuming standard occupancy, in which various end use defaults (e.g., plug loads, appliances, and hot water usage) are calculated based on Number of Bedrooms and Conditioned Floor Area per ANSI/RESNET/ICC 301-2019. If provided, an *operational* calculation is instead performed in which the end use defaults are adjusted using the relationship between Number of Bedrooms and Number of Occupants from RECS 2015. +The number of occupants in the unit. If not provided, an *asset* calculation is performed assuming standard occupancy, in which various end use defaults (e.g., plug loads, appliances, and hot water usage) are calculated based on Number of Bedrooms and Conditioned Floor Area per ANSI/RESNET/ICC 301. If provided, an *operational* calculation is instead performed in which the end use defaults to reflect real-world data (where possible). - **Name:** ``geometry_unit_num_occupants`` - **Type:** ``Double`` @@ -593,7 +593,7 @@ Average distance from the floor to the ceiling. **Geometry: Unit Height Above Grade** -Describes the above-grade height of apartment units on upper floors or homes above ambient or belly-and-wing foundations. It is defined as the height of the lowest conditioned floor above grade and is used to calculate the wind speed for the infiltration model. If not provided, the OS-HPXML default (see HPXML Building Construction) is used. +Describes the above-grade height of apartment units on upper floors or homes above ambient or belly-and-wing foundations. It is defined as the height of the lowest conditioned floor above grade and is used to calculate the wind speed for the infiltration model. If not provided, the OS-HPXML default (see HPXML Building Construction) is used. - **Name:** ``geometry_unit_height_above_grade`` - **Type:** ``Double`` @@ -814,7 +814,7 @@ The distance between the unit and the neighboring building to the right (not inc **Neighbor: Front Height** -The height of the neighboring building to the front. If not provided, the OS-HPXML default (see HPXML Neighbor Building) is used. +The height of the neighboring building to the front. If not provided, the OS-HPXML default (see HPXML Neighbor Building) is used. - **Name:** ``neighbor_front_height`` - **Type:** ``Double`` @@ -827,7 +827,7 @@ The height of the neighboring building to the front. If not provided, the OS-HPX **Neighbor: Back Height** -The height of the neighboring building to the back. If not provided, the OS-HPXML default (see HPXML Neighbor Building) is used. +The height of the neighboring building to the back. If not provided, the OS-HPXML default (see HPXML Neighbor Building) is used. - **Name:** ``neighbor_back_height`` - **Type:** ``Double`` @@ -840,7 +840,7 @@ The height of the neighboring building to the back. If not provided, the OS-HPXM **Neighbor: Left Height** -The height of the neighboring building to the left. If not provided, the OS-HPXML default (see HPXML Neighbor Building) is used. +The height of the neighboring building to the left. If not provided, the OS-HPXML default (see HPXML Neighbor Building) is used. - **Name:** ``neighbor_left_height`` - **Type:** ``Double`` @@ -853,7 +853,7 @@ The height of the neighboring building to the left. If not provided, the OS-HPXM **Neighbor: Right Height** -The height of the neighboring building to the right. If not provided, the OS-HPXML default (see HPXML Neighbor Building) is used. +The height of the neighboring building to the right. If not provided, the OS-HPXML default (see HPXML Neighbor Building) is used. - **Name:** ``neighbor_right_height`` - **Type:** ``Double`` @@ -905,7 +905,7 @@ The type of floors. **Foundation Wall: Type** -The material type of the foundation wall. If not provided, the OS-HPXML default (see HPXML Foundation Walls) is used. +The material type of the foundation wall. If not provided, the OS-HPXML default (see HPXML Foundation Walls) is used. - **Name:** ``foundation_wall_type`` - **Type:** ``Choice`` @@ -918,7 +918,7 @@ The material type of the foundation wall. If not provided, the OS-HPXML default **Foundation Wall: Thickness** -The thickness of the foundation wall. If not provided, the OS-HPXML default (see HPXML Foundation Walls) is used. +The thickness of the foundation wall. If not provided, the OS-HPXML default (see HPXML Foundation Walls) is used. - **Name:** ``foundation_wall_thickness`` - **Type:** ``Double`` @@ -957,7 +957,7 @@ Whether the insulation is on the interior or exterior of the foundation wall. On **Foundation Wall: Insulation Distance To Top** -The distance from the top of the foundation wall to the top of the foundation wall insulation. Only applies to basements/crawlspaces. If not provided, the OS-HPXML default (see HPXML Foundation Walls) is used. +The distance from the top of the foundation wall to the top of the foundation wall insulation. Only applies to basements/crawlspaces. If not provided, the OS-HPXML default (see HPXML Foundation Walls) is used. - **Name:** ``foundation_wall_insulation_distance_to_top`` - **Type:** ``Double`` @@ -970,7 +970,7 @@ The distance from the top of the foundation wall to the top of the foundation wa **Foundation Wall: Insulation Distance To Bottom** -The distance from the top of the foundation wall to the bottom of the foundation wall insulation. Only applies to basements/crawlspaces. If not provided, the OS-HPXML default (see HPXML Foundation Walls) is used. +The distance from the top of the foundation wall to the bottom of the foundation wall insulation. Only applies to basements/crawlspaces. If not provided, the OS-HPXML default (see HPXML Foundation Walls) is used. - **Name:** ``foundation_wall_insulation_distance_to_bottom`` - **Type:** ``Double`` @@ -1100,7 +1100,7 @@ Width from slab edge inward of horizontal under-slab insulation. Enter 999 to sp **Slab: Thickness** -The thickness of the slab. Zero can be entered if there is a dirt floor instead of a slab. If not provided, the OS-HPXML default (see HPXML Slabs) is used. +The thickness of the slab. Zero can be entered if there is a dirt floor instead of a slab. If not provided, the OS-HPXML default (see HPXML Slabs) is used. - **Name:** ``slab_thickness`` - **Type:** ``Double`` @@ -1113,7 +1113,7 @@ The thickness of the slab. Zero can be entered if there is a dirt floor instead **Slab: Carpet Fraction** -Fraction of the slab floor area that is carpeted. If not provided, the OS-HPXML default (see HPXML Slabs) is used. +Fraction of the slab floor area that is carpeted. If not provided, the OS-HPXML default (see HPXML Slabs) is used. - **Name:** ``slab_carpet_fraction`` - **Type:** ``Double`` @@ -1126,7 +1126,7 @@ Fraction of the slab floor area that is carpeted. If not provided, the OS-HPXML **Slab: Carpet R-value** -R-value of the slab carpet. If not provided, the OS-HPXML default (see HPXML Slabs) is used. +R-value of the slab carpet. If not provided, the OS-HPXML default (see HPXML Slabs) is used. - **Name:** ``slab_carpet_r`` - **Type:** ``Double`` @@ -1152,7 +1152,7 @@ Assembly R-value for the ceiling (attic floor). **Roof: Material Type** -The material type of the roof. If not provided, the OS-HPXML default (see HPXML Roofs) is used. +The material type of the roof. If not provided, the OS-HPXML default (see HPXML Roofs) is used. - **Name:** ``roof_material_type`` - **Type:** ``Choice`` @@ -1165,7 +1165,7 @@ The material type of the roof. If not provided, the OS-HPXML default (see HPXML Roofs) is used. +The color of the roof. If not provided, the OS-HPXML default (see HPXML Roofs) is used. - **Name:** ``roof_color`` - **Type:** ``Choice`` @@ -1204,7 +1204,7 @@ The location of the radiant barrier in the attic. **Attic: Radiant Barrier Grade** -The grade of the radiant barrier in the attic. If not provided, the OS-HPXML default (see HPXML Roofs) is used. +The grade of the radiant barrier in the attic. If not provided, the OS-HPXML default (see HPXML Roofs) is used. - **Name:** ``radiant_barrier_grade`` - **Type:** ``Choice`` @@ -1230,7 +1230,7 @@ The type of walls. **Wall: Siding Type** -The siding type of the walls. Also applies to rim joists. If not provided, the OS-HPXML default (see HPXML Walls) is used. +The siding type of the walls. Also applies to rim joists. If not provided, the OS-HPXML default (see HPXML Walls) is used. - **Name:** ``wall_siding_type`` - **Type:** ``Choice`` @@ -1243,7 +1243,7 @@ The siding type of the walls. Also applies to rim joists. If not provided, the O **Wall: Color** -The color of the walls. Also applies to rim joists. If not provided, the OS-HPXML default (see HPXML Walls) is used. +The color of the walls. Also applies to rim joists. If not provided, the OS-HPXML default (see HPXML Walls) is used. - **Name:** ``wall_color`` - **Type:** ``Choice`` @@ -1386,7 +1386,7 @@ Ratio of window height to width. **Windows: Fraction Operable** -Fraction of windows that are operable. If not provided, the OS-HPXML default (see HPXML Windows) is used. +Fraction of windows that are operable. If not provided, the OS-HPXML default (see HPXML Windows) is used. - **Name:** ``window_fraction_operable`` - **Type:** ``Double`` @@ -1399,7 +1399,7 @@ Fraction of windows that are operable. If not provided, the OS-HPXML default (se **Windows: Natural Ventilation Availability** -For operable windows, the number of days/week that windows can be opened by occupants for natural ventilation. If not provided, the OS-HPXML default (see HPXML Windows) is used. +For operable windows, the number of days/week that windows can be opened by occupants for natural ventilation. If not provided, the OS-HPXML default (see HPXML Windows) is used. - **Name:** ``window_natvent_availability`` - **Type:** ``Integer`` @@ -1436,7 +1436,7 @@ Full-assembly NFRC solar heat gain coefficient. **Windows: Interior Shading Type** -Type of window interior shading. Summer/winter shading coefficients can be provided below instead. If neither is provided, the OS-HPXML default (see HPXML Interior Shading) is used. +Type of window interior shading. Summer/winter shading coefficients can be provided below instead. If neither is provided, the OS-HPXML default (see HPXML Interior Shading) is used. - **Name:** ``window_interior_shading_type`` - **Type:** ``Choice`` @@ -1449,7 +1449,7 @@ Type of window interior shading. Summer/winter shading coefficients can be provi **Windows: Winter Interior Shading Coefficient** -Interior shading coefficient for the winter season, which if provided overrides the shading type input. 1.0 indicates no reduction in solar gain, 0.85 indicates 15% reduction, etc. If not provided, the OS-HPXML default (see HPXML Interior Shading) is used. +Interior shading coefficient for the winter season, which if provided overrides the shading type input. 1.0 indicates no reduction in solar gain, 0.85 indicates 15% reduction, etc. If not provided, the OS-HPXML default (see HPXML Interior Shading) is used. - **Name:** ``window_interior_shading_winter`` - **Type:** ``Double`` @@ -1462,7 +1462,7 @@ Interior shading coefficient for the winter season, which if provided overrides **Windows: Summer Interior Shading Coefficient** -Interior shading coefficient for the summer season, which if provided overrides the shading type input. 1.0 indicates no reduction in solar gain, 0.85 indicates 15% reduction, etc. If not provided, the OS-HPXML default (see HPXML Interior Shading) is used. +Interior shading coefficient for the summer season, which if provided overrides the shading type input. 1.0 indicates no reduction in solar gain, 0.85 indicates 15% reduction, etc. If not provided, the OS-HPXML default (see HPXML Interior Shading) is used. - **Name:** ``window_interior_shading_summer`` - **Type:** ``Double`` @@ -1475,7 +1475,7 @@ Interior shading coefficient for the summer season, which if provided overrides **Windows: Exterior Shading Type** -Type of window exterior shading. Summer/winter shading coefficients can be provided below instead. If neither is provided, the OS-HPXML default (see HPXML Exterior Shading) is used. +Type of window exterior shading. Summer/winter shading coefficients can be provided below instead. If neither is provided, the OS-HPXML default (see HPXML Exterior Shading) is used. - **Name:** ``window_exterior_shading_type`` - **Type:** ``Choice`` @@ -1488,7 +1488,7 @@ Type of window exterior shading. Summer/winter shading coefficients can be provi **Windows: Winter Exterior Shading Coefficient** -Exterior shading coefficient for the winter season, which if provided overrides the shading type input. 1.0 indicates no reduction in solar gain, 0.85 indicates 15% reduction, etc. If not provided, the OS-HPXML default (see HPXML Exterior Shading) is used. +Exterior shading coefficient for the winter season, which if provided overrides the shading type input. 1.0 indicates no reduction in solar gain, 0.85 indicates 15% reduction, etc. If not provided, the OS-HPXML default (see HPXML Exterior Shading) is used. - **Name:** ``window_exterior_shading_winter`` - **Type:** ``Double`` @@ -1501,7 +1501,7 @@ Exterior shading coefficient for the winter season, which if provided overrides **Windows: Summer Exterior Shading Coefficient** -Exterior shading coefficient for the summer season, which if provided overrides the shading type input. 1.0 indicates no reduction in solar gain, 0.85 indicates 15% reduction, etc. If not provided, the OS-HPXML default (see HPXML Exterior Shading) is used. +Exterior shading coefficient for the summer season, which if provided overrides the shading type input. 1.0 indicates no reduction in solar gain, 0.85 indicates 15% reduction, etc. If not provided, the OS-HPXML default (see HPXML Exterior Shading) is used. - **Name:** ``window_exterior_shading_summer`` - **Type:** ``Double`` @@ -1514,7 +1514,7 @@ Exterior shading coefficient for the summer season, which if provided overrides **Windows: Shading Summer Season** -Enter a date range like 'May 1 - Sep 30'. Defines the summer season for purposes of shading coefficients; the rest of the year is assumed to be winter. If not provided, the OS-HPXML default (see HPXML Windows) is used. +Enter a date range like 'May 1 - Sep 30'. Defines the summer season for purposes of shading coefficients; the rest of the year is assumed to be winter. If not provided, the OS-HPXML default (see HPXML Windows) is used. - **Name:** ``window_shading_summer_season`` - **Type:** ``String`` @@ -1885,7 +1885,7 @@ Type of air leakage if providing a numeric air leakage value. If 'unit total', r **Air Leakage: Has Flue or Chimney in Conditioned Space** -Presence of flue or chimney with combustion air from conditioned space; used for infiltration model. If not provided, the OS-HPXML default (see Flue or Chimney) is used. +Presence of flue or chimney with combustion air from conditioned space; used for infiltration model. If not provided, the OS-HPXML default (see Flue or Chimney) is used. - **Name:** ``air_leakage_has_flue_or_chimney_in_conditioned_space`` - **Type:** ``Boolean`` @@ -1935,7 +1935,7 @@ The rated heating efficiency value of the heating system. **Heating System: Heating Capacity** -The output heating capacity of the heating system. If not provided, the OS-HPXML autosized default (see HPXML Heating Systems) is used. +The output heating capacity of the heating system. If not provided, the OS-HPXML autosized default (see HPXML Heating Systems) is used. - **Name:** ``heating_system_heating_capacity`` - **Type:** ``Double`` @@ -2048,7 +2048,7 @@ The rated efficiency value of the cooling system. Ignored for evaporative cooler **Cooling System: Cooling Compressor Type** -The compressor type of the cooling system. Only applies to central air conditioner and mini-split. If not provided, the OS-HPXML default (see Central Air Conditioner, Mini-Split Air Conditioner) is used. +The compressor type of the cooling system. Only applies to central air conditioner and mini-split. If not provided, the OS-HPXML default (see Central Air Conditioner, Mini-Split Air Conditioner) is used. - **Name:** ``cooling_system_cooling_compressor_type`` - **Type:** ``Choice`` @@ -2061,7 +2061,7 @@ The compressor type of the cooling system. Only applies to central air condition **Cooling System: Cooling Sensible Heat Fraction** -The sensible heat fraction of the cooling system. Ignored for evaporative cooler. If not provided, the OS-HPXML default (see Central Air Conditioner, Room Air Conditioner, Packaged Terminal Air Conditioner, Mini-Split Air Conditioner) is used. +The sensible heat fraction of the cooling system. Ignored for evaporative cooler. If not provided, the OS-HPXML default (see Central Air Conditioner, Room Air Conditioner, Packaged Terminal Air Conditioner, Mini-Split Air Conditioner) is used. - **Name:** ``cooling_system_cooling_sensible_heat_fraction`` - **Type:** ``Double`` @@ -2074,7 +2074,7 @@ The sensible heat fraction of the cooling system. Ignored for evaporative cooler **Cooling System: Cooling Capacity** -The output cooling capacity of the cooling system. If not provided, the OS-HPXML autosized default (see Central Air Conditioner, Room Air Conditioner, Packaged Terminal Air Conditioner, Evaporative Cooler, Mini-Split Air Conditioner) is used. +The output cooling capacity of the cooling system. If not provided, the OS-HPXML autosized default (see Central Air Conditioner, Room Air Conditioner, Packaged Terminal Air Conditioner, Evaporative Cooler, Mini-Split Air Conditioner) is used. - **Name:** ``cooling_system_cooling_capacity`` - **Type:** ``Double`` @@ -2161,7 +2161,7 @@ The refrigerant charge defect ratio, defined as (InstalledCharge - DesignCharge) **Cooling System: Crankcase Heater Power Watts** -Cooling system crankcase heater power consumption in Watts. Applies only to central air conditioner, room air conditioner, packaged terminal air conditioner and mini-split. If not provided, the OS-HPXML default (see Central Air Conditioner, Room Air Conditioner, Packaged Terminal Air Conditioner, Mini-Split Air Conditioner) is used. +Cooling system crankcase heater power consumption in Watts. Applies only to central air conditioner, room air conditioner, packaged terminal air conditioner and mini-split. If not provided, the OS-HPXML default (see Central Air Conditioner, Room Air Conditioner, Packaged Terminal Air Conditioner, Mini-Split Air Conditioner) is used. - **Name:** ``cooling_system_crankcase_heater_watts`` - **Type:** ``Double`` @@ -2200,7 +2200,7 @@ The rated heating efficiency value of the heating system integrated into cooling **Cooling System: Integrated Heating System Heating Capacity** -The output heating capacity of the heating system integrated into cooling system. If not provided, the OS-HPXML autosized default (see Room Air Conditioner, Packaged Terminal Air Conditioner) is used. Only used for room air conditioner and packaged terminal air conditioner. +The output heating capacity of the heating system integrated into cooling system. If not provided, the OS-HPXML autosized default (see Room Air Conditioner, Packaged Terminal Air Conditioner) is used. Only used for room air conditioner and packaged terminal air conditioner. - **Name:** ``cooling_system_integrated_heating_system_capacity`` - **Type:** ``Double`` @@ -2287,7 +2287,7 @@ The rated cooling efficiency value of the heat pump. **Heat Pump: Cooling Compressor Type** -The compressor type of the heat pump. Only applies to air-to-air and mini-split. If not provided, the OS-HPXML default (see Air-to-Air Heat Pump, Mini-Split Heat Pump) is used. +The compressor type of the heat pump. Only applies to air-to-air and mini-split. If not provided, the OS-HPXML default (see Air-to-Air Heat Pump, Mini-Split Heat Pump) is used. - **Name:** ``heat_pump_cooling_compressor_type`` - **Type:** ``Choice`` @@ -2300,7 +2300,7 @@ The compressor type of the heat pump. Only applies to air-to-air and mini-split. **Heat Pump: Cooling Sensible Heat Fraction** -The sensible heat fraction of the heat pump. If not provided, the OS-HPXML default (see Air-to-Air Heat Pump, Mini-Split Heat Pump, Packaged Terminal Heat Pump, Room Air Conditioner w/ Reverse Cycle, Ground-to-Air Heat Pump) is used. +The sensible heat fraction of the heat pump. If not provided, the OS-HPXML default (see Air-to-Air Heat Pump, Mini-Split Heat Pump, Packaged Terminal Heat Pump, Room Air Conditioner w/ Reverse Cycle, Ground-to-Air Heat Pump) is used. - **Name:** ``heat_pump_cooling_sensible_heat_fraction`` - **Type:** ``Double`` @@ -2313,7 +2313,7 @@ The sensible heat fraction of the heat pump. If not provided, the OS-HPXML defau **Heat Pump: Heating Capacity** -The output heating capacity of the heat pump. If not provided, the OS-HPXML autosized default (see Air-to-Air Heat Pump, Mini-Split Heat Pump, Packaged Terminal Heat Pump, Room Air Conditioner w/ Reverse Cycle, Ground-to-Air Heat Pump) is used. +The output heating capacity of the heat pump. If not provided, the OS-HPXML autosized default (see Air-to-Air Heat Pump, Mini-Split Heat Pump, Packaged Terminal Heat Pump, Room Air Conditioner w/ Reverse Cycle, Ground-to-Air Heat Pump) is used. - **Name:** ``heat_pump_heating_capacity`` - **Type:** ``Double`` @@ -2350,7 +2350,7 @@ The maximum capacity limit applied to the auto-sizing methodology. If not provid **Heat Pump: Heating Capacity Retention Fraction** -The output heating capacity of the heat pump at a user-specified temperature (e.g., 17F or 5F) divided by the above nominal heating capacity. Applies to all heat pump types except ground-to-air. If not provided, the OS-HPXML default (see Air-to-Air Heat Pump, Mini-Split Heat Pump, Packaged Terminal Heat Pump, Room Air Conditioner w/ Reverse Cycle) is used. +The output heating capacity of the heat pump at a user-specified temperature (e.g., 17F or 5F) divided by the above nominal heating capacity. Applies to all heat pump types except ground-to-air. If not provided, the OS-HPXML default (see Air-to-Air Heat Pump, Mini-Split Heat Pump, Packaged Terminal Heat Pump, Room Air Conditioner w/ Reverse Cycle) is used. - **Name:** ``heat_pump_heating_capacity_retention_fraction`` - **Type:** ``Double`` @@ -2376,7 +2376,7 @@ The user-specified temperature (e.g., 17F or 5F) for the above heating capacity **Heat Pump: Cooling Capacity** -The output cooling capacity of the heat pump. If not provided, the OS-HPXML autosized default (see Air-to-Air Heat Pump, Mini-Split Heat Pump, Packaged Terminal Heat Pump, Room Air Conditioner w/ Reverse Cycle, Ground-to-Air Heat Pump) is used. +The output cooling capacity of the heat pump. If not provided, the OS-HPXML autosized default (see Air-to-Air Heat Pump, Mini-Split Heat Pump, Packaged Terminal Heat Pump, Room Air Conditioner w/ Reverse Cycle, Ground-to-Air Heat Pump) is used. - **Name:** ``heat_pump_cooling_capacity`` - **Type:** ``Double`` @@ -2439,7 +2439,7 @@ The cooling load served by the heat pump. **Heat Pump: Compressor Lockout Temperature** -The temperature below which the heat pump compressor is disabled. If both this and Backup Heating Lockout Temperature are provided and use the same value, it essentially defines a switchover temperature (for, e.g., a dual-fuel heat pump). Applies to all heat pump types other than ground-to-air. If not provided, the OS-HPXML default (see Air-to-Air Heat Pump, Mini-Split Heat Pump, Packaged Terminal Heat Pump, Room Air Conditioner w/ Reverse Cycle) is used. +The temperature below which the heat pump compressor is disabled. If both this and Backup Heating Lockout Temperature are provided and use the same value, it essentially defines a switchover temperature (for, e.g., a dual-fuel heat pump). Applies to all heat pump types other than ground-to-air. If not provided, the OS-HPXML default (see Air-to-Air Heat Pump, Mini-Split Heat Pump, Packaged Terminal Heat Pump, Room Air Conditioner w/ Reverse Cycle) is used. - **Name:** ``heat_pump_compressor_lockout_temp`` - **Type:** ``Double`` @@ -2513,7 +2513,7 @@ The backup rated efficiency value of the heat pump. Percent for electricity fuel **Heat Pump: Backup Heating Capacity** -The backup output heating capacity of the heat pump. If not provided, the OS-HPXML autosized default (see Backup) is used. Only applies if Backup Type is 'integrated'. +The backup output heating capacity of the heat pump. If not provided, the OS-HPXML autosized default (see Backup) is used. Only applies if Backup Type is 'integrated'. - **Name:** ``heat_pump_backup_heating_capacity`` - **Type:** ``Double`` @@ -2526,7 +2526,7 @@ The backup output heating capacity of the heat pump. If not provided, the OS-HPX **Heat Pump: Backup Heating Lockout Temperature** -The temperature above which the heat pump backup system is disabled. If both this and Compressor Lockout Temperature are provided and use the same value, it essentially defines a switchover temperature (for, e.g., a dual-fuel heat pump). Applies for both Backup Type of 'integrated' and 'separate'. If not provided, the OS-HPXML default (see Backup) is used. +The temperature above which the heat pump backup system is disabled. If both this and Compressor Lockout Temperature are provided and use the same value, it essentially defines a switchover temperature (for, e.g., a dual-fuel heat pump). Applies for both Backup Type of 'integrated' and 'separate'. If not provided, the OS-HPXML default (see Backup) is used. - **Name:** ``heat_pump_backup_heating_lockout_temp`` - **Type:** ``Double`` @@ -2539,7 +2539,7 @@ The temperature above which the heat pump backup system is disabled. If both thi **Heat Pump: Sizing Methodology** -The auto-sizing methodology to use when the heat pump capacity is not provided. If not provided, the OS-HPXML default (see HPXML HVAC Sizing Control) is used. +The auto-sizing methodology to use when the heat pump capacity is not provided. If not provided, the OS-HPXML default (see HPXML HVAC Sizing Control) is used. - **Name:** ``heat_pump_sizing_methodology`` - **Type:** ``Choice`` @@ -2552,7 +2552,7 @@ The auto-sizing methodology to use when the heat pump capacity is not provided. **Heat Pump: Backup Sizing Methodology** -The auto-sizing methodology to use when the heat pump backup capacity is not provided. If not provided, the OS-HPXML default (see HPXML HVAC Sizing Control) is used. +The auto-sizing methodology to use when the heat pump backup capacity is not provided. If not provided, the OS-HPXML default (see HPXML HVAC Sizing Control) is used. - **Name:** ``heat_pump_backup_sizing_methodology`` - **Type:** ``Choice`` @@ -2602,7 +2602,7 @@ The refrigerant charge defect ratio, defined as (InstalledCharge - DesignCharge) **Heat Pump: Crankcase Heater Power Watts** -Heat Pump crankcase heater power consumption in Watts. Applies only to air-to-air, mini-split, packaged terminal heat pump and room air conditioner with reverse cycle. If not provided, the OS-HPXML default (see Air-to-Air Heat Pump, Mini-Split Heat Pump, Packaged Terminal Heat Pump, Room Air Conditioner w/ Reverse Cycle) is used. +Heat Pump crankcase heater power consumption in Watts. Applies only to air-to-air, mini-split, packaged terminal heat pump and room air conditioner with reverse cycle. If not provided, the OS-HPXML default (see Air-to-Air Heat Pump, Mini-Split Heat Pump, Packaged Terminal Heat Pump, Room Air Conditioner w/ Reverse Cycle) is used. - **Name:** ``heat_pump_crankcase_heater_watts`` - **Type:** ``Double`` @@ -2738,7 +2738,7 @@ Maximum speed efficiency COP values of cooling detailed performance data if avai **Geothermal Loop: Configuration** -Configuration of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see Ground-to-Air Heat Pump) is used. +Configuration of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see Ground-to-Air Heat Pump) is used. - **Name:** ``geothermal_loop_configuration`` - **Type:** ``Choice`` @@ -2751,7 +2751,7 @@ Configuration of the geothermal loop. Only applies to ground-to-air heat pump ty **Geothermal Loop: Borefield Configuration** -Borefield configuration of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used. +Borefield configuration of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used. - **Name:** ``geothermal_loop_borefield_configuration`` - **Type:** ``Choice`` @@ -2764,7 +2764,7 @@ Borefield configuration of the geothermal loop. Only applies to ground-to-air he **Geothermal Loop: Loop Flow** -Water flow rate through the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML autosized default (see HPXML Geothermal Loops) is used. +Water flow rate through the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML autosized default (see HPXML Geothermal Loops) is used. - **Name:** ``geothermal_loop_loop_flow`` - **Type:** ``Double`` @@ -2777,7 +2777,7 @@ Water flow rate through the geothermal loop. Only applies to ground-to-air heat **Geothermal Loop: Boreholes Count** -Number of boreholes. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML autosized default (see HPXML Geothermal Loops) is used. +Number of boreholes. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML autosized default (see HPXML Geothermal Loops) is used. - **Name:** ``geothermal_loop_boreholes_count`` - **Type:** ``Integer`` @@ -2790,7 +2790,7 @@ Number of boreholes. Only applies to ground-to-air heat pump type. If not provid **Geothermal Loop: Boreholes Length** -Average length of each borehole (vertical). Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML autosized default (see HPXML Geothermal Loops) is used. +Average length of each borehole (vertical). Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML autosized default (see HPXML Geothermal Loops) is used. - **Name:** ``geothermal_loop_boreholes_length`` - **Type:** ``Double`` @@ -2803,7 +2803,7 @@ Average length of each borehole (vertical). Only applies to ground-to-air heat p **Geothermal Loop: Boreholes Spacing** -Distance between bores. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used. +Distance between bores. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used. - **Name:** ``geothermal_loop_boreholes_spacing`` - **Type:** ``Double`` @@ -2816,7 +2816,7 @@ Distance between bores. Only applies to ground-to-air heat pump type. If not pro **Geothermal Loop: Boreholes Diameter** -Diameter of bores. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used. +Diameter of bores. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used. - **Name:** ``geothermal_loop_boreholes_diameter`` - **Type:** ``Double`` @@ -2829,7 +2829,7 @@ Diameter of bores. Only applies to ground-to-air heat pump type. If not provided **Geothermal Loop: Grout Type** -Grout type of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used. +Grout type of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used. - **Name:** ``geothermal_loop_grout_type`` - **Type:** ``Choice`` @@ -2842,7 +2842,7 @@ Grout type of the geothermal loop. Only applies to ground-to-air heat pump type. **Geothermal Loop: Pipe Type** -Pipe type of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used. +Pipe type of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used. - **Name:** ``geothermal_loop_pipe_type`` - **Type:** ``Choice`` @@ -2855,7 +2855,7 @@ Pipe type of the geothermal loop. Only applies to ground-to-air heat pump type. **Geothermal Loop: Pipe Diameter** -Pipe diameter of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used. +Pipe diameter of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see HPXML Geothermal Loops) is used. - **Name:** ``geothermal_loop_pipe_diameter`` - **Type:** ``Choice`` @@ -2907,7 +2907,7 @@ The rated heating efficiency value of the second heating system. **Heating System 2: Heating Capacity** -The output heating capacity of the second heating system. If not provided, the OS-HPXML autosized default (see HPXML Heating Systems) is used. +The output heating capacity of the second heating system. If not provided, the OS-HPXML autosized default (see HPXML Heating Systems) is used. - **Name:** ``heating_system_2_heating_capacity`` - **Type:** ``Double`` @@ -3001,7 +3001,7 @@ Specify the constant or 24-hour comma-separated weekend cooling setpoint schedul **HVAC Control: Heating Season Period** -Enter a date range like 'Nov 1 - Jun 30'. If not provided, the OS-HPXML default (see HPXML HVAC Control) is used. Can also provide 'BuildingAmerica' to use automatic seasons from the Building America House Simulation Protocols. +Enter a date range like 'Nov 1 - Jun 30'. If not provided, the OS-HPXML default (see HPXML HVAC Control) is used. Can also provide 'BuildingAmerica' to use automatic seasons from the Building America House Simulation Protocols. - **Name:** ``hvac_control_heating_season_period`` - **Type:** ``String`` @@ -3012,7 +3012,7 @@ Enter a date range like 'Nov 1 - Jun 30'. If not provided, the OS-HPXML default **HVAC Control: Cooling Season Period** -Enter a date range like 'Jun 1 - Oct 31'. If not provided, the OS-HPXML default (see HPXML HVAC Control) is used. Can also provide 'BuildingAmerica' to use automatic seasons from the Building America House Simulation Protocols. +Enter a date range like 'Jun 1 - Oct 31'. If not provided, the OS-HPXML default (see HPXML HVAC Control) is used. Can also provide 'BuildingAmerica' to use automatic seasons from the Building America House Simulation Protocols. - **Name:** ``hvac_control_cooling_season_period`` - **Type:** ``String`` @@ -3023,7 +3023,7 @@ Enter a date range like 'Jun 1 - Oct 31'. If not provided, the OS-HPXML default **HVAC Blower: Fan Efficiency** -The blower fan efficiency at maximum fan speed. Applies only to split (not packaged) systems (i.e., applies to ducted systems as well as ductless mini-split systems). If not provided, the OS-HPXML default (see HPXML Heating Systems, HPXML Cooling Systems, HPXML Heat Pumps) is used. +The blower fan efficiency at maximum fan speed. Applies only to split (not packaged) systems (i.e., applies to ducted systems as well as ductless mini-split systems). If not provided, the OS-HPXML default (see HPXML Heating Systems, HPXML Cooling Systems, HPXML Heat Pumps) is used. - **Name:** ``hvac_blower_fan_watts_per_cfm`` - **Type:** ``Double`` @@ -3060,7 +3060,7 @@ The leakage value to outside for the supply ducts. **Ducts: Supply Location** -The location of the supply ducts. If not provided, the OS-HPXML default (see Air Distribution) is used. +The location of the supply ducts. If not provided, the OS-HPXML default (see Air Distribution) is used. - **Name:** ``ducts_supply_location`` - **Type:** ``Choice`` @@ -3099,7 +3099,7 @@ Whether the supply ducts are buried in, e.g., attic loose-fill insulation. Parti **Ducts: Supply Surface Area** -The supply ducts surface area in the given location. If neither Surface Area nor Area Fraction provided, the OS-HPXML default (see Air Distribution) is used. +The supply ducts surface area in the given location. If neither Surface Area nor Area Fraction provided, the OS-HPXML default (see Air Distribution) is used. - **Name:** ``ducts_supply_surface_area`` - **Type:** ``Double`` @@ -3112,7 +3112,7 @@ The supply ducts surface area in the given location. If neither Surface Area nor **Ducts: Supply Area Fraction** -The fraction of supply ducts surface area in the given location. Only used if Surface Area is not provided. If the fraction is less than 1, the remaining duct area is assumed to be in conditioned space. If neither Surface Area nor Area Fraction provided, the OS-HPXML default (see Air Distribution) is used. +The fraction of supply ducts surface area in the given location. Only used if Surface Area is not provided. If the fraction is less than 1, the remaining duct area is assumed to be in conditioned space. If neither Surface Area nor Area Fraction provided, the OS-HPXML default (see Air Distribution) is used. - **Name:** ``ducts_supply_surface_area_fraction`` - **Type:** ``Double`` @@ -3125,7 +3125,7 @@ The fraction of supply ducts surface area in the given location. Only used if Su **Ducts: Supply Fraction Rectangular** -The fraction of supply ducts that are rectangular (as opposed to round); this affects the duct effective R-value used for modeling. If not provided, the OS-HPXML default (see Air Distribution) is used. +The fraction of supply ducts that are rectangular (as opposed to round); this affects the duct effective R-value used for modeling. If not provided, the OS-HPXML default (see Air Distribution) is used. - **Name:** ``ducts_supply_fraction_rectangular`` - **Type:** ``Double`` @@ -3149,7 +3149,7 @@ The leakage value to outside for the return ducts. **Ducts: Return Location** -The location of the return ducts. If not provided, the OS-HPXML default (see Air Distribution) is used. +The location of the return ducts. If not provided, the OS-HPXML default (see Air Distribution) is used. - **Name:** ``ducts_return_location`` - **Type:** ``Choice`` @@ -3188,7 +3188,7 @@ Whether the return ducts are buried in, e.g., attic loose-fill insulation. Parti **Ducts: Return Surface Area** -The return ducts surface area in the given location. If neither Surface Area nor Area Fraction provided, the OS-HPXML default (see Air Distribution) is used. +The return ducts surface area in the given location. If neither Surface Area nor Area Fraction provided, the OS-HPXML default (see Air Distribution) is used. - **Name:** ``ducts_return_surface_area`` - **Type:** ``Double`` @@ -3201,7 +3201,7 @@ The return ducts surface area in the given location. If neither Surface Area nor **Ducts: Return Area Fraction** -The fraction of return ducts surface area in the given location. Only used if Surface Area is not provided. If the fraction is less than 1, the remaining duct area is assumed to be in conditioned space. If neither Surface Area nor Area Fraction provided, the OS-HPXML default (see Air Distribution) is used. +The fraction of return ducts surface area in the given location. Only used if Surface Area is not provided. If the fraction is less than 1, the remaining duct area is assumed to be in conditioned space. If neither Surface Area nor Area Fraction provided, the OS-HPXML default (see Air Distribution) is used. - **Name:** ``ducts_return_surface_area_fraction`` - **Type:** ``Double`` @@ -3214,7 +3214,7 @@ The fraction of return ducts surface area in the given location. Only used if Su **Ducts: Number of Return Registers** -The number of return registers of the ducts. Only used to calculate default return duct surface area. If not provided, the OS-HPXML default (see Air Distribution) is used. +The number of return registers of the ducts. Only used to calculate default return duct surface area. If not provided, the OS-HPXML default (see Air Distribution) is used. - **Name:** ``ducts_number_of_return_registers`` - **Type:** ``Integer`` @@ -3227,7 +3227,7 @@ The number of return registers of the ducts. Only used to calculate default retu **Ducts: Return Fraction Rectangular** -The fraction of return ducts that are rectangular (as opposed to round); this affects the duct effective R-value used for modeling. If not provided, the OS-HPXML default (see Air Distribution) is used. +The fraction of return ducts that are rectangular (as opposed to round); this affects the duct effective R-value used for modeling. If not provided, the OS-HPXML default (see Air Distribution) is used. - **Name:** ``ducts_return_fraction_rectangular`` - **Type:** ``Double`` @@ -3253,7 +3253,7 @@ The type of the mechanical ventilation. Use 'none' if there is no mechanical ven **Mechanical Ventilation: Flow Rate** -The flow rate of the mechanical ventilation. If not provided, the OS-HPXML default (see HPXML Mechanical Ventilation Fans) is used. +The flow rate of the mechanical ventilation. If not provided, the OS-HPXML default (see HPXML Mechanical Ventilation Fans) is used. - **Name:** ``mech_vent_flow_rate`` - **Type:** ``Double`` @@ -3266,7 +3266,7 @@ The flow rate of the mechanical ventilation. If not provided, the OS-HPXML defau **Mechanical Ventilation: Hours In Operation** -The hours in operation of the mechanical ventilation. If not provided, the OS-HPXML default (see HPXML Mechanical Ventilation Fans) is used. +The hours in operation of the mechanical ventilation. If not provided, the OS-HPXML default (see HPXML Mechanical Ventilation Fans) is used. - **Name:** ``mech_vent_hours_in_operation`` - **Type:** ``Double`` @@ -3318,7 +3318,7 @@ The Unadjusted or Adjusted sensible recovery efficiency of the mechanical ventil **Mechanical Ventilation: Fan Power** -The fan power of the mechanical ventilation. If not provided, the OS-HPXML default (see HPXML Mechanical Ventilation Fans) is used. +The fan power of the mechanical ventilation. If not provided, the OS-HPXML default (see HPXML Mechanical Ventilation Fans) is used. - **Name:** ``mech_vent_fan_power`` - **Type:** ``Double`` @@ -3526,7 +3526,7 @@ The fan power of the second mechanical ventilation. **Kitchen Fans: Quantity** -The quantity of the kitchen fans. If not provided, the OS-HPXML default (see HPXML Local Ventilation Fans) is used. +The quantity of the kitchen fans. If not provided, the OS-HPXML default (see HPXML Local Ventilation Fans) is used. - **Name:** ``kitchen_fans_quantity`` - **Type:** ``Integer`` @@ -3539,7 +3539,7 @@ The quantity of the kitchen fans. If not provided, the OS-HPXML default (see HPXML Local Ventilation Fans) is used. +The flow rate of the kitchen fan. If not provided, the OS-HPXML default (see HPXML Local Ventilation Fans) is used. - **Name:** ``kitchen_fans_flow_rate`` - **Type:** ``Double`` @@ -3552,7 +3552,7 @@ The flow rate of the kitchen fan. If not provided, the OS-HPXML default (see HPXML Local Ventilation Fans) is used. +The hours in operation of the kitchen fan. If not provided, the OS-HPXML default (see HPXML Local Ventilation Fans) is used. - **Name:** ``kitchen_fans_hours_in_operation`` - **Type:** ``Double`` @@ -3565,7 +3565,7 @@ The hours in operation of the kitchen fan. If not provided, the OS-HPXML default **Kitchen Fans: Fan Power** -The fan power of the kitchen fan. If not provided, the OS-HPXML default (see HPXML Local Ventilation Fans) is used. +The fan power of the kitchen fan. If not provided, the OS-HPXML default (see HPXML Local Ventilation Fans) is used. - **Name:** ``kitchen_fans_power`` - **Type:** ``Double`` @@ -3578,7 +3578,7 @@ The fan power of the kitchen fan. If not provided, the OS-HPXML default (see HPXML Local Ventilation Fans) is used. +The start hour of the kitchen fan. If not provided, the OS-HPXML default (see HPXML Local Ventilation Fans) is used. - **Name:** ``kitchen_fans_start_hour`` - **Type:** ``Integer`` @@ -3591,7 +3591,7 @@ The start hour of the kitchen fan. If not provided, the OS-HPXML default (see HPXML Local Ventilation Fans) is used. +The quantity of the bathroom fans. If not provided, the OS-HPXML default (see HPXML Local Ventilation Fans) is used. - **Name:** ``bathroom_fans_quantity`` - **Type:** ``Integer`` @@ -3604,7 +3604,7 @@ The quantity of the bathroom fans. If not provided, the OS-HPXML default (see HPXML Local Ventilation Fans) is used. +The flow rate of the bathroom fans. If not provided, the OS-HPXML default (see HPXML Local Ventilation Fans) is used. - **Name:** ``bathroom_fans_flow_rate`` - **Type:** ``Double`` @@ -3617,7 +3617,7 @@ The flow rate of the bathroom fans. If not provided, the OS-HPXML default (see < **Bathroom Fans: Hours In Operation** -The hours in operation of the bathroom fans. If not provided, the OS-HPXML default (see HPXML Local Ventilation Fans) is used. +The hours in operation of the bathroom fans. If not provided, the OS-HPXML default (see HPXML Local Ventilation Fans) is used. - **Name:** ``bathroom_fans_hours_in_operation`` - **Type:** ``Double`` @@ -3630,7 +3630,7 @@ The hours in operation of the bathroom fans. If not provided, the OS-HPXML defau **Bathroom Fans: Fan Power** -The fan power of the bathroom fans. If not provided, the OS-HPXML default (see HPXML Local Ventilation Fans) is used. +The fan power of the bathroom fans. If not provided, the OS-HPXML default (see HPXML Local Ventilation Fans) is used. - **Name:** ``bathroom_fans_power`` - **Type:** ``Double`` @@ -3643,7 +3643,7 @@ The fan power of the bathroom fans. If not provided, the OS-HPXML default (see < **Bathroom Fans: Start Hour** -The start hour of the bathroom fans. If not provided, the OS-HPXML default (see HPXML Local Ventilation Fans) is used. +The start hour of the bathroom fans. If not provided, the OS-HPXML default (see HPXML Local Ventilation Fans) is used. - **Name:** ``bathroom_fans_start_hour`` - **Type:** ``Integer`` @@ -3667,7 +3667,7 @@ Whether there is a whole house fan. **Whole House Fan: Flow Rate** -The flow rate of the whole house fan. If not provided, the OS-HPXML default (see HPXML Whole House Fans) is used. +The flow rate of the whole house fan. If not provided, the OS-HPXML default (see HPXML Whole House Fans) is used. - **Name:** ``whole_house_fan_flow_rate`` - **Type:** ``Double`` @@ -3680,7 +3680,7 @@ The flow rate of the whole house fan. If not provided, the OS-HPXML default (see **Whole House Fan: Fan Power** -The fan power of the whole house fan. If not provided, the OS-HPXML default (see HPXML Whole House Fans) is used. +The fan power of the whole house fan. If not provided, the OS-HPXML default (see HPXML Whole House Fans) is used. - **Name:** ``whole_house_fan_power`` - **Type:** ``Double`` @@ -3719,7 +3719,7 @@ The fuel type of water heater. Ignored for heat pump water heater. **Water Heater: Location** -The location of water heater. If not provided, the OS-HPXML default (see HPXML Water Heating Systems) is used. +The location of water heater. If not provided, the OS-HPXML default (see HPXML Water Heating Systems) is used. - **Name:** ``water_heater_location`` - **Type:** ``Choice`` @@ -3732,7 +3732,7 @@ The location of water heater. If not provided, the OS-HPXML default (see Conventional Storage, Heat Pump, Combi Boiler w/ Storage) is used. +Nominal volume of water heater tank. If not provided, the OS-HPXML default (see Conventional Storage, Heat Pump, Combi Boiler w/ Storage) is used. - **Name:** ``water_heater_tank_volume`` - **Type:** ``Double`` @@ -3769,7 +3769,7 @@ Rated Energy Factor or Uniform Energy Factor. Does not apply to space-heating bo **Water Heater: Usage Bin** -The usage of the water heater. Only applies if Efficiency Type is UniformEnergyFactor and Type is not instantaneous water heater. Does not apply to space-heating boilers. If not provided, the OS-HPXML default (see Conventional Storage, Heat Pump) is used. +The usage of the water heater. Only applies if Efficiency Type is UniformEnergyFactor and Type is not instantaneous water heater. Does not apply to space-heating boilers. If not provided, the OS-HPXML default (see Conventional Storage, Heat Pump) is used. - **Name:** ``water_heater_usage_bin`` - **Type:** ``Choice`` @@ -3782,7 +3782,7 @@ The usage of the water heater. Only applies if Efficiency Type is UniformEnergyF **Water Heater: Recovery Efficiency** -Ratio of energy delivered to water heater to the energy content of the fuel consumed by the water heater. Only used for non-electric storage water heaters. If not provided, the OS-HPXML default (see Conventional Storage) is used. +Ratio of energy delivered to water heater to the energy content of the fuel consumed by the water heater. Only used for non-electric storage water heaters. If not provided, the OS-HPXML default (see Conventional Storage) is used. - **Name:** ``water_heater_recovery_efficiency`` - **Type:** ``Double`` @@ -3795,7 +3795,7 @@ Ratio of energy delivered to water heater to the energy content of the fuel cons **Water Heater: Heating Capacity** -Heating capacity. Only applies to storage water heater and heat pump water heater (compressor). If not provided, the OS-HPXML default (see Conventional Storage, Heat Pump) is used. +Heating capacity. Only applies to storage water heater and heat pump water heater (compressor). If not provided, the OS-HPXML default (see Conventional Storage, Heat Pump) is used. - **Name:** ``water_heater_heating_capacity`` - **Type:** ``Double`` @@ -3808,7 +3808,7 @@ Heating capacity. Only applies to storage water heater and heat pump water heate **Water Heater: Backup Heating Capacity** -Backup heating capacity for a heat pump water heater. If not provided, the OS-HPXML default (see Heat Pump) is used. +Backup heating capacity for a heat pump water heater. If not provided, the OS-HPXML default (see Heat Pump) is used. - **Name:** ``water_heater_backup_heating_capacity`` - **Type:** ``Double`` @@ -3821,7 +3821,7 @@ Backup heating capacity for a heat pump water heater. If not provided, the OS-HP **Water Heater: Standby Loss** -The standby loss of water heater. Only applies to space-heating boilers. If not provided, the OS-HPXML default (see Combi Boiler w/ Storage) is used. +The standby loss of water heater. Only applies to space-heating boilers. If not provided, the OS-HPXML default (see Combi Boiler w/ Storage) is used. - **Name:** ``water_heater_standby_loss`` - **Type:** ``Double`` @@ -3847,7 +3847,7 @@ The jacket R-value of water heater. Doesn't apply to instantaneous water heater **Water Heater: Setpoint Temperature** -The setpoint temperature of water heater. If not provided, the OS-HPXML default (see HPXML Water Heating Systems) is used. +The setpoint temperature of water heater. If not provided, the OS-HPXML default (see HPXML Water Heating Systems) is used. - **Name:** ``water_heater_setpoint_temperature`` - **Type:** ``Double`` @@ -3884,7 +3884,7 @@ Requires that the dwelling unit has a air-to-air, mini-split, or ground-to-air h **Water Heater: Tank Type** -Type of tank model to use. The 'stratified' tank generally provide more accurate results, but may significantly increase run time. Applies only to storage water heater. If not provided, the OS-HPXML default (see Conventional Storage) is used. +Type of tank model to use. The 'stratified' tank generally provide more accurate results, but may significantly increase run time. Applies only to storage water heater. If not provided, the OS-HPXML default (see Conventional Storage) is used. - **Name:** ``water_heater_tank_model_type`` - **Type:** ``Choice`` @@ -3897,7 +3897,7 @@ Type of tank model to use. The 'stratified' tank generally provide more accurate **Water Heater: Operating Mode** -The water heater operating mode. The 'heat pump only' option only uses the heat pump, while 'hybrid/auto' allows the backup electric resistance to come on in high demand situations. This is ignored if a scheduled operating mode type is selected. Applies only to heat pump water heater. If not provided, the OS-HPXML default (see Heat Pump) is used. +The water heater operating mode. The 'heat pump only' option only uses the heat pump, while 'hybrid/auto' allows the backup electric resistance to come on in high demand situations. This is ignored if a scheduled operating mode type is selected. Applies only to heat pump water heater. If not provided, the OS-HPXML default (see Heat Pump) is used. - **Name:** ``water_heater_operating_mode`` - **Type:** ``Choice`` @@ -3923,7 +3923,7 @@ The type of the hot water distribution system. **Hot Water Distribution: Standard Piping Length** -If the distribution system is Standard, the length of the piping. If not provided, the OS-HPXML default (see Standard) is used. +If the distribution system is Standard, the length of the piping. If not provided, the OS-HPXML default (see Standard) is used. - **Name:** ``hot_water_distribution_standard_piping_length`` - **Type:** ``Double`` @@ -3949,7 +3949,7 @@ If the distribution system is Recirculation, the type of hot water recirculation **Hot Water Distribution: Recirculation Piping Length** -If the distribution system is Recirculation, the length of the recirculation piping. If not provided, the OS-HPXML default (see Recirculation (In-Unit)) is used. +If the distribution system is Recirculation, the length of the recirculation piping. If not provided, the OS-HPXML default (see Recirculation (In-Unit)) is used. - **Name:** ``hot_water_distribution_recirc_piping_length`` - **Type:** ``Double`` @@ -3962,7 +3962,7 @@ If the distribution system is Recirculation, the length of the recirculation pip **Hot Water Distribution: Recirculation Branch Piping Length** -If the distribution system is Recirculation, the length of the recirculation branch piping. If not provided, the OS-HPXML default (see Recirculation (In-Unit)) is used. +If the distribution system is Recirculation, the length of the recirculation branch piping. If not provided, the OS-HPXML default (see Recirculation (In-Unit)) is used. - **Name:** ``hot_water_distribution_recirc_branch_piping_length`` - **Type:** ``Double`` @@ -3975,7 +3975,7 @@ If the distribution system is Recirculation, the length of the recirculation bra **Hot Water Distribution: Recirculation Pump Power** -If the distribution system is Recirculation, the recirculation pump power. If not provided, the OS-HPXML default (see Recirculation (In-Unit)) is used. +If the distribution system is Recirculation, the recirculation pump power. If not provided, the OS-HPXML default (see Recirculation (In-Unit)) is used. - **Name:** ``hot_water_distribution_recirc_pump_power`` - **Type:** ``Double`` @@ -3988,7 +3988,7 @@ If the distribution system is Recirculation, the recirculation pump power. If no **Hot Water Distribution: Pipe Insulation Nominal R-Value** -Nominal R-value of the pipe insulation. If not provided, the OS-HPXML default (see HPXML Hot Water Distribution) is used. +Nominal R-value of the pipe insulation. If not provided, the OS-HPXML default (see HPXML Hot Water Distribution) is used. - **Name:** ``hot_water_distribution_pipe_r`` - **Type:** ``Double`` @@ -4060,7 +4060,7 @@ Whether the sink fixture is low flow. **Hot Water Fixtures: Usage Multiplier** -Multiplier on the hot water usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Water Fixtures) is used. +Multiplier on the hot water usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Water Fixtures) is used. - **Name:** ``water_fixtures_usage_multiplier`` - **Type:** ``Double`` @@ -4071,7 +4071,7 @@ Multiplier on the hot water usage that can reflect, e.g., high/low usage occupan **General Water Use: Usage Multiplier** -Multiplier on internal gains from general water use (floor mopping, shower evaporation, water films on showers, tubs & sinks surfaces, plant watering, etc.) that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Building Occupancy) is used. +Multiplier on internal gains from general water use (floor mopping, shower evaporation, water films on showers, tubs & sinks surfaces, plant watering, etc.) that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Building Occupancy) is used. - **Name:** ``general_water_use_usage_multiplier`` - **Type:** ``Double`` @@ -4184,7 +4184,7 @@ The collector rated thermal losses of the solar thermal system. **Solar Thermal: Storage Volume** -The storage volume of the solar thermal system. If not provided, the OS-HPXML default (see Detailed Inputs) is used. +The storage volume of the solar thermal system. If not provided, the OS-HPXML default (see Detailed Inputs) is used. - **Name:** ``solar_thermal_storage_volume`` - **Type:** ``Double`` @@ -4221,7 +4221,7 @@ Whether there is a PV system present. **PV System: Module Type** -Module type of the PV system. If not provided, the OS-HPXML default (see HPXML Photovoltaics) is used. +Module type of the PV system. If not provided, the OS-HPXML default (see HPXML Photovoltaics) is used. - **Name:** ``pv_system_module_type`` - **Type:** ``Choice`` @@ -4234,7 +4234,7 @@ Module type of the PV system. If not provided, the OS-HPXML default (see HPXML Photovoltaics) is used. +Location of the PV system. If not provided, the OS-HPXML default (see HPXML Photovoltaics) is used. - **Name:** ``pv_system_location`` - **Type:** ``Choice`` @@ -4247,7 +4247,7 @@ Location of the PV system. If not provided, the OS-HPXML default (see HPXML Photovoltaics) is used. +Type of tracking for the PV system. If not provided, the OS-HPXML default (see HPXML Photovoltaics) is used. - **Name:** ``pv_system_tracking`` - **Type:** ``Choice`` @@ -4297,7 +4297,7 @@ Maximum power output of the PV system. For a shared system, this is the total bu **PV System: Inverter Efficiency** -Inverter efficiency of the PV system. If there are two PV systems, this will apply to both. If not provided, the OS-HPXML default (see HPXML Photovoltaics) is used. +Inverter efficiency of the PV system. If there are two PV systems, this will apply to both. If not provided, the OS-HPXML default (see HPXML Photovoltaics) is used. - **Name:** ``pv_system_inverter_efficiency`` - **Type:** ``Double`` @@ -4310,7 +4310,7 @@ Inverter efficiency of the PV system. If there are two PV systems, this will app **PV System: System Losses Fraction** -System losses fraction of the PV system. If there are two PV systems, this will apply to both. If not provided, the OS-HPXML default (see HPXML Photovoltaics) is used. +System losses fraction of the PV system. If there are two PV systems, this will apply to both. If not provided, the OS-HPXML default (see HPXML Photovoltaics) is used. - **Name:** ``pv_system_system_losses_fraction`` - **Type:** ``Double`` @@ -4347,7 +4347,7 @@ Whether there is a second PV system present. **PV System 2: Module Type** -Module type of the second PV system. If not provided, the OS-HPXML default (see HPXML Photovoltaics) is used. +Module type of the second PV system. If not provided, the OS-HPXML default (see HPXML Photovoltaics) is used. - **Name:** ``pv_system_2_module_type`` - **Type:** ``Choice`` @@ -4360,7 +4360,7 @@ Module type of the second PV system. If not provided, the OS-HPXML default (see **PV System 2: Location** -Location of the second PV system. If not provided, the OS-HPXML default (see HPXML Photovoltaics) is used. +Location of the second PV system. If not provided, the OS-HPXML default (see HPXML Photovoltaics) is used. - **Name:** ``pv_system_2_location`` - **Type:** ``Choice`` @@ -4373,7 +4373,7 @@ Location of the second PV system. If not provided, the OS-HPXML default (see HPXML Photovoltaics) is used. +Type of tracking for the second PV system. If not provided, the OS-HPXML default (see HPXML Photovoltaics) is used. - **Name:** ``pv_system_2_tracking`` - **Type:** ``Choice`` @@ -4434,7 +4434,7 @@ Whether there is a lithium ion battery present. **Battery: Location** -The space type for the lithium ion battery location. If not provided, the OS-HPXML default (see HPXML Batteries) is used. +The space type for the lithium ion battery location. If not provided, the OS-HPXML default (see HPXML Batteries) is used. - **Name:** ``battery_location`` - **Type:** ``Choice`` @@ -4447,7 +4447,7 @@ The space type for the lithium ion battery location. If not provided, the OS-HPX **Battery: Rated Power Output** -The rated power output of the lithium ion battery. If not provided, the OS-HPXML default (see HPXML Batteries) is used. +The rated power output of the lithium ion battery. If not provided, the OS-HPXML default (see HPXML Batteries) is used. - **Name:** ``battery_power`` - **Type:** ``Double`` @@ -4460,7 +4460,7 @@ The rated power output of the lithium ion battery. If not provided, the OS-HPXML **Battery: Nominal Capacity** -The nominal capacity of the lithium ion battery. If not provided, the OS-HPXML default (see HPXML Batteries) is used. +The nominal capacity of the lithium ion battery. If not provided, the OS-HPXML default (see HPXML Batteries) is used. - **Name:** ``battery_capacity`` - **Type:** ``Double`` @@ -4473,7 +4473,7 @@ The nominal capacity of the lithium ion battery. If not provided, the OS-HPXML d **Battery: Usable Capacity** -The usable capacity of the lithium ion battery. If not provided, the OS-HPXML default (see HPXML Batteries) is used. +The usable capacity of the lithium ion battery. If not provided, the OS-HPXML default (see HPXML Batteries) is used. - **Name:** ``battery_usable_capacity`` - **Type:** ``Double`` @@ -4486,7 +4486,7 @@ The usable capacity of the lithium ion battery. If not provided, the OS-HPXML de **Battery: Round Trip Efficiency** -The round trip efficiency of the lithium ion battery. If not provided, the OS-HPXML default (see HPXML Batteries) is used. +The round trip efficiency of the lithium ion battery. If not provided, the OS-HPXML default (see HPXML Batteries) is used. - **Name:** ``battery_round_trip_efficiency`` - **Type:** ``Double`` @@ -4556,7 +4556,7 @@ Fraction of all lamps (interior) that are light emitting diodes. Lighting not sp **Lighting: Interior Usage Multiplier** -Multiplier on the lighting energy usage (interior) that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Lighting) is used. +Multiplier on the lighting energy usage (interior) that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Lighting) is used. - **Name:** ``lighting_interior_usage_multiplier`` - **Type:** ``Double`` @@ -4600,7 +4600,7 @@ Fraction of all lamps (exterior) that are light emitting diodes. Lighting not sp **Lighting: Exterior Usage Multiplier** -Multiplier on the lighting energy usage (exterior) that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Lighting) is used. +Multiplier on the lighting energy usage (exterior) that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Lighting) is used. - **Name:** ``lighting_exterior_usage_multiplier`` - **Type:** ``Double`` @@ -4644,7 +4644,7 @@ Fraction of all lamps (garage) that are light emitting diodes. Lighting not spec **Lighting: Garage Usage Multiplier** -Multiplier on the lighting energy usage (garage) that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Lighting) is used. +Multiplier on the lighting energy usage (garage) that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Lighting) is used. - **Name:** ``lighting_garage_usage_multiplier`` - **Type:** ``Double`` @@ -4666,7 +4666,7 @@ Whether there is holiday lighting. **Holiday Lighting: Daily Consumption** -The daily energy consumption for holiday lighting (exterior). If not provided, the OS-HPXML default (see HPXML Lighting) is used. +The daily energy consumption for holiday lighting (exterior). If not provided, the OS-HPXML default (see HPXML Lighting) is used. - **Name:** ``holiday_lighting_daily_kwh`` - **Type:** ``Double`` @@ -4679,7 +4679,7 @@ The daily energy consumption for holiday lighting (exterior). If not provided, t **Holiday Lighting: Period** -Enter a date range like 'Nov 25 - Jan 5'. If not provided, the OS-HPXML default (see HPXML Lighting) is used. +Enter a date range like 'Nov 25 - Jan 5'. If not provided, the OS-HPXML default (see HPXML Lighting) is used. - **Name:** ``holiday_lighting_period`` - **Type:** ``String`` @@ -4779,7 +4779,7 @@ Whether there is a clothes washer present. **Clothes Washer: Location** -The space type for the clothes washer location. If not provided, the OS-HPXML default (see HPXML Clothes Washer) is used. +The space type for the clothes washer location. If not provided, the OS-HPXML default (see HPXML Clothes Washer) is used. - **Name:** ``clothes_washer_location`` - **Type:** ``Choice`` @@ -4805,7 +4805,7 @@ The efficiency type of the clothes washer. **Clothes Washer: Efficiency** -The efficiency of the clothes washer. If not provided, the OS-HPXML default (see HPXML Clothes Washer) is used. +The efficiency of the clothes washer. If not provided, the OS-HPXML default (see HPXML Clothes Washer) is used. - **Name:** ``clothes_washer_efficiency`` - **Type:** ``Double`` @@ -4818,7 +4818,7 @@ The efficiency of the clothes washer. If not provided, the OS-HPXML default (see **Clothes Washer: Rated Annual Consumption** -The annual energy consumed by the clothes washer, as rated, obtained from the EnergyGuide label. This includes both the appliance electricity consumption and the energy required for water heating. If not provided, the OS-HPXML default (see HPXML Clothes Washer) is used. +The annual energy consumed by the clothes washer, as rated, obtained from the EnergyGuide label. This includes both the appliance electricity consumption and the energy required for water heating. If not provided, the OS-HPXML default (see HPXML Clothes Washer) is used. - **Name:** ``clothes_washer_rated_annual_kwh`` - **Type:** ``Double`` @@ -4831,7 +4831,7 @@ The annual energy consumed by the clothes washer, as rated, obtained from the En **Clothes Washer: Label Electric Rate** -The annual energy consumed by the clothes washer, as rated, obtained from the EnergyGuide label. This includes both the appliance electricity consumption and the energy required for water heating. If not provided, the OS-HPXML default (see HPXML Clothes Washer) is used. +The annual energy consumed by the clothes washer, as rated, obtained from the EnergyGuide label. This includes both the appliance electricity consumption and the energy required for water heating. If not provided, the OS-HPXML default (see HPXML Clothes Washer) is used. - **Name:** ``clothes_washer_label_electric_rate`` - **Type:** ``Double`` @@ -4844,7 +4844,7 @@ The annual energy consumed by the clothes washer, as rated, obtained from the En **Clothes Washer: Label Gas Rate** -The annual energy consumed by the clothes washer, as rated, obtained from the EnergyGuide label. This includes both the appliance electricity consumption and the energy required for water heating. If not provided, the OS-HPXML default (see HPXML Clothes Washer) is used. +The annual energy consumed by the clothes washer, as rated, obtained from the EnergyGuide label. This includes both the appliance electricity consumption and the energy required for water heating. If not provided, the OS-HPXML default (see HPXML Clothes Washer) is used. - **Name:** ``clothes_washer_label_gas_rate`` - **Type:** ``Double`` @@ -4857,7 +4857,7 @@ The annual energy consumed by the clothes washer, as rated, obtained from the En **Clothes Washer: Label Annual Cost with Gas DHW** -The annual cost of using the system under test conditions. Input is obtained from the EnergyGuide label. If not provided, the OS-HPXML default (see HPXML Clothes Washer) is used. +The annual cost of using the system under test conditions. Input is obtained from the EnergyGuide label. If not provided, the OS-HPXML default (see HPXML Clothes Washer) is used. - **Name:** ``clothes_washer_label_annual_gas_cost`` - **Type:** ``Double`` @@ -4870,7 +4870,7 @@ The annual cost of using the system under test conditions. Input is obtained fro **Clothes Washer: Label Usage** -The clothes washer loads per week. If not provided, the OS-HPXML default (see HPXML Clothes Washer) is used. +The clothes washer loads per week. If not provided, the OS-HPXML default (see HPXML Clothes Washer) is used. - **Name:** ``clothes_washer_label_usage`` - **Type:** ``Double`` @@ -4883,7 +4883,7 @@ The clothes washer loads per week. If not provided, the OS-HPXML default (see HPXML Clothes Washer) is used. +Volume of the washer drum. Obtained from the EnergyStar website or the manufacturer's literature. If not provided, the OS-HPXML default (see HPXML Clothes Washer) is used. - **Name:** ``clothes_washer_capacity`` - **Type:** ``Double`` @@ -4896,7 +4896,7 @@ Volume of the washer drum. Obtained from the EnergyStar website or the manufactu **Clothes Washer: Usage Multiplier** -Multiplier on the clothes washer energy and hot water usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Clothes Washer) is used. +Multiplier on the clothes washer energy and hot water usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Clothes Washer) is used. - **Name:** ``clothes_washer_usage_multiplier`` - **Type:** ``Double`` @@ -4918,7 +4918,7 @@ Whether there is a clothes dryer present. **Clothes Dryer: Location** -The space type for the clothes dryer location. If not provided, the OS-HPXML default (see HPXML Clothes Dryer) is used. +The space type for the clothes dryer location. If not provided, the OS-HPXML default (see HPXML Clothes Dryer) is used. - **Name:** ``clothes_dryer_location`` - **Type:** ``Choice`` @@ -4957,7 +4957,7 @@ The efficiency type of the clothes dryer. **Clothes Dryer: Efficiency** -The efficiency of the clothes dryer. If not provided, the OS-HPXML default (see HPXML Clothes Dryer) is used. +The efficiency of the clothes dryer. If not provided, the OS-HPXML default (see HPXML Clothes Dryer) is used. - **Name:** ``clothes_dryer_efficiency`` - **Type:** ``Double`` @@ -4970,7 +4970,7 @@ The efficiency of the clothes dryer. If not provided, the OS-HPXML default (see **Clothes Dryer: Vented Flow Rate** -The exhaust flow rate of the vented clothes dryer. If not provided, the OS-HPXML default (see HPXML Clothes Dryer) is used. +The exhaust flow rate of the vented clothes dryer. If not provided, the OS-HPXML default (see HPXML Clothes Dryer) is used. - **Name:** ``clothes_dryer_vented_flow_rate`` - **Type:** ``Double`` @@ -4983,7 +4983,7 @@ The exhaust flow rate of the vented clothes dryer. If not provided, the OS-HPXML **Clothes Dryer: Usage Multiplier** -Multiplier on the clothes dryer energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Clothes Dryer) is used. +Multiplier on the clothes dryer energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Clothes Dryer) is used. - **Name:** ``clothes_dryer_usage_multiplier`` - **Type:** ``Double`` @@ -5005,7 +5005,7 @@ Whether there is a dishwasher present. **Dishwasher: Location** -The space type for the dishwasher location. If not provided, the OS-HPXML default (see HPXML Dishwasher) is used. +The space type for the dishwasher location. If not provided, the OS-HPXML default (see HPXML Dishwasher) is used. - **Name:** ``dishwasher_location`` - **Type:** ``Choice`` @@ -5031,7 +5031,7 @@ The efficiency type of dishwasher. **Dishwasher: Efficiency** -The efficiency of the dishwasher. If not provided, the OS-HPXML default (see HPXML Dishwasher) is used. +The efficiency of the dishwasher. If not provided, the OS-HPXML default (see HPXML Dishwasher) is used. - **Name:** ``dishwasher_efficiency`` - **Type:** ``Double`` @@ -5044,7 +5044,7 @@ The efficiency of the dishwasher. If not provided, the OS-HPXML default (see HPXML Dishwasher) is used. +The label electric rate of the dishwasher. If not provided, the OS-HPXML default (see HPXML Dishwasher) is used. - **Name:** ``dishwasher_label_electric_rate`` - **Type:** ``Double`` @@ -5057,7 +5057,7 @@ The label electric rate of the dishwasher. If not provided, the OS-HPXML default **Dishwasher: Label Gas Rate** -The label gas rate of the dishwasher. If not provided, the OS-HPXML default (see HPXML Dishwasher) is used. +The label gas rate of the dishwasher. If not provided, the OS-HPXML default (see HPXML Dishwasher) is used. - **Name:** ``dishwasher_label_gas_rate`` - **Type:** ``Double`` @@ -5070,7 +5070,7 @@ The label gas rate of the dishwasher. If not provided, the OS-HPXML default (see **Dishwasher: Label Annual Gas Cost** -The label annual gas cost of the dishwasher. If not provided, the OS-HPXML default (see HPXML Dishwasher) is used. +The label annual gas cost of the dishwasher. If not provided, the OS-HPXML default (see HPXML Dishwasher) is used. - **Name:** ``dishwasher_label_annual_gas_cost`` - **Type:** ``Double`` @@ -5083,7 +5083,7 @@ The label annual gas cost of the dishwasher. If not provided, the OS-HPXML defau **Dishwasher: Label Usage** -The dishwasher loads per week. If not provided, the OS-HPXML default (see HPXML Dishwasher) is used. +The dishwasher loads per week. If not provided, the OS-HPXML default (see HPXML Dishwasher) is used. - **Name:** ``dishwasher_label_usage`` - **Type:** ``Double`` @@ -5096,7 +5096,7 @@ The dishwasher loads per week. If not provided, the OS-HPXML default (see HPXML Dishwasher) is used. +The number of place settings for the unit. Data obtained from manufacturer's literature. If not provided, the OS-HPXML default (see HPXML Dishwasher) is used. - **Name:** ``dishwasher_place_setting_capacity`` - **Type:** ``Integer`` @@ -5109,7 +5109,7 @@ The number of place settings for the unit. Data obtained from manufacturer's lit **Dishwasher: Usage Multiplier** -Multiplier on the dishwasher energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Dishwasher) is used. +Multiplier on the dishwasher energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Dishwasher) is used. - **Name:** ``dishwasher_usage_multiplier`` - **Type:** ``Double`` @@ -5131,7 +5131,7 @@ Whether there is a refrigerator present. **Refrigerator: Location** -The space type for the refrigerator location. If not provided, the OS-HPXML default (see HPXML Refrigerators) is used. +The space type for the refrigerator location. If not provided, the OS-HPXML default (see HPXML Refrigerators) is used. - **Name:** ``refrigerator_location`` - **Type:** ``Choice`` @@ -5144,7 +5144,7 @@ The space type for the refrigerator location. If not provided, the OS-HPXML defa **Refrigerator: Rated Annual Consumption** -The EnergyGuide rated annual energy consumption for a refrigerator. If not provided, the OS-HPXML default (see HPXML Refrigerators) is used. +The EnergyGuide rated annual energy consumption for a refrigerator. If not provided, the OS-HPXML default (see HPXML Refrigerators) is used. - **Name:** ``refrigerator_rated_annual_kwh`` - **Type:** ``Double`` @@ -5157,7 +5157,7 @@ The EnergyGuide rated annual energy consumption for a refrigerator. If not provi **Refrigerator: Usage Multiplier** -Multiplier on the refrigerator energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Refrigerators) is used. +Multiplier on the refrigerator energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Refrigerators) is used. - **Name:** ``refrigerator_usage_multiplier`` - **Type:** ``Double`` @@ -5179,7 +5179,7 @@ Whether there is an extra refrigerator present. **Extra Refrigerator: Location** -The space type for the extra refrigerator location. If not provided, the OS-HPXML default (see HPXML Refrigerators) is used. +The space type for the extra refrigerator location. If not provided, the OS-HPXML default (see HPXML Refrigerators) is used. - **Name:** ``extra_refrigerator_location`` - **Type:** ``Choice`` @@ -5192,7 +5192,7 @@ The space type for the extra refrigerator location. If not provided, the OS-HPXM **Extra Refrigerator: Rated Annual Consumption** -The EnergyGuide rated annual energy consumption for an extra refrigerator. If not provided, the OS-HPXML default (see HPXML Refrigerators) is used. +The EnergyGuide rated annual energy consumption for an extra refrigerator. If not provided, the OS-HPXML default (see HPXML Refrigerators) is used. - **Name:** ``extra_refrigerator_rated_annual_kwh`` - **Type:** ``Double`` @@ -5205,7 +5205,7 @@ The EnergyGuide rated annual energy consumption for an extra refrigerator. If no **Extra Refrigerator: Usage Multiplier** -Multiplier on the extra refrigerator energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Refrigerators) is used. +Multiplier on the extra refrigerator energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Refrigerators) is used. - **Name:** ``extra_refrigerator_usage_multiplier`` - **Type:** ``Double`` @@ -5227,7 +5227,7 @@ Whether there is a freezer present. **Freezer: Location** -The space type for the freezer location. If not provided, the OS-HPXML default (see HPXML Freezers) is used. +The space type for the freezer location. If not provided, the OS-HPXML default (see HPXML Freezers) is used. - **Name:** ``freezer_location`` - **Type:** ``Choice`` @@ -5240,7 +5240,7 @@ The space type for the freezer location. If not provided, the OS-HPXML default ( **Freezer: Rated Annual Consumption** -The EnergyGuide rated annual energy consumption for a freezer. If not provided, the OS-HPXML default (see HPXML Freezers) is used. +The EnergyGuide rated annual energy consumption for a freezer. If not provided, the OS-HPXML default (see HPXML Freezers) is used. - **Name:** ``freezer_rated_annual_kwh`` - **Type:** ``Double`` @@ -5253,7 +5253,7 @@ The EnergyGuide rated annual energy consumption for a freezer. If not provided, **Freezer: Usage Multiplier** -Multiplier on the freezer energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Freezers) is used. +Multiplier on the freezer energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Freezers) is used. - **Name:** ``freezer_usage_multiplier`` - **Type:** ``Double`` @@ -5275,7 +5275,7 @@ Whether there is a cooking range/oven present. **Cooking Range/Oven: Location** -The space type for the cooking range/oven location. If not provided, the OS-HPXML default (see HPXML Cooking Range/Oven) is used. +The space type for the cooking range/oven location. If not provided, the OS-HPXML default (see HPXML Cooking Range/Oven) is used. - **Name:** ``cooking_range_oven_location`` - **Type:** ``Choice`` @@ -5301,7 +5301,7 @@ Type of fuel used by the cooking range/oven. **Cooking Range/Oven: Is Induction** -Whether the cooking range is induction. If not provided, the OS-HPXML default (see HPXML Cooking Range/Oven) is used. +Whether the cooking range is induction. If not provided, the OS-HPXML default (see HPXML Cooking Range/Oven) is used. - **Name:** ``cooking_range_oven_is_induction`` - **Type:** ``Boolean`` @@ -5312,7 +5312,7 @@ Whether the cooking range is induction. If not provided, the OS-HPXML default (s **Cooking Range/Oven: Is Convection** -Whether the oven is convection. If not provided, the OS-HPXML default (see HPXML Cooking Range/Oven) is used. +Whether the oven is convection. If not provided, the OS-HPXML default (see HPXML Cooking Range/Oven) is used. - **Name:** ``cooking_range_oven_is_convection`` - **Type:** ``Boolean`` @@ -5323,7 +5323,7 @@ Whether the oven is convection. If not provided, the OS-HPXML default (see HPXML Cooking Range/Oven) is used. +Multiplier on the cooking range/oven energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Cooking Range/Oven) is used. - **Name:** ``cooking_range_oven_usage_multiplier`` - **Type:** ``Double`` @@ -5345,7 +5345,7 @@ Whether there are any ceiling fans. **Ceiling Fan: Label Energy Use** -The label average energy use of the ceiling fan(s). If neither Efficiency nor Label Energy Use provided, the OS-HPXML default (see HPXML Ceiling Fans) is used. +The label average energy use of the ceiling fan(s). If neither Efficiency nor Label Energy Use provided, the OS-HPXML default (see HPXML Ceiling Fans) is used. - **Name:** ``ceiling_fan_label_energy_use`` - **Type:** ``Double`` @@ -5358,7 +5358,7 @@ The label average energy use of the ceiling fan(s). If neither Efficiency nor La **Ceiling Fan: Efficiency** -The efficiency rating of the ceiling fan(s) at medium speed. Only used if Label Energy Use not provided. If neither Efficiency nor Label Energy Use provided, the OS-HPXML default (see HPXML Ceiling Fans) is used. +The efficiency rating of the ceiling fan(s) at medium speed. Only used if Label Energy Use not provided. If neither Efficiency nor Label Energy Use provided, the OS-HPXML default (see HPXML Ceiling Fans) is used. - **Name:** ``ceiling_fan_efficiency`` - **Type:** ``Double`` @@ -5371,7 +5371,7 @@ The efficiency rating of the ceiling fan(s) at medium speed. Only used if Label **Ceiling Fan: Quantity** -Total number of ceiling fans. If not provided, the OS-HPXML default (see HPXML Ceiling Fans) is used. +Total number of ceiling fans. If not provided, the OS-HPXML default (see HPXML Ceiling Fans) is used. - **Name:** ``ceiling_fan_quantity`` - **Type:** ``Integer`` @@ -5384,7 +5384,7 @@ Total number of ceiling fans. If not provided, the OS-HPXML default (see HPXML Ceiling Fans) is used. +The cooling setpoint temperature offset during months when the ceiling fans are operating. Only applies if ceiling fan quantity is greater than zero. If not provided, the OS-HPXML default (see HPXML Ceiling Fans) is used. - **Name:** ``ceiling_fan_cooling_setpoint_temp_offset`` - **Type:** ``Double`` @@ -5408,7 +5408,7 @@ Whether there are televisions. **Misc Plug Loads: Television Annual kWh** -The annual energy consumption of the television plug loads. If not provided, the OS-HPXML default (see HPXML Plug Loads) is used. +The annual energy consumption of the television plug loads. If not provided, the OS-HPXML default (see HPXML Plug Loads) is used. - **Name:** ``misc_plug_loads_television_annual_kwh`` - **Type:** ``Double`` @@ -5421,7 +5421,7 @@ The annual energy consumption of the television plug loads. If not provided, the **Misc Plug Loads: Television Usage Multiplier** -Multiplier on the television energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Plug Loads) is used. +Multiplier on the television energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Plug Loads) is used. - **Name:** ``misc_plug_loads_television_usage_multiplier`` - **Type:** ``Double`` @@ -5432,7 +5432,7 @@ Multiplier on the television energy usage that can reflect, e.g., high/low usage **Misc Plug Loads: Other Annual kWh** -The annual energy consumption of the other residual plug loads. If not provided, the OS-HPXML default (see HPXML Plug Loads) is used. +The annual energy consumption of the other residual plug loads. If not provided, the OS-HPXML default (see HPXML Plug Loads) is used. - **Name:** ``misc_plug_loads_other_annual_kwh`` - **Type:** ``Double`` @@ -5445,7 +5445,7 @@ The annual energy consumption of the other residual plug loads. If not provided, **Misc Plug Loads: Other Sensible Fraction** -Fraction of other residual plug loads' internal gains that are sensible. If not provided, the OS-HPXML default (see HPXML Plug Loads) is used. +Fraction of other residual plug loads' internal gains that are sensible. If not provided, the OS-HPXML default (see HPXML Plug Loads) is used. - **Name:** ``misc_plug_loads_other_frac_sensible`` - **Type:** ``Double`` @@ -5458,7 +5458,7 @@ Fraction of other residual plug loads' internal gains that are sensible. If not **Misc Plug Loads: Other Latent Fraction** -Fraction of other residual plug loads' internal gains that are latent. If not provided, the OS-HPXML default (see HPXML Plug Loads) is used. +Fraction of other residual plug loads' internal gains that are latent. If not provided, the OS-HPXML default (see HPXML Plug Loads) is used. - **Name:** ``misc_plug_loads_other_frac_latent`` - **Type:** ``Double`` @@ -5471,7 +5471,7 @@ Fraction of other residual plug loads' internal gains that are latent. If not pr **Misc Plug Loads: Other Usage Multiplier** -Multiplier on the other energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Plug Loads) is used. +Multiplier on the other energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Plug Loads) is used. - **Name:** ``misc_plug_loads_other_usage_multiplier`` - **Type:** ``Double`` @@ -5493,7 +5493,7 @@ Whether there is a well pump. **Misc Plug Loads: Well Pump Annual kWh** -The annual energy consumption of the well pump plug loads. If not provided, the OS-HPXML default (see HPXML Plug Loads) is used. +The annual energy consumption of the well pump plug loads. If not provided, the OS-HPXML default (see HPXML Plug Loads) is used. - **Name:** ``misc_plug_loads_well_pump_annual_kwh`` - **Type:** ``Double`` @@ -5506,7 +5506,7 @@ The annual energy consumption of the well pump plug loads. If not provided, the **Misc Plug Loads: Well Pump Usage Multiplier** -Multiplier on the well pump energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Plug Loads) is used. +Multiplier on the well pump energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Plug Loads) is used. - **Name:** ``misc_plug_loads_well_pump_usage_multiplier`` - **Type:** ``Double`` @@ -5528,7 +5528,7 @@ Whether there is an electric vehicle. **Misc Plug Loads: Vehicle Annual kWh** -The annual energy consumption of the electric vehicle plug loads. If not provided, the OS-HPXML default (see HPXML Plug Loads) is used. +The annual energy consumption of the electric vehicle plug loads. If not provided, the OS-HPXML default (see HPXML Plug Loads) is used. - **Name:** ``misc_plug_loads_vehicle_annual_kwh`` - **Type:** ``Double`` @@ -5541,7 +5541,7 @@ The annual energy consumption of the electric vehicle plug loads. If not provide **Misc Plug Loads: Vehicle Usage Multiplier** -Multiplier on the electric vehicle energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Plug Loads) is used. +Multiplier on the electric vehicle energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Plug Loads) is used. - **Name:** ``misc_plug_loads_vehicle_usage_multiplier`` - **Type:** ``Double`` @@ -5576,7 +5576,7 @@ The fuel type of the fuel loads grill. **Misc Fuel Loads: Grill Annual therm** -The annual energy consumption of the fuel loads grill. If not provided, the OS-HPXML default (see HPXML Fuel Loads) is used. +The annual energy consumption of the fuel loads grill. If not provided, the OS-HPXML default (see HPXML Fuel Loads) is used. - **Name:** ``misc_fuel_loads_grill_annual_therm`` - **Type:** ``Double`` @@ -5589,7 +5589,7 @@ The annual energy consumption of the fuel loads grill. If not provided, the OS-H **Misc Fuel Loads: Grill Usage Multiplier** -Multiplier on the fuel loads grill energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Fuel Loads) is used. +Multiplier on the fuel loads grill energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Fuel Loads) is used. - **Name:** ``misc_fuel_loads_grill_usage_multiplier`` - **Type:** ``Double`` @@ -5624,7 +5624,7 @@ The fuel type of the fuel loads lighting. **Misc Fuel Loads: Lighting Annual therm** -The annual energy consumption of the fuel loads lighting. If not provided, the OS-HPXML default (see HPXML Fuel Loads)is used. +The annual energy consumption of the fuel loads lighting. If not provided, the OS-HPXML default (see HPXML Fuel Loads)is used. - **Name:** ``misc_fuel_loads_lighting_annual_therm`` - **Type:** ``Double`` @@ -5637,7 +5637,7 @@ The annual energy consumption of the fuel loads lighting. If not provided, the O **Misc Fuel Loads: Lighting Usage Multiplier** -Multiplier on the fuel loads lighting energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Fuel Loads) is used. +Multiplier on the fuel loads lighting energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Fuel Loads) is used. - **Name:** ``misc_fuel_loads_lighting_usage_multiplier`` - **Type:** ``Double`` @@ -5672,7 +5672,7 @@ The fuel type of the fuel loads fireplace. **Misc Fuel Loads: Fireplace Annual therm** -The annual energy consumption of the fuel loads fireplace. If not provided, the OS-HPXML default (see HPXML Fuel Loads) is used. +The annual energy consumption of the fuel loads fireplace. If not provided, the OS-HPXML default (see HPXML Fuel Loads) is used. - **Name:** ``misc_fuel_loads_fireplace_annual_therm`` - **Type:** ``Double`` @@ -5685,7 +5685,7 @@ The annual energy consumption of the fuel loads fireplace. If not provided, the **Misc Fuel Loads: Fireplace Sensible Fraction** -Fraction of fireplace residual fuel loads' internal gains that are sensible. If not provided, the OS-HPXML default (see HPXML Fuel Loads) is used. +Fraction of fireplace residual fuel loads' internal gains that are sensible. If not provided, the OS-HPXML default (see HPXML Fuel Loads) is used. - **Name:** ``misc_fuel_loads_fireplace_frac_sensible`` - **Type:** ``Double`` @@ -5698,7 +5698,7 @@ Fraction of fireplace residual fuel loads' internal gains that are sensible. If **Misc Fuel Loads: Fireplace Latent Fraction** -Fraction of fireplace residual fuel loads' internal gains that are latent. If not provided, the OS-HPXML default (see HPXML Fuel Loads) is used. +Fraction of fireplace residual fuel loads' internal gains that are latent. If not provided, the OS-HPXML default (see HPXML Fuel Loads) is used. - **Name:** ``misc_fuel_loads_fireplace_frac_latent`` - **Type:** ``Double`` @@ -5711,7 +5711,7 @@ Fraction of fireplace residual fuel loads' internal gains that are latent. If no **Misc Fuel Loads: Fireplace Usage Multiplier** -Multiplier on the fuel loads fireplace energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Fuel Loads) is used. +Multiplier on the fuel loads fireplace energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see HPXML Fuel Loads) is used. - **Name:** ``misc_fuel_loads_fireplace_usage_multiplier`` - **Type:** ``Double`` @@ -5733,7 +5733,7 @@ Whether there is a pool. **Pool: Pump Annual kWh** -The annual energy consumption of the pool pump. If not provided, the OS-HPXML default (see Pool Pump) is used. +The annual energy consumption of the pool pump. If not provided, the OS-HPXML default (see Pool Pump) is used. - **Name:** ``pool_pump_annual_kwh`` - **Type:** ``Double`` @@ -5746,7 +5746,7 @@ The annual energy consumption of the pool pump. If not provided, the OS-HPXML de **Pool: Pump Usage Multiplier** -Multiplier on the pool pump energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see Pool Pump) is used. +Multiplier on the pool pump energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see Pool Pump) is used. - **Name:** ``pool_pump_usage_multiplier`` - **Type:** ``Double`` @@ -5770,7 +5770,7 @@ The type of pool heater. Use 'none' if there is no pool heater. **Pool: Heater Annual kWh** -The annual energy consumption of the electric resistance pool heater. If not provided, the OS-HPXML default (see Pool Heater) is used. +The annual energy consumption of the electric resistance pool heater. If not provided, the OS-HPXML default (see Pool Heater) is used. - **Name:** ``pool_heater_annual_kwh`` - **Type:** ``Double`` @@ -5783,7 +5783,7 @@ The annual energy consumption of the electric resistance pool heater. If not pro **Pool: Heater Annual therm** -The annual energy consumption of the gas fired pool heater. If not provided, the OS-HPXML default (see Pool Heater) is used. +The annual energy consumption of the gas fired pool heater. If not provided, the OS-HPXML default (see Pool Heater) is used. - **Name:** ``pool_heater_annual_therm`` - **Type:** ``Double`` @@ -5796,7 +5796,7 @@ The annual energy consumption of the gas fired pool heater. If not provided, the **Pool: Heater Usage Multiplier** -Multiplier on the pool heater energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see Pool Heater) is used. +Multiplier on the pool heater energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see Pool Heater) is used. - **Name:** ``pool_heater_usage_multiplier`` - **Type:** ``Double`` @@ -5818,7 +5818,7 @@ Whether there is a permanent spa. **Permanent Spa: Pump Annual kWh** -The annual energy consumption of the permanent spa pump. If not provided, the OS-HPXML default (see Permanent Spa Pump) is used. +The annual energy consumption of the permanent spa pump. If not provided, the OS-HPXML default (see Permanent Spa Pump) is used. - **Name:** ``permanent_spa_pump_annual_kwh`` - **Type:** ``Double`` @@ -5831,7 +5831,7 @@ The annual energy consumption of the permanent spa pump. If not provided, the OS **Permanent Spa: Pump Usage Multiplier** -Multiplier on the permanent spa pump energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see Permanent Spa Pump) is used. +Multiplier on the permanent spa pump energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see Permanent Spa Pump) is used. - **Name:** ``permanent_spa_pump_usage_multiplier`` - **Type:** ``Double`` @@ -5855,7 +5855,7 @@ The type of permanent spa heater. Use 'none' if there is no permanent spa heater **Permanent Spa: Heater Annual kWh** -The annual energy consumption of the electric resistance permanent spa heater. If not provided, the OS-HPXML default (see Permanent Spa Heater) is used. +The annual energy consumption of the electric resistance permanent spa heater. If not provided, the OS-HPXML default (see Permanent Spa Heater) is used. - **Name:** ``permanent_spa_heater_annual_kwh`` - **Type:** ``Double`` @@ -5868,7 +5868,7 @@ The annual energy consumption of the electric resistance permanent spa heater. I **Permanent Spa: Heater Annual therm** -The annual energy consumption of the gas fired permanent spa heater. If not provided, the OS-HPXML default (see Permanent Spa Heater) is used. +The annual energy consumption of the gas fired permanent spa heater. If not provided, the OS-HPXML default (see Permanent Spa Heater) is used. - **Name:** ``permanent_spa_heater_annual_therm`` - **Type:** ``Double`` @@ -5881,7 +5881,7 @@ The annual energy consumption of the gas fired permanent spa heater. If not prov **Permanent Spa: Heater Usage Multiplier** -Multiplier on the permanent spa heater energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see Permanent Spa Heater) is used. +Multiplier on the permanent spa heater energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see Permanent Spa Heater) is used. - **Name:** ``permanent_spa_heater_usage_multiplier`` - **Type:** ``Double`` diff --git a/resources/hpxml-measures/BuildResidentialHPXML/measure.rb b/resources/hpxml-measures/BuildResidentialHPXML/measure.rb index bd3faca4f7..b45579f0c6 100644 --- a/resources/hpxml-measures/BuildResidentialHPXML/measure.rb +++ b/resources/hpxml-measures/BuildResidentialHPXML/measure.rb @@ -343,7 +343,7 @@ def arguments(model) # rubocop:disable Lint/UnusedMethodArgument arg = OpenStudio::Measure::OSArgument::makeDoubleArgument('geometry_unit_num_occupants', false) arg.setDisplayName('Geometry: Unit Number of Occupants') arg.setUnits('#') - arg.setDescription('The number of occupants in the unit. If not provided, an *asset* calculation is performed assuming standard occupancy, in which various end use defaults (e.g., plug loads, appliances, and hot water usage) are calculated based on Number of Bedrooms and Conditioned Floor Area per ANSI/RESNET/ICC 301-2019. If provided, an *operational* calculation is instead performed in which the end use defaults are adjusted using the relationship between Number of Bedrooms and Number of Occupants from RECS 2015.') + arg.setDescription('The number of occupants in the unit. If not provided, an *asset* calculation is performed assuming standard occupancy, in which various end use defaults (e.g., plug loads, appliances, and hot water usage) are calculated based on Number of Bedrooms and Conditioned Floor Area per ANSI/RESNET/ICC 301. If provided, an *operational* calculation is instead performed in which the end use defaults to reflect real-world data (where possible).') args << arg arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('geometry_building_num_units', false) @@ -4082,13 +4082,14 @@ def self.create_geometry_envelope(runner, model, args) return false end - if args[:geometry_unit_type] == HPXML::ResidentialTypeSFD + case args[:geometry_unit_type] + when HPXML::ResidentialTypeSFD success = Geometry.create_single_family_detached(runner: runner, model: model, **args) - elsif args[:geometry_unit_type] == HPXML::ResidentialTypeSFA + when HPXML::ResidentialTypeSFA success = Geometry.create_single_family_attached(model: model, **args) - elsif args[:geometry_unit_type] == HPXML::ResidentialTypeApartment + when HPXML::ResidentialTypeApartment success = Geometry.create_apartment(model: model, **args) - elsif args[:geometry_unit_type] == HPXML::ResidentialTypeManufactured + when HPXML::ResidentialTypeManufactured success = Geometry.create_single_family_detached(runner: runner, model: model, **args) end return false if not success @@ -4613,7 +4614,8 @@ def self.set_site(hpxml_bldg, args) adb_walls = [args[:geometry_unit_left_wall_is_adiabatic], args[:geometry_unit_right_wall_is_adiabatic], args[:geometry_unit_front_wall_is_adiabatic], args[:geometry_unit_back_wall_is_adiabatic]] n_walls_attached = adb_walls.count(true) - if [HPXML::ResidentialTypeSFA, HPXML::ResidentialTypeApartment].include? args[:geometry_unit_type] + case args[:geometry_unit_type] + when HPXML::ResidentialTypeSFA, HPXML::ResidentialTypeApartment if n_walls_attached == 3 hpxml_bldg.site.surroundings = HPXML::SurroundingsThreeSides elsif n_walls_attached == 2 @@ -4636,7 +4638,7 @@ def self.set_site(hpxml_bldg, args) hpxml_bldg.site.vertical_surroundings = HPXML::VerticalSurroundingsNoAboveOrBelow end end - elsif [HPXML::ResidentialTypeSFD, HPXML::ResidentialTypeManufactured].include? args[:geometry_unit_type] + when HPXML::ResidentialTypeSFD, HPXML::ResidentialTypeManufactured hpxml_bldg.site.surroundings = HPXML::SurroundingsStandAlone hpxml_bldg.site.vertical_surroundings = HPXML::VerticalSurroundingsNoAboveOrBelow end @@ -5178,9 +5180,10 @@ def self.set_floors(hpxml_bldg, args, sorted_surfaces) @surface_ids[surface.name.to_s] = hpxml_bldg.floors[-1].id if hpxml_bldg.floors[-1].is_thermal_boundary - if [HPXML::LocationAtticUnvented, HPXML::LocationAtticVented].include? exterior_adjacent_to + case exterior_adjacent_to + when HPXML::LocationAtticUnvented, HPXML::LocationAtticVented hpxml_bldg.floors[-1].insulation_assembly_r_value = args[:ceiling_assembly_r] - elsif [HPXML::LocationGarage].include? exterior_adjacent_to + when HPXML::LocationGarage hpxml_bldg.floors[-1].insulation_assembly_r_value = args[:floor_over_garage_assembly_r] else hpxml_bldg.floors[-1].insulation_assembly_r_value = args[:floor_over_foundation_assembly_r] @@ -5229,11 +5232,7 @@ def self.set_slabs(hpxml_bldg, model, args, sorted_surfaces) exposed_perimeter = Geometry.calculate_exposed_perimeter(model: model, ground_floor_surfaces: [surface], has_foundation_walls: has_foundation_walls).round(1) next if exposed_perimeter == 0 - if [HPXML::LocationCrawlspaceVented, - HPXML::LocationCrawlspaceUnvented, - HPXML::LocationCrawlspaceConditioned, - HPXML::LocationBasementUnconditioned, - HPXML::LocationBasementConditioned].include? interior_adjacent_to + if has_foundation_walls exposed_perimeter -= Geometry.get_unexposed_garage_perimeter(**args) end @@ -5627,13 +5626,14 @@ def self.set_cooling_systems(hpxml_bldg, args) end if cooling_system_type != HPXML::HVACTypeEvaporativeCooler - if args[:cooling_system_cooling_efficiency_type] == HPXML::UnitsSEER + case args[:cooling_system_cooling_efficiency_type] + when HPXML::UnitsSEER cooling_efficiency_seer = args[:cooling_system_cooling_efficiency] - elsif args[:cooling_system_cooling_efficiency_type] == HPXML::UnitsSEER2 + when HPXML::UnitsSEER2 cooling_efficiency_seer2 = args[:cooling_system_cooling_efficiency] - elsif args[:cooling_system_cooling_efficiency_type] == HPXML::UnitsEER + when HPXML::UnitsEER cooling_efficiency_eer = args[:cooling_system_cooling_efficiency] - elsif args[:cooling_system_cooling_efficiency_type] == HPXML::UnitsCEER + when HPXML::UnitsCEER cooling_efficiency_ceer = args[:cooling_system_cooling_efficiency] end end @@ -5695,10 +5695,11 @@ def self.set_cooling_systems(hpxml_bldg, args) cooling_perf_data_data_points.each do |cooling_perf_data_data_point| outdoor_temperature, min_speed_cap_or_frac, max_speed_cap_or_frac, min_speed_cop, max_speed_cop = cooling_perf_data_data_point - if hvac_perf_data_capacity_type == 'Absolute capacities' + case hvac_perf_data_capacity_type + when 'Absolute capacities' min_speed_capacity = Float(min_speed_cap_or_frac) max_speed_capacity = Float(max_speed_cap_or_frac) - elsif hvac_perf_data_capacity_type == 'Normalized capacity fractions' + when 'Normalized capacity fractions' min_speed_capacity_fraction_of_nominal = Float(min_speed_cap_or_frac) max_speed_capacity_fraction_of_nominal = Float(max_speed_cap_or_frac) end @@ -5737,7 +5738,8 @@ def self.set_heat_pumps(hpxml_bldg, args) return if heat_pump_type == Constants::None - if args[:heat_pump_backup_type] == HPXML::HeatPumpBackupTypeIntegrated + case args[:heat_pump_backup_type] + when HPXML::HeatPumpBackupTypeIntegrated backup_type = args[:heat_pump_backup_type] backup_heating_fuel = args[:heat_pump_backup_fuel] backup_heating_capacity = args[:heat_pump_backup_heating_capacity] @@ -5747,7 +5749,7 @@ def self.set_heat_pumps(hpxml_bldg, args) else backup_heating_efficiency_afue = args[:heat_pump_backup_heating_efficiency] end - elsif args[:heat_pump_backup_type] == HPXML::HeatPumpBackupTypeSeparate + when HPXML::HeatPumpBackupTypeSeparate if args[:heating_system_2_type] == Constants::None fail "Heat pump backup type specified as '#{args[:heat_pump_backup_type]}' but no heating system provided." end @@ -5769,19 +5771,21 @@ def self.set_heat_pumps(hpxml_bldg, args) compressor_type = args[:heat_pump_cooling_compressor_type] end - if args[:heat_pump_heating_efficiency_type] == HPXML::UnitsHSPF + case args[:heat_pump_heating_efficiency_type] + when HPXML::UnitsHSPF heating_efficiency_hspf = args[:heat_pump_heating_efficiency] - elsif args[:heat_pump_heating_efficiency_type] == HPXML::UnitsHSPF2 + when HPXML::UnitsHSPF2 heating_efficiency_hspf2 = args[:heat_pump_heating_efficiency] - elsif args[:heat_pump_heating_efficiency_type] == HPXML::UnitsCOP + when HPXML::UnitsCOP heating_efficiency_cop = args[:heat_pump_heating_efficiency] end - if args[:heat_pump_cooling_efficiency_type] == HPXML::UnitsSEER + case args[:heat_pump_cooling_efficiency_type] + when HPXML::UnitsSEER cooling_efficiency_seer = args[:heat_pump_cooling_efficiency] - elsif args[:heat_pump_cooling_efficiency_type] == HPXML::UnitsSEER2 + when HPXML::UnitsSEER2 cooling_efficiency_seer2 = args[:heat_pump_cooling_efficiency] - elsif args[:heat_pump_cooling_efficiency_type] == HPXML::UnitsEER + when HPXML::UnitsEER cooling_efficiency_eer = args[:heat_pump_cooling_efficiency] end @@ -5848,10 +5852,11 @@ def self.set_heat_pumps(hpxml_bldg, args) heating_perf_data_data_points.each do |heating_perf_data_data_point| outdoor_temperature, min_speed_cap_or_frac, max_speed_cap_or_frac, min_speed_cop, max_speed_cop = heating_perf_data_data_point - if hvac_perf_data_capacity_type == 'Absolute capacities' + case hvac_perf_data_capacity_type + when 'Absolute capacities' min_speed_capacity = Float(min_speed_cap_or_frac) max_speed_capacity = Float(max_speed_cap_or_frac) - elsif hvac_perf_data_capacity_type == 'Normalized capacity fractions' + when 'Normalized capacity fractions' min_speed_capacity_fraction_of_nominal = Float(min_speed_cap_or_frac) max_speed_capacity_fraction_of_nominal = Float(max_speed_cap_or_frac) end @@ -5885,10 +5890,11 @@ def self.set_heat_pumps(hpxml_bldg, args) cooling_perf_data_data_points.each do |cooling_perf_data_data_point| outdoor_temperature, min_speed_cap_or_frac, max_speed_cap_or_frac, min_speed_cop, max_speed_cop = cooling_perf_data_data_point - if hvac_perf_data_capacity_type == 'Absolute capacities' + case hvac_perf_data_capacity_type + when 'Absolute capacities' min_speed_capacity = Float(min_speed_cap_or_frac) max_speed_capacity = Float(max_speed_cap_or_frac) - elsif hvac_perf_data_capacity_type == 'Normalized capacity fractions' + when 'Normalized capacity fractions' min_speed_capacity_fraction_of_nominal = Float(min_speed_cap_or_frac) max_speed_capacity_fraction_of_nominal = Float(max_speed_cap_or_frac) end @@ -5926,12 +5932,12 @@ def self.set_geothermal_loop(hpxml_bldg, args) return if args[:geothermal_loop_configuration].nil? || args[:geothermal_loop_configuration] == Constants::None if not args[:geothermal_loop_pipe_diameter].nil? - pipe_diameter = args[:geothermal_loop_pipe_diameter] - if pipe_diameter == '3/4" pipe' + case args[:geothermal_loop_pipe_diameter] + when '3/4" pipe' pipe_diameter = 0.75 - elsif pipe_diameter == '1" pipe' + when '1" pipe' pipe_diameter = 1.0 - elsif pipe_diameter == '1-1/4" pipe' + when '1-1/4" pipe' pipe_diameter = 1.25 end end @@ -6018,24 +6024,25 @@ def self.set_hvac_distribution(hpxml_bldg, args) # AirDistribution? air_distribution_systems = [] hpxml_bldg.heating_systems.each do |heating_system| - if [HPXML::HVACTypeFurnace].include?(heating_system.heating_system_type) + case heating_system.heating_system_type + when HPXML::HVACTypeFurnace air_distribution_systems << heating_system end end hpxml_bldg.cooling_systems.each do |cooling_system| - if [HPXML::HVACTypeCentralAirConditioner].include?(cooling_system.cooling_system_type) - air_distribution_systems << cooling_system - elsif [HPXML::HVACTypeEvaporativeCooler, HPXML::HVACTypeMiniSplitAirConditioner].include?(cooling_system.cooling_system_type) && args[:cooling_system_is_ducted] + case cooling_system.cooling_system_type + when HPXML::HVACTypeCentralAirConditioner air_distribution_systems << cooling_system + when HPXML::HVACTypeEvaporativeCooler, HPXML::HVACTypeMiniSplitAirConditioner + air_distribution_systems << cooling_system if args[:cooling_system_is_ducted] end end hpxml_bldg.heat_pumps.each do |heat_pump| - if [HPXML::HVACTypeHeatPumpAirToAir, HPXML::HVACTypeHeatPumpGroundToAir].include? heat_pump.heat_pump_type + case heat_pump.heat_pump_type + when HPXML::HVACTypeHeatPumpAirToAir, HPXML::HVACTypeHeatPumpGroundToAir air_distribution_systems << heat_pump - elsif [HPXML::HVACTypeHeatPumpMiniSplit].include?(heat_pump.heat_pump_type) - if args[:heat_pump_is_ducted] - air_distribution_systems << heat_pump if args[:heat_pump_is_ducted] - end + when HPXML::HVACTypeHeatPumpMiniSplit + air_distribution_systems << heat_pump if args[:heat_pump_is_ducted] end end @@ -6089,7 +6096,8 @@ def self.set_hvac_distribution(hpxml_bldg, args) def self.set_hvac_blower(hpxml_bldg, args) # Blower fan W/cfm hpxml_bldg.hvac_systems.each do |hvac_system| - next unless (!hvac_system.distribution_system.nil? && hvac_system.distribution_system.distribution_system_type == HPXML::HVACDistributionTypeAir) || (hvac_system.is_a?(HPXML::HeatPump) && [HPXML::HVACTypeHeatPumpMiniSplit].include?(hvac_system.heat_pump_type)) + next unless (!hvac_system.distribution_system.nil? && hvac_system.distribution_system.distribution_system_type == HPXML::HVACDistributionTypeAir) || + (hvac_system.is_a?(HPXML::HeatPump) && hvac_system.heat_pump_type == HPXML::HVACTypeHeatPumpMiniSplit) fan_watts_per_cfm = args[:hvac_blower_fan_watts_per_cfm] @@ -6098,11 +6106,14 @@ def self.set_hvac_blower(hpxml_bldg, args) hvac_system.fan_watts_per_cfm = fan_watts_per_cfm end elsif hvac_system.is_a?(HPXML::CoolingSystem) - if [HPXML::HVACTypeCentralAirConditioner, HPXML::HVACTypeMiniSplitAirConditioner].include?(hvac_system.cooling_system_type) + if [HPXML::HVACTypeCentralAirConditioner, + HPXML::HVACTypeMiniSplitAirConditioner].include?(hvac_system.cooling_system_type) hvac_system.fan_watts_per_cfm = fan_watts_per_cfm end elsif hvac_system.is_a?(HPXML::HeatPump) - if [HPXML::HVACTypeHeatPumpAirToAir, HPXML::HVACTypeHeatPumpMiniSplit, HPXML::HVACTypeHeatPumpGroundToAir].include?(hvac_system.heat_pump_type) + if [HPXML::HVACTypeHeatPumpAirToAir, + HPXML::HVACTypeHeatPumpMiniSplit, + HPXML::HVACTypeHeatPumpGroundToAir].include?(hvac_system.heat_pump_type) hvac_system.fan_watts_per_cfm = fan_watts_per_cfm end end @@ -6138,21 +6149,23 @@ def self.get_location(location, foundation_type, attic_type) return if location.nil? if location == HPXML::LocationCrawlspace - if foundation_type == HPXML::FoundationTypeCrawlspaceUnvented + case foundation_type + when HPXML::FoundationTypeCrawlspaceUnvented return HPXML::LocationCrawlspaceUnvented - elsif foundation_type == HPXML::FoundationTypeCrawlspaceVented + when HPXML::FoundationTypeCrawlspaceVented return HPXML::LocationCrawlspaceVented - elsif foundation_type == HPXML::FoundationTypeCrawlspaceConditioned + when HPXML::FoundationTypeCrawlspaceConditioned return HPXML::LocationCrawlspaceConditioned else fail "Specified '#{location}' but foundation type is '#{foundation_type}'." end elsif location == HPXML::LocationAttic - if attic_type == HPXML::AtticTypeUnvented + case attic_type + when HPXML::AtticTypeUnvented return HPXML::LocationAtticUnvented - elsif attic_type == HPXML::AtticTypeVented + when HPXML::AtticTypeVented return HPXML::LocationAtticVented - elsif attic_type == HPXML::AtticTypeConditioned + when HPXML::AtticTypeConditioned return HPXML::LocationConditionedSpace else fail "Specified '#{location}' but attic type is '#{attic_type}'." @@ -6393,24 +6406,26 @@ def self.set_hvac_control(hpxml, hpxml_bldg, args, weather) def self.set_ventilation_fans(hpxml_bldg, args) if args[:mech_vent_fan_type] != Constants::None - if [HPXML::MechVentTypeERV].include?(args[:mech_vent_fan_type]) - if args[:mech_vent_recovery_efficiency_type] == 'Unadjusted' + distribution_system_idref = nil + + case args[:mech_vent_fan_type] + when HPXML::MechVentTypeERV + case args[:mech_vent_recovery_efficiency_type] + when 'Unadjusted' total_recovery_efficiency = args[:mech_vent_total_recovery_efficiency] sensible_recovery_efficiency = args[:mech_vent_sensible_recovery_efficiency] - elsif args[:mech_vent_recovery_efficiency_type] == 'Adjusted' + when 'Adjusted' total_recovery_efficiency_adjusted = args[:mech_vent_total_recovery_efficiency] sensible_recovery_efficiency_adjusted = args[:mech_vent_sensible_recovery_efficiency] end - elsif [HPXML::MechVentTypeHRV].include?(args[:mech_vent_fan_type]) - if args[:mech_vent_recovery_efficiency_type] == 'Unadjusted' + when HPXML::MechVentTypeHRV + case args[:mech_vent_recovery_efficiency_type] + when 'Unadjusted' sensible_recovery_efficiency = args[:mech_vent_sensible_recovery_efficiency] - elsif args[:mech_vent_recovery_efficiency_type] == 'Adjusted' + when 'Adjusted' sensible_recovery_efficiency_adjusted = args[:mech_vent_sensible_recovery_efficiency] end - end - - distribution_system_idref = nil - if args[:mech_vent_fan_type] == HPXML::MechVentTypeCFIS + when HPXML::MechVentTypeCFIS hpxml_bldg.hvac_distributions.each do |hvac_distribution| next unless hvac_distribution.distribution_system_type == HPXML::HVACDistributionTypeAir next if hvac_distribution.air_type != HPXML::AirTypeRegularVelocity @@ -6474,19 +6489,21 @@ def self.set_ventilation_fans(hpxml_bldg, args) if args[:mech_vent_2_fan_type] != Constants::None - if [HPXML::MechVentTypeERV].include?(args[:mech_vent_2_fan_type]) - - if args[:mech_vent_2_recovery_efficiency_type] == 'Unadjusted' + case args[:mech_vent_2_fan_type] + when HPXML::MechVentTypeERV + case args[:mech_vent_2_recovery_efficiency_type] + when 'Unadjusted' total_recovery_efficiency = args[:mech_vent_2_total_recovery_efficiency] sensible_recovery_efficiency = args[:mech_vent_2_sensible_recovery_efficiency] - elsif args[:mech_vent_2_recovery_efficiency_type] == 'Adjusted' + when 'Adjusted' total_recovery_efficiency_adjusted = args[:mech_vent_2_total_recovery_efficiency] sensible_recovery_efficiency_adjusted = args[:mech_vent_2_sensible_recovery_efficiency] end - elsif [HPXML::MechVentTypeHRV].include?(args[:mech_vent_2_fan_type]) - if args[:mech_vent_2_recovery_efficiency_type] == 'Unadjusted' + when HPXML::MechVentTypeHRV + case args[:mech_vent_2_recovery_efficiency_type] + when 'Unadjusted' sensible_recovery_efficiency = args[:mech_vent_2_sensible_recovery_efficiency] - elsif args[:mech_vent_2_recovery_efficiency_type] == 'Adjusted' + when 'Adjusted' sensible_recovery_efficiency_adjusted = args[:mech_vent_2_sensible_recovery_efficiency] end end @@ -6560,9 +6577,10 @@ def self.set_water_heating_systems(hpxml_bldg, args) location = get_location(args[:water_heater_location], hpxml_bldg.foundations[-1].foundation_type, hpxml_bldg.attics[-1].attic_type) if not [HPXML::WaterHeaterTypeCombiStorage, HPXML::WaterHeaterTypeCombiTankless].include? water_heater_type - if args[:water_heater_efficiency_type] == 'EnergyFactor' + case args[:water_heater_efficiency_type] + when 'EnergyFactor' energy_factor = args[:water_heater_efficiency] - elsif args[:water_heater_efficiency_type] == 'UniformEnergyFactor' + when 'UniformEnergyFactor' uniform_energy_factor = args[:water_heater_efficiency] if water_heater_type != HPXML::WaterHeaterTypeTankless usage_bin = args[:water_heater_usage_bin] @@ -6955,9 +6973,10 @@ def self.set_lighting(hpxml_bldg, args) def self.set_dehumidifier(hpxml_bldg, args) return if args[:dehumidifier_type] == Constants::None - if args[:dehumidifier_efficiency_type] == 'EnergyFactor' + case args[:dehumidifier_efficiency_type] + when 'EnergyFactor' energy_factor = args[:dehumidifier_efficiency] - elsif args[:dehumidifier_efficiency_type] == 'IntegratedEnergyFactor' + when 'IntegratedEnergyFactor' integrated_energy_factor = args[:dehumidifier_efficiency] end @@ -6987,9 +7006,10 @@ def self.set_clothes_washer(hpxml_bldg, args) return if args[:water_heater_type] == Constants::None return unless args[:clothes_washer_present] - if args[:clothes_washer_efficiency_type] == 'ModifiedEnergyFactor' + case args[:clothes_washer_efficiency_type] + when 'ModifiedEnergyFactor' modified_energy_factor = args[:clothes_washer_efficiency] - elsif args[:clothes_washer_efficiency_type] == 'IntegratedModifiedEnergyFactor' + when 'IntegratedModifiedEnergyFactor' integrated_modified_energy_factor = args[:clothes_washer_efficiency] end @@ -7021,9 +7041,10 @@ def self.set_clothes_dryer(hpxml_bldg, args) return unless args[:clothes_washer_present] return unless args[:clothes_dryer_present] - if args[:clothes_dryer_efficiency_type] == 'EnergyFactor' + case args[:clothes_dryer_efficiency_type] + when 'EnergyFactor' energy_factor = args[:clothes_dryer_efficiency] - elsif args[:clothes_dryer_efficiency_type] == 'CombinedEnergyFactor' + when 'CombinedEnergyFactor' combined_energy_factor = args[:clothes_dryer_efficiency] end @@ -7061,9 +7082,10 @@ def self.set_dishwasher(hpxml_bldg, args) return if args[:water_heater_type] == Constants::None return unless args[:dishwasher_present] - if args[:dishwasher_efficiency_type] == 'RatedAnnualkWh' + case args[:dishwasher_efficiency_type] + when 'RatedAnnualkWh' rated_annual_kwh = args[:dishwasher_efficiency] - elsif args[:dishwasher_efficiency_type] == 'EnergyFactor' + when 'EnergyFactor' energy_factor = args[:dishwasher_efficiency] end @@ -7305,14 +7327,13 @@ def self.set_misc_fuel_loads_fireplace(hpxml_bldg, args) def self.set_pool(hpxml_bldg, args) return unless args[:pool_present] - if [HPXML::HeaterTypeElectricResistance, HPXML::HeaterTypeHeatPump].include?(args[:pool_heater_type]) + case args[:pool_heater_type] + when HPXML::HeaterTypeElectricResistance, HPXML::HeaterTypeHeatPump if not args[:pool_heater_annual_kwh].nil? heater_load_units = HPXML::UnitsKwhPerYear heater_load_value = args[:pool_heater_annual_kwh] end - end - - if [HPXML::HeaterTypeGas].include?(args[:pool_heater_type]) + when HPXML::HeaterTypeGas if not args[:pool_heater_annual_therm].nil? heater_load_units = HPXML::UnitsThermPerYear heater_load_value = args[:pool_heater_annual_therm] @@ -7343,14 +7364,13 @@ def self.set_pool(hpxml_bldg, args) def self.set_permanent_spa(hpxml_bldg, args) return unless args[:permanent_spa_present] - if [HPXML::HeaterTypeElectricResistance, HPXML::HeaterTypeHeatPump].include?(args[:permanent_spa_heater_type]) + case args[:permanent_spa_heater_type] + when HPXML::HeaterTypeElectricResistance, HPXML::HeaterTypeHeatPump if not args[:permanent_spa_heater_annual_kwh].nil? heater_load_units = HPXML::UnitsKwhPerYear heater_load_value = args[:permanent_spa_heater_annual_kwh] end - end - - if [HPXML::HeaterTypeGas].include?(args[:permanent_spa_heater_type]) + when HPXML::HeaterTypeGas if not args[:permanent_spa_heater_annual_therm].nil? heater_load_units = HPXML::UnitsThermPerYear heater_load_value = args[:permanent_spa_heater_annual_therm] diff --git a/resources/hpxml-measures/BuildResidentialHPXML/measure.xml b/resources/hpxml-measures/BuildResidentialHPXML/measure.xml index ea8c333d99..154e205c1e 100644 --- a/resources/hpxml-measures/BuildResidentialHPXML/measure.xml +++ b/resources/hpxml-measures/BuildResidentialHPXML/measure.xml @@ -3,8 +3,8 @@ 3.1 build_residential_hpxml a13a8983-2b01-4930-8af2-42030b6e4233 - 6024806a-1640-4c75-86e4-d00329c89e3a - 2024-10-31T22:43:54Z + 32bd49ca-09dc-40ec-b676-f01d76e98566 + 2024-12-09T21:40:28Z 2C38F48B BuildResidentialHPXML HPXML Builder @@ -88,7 +88,7 @@ schedules_unavailable_period_window_natvent_availabilities Schedules: Unavailable Period Window Natural Ventilation Availabilities - The availability of the natural ventilation schedule during unavailable periods. Valid choices are: regular schedule, always available, always unavailable. If multiple periods, use a comma-separated list. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-unavailable-periods'>HPXML Unavailable Periods</a>) is used. + The availability of the natural ventilation schedule during unavailable periods. Valid choices are: regular schedule, always available, always unavailable. If multiple periods, use a comma-separated list. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-unavailable-periods'>HPXML Unavailable Periods</a>) is used. String false false @@ -96,7 +96,7 @@ simulation_control_timestep Simulation Control: Timestep - Value must be a divisor of 60. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-simulation-control'>HPXML Simulation Control</a>) is used. + Value must be a divisor of 60. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-simulation-control'>HPXML Simulation Control</a>) is used. Integer min false @@ -105,7 +105,7 @@ simulation_control_run_period Simulation Control: Run Period - Enter a date range like 'Jan 1 - Dec 31'. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-simulation-control'>HPXML Simulation Control</a>) is used. + Enter a date range like 'Jan 1 - Dec 31'. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-simulation-control'>HPXML Simulation Control</a>) is used. String false false @@ -113,7 +113,7 @@ simulation_control_run_period_calendar_year Simulation Control: Run Period Calendar Year - This numeric field should contain the calendar year that determines the start day of week. If you are running simulations using AMY weather files, the value entered for calendar year will not be used; it will be overridden by the actual year found in the AMY weather file. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-simulation-control'>HPXML Simulation Control</a>) is used. + This numeric field should contain the calendar year that determines the start day of week. If you are running simulations using AMY weather files, the value entered for calendar year will not be used; it will be overridden by the actual year found in the AMY weather file. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-simulation-control'>HPXML Simulation Control</a>) is used. Integer year false @@ -122,7 +122,7 @@ simulation_control_daylight_saving_enabled Simulation Control: Daylight Saving Enabled - Whether to use daylight saving. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-building-site'>HPXML Building Site</a>) is used. + Whether to use daylight saving. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-building-site'>HPXML Building Site</a>) is used. Boolean false false @@ -140,7 +140,7 @@ simulation_control_daylight_saving_period Simulation Control: Daylight Saving Period - Enter a date range like 'Mar 15 - Dec 15'. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-building-site'>HPXML Building Site</a>) is used. + Enter a date range like 'Mar 15 - Dec 15'. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-building-site'>HPXML Building Site</a>) is used. String false false @@ -148,7 +148,7 @@ simulation_control_temperature_capacitance_multiplier Simulation Control: Temperature Capacitance Multiplier - Affects the transient calculation of indoor air temperatures. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-simulation-control'>HPXML Simulation Control</a>) is used. + Affects the transient calculation of indoor air temperatures. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-simulation-control'>HPXML Simulation Control</a>) is used. String false false @@ -156,7 +156,7 @@ simulation_control_defrost_model_type Simulation Control: Defrost Model Type - Research feature to select the type of defrost model. Use standard for default E+ defrost setting. Use advanced for an improved model that better accounts for load and energy use during defrost; using advanced may impact simulation runtime. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-simulation-control'>HPXML Simulation Control</a>) is used. + Research feature to select the type of defrost model. Use standard for default E+ defrost setting. Use advanced for an improved model that better accounts for load and energy use during defrost; using advanced may impact simulation runtime. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-simulation-control'>HPXML Simulation Control</a>) is used. Choice false false @@ -192,7 +192,7 @@ site_type Site: Type - The type of site. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-site'>HPXML Site</a>) is used. + The type of site. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-site'>HPXML Site</a>) is used. Choice false false @@ -214,7 +214,7 @@ site_shielding_of_home Site: Shielding of Home - Presence of nearby buildings, trees, obstructions for infiltration model. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-site'>HPXML Site</a>) is used. + Presence of nearby buildings, trees, obstructions for infiltration model. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-site'>HPXML Site</a>) is used. Choice false false @@ -236,7 +236,7 @@ site_soil_and_moisture_type Site: Soil and Moisture Type - Type of soil and moisture. This is used to inform ground conductivity and diffusivity. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-site'>HPXML Site</a>) is used. + Type of soil and moisture. This is used to inform ground conductivity and diffusivity. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-site'>HPXML Site</a>) is used. Choice false false @@ -434,7 +434,7 @@ site_state_code Site: State Code - State code of the home address. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-site'>HPXML Site</a>) is used. + State code of the home address. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-site'>HPXML Site</a>) is used. Choice false false @@ -656,7 +656,7 @@ site_time_zone_utc_offset Site: Time Zone UTC Offset - Time zone UTC offset of the home address. Must be between -12 and 14. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-site'>HPXML Site</a>) is used. + Time zone UTC offset of the home address. Must be between -12 and 14. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-site'>HPXML Site</a>) is used. Double hr false @@ -665,7 +665,7 @@ site_elevation Site: Elevation - Elevation of the home address. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-site'>HPXML Site</a>) is used. + Elevation of the home address. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-site'>HPXML Site</a>) is used. Double ft false @@ -674,7 +674,7 @@ site_latitude Site: Latitude - Latitude of the home address. Must be between -90 and 90. Use negative values for southern hemisphere. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-site'>HPXML Site</a>) is used. + Latitude of the home address. Must be between -90 and 90. Use negative values for southern hemisphere. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-site'>HPXML Site</a>) is used. Double deg false @@ -683,7 +683,7 @@ site_longitude Site: Longitude - Longitude of the home address. Must be between -180 and 180. Use negative values for the western hemisphere. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-site'>HPXML Site</a>) is used. + Longitude of the home address. Must be between -180 and 180. Use negative values for the western hemisphere. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-site'>HPXML Site</a>) is used. Double deg false @@ -869,7 +869,7 @@ geometry_unit_num_bathrooms Geometry: Unit Number of Bathrooms - The number of bathrooms in the unit. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-building-construction'>HPXML Building Construction</a>) is used. + The number of bathrooms in the unit. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-building-construction'>HPXML Building Construction</a>) is used. Integer # false @@ -878,7 +878,7 @@ geometry_unit_num_occupants Geometry: Unit Number of Occupants - The number of occupants in the unit. If not provided, an *asset* calculation is performed assuming standard occupancy, in which various end use defaults (e.g., plug loads, appliances, and hot water usage) are calculated based on Number of Bedrooms and Conditioned Floor Area per ANSI/RESNET/ICC 301-2019. If provided, an *operational* calculation is instead performed in which the end use defaults are adjusted using the relationship between Number of Bedrooms and Number of Occupants from RECS 2015. + The number of occupants in the unit. If not provided, an *asset* calculation is performed assuming standard occupancy, in which various end use defaults (e.g., plug loads, appliances, and hot water usage) are calculated based on Number of Bedrooms and Conditioned Floor Area per ANSI/RESNET/ICC 301. If provided, an *operational* calculation is instead performed in which the end use defaults to reflect real-world data (where possible). Double # false @@ -906,7 +906,7 @@ geometry_unit_height_above_grade Geometry: Unit Height Above Grade - Describes the above-grade height of apartment units on upper floors or homes above ambient or belly-and-wing foundations. It is defined as the height of the lowest conditioned floor above grade and is used to calculate the wind speed for the infiltration model. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-building-construction'>HPXML Building Construction</a>) is used. + Describes the above-grade height of apartment units on upper floors or homes above ambient or belly-and-wing foundations. It is defined as the height of the lowest conditioned floor above grade and is used to calculate the wind speed for the infiltration model. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-building-construction'>HPXML Building Construction</a>) is used. Double ft false @@ -1203,7 +1203,7 @@ neighbor_front_height Neighbor: Front Height - The height of the neighboring building to the front. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-neighbor-buildings'>HPXML Neighbor Building</a>) is used. + The height of the neighboring building to the front. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-neighbor-buildings'>HPXML Neighbor Building</a>) is used. Double ft false @@ -1212,7 +1212,7 @@ neighbor_back_height Neighbor: Back Height - The height of the neighboring building to the back. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-neighbor-buildings'>HPXML Neighbor Building</a>) is used. + The height of the neighboring building to the back. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-neighbor-buildings'>HPXML Neighbor Building</a>) is used. Double ft false @@ -1221,7 +1221,7 @@ neighbor_left_height Neighbor: Left Height - The height of the neighboring building to the left. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-neighbor-buildings'>HPXML Neighbor Building</a>) is used. + The height of the neighboring building to the left. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-neighbor-buildings'>HPXML Neighbor Building</a>) is used. Double ft false @@ -1230,7 +1230,7 @@ neighbor_right_height Neighbor: Right Height - The height of the neighboring building to the right. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-neighbor-buildings'>HPXML Neighbor Building</a>) is used. + The height of the neighboring building to the right. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-neighbor-buildings'>HPXML Neighbor Building</a>) is used. Double ft false @@ -1286,7 +1286,7 @@ foundation_wall_type Foundation Wall: Type - The material type of the foundation wall. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-foundation-walls'>HPXML Foundation Walls</a>) is used. + The material type of the foundation wall. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-foundation-walls'>HPXML Foundation Walls</a>) is used. Choice false false @@ -1328,7 +1328,7 @@ foundation_wall_thickness Foundation Wall: Thickness - The thickness of the foundation wall. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-foundation-walls'>HPXML Foundation Walls</a>) is used. + The thickness of the foundation wall. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-foundation-walls'>HPXML Foundation Walls</a>) is used. Double in false @@ -1367,7 +1367,7 @@ foundation_wall_insulation_distance_to_top Foundation Wall: Insulation Distance To Top - The distance from the top of the foundation wall to the top of the foundation wall insulation. Only applies to basements/crawlspaces. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-foundation-walls'>HPXML Foundation Walls</a>) is used. + The distance from the top of the foundation wall to the top of the foundation wall insulation. Only applies to basements/crawlspaces. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-foundation-walls'>HPXML Foundation Walls</a>) is used. Double ft false @@ -1376,7 +1376,7 @@ foundation_wall_insulation_distance_to_bottom Foundation Wall: Insulation Distance To Bottom - The distance from the top of the foundation wall to the bottom of the foundation wall insulation. Only applies to basements/crawlspaces. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-foundation-walls'>HPXML Foundation Walls</a>) is used. + The distance from the top of the foundation wall to the bottom of the foundation wall insulation. Only applies to basements/crawlspaces. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-foundation-walls'>HPXML Foundation Walls</a>) is used. Double ft false @@ -1470,7 +1470,7 @@ slab_thickness Slab: Thickness - The thickness of the slab. Zero can be entered if there is a dirt floor instead of a slab. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-slabs'>HPXML Slabs</a>) is used. + The thickness of the slab. Zero can be entered if there is a dirt floor instead of a slab. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-slabs'>HPXML Slabs</a>) is used. Double in false @@ -1479,7 +1479,7 @@ slab_carpet_fraction Slab: Carpet Fraction - Fraction of the slab floor area that is carpeted. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-slabs'>HPXML Slabs</a>) is used. + Fraction of the slab floor area that is carpeted. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-slabs'>HPXML Slabs</a>) is used. Double Frac false @@ -1488,7 +1488,7 @@ slab_carpet_r Slab: Carpet R-value - R-value of the slab carpet. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-slabs'>HPXML Slabs</a>) is used. + R-value of the slab carpet. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-slabs'>HPXML Slabs</a>) is used. Double h-ft^2-R/Btu false @@ -1507,7 +1507,7 @@ roof_material_type Roof: Material Type - The material type of the roof. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-roofs'>HPXML Roofs</a>) is used. + The material type of the roof. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-roofs'>HPXML Roofs</a>) is used. Choice false false @@ -1553,7 +1553,7 @@ roof_color Roof: Color - The color of the roof. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-roofs'>HPXML Roofs</a>) is used. + The color of the roof. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-roofs'>HPXML Roofs</a>) is used. Choice false false @@ -1619,7 +1619,7 @@ radiant_barrier_grade Attic: Radiant Barrier Grade - The grade of the radiant barrier in the attic. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-roofs'>HPXML Roofs</a>) is used. + The grade of the radiant barrier in the attic. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-roofs'>HPXML Roofs</a>) is used. Choice false false @@ -1696,7 +1696,7 @@ wall_siding_type Wall: Siding Type - The siding type of the walls. Also applies to rim joists. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-walls'>HPXML Walls</a>) is used. + The siding type of the walls. Also applies to rim joists. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-walls'>HPXML Walls</a>) is used. Choice false false @@ -1750,7 +1750,7 @@ wall_color Wall: Color - The color of the walls. Also applies to rim joists. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-walls'>HPXML Walls</a>) is used. + The color of the walls. Also applies to rim joists. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-walls'>HPXML Walls</a>) is used. Choice false false @@ -1880,7 +1880,7 @@ window_fraction_operable Windows: Fraction Operable - Fraction of windows that are operable. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-windows'>HPXML Windows</a>) is used. + Fraction of windows that are operable. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-windows'>HPXML Windows</a>) is used. Double Frac false @@ -1889,7 +1889,7 @@ window_natvent_availability Windows: Natural Ventilation Availability - For operable windows, the number of days/week that windows can be opened by occupants for natural ventilation. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-windows'>HPXML Windows</a>) is used. + For operable windows, the number of days/week that windows can be opened by occupants for natural ventilation. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-windows'>HPXML Windows</a>) is used. Integer Days/week false @@ -1917,7 +1917,7 @@ window_interior_shading_type Windows: Interior Shading Type - Type of window interior shading. Summer/winter shading coefficients can be provided below instead. If neither is provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-interior-shading'>HPXML Interior Shading</a>) is used. + Type of window interior shading. Summer/winter shading coefficients can be provided below instead. If neither is provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-interior-shading'>HPXML Interior Shading</a>) is used. Choice false false @@ -1967,7 +1967,7 @@ window_interior_shading_winter Windows: Winter Interior Shading Coefficient - Interior shading coefficient for the winter season, which if provided overrides the shading type input. 1.0 indicates no reduction in solar gain, 0.85 indicates 15% reduction, etc. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-interior-shading'>HPXML Interior Shading</a>) is used. + Interior shading coefficient for the winter season, which if provided overrides the shading type input. 1.0 indicates no reduction in solar gain, 0.85 indicates 15% reduction, etc. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-interior-shading'>HPXML Interior Shading</a>) is used. Double Frac false @@ -1976,7 +1976,7 @@ window_interior_shading_summer Windows: Summer Interior Shading Coefficient - Interior shading coefficient for the summer season, which if provided overrides the shading type input. 1.0 indicates no reduction in solar gain, 0.85 indicates 15% reduction, etc. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-interior-shading'>HPXML Interior Shading</a>) is used. + Interior shading coefficient for the summer season, which if provided overrides the shading type input. 1.0 indicates no reduction in solar gain, 0.85 indicates 15% reduction, etc. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-interior-shading'>HPXML Interior Shading</a>) is used. Double Frac false @@ -1985,7 +1985,7 @@ window_exterior_shading_type Windows: Exterior Shading Type - Type of window exterior shading. Summer/winter shading coefficients can be provided below instead. If neither is provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-exterior-shading'>HPXML Exterior Shading</a>) is used. + Type of window exterior shading. Summer/winter shading coefficients can be provided below instead. If neither is provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-exterior-shading'>HPXML Exterior Shading</a>) is used. Choice false false @@ -2007,7 +2007,7 @@ window_exterior_shading_winter Windows: Winter Exterior Shading Coefficient - Exterior shading coefficient for the winter season, which if provided overrides the shading type input. 1.0 indicates no reduction in solar gain, 0.85 indicates 15% reduction, etc. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-exterior-shading'>HPXML Exterior Shading</a>) is used. + Exterior shading coefficient for the winter season, which if provided overrides the shading type input. 1.0 indicates no reduction in solar gain, 0.85 indicates 15% reduction, etc. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-exterior-shading'>HPXML Exterior Shading</a>) is used. Double Frac false @@ -2016,7 +2016,7 @@ window_exterior_shading_summer Windows: Summer Exterior Shading Coefficient - Exterior shading coefficient for the summer season, which if provided overrides the shading type input. 1.0 indicates no reduction in solar gain, 0.85 indicates 15% reduction, etc. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-exterior-shading'>HPXML Exterior Shading</a>) is used. + Exterior shading coefficient for the summer season, which if provided overrides the shading type input. 1.0 indicates no reduction in solar gain, 0.85 indicates 15% reduction, etc. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-exterior-shading'>HPXML Exterior Shading</a>) is used. Double Frac false @@ -2025,7 +2025,7 @@ window_shading_summer_season Windows: Shading Summer Season - Enter a date range like 'May 1 - Sep 30'. Defines the summer season for purposes of shading coefficients; the rest of the year is assumed to be winter. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-windows'>HPXML Windows</a>) is used. + Enter a date range like 'May 1 - Sep 30'. Defines the summer season for purposes of shading coefficients; the rest of the year is assumed to be winter. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-windows'>HPXML Windows</a>) is used. String false false @@ -2386,7 +2386,7 @@ air_leakage_has_flue_or_chimney_in_conditioned_space Air Leakage: Has Flue or Chimney in Conditioned Space - Presence of flue or chimney with combustion air from conditioned space; used for infiltration model. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#flue-or-chimney'>Flue or Chimney</a>) is used. + Presence of flue or chimney with combustion air from conditioned space; used for infiltration model. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#flue-or-chimney'>Flue or Chimney</a>) is used. Boolean false false @@ -2508,7 +2508,7 @@ heating_system_heating_capacity Heating System: Heating Capacity - The output heating capacity of the heating system. If not provided, the OS-HPXML autosized default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-heating-systems'>HPXML Heating Systems</a>) is used. + The output heating capacity of the heating system. If not provided, the OS-HPXML autosized default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-heating-systems'>HPXML Heating Systems</a>) is used. Double Btu/hr false @@ -2633,7 +2633,7 @@ cooling_system_cooling_compressor_type Cooling System: Cooling Compressor Type - The compressor type of the cooling system. Only applies to central air conditioner and mini-split. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#central-air-conditioner'>Central Air Conditioner</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#mini-split-air-conditioner'>Mini-Split Air Conditioner</a>) is used. + The compressor type of the cooling system. Only applies to central air conditioner and mini-split. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#central-air-conditioner'>Central Air Conditioner</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#mini-split-air-conditioner'>Mini-Split Air Conditioner</a>) is used. Choice false false @@ -2655,7 +2655,7 @@ cooling_system_cooling_sensible_heat_fraction Cooling System: Cooling Sensible Heat Fraction - The sensible heat fraction of the cooling system. Ignored for evaporative cooler. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#central-air-conditioner'>Central Air Conditioner</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#room-air-conditioner'>Room Air Conditioner</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#packaged-terminal-air-conditioner'>Packaged Terminal Air Conditioner</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#mini-split-air-conditioner'>Mini-Split Air Conditioner</a>) is used. + The sensible heat fraction of the cooling system. Ignored for evaporative cooler. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#central-air-conditioner'>Central Air Conditioner</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#room-air-conditioner'>Room Air Conditioner</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#packaged-terminal-air-conditioner'>Packaged Terminal Air Conditioner</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#mini-split-air-conditioner'>Mini-Split Air Conditioner</a>) is used. Double Frac false @@ -2664,7 +2664,7 @@ cooling_system_cooling_capacity Cooling System: Cooling Capacity - The output cooling capacity of the cooling system. If not provided, the OS-HPXML autosized default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#central-air-conditioner'>Central Air Conditioner</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#room-air-conditioner'>Room Air Conditioner</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#packaged-terminal-air-conditioner'>Packaged Terminal Air Conditioner</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#evaporative-cooler'>Evaporative Cooler</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#mini-split-air-conditioner'>Mini-Split Air Conditioner</a>) is used. + The output cooling capacity of the cooling system. If not provided, the OS-HPXML autosized default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#central-air-conditioner'>Central Air Conditioner</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#room-air-conditioner'>Room Air Conditioner</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#packaged-terminal-air-conditioner'>Packaged Terminal Air Conditioner</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#evaporative-cooler'>Evaporative Cooler</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#mini-split-air-conditioner'>Mini-Split Air Conditioner</a>) is used. Double Btu/hr false @@ -2737,7 +2737,7 @@ cooling_system_crankcase_heater_watts Cooling System: Crankcase Heater Power Watts - Cooling system crankcase heater power consumption in Watts. Applies only to central air conditioner, room air conditioner, packaged terminal air conditioner and mini-split. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#central-air-conditioner'>Central Air Conditioner</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#room-air-conditioner'>Room Air Conditioner</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#packaged-terminal-air-conditioner'>Packaged Terminal Air Conditioner</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#mini-split-air-conditioner'>Mini-Split Air Conditioner</a>) is used. + Cooling system crankcase heater power consumption in Watts. Applies only to central air conditioner, room air conditioner, packaged terminal air conditioner and mini-split. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#central-air-conditioner'>Central Air Conditioner</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#room-air-conditioner'>Room Air Conditioner</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#packaged-terminal-air-conditioner'>Packaged Terminal Air Conditioner</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#mini-split-air-conditioner'>Mini-Split Air Conditioner</a>) is used. Double W false @@ -2793,7 +2793,7 @@ cooling_system_integrated_heating_system_capacity Cooling System: Integrated Heating System Heating Capacity - The output heating capacity of the heating system integrated into cooling system. If not provided, the OS-HPXML autosized default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#room-air-conditioner'>Room Air Conditioner</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#packaged-terminal-air-conditioner'>Packaged Terminal Air Conditioner</a>) is used. Only used for room air conditioner and packaged terminal air conditioner. + The output heating capacity of the heating system integrated into cooling system. If not provided, the OS-HPXML autosized default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#room-air-conditioner'>Room Air Conditioner</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#packaged-terminal-air-conditioner'>Packaged Terminal Air Conditioner</a>) is used. Only used for room air conditioner and packaged terminal air conditioner. Double Btu/hr false @@ -2914,7 +2914,7 @@ heat_pump_cooling_compressor_type Heat Pump: Cooling Compressor Type - The compressor type of the heat pump. Only applies to air-to-air and mini-split. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#air-to-air-heat-pump'>Air-to-Air Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#mini-split-heat-pump'>Mini-Split Heat Pump</a>) is used. + The compressor type of the heat pump. Only applies to air-to-air and mini-split. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#air-to-air-heat-pump'>Air-to-Air Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#mini-split-heat-pump'>Mini-Split Heat Pump</a>) is used. Choice false false @@ -2936,7 +2936,7 @@ heat_pump_cooling_sensible_heat_fraction Heat Pump: Cooling Sensible Heat Fraction - The sensible heat fraction of the heat pump. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#air-to-air-heat-pump'>Air-to-Air Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#mini-split-heat-pump'>Mini-Split Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#packaged-terminal-heat-pump'>Packaged Terminal Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#room-air-conditioner-w-reverse-cycle'>Room Air Conditioner w/ Reverse Cycle</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#ground-to-air-heat-pump'>Ground-to-Air Heat Pump</a>) is used. + The sensible heat fraction of the heat pump. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#air-to-air-heat-pump'>Air-to-Air Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#mini-split-heat-pump'>Mini-Split Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#packaged-terminal-heat-pump'>Packaged Terminal Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#room-air-conditioner-w-reverse-cycle'>Room Air Conditioner w/ Reverse Cycle</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#ground-to-air-heat-pump'>Ground-to-Air Heat Pump</a>) is used. Double Frac false @@ -2945,7 +2945,7 @@ heat_pump_heating_capacity Heat Pump: Heating Capacity - The output heating capacity of the heat pump. If not provided, the OS-HPXML autosized default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#air-to-air-heat-pump'>Air-to-Air Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#mini-split-heat-pump'>Mini-Split Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#packaged-terminal-heat-pump'>Packaged Terminal Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#room-air-conditioner-w-reverse-cycle'>Room Air Conditioner w/ Reverse Cycle</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#ground-to-air-heat-pump'>Ground-to-Air Heat Pump</a>) is used. + The output heating capacity of the heat pump. If not provided, the OS-HPXML autosized default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#air-to-air-heat-pump'>Air-to-Air Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#mini-split-heat-pump'>Mini-Split Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#packaged-terminal-heat-pump'>Packaged Terminal Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#room-air-conditioner-w-reverse-cycle'>Room Air Conditioner w/ Reverse Cycle</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#ground-to-air-heat-pump'>Ground-to-Air Heat Pump</a>) is used. Double Btu/hr false @@ -2971,7 +2971,7 @@ heat_pump_heating_capacity_retention_fraction Heat Pump: Heating Capacity Retention Fraction - The output heating capacity of the heat pump at a user-specified temperature (e.g., 17F or 5F) divided by the above nominal heating capacity. Applies to all heat pump types except ground-to-air. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#air-to-air-heat-pump'>Air-to-Air Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#mini-split-heat-pump'>Mini-Split Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#packaged-terminal-heat-pump'>Packaged Terminal Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#room-air-conditioner-w-reverse-cycle'>Room Air Conditioner w/ Reverse Cycle</a>) is used. + The output heating capacity of the heat pump at a user-specified temperature (e.g., 17F or 5F) divided by the above nominal heating capacity. Applies to all heat pump types except ground-to-air. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#air-to-air-heat-pump'>Air-to-Air Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#mini-split-heat-pump'>Mini-Split Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#packaged-terminal-heat-pump'>Packaged Terminal Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#room-air-conditioner-w-reverse-cycle'>Room Air Conditioner w/ Reverse Cycle</a>) is used. Double Frac false @@ -2989,7 +2989,7 @@ heat_pump_cooling_capacity Heat Pump: Cooling Capacity - The output cooling capacity of the heat pump. If not provided, the OS-HPXML autosized default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#air-to-air-heat-pump'>Air-to-Air Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#mini-split-heat-pump'>Mini-Split Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#packaged-terminal-heat-pump'>Packaged Terminal Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#room-air-conditioner-w-reverse-cycle'>Room Air Conditioner w/ Reverse Cycle</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#ground-to-air-heat-pump'>Ground-to-Air Heat Pump</a>) is used. + The output cooling capacity of the heat pump. If not provided, the OS-HPXML autosized default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#air-to-air-heat-pump'>Air-to-Air Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#mini-split-heat-pump'>Mini-Split Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#packaged-terminal-heat-pump'>Packaged Terminal Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#room-air-conditioner-w-reverse-cycle'>Room Air Conditioner w/ Reverse Cycle</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#ground-to-air-heat-pump'>Ground-to-Air Heat Pump</a>) is used. Double Btu/hr false @@ -3035,7 +3035,7 @@ heat_pump_compressor_lockout_temp Heat Pump: Compressor Lockout Temperature - The temperature below which the heat pump compressor is disabled. If both this and Backup Heating Lockout Temperature are provided and use the same value, it essentially defines a switchover temperature (for, e.g., a dual-fuel heat pump). Applies to all heat pump types other than ground-to-air. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#air-to-air-heat-pump'>Air-to-Air Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#mini-split-heat-pump'>Mini-Split Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#packaged-terminal-heat-pump'>Packaged Terminal Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#room-air-conditioner-w-reverse-cycle'>Room Air Conditioner w/ Reverse Cycle</a>) is used. + The temperature below which the heat pump compressor is disabled. If both this and Backup Heating Lockout Temperature are provided and use the same value, it essentially defines a switchover temperature (for, e.g., a dual-fuel heat pump). Applies to all heat pump types other than ground-to-air. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#air-to-air-heat-pump'>Air-to-Air Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#mini-split-heat-pump'>Mini-Split Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#packaged-terminal-heat-pump'>Packaged Terminal Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#room-air-conditioner-w-reverse-cycle'>Room Air Conditioner w/ Reverse Cycle</a>) is used. Double F false @@ -3120,7 +3120,7 @@ heat_pump_backup_heating_capacity Heat Pump: Backup Heating Capacity - The backup output heating capacity of the heat pump. If not provided, the OS-HPXML autosized default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#backup'>Backup</a>) is used. Only applies if Backup Type is 'integrated'. + The backup output heating capacity of the heat pump. If not provided, the OS-HPXML autosized default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#backup'>Backup</a>) is used. Only applies if Backup Type is 'integrated'. Double Btu/hr false @@ -3129,7 +3129,7 @@ heat_pump_backup_heating_lockout_temp Heat Pump: Backup Heating Lockout Temperature - The temperature above which the heat pump backup system is disabled. If both this and Compressor Lockout Temperature are provided and use the same value, it essentially defines a switchover temperature (for, e.g., a dual-fuel heat pump). Applies for both Backup Type of 'integrated' and 'separate'. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#backup'>Backup</a>) is used. + The temperature above which the heat pump backup system is disabled. If both this and Compressor Lockout Temperature are provided and use the same value, it essentially defines a switchover temperature (for, e.g., a dual-fuel heat pump). Applies for both Backup Type of 'integrated' and 'separate'. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#backup'>Backup</a>) is used. Double F false @@ -3138,7 +3138,7 @@ heat_pump_sizing_methodology Heat Pump: Sizing Methodology - The auto-sizing methodology to use when the heat pump capacity is not provided. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-hvac-sizing-control'>HPXML HVAC Sizing Control</a>) is used. + The auto-sizing methodology to use when the heat pump capacity is not provided. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-hvac-sizing-control'>HPXML HVAC Sizing Control</a>) is used. Choice false false @@ -3160,7 +3160,7 @@ heat_pump_backup_sizing_methodology Heat Pump: Backup Sizing Methodology - The auto-sizing methodology to use when the heat pump backup capacity is not provided. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-hvac-sizing-control'>HPXML HVAC Sizing Control</a>) is used. + The auto-sizing methodology to use when the heat pump backup capacity is not provided. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-hvac-sizing-control'>HPXML HVAC Sizing Control</a>) is used. Choice false false @@ -3214,7 +3214,7 @@ heat_pump_crankcase_heater_watts Heat Pump: Crankcase Heater Power Watts - Heat Pump crankcase heater power consumption in Watts. Applies only to air-to-air, mini-split, packaged terminal heat pump and room air conditioner with reverse cycle. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#air-to-air-heat-pump'>Air-to-Air Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#mini-split-heat-pump'>Mini-Split Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#packaged-terminal-heat-pump'>Packaged Terminal Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#room-air-conditioner-w-reverse-cycle'>Room Air Conditioner w/ Reverse Cycle</a>) is used. + Heat Pump crankcase heater power consumption in Watts. Applies only to air-to-air, mini-split, packaged terminal heat pump and room air conditioner with reverse cycle. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#air-to-air-heat-pump'>Air-to-Air Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#mini-split-heat-pump'>Mini-Split Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#packaged-terminal-heat-pump'>Packaged Terminal Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#room-air-conditioner-w-reverse-cycle'>Room Air Conditioner w/ Reverse Cycle</a>) is used. Double W false @@ -3332,7 +3332,7 @@ geothermal_loop_configuration Geothermal Loop: Configuration - Configuration of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#ground-to-air-heat-pump'>Ground-to-Air Heat Pump</a>) is used. + Configuration of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#ground-to-air-heat-pump'>Ground-to-Air Heat Pump</a>) is used. Choice false false @@ -3350,7 +3350,7 @@ geothermal_loop_borefield_configuration Geothermal Loop: Borefield Configuration - Borefield configuration of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. + Borefield configuration of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. Choice false false @@ -3384,7 +3384,7 @@ geothermal_loop_loop_flow Geothermal Loop: Loop Flow - Water flow rate through the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML autosized default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. + Water flow rate through the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML autosized default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. Double gpm false @@ -3393,7 +3393,7 @@ geothermal_loop_boreholes_count Geothermal Loop: Boreholes Count - Number of boreholes. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML autosized default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. + Number of boreholes. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML autosized default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. Integer # false @@ -3402,7 +3402,7 @@ geothermal_loop_boreholes_length Geothermal Loop: Boreholes Length - Average length of each borehole (vertical). Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML autosized default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. + Average length of each borehole (vertical). Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML autosized default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. Double ft false @@ -3411,7 +3411,7 @@ geothermal_loop_boreholes_spacing Geothermal Loop: Boreholes Spacing - Distance between bores. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. + Distance between bores. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. Double ft false @@ -3420,7 +3420,7 @@ geothermal_loop_boreholes_diameter Geothermal Loop: Boreholes Diameter - Diameter of bores. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. + Diameter of bores. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. Double in false @@ -3429,7 +3429,7 @@ geothermal_loop_grout_type Geothermal Loop: Grout Type - Grout type of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. + Grout type of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. Choice false false @@ -3447,7 +3447,7 @@ geothermal_loop_pipe_type Geothermal Loop: Pipe Type - Pipe type of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. + Pipe type of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. Choice false false @@ -3465,7 +3465,7 @@ geothermal_loop_pipe_diameter Geothermal Loop: Pipe Diameter - Pipe diameter of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. + Pipe diameter of the geothermal loop. Only applies to ground-to-air heat pump type. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-geothermal-loops'>HPXML Geothermal Loops</a>) is used. Choice in false @@ -3584,7 +3584,7 @@ heating_system_2_heating_capacity Heating System 2: Heating Capacity - The output heating capacity of the second heating system. If not provided, the OS-HPXML autosized default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-heating-systems'>HPXML Heating Systems</a>) is used. + The output heating capacity of the second heating system. If not provided, the OS-HPXML autosized default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-heating-systems'>HPXML Heating Systems</a>) is used. Double Btu/hr false @@ -3656,7 +3656,7 @@ hvac_control_heating_season_period HVAC Control: Heating Season Period - Enter a date range like 'Nov 1 - Jun 30'. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-hvac-control'>HPXML HVAC Control</a>) is used. Can also provide 'BuildingAmerica' to use automatic seasons from the Building America House Simulation Protocols. + Enter a date range like 'Nov 1 - Jun 30'. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-hvac-control'>HPXML HVAC Control</a>) is used. Can also provide 'BuildingAmerica' to use automatic seasons from the Building America House Simulation Protocols. String false false @@ -3664,7 +3664,7 @@ hvac_control_cooling_season_period HVAC Control: Cooling Season Period - Enter a date range like 'Jun 1 - Oct 31'. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-hvac-control'>HPXML HVAC Control</a>) is used. Can also provide 'BuildingAmerica' to use automatic seasons from the Building America House Simulation Protocols. + Enter a date range like 'Jun 1 - Oct 31'. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-hvac-control'>HPXML HVAC Control</a>) is used. Can also provide 'BuildingAmerica' to use automatic seasons from the Building America House Simulation Protocols. String false false @@ -3672,7 +3672,7 @@ hvac_blower_fan_watts_per_cfm HVAC Blower: Fan Efficiency - The blower fan efficiency at maximum fan speed. Applies only to split (not packaged) systems (i.e., applies to ducted systems as well as ductless mini-split systems). If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-heating-systems'>HPXML Heating Systems</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-cooling-systems'>HPXML Cooling Systems</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-heat-pumps'>HPXML Heat Pumps</a>) is used. + The blower fan efficiency at maximum fan speed. Applies only to split (not packaged) systems (i.e., applies to ducted systems as well as ductless mini-split systems). If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-heating-systems'>HPXML Heating Systems</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-cooling-systems'>HPXML Cooling Systems</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-heat-pumps'>HPXML Heat Pumps</a>) is used. Double W/CFM false @@ -3713,7 +3713,7 @@ ducts_supply_location Ducts: Supply Location - The location of the supply ducts. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#air-distribution'>Air Distribution</a>) is used. + The location of the supply ducts. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#air-distribution'>Air Distribution</a>) is used. Choice false false @@ -3839,7 +3839,7 @@ ducts_supply_surface_area Ducts: Supply Surface Area - The supply ducts surface area in the given location. If neither Surface Area nor Area Fraction provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#air-distribution'>Air Distribution</a>) is used. + The supply ducts surface area in the given location. If neither Surface Area nor Area Fraction provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#air-distribution'>Air Distribution</a>) is used. Double ft^2 false @@ -3848,7 +3848,7 @@ ducts_supply_surface_area_fraction Ducts: Supply Area Fraction - The fraction of supply ducts surface area in the given location. Only used if Surface Area is not provided. If the fraction is less than 1, the remaining duct area is assumed to be in conditioned space. If neither Surface Area nor Area Fraction provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#air-distribution'>Air Distribution</a>) is used. + The fraction of supply ducts surface area in the given location. Only used if Surface Area is not provided. If the fraction is less than 1, the remaining duct area is assumed to be in conditioned space. If neither Surface Area nor Area Fraction provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#air-distribution'>Air Distribution</a>) is used. Double frac false @@ -3857,7 +3857,7 @@ ducts_supply_fraction_rectangular Ducts: Supply Fraction Rectangular - The fraction of supply ducts that are rectangular (as opposed to round); this affects the duct effective R-value used for modeling. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#air-distribution'>Air Distribution</a>) is used. + The fraction of supply ducts that are rectangular (as opposed to round); this affects the duct effective R-value used for modeling. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#air-distribution'>Air Distribution</a>) is used. Double frac false @@ -3875,7 +3875,7 @@ ducts_return_location Ducts: Return Location - The location of the return ducts. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#air-distribution'>Air Distribution</a>) is used. + The location of the return ducts. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#air-distribution'>Air Distribution</a>) is used. Choice false false @@ -4001,7 +4001,7 @@ ducts_return_surface_area Ducts: Return Surface Area - The return ducts surface area in the given location. If neither Surface Area nor Area Fraction provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#air-distribution'>Air Distribution</a>) is used. + The return ducts surface area in the given location. If neither Surface Area nor Area Fraction provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#air-distribution'>Air Distribution</a>) is used. Double ft^2 false @@ -4010,7 +4010,7 @@ ducts_return_surface_area_fraction Ducts: Return Area Fraction - The fraction of return ducts surface area in the given location. Only used if Surface Area is not provided. If the fraction is less than 1, the remaining duct area is assumed to be in conditioned space. If neither Surface Area nor Area Fraction provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#air-distribution'>Air Distribution</a>) is used. + The fraction of return ducts surface area in the given location. Only used if Surface Area is not provided. If the fraction is less than 1, the remaining duct area is assumed to be in conditioned space. If neither Surface Area nor Area Fraction provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#air-distribution'>Air Distribution</a>) is used. Double frac false @@ -4019,7 +4019,7 @@ ducts_number_of_return_registers Ducts: Number of Return Registers - The number of return registers of the ducts. Only used to calculate default return duct surface area. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#air-distribution'>Air Distribution</a>) is used. + The number of return registers of the ducts. Only used to calculate default return duct surface area. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#air-distribution'>Air Distribution</a>) is used. Integer # false @@ -4028,7 +4028,7 @@ ducts_return_fraction_rectangular Ducts: Return Fraction Rectangular - The fraction of return ducts that are rectangular (as opposed to round); this affects the duct effective R-value used for modeling. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#air-distribution'>Air Distribution</a>) is used. + The fraction of return ducts that are rectangular (as opposed to round); this affects the duct effective R-value used for modeling. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#air-distribution'>Air Distribution</a>) is used. Double frac false @@ -4076,7 +4076,7 @@ mech_vent_flow_rate Mechanical Ventilation: Flow Rate - The flow rate of the mechanical ventilation. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-mechanical-ventilation-fans'>HPXML Mechanical Ventilation Fans</a>) is used. + The flow rate of the mechanical ventilation. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-mechanical-ventilation-fans'>HPXML Mechanical Ventilation Fans</a>) is used. Double CFM false @@ -4085,7 +4085,7 @@ mech_vent_hours_in_operation Mechanical Ventilation: Hours In Operation - The hours in operation of the mechanical ventilation. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-mechanical-ventilation-fans'>HPXML Mechanical Ventilation Fans</a>) is used. + The hours in operation of the mechanical ventilation. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-mechanical-ventilation-fans'>HPXML Mechanical Ventilation Fans</a>) is used. Double hrs/day false @@ -4133,7 +4133,7 @@ mech_vent_fan_power Mechanical Ventilation: Fan Power - The fan power of the mechanical ventilation. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-mechanical-ventilation-fans'>HPXML Mechanical Ventilation Fans</a>) is used. + The fan power of the mechanical ventilation. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-mechanical-ventilation-fans'>HPXML Mechanical Ventilation Fans</a>) is used. Double W false @@ -4353,7 +4353,7 @@ kitchen_fans_quantity Kitchen Fans: Quantity - The quantity of the kitchen fans. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-local-ventilation-fans'>HPXML Local Ventilation Fans</a>) is used. + The quantity of the kitchen fans. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-local-ventilation-fans'>HPXML Local Ventilation Fans</a>) is used. Integer # false @@ -4362,7 +4362,7 @@ kitchen_fans_flow_rate Kitchen Fans: Flow Rate - The flow rate of the kitchen fan. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-local-ventilation-fans'>HPXML Local Ventilation Fans</a>) is used. + The flow rate of the kitchen fan. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-local-ventilation-fans'>HPXML Local Ventilation Fans</a>) is used. Double CFM false @@ -4371,7 +4371,7 @@ kitchen_fans_hours_in_operation Kitchen Fans: Hours In Operation - The hours in operation of the kitchen fan. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-local-ventilation-fans'>HPXML Local Ventilation Fans</a>) is used. + The hours in operation of the kitchen fan. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-local-ventilation-fans'>HPXML Local Ventilation Fans</a>) is used. Double hrs/day false @@ -4380,7 +4380,7 @@ kitchen_fans_power Kitchen Fans: Fan Power - The fan power of the kitchen fan. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-local-ventilation-fans'>HPXML Local Ventilation Fans</a>) is used. + The fan power of the kitchen fan. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-local-ventilation-fans'>HPXML Local Ventilation Fans</a>) is used. Double W false @@ -4389,7 +4389,7 @@ kitchen_fans_start_hour Kitchen Fans: Start Hour - The start hour of the kitchen fan. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-local-ventilation-fans'>HPXML Local Ventilation Fans</a>) is used. + The start hour of the kitchen fan. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-local-ventilation-fans'>HPXML Local Ventilation Fans</a>) is used. Integer hr false @@ -4398,7 +4398,7 @@ bathroom_fans_quantity Bathroom Fans: Quantity - The quantity of the bathroom fans. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-local-ventilation-fans'>HPXML Local Ventilation Fans</a>) is used. + The quantity of the bathroom fans. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-local-ventilation-fans'>HPXML Local Ventilation Fans</a>) is used. Integer # false @@ -4407,7 +4407,7 @@ bathroom_fans_flow_rate Bathroom Fans: Flow Rate - The flow rate of the bathroom fans. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-local-ventilation-fans'>HPXML Local Ventilation Fans</a>) is used. + The flow rate of the bathroom fans. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-local-ventilation-fans'>HPXML Local Ventilation Fans</a>) is used. Double CFM false @@ -4416,7 +4416,7 @@ bathroom_fans_hours_in_operation Bathroom Fans: Hours In Operation - The hours in operation of the bathroom fans. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-local-ventilation-fans'>HPXML Local Ventilation Fans</a>) is used. + The hours in operation of the bathroom fans. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-local-ventilation-fans'>HPXML Local Ventilation Fans</a>) is used. Double hrs/day false @@ -4425,7 +4425,7 @@ bathroom_fans_power Bathroom Fans: Fan Power - The fan power of the bathroom fans. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-local-ventilation-fans'>HPXML Local Ventilation Fans</a>) is used. + The fan power of the bathroom fans. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-local-ventilation-fans'>HPXML Local Ventilation Fans</a>) is used. Double W false @@ -4434,7 +4434,7 @@ bathroom_fans_start_hour Bathroom Fans: Start Hour - The start hour of the bathroom fans. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-local-ventilation-fans'>HPXML Local Ventilation Fans</a>) is used. + The start hour of the bathroom fans. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-local-ventilation-fans'>HPXML Local Ventilation Fans</a>) is used. Integer hr false @@ -4462,7 +4462,7 @@ whole_house_fan_flow_rate Whole House Fan: Flow Rate - The flow rate of the whole house fan. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-whole-house-fans'>HPXML Whole House Fans</a>) is used. + The flow rate of the whole house fan. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-whole-house-fans'>HPXML Whole House Fans</a>) is used. Double CFM false @@ -4471,7 +4471,7 @@ whole_house_fan_power Whole House Fan: Fan Power - The fan power of the whole house fan. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-whole-house-fans'>HPXML Whole House Fans</a>) is used. + The fan power of the whole house fan. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-whole-house-fans'>HPXML Whole House Fans</a>) is used. Double W false @@ -4550,7 +4550,7 @@ water_heater_location Water Heater: Location - The location of water heater. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-water-heating-systems'>HPXML Water Heating Systems</a>) is used. + The location of water heater. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-water-heating-systems'>HPXML Water Heating Systems</a>) is used. Choice false false @@ -4624,7 +4624,7 @@ water_heater_tank_volume Water Heater: Tank Volume - Nominal volume of water heater tank. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#conventional-storage'>Conventional Storage</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#heat-pump'>Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#combi-boiler-w-storage'>Combi Boiler w/ Storage</a>) is used. + Nominal volume of water heater tank. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#conventional-storage'>Conventional Storage</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#heat-pump'>Heat Pump</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#combi-boiler-w-storage'>Combi Boiler w/ Storage</a>) is used. Double gal false @@ -4661,7 +4661,7 @@ water_heater_usage_bin Water Heater: Usage Bin - The usage of the water heater. Only applies if Efficiency Type is UniformEnergyFactor and Type is not instantaneous water heater. Does not apply to space-heating boilers. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#conventional-storage'>Conventional Storage</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#heat-pump'>Heat Pump</a>) is used. + The usage of the water heater. Only applies if Efficiency Type is UniformEnergyFactor and Type is not instantaneous water heater. Does not apply to space-heating boilers. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#conventional-storage'>Conventional Storage</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#heat-pump'>Heat Pump</a>) is used. Choice false false @@ -4687,7 +4687,7 @@ water_heater_recovery_efficiency Water Heater: Recovery Efficiency - Ratio of energy delivered to water heater to the energy content of the fuel consumed by the water heater. Only used for non-electric storage water heaters. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#conventional-storage'>Conventional Storage</a>) is used. + Ratio of energy delivered to water heater to the energy content of the fuel consumed by the water heater. Only used for non-electric storage water heaters. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#conventional-storage'>Conventional Storage</a>) is used. Double Frac false @@ -4696,7 +4696,7 @@ water_heater_heating_capacity Water Heater: Heating Capacity - Heating capacity. Only applies to storage water heater and heat pump water heater (compressor). If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#conventional-storage'>Conventional Storage</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#heat-pump'>Heat Pump</a>) is used. + Heating capacity. Only applies to storage water heater and heat pump water heater (compressor). If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#conventional-storage'>Conventional Storage</a>, <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#heat-pump'>Heat Pump</a>) is used. Double Btu/hr false @@ -4705,7 +4705,7 @@ water_heater_backup_heating_capacity Water Heater: Backup Heating Capacity - Backup heating capacity for a heat pump water heater. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#heat-pump'>Heat Pump</a>) is used. + Backup heating capacity for a heat pump water heater. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#heat-pump'>Heat Pump</a>) is used. Double Btu/hr false @@ -4714,7 +4714,7 @@ water_heater_standby_loss Water Heater: Standby Loss - The standby loss of water heater. Only applies to space-heating boilers. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#combi-boiler-w-storage'>Combi Boiler w/ Storage</a>) is used. + The standby loss of water heater. Only applies to space-heating boilers. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#combi-boiler-w-storage'>Combi Boiler w/ Storage</a>) is used. Double F/hr false @@ -4732,7 +4732,7 @@ water_heater_setpoint_temperature Water Heater: Setpoint Temperature - The setpoint temperature of water heater. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-water-heating-systems'>HPXML Water Heating Systems</a>) is used. + The setpoint temperature of water heater. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-water-heating-systems'>HPXML Water Heating Systems</a>) is used. Double F false @@ -4768,7 +4768,7 @@ water_heater_tank_model_type Water Heater: Tank Type - Type of tank model to use. The 'stratified' tank generally provide more accurate results, but may significantly increase run time. Applies only to storage water heater. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#conventional-storage'>Conventional Storage</a>) is used. + Type of tank model to use. The 'stratified' tank generally provide more accurate results, but may significantly increase run time. Applies only to storage water heater. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#conventional-storage'>Conventional Storage</a>) is used. Choice false false @@ -4786,7 +4786,7 @@ water_heater_operating_mode Water Heater: Operating Mode - The water heater operating mode. The 'heat pump only' option only uses the heat pump, while 'hybrid/auto' allows the backup electric resistance to come on in high demand situations. This is ignored if a scheduled operating mode type is selected. Applies only to heat pump water heater. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#heat-pump'>Heat Pump</a>) is used. + The water heater operating mode. The 'heat pump only' option only uses the heat pump, while 'hybrid/auto' allows the backup electric resistance to come on in high demand situations. This is ignored if a scheduled operating mode type is selected. Applies only to heat pump water heater. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#heat-pump'>Heat Pump</a>) is used. Choice false false @@ -4823,7 +4823,7 @@ hot_water_distribution_standard_piping_length Hot Water Distribution: Standard Piping Length - If the distribution system is Standard, the length of the piping. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#standard'>Standard</a>) is used. + If the distribution system is Standard, the length of the piping. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#standard'>Standard</a>) is used. Double ft false @@ -4863,7 +4863,7 @@ hot_water_distribution_recirc_piping_length Hot Water Distribution: Recirculation Piping Length - If the distribution system is Recirculation, the length of the recirculation piping. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#recirculation-in-unit'>Recirculation (In-Unit)</a>) is used. + If the distribution system is Recirculation, the length of the recirculation piping. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#recirculation-in-unit'>Recirculation (In-Unit)</a>) is used. Double ft false @@ -4872,7 +4872,7 @@ hot_water_distribution_recirc_branch_piping_length Hot Water Distribution: Recirculation Branch Piping Length - If the distribution system is Recirculation, the length of the recirculation branch piping. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#recirculation-in-unit'>Recirculation (In-Unit)</a>) is used. + If the distribution system is Recirculation, the length of the recirculation branch piping. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#recirculation-in-unit'>Recirculation (In-Unit)</a>) is used. Double ft false @@ -4881,7 +4881,7 @@ hot_water_distribution_recirc_pump_power Hot Water Distribution: Recirculation Pump Power - If the distribution system is Recirculation, the recirculation pump power. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#recirculation-in-unit'>Recirculation (In-Unit)</a>) is used. + If the distribution system is Recirculation, the recirculation pump power. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#recirculation-in-unit'>Recirculation (In-Unit)</a>) is used. Double W false @@ -4890,7 +4890,7 @@ hot_water_distribution_pipe_r Hot Water Distribution: Pipe Insulation Nominal R-Value - Nominal R-value of the pipe insulation. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-hot-water-distribution'>HPXML Hot Water Distribution</a>) is used. + Nominal R-value of the pipe insulation. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-hot-water-distribution'>HPXML Hot Water Distribution</a>) is used. Double h-ft^2-R/Btu false @@ -4989,7 +4989,7 @@ water_fixtures_usage_multiplier Hot Water Fixtures: Usage Multiplier - Multiplier on the hot water usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-water-fixtures'>HPXML Water Fixtures</a>) is used. + Multiplier on the hot water usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-water-fixtures'>HPXML Water Fixtures</a>) is used. Double false false @@ -4997,7 +4997,7 @@ general_water_use_usage_multiplier General Water Use: Usage Multiplier - Multiplier on internal gains from general water use (floor mopping, shower evaporation, water films on showers, tubs & sinks surfaces, plant watering, etc.) that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-building-occupancy'>HPXML Building Occupancy</a>) is used. + Multiplier on internal gains from general water use (floor mopping, shower evaporation, water films on showers, tubs & sinks surfaces, plant watering, etc.) that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-building-occupancy'>HPXML Building Occupancy</a>) is used. Double false false @@ -5124,7 +5124,7 @@ solar_thermal_storage_volume Solar Thermal: Storage Volume - The storage volume of the solar thermal system. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#detailed-inputs'>Detailed Inputs</a>) is used. + The storage volume of the solar thermal system. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#detailed-inputs'>Detailed Inputs</a>) is used. Double gal false @@ -5162,7 +5162,7 @@ pv_system_module_type PV System: Module Type - Module type of the PV system. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-photovoltaics'>HPXML Photovoltaics</a>) is used. + Module type of the PV system. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-photovoltaics'>HPXML Photovoltaics</a>) is used. Choice false false @@ -5184,7 +5184,7 @@ pv_system_location PV System: Location - Location of the PV system. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-photovoltaics'>HPXML Photovoltaics</a>) is used. + Location of the PV system. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-photovoltaics'>HPXML Photovoltaics</a>) is used. Choice false false @@ -5202,7 +5202,7 @@ pv_system_tracking PV System: Tracking - Type of tracking for the PV system. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-photovoltaics'>HPXML Photovoltaics</a>) is used. + Type of tracking for the PV system. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-photovoltaics'>HPXML Photovoltaics</a>) is used. Choice false false @@ -5258,7 +5258,7 @@ pv_system_inverter_efficiency PV System: Inverter Efficiency - Inverter efficiency of the PV system. If there are two PV systems, this will apply to both. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-photovoltaics'>HPXML Photovoltaics</a>) is used. + Inverter efficiency of the PV system. If there are two PV systems, this will apply to both. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-photovoltaics'>HPXML Photovoltaics</a>) is used. Double Frac false @@ -5267,7 +5267,7 @@ pv_system_system_losses_fraction PV System: System Losses Fraction - System losses fraction of the PV system. If there are two PV systems, this will apply to both. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-photovoltaics'>HPXML Photovoltaics</a>) is used. + System losses fraction of the PV system. If there are two PV systems, this will apply to both. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-photovoltaics'>HPXML Photovoltaics</a>) is used. Double Frac false @@ -5304,7 +5304,7 @@ pv_system_2_module_type PV System 2: Module Type - Module type of the second PV system. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-photovoltaics'>HPXML Photovoltaics</a>) is used. + Module type of the second PV system. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-photovoltaics'>HPXML Photovoltaics</a>) is used. Choice false false @@ -5326,7 +5326,7 @@ pv_system_2_location PV System 2: Location - Location of the second PV system. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-photovoltaics'>HPXML Photovoltaics</a>) is used. + Location of the second PV system. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-photovoltaics'>HPXML Photovoltaics</a>) is used. Choice false false @@ -5344,7 +5344,7 @@ pv_system_2_tracking PV System 2: Tracking - Type of tracking for the second PV system. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-photovoltaics'>HPXML Photovoltaics</a>) is used. + Type of tracking for the second PV system. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-photovoltaics'>HPXML Photovoltaics</a>) is used. Choice false false @@ -5419,7 +5419,7 @@ battery_location Battery: Location - The space type for the lithium ion battery location. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-batteries'>HPXML Batteries</a>) is used. + The space type for the lithium ion battery location. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-batteries'>HPXML Batteries</a>) is used. Choice false false @@ -5477,7 +5477,7 @@ battery_power Battery: Rated Power Output - The rated power output of the lithium ion battery. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-batteries'>HPXML Batteries</a>) is used. + The rated power output of the lithium ion battery. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-batteries'>HPXML Batteries</a>) is used. Double W false @@ -5486,7 +5486,7 @@ battery_capacity Battery: Nominal Capacity - The nominal capacity of the lithium ion battery. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-batteries'>HPXML Batteries</a>) is used. + The nominal capacity of the lithium ion battery. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-batteries'>HPXML Batteries</a>) is used. Double kWh false @@ -5495,7 +5495,7 @@ battery_usable_capacity Battery: Usable Capacity - The usable capacity of the lithium ion battery. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-batteries'>HPXML Batteries</a>) is used. + The usable capacity of the lithium ion battery. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-batteries'>HPXML Batteries</a>) is used. Double kWh false @@ -5504,7 +5504,7 @@ battery_round_trip_efficiency Battery: Round Trip Efficiency - The round trip efficiency of the lithium ion battery. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-batteries'>HPXML Batteries</a>) is used. + The round trip efficiency of the lithium ion battery. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-batteries'>HPXML Batteries</a>) is used. Double Frac false @@ -5568,7 +5568,7 @@ lighting_interior_usage_multiplier Lighting: Interior Usage Multiplier - Multiplier on the lighting energy usage (interior) that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-lighting'>HPXML Lighting</a>) is used. + Multiplier on the lighting energy usage (interior) that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-lighting'>HPXML Lighting</a>) is used. Double false false @@ -5603,7 +5603,7 @@ lighting_exterior_usage_multiplier Lighting: Exterior Usage Multiplier - Multiplier on the lighting energy usage (exterior) that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-lighting'>HPXML Lighting</a>) is used. + Multiplier on the lighting energy usage (exterior) that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-lighting'>HPXML Lighting</a>) is used. Double false false @@ -5638,7 +5638,7 @@ lighting_garage_usage_multiplier Lighting: Garage Usage Multiplier - Multiplier on the lighting energy usage (garage) that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-lighting'>HPXML Lighting</a>) is used. + Multiplier on the lighting energy usage (garage) that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-lighting'>HPXML Lighting</a>) is used. Double false false @@ -5665,7 +5665,7 @@ holiday_lighting_daily_kwh Holiday Lighting: Daily Consumption - The daily energy consumption for holiday lighting (exterior). If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-lighting'>HPXML Lighting</a>) is used. + The daily energy consumption for holiday lighting (exterior). If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-lighting'>HPXML Lighting</a>) is used. Double kWh/day false @@ -5674,7 +5674,7 @@ holiday_lighting_period Holiday Lighting: Period - Enter a date range like 'Nov 25 - Jan 5'. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-lighting'>HPXML Lighting</a>) is used. + Enter a date range like 'Nov 25 - Jan 5'. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-lighting'>HPXML Lighting</a>) is used. String false false @@ -5783,7 +5783,7 @@ clothes_washer_location Clothes Washer: Location - The space type for the clothes washer location. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-clothes-washer'>HPXML Clothes Washer</a>) is used. + The space type for the clothes washer location. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-clothes-washer'>HPXML Clothes Washer</a>) is used. Choice false false @@ -5844,7 +5844,7 @@ clothes_washer_efficiency Clothes Washer: Efficiency - The efficiency of the clothes washer. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-clothes-washer'>HPXML Clothes Washer</a>) is used. + The efficiency of the clothes washer. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-clothes-washer'>HPXML Clothes Washer</a>) is used. Double ft^3/kWh-cyc false @@ -5853,7 +5853,7 @@ clothes_washer_rated_annual_kwh Clothes Washer: Rated Annual Consumption - The annual energy consumed by the clothes washer, as rated, obtained from the EnergyGuide label. This includes both the appliance electricity consumption and the energy required for water heating. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-clothes-washer'>HPXML Clothes Washer</a>) is used. + The annual energy consumed by the clothes washer, as rated, obtained from the EnergyGuide label. This includes both the appliance electricity consumption and the energy required for water heating. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-clothes-washer'>HPXML Clothes Washer</a>) is used. Double kWh/yr false @@ -5862,7 +5862,7 @@ clothes_washer_label_electric_rate Clothes Washer: Label Electric Rate - The annual energy consumed by the clothes washer, as rated, obtained from the EnergyGuide label. This includes both the appliance electricity consumption and the energy required for water heating. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-clothes-washer'>HPXML Clothes Washer</a>) is used. + The annual energy consumed by the clothes washer, as rated, obtained from the EnergyGuide label. This includes both the appliance electricity consumption and the energy required for water heating. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-clothes-washer'>HPXML Clothes Washer</a>) is used. Double $/kWh false @@ -5871,7 +5871,7 @@ clothes_washer_label_gas_rate Clothes Washer: Label Gas Rate - The annual energy consumed by the clothes washer, as rated, obtained from the EnergyGuide label. This includes both the appliance electricity consumption and the energy required for water heating. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-clothes-washer'>HPXML Clothes Washer</a>) is used. + The annual energy consumed by the clothes washer, as rated, obtained from the EnergyGuide label. This includes both the appliance electricity consumption and the energy required for water heating. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-clothes-washer'>HPXML Clothes Washer</a>) is used. Double $/therm false @@ -5880,7 +5880,7 @@ clothes_washer_label_annual_gas_cost Clothes Washer: Label Annual Cost with Gas DHW - The annual cost of using the system under test conditions. Input is obtained from the EnergyGuide label. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-clothes-washer'>HPXML Clothes Washer</a>) is used. + The annual cost of using the system under test conditions. Input is obtained from the EnergyGuide label. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-clothes-washer'>HPXML Clothes Washer</a>) is used. Double $ false @@ -5889,7 +5889,7 @@ clothes_washer_label_usage Clothes Washer: Label Usage - The clothes washer loads per week. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-clothes-washer'>HPXML Clothes Washer</a>) is used. + The clothes washer loads per week. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-clothes-washer'>HPXML Clothes Washer</a>) is used. Double cyc/wk false @@ -5898,7 +5898,7 @@ clothes_washer_capacity Clothes Washer: Drum Volume - Volume of the washer drum. Obtained from the EnergyStar website or the manufacturer's literature. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-clothes-washer'>HPXML Clothes Washer</a>) is used. + Volume of the washer drum. Obtained from the EnergyStar website or the manufacturer's literature. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-clothes-washer'>HPXML Clothes Washer</a>) is used. Double ft^3 false @@ -5907,7 +5907,7 @@ clothes_washer_usage_multiplier Clothes Washer: Usage Multiplier - Multiplier on the clothes washer energy and hot water usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-clothes-washer'>HPXML Clothes Washer</a>) is used. + Multiplier on the clothes washer energy and hot water usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-clothes-washer'>HPXML Clothes Washer</a>) is used. Double false false @@ -5934,7 +5934,7 @@ clothes_dryer_location Clothes Dryer: Location - The space type for the clothes dryer location. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-clothes-dryer'>HPXML Clothes Dryer</a>) is used. + The space type for the clothes dryer location. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-clothes-dryer'>HPXML Clothes Dryer</a>) is used. Choice false false @@ -6030,7 +6030,7 @@ clothes_dryer_efficiency Clothes Dryer: Efficiency - The efficiency of the clothes dryer. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-clothes-dryer'>HPXML Clothes Dryer</a>) is used. + The efficiency of the clothes dryer. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-clothes-dryer'>HPXML Clothes Dryer</a>) is used. Double lb/kWh false @@ -6039,7 +6039,7 @@ clothes_dryer_vented_flow_rate Clothes Dryer: Vented Flow Rate - The exhaust flow rate of the vented clothes dryer. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-clothes-dryer'>HPXML Clothes Dryer</a>) is used. + The exhaust flow rate of the vented clothes dryer. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-clothes-dryer'>HPXML Clothes Dryer</a>) is used. Double CFM false @@ -6048,7 +6048,7 @@ clothes_dryer_usage_multiplier Clothes Dryer: Usage Multiplier - Multiplier on the clothes dryer energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-clothes-dryer'>HPXML Clothes Dryer</a>) is used. + Multiplier on the clothes dryer energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-clothes-dryer'>HPXML Clothes Dryer</a>) is used. Double false false @@ -6075,7 +6075,7 @@ dishwasher_location Dishwasher: Location - The space type for the dishwasher location. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-dishwasher'>HPXML Dishwasher</a>) is used. + The space type for the dishwasher location. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-dishwasher'>HPXML Dishwasher</a>) is used. Choice false false @@ -6136,7 +6136,7 @@ dishwasher_efficiency Dishwasher: Efficiency - The efficiency of the dishwasher. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-dishwasher'>HPXML Dishwasher</a>) is used. + The efficiency of the dishwasher. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-dishwasher'>HPXML Dishwasher</a>) is used. Double RatedAnnualkWh or EnergyFactor false @@ -6145,7 +6145,7 @@ dishwasher_label_electric_rate Dishwasher: Label Electric Rate - The label electric rate of the dishwasher. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-dishwasher'>HPXML Dishwasher</a>) is used. + The label electric rate of the dishwasher. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-dishwasher'>HPXML Dishwasher</a>) is used. Double $/kWh false @@ -6154,7 +6154,7 @@ dishwasher_label_gas_rate Dishwasher: Label Gas Rate - The label gas rate of the dishwasher. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-dishwasher'>HPXML Dishwasher</a>) is used. + The label gas rate of the dishwasher. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-dishwasher'>HPXML Dishwasher</a>) is used. Double $/therm false @@ -6163,7 +6163,7 @@ dishwasher_label_annual_gas_cost Dishwasher: Label Annual Gas Cost - The label annual gas cost of the dishwasher. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-dishwasher'>HPXML Dishwasher</a>) is used. + The label annual gas cost of the dishwasher. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-dishwasher'>HPXML Dishwasher</a>) is used. Double $ false @@ -6172,7 +6172,7 @@ dishwasher_label_usage Dishwasher: Label Usage - The dishwasher loads per week. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-dishwasher'>HPXML Dishwasher</a>) is used. + The dishwasher loads per week. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-dishwasher'>HPXML Dishwasher</a>) is used. Double cyc/wk false @@ -6181,7 +6181,7 @@ dishwasher_place_setting_capacity Dishwasher: Number of Place Settings - The number of place settings for the unit. Data obtained from manufacturer's literature. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-dishwasher'>HPXML Dishwasher</a>) is used. + The number of place settings for the unit. Data obtained from manufacturer's literature. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-dishwasher'>HPXML Dishwasher</a>) is used. Integer # false @@ -6190,7 +6190,7 @@ dishwasher_usage_multiplier Dishwasher: Usage Multiplier - Multiplier on the dishwasher energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-dishwasher'>HPXML Dishwasher</a>) is used. + Multiplier on the dishwasher energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-dishwasher'>HPXML Dishwasher</a>) is used. Double false false @@ -6217,7 +6217,7 @@ refrigerator_location Refrigerator: Location - The space type for the refrigerator location. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-refrigerators'>HPXML Refrigerators</a>) is used. + The space type for the refrigerator location. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-refrigerators'>HPXML Refrigerators</a>) is used. Choice false false @@ -6259,7 +6259,7 @@ refrigerator_rated_annual_kwh Refrigerator: Rated Annual Consumption - The EnergyGuide rated annual energy consumption for a refrigerator. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-refrigerators'>HPXML Refrigerators</a>) is used. + The EnergyGuide rated annual energy consumption for a refrigerator. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-refrigerators'>HPXML Refrigerators</a>) is used. Double kWh/yr false @@ -6268,7 +6268,7 @@ refrigerator_usage_multiplier Refrigerator: Usage Multiplier - Multiplier on the refrigerator energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-refrigerators'>HPXML Refrigerators</a>) is used. + Multiplier on the refrigerator energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-refrigerators'>HPXML Refrigerators</a>) is used. Double false false @@ -6295,7 +6295,7 @@ extra_refrigerator_location Extra Refrigerator: Location - The space type for the extra refrigerator location. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-refrigerators'>HPXML Refrigerators</a>) is used. + The space type for the extra refrigerator location. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-refrigerators'>HPXML Refrigerators</a>) is used. Choice false false @@ -6337,7 +6337,7 @@ extra_refrigerator_rated_annual_kwh Extra Refrigerator: Rated Annual Consumption - The EnergyGuide rated annual energy consumption for an extra refrigerator. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-refrigerators'>HPXML Refrigerators</a>) is used. + The EnergyGuide rated annual energy consumption for an extra refrigerator. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-refrigerators'>HPXML Refrigerators</a>) is used. Double kWh/yr false @@ -6346,7 +6346,7 @@ extra_refrigerator_usage_multiplier Extra Refrigerator: Usage Multiplier - Multiplier on the extra refrigerator energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-refrigerators'>HPXML Refrigerators</a>) is used. + Multiplier on the extra refrigerator energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-refrigerators'>HPXML Refrigerators</a>) is used. Double false false @@ -6373,7 +6373,7 @@ freezer_location Freezer: Location - The space type for the freezer location. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-freezers'>HPXML Freezers</a>) is used. + The space type for the freezer location. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-freezers'>HPXML Freezers</a>) is used. Choice false false @@ -6415,7 +6415,7 @@ freezer_rated_annual_kwh Freezer: Rated Annual Consumption - The EnergyGuide rated annual energy consumption for a freezer. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-freezers'>HPXML Freezers</a>) is used. + The EnergyGuide rated annual energy consumption for a freezer. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-freezers'>HPXML Freezers</a>) is used. Double kWh/yr false @@ -6424,7 +6424,7 @@ freezer_usage_multiplier Freezer: Usage Multiplier - Multiplier on the freezer energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-freezers'>HPXML Freezers</a>) is used. + Multiplier on the freezer energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-freezers'>HPXML Freezers</a>) is used. Double false false @@ -6451,7 +6451,7 @@ cooking_range_oven_location Cooking Range/Oven: Location - The space type for the cooking range/oven location. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-cooking-range-oven'>HPXML Cooking Range/Oven</a>) is used. + The space type for the cooking range/oven location. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-cooking-range-oven'>HPXML Cooking Range/Oven</a>) is used. Choice false false @@ -6528,7 +6528,7 @@ cooking_range_oven_is_induction Cooking Range/Oven: Is Induction - Whether the cooking range is induction. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-cooking-range-oven'>HPXML Cooking Range/Oven</a>) is used. + Whether the cooking range is induction. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-cooking-range-oven'>HPXML Cooking Range/Oven</a>) is used. Boolean false false @@ -6546,7 +6546,7 @@ cooking_range_oven_is_convection Cooking Range/Oven: Is Convection - Whether the oven is convection. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-cooking-range-oven'>HPXML Cooking Range/Oven</a>) is used. + Whether the oven is convection. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-cooking-range-oven'>HPXML Cooking Range/Oven</a>) is used. Boolean false false @@ -6564,7 +6564,7 @@ cooking_range_oven_usage_multiplier Cooking Range/Oven: Usage Multiplier - Multiplier on the cooking range/oven energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-cooking-range-oven'>HPXML Cooking Range/Oven</a>) is used. + Multiplier on the cooking range/oven energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-cooking-range-oven'>HPXML Cooking Range/Oven</a>) is used. Double false false @@ -6591,7 +6591,7 @@ ceiling_fan_label_energy_use Ceiling Fan: Label Energy Use - The label average energy use of the ceiling fan(s). If neither Efficiency nor Label Energy Use provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-ceiling-fans'>HPXML Ceiling Fans</a>) is used. + The label average energy use of the ceiling fan(s). If neither Efficiency nor Label Energy Use provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-ceiling-fans'>HPXML Ceiling Fans</a>) is used. Double W false @@ -6600,7 +6600,7 @@ ceiling_fan_efficiency Ceiling Fan: Efficiency - The efficiency rating of the ceiling fan(s) at medium speed. Only used if Label Energy Use not provided. If neither Efficiency nor Label Energy Use provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-ceiling-fans'>HPXML Ceiling Fans</a>) is used. + The efficiency rating of the ceiling fan(s) at medium speed. Only used if Label Energy Use not provided. If neither Efficiency nor Label Energy Use provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-ceiling-fans'>HPXML Ceiling Fans</a>) is used. Double CFM/W false @@ -6609,7 +6609,7 @@ ceiling_fan_quantity Ceiling Fan: Quantity - Total number of ceiling fans. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-ceiling-fans'>HPXML Ceiling Fans</a>) is used. + Total number of ceiling fans. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-ceiling-fans'>HPXML Ceiling Fans</a>) is used. Integer # false @@ -6618,7 +6618,7 @@ ceiling_fan_cooling_setpoint_temp_offset Ceiling Fan: Cooling Setpoint Temperature Offset - The cooling setpoint temperature offset during months when the ceiling fans are operating. Only applies if ceiling fan quantity is greater than zero. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-ceiling-fans'>HPXML Ceiling Fans</a>) is used. + The cooling setpoint temperature offset during months when the ceiling fans are operating. Only applies if ceiling fan quantity is greater than zero. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-ceiling-fans'>HPXML Ceiling Fans</a>) is used. Double F false @@ -6646,7 +6646,7 @@ misc_plug_loads_television_annual_kwh Misc Plug Loads: Television Annual kWh - The annual energy consumption of the television plug loads. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-plug-loads'>HPXML Plug Loads</a>) is used. + The annual energy consumption of the television plug loads. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-plug-loads'>HPXML Plug Loads</a>) is used. Double kWh/yr false @@ -6655,7 +6655,7 @@ misc_plug_loads_television_usage_multiplier Misc Plug Loads: Television Usage Multiplier - Multiplier on the television energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-plug-loads'>HPXML Plug Loads</a>) is used. + Multiplier on the television energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-plug-loads'>HPXML Plug Loads</a>) is used. Double false false @@ -6663,7 +6663,7 @@ misc_plug_loads_other_annual_kwh Misc Plug Loads: Other Annual kWh - The annual energy consumption of the other residual plug loads. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-plug-loads'>HPXML Plug Loads</a>) is used. + The annual energy consumption of the other residual plug loads. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-plug-loads'>HPXML Plug Loads</a>) is used. Double kWh/yr false @@ -6672,7 +6672,7 @@ misc_plug_loads_other_frac_sensible Misc Plug Loads: Other Sensible Fraction - Fraction of other residual plug loads' internal gains that are sensible. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-plug-loads'>HPXML Plug Loads</a>) is used. + Fraction of other residual plug loads' internal gains that are sensible. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-plug-loads'>HPXML Plug Loads</a>) is used. Double Frac false @@ -6681,7 +6681,7 @@ misc_plug_loads_other_frac_latent Misc Plug Loads: Other Latent Fraction - Fraction of other residual plug loads' internal gains that are latent. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-plug-loads'>HPXML Plug Loads</a>) is used. + Fraction of other residual plug loads' internal gains that are latent. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-plug-loads'>HPXML Plug Loads</a>) is used. Double Frac false @@ -6690,7 +6690,7 @@ misc_plug_loads_other_usage_multiplier Misc Plug Loads: Other Usage Multiplier - Multiplier on the other energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-plug-loads'>HPXML Plug Loads</a>) is used. + Multiplier on the other energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-plug-loads'>HPXML Plug Loads</a>) is used. Double false false @@ -6717,7 +6717,7 @@ misc_plug_loads_well_pump_annual_kwh Misc Plug Loads: Well Pump Annual kWh - The annual energy consumption of the well pump plug loads. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-plug-loads'>HPXML Plug Loads</a>) is used. + The annual energy consumption of the well pump plug loads. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-plug-loads'>HPXML Plug Loads</a>) is used. Double kWh/yr false @@ -6726,7 +6726,7 @@ misc_plug_loads_well_pump_usage_multiplier Misc Plug Loads: Well Pump Usage Multiplier - Multiplier on the well pump energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-plug-loads'>HPXML Plug Loads</a>) is used. + Multiplier on the well pump energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-plug-loads'>HPXML Plug Loads</a>) is used. Double false false @@ -6753,7 +6753,7 @@ misc_plug_loads_vehicle_annual_kwh Misc Plug Loads: Vehicle Annual kWh - The annual energy consumption of the electric vehicle plug loads. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-plug-loads'>HPXML Plug Loads</a>) is used. + The annual energy consumption of the electric vehicle plug loads. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-plug-loads'>HPXML Plug Loads</a>) is used. Double kWh/yr false @@ -6762,7 +6762,7 @@ misc_plug_loads_vehicle_usage_multiplier Misc Plug Loads: Vehicle Usage Multiplier - Multiplier on the electric vehicle energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-plug-loads'>HPXML Plug Loads</a>) is used. + Multiplier on the electric vehicle energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-plug-loads'>HPXML Plug Loads</a>) is used. Double false false @@ -6820,7 +6820,7 @@ misc_fuel_loads_grill_annual_therm Misc Fuel Loads: Grill Annual therm - The annual energy consumption of the fuel loads grill. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-fuel-loads'>HPXML Fuel Loads</a>) is used. + The annual energy consumption of the fuel loads grill. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-fuel-loads'>HPXML Fuel Loads</a>) is used. Double therm/yr false @@ -6829,7 +6829,7 @@ misc_fuel_loads_grill_usage_multiplier Misc Fuel Loads: Grill Usage Multiplier - Multiplier on the fuel loads grill energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-fuel-loads'>HPXML Fuel Loads</a>) is used. + Multiplier on the fuel loads grill energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-fuel-loads'>HPXML Fuel Loads</a>) is used. Double false false @@ -6887,7 +6887,7 @@ misc_fuel_loads_lighting_annual_therm Misc Fuel Loads: Lighting Annual therm - The annual energy consumption of the fuel loads lighting. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-fuel-loads'>HPXML Fuel Loads</a>)is used. + The annual energy consumption of the fuel loads lighting. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-fuel-loads'>HPXML Fuel Loads</a>)is used. Double therm/yr false @@ -6896,7 +6896,7 @@ misc_fuel_loads_lighting_usage_multiplier Misc Fuel Loads: Lighting Usage Multiplier - Multiplier on the fuel loads lighting energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-fuel-loads'>HPXML Fuel Loads</a>) is used. + Multiplier on the fuel loads lighting energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-fuel-loads'>HPXML Fuel Loads</a>) is used. Double false false @@ -6954,7 +6954,7 @@ misc_fuel_loads_fireplace_annual_therm Misc Fuel Loads: Fireplace Annual therm - The annual energy consumption of the fuel loads fireplace. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-fuel-loads'>HPXML Fuel Loads</a>) is used. + The annual energy consumption of the fuel loads fireplace. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-fuel-loads'>HPXML Fuel Loads</a>) is used. Double therm/yr false @@ -6963,7 +6963,7 @@ misc_fuel_loads_fireplace_frac_sensible Misc Fuel Loads: Fireplace Sensible Fraction - Fraction of fireplace residual fuel loads' internal gains that are sensible. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-fuel-loads'>HPXML Fuel Loads</a>) is used. + Fraction of fireplace residual fuel loads' internal gains that are sensible. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-fuel-loads'>HPXML Fuel Loads</a>) is used. Double Frac false @@ -6972,7 +6972,7 @@ misc_fuel_loads_fireplace_frac_latent Misc Fuel Loads: Fireplace Latent Fraction - Fraction of fireplace residual fuel loads' internal gains that are latent. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-fuel-loads'>HPXML Fuel Loads</a>) is used. + Fraction of fireplace residual fuel loads' internal gains that are latent. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-fuel-loads'>HPXML Fuel Loads</a>) is used. Double Frac false @@ -6981,7 +6981,7 @@ misc_fuel_loads_fireplace_usage_multiplier Misc Fuel Loads: Fireplace Usage Multiplier - Multiplier on the fuel loads fireplace energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#hpxml-fuel-loads'>HPXML Fuel Loads</a>) is used. + Multiplier on the fuel loads fireplace energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#hpxml-fuel-loads'>HPXML Fuel Loads</a>) is used. Double false false @@ -7008,7 +7008,7 @@ pool_pump_annual_kwh Pool: Pump Annual kWh - The annual energy consumption of the pool pump. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#pool-pump'>Pool Pump</a>) is used. + The annual energy consumption of the pool pump. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#pool-pump'>Pool Pump</a>) is used. Double kWh/yr false @@ -7017,7 +7017,7 @@ pool_pump_usage_multiplier Pool: Pump Usage Multiplier - Multiplier on the pool pump energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#pool-pump'>Pool Pump</a>) is used. + Multiplier on the pool pump energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#pool-pump'>Pool Pump</a>) is used. Double false false @@ -7052,7 +7052,7 @@ pool_heater_annual_kwh Pool: Heater Annual kWh - The annual energy consumption of the electric resistance pool heater. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#pool-heater'>Pool Heater</a>) is used. + The annual energy consumption of the electric resistance pool heater. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#pool-heater'>Pool Heater</a>) is used. Double kWh/yr false @@ -7061,7 +7061,7 @@ pool_heater_annual_therm Pool: Heater Annual therm - The annual energy consumption of the gas fired pool heater. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#pool-heater'>Pool Heater</a>) is used. + The annual energy consumption of the gas fired pool heater. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#pool-heater'>Pool Heater</a>) is used. Double therm/yr false @@ -7070,7 +7070,7 @@ pool_heater_usage_multiplier Pool: Heater Usage Multiplier - Multiplier on the pool heater energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#pool-heater'>Pool Heater</a>) is used. + Multiplier on the pool heater energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#pool-heater'>Pool Heater</a>) is used. Double false false @@ -7097,7 +7097,7 @@ permanent_spa_pump_annual_kwh Permanent Spa: Pump Annual kWh - The annual energy consumption of the permanent spa pump. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#permanent-spa-pump'>Permanent Spa Pump</a>) is used. + The annual energy consumption of the permanent spa pump. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#permanent-spa-pump'>Permanent Spa Pump</a>) is used. Double kWh/yr false @@ -7106,7 +7106,7 @@ permanent_spa_pump_usage_multiplier Permanent Spa: Pump Usage Multiplier - Multiplier on the permanent spa pump energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#permanent-spa-pump'>Permanent Spa Pump</a>) is used. + Multiplier on the permanent spa pump energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#permanent-spa-pump'>Permanent Spa Pump</a>) is used. Double false false @@ -7141,7 +7141,7 @@ permanent_spa_heater_annual_kwh Permanent Spa: Heater Annual kWh - The annual energy consumption of the electric resistance permanent spa heater. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#permanent-spa-heater'>Permanent Spa Heater</a>) is used. + The annual energy consumption of the electric resistance permanent spa heater. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#permanent-spa-heater'>Permanent Spa Heater</a>) is used. Double kWh/yr false @@ -7150,7 +7150,7 @@ permanent_spa_heater_annual_therm Permanent Spa: Heater Annual therm - The annual energy consumption of the gas fired permanent spa heater. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#permanent-spa-heater'>Permanent Spa Heater</a>) is used. + The annual energy consumption of the gas fired permanent spa heater. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#permanent-spa-heater'>Permanent Spa Heater</a>) is used. Double therm/yr false @@ -7159,7 +7159,7 @@ permanent_spa_heater_usage_multiplier Permanent Spa: Heater Usage Multiplier - Multiplier on the permanent spa heater energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.8.1/workflow_inputs.html#permanent-spa-heater'>Permanent Spa Heater</a>) is used. + Multiplier on the permanent spa heater energy usage that can reflect, e.g., high/low usage occupants. If not provided, the OS-HPXML default (see <a href='https://openstudio-hpxml.readthedocs.io/en/v1.10.0/workflow_inputs.html#permanent-spa-heater'>Permanent Spa Heater</a>) is used. Double false false @@ -7527,7 +7527,7 @@ README.md md readme - 25110074 + ECAEDA1E README.md.erb @@ -7544,7 +7544,7 @@ measure.rb rb script - 79912FCC + 612549F4 constants.rb @@ -7556,13 +7556,13 @@ geometry.rb rb resource - E50F00EB + 425682E4 test_build_residential_hpxml.rb rb test - 04146810 + CCBB49E7 diff --git a/resources/hpxml-measures/BuildResidentialHPXML/resources/geometry.rb b/resources/hpxml-measures/BuildResidentialHPXML/resources/geometry.rb index cba189f455..6bf1d4ef74 100644 --- a/resources/hpxml-measures/BuildResidentialHPXML/resources/geometry.rb +++ b/resources/hpxml-measures/BuildResidentialHPXML/resources/geometry.rb @@ -268,7 +268,8 @@ def self.create_single_family_detached(runner:, # make polygons polygon_floor = make_polygon(roof_nw_point, roof_ne_point, roof_se_point, roof_sw_point) side_type = nil - if roof_type == Constants::RoofTypeGable + case roof_type + when Constants::RoofTypeGable if length >= width roof_w_point = OpenStudio::Point3d.new(0, width / 2.0, z + attic_height) roof_e_point = OpenStudio::Point3d.new(length, width / 2.0, z + attic_height) @@ -285,7 +286,7 @@ def self.create_single_family_detached(runner:, polygon_e_wall = make_polygon(roof_e_point, roof_ne_point, roof_nw_point) end side_type = EPlus::SurfaceTypeWall - elsif roof_type == Constants::RoofTypeHip + when Constants::RoofTypeHip if length >= width roof_w_point = OpenStudio::Point3d.new(width / 2.0, width / 2.0, z + attic_height) roof_e_point = OpenStudio::Point3d.new(length - width / 2.0, width / 2.0, z + attic_height) @@ -330,7 +331,8 @@ def self.create_single_family_detached(runner:, surface_e_wall.setSpace(attic_space) # set these to the attic zone - if (attic_type == HPXML::AtticTypeVented) || (attic_type == HPXML::AtticTypeUnvented) + case attic_type + when HPXML::AtticTypeVented, HPXML::AtticTypeUnvented # create attic zone attic_zone = OpenStudio::Model::ThermalZone.new(model) attic_space.setThermalZone(attic_zone) @@ -340,7 +342,7 @@ def self.create_single_family_detached(runner:, attic_space_name = HPXML::LocationAtticUnvented end attic_zone.setName(attic_space_name) - elsif attic_type == HPXML::AtticTypeConditioned + when HPXML::AtticTypeConditioned attic_space.setThermalZone(conditioned_zone) attic_space_name = HPXML::LocationConditionedSpace end @@ -379,20 +381,23 @@ def self.create_single_family_detached(runner:, foundation_space = OpenStudio::Model::Space::fromFloorPrint(foundation_polygon, foundation_height, model) foundation_space = foundation_space.get assign_indexes(model: model, footprint_polygon: foundation_polygon, space: foundation_space) - if foundation_type == HPXML::FoundationTypeCrawlspaceVented + case foundation_type + when HPXML::FoundationTypeCrawlspaceVented foundation_space_name = HPXML::LocationCrawlspaceVented - elsif foundation_type == HPXML::FoundationTypeCrawlspaceUnvented + when HPXML::FoundationTypeCrawlspaceUnvented foundation_space_name = HPXML::LocationCrawlspaceUnvented - elsif foundation_type == HPXML::FoundationTypeCrawlspaceConditioned + when HPXML::FoundationTypeCrawlspaceConditioned foundation_space_name = HPXML::LocationCrawlspaceConditioned - elsif foundation_type == HPXML::FoundationTypeBasementUnconditioned + when HPXML::FoundationTypeBasementUnconditioned foundation_space_name = HPXML::LocationBasementUnconditioned - elsif foundation_type == HPXML::FoundationTypeBasementConditioned + when HPXML::FoundationTypeBasementConditioned foundation_space_name = HPXML::LocationBasementConditioned - elsif foundation_type == HPXML::FoundationTypeAmbient + when HPXML::FoundationTypeAmbient foundation_space_name = HPXML::LocationOutside - elsif foundation_type.start_with?(HPXML::FoundationTypeBellyAndWing) - foundation_space_name = HPXML::LocationManufacturedHomeUnderBelly + else + if foundation_type.start_with? HPXML::FoundationTypeBellyAndWing + foundation_space_name = HPXML::LocationManufacturedHomeUnderBelly + end end foundation_zone.setName(foundation_space_name) foundation_space.setName(foundation_space_name) @@ -814,17 +819,18 @@ def self.create_single_family_attached(model:, # create foundation zone foundation_zone = OpenStudio::Model::ThermalZone.new(model) - if foundation_type == HPXML::FoundationTypeCrawlspaceVented + case foundation_type + when HPXML::FoundationTypeCrawlspaceVented foundation_space_name = HPXML::LocationCrawlspaceVented - elsif foundation_type == HPXML::FoundationTypeCrawlspaceUnvented + when HPXML::FoundationTypeCrawlspaceUnvented foundation_space_name = HPXML::LocationCrawlspaceUnvented - elsif foundation_type == HPXML::FoundationTypeCrawlspaceConditioned + when HPXML::FoundationTypeCrawlspaceConditioned foundation_space_name = HPXML::LocationCrawlspaceConditioned - elsif foundation_type == HPXML::FoundationTypeBasementUnconditioned + when HPXML::FoundationTypeBasementUnconditioned foundation_space_name = HPXML::LocationBasementUnconditioned - elsif foundation_type == HPXML::FoundationTypeBasementConditioned + when HPXML::FoundationTypeBasementConditioned foundation_space_name = HPXML::LocationBasementConditioned - elsif foundation_type == HPXML::FoundationTypeAmbient + when HPXML::FoundationTypeAmbient foundation_space_name = HPXML::LocationOutside end foundation_zone.setName(foundation_space_name) @@ -889,7 +895,8 @@ def self.create_single_family_attached(model:, attic_space = get_attic_space(model: model, x: x, y: y, average_ceiling_height: average_ceiling_height, num_floors: num_floors, roof_pitch: roof_pitch, roof_type: roof_type, rim_joist_height: rim_joist_height) # set these to the attic zone - if (attic_type == HPXML::AtticTypeVented) || (attic_type == HPXML::AtticTypeUnvented) + case attic_type + when HPXML::AtticTypeVented, HPXML::AtticTypeUnvented # create attic zone attic_zone = OpenStudio::Model::ThermalZone.new(model) attic_space.setThermalZone(attic_zone) @@ -1106,17 +1113,18 @@ def self.create_apartment(model:, # create foundation zone foundation_zone = OpenStudio::Model::ThermalZone.new(model) - if foundation_type == HPXML::FoundationTypeCrawlspaceVented + case foundation_type + when HPXML::FoundationTypeCrawlspaceVented foundation_space_name = HPXML::LocationCrawlspaceVented - elsif foundation_type == HPXML::FoundationTypeCrawlspaceUnvented + when HPXML::FoundationTypeCrawlspaceUnvented foundation_space_name = HPXML::LocationCrawlspaceUnvented - elsif foundation_type == HPXML::FoundationTypeCrawlspaceConditioned + when HPXML::FoundationTypeCrawlspaceConditioned foundation_space_name = HPXML::LocationCrawlspaceConditioned - elsif foundation_type == HPXML::FoundationTypeBasementUnconditioned + when HPXML::FoundationTypeBasementUnconditioned foundation_space_name = HPXML::LocationBasementUnconditioned - elsif foundation_type == HPXML::FoundationTypeBasementConditioned + when HPXML::FoundationTypeBasementConditioned foundation_space_name = HPXML::LocationBasementConditioned - elsif foundation_type == HPXML::FoundationTypeAmbient + when HPXML::FoundationTypeAmbient foundation_space_name = HPXML::LocationOutside end foundation_zone.setName(foundation_space_name) @@ -1179,7 +1187,8 @@ def self.create_apartment(model:, attic_space = get_attic_space(model: model, x: x, y: y, average_ceiling_height: average_ceiling_height, num_floors: num_floors, roof_pitch: roof_pitch, roof_type: roof_type, rim_joist_height: rim_joist_height) # set these to the attic zone - if (attic_type == HPXML::AtticTypeVented) || (attic_type == HPXML::AtticTypeUnvented) + case attic_type + when HPXML::AtticTypeVented, HPXML::AtticTypeUnvented # create attic zone attic_zone = OpenStudio::Model::ThermalZone.new(model) attic_space.setThermalZone(attic_zone) @@ -1326,16 +1335,17 @@ def self.create_doors(runner:, # Convert to 3D geometry; assign to surface door_polygon = OpenStudio::Point3dVector.new - if facade == Constants::FacadeFront + case facade + when Constants::FacadeFront multx = 1 multy = 0 - elsif facade == Constants::FacadeBack + when Constants::FacadeBack multx = -1 multy = 0 - elsif facade == Constants::FacadeLeft + when Constants::FacadeLeft multx = 0 multy = -1 - elsif facade == Constants::FacadeRight + when Constants::FacadeRight multx = 0 multy = 1 end @@ -1602,19 +1612,20 @@ def self.create_windows_and_skylights(runner:, leftx = skylight_bottom_left.x lefty = skylight_bottom_left.y bottomz = skylight_bottom_left.z - if (facade == Constants::FacadeFront) || (facade == Constants::FacadeNone) + case facade + when Constants::FacadeFront, Constants::FacadeNone skylight_top_left = OpenStudio::Point3d.new(leftx, lefty + Math.cos(surface.tilt) * skylight_length, bottomz + Math.sin(surface.tilt) * skylight_length) skylight_top_right = OpenStudio::Point3d.new(leftx + skylight_width, lefty + Math.cos(surface.tilt) * skylight_length, bottomz + Math.sin(surface.tilt) * skylight_length) skylight_bottom_right = OpenStudio::Point3d.new(leftx + skylight_width, lefty, bottomz) - elsif facade == Constants::FacadeBack + when Constants::FacadeBack skylight_top_left = OpenStudio::Point3d.new(leftx, lefty - Math.cos(surface.tilt) * skylight_length, bottomz + Math.sin(surface.tilt) * skylight_length) skylight_top_right = OpenStudio::Point3d.new(leftx - skylight_width, lefty - Math.cos(surface.tilt) * skylight_length, bottomz + Math.sin(surface.tilt) * skylight_length) skylight_bottom_right = OpenStudio::Point3d.new(leftx - skylight_width, lefty, bottomz) - elsif facade == Constants::FacadeLeft + when Constants::FacadeLeft skylight_top_left = OpenStudio::Point3d.new(leftx + Math.cos(surface.tilt) * skylight_length, lefty, bottomz + Math.sin(surface.tilt) * skylight_length) skylight_top_right = OpenStudio::Point3d.new(leftx + Math.cos(surface.tilt) * skylight_length, lefty - skylight_width, bottomz + Math.sin(surface.tilt) * skylight_length) skylight_bottom_right = OpenStudio::Point3d.new(leftx, lefty - skylight_width, bottomz) - elsif facade == Constants::FacadeRight + when Constants::FacadeRight skylight_top_left = OpenStudio::Point3d.new(leftx - Math.cos(surface.tilt) * skylight_length, lefty, bottomz + Math.sin(surface.tilt) * skylight_length) skylight_top_right = OpenStudio::Point3d.new(leftx - Math.cos(surface.tilt) * skylight_length, lefty + skylight_width, bottomz + Math.sin(surface.tilt) * skylight_length) skylight_bottom_right = OpenStudio::Point3d.new(leftx, lefty + skylight_width, bottomz) @@ -1802,13 +1813,14 @@ def self.get_facade_for_surface(surface:) # @return [Double] the absolute azimuth based on relative azimuth of the facade and building orientation def self.get_azimuth_from_facade(facade:, orientation:) - if facade == Constants::FacadeFront + case facade + when Constants::FacadeFront return get_abs_azimuth(relative_azimuth: 0, building_orientation: orientation) - elsif facade == Constants::FacadeBack + when Constants::FacadeBack return get_abs_azimuth(relative_azimuth: 180, building_orientation: orientation) - elsif facade == Constants::FacadeLeft + when Constants::FacadeLeft return get_abs_azimuth(relative_azimuth: 90, building_orientation: orientation) - elsif facade == Constants::FacadeRight + when Constants::FacadeRight return get_abs_azimuth(relative_azimuth: 270, building_orientation: orientation) else fail 'Unexpected facade.' @@ -2290,16 +2302,17 @@ def self.add_window_to_wall(surface:, # Convert to 3D geometry; assign to surface window_polygon = OpenStudio::Point3dVector.new - if facade == Constants::FacadeFront + case facade + when Constants::FacadeFront multx = 1 multy = 0 - elsif facade == Constants::FacadeBack + when Constants::FacadeBack multx = -1 multy = 0 - elsif facade == Constants::FacadeLeft + when Constants::FacadeLeft multx = 0 multy = -1 - elsif facade == Constants::FacadeRight + when Constants::FacadeRight multx = 0 multy = 1 end @@ -2458,7 +2471,8 @@ def self.get_attic_space(model:, attic_height = (y_tot / 2.0) * roof_pitch + rim_joist_height # Roof always has same orientation side_type = nil - if roof_type == Constants::RoofTypeGable + case roof_type + when Constants::RoofTypeGable roof_w_point = OpenStudio::Point3d.new(0, y_peak, average_ceiling_height * num_floors + attic_height) roof_e_point = OpenStudio::Point3d.new(x, y_peak, average_ceiling_height * num_floors + attic_height) polygon_w_roof = make_polygon(roof_w_point, roof_e_point, ne_point, nw_point) @@ -2466,7 +2480,7 @@ def self.get_attic_space(model:, polygon_s_wall = make_polygon(roof_w_point, nw_point, sw_point) polygon_n_wall = make_polygon(roof_e_point, se_point, ne_point) side_type = EPlus::SurfaceTypeWall - elsif roof_type == Constants::RoofTypeHip + when Constants::RoofTypeHip if y > 0 if x <= (y + y_rear) roof_n_point = OpenStudio::Point3d.new(x / 2.0, y_rear - x / 2.0, average_ceiling_height * num_floors + attic_height) diff --git a/resources/hpxml-measures/BuildResidentialHPXML/tests/test_build_residential_hpxml.rb b/resources/hpxml-measures/BuildResidentialHPXML/tests/test_build_residential_hpxml.rb index 9b79b0e8b8..06a9471fff 100644 --- a/resources/hpxml-measures/BuildResidentialHPXML/tests/test_build_residential_hpxml.rb +++ b/resources/hpxml-measures/BuildResidentialHPXML/tests/test_build_residential_hpxml.rb @@ -386,6 +386,22 @@ def test_workflows assert_equal(31, hvac_control.seasons_cooling_end_day) end + def test_version + found_match = false + measure_xml_path = File.join(File.dirname(__FILE__), '..', 'measure.xml') + File.readlines(measure_xml_path).each do |xml_line| + next unless xml_line.include? '' + next unless xml_line.include? 'https://openstudio-hpxml.readthedocs.io' + + found_match = true + if not xml_line.include? Version::OS_HPXML_Version + puts "ERROR: Found incorrect OS-HPXML version. Manually edit the BuildResidentialHPXML/measure.rb and run 'openstudio tasks.rb update_measures' to force the measure.xml to be regenerated." + end + assert(xml_line.include? Version::OS_HPXML_Version) + end + assert(found_match) + end + private def _set_measure_argument_values(hpxml_file, args) @@ -394,7 +410,8 @@ def _set_measure_argument_values(hpxml_file, args) args['apply_validation'] = true # Base - if ['base-sfd.xml'].include? hpxml_file + case hpxml_file + when 'base-sfd.xml' args['simulation_control_timestep'] = 60 args['weather_station_epw_filepath'] = 'USA_CO_Denver.Intl.AP.725650_TMY3.epw' args['site_type'] = HPXML::SiteTypeSuburban @@ -669,10 +686,10 @@ def _set_measure_argument_values(hpxml_file, args) args['pool_heater_type'] = HPXML::HeaterTypeElectricResistance args['permanent_spa_present'] = false args['permanent_spa_heater_type'] = HPXML::HeaterTypeElectricResistance - elsif ['base-sfd2.xml'].include? hpxml_file + when 'base-sfd2.xml' args['existing_hpxml_path'] = File.join(File.dirname(__FILE__), 'extra_files/base-sfd.xml') args['whole_sfa_or_mf_building_sim'] = true - elsif ['base-sfa.xml'].include? hpxml_file + when 'base-sfa.xml' args['geometry_unit_type'] = HPXML::ResidentialTypeSFA args['geometry_unit_cfa'] = 1800.0 args['geometry_building_num_units'] = 3 @@ -686,13 +703,13 @@ def _set_measure_argument_values(hpxml_file, args) args['window_area_left'] = 0 args['window_area_right'] = 0 args['air_leakage_type'] = HPXML::InfiltrationTypeUnitTotal - elsif ['base-sfa2.xml'].include? hpxml_file + when 'base-sfa2.xml' args['existing_hpxml_path'] = File.join(File.dirname(__FILE__), 'extra_files/base-sfa.xml') args['whole_sfa_or_mf_building_sim'] = true - elsif ['base-sfa3.xml'].include? hpxml_file + when 'base-sfa3.xml' args['existing_hpxml_path'] = File.join(File.dirname(__FILE__), 'extra_files/base-sfa2.xml') args['whole_sfa_or_mf_building_sim'] = true - elsif ['base-mf.xml'].include? hpxml_file + when 'base-mf.xml' args['geometry_unit_type'] = HPXML::ResidentialTypeApartment args['geometry_unit_cfa'] = 900.0 args['geometry_foundation_type'] = HPXML::FoundationTypeBasementUnconditioned @@ -717,16 +734,16 @@ def _set_measure_argument_values(hpxml_file, args) args['ducts_number_of_return_registers'] = 1 args['door_area'] = 20.0 args['air_leakage_type'] = HPXML::InfiltrationTypeUnitTotal - elsif ['base-mf2.xml'].include? hpxml_file + when 'base-mf2.xml' args['existing_hpxml_path'] = File.join(File.dirname(__FILE__), 'extra_files/base-mf.xml') args['whole_sfa_or_mf_building_sim'] = true - elsif ['base-mf3.xml'].include? hpxml_file + when 'base-mf3.xml' args['existing_hpxml_path'] = File.join(File.dirname(__FILE__), 'extra_files/base-mf2.xml') args['whole_sfa_or_mf_building_sim'] = true - elsif ['base-mf4.xml'].include? hpxml_file + when 'base-mf4.xml' args['existing_hpxml_path'] = File.join(File.dirname(__FILE__), 'extra_files/base-mf3.xml') args['whole_sfa_or_mf_building_sim'] = true - elsif ['base-sfd-header.xml'].include? hpxml_file + when 'base-sfd-header.xml' args['software_info_program_used'] = 'Program' args['software_info_program_version'] = '1' args['schedules_unavailable_period_types'] = 'Vacancy, Power Outage' @@ -742,13 +759,14 @@ def _set_measure_argument_values(hpxml_file, args) args['emissions_fossil_fuel_units'] = 'kg/MBtu' args['emissions_natural_gas_values'] = '2' args['utility_bill_scenario_names'] = 'Bills' - elsif ['base-sfd-header-no-duplicates.xml'].include? hpxml_file + when 'base-sfd-header-no-duplicates.xml' args['existing_hpxml_path'] = File.join(File.dirname(__FILE__), 'extra_files/base-sfd-header.xml') args['whole_sfa_or_mf_building_sim'] = true end # Extras - if ['extra-auto.xml'].include? hpxml_file + case hpxml_file + when 'extra-auto.xml' args.delete('geometry_unit_num_occupants') args.delete('ducts_supply_location') args.delete('ducts_return_location') @@ -760,20 +778,20 @@ def _set_measure_argument_values(hpxml_file, args) args.delete('clothes_washer_location') args.delete('clothes_dryer_location') args.delete('refrigerator_location') - elsif ['extra-auto-duct-locations.xml'].include? hpxml_file + when 'extra-auto-duct-locations.xml' args['ducts_supply_location'] = HPXML::LocationAtticUnvented args['ducts_return_location'] = HPXML::LocationAtticUnvented - elsif ['extra-pv-roofpitch.xml'].include? hpxml_file + when 'extra-pv-roofpitch.xml' args['pv_system_module_type'] = HPXML::PVModuleTypeStandard args['pv_system_2_module_type'] = HPXML::PVModuleTypeStandard args['pv_system_array_tilt'] = 'roofpitch' args['pv_system_2_array_tilt'] = 'roofpitch+15' - elsif ['extra-dhw-solar-latitude.xml'].include? hpxml_file + when 'extra-dhw-solar-latitude.xml' args['solar_thermal_system_type'] = HPXML::SolarThermalSystemTypeHotWater args['solar_thermal_collector_tilt'] = 'Latitude-15' - elsif ['extra-second-refrigerator.xml'].include? hpxml_file + when 'extra-second-refrigerator.xml' args['extra_refrigerator_location'] = HPXML::LocationConditionedSpace - elsif ['extra-second-heating-system-portable-heater-to-heating-system.xml'].include? hpxml_file + when 'extra-second-heating-system-portable-heater-to-heating-system.xml' args['heating_system_fuel'] = HPXML::FuelTypeElectricity args['heating_system_heating_capacity'] = 48000.0 args['heating_system_fraction_heat_load_served'] = 0.75 @@ -783,7 +801,7 @@ def _set_measure_argument_values(hpxml_file, args) args['ducts_return_location'] = HPXML::LocationConditionedSpace args['heating_system_2_type'] = HPXML::HVACTypeSpaceHeater args['heating_system_2_heating_capacity'] = 16000.0 - elsif ['extra-second-heating-system-fireplace-to-heating-system.xml'].include? hpxml_file + when 'extra-second-heating-system-fireplace-to-heating-system.xml' args['heating_system_type'] = HPXML::HVACTypeElectricResistance args['heating_system_fuel'] = HPXML::FuelTypeElectricity args['heating_system_heating_efficiency'] = 1.0 @@ -792,11 +810,11 @@ def _set_measure_argument_values(hpxml_file, args) args['cooling_system_type'] = Constants::None args['heating_system_2_type'] = HPXML::HVACTypeFireplace args['heating_system_2_heating_capacity'] = 16000.0 - elsif ['extra-second-heating-system-boiler-to-heating-system.xml'].include? hpxml_file + when 'extra-second-heating-system-boiler-to-heating-system.xml' args['heating_system_type'] = HPXML::HVACTypeBoiler args['heating_system_fraction_heat_load_served'] = 0.75 args['heating_system_2_type'] = HPXML::HVACTypeBoiler - elsif ['extra-second-heating-system-portable-heater-to-heat-pump.xml'].include? hpxml_file + when 'extra-second-heating-system-portable-heater-to-heat-pump.xml' args['heating_system_type'] = Constants::None args['cooling_system_type'] = Constants::None args['heat_pump_type'] = HPXML::HVACTypeHeatPumpAirToAir @@ -810,7 +828,7 @@ def _set_measure_argument_values(hpxml_file, args) args['ducts_return_location'] = HPXML::LocationConditionedSpace args['heating_system_2_type'] = HPXML::HVACTypeSpaceHeater args['heating_system_2_heating_capacity'] = 16000.0 - elsif ['extra-second-heating-system-fireplace-to-heat-pump.xml'].include? hpxml_file + when 'extra-second-heating-system-fireplace-to-heat-pump.xml' args['heating_system_type'] = Constants::None args['cooling_system_type'] = Constants::None args['heat_pump_type'] = HPXML::HVACTypeHeatPumpMiniSplit @@ -822,7 +840,7 @@ def _set_measure_argument_values(hpxml_file, args) args['heat_pump_fraction_heat_load_served'] = 0.75 args['heating_system_2_type'] = HPXML::HVACTypeFireplace args['heating_system_2_heating_capacity'] = 16000.0 - elsif ['extra-second-heating-system-boiler-to-heat-pump.xml'].include? hpxml_file + when 'extra-second-heating-system-boiler-to-heat-pump.xml' args['heating_system_type'] = Constants::None args['cooling_system_type'] = Constants::None args['heat_pump_type'] = HPXML::HVACTypeHeatPumpGroundToAir @@ -834,15 +852,15 @@ def _set_measure_argument_values(hpxml_file, args) args['heat_pump_backup_fuel'] = HPXML::FuelTypeElectricity args['heat_pump_fraction_heat_load_served'] = 0.75 args['heating_system_2_type'] = HPXML::HVACTypeBoiler - elsif ['extra-enclosure-windows-shading.xml'].include? hpxml_file + when 'extra-enclosure-windows-shading.xml' args['window_interior_shading_winter'] = 0.99 args['window_interior_shading_summer'] = 0.01 args['window_exterior_shading_winter'] = 0.9 args['window_exterior_shading_summer'] = 0.1 - elsif ['extra-enclosure-garage-partially-protruded.xml'].include? hpxml_file + when 'extra-enclosure-garage-partially-protruded.xml' args['geometry_garage_width'] = 12 args['geometry_garage_protrusion'] = 0.5 - elsif ['extra-enclosure-garage-atticroof-conditioned.xml'].include? hpxml_file + when 'extra-enclosure-garage-atticroof-conditioned.xml' args['geometry_garage_width'] = 30.0 args['geometry_garage_protrusion'] = 1.0 args['window_area_front'] = 12.0 @@ -853,7 +871,7 @@ def _set_measure_argument_values(hpxml_file, args) args['floor_over_garage_assembly_r'] = 39.3 args['ducts_supply_location'] = HPXML::LocationGarage args['ducts_return_location'] = HPXML::LocationGarage - elsif ['extra-enclosure-atticroof-conditioned-eaves-gable.xml'].include? hpxml_file + when 'extra-enclosure-atticroof-conditioned-eaves-gable.xml' args['geometry_foundation_type'] = HPXML::FoundationTypeSlab args['geometry_foundation_height'] = 0.0 args['geometry_foundation_height_above_grade'] = 0.0 @@ -864,26 +882,26 @@ def _set_measure_argument_values(hpxml_file, args) args['geometry_eaves_depth'] = 2 args['ducts_supply_location'] = HPXML::LocationUnderSlab args['ducts_return_location'] = HPXML::LocationUnderSlab - elsif ['extra-enclosure-atticroof-conditioned-eaves-hip.xml'].include? hpxml_file + when 'extra-enclosure-atticroof-conditioned-eaves-hip.xml' args['geometry_roof_type'] = Constants::RoofTypeHip - elsif ['extra-gas-pool-heater-with-zero-kwh.xml'].include? hpxml_file + when 'extra-gas-pool-heater-with-zero-kwh.xml' args['pool_present'] = true args['pool_heater_type'] = HPXML::HeaterTypeGas args['pool_heater_annual_kwh'] = 0 - elsif ['extra-gas-hot-tub-heater-with-zero-kwh.xml'].include? hpxml_file + when 'extra-gas-hot-tub-heater-with-zero-kwh.xml' args['permanent_spa_present'] = true args['permanent_spa_heater_type'] = HPXML::HeaterTypeGas args['permanent_spa_heater_annual_kwh'] = 0 - elsif ['extra-no-rim-joists.xml'].include? hpxml_file + when 'extra-no-rim-joists.xml' args.delete('geometry_rim_joist_height') args.delete('rim_joist_assembly_r') - elsif ['extra-iecc-zone-different-than-epw.xml'].include? hpxml_file + when 'extra-iecc-zone-different-than-epw.xml' args['site_iecc_zone'] = '6B' - elsif ['extra-state-code-different-than-epw.xml'].include? hpxml_file + when 'extra-state-code-different-than-epw.xml' args['site_state_code'] = 'WY' - elsif ['extra-time-zone-different-than-epw.xml'].include? hpxml_file + when 'extra-time-zone-different-than-epw.xml' args['site_time_zone_utc_offset'] = '-6' - elsif ['extra-emissions-fossil-fuel-factors.xml'].include? hpxml_file + when 'extra-emissions-fossil-fuel-factors.xml' args['emissions_scenario_names'] = 'Scenario1, Scenario2' args['emissions_types'] = 'CO2e, SO2' args['emissions_electricity_units'] = "#{HPXML::EmissionsScenario::UnitsKgPerMWh}, #{HPXML::EmissionsScenario::UnitsLbPerMWh}" @@ -894,7 +912,7 @@ def _set_measure_argument_values(hpxml_file, args) args['emissions_fuel_oil_values'] = '161.0, 0.0015' args['emissions_coal_values'] = '211.1, 0.0020' args['emissions_wood_values'] = '200.0, 0.0025' - elsif ['extra-bills-fossil-fuel-rates.xml'].include? hpxml_file + when 'extra-bills-fossil-fuel-rates.xml' args['utility_bill_scenario_names'] = 'Scenario1, Scenario2' args['utility_bill_propane_fixed_charges'] = '1, 2' args['utility_bill_propane_marginal_rates'] = '3, 4' @@ -906,38 +924,38 @@ def _set_measure_argument_values(hpxml_file, args) args['utility_bill_wood_marginal_rates'] = '14, 15' args['utility_bill_wood_pellets_fixed_charges'] = '16, 17' args['utility_bill_wood_pellets_marginal_rates'] = '18, 19' - elsif ['extra-seasons-building-america.xml'].include? hpxml_file + when 'extra-seasons-building-america.xml' args['hvac_control_heating_season_period'] = Constants::BuildingAmerica args['hvac_control_cooling_season_period'] = Constants::BuildingAmerica - elsif ['extra-ducts-crawlspace.xml'].include? hpxml_file + when 'extra-ducts-crawlspace.xml' args['geometry_foundation_type'] = HPXML::FoundationTypeCrawlspaceUnvented args['geometry_foundation_height'] = 4 args['floor_over_foundation_assembly_r'] = 18.7 args['foundation_wall_insulation_distance_to_bottom'] = 4 args['ducts_supply_location'] = HPXML::LocationCrawlspace args['ducts_return_location'] = HPXML::LocationCrawlspace - elsif ['extra-ducts-attic.xml'].include? hpxml_file + when 'extra-ducts-attic.xml' args['ducts_supply_location'] = HPXML::LocationAttic args['ducts_return_location'] = HPXML::LocationAttic - elsif ['extra-water-heater-crawlspace.xml'].include? hpxml_file + when 'extra-water-heater-crawlspace.xml' args['geometry_foundation_type'] = HPXML::FoundationTypeCrawlspaceUnvented args['geometry_foundation_height'] = 4 args['floor_over_foundation_assembly_r'] = 18.7 args['foundation_wall_insulation_distance_to_bottom'] = 4 args['water_heater_location'] = HPXML::LocationCrawlspace - elsif ['extra-water-heater-attic.xml'].include? hpxml_file + when 'extra-water-heater-attic.xml' args['water_heater_location'] = HPXML::LocationAttic - elsif ['extra-battery-crawlspace.xml'].include? hpxml_file + when 'extra-battery-crawlspace.xml' args['geometry_foundation_type'] = HPXML::FoundationTypeCrawlspaceUnvented args['geometry_foundation_height'] = 4 args['floor_over_foundation_assembly_r'] = 18.7 args['foundation_wall_insulation_distance_to_bottom'] = 4 args['battery_present'] = true args['battery_location'] = HPXML::LocationCrawlspace - elsif ['extra-battery-attic.xml'].include? hpxml_file + when 'extra-battery-attic.xml' args['battery_present'] = true args['battery_location'] = HPXML::LocationAttic - elsif ['extra-detailed-performance-autosize.xml'].include? hpxml_file + when 'extra-detailed-performance-autosize.xml' args['heating_system_type'] = Constants::None args['cooling_system_type'] = Constants::None args['heat_pump_type'] = HPXML::HVACTypeHeatPumpAirToAir @@ -958,214 +976,202 @@ def _set_measure_argument_values(hpxml_file, args) args['hvac_perf_data_cooling_max_speed_capacities'] = '1.0, 1.11' args['hvac_perf_data_cooling_min_speed_cops'] = '4.47, 6.34' args['hvac_perf_data_cooling_max_speed_cops'] = '2.71, 3.53' - elsif ['extra-power-outage-periods.xml'].include? hpxml_file + when 'extra-power-outage-periods.xml' args['schedules_unavailable_period_types'] = 'Power Outage, Power Outage' args['schedules_unavailable_period_dates'] = 'Jan 1 - Jan 5, Jan 7 - Jan 9' - elsif ['extra-sfa-atticroof-flat.xml'].include? hpxml_file + when 'extra-sfa-atticroof-flat.xml' args['geometry_attic_type'] = HPXML::AtticTypeFlatRoof args['ducts_supply_leakage_to_outside_value'] = 0.0 args['ducts_return_leakage_to_outside_value'] = 0.0 args['ducts_supply_location'] = HPXML::LocationBasementConditioned args['ducts_return_location'] = HPXML::LocationBasementConditioned - elsif ['extra-sfa-atticroof-conditioned-eaves-gable.xml'].include? hpxml_file + when 'extra-sfa-atticroof-conditioned-eaves-gable.xml' args['geometry_unit_num_floors_above_grade'] = 2 args['geometry_attic_type'] = HPXML::AtticTypeConditioned args['geometry_eaves_depth'] = 2 args['ducts_supply_location'] = HPXML::LocationConditionedSpace args['ducts_return_location'] = HPXML::LocationConditionedSpace - elsif ['extra-sfa-atticroof-conditioned-eaves-hip.xml'].include? hpxml_file + when 'extra-sfa-atticroof-conditioned-eaves-hip.xml' args['geometry_roof_type'] = Constants::RoofTypeHip - elsif ['extra-mf-eaves.xml'].include? hpxml_file + when 'extra-mf-eaves.xml' args['geometry_eaves_depth'] = 2 - elsif ['extra-sfa-slab.xml'].include? hpxml_file + when 'extra-sfa-slab.xml' args['geometry_foundation_type'] = HPXML::FoundationTypeSlab args['geometry_foundation_height'] = 0.0 args['geometry_foundation_height_above_grade'] = 0.0 args.delete('foundation_wall_insulation_distance_to_bottom') - elsif ['extra-sfa-vented-crawlspace.xml'].include? hpxml_file + when 'extra-sfa-vented-crawlspace.xml' args['geometry_foundation_type'] = HPXML::FoundationTypeCrawlspaceVented args['geometry_foundation_height'] = 4.0 args['floor_over_foundation_assembly_r'] = 18.7 args['foundation_wall_insulation_distance_to_bottom'] = 4.0 - elsif ['extra-sfa-unvented-crawlspace.xml'].include? hpxml_file + when 'extra-sfa-unvented-crawlspace.xml' args['geometry_foundation_type'] = HPXML::FoundationTypeCrawlspaceUnvented args['geometry_foundation_height'] = 4.0 args['floor_over_foundation_assembly_r'] = 18.7 args['foundation_wall_insulation_distance_to_bottom'] = 4.0 - elsif ['extra-sfa-conditioned-crawlspace.xml'].include? hpxml_file + when 'extra-sfa-conditioned-crawlspace.xml' args['geometry_foundation_type'] = HPXML::FoundationTypeCrawlspaceConditioned args['geometry_foundation_height'] = 4.0 args['floor_over_foundation_assembly_r'] = 2.1 args['foundation_wall_insulation_distance_to_bottom'] = 4.0 - elsif ['extra-sfa-unconditioned-basement.xml'].include? hpxml_file + when 'extra-sfa-unconditioned-basement.xml' args['geometry_foundation_type'] = HPXML::FoundationTypeBasementUnconditioned args['floor_over_foundation_assembly_r'] = 18.7 args['foundation_wall_insulation_r'] = 0 args['foundation_wall_insulation_distance_to_bottom'] = 0.0 - elsif ['extra-sfa-ambient.xml'].include? hpxml_file + when 'extra-sfa-ambient.xml' args['geometry_unit_cfa'] = 900.0 args['geometry_foundation_type'] = HPXML::FoundationTypeAmbient args.delete('geometry_rim_joist_height') args['floor_over_foundation_assembly_r'] = 18.7 args.delete('rim_joist_assembly_r') args['misc_plug_loads_other_annual_kwh'] = 1228.5 - elsif ['extra-sfa-rear-units.xml'].include? hpxml_file + when 'extra-sfa-rear-units.xml' args['geometry_building_num_units'] = 4 - elsif ['extra-sfa-exterior-corridor.xml'].include? hpxml_file + when 'extra-sfa-exterior-corridor.xml' args['geometry_building_num_units'] = 4 - elsif ['extra-sfa-slab-middle.xml', - 'extra-sfa-vented-crawlspace-middle.xml', - 'extra-sfa-unvented-crawlspace-middle.xml', - 'extra-sfa-unconditioned-basement-middle.xml'].include? hpxml_file + when 'extra-sfa-slab-middle.xml', 'extra-sfa-vented-crawlspace-middle.xml', + 'extra-sfa-unvented-crawlspace-middle.xml', 'extra-sfa-unconditioned-basement-middle.xml' args['geometry_unit_left_wall_is_adiabatic'] = true args['geometry_unit_right_wall_is_adiabatic'] = true - elsif ['extra-sfa-slab-right.xml', - 'extra-sfa-vented-crawlspace-right.xml', - 'extra-sfa-unvented-crawlspace-right.xml', - 'extra-sfa-unconditioned-basement-right.xml'].include? hpxml_file + when 'extra-sfa-slab-right.xml', 'extra-sfa-vented-crawlspace-right.xml', + 'extra-sfa-unvented-crawlspace-right.xml', 'extra-sfa-unconditioned-basement-right.xml' args['geometry_unit_left_wall_is_adiabatic'] = true - elsif ['extra-mf-atticroof-flat.xml'].include? hpxml_file + when 'extra-mf-atticroof-flat.xml' args['geometry_attic_type'] = HPXML::AtticTypeFlatRoof - elsif ['extra-mf-atticroof-vented.xml'].include? hpxml_file + when 'extra-mf-atticroof-vented.xml' args['geometry_attic_type'] = HPXML::AtticTypeVented - elsif ['extra-mf-slab.xml'].include? hpxml_file + when 'extra-mf-slab.xml' args['geometry_building_num_units'] = 18 args['geometry_foundation_type'] = HPXML::FoundationTypeSlab args['geometry_foundation_height'] = 0.0 args['geometry_foundation_height_above_grade'] = 0.0 args.delete('foundation_wall_insulation_distance_to_bottom') - elsif ['extra-mf-vented-crawlspace.xml'].include? hpxml_file + when 'extra-mf-vented-crawlspace.xml' args['geometry_building_num_units'] = 18 args['geometry_foundation_type'] = HPXML::FoundationTypeCrawlspaceVented args['geometry_foundation_height'] = 4.0 args['floor_over_foundation_assembly_r'] = 18.7 args['foundation_wall_insulation_distance_to_bottom'] = 4.0 - elsif ['extra-mf-unvented-crawlspace.xml'].include? hpxml_file + when 'extra-mf-unvented-crawlspace.xml' args['geometry_building_num_units'] = 18 args['geometry_foundation_type'] = HPXML::FoundationTypeCrawlspaceUnvented args['geometry_foundation_height'] = 4.0 args['floor_over_foundation_assembly_r'] = 18.7 args['foundation_wall_insulation_distance_to_bottom'] = 4.0 - elsif ['extra-mf-ambient.xml'].include? hpxml_file + when 'extra-mf-ambient.xml' args['geometry_unit_cfa'] = 450.0 args['geometry_foundation_type'] = HPXML::FoundationTypeAmbient args.delete('geometry_rim_joist_height') args['floor_over_foundation_assembly_r'] = 18.7 args.delete('rim_joist_assembly_r') args['misc_plug_loads_other_annual_kwh'] = 1228.5 - elsif ['extra-mf-rear-units.xml'].include? hpxml_file + when 'extra-mf-rear-units.xml' args['geometry_building_num_units'] = 18 - elsif ['extra-mf-exterior-corridor.xml'].include? hpxml_file + when 'extra-mf-exterior-corridor.xml' args['geometry_building_num_units'] = 18 - elsif ['extra-mf-slab-left-bottom.xml', - 'extra-mf-vented-crawlspace-left-bottom.xml', - 'extra-mf-unvented-crawlspace-left-bottom.xml'].include? hpxml_file + when 'extra-mf-slab-left-bottom.xml', 'extra-mf-vented-crawlspace-left-bottom.xml', + 'extra-mf-unvented-crawlspace-left-bottom.xml' args['geometry_unit_right_wall_is_adiabatic'] = true args['geometry_attic_type'] = HPXML::AtticTypeBelowApartment - elsif ['extra-mf-slab-left-middle.xml', - 'extra-mf-vented-crawlspace-left-middle.xml', - 'extra-mf-unvented-crawlspace-left-middle.xml'].include? hpxml_file + when 'extra-mf-slab-left-middle.xml', 'extra-mf-vented-crawlspace-left-middle.xml', + 'extra-mf-unvented-crawlspace-left-middle.xml' args['geometry_unit_right_wall_is_adiabatic'] = true args['geometry_attic_type'] = HPXML::AtticTypeBelowApartment args['geometry_foundation_type'] = HPXML::FoundationTypeAboveApartment - elsif ['extra-mf-slab-left-top.xml', - 'extra-mf-vented-crawlspace-left-top.xml', - 'extra-mf-unvented-crawlspace-left-top.xml'].include? hpxml_file + when 'extra-mf-slab-left-top.xml', 'extra-mf-vented-crawlspace-left-top.xml', + 'extra-mf-unvented-crawlspace-left-top.xml' args['geometry_unit_right_wall_is_adiabatic'] = true args['geometry_foundation_type'] = HPXML::FoundationTypeAboveApartment - elsif ['extra-mf-slab-middle-bottom.xml', - 'extra-mf-vented-crawlspace-middle-bottom.xml', - 'extra-mf-unvented-crawlspace-middle-bottom.xml'].include? hpxml_file + when 'extra-mf-slab-middle-bottom.xml', 'extra-mf-vented-crawlspace-middle-bottom.xml', + 'extra-mf-unvented-crawlspace-middle-bottom.xml' args['geometry_unit_left_wall_is_adiabatic'] = true args['geometry_unit_right_wall_is_adiabatic'] = true args['geometry_attic_type'] = HPXML::AtticTypeBelowApartment - elsif ['extra-mf-slab-middle-middle.xml', - 'extra-mf-vented-crawlspace-middle-middle.xml', - 'extra-mf-unvented-crawlspace-middle-middle.xml'].include? hpxml_file + when 'extra-mf-slab-middle-middle.xml', 'extra-mf-vented-crawlspace-middle-middle.xml', + 'extra-mf-unvented-crawlspace-middle-middle.xml' args['geometry_unit_left_wall_is_adiabatic'] = true args['geometry_unit_right_wall_is_adiabatic'] = true args['geometry_attic_type'] = HPXML::AtticTypeBelowApartment args['geometry_foundation_type'] = HPXML::FoundationTypeAboveApartment - elsif ['extra-mf-slab-middle-top.xml', - 'extra-mf-vented-crawlspace-middle-top.xml', - 'extra-mf-unvented-crawlspace-middle-top.xml'].include? hpxml_file + when 'extra-mf-slab-middle-top.xml', 'extra-mf-vented-crawlspace-middle-top.xml', + 'extra-mf-unvented-crawlspace-middle-top.xml' args['geometry_unit_left_wall_is_adiabatic'] = true args['geometry_unit_right_wall_is_adiabatic'] = true args['geometry_foundation_type'] = HPXML::FoundationTypeAboveApartment - elsif ['extra-mf-slab-right-bottom.xml', - 'extra-mf-vented-crawlspace-right-bottom.xml', - 'extra-mf-unvented-crawlspace-right-bottom.xml'].include? hpxml_file + when 'extra-mf-slab-right-bottom.xml', 'extra-mf-vented-crawlspace-right-bottom.xml', + 'extra-mf-unvented-crawlspace-right-bottom.xml' args['geometry_unit_left_wall_is_adiabatic'] = true args['geometry_attic_type'] = HPXML::AtticTypeBelowApartment - elsif ['extra-mf-slab-right-middle.xml', - 'extra-mf-vented-crawlspace-right-middle.xml', - 'extra-mf-unvented-crawlspace-right-middle.xml'].include? hpxml_file + when 'extra-mf-slab-right-middle.xml', 'extra-mf-vented-crawlspace-right-middle.xml', + 'extra-mf-unvented-crawlspace-right-middle.xml' args['geometry_unit_left_wall_is_adiabatic'] = true args['geometry_attic_type'] = HPXML::AtticTypeBelowApartment args['geometry_foundation_type'] = HPXML::FoundationTypeAboveApartment - elsif ['extra-mf-slab-right-top.xml', - 'extra-mf-vented-crawlspace-right-top.xml', - 'extra-mf-unvented-crawlspace-right-top.xml'].include? hpxml_file + when 'extra-mf-slab-right-top.xml', 'extra-mf-vented-crawlspace-right-top.xml', + 'extra-mf-unvented-crawlspace-right-top.xml' args['geometry_unit_left_wall_is_adiabatic'] = true args['geometry_foundation_type'] = HPXML::FoundationTypeAboveApartment - elsif ['extra-mf-slab-rear-units.xml', - 'extra-mf-vented-crawlspace-rear-units.xml', - 'extra-mf-unvented-crawlspace-rear-units.xml', - 'extra-mf-slab-left-bottom-rear-units.xml', - 'extra-mf-slab-left-middle-rear-units.xml', - 'extra-mf-slab-left-top-rear-units.xml', - 'extra-mf-slab-middle-bottom-rear-units.xml', - 'extra-mf-slab-middle-middle-rear-units.xml', - 'extra-mf-slab-middle-top-rear-units.xml', - 'extra-mf-slab-right-bottom-rear-units.xml', - 'extra-mf-slab-right-middle-rear-units.xml', - 'extra-mf-slab-right-top-rear-units.xml', - 'extra-mf-vented-crawlspace-left-bottom-rear-units.xml', - 'extra-mf-vented-crawlspace-left-middle-rear-units.xml', - 'extra-mf-vented-crawlspace-left-top-rear-units.xml', - 'extra-mf-vented-crawlspace-middle-bottom-rear-units.xml', - 'extra-mf-vented-crawlspace-middle-middle-rear-units.xml', - 'extra-mf-vented-crawlspace-middle-top-rear-units.xml', - 'extra-mf-vented-crawlspace-right-bottom-rear-units.xml', - 'extra-mf-vented-crawlspace-right-middle-rear-units.xml', - 'extra-mf-vented-crawlspace-right-top-rear-units.xml', + when 'extra-mf-slab-rear-units.xml', + 'extra-mf-vented-crawlspace-rear-units.xml', + 'extra-mf-unvented-crawlspace-rear-units.xml', + 'extra-mf-slab-left-bottom-rear-units.xml', + 'extra-mf-slab-left-middle-rear-units.xml', + 'extra-mf-slab-left-top-rear-units.xml', + 'extra-mf-slab-middle-bottom-rear-units.xml', + 'extra-mf-slab-middle-middle-rear-units.xml', + 'extra-mf-slab-middle-top-rear-units.xml', + 'extra-mf-slab-right-bottom-rear-units.xml', + 'extra-mf-slab-right-middle-rear-units.xml', + 'extra-mf-slab-right-top-rear-units.xml', + 'extra-mf-vented-crawlspace-left-bottom-rear-units.xml', + 'extra-mf-vented-crawlspace-left-middle-rear-units.xml', + 'extra-mf-vented-crawlspace-left-top-rear-units.xml', + 'extra-mf-vented-crawlspace-middle-bottom-rear-units.xml', + 'extra-mf-vented-crawlspace-middle-middle-rear-units.xml', + 'extra-mf-vented-crawlspace-middle-top-rear-units.xml', + 'extra-mf-vented-crawlspace-right-bottom-rear-units.xml', + 'extra-mf-vented-crawlspace-right-middle-rear-units.xml', + 'extra-mf-vented-crawlspace-right-top-rear-units.xml', 'extra-mf-unvented-crawlspace-left-bottom-rear-units.xml', - 'extra-mf-unvented-crawlspace-left-middle-rear-units.xml', + 'extra-mf-unvented-crawlspace-left-middle-rear-units.xml', 'extra-mf-unvented-crawlspace-left-top-rear-units.xml', 'extra-mf-unvented-crawlspace-middle-bottom-rear-units.xml', 'extra-mf-unvented-crawlspace-middle-middle-rear-units.xml', 'extra-mf-unvented-crawlspace-middle-top-rear-units.xml', 'extra-mf-unvented-crawlspace-right-bottom-rear-units.xml', 'extra-mf-unvented-crawlspace-right-middle-rear-units.xml', - 'extra-mf-unvented-crawlspace-right-top-rear-units.xml'].include? hpxml_file + 'extra-mf-unvented-crawlspace-right-top-rear-units.xml' args['geometry_unit_front_wall_is_adiabatic'] = true end # Error - if ['error-heating-system-and-heat-pump.xml'].include? hpxml_file + case hpxml_file + when 'error-heating-system-and-heat-pump.xml' args['cooling_system_type'] = Constants::None args['heat_pump_type'] = HPXML::HVACTypeHeatPumpAirToAir - elsif ['error-cooling-system-and-heat-pump.xml'].include? hpxml_file + when 'error-cooling-system-and-heat-pump.xml' args['heating_system_type'] = Constants::None args['heat_pump_type'] = HPXML::HVACTypeHeatPumpAirToAir - elsif ['error-sfd-conditioned-basement-zero-foundation-height.xml'].include? hpxml_file + when 'error-sfd-conditioned-basement-zero-foundation-height.xml' args['geometry_foundation_height'] = 0.0 args.delete('foundation_wall_insulation_distance_to_bottom') - elsif ['error-sfd-adiabatic-walls.xml'].include? hpxml_file + when 'error-sfd-adiabatic-walls.xml' args['geometry_unit_left_wall_is_adiabatic'] = true - elsif ['error-mf-conditioned-basement'].include? hpxml_file + when 'error-mf-conditioned-basement' args['geometry_foundation_type'] = HPXML::FoundationTypeBasementConditioned - elsif ['error-mf-conditioned-crawlspace'].include? hpxml_file + when 'error-mf-conditioned-crawlspace' args['geometry_foundation_type'] = HPXML::FoundationTypeCrawlspaceConditioned - elsif ['error-mf-bottom-crawlspace-zero-foundation-height.xml'].include? hpxml_file + when 'error-mf-bottom-crawlspace-zero-foundation-height.xml' args['geometry_foundation_type'] = HPXML::FoundationTypeCrawlspaceUnvented args['geometry_foundation_height'] = 0.0 args['geometry_attic_type'] = HPXML::AtticTypeBelowApartment args.delete('foundation_wall_insulation_distance_to_bottom') - elsif ['error-second-heating-system-but-no-primary-heating.xml'].include? hpxml_file + when 'error-second-heating-system-but-no-primary-heating.xml' args['heating_system_type'] = Constants::None args['heating_system_2_type'] = HPXML::HVACTypeFireplace - elsif ['error-second-heating-system-ducted-with-ducted-primary-heating.xml'].include? hpxml_file + when 'error-second-heating-system-ducted-with-ducted-primary-heating.xml' args['heating_system_type'] = Constants::None args['cooling_system_type'] = Constants::None args['heat_pump_type'] = HPXML::HVACTypeHeatPumpMiniSplit @@ -1173,119 +1179,119 @@ def _set_measure_argument_values(hpxml_file, args) args['heat_pump_is_ducted'] = true args['heat_pump_backup_type'] = HPXML::HeatPumpBackupTypeSeparate args['heating_system_2_type'] = HPXML::HVACTypeFurnace - elsif ['error-sfa-no-building-num-units.xml'].include? hpxml_file + when 'error-sfa-no-building-num-units.xml' args.delete('geometry_building_num_units') - elsif ['error-sfa-above-apartment.xml'].include? hpxml_file + when 'error-sfa-above-apartment.xml' args['geometry_foundation_type'] = HPXML::FoundationTypeAboveApartment - elsif ['error-sfa-below-apartment.xml'].include? hpxml_file + when 'error-sfa-below-apartment.xml' args['geometry_attic_type'] = HPXML::AtticTypeBelowApartment - elsif ['error-sfa-all-adiabatic-walls.xml'].include? hpxml_file + when 'error-sfa-all-adiabatic-walls.xml' args['geometry_unit_left_wall_is_adiabatic'] = true args['geometry_unit_right_wall_is_adiabatic'] = true args['geometry_unit_front_wall_is_adiabatic'] = true args['geometry_unit_back_wall_is_adiabatic'] = true - elsif ['error-mf-no-building-num-units.xml'].include? hpxml_file + when 'error-mf-no-building-num-units.xml' args.delete('geometry_building_num_units') - elsif ['error-mf-all-adiabatic-walls.xml'].include? hpxml_file + when 'error-mf-all-adiabatic-walls.xml' args['geometry_unit_left_wall_is_adiabatic'] = true args['geometry_unit_right_wall_is_adiabatic'] = true args['geometry_unit_front_wall_is_adiabatic'] = true args['geometry_unit_back_wall_is_adiabatic'] = true - elsif ['error-mf-two-stories.xml'].include? hpxml_file + when 'error-mf-two-stories.xml' args['geometry_unit_num_floors_above_grade'] = 2 - elsif ['error-mf-conditioned-attic.xml'].include? hpxml_file + when 'error-mf-conditioned-attic.xml' args['geometry_attic_type'] = HPXML::AtticTypeConditioned - elsif ['error-dhw-indirect-without-boiler.xml'].include? hpxml_file + when 'error-dhw-indirect-without-boiler.xml' args['water_heater_type'] = HPXML::WaterHeaterTypeCombiStorage - elsif ['error-conditioned-attic-with-one-floor-above-grade.xml'].include? hpxml_file + when 'error-conditioned-attic-with-one-floor-above-grade.xml' args['geometry_attic_type'] = HPXML::AtticTypeConditioned args['ceiling_assembly_r'] = 0.0 - elsif ['error-sfd-with-shared-system.xml'].include? hpxml_file + when 'error-sfd-with-shared-system.xml' args['heating_system_type'] = "Shared #{HPXML::HVACTypeBoiler} w/ Baseboard" - elsif ['error-rim-joist-height-but-no-assembly-r.xml'].include? hpxml_file + when 'error-rim-joist-height-but-no-assembly-r.xml' args.delete('rim_joist_assembly_r') - elsif ['error-rim-joist-assembly-r-but-no-height.xml'].include? hpxml_file + when 'error-rim-joist-assembly-r-but-no-height.xml' args.delete('geometry_rim_joist_height') - elsif ['error-unavailable-period-args-not-all-specified'].include? hpxml_file + when 'error-unavailable-period-args-not-all-specified' args['schedules_unavailable_period_types'] = 'Vacancy' - elsif ['error-unavailable-period-args-not-all-same-size.xml'].include? hpxml_file + when 'error-unavailable-period-args-not-all-same-size.xml' args['schedules_unavailable_period_types'] = 'Vacancy, Power Outage' args['schedules_unavailable_period_dates'] = 'Jan 1 - Jan 5, Jan 7 - Jan 9' args['schedules_unavailable_period_window_natvent_availabilities'] = HPXML::ScheduleRegular - elsif ['error-unavailable-period-window-natvent-invalid.xml'].include? hpxml_file + when 'error-unavailable-period-window-natvent-invalid.xml' args['schedules_unavailable_period_types'] = 'Power Outage' args['schedules_unavailable_period_dates'] = 'Jan 7 - Jan 9' args['schedules_unavailable_period_window_natvent_availabilities'] = 'invalid' - elsif ['error-heating-perf-data-not-all-specified.xml'].include? hpxml_file + when 'error-heating-perf-data-not-all-specified.xml' args['hvac_perf_data_heating_outdoor_temperatures'] = '47.0' - elsif ['error-heating-perf-data-not-all-same-size.xml'].include? hpxml_file + when 'error-heating-perf-data-not-all-same-size.xml' args['hvac_perf_data_heating_outdoor_temperatures'] = '47.0' args['hvac_perf_data_heating_min_speed_capacities'] = '10000, 4200' args['hvac_perf_data_heating_max_speed_capacities'] = '36000, 24800' args['hvac_perf_data_heating_min_speed_cops'] = '4.73, 1.84' args['hvac_perf_data_heating_max_speed_cops'] = '3.44, 2.66' - elsif ['error-cooling-perf-data-not-all-specified.xml'].include? hpxml_file + when 'error-cooling-perf-data-not-all-specified.xml' args['hvac_perf_data_cooling_outdoor_temperatures'] = '95.0' - elsif ['error-cooling-perf-data-not-all-same-size.xml'].include? hpxml_file + when 'error-cooling-perf-data-not-all-same-size.xml' args['hvac_perf_data_cooling_outdoor_temperatures'] = '95.0' args['hvac_perf_data_cooling_min_speed_capacities'] = '11700, 13200' args['hvac_perf_data_cooling_max_speed_capacities'] = '36000, 40000' args['hvac_perf_data_cooling_min_speed_cops'] = '4.47, 6.34' args['hvac_perf_data_cooling_max_speed_cops'] = '2.71, 3.53' - elsif ['error-emissions-args-not-all-specified.xml'].include? hpxml_file + when 'error-emissions-args-not-all-specified.xml' args['emissions_scenario_names'] = 'Scenario1' - elsif ['error-emissions-args-not-all-same-size.xml'].include? hpxml_file + when 'error-emissions-args-not-all-same-size.xml' args['emissions_scenario_names'] = 'Scenario1' args['emissions_types'] = 'CO2e,CO2e' args['emissions_electricity_units'] = HPXML::EmissionsScenario::UnitsLbPerMWh args['emissions_electricity_values_or_filepaths'] = '../../HPXMLtoOpenStudio/resources/data/cambium/LRMER_MidCase.csv' - elsif ['error-emissions-natural-gas-args-not-all-specified.xml'].include? hpxml_file + when 'error-emissions-natural-gas-args-not-all-specified.xml' args['emissions_natural_gas_values'] = '117.6' - elsif ['error-bills-args-not-all-same-size.xml'].include? hpxml_file + when 'error-bills-args-not-all-same-size.xml' args['utility_bill_scenario_names'] = 'Scenario1' args['utility_bill_electricity_fixed_charges'] = '1' args['utility_bill_electricity_marginal_rates'] = '2,2' - elsif ['error-invalid-aspect-ratio.xml'].include? hpxml_file + when 'error-invalid-aspect-ratio.xml' args['geometry_unit_aspect_ratio'] = -1 - elsif ['error-negative-foundation-height.xml'].include? hpxml_file + when 'error-negative-foundation-height.xml' args['geometry_foundation_height'] = -8 - elsif ['error-too-many-floors.xml'].include? hpxml_file + when 'error-too-many-floors.xml' args['geometry_unit_num_floors_above_grade'] = 7 - elsif ['error-invalid-garage-protrusion.xml'].include? hpxml_file + when 'error-invalid-garage-protrusion.xml' args['geometry_garage_protrusion'] = 1.5 - elsif ['error-sfa-no-non-adiabatic-walls.xml'].include? hpxml_file + when 'error-sfa-no-non-adiabatic-walls.xml' args['geometry_unit_left_wall_is_adiabatic'] = true args['geometry_unit_front_wall_is_adiabatic'] = true args['geometry_unit_back_wall_is_adiabatic'] = true - elsif ['error-hip-roof-and-protruding-garage.xml'].include? hpxml_file + when 'error-hip-roof-and-protruding-garage.xml' args['geometry_roof_type'] = Constants::RoofTypeHip args['geometry_garage_width'] = 12 args['geometry_garage_protrusion'] = 0.5 - elsif ['error-protruding-garage-under-gable-roof.xml'].include? hpxml_file + when 'error-protruding-garage-under-gable-roof.xml' args['geometry_unit_aspect_ratio'] = 0.5 args['geometry_garage_width'] = 12 args['geometry_garage_protrusion'] = 0.5 - elsif ['error-ambient-with-garage.xml'].include? hpxml_file + when 'error-ambient-with-garage.xml' args['geometry_garage_width'] = 12 args['geometry_foundation_type'] = HPXML::FoundationTypeAmbient - elsif ['error-invalid-door-area.xml'].include? hpxml_file + when 'error-invalid-door-area.xml' args['door_area'] = -10 - elsif ['error-invalid-window-aspect-ratio.xml'].include? hpxml_file + when 'error-invalid-window-aspect-ratio.xml' args['window_aspect_ratio'] = 0 - elsif ['error-garage-too-wide.xml'].include? hpxml_file + when 'error-garage-too-wide.xml' args['geometry_garage_width'] = 72 - elsif ['error-garage-too-deep.xml'].include? hpxml_file + when 'error-garage-too-deep.xml' args['geometry_garage_width'] = 12 args['geometry_garage_depth'] = 40 - elsif ['error-vented-attic-with-zero-floor-insulation.xml'].include? hpxml_file + when 'error-vented-attic-with-zero-floor-insulation.xml' args['ceiling_assembly_r'] = 0 - elsif ['error-different-software-program.xml'].include? hpxml_file + when 'error-different-software-program.xml' args['existing_hpxml_path'] = File.join(File.dirname(__FILE__), 'extra_files/base-sfd-header.xml') args['software_info_program_used'] = 'Program2' args['software_info_program_version'] = '2' args['emissions_scenario_names'] = 'Emissions2' args['utility_bill_scenario_names'] = 'Bills2' - elsif ['error-different-simulation-control.xml'].include? hpxml_file + when 'error-different-simulation-control.xml' args['existing_hpxml_path'] = File.join(File.dirname(__FILE__), 'extra_files/base-sfd-header.xml') args['simulation_control_timestep'] = 10 args['simulation_control_run_period'] = 'Jan 2 - Dec 30' @@ -1293,63 +1299,64 @@ def _set_measure_argument_values(hpxml_file, args) args['simulation_control_temperature_capacitance_multiplier'] = 2.0 args['emissions_scenario_names'] = 'Emissions2' args['utility_bill_scenario_names'] = 'Bills2' - elsif ['error-same-emissions-scenario-name.xml'].include? hpxml_file + when 'error-same-emissions-scenario-name.xml' args['existing_hpxml_path'] = File.join(File.dirname(__FILE__), 'extra_files/base-sfd-header.xml') args['emissions_electricity_values_or_filepaths'] = '2' - elsif ['error-same-utility-bill-scenario-name.xml'].include? hpxml_file + when 'error-same-utility-bill-scenario-name.xml' args['existing_hpxml_path'] = File.join(File.dirname(__FILE__), 'extra_files/base-sfd-header.xml') args['utility_bill_electricity_fixed_charges'] = '13.0' end # Warning - if ['warning-non-electric-heat-pump-water-heater.xml'].include? hpxml_file + case hpxml_file + when 'warning-non-electric-heat-pump-water-heater.xml' args['water_heater_type'] = HPXML::WaterHeaterTypeHeatPump args['water_heater_fuel_type'] = HPXML::FuelTypeNaturalGas args['water_heater_efficiency'] = 2.3 - elsif ['warning-sfd-slab-non-zero-foundation-height.xml'].include? hpxml_file + when 'warning-sfd-slab-non-zero-foundation-height.xml' args['geometry_foundation_type'] = HPXML::FoundationTypeSlab args['geometry_foundation_height_above_grade'] = 0.0 - elsif ['warning-mf-bottom-slab-non-zero-foundation-height.xml'].include? hpxml_file + when 'warning-mf-bottom-slab-non-zero-foundation-height.xml' args['geometry_foundation_type'] = HPXML::FoundationTypeSlab args['geometry_foundation_height_above_grade'] = 0.0 args['geometry_attic_type'] = HPXML::AtticTypeBelowApartment - elsif ['warning-slab-non-zero-foundation-height-above-grade.xml'].include? hpxml_file + when 'warning-slab-non-zero-foundation-height-above-grade.xml' args['geometry_foundation_type'] = HPXML::FoundationTypeSlab args['geometry_foundation_height'] = 0.0 args.delete('foundation_wall_insulation_distance_to_bottom') - elsif ['warning-vented-crawlspace-with-wall-and-ceiling-insulation.xml'].include? hpxml_file + when 'warning-vented-crawlspace-with-wall-and-ceiling-insulation.xml' args['geometry_foundation_type'] = HPXML::FoundationTypeCrawlspaceVented args['geometry_foundation_height'] = 3.0 args['floor_over_foundation_assembly_r'] = 10 args['foundation_wall_insulation_distance_to_bottom'] = 0.0 args['foundation_wall_assembly_r'] = 10 - elsif ['warning-unvented-crawlspace-with-wall-and-ceiling-insulation.xml'].include? hpxml_file + when 'warning-unvented-crawlspace-with-wall-and-ceiling-insulation.xml' args['geometry_foundation_type'] = HPXML::FoundationTypeCrawlspaceUnvented args['geometry_foundation_height'] = 3.0 args['floor_over_foundation_assembly_r'] = 10 args['foundation_wall_insulation_distance_to_bottom'] = 0.0 args['foundation_wall_assembly_r'] = 10 - elsif ['warning-unconditioned-basement-with-wall-and-ceiling-insulation.xml'].include? hpxml_file + when 'warning-unconditioned-basement-with-wall-and-ceiling-insulation.xml' args['geometry_foundation_type'] = HPXML::FoundationTypeBasementUnconditioned args['floor_over_foundation_assembly_r'] = 10 args['foundation_wall_assembly_r'] = 10 - elsif ['warning-vented-attic-with-floor-and-roof-insulation.xml'].include? hpxml_file + when 'warning-vented-attic-with-floor-and-roof-insulation.xml' args['geometry_attic_type'] = HPXML::AtticTypeVented args['roof_assembly_r'] = 10 args['ducts_supply_location'] = HPXML::LocationAtticVented args['ducts_return_location'] = HPXML::LocationAtticVented - elsif ['warning-unvented-attic-with-floor-and-roof-insulation.xml'].include? hpxml_file + when 'warning-unvented-attic-with-floor-and-roof-insulation.xml' args['geometry_attic_type'] = HPXML::AtticTypeUnvented args['roof_assembly_r'] = 10 - elsif ['warning-conditioned-basement-with-ceiling-insulation.xml'].include? hpxml_file + when 'warning-conditioned-basement-with-ceiling-insulation.xml' args['geometry_foundation_type'] = HPXML::FoundationTypeBasementConditioned args['floor_over_foundation_assembly_r'] = 10 - elsif ['warning-conditioned-attic-with-floor-insulation.xml'].include? hpxml_file + when 'warning-conditioned-attic-with-floor-insulation.xml' args['geometry_unit_num_floors_above_grade'] = 2 args['geometry_attic_type'] = HPXML::AtticTypeConditioned args['ducts_supply_location'] = HPXML::LocationConditionedSpace args['ducts_return_location'] = HPXML::LocationConditionedSpace - elsif ['warning-geothermal-loop-but-no-gshp.xml'].include? hpxml_file + when 'warning-geothermal-loop-but-no-gshp.xml' args['geothermal_loop_configuration'] = HPXML::GeothermalLoopLoopConfigurationVertical end end diff --git a/resources/hpxml-measures/BuildResidentialScheduleFile/measure.xml b/resources/hpxml-measures/BuildResidentialScheduleFile/measure.xml index 92ee872119..5ac98b35e0 100644 --- a/resources/hpxml-measures/BuildResidentialScheduleFile/measure.xml +++ b/resources/hpxml-measures/BuildResidentialScheduleFile/measure.xml @@ -3,8 +3,8 @@ 3.1 build_residential_schedule_file f770b2db-1a9f-4e99-99a7-7f3161a594b1 - fac68af6-8045-433e-8eca-df53c8274e61 - 2024-09-29T23:07:27Z + 12b68002-26b0-4e2d-bb89-f337226f0ac3 + 2024-12-09T21:40:29Z 03F02484 BuildResidentialScheduleFile Schedule File Builder @@ -229,7 +229,7 @@ schedules.rb rb resource - F53FB2CB + F14B1337 shower_cluster_size_probability.csv diff --git a/resources/hpxml-measures/BuildResidentialScheduleFile/resources/schedules.rb b/resources/hpxml-measures/BuildResidentialScheduleFile/resources/schedules.rb index 4720b00c67..540d41b6eb 100644 --- a/resources/hpxml-measures/BuildResidentialScheduleFile/resources/schedules.rb +++ b/resources/hpxml-measures/BuildResidentialScheduleFile/resources/schedules.rb @@ -176,7 +176,7 @@ def create_stochastic_schedules(args:, plugload_tv_monthly_multiplier = Schedule.validate_values(schedules_csv_data[SchedulesFile::Columns[:PlugLoadsTV].name]['PlugLoadsTVMonthlyMultipliers'], 12, 'monthly') # American Time Use Survey ceiling_fan_weekday_sch = Schedule.validate_values(default_schedules_csv_data[SchedulesFile::Columns[:CeilingFan].name]['WeekdayScheduleFractions'], 24, 'weekday') # Table C.3(5) of ANSI/RESNET/ICC 301-2022 Addendum C ceiling_fan_weekend_sch = Schedule.validate_values(default_schedules_csv_data[SchedulesFile::Columns[:CeilingFan].name]['WeekendScheduleFractions'], 24, 'weekend') # Table C.3(5) of ANSI/RESNET/ICC 301-2022 Addendum C - ceiling_fan_monthly_multiplier = Schedule.validate_values(Defaults.get_ceiling_fan_months(weather).join(', '), 12, 'monthly') # based on monthly average outdoor temperatures per ANSI/RESNET/ICC 301-2019 + ceiling_fan_monthly_multiplier = Schedule.validate_values(Defaults.get_ceiling_fan_months(weather).join(', '), 12, 'monthly') # based on monthly average outdoor temperatures per ANSI/RESNET/ICC 301 sch = get_building_america_lighting_schedule(args[:time_zone_utc_offset], args[:latitude], args[:longitude], schedules_csv_data) interior_lighting_schedule = [] diff --git a/resources/hpxml-measures/Changelog.md b/resources/hpxml-measures/Changelog.md index baf2cef1c9..b2a9029a11 100644 --- a/resources/hpxml-measures/Changelog.md +++ b/resources/hpxml-measures/Changelog.md @@ -1,3 +1,18 @@ +## OpenStudio-HPXML v1.10.0 + +__New Features__ + +__Bugfixes__ +- Fixes zero occupants specified for one unit in a whole MF building from being treated like zero occupants for every unit. + +## OpenStudio-HPXML v1.9.1 + +__New Features__ +- Now can be used to obtain ACCA Manual J approval; see the [OpenStudio-HPXML documentation](https://openstudio-hpxml.readthedocs.io/en/latest/intro.html#capabilities). + +__Bugfixes__ +- Fixes Manual J design load calculations for radiant floors. + ## OpenStudio-HPXML v1.9.0 __New Features__ diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/measure.rb b/resources/hpxml-measures/HPXMLtoOpenStudio/measure.rb index b22a139b26..0b68841d76 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/measure.rb +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/measure.rb @@ -407,20 +407,6 @@ def init(model, hpxml_bldg, hpxml_header) if hpxml_header.apply_ashrae140_assumptions.nil? hpxml_header.apply_ashrae140_assumptions = false end - - if not hpxml_bldg.building_occupancy.number_of_residents.nil? - # If zero occupants, ensure end uses of interest are zeroed out - if (hpxml_bldg.building_occupancy.number_of_residents == 0) && (not hpxml_header.apply_ashrae140_assumptions) - hpxml_header.unavailable_periods.add(column_name: 'Vacancy', - begin_month: hpxml_header.sim_begin_month, - begin_day: hpxml_header.sim_begin_day, - begin_hour: 0, - end_month: hpxml_header.sim_end_month, - end_day: hpxml_header.sim_end_day, - end_hour: 24, - natvent_availability: HPXML::ScheduleUnavailable) - end - end end end diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/measure.xml b/resources/hpxml-measures/HPXMLtoOpenStudio/measure.xml index acf153b252..bd36e2924f 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/measure.xml +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/measure.xml @@ -3,8 +3,8 @@ 3.1 hpxm_lto_openstudio b1543b30-9465-45ff-ba04-1d1f85e763bc - 531c1027-0d75-4343-a8ce-6717ad2b9924 - 2024-11-16T04:46:12Z + f6215039-69e4-4cc9-a911-32c6e2db4759 + 2024-12-17T21:18:42Z D8922A73 HPXMLtoOpenStudio HPXML to OpenStudio Translator @@ -183,13 +183,13 @@ measure.rb rb script - D7F18DFB + CA101CA3 airflow.rb rb resource - 87ABF972 + 06E4A131 battery.rb @@ -213,7 +213,7 @@ constructions.rb rb resource - B3B897EB + 75FBCCF4 data/Xing_okstate_0664D_13659_Table_A-3.csv @@ -327,13 +327,13 @@ defaults.rb rb resource - BCA4AD98 + CADAF9FE energyplus.rb rb resource - 978EE36D + 071927F3 generator.rb @@ -345,19 +345,19 @@ geometry.rb rb resource - 6C147EFE + 58D1C43A hotwater_appliances.rb rb resource - 1EE4897F + 0B205523 hpxml.rb rb resource - 3F71DE61 + 270F2EEB hpxml_schema/HPXML.xsd @@ -375,7 +375,7 @@ hpxml_schematron/EPvalidator.xml xml resource - 94AE43FB + 105F837D hpxml_schematron/iso-schematron.xsd @@ -387,25 +387,25 @@ hvac.rb rb resource - 0DF759D2 + 0F2DDAA0 hvac_sizing.rb rb resource - C6F9CE12 + A3B81222 internal_gains.rb rb resource - 94B4EA05 + 206BE2B6 lighting.rb rb resource - 9B17C563 + 7B7F6D4C location.rb @@ -417,7 +417,7 @@ materials.rb rb resource - 0E69FBCE + 23B30F2C math.rb @@ -441,13 +441,13 @@ misc_loads.rb rb resource - 2DCA8614 + 039B0042 model.rb rb resource - A578B92B + 56A086CD output.rb @@ -465,7 +465,7 @@ pv.rb rb resource - 58457C1A + F8E8DDDD schedule_files/battery.csv @@ -591,7 +591,7 @@ schedules.rb rb resource - 29DAE0EC + 467EB413 simcontrols.rb @@ -615,19 +615,19 @@ utility_bills.rb rb resource - 17195DD4 + C87C3553 version.rb rb resource - CB4D15AB + FB92922A waterheater.rb rb resource - 6F8A18EC + B6FE7ABC weather.rb @@ -639,7 +639,7 @@ xmlhelper.rb rb resource - DA4456A1 + B18A6A72 xmlvalidator.rb @@ -651,7 +651,7 @@ test_airflow.rb rb test - DA1297B3 + 6BDC58E4 test_battery.rb @@ -681,7 +681,7 @@ test_hotwater_appliance.rb rb test - A1E1E023 + 27A0085A test_hvac.rb @@ -699,7 +699,7 @@ test_lighting.rb rb test - 9F945097 + 5300BCE3 test_location.rb @@ -711,7 +711,7 @@ test_miscloads.rb rb test - 974B3838 + 784CC382 test_pv.rb @@ -735,7 +735,7 @@ test_validation.rb rb test - CABF42C5 + 95476C6B test_water_heater.rb diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/airflow.rb b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/airflow.rb index 16b83d830c..8709970c39 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/airflow.rb +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/airflow.rb @@ -38,6 +38,10 @@ def self.apply(runner, model, weather, spaces, hpxml_bldg, hpxml_header, schedul elsif f.used_for_seasonal_cooling_load_reduction vent_fans[:whf] << f elsif f.used_for_local_ventilation + if hpxml_bldg.building_occupancy.number_of_residents == 0 + # Operational calculation w/ zero occupants, zero out energy use + continue + end if f.fan_location == HPXML::LocationKitchen vent_fans[:kitchen] << f elsif f.fan_location == HPXML::LocationBath @@ -278,17 +282,18 @@ def self.set_wind_speed_correction(model, hpxml_bldg) site_ap.ashrae_terrain_thickness = 270 site_ap.ashrae_terrain_exponent = 0.14 - if site.site_type == HPXML::SiteTypeRural + case site.site_type + when HPXML::SiteTypeRural site_ap.site_terrain_multiplier = 0.85 site_ap.site_terrain_exponent = 0.20 site_ap.ashrae_site_terrain_thickness = 270 # Flat, open country site_ap.ashrae_site_terrain_exponent = 0.14 # Flat, open country - elsif site.site_type == HPXML::SiteTypeSuburban + when HPXML::SiteTypeSuburban site_ap.site_terrain_multiplier = 0.67 site_ap.site_terrain_exponent = 0.25 site_ap.ashrae_site_terrain_thickness = 370 # Rough, wooded country, suburbs site_ap.ashrae_site_terrain_exponent = 0.22 # Rough, wooded country, suburbs - elsif site.site_type == HPXML::SiteTypeUrban + when HPXML::SiteTypeUrban site_ap.site_terrain_multiplier = 0.47 site_ap.site_terrain_exponent = 0.35 site_ap.ashrae_site_terrain_thickness = 460 # Towns, city outskirts, center of large cities @@ -297,11 +302,12 @@ def self.set_wind_speed_correction(model, hpxml_bldg) # Mapping based on AIM-2 Model by Walker/Wilson # Table 2: Estimates of Shelter Coefficient S_wo for No Flue (flue effect is handled later) - if site.shielding_of_home == HPXML::ShieldingNormal + case site.shielding_of_home + when HPXML::ShieldingNormal site_ap.aim2_shelter_coeff = 0.50 # Class 4: "Very heavy shielding, many large obstructions within one house height" - elsif site.shielding_of_home == HPXML::ShieldingExposed + when HPXML::ShieldingExposed site_ap.aim2_shelter_coeff = 0.90 # Class 2: "Light local shielding with few obstructions within two house heights" - elsif site.shielding_of_home == HPXML::ShieldingWellShielded + when HPXML::ShieldingWellShielded site_ap.aim2_shelter_coeff = 0.30 # Class 5: "Complete shielding, with large buildings immediately adjacent" end @@ -528,7 +534,7 @@ def self.apply_natural_ventilation_and_whole_house_fan(runner, model, spaces, hp neutral_level = 0.5 hor_lk_frac = 0.0 c_w, c_s = calc_wind_stack_coeffs(hpxml_bldg, hor_lk_frac, neutral_level, conditioned_space, infil_values[:height]) - max_oa_hr = 0.0115 # From ANSI 301-2022 + max_oa_hr = 0.0115 # From ANSI/RESNET/ICC 301-2022 # Program vent_program = Model.add_ems_program( @@ -586,12 +592,19 @@ def self.apply_natural_ventilation_and_whole_house_fan(runner, model, spaces, hp vent_program.addLine(' Set Qwhf = WHF_Flow*Adj') vent_program.addLine(" Set #{cond_to_zone_flow_rate_actuator.name} = WHF_Flow*Adj") unless whf_zone.nil? vent_program.addLine(' Set WHF_W = 0') - vent_fans[:whf].each do |vent_whf| - vent_program.addLine(" Set WHF_W = WHF_W + #{vent_whf.fan_power} * #{whf_avail_sensors[vent_whf.id].name}") + if hpxml_bldg.building_occupancy.number_of_residents != 0 # If operational calculation w/ zero occupants, zero out whole house fan + vent_fans[:whf].each do |vent_whf| + vent_program.addLine(" Set WHF_W = WHF_W + #{vent_whf.fan_power} * #{whf_avail_sensors[vent_whf.id].name}") + end end vent_program.addLine(" Set #{whf_elec_actuator.name} = WHF_W*Adj") vent_program.addLine(' ElseIf (NVavail > 0)') # Natural ventilation - vent_program.addLine(" Set NVArea = #{UnitConversions.convert(area, 'ft^2', 'cm^2')}") + if hpxml_bldg.building_occupancy.number_of_residents == 0 + # Operational calculation w/ zero occupants, zero out natural ventilation + vent_program.addLine(' Set NVArea = 0') + else + vent_program.addLine(" Set NVArea = #{UnitConversions.convert(area, 'ft^2', 'cm^2')}") + end vent_program.addLine(" Set Cs = #{UnitConversions.convert(c_s, 'ft^2/(s^2*R)', 'L^2/(s^2*cm^4*K)')}") vent_program.addLine(" Set Cw = #{c_w * 0.01}") vent_program.addLine(' Set Tdiff = Tin-Tout') @@ -854,11 +867,12 @@ def self.check_duct_leakage(runner, hpxml_bldg) if hvac_distribution.ducts.count { |d| !HPXML::conditioned_locations_this_unit.include?(d.duct_location) } == 0 # If ducts completely in conditioned space, issue warning if duct leakage to outside above a certain threshold (e.g., 5%) issue_warning = false - if units == HPXML::UnitsCFM25 + case units + when HPXML::UnitsCFM25 issue_warning = true if sum_lto > 0.04 * cfa - elsif units == HPXML::UnitsCFM50 + when HPXML::UnitsCFM50 issue_warning = true if sum_lto > 0.06 * cfa - elsif units == HPXML::UnitsPercent + when HPXML::UnitsPercent issue_warning = true if sum_lto > 0.05 end next unless issue_warning @@ -867,11 +881,12 @@ def self.check_duct_leakage(runner, hpxml_bldg) else # If ducts in unconditioned space, issue warning if duct leakage to outside above a certain threshold (e.g., 40%) issue_warning = false - if units == HPXML::UnitsCFM25 + case units + when HPXML::UnitsCFM25 issue_warning = true if sum_lto >= 0.32 * cfa - elsif units == HPXML::UnitsCFM50 + when HPXML::UnitsCFM50 issue_warning = true if sum_lto >= 0.48 * cfa - elsif units == HPXML::UnitsPercent + when HPXML::UnitsPercent issue_warning = true if sum_lto >= 0.4 end next unless issue_warning @@ -1455,7 +1470,7 @@ def self.apply_duct_location(model, spaces, hpxml_bldg, ducts, object, i, duct_l duct_subroutine.addLine(' Set SupLatLkToDZ = sup_lk_mfr*h_fg*(AH_Wout-DZ_W)') # W duct_subroutine.addLine(' Set SupSensLkToDZ = SupTotLkToDZ-SupLatLkToDZ') # W - # Handle duct leakage imbalance induced infiltration (ANSI 301-2022 Addendum C Table 4.2.2(1c) + # Handle duct leakage imbalance induced infiltration (ANSI/RESNET/ICC 301-2022 Addendum C Table 4.2.2(1c) leakage_supply = leakage_fracs[HPXML::DuctTypeSupply].to_f + leakage_cfm25s[HPXML::DuctTypeSupply].to_f leakage_return = leakage_fracs[HPXML::DuctTypeReturn].to_f + leakage_cfm25s[HPXML::DuctTypeReturn].to_f if leakage_supply == leakage_return @@ -1984,30 +1999,32 @@ def self.apply_cfis(runner, infil_program, vent_mech_fans, cfis_data, cfis_fan_a infil_program.addLine("Set f_operation = #{[vent_mech.hours_in_operation / 24.0, 0.0001].max}") # Operation, fraction of hour infil_program.addLine("Set oa_cfm_ah = #{UnitConversions.convert(vent_mech.oa_unit_flow_rate, 'cfm', 'm^3/s')}") - if vent_mech.cfis_addtl_runtime_operating_mode == HPXML::CFISModeSupplementalFan + case vent_mech.cfis_addtl_runtime_operating_mode + when HPXML::CFISModeSupplementalFan if vent_mech.cfis_supplemental_fan.oa_unit_flow_rate < vent_mech.average_unit_flow_rate runner.registerWarning("CFIS supplemental fan '#{vent_mech.cfis_supplemental_fan.id}' is undersized (#{vent_mech.cfis_supplemental_fan.oa_unit_flow_rate} cfm) compared to the target hourly ventilation rate (#{vent_mech.average_unit_flow_rate} cfm).") end infil_program.addLine("Set suppl_fan_w = #{vent_mech.cfis_supplemental_fan.unit_fan_power}") # W, supplemental fan power infil_program.addLine("Set oa_cfm_suppl = #{UnitConversions.convert(vent_mech.cfis_supplemental_fan.oa_unit_flow_rate, 'cfm', 'm^3/s')}") - elsif vent_mech.cfis_addtl_runtime_operating_mode == HPXML::CFISModeAirHandler + when HPXML::CFISModeAirHandler infil_program.addLine("Set ah_fan_w = #{vent_mech.unit_fan_power}") # W, air handler fan power end infil_program.addLine("Set has_outdoor_air_control = #{vent_mech.cfis_has_outdoor_air_control ? 1 : 0}") - if vent_mech.cfis_control_type == HPXML::CFISControlTypeTimer + case vent_mech.cfis_control_type + when HPXML::CFISControlTypeTimer # Ventilation occurs at fixed intervals regardless of HVAC operation # Calculate outdoor air ventilation infil_program.addLine('Set QWHV_cfis_sup = QWHV_cfis_sup + (oa_cfm_ah * f_operation)') - # Calculate fraction of the timestep with ventilation only mode runtime per ANSI 301-2022 Addendum E + # Calculate fraction of the timestep with ventilation only mode runtime per ANSI/RESNET/ICC 301-2022 Addendum E infil_program.addLine("Set #{f_vent_only_mode_var.name} = f_operation * (1 - fan_rtf_hvac)") # Calculate additional fan energy infil_program.addLine("Set #{cfis_fan_actuator.name} = #{cfis_fan_actuator.name} + (ah_fan_w * #{f_vent_only_mode_var.name})") - elsif vent_mech.cfis_control_type == HPXML::CFISControlTypeOptimized + when HPXML::CFISControlTypeOptimized # Ventilation optimized to make use of HVAC operation infil_program.addLine("Set #{f_vent_only_mode_var.name} = 0") @@ -2040,9 +2057,10 @@ def self.apply_cfis(runner, infil_program, vent_mech_fans, cfis_data, cfis_fan_a infil_program.addLine(' If hr_oa_cfm_during_hvac > 0') infil_program.addLine(' Set f_open_damper_ah = (hr_oa_cfm_during_hvac / hr_oa_cfm_during_hvac_avail) * fan_rtf_hvac') infil_program.addLine(" Set #{cfis_suppl_fan_actuator.name} = #{cfis_suppl_fan_actuator.name} + (suppl_fan_w * f_open_damper_ah)") - if vent_mech.cfis_supplemental_fan.fan_type == HPXML::MechVentTypeSupply + case vent_mech.cfis_supplemental_fan.fan_type + when HPXML::MechVentTypeSupply infil_program.addLine(' Set QWHV_cfis_suppl_sup = QWHV_cfis_suppl_sup + (f_open_damper_ah * oa_cfm_suppl)') - elsif vent_mech.cfis_supplemental_fan.fan_type == HPXML::MechVentTypeExhaust + when HPXML::MechVentTypeExhaust infil_program.addLine(' Set QWHV_cfis_suppl_exh = QWHV_cfis_suppl_exh + (f_open_damper_ah * oa_cfm_suppl)') end infil_program.addLine(' EndIf') @@ -2052,16 +2070,18 @@ def self.apply_cfis(runner, infil_program, vent_mech_fans, cfis_data, cfis_fan_a infil_program.addLine(' Set hr_oa_cfm_addtl_needed = hr_oa_cfm_needed - hr_oa_cfm_during_hvac') # Calculate hourly-average outdoor air ventilation that can be brought in during subsequent timesteps of the hour if needed - if vent_mech.cfis_addtl_runtime_operating_mode == HPXML::CFISModeAirHandler + case vent_mech.cfis_addtl_runtime_operating_mode + when HPXML::CFISModeAirHandler infil_program.addLine(' Set hr_oa_cfm_addtl_needed = hr_oa_cfm_addtl_needed - (((60 - Minute) / 60) * oa_cfm_ah)') - elsif vent_mech.cfis_addtl_runtime_operating_mode == HPXML::CFISModeSupplementalFan + when HPXML::CFISModeSupplementalFan infil_program.addLine(' Set hr_oa_cfm_addtl_needed = hr_oa_cfm_addtl_needed - (((60 - Minute) / 60) * oa_cfm_suppl)') - elsif vent_mech.cfis_addtl_runtime_operating_mode == HPXML::CFISModeNone + when HPXML::CFISModeNone infil_program.addLine(' Set hr_oa_cfm_addtl_needed = 0') end infil_program.addLine(' If hr_oa_cfm_addtl_needed > 0') - if vent_mech.cfis_addtl_runtime_operating_mode == HPXML::CFISModeAirHandler + case vent_mech.cfis_addtl_runtime_operating_mode + when HPXML::CFISModeAirHandler # Air handler meets additional runtime requirement # Calculate hourly-average available outdoor air ventilation during non-HVAC runtime @@ -2078,7 +2098,7 @@ def self.apply_cfis(runner, infil_program, vent_mech_fans, cfis_data, cfis_fan_a infil_program.addLine(" Set #{cfis_fan_actuator.name} = #{cfis_fan_actuator.name} + (ah_fan_w * #{f_vent_only_mode_var.name})") infil_program.addLine(' EndIf') - elsif vent_mech.cfis_addtl_runtime_operating_mode == HPXML::CFISModeSupplementalFan + when HPXML::CFISModeSupplementalFan # Supplemental fan meets additional runtime requirement # Calculate hourly-average available outdoor air ventilation during non-HVAC runtime @@ -2086,9 +2106,10 @@ def self.apply_cfis(runner, infil_program, vent_mech_fans, cfis_data, cfis_fan_a # Calculate hourly-average actual outdoor air ventilation brought in during non-HVAC runtime infil_program.addLine(' Set hr_oa_cfm_during_non_hvac = @Min hr_oa_cfm_during_non_hvac_avail hr_oa_cfm_addtl_needed') - if vent_mech.cfis_supplemental_fan.fan_type == HPXML::MechVentTypeSupply + case vent_mech.cfis_supplemental_fan.fan_type + when HPXML::MechVentTypeSupply infil_program.addLine(' Set QWHV_cfis_suppl_sup = QWHV_cfis_suppl_sup + (hr_oa_cfm_during_non_hvac / ZoneTimestep)') - elsif vent_mech.cfis_supplemental_fan.fan_type == HPXML::MechVentTypeExhaust + when HPXML::MechVentTypeExhaust infil_program.addLine(' Set QWHV_cfis_suppl_exh = QWHV_cfis_suppl_exh + (hr_oa_cfm_during_non_hvac / ZoneTimestep)') end infil_program.addLine(" Set #{sum_oa_cfm_var.name} = #{sum_oa_cfm_var.name} + hr_oa_cfm_during_non_hvac") @@ -2288,6 +2309,7 @@ def self.apply_infiltration_adjustment_to_conditioned(runner, model, spaces, hpx clothes_dryer_in_cond_space = hpxml_bldg.clothes_dryers.empty? ? true : HPXML::conditioned_locations_this_unit.include?(hpxml_bldg.clothes_dryers[0].location) vented_dryers = hpxml_bldg.clothes_dryers.select { |cd| cd.is_vented && cd.vented_flow_rate.to_f > 0 } vented_dryers.each_with_index do |vented_dryer, index| + next if hpxml_bldg.building_occupancy.number_of_residents == 0 # Operational calculation w/ zero occupants, zero out energy use next unless clothes_dryer_in_cond_space # Infiltration impact @@ -2905,11 +2927,11 @@ def self.get_mech_vent_qtot_cfm(nbeds, cfa) # @param is_balanced [TODO] TODO # @param frac_imbal [TODO] TODO # @param a_ext [TODO] TODO - # @param bldg_type [TODO] TODO + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @param eri_version [String] Version of the ANSI/RESNET/ICC 301 Standard to use for equations/assumptions # @param hours_in_operation [TODO] TODO # @return [TODO] TODO - def self.get_mech_vent_qfan_cfm(q_tot, q_inf, is_balanced, frac_imbal, a_ext, bldg_type, eri_version, hours_in_operation) + def self.get_mech_vent_qfan_cfm(q_tot, q_inf, is_balanced, frac_imbal, a_ext, unit_type, eri_version, hours_in_operation) q_inf_eff = q_inf * a_ext if Constants::ERIVersions.index(eri_version) >= Constants::ERIVersions.index('2022') if frac_imbal == 0 @@ -2930,7 +2952,7 @@ def self.get_mech_vent_qfan_cfm(q_tot, q_inf, is_balanced, frac_imbal, a_ext, bl end q_fan = q_tot - phi * q_inf_eff else - if [HPXML::ResidentialTypeApartment, HPXML::ResidentialTypeSFA].include? bldg_type + if [HPXML::ResidentialTypeApartment, HPXML::ResidentialTypeSFA].include? unit_type # No infiltration credit for attached/multifamily return q_tot end @@ -3057,11 +3079,12 @@ def self.create_ducts(model, hvac_distribution, spaces) duct_leakage_value = leakage_to_outside[duct_side][0] duct_leakage_units = leakage_to_outside[duct_side][1] - if duct_leakage_units == HPXML::UnitsCFM25 + case duct_leakage_units + when HPXML::UnitsCFM25 duct_leakage_cfm25 = duct_leakage_value - elsif duct_leakage_units == HPXML::UnitsCFM50 + when HPXML::UnitsCFM50 duct_leakage_cfm50 = duct_leakage_value - elsif duct_leakage_units == HPXML::UnitsPercent + when HPXML::UnitsPercent duct_leakage_frac = duct_leakage_value else fail "#{duct_side.capitalize} ducts exist but leakage was not specified for distribution system '#{hvac_distribution.id}'." diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constructions.rb b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constructions.rb index 36c34aca50..252409cd60 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constructions.rb +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constructions.rb @@ -1544,13 +1544,15 @@ def self.apply_furniture(model, furniture_mass, spaces) furnSolarAbsorptance = 0.6 furnSpecHeat = mat.cp furnDensity = mat.rho - if location == HPXML::LocationConditionedSpace + + case location + when HPXML::LocationConditionedSpace furnAreaFraction = furniture_mass.area_fraction furnMass = mass_lb_per_sqft - elsif location == HPXML::LocationBasementUnconditioned + when HPXML::LocationBasementUnconditioned furnAreaFraction = 0.4 furnMass = mass_lb_per_sqft - elsif location == HPXML::LocationGarage + when HPXML::LocationGarage furnAreaFraction = 0.1 furnMass = 2.0 end @@ -1686,11 +1688,14 @@ def self.get_wall_color_and_solar_absorptance_map def self.get_gap_factor(install_grade, framing_factor, cavity_r) if cavity_r <= 0 return 0 # Gap factor only applies when there is cavity insulation - elsif install_grade == 1 + end + + case install_grade + when 1 return 0 - elsif install_grade == 2 + when 2 return 0.02 * (1 - framing_factor) - elsif install_grade == 3 + when 3 return 0.05 * (1 - framing_factor) end @@ -1920,7 +1925,8 @@ def self.apply_kiva_initial_temperature(foundation, weather, hpxml_bldg, hpxml_h else # Space temperature assumptions from ASHRAE 152 - Duct Efficiency Calculations.xls, Zone temperatures ground_temp = weather.data.ShallowGroundMonthlyTemps[sim_begin_month - 1] - if interior_adjacent_to == HPXML::LocationBasementUnconditioned + case interior_adjacent_to + when HPXML::LocationBasementUnconditioned if foundation_ceiling_insulated # Insulated ceiling: 75% ground, 25% outdoor, 0% indoor ground_weight, outdoor_weight, indoor_weight = 0.75, 0.25, 0.0 @@ -1932,7 +1938,7 @@ def self.apply_kiva_initial_temperature(foundation, weather, hpxml_bldg, hpxml_h ground_weight, outdoor_weight, indoor_weight = 0.5, 0.2, 0.3 end initial_temp = outdoor_temp * outdoor_weight + ground_temp * ground_weight + indoor_weight * indoor_temp - elsif interior_adjacent_to == HPXML::LocationCrawlspaceVented + when HPXML::LocationCrawlspaceVented if foundation_ceiling_insulated # Insulated ceiling: 90% outdoor, 10% indoor outdoor_weight, indoor_weight = 0.9, 0.1 @@ -1944,7 +1950,7 @@ def self.apply_kiva_initial_temperature(foundation, weather, hpxml_bldg, hpxml_h outdoor_weight, indoor_weight = 0.5, 0.5 end initial_temp = outdoor_temp * outdoor_weight + indoor_weight * indoor_temp - elsif interior_adjacent_to == HPXML::LocationCrawlspaceUnvented + when HPXML::LocationCrawlspaceUnvented if foundation_ceiling_insulated # Insulated ceiling: 85% outdoor, 15% indoor outdoor_weight, indoor_weight = 0.85, 0.15 @@ -1956,7 +1962,7 @@ def self.apply_kiva_initial_temperature(foundation, weather, hpxml_bldg, hpxml_h outdoor_weight, indoor_weight = 0.4, 0.6 end initial_temp = outdoor_temp * outdoor_weight + indoor_weight * indoor_temp - elsif interior_adjacent_to == HPXML::LocationGarage + when HPXML::LocationGarage initial_temp = outdoor_temp + 11.0 else fail "Unhandled space: #{interior_adjacent_to}" @@ -2036,14 +2042,14 @@ def self.apply_window_skylight_shading(model, window_or_skylight, sub_surface, s esf_winter = window_or_skylight.exterior_shading_factor_winter.nil? ? 1.0 : window_or_skylight.exterior_shading_factor_winter if window_or_skylight.is_a? HPXML::Window # These inputs currently only pertain to windows (not skylights) - if [HPXML::ExteriorShadingTypeExternalOverhangs, - HPXML::ExteriorShadingTypeAwnings].include? window_or_skylight.exterior_shading_type + case window_or_skylight.exterior_shading_type + when HPXML::ExteriorShadingTypeExternalOverhangs, HPXML::ExteriorShadingTypeAwnings if window_or_skylight.overhangs_depth.to_f > 0 # Explicitly modeling the overhangs, so don't double count the shading effect esf_summer = 1.0 esf_winter = 1.0 end - elsif [HPXML::ExteriorShadingTypeBuilding].include? window_or_skylight.exterior_shading_type + when HPXML::ExteriorShadingTypeBuilding if hpxml_bldg.neighbor_buildings.size > 0 # Explicitly modeling neighboring building, so don't double count the shading effect esf_summer = 1.0 @@ -2184,7 +2190,8 @@ def self.apply_wall_construction(runner, fallback_mat_int_finish = Material.InteriorFinishMaterial(mat_int_finish.name, 0.1) # Try thin material end - if wall_type == HPXML::WallTypeWoodStud + case wall_type + when HPXML::WallTypeWoodStud install_grade = 1 cavity_filled = true @@ -2215,7 +2222,7 @@ def self.apply_wall_construction(runner, radiant_barrier_grade, solar_absorptance, emittance) - elsif wall_type == HPXML::WallTypeSteelStud + when HPXML::WallTypeSteelStud install_grade = 1 cavity_filled = true corr_factor = 0.45 @@ -2236,7 +2243,7 @@ def self.apply_wall_construction(runner, constr_set.osb_thick_in, constr_set.rigid_r, constr_set.mat_ext_finish, has_radiant_barrier, inside_film, outside_film, radiant_barrier_grade, solar_absorptance, emittance) - elsif wall_type == HPXML::WallTypeDoubleWoodStud + when HPXML::WallTypeDoubleWoodStud install_grade = 1 is_staggered = false @@ -2255,7 +2262,7 @@ def self.apply_wall_construction(runner, has_radiant_barrier, inside_film, outside_film, radiant_barrier_grade, solar_absorptance, emittance) - elsif wall_type == HPXML::WallTypeCMU + when HPXML::WallTypeCMU density = 119.0 # lb/ft^3 furring_r = 0 furring_cavity_depth_in = 0 # in @@ -2274,7 +2281,7 @@ def self.apply_wall_construction(runner, constr_set.mat_int_finish, constr_set.osb_thick_in, rigid_r, constr_set.mat_ext_finish, has_radiant_barrier, inside_film, outside_film, radiant_barrier_grade, solar_absorptance, emittance) - elsif wall_type == HPXML::WallTypeSIP + when HPXML::WallTypeSIP sheathing_thick_in = 0.44 constr_sets = [ @@ -2290,7 +2297,7 @@ def self.apply_wall_construction(runner, constr_set.osb_thick_in, constr_set.rigid_r, constr_set.mat_ext_finish, has_radiant_barrier, inside_film, outside_film, radiant_barrier_grade, solar_absorptance, emittance) - elsif wall_type == HPXML::WallTypeICF + when HPXML::WallTypeICF constr_sets = [ ICFConstructionSet.new(2.0, 4.0, 0.08, 0.0, 0.5, mat_int_finish, mat_ext_finish), # ICF w/4" concrete and 2" rigid ins layers ICFConstructionSet.new(1.0, 1.0, 0.01, 0.0, 0.0, fallback_mat_int_finish, fallback_mat_ext_finish), # Fallback @@ -2305,7 +2312,7 @@ def self.apply_wall_construction(runner, has_radiant_barrier, inside_film, outside_film, radiant_barrier_grade, solar_absorptance, emittance) - elsif [HPXML::WallTypeConcrete, HPXML::WallTypeBrick, HPXML::WallTypeAdobe, HPXML::WallTypeStrawBale, HPXML::WallTypeStone, HPXML::WallTypeLog].include? wall_type + when HPXML::WallTypeConcrete, HPXML::WallTypeBrick, HPXML::WallTypeAdobe, HPXML::WallTypeStrawBale, HPXML::WallTypeStone, HPXML::WallTypeLog constr_sets = [ GenericConstructionSet.new(10.0, 0.5, mat_int_finish, mat_ext_finish), # w/R-10 rigid GenericConstructionSet.new(0.0, 0.5, mat_int_finish, mat_ext_finish), # Standard @@ -2313,22 +2320,23 @@ def self.apply_wall_construction(runner, ] match, constr_set, layer_r = pick_generic_construction_set(assembly_r, constr_sets, inside_film, outside_film) - if wall_type == HPXML::WallTypeConcrete + case wall_type + when HPXML::WallTypeConcrete thick_in = 6.0 base_mat = BaseMaterial.Concrete - elsif wall_type == HPXML::WallTypeBrick + when HPXML::WallTypeBrick thick_in = 8.0 base_mat = BaseMaterial.Brick - elsif wall_type == HPXML::WallTypeAdobe + when HPXML::WallTypeAdobe thick_in = 10.0 base_mat = BaseMaterial.Soil(12.0) - elsif wall_type == HPXML::WallTypeStrawBale + when HPXML::WallTypeStrawBale thick_in = 23.0 base_mat = BaseMaterial.StrawBale - elsif wall_type == HPXML::WallTypeStone + when HPXML::WallTypeStone thick_in = 6.0 base_mat = BaseMaterial.Stone - elsif wall_type == HPXML::WallTypeLog + when HPXML::WallTypeLog thick_in = 6.0 base_mat = BaseMaterial.Wood end @@ -2385,7 +2393,8 @@ def self.apply_floor_ceiling_construction(runner, model, surface, floor_id, floo end osb_thick_in = (is_ceiling ? 0.0 : 0.75) - if floor_type == HPXML::FloorTypeWoodFrame + case floor_type + when HPXML::FloorTypeWoodFrame install_grade = 1 constr_sets = [ WoodStudConstructionSet.new(Material.Stud2x6, 0.10, 50.0, osb_thick_in, mat_int_finish_or_covering, nil), # 2x6, 24" o.c. + R50 @@ -2406,7 +2415,7 @@ def self.apply_floor_ceiling_construction(runner, model, surface, floor_id, floo constr_set.osb_thick_in, constr_set.rigid_r, constr_int_finish_or_covering, has_radiant_barrier, inside_film, outside_film, radiant_barrier_grade) - elsif floor_type == HPXML::FloorTypeSteelFrame + when HPXML::FloorTypeSteelFrame install_grade = 1 corr_factor = 0.45 osb_thick_in = (is_ceiling ? 0.0 : 0.75) @@ -2428,7 +2437,7 @@ def self.apply_floor_ceiling_construction(runner, model, surface, floor_id, floo constr_set.osb_thick_in, constr_set.rigid_r, constr_int_finish_or_covering, has_radiant_barrier, inside_film, outside_film, radiant_barrier_grade) - elsif floor_type == HPXML::FloorTypeSIP + when HPXML::FloorTypeSIP constr_sets = [ SIPConstructionSet.new(16.0, 0.08, 0.0, 0.0, osb_thick_in, mat_int_finish_or_covering, nil), # 16" SIP core SIPConstructionSet.new(12.0, 0.08, 0.0, 0.0, osb_thick_in, mat_int_finish_or_covering, nil), # 12" SIP core @@ -2441,7 +2450,7 @@ def self.apply_floor_ceiling_construction(runner, model, surface, floor_id, floo cavity_r, constr_set.thick_in, constr_set.framing_factor, constr_set.mat_int_finish, constr_set.osb_thick_in, constr_set.rigid_r, constr_set.mat_ext_finish, has_radiant_barrier, inside_film, outside_film, radiant_barrier_grade) - elsif floor_type == HPXML::FloorTypeConcrete + when HPXML::FloorTypeConcrete constr_sets = [ GenericConstructionSet.new(20.0, osb_thick_in, mat_int_finish_or_covering, nil), # w/R-20 rigid GenericConstructionSet.new(10.0, osb_thick_in, mat_int_finish_or_covering, nil), # w/R-10 rigid diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/defaults.rb b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/defaults.rb index 5f84296aab..841bc497d1 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/defaults.rb +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/defaults.rb @@ -24,7 +24,7 @@ module Defaults # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param weather [WeatherFile] Weather object containing EPW information # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files - # @param convert_shared_systems [Boolean] Whether to convert shared systems to equivalent in-unit systems per ANSI 301 + # @param convert_shared_systems [Boolean] Whether to convert shared systems to equivalent in-unit systems per ANSI/RESNET/ICC 301 # @return [Array] Maps of HPXML::Zones => DesignLoadValues object, HPXML::Spaces => DesignLoadValues object def self.apply(runner, hpxml, hpxml_bldg, weather, schedules_file: nil, convert_shared_systems: true) eri_version = hpxml.header.eri_calculation_version @@ -41,7 +41,7 @@ def self.apply(runner, hpxml, hpxml_bldg, weather, schedules_file: nil, convert_ end # Check for presence of fuels once - has_fuel = hpxml_bldg.has_fuels(hpxml.to_doc) + has_fuel = hpxml_bldg.has_fuels() add_zones_spaces_if_needed(hpxml_bldg, unit_num) @@ -652,7 +652,8 @@ def self.apply_building(hpxml_bldg, weather) # Conductivity/diffusivity values come from https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4813881 (with the exception of "unknown") if hpxml_bldg.site.ground_conductivity.nil? && hpxml_bldg.site.ground_diffusivity.nil? - if hpxml_bldg.site.soil_type == HPXML::SiteSoilTypeSand + case hpxml_bldg.site.soil_type + when HPXML::SiteSoilTypeSand if hpxml_bldg.site.moisture_type == HPXML::SiteSoilMoistureTypeDry hpxml_bldg.site.ground_conductivity = 0.2311 # Btu/hr-ft-F hpxml_bldg.site.ground_diffusivity = 0.0097 # ft^2/hr @@ -665,39 +666,40 @@ def self.apply_building(hpxml_bldg, weather) end hpxml_bldg.site.ground_conductivity_isdefaulted = true hpxml_bldg.site.ground_diffusivity_isdefaulted = true - elsif hpxml_bldg.site.soil_type == HPXML::SiteSoilTypeSilt || hpxml_bldg.site.soil_type == HPXML::SiteSoilTypeClay - if hpxml_bldg.site.moisture_type == HPXML::SiteSoilMoistureTypeDry + when HPXML::SiteSoilTypeSilt, HPXML::SiteSoilTypeClay + case hpxml_bldg.site.moisture_type + when HPXML::SiteSoilMoistureTypeDry hpxml_bldg.site.ground_conductivity = 0.2889 # Btu/hr-ft-F hpxml_bldg.site.ground_diffusivity = 0.0120 # ft^2/hr - elsif hpxml_bldg.site.moisture_type == HPXML::SiteSoilMoistureTypeWet + when HPXML::SiteSoilMoistureTypeWet hpxml_bldg.site.ground_conductivity = 0.9821 # Btu/hr-ft-F hpxml_bldg.site.ground_diffusivity = 0.0194 # ft^2/hr - elsif hpxml_bldg.site.moisture_type == HPXML::SiteSoilMoistureTypeMixed + when HPXML::SiteSoilMoistureTypeMixed hpxml_bldg.site.ground_conductivity = ((0.2889 + 0.9821) / 2.0).round(4) # Btu/hr-ft-F hpxml_bldg.site.ground_diffusivity = ((0.0120 + 0.0194) / 2.0).round(4) # ft^2/hr end hpxml_bldg.site.ground_conductivity_isdefaulted = true hpxml_bldg.site.ground_diffusivity_isdefaulted = true - elsif hpxml_bldg.site.soil_type == HPXML::SiteSoilTypeLoam + when HPXML::SiteSoilTypeLoam hpxml_bldg.site.ground_conductivity = 1.2132 # Btu/hr-ft-F hpxml_bldg.site.ground_diffusivity = 0.0353 # ft^2/hr - hpxml_bldg.site.ground_conductivity_isdefaulted = true hpxml_bldg.site.ground_diffusivity_isdefaulted = true - elsif hpxml_bldg.site.soil_type == HPXML::SiteSoilTypeGravel - if hpxml_bldg.site.moisture_type == HPXML::SiteSoilMoistureTypeDry + when HPXML::SiteSoilTypeGravel + case hpxml_bldg.site.moisture_type + when HPXML::SiteSoilMoistureTypeDry hpxml_bldg.site.ground_conductivity = 0.2311 # Btu/hr-ft-F hpxml_bldg.site.ground_diffusivity = 0.0097 # ft^2/hr - elsif hpxml_bldg.site.moisture_type == HPXML::SiteSoilMoistureTypeWet + when HPXML::SiteSoilMoistureTypeWet hpxml_bldg.site.ground_conductivity = 1.0399 # Btu/hr-ft-F hpxml_bldg.site.ground_diffusivity = 0.0291 # ft^2/hr - elsif hpxml_bldg.site.moisture_type == HPXML::SiteSoilMoistureTypeMixed + when HPXML::SiteSoilMoistureTypeMixed hpxml_bldg.site.ground_conductivity = ((0.2311 + 1.0399) / 2.0).round(4) # Btu/hr-ft-F hpxml_bldg.site.ground_diffusivity = ((0.0097 + 0.0291) / 2.0).round(4) # ft^2/hr end hpxml_bldg.site.ground_conductivity_isdefaulted = true hpxml_bldg.site.ground_diffusivity_isdefaulted = true - elsif hpxml_bldg.site.soil_type == HPXML::SiteSoilTypeUnknown + when HPXML::SiteSoilTypeUnknown hpxml_bldg.site.ground_conductivity = 1.0 # ANSI/RESNET/ICC 301-2022 Addendum C hpxml_bldg.site.ground_diffusivity = 0.0208 hpxml_bldg.site.ground_conductivity_isdefaulted = true @@ -827,13 +829,6 @@ def self.apply_neighbor_buildings(hpxml_bldg) # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files # @return [nil] def self.apply_building_occupancy(hpxml_bldg, schedules_file) - if not hpxml_bldg.building_occupancy.number_of_residents.nil? - # Set equivalent number of bedrooms for operational calculation; this is an adjustment on - # ANSI 301 or Building America equations, which are based on number of bedrooms. - hpxml_bldg.building_construction.additional_properties.equivalent_number_of_bedrooms = get_equivalent_nbeds_for_operational_calculation(hpxml_bldg) - else - hpxml_bldg.building_construction.additional_properties.equivalent_number_of_bedrooms = hpxml_bldg.building_construction.number_of_bedrooms - end schedules_file_includes_occupants = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:Occupants].name)) if hpxml_bldg.building_occupancy.weekday_fractions.nil? && !schedules_file_includes_occupants hpxml_bldg.building_occupancy.weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:Occupants].name]['WeekdayScheduleFractions'] @@ -1826,7 +1821,7 @@ def self.apply_furniture_mass(hpxml_bldg) # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param weather [WeatherFile] Weather object containing EPW information - # @param convert_shared_systems [Boolean] Whether to convert shared systems to equivalent in-unit systems per ANSI 301 + # @param convert_shared_systems [Boolean] Whether to convert shared systems to equivalent in-unit systems per ANSI/RESNET/ICC 301 # @param unit_num [Integer] Dwelling unit number # @return [nil] def self.apply_hvac(runner, hpxml_bldg, weather, convert_shared_systems, unit_num) @@ -2008,20 +2003,21 @@ def self.apply_hvac(runner, hpxml_bldg, weather, convert_shared_systems, unit_nu hpxml_bldg.cooling_systems.each do |cooling_system| next unless cooling_system.cooling_shr.nil? - if cooling_system.cooling_system_type == HPXML::HVACTypeCentralAirConditioner - if cooling_system.compressor_type == HPXML::HVACCompressorTypeSingleStage + case cooling_system.cooling_system_type + when HPXML::HVACTypeCentralAirConditioner + case cooling_system.compressor_type + when HPXML::HVACCompressorTypeSingleStage cooling_system.cooling_shr = 0.73 - elsif cooling_system.compressor_type == HPXML::HVACCompressorTypeTwoStage + when HPXML::HVACCompressorTypeTwoStage cooling_system.cooling_shr = 0.73 - elsif cooling_system.compressor_type == HPXML::HVACCompressorTypeVariableSpeed + when HPXML::HVACCompressorTypeVariableSpeed cooling_system.cooling_shr = 0.78 end cooling_system.cooling_shr_isdefaulted = true - elsif cooling_system.cooling_system_type == HPXML::HVACTypeRoomAirConditioner || - cooling_system.cooling_system_type == HPXML::HVACTypePTAC + when HPXML::HVACTypeRoomAirConditioner, HPXML::HVACTypePTAC cooling_system.cooling_shr = 0.65 cooling_system.cooling_shr_isdefaulted = true - elsif cooling_system.cooling_system_type == HPXML::HVACTypeMiniSplitAirConditioner + when HPXML::HVACTypeMiniSplitAirConditioner cooling_system.cooling_shr = 0.73 cooling_system.cooling_shr_isdefaulted = true end @@ -2029,23 +2025,24 @@ def self.apply_hvac(runner, hpxml_bldg, weather, convert_shared_systems, unit_nu hpxml_bldg.heat_pumps.each do |heat_pump| next unless heat_pump.cooling_shr.nil? - if heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpAirToAir - if heat_pump.compressor_type == HPXML::HVACCompressorTypeSingleStage + case heat_pump.heat_pump_type + when HPXML::HVACTypeHeatPumpAirToAir + case heat_pump.compressor_type + when HPXML::HVACCompressorTypeSingleStage heat_pump.cooling_shr = 0.73 - elsif heat_pump.compressor_type == HPXML::HVACCompressorTypeTwoStage + when HPXML::HVACCompressorTypeTwoStage heat_pump.cooling_shr = 0.73 - elsif heat_pump.compressor_type == HPXML::HVACCompressorTypeVariableSpeed + when HPXML::HVACCompressorTypeVariableSpeed heat_pump.cooling_shr = 0.78 end heat_pump.cooling_shr_isdefaulted = true - elsif heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpMiniSplit + when HPXML::HVACTypeHeatPumpMiniSplit heat_pump.cooling_shr = 0.73 heat_pump.cooling_shr_isdefaulted = true - elsif heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToAir + when HPXML::HVACTypeHeatPumpGroundToAir heat_pump.cooling_shr = 0.73 heat_pump.cooling_shr_isdefaulted = true - elsif heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpPTHP || - heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpRoom + when HPXML::HVACTypeHeatPumpPTHP, HPXML::HVACTypeHeatPumpRoom heat_pump.cooling_shr = 0.65 heat_pump.cooling_shr_isdefaulted = true end @@ -2111,7 +2108,8 @@ def self.apply_hvac(runner, hpxml_bldg, weather, convert_shared_systems, unit_nu mini_split_ductless_watts_per_cfm = 0.07 # W/cfm mini_split_ducted_watts_per_cfm = 0.18 # W/cfm hpxml_bldg.heating_systems.each do |heating_system| - if [HPXML::HVACTypeFurnace].include? heating_system.heating_system_type + case heating_system.heating_system_type + when HPXML::HVACTypeFurnace if heating_system.fan_watts_per_cfm.nil? if (not heating_system.distribution_system.nil?) && (heating_system.distribution_system.air_type == HPXML::AirTypeGravity) heating_system.fan_watts_per_cfm = 0.0 @@ -2122,15 +2120,13 @@ def self.apply_hvac(runner, hpxml_bldg, weather, convert_shared_systems, unit_nu end heating_system.fan_watts_per_cfm_isdefaulted = true end - elsif [HPXML::HVACTypeStove].include? heating_system.heating_system_type + when HPXML::HVACTypeStove if heating_system.fan_watts.nil? heating_system.fan_watts = 40.0 # W heating_system.fan_watts_isdefaulted = true end - elsif [HPXML::HVACTypeWallFurnace, - HPXML::HVACTypeFloorFurnace, - HPXML::HVACTypeSpaceHeater, - HPXML::HVACTypeFireplace].include? heating_system.heating_system_type + when HPXML::HVACTypeWallFurnace, HPXML::HVACTypeFloorFurnace, + HPXML::HVACTypeSpaceHeater, HPXML::HVACTypeFireplace if heating_system.fan_watts.nil? heating_system.fan_watts = 0.0 # W/cfm, assume no fan power heating_system.fan_watts_isdefaulted = true @@ -2143,42 +2139,46 @@ def self.apply_hvac(runner, hpxml_bldg, weather, convert_shared_systems, unit_nu if (not cooling_system.attached_heating_system.nil?) && (not cooling_system.attached_heating_system.fan_watts_per_cfm.nil?) cooling_system.fan_watts_per_cfm = cooling_system.attached_heating_system.fan_watts_per_cfm cooling_system.fan_watts_per_cfm_isdefaulted = true - elsif [HPXML::HVACTypeCentralAirConditioner].include? cooling_system.cooling_system_type - if cooling_system.cooling_efficiency_seer > 13.5 # HEScore assumption - cooling_system.fan_watts_per_cfm = ecm_watts_per_cfm - else - cooling_system.fan_watts_per_cfm = psc_watts_per_cfm - end - cooling_system.fan_watts_per_cfm_isdefaulted = true - elsif [HPXML::HVACTypeMiniSplitAirConditioner].include? cooling_system.cooling_system_type - if not cooling_system.distribution_system.nil? - cooling_system.fan_watts_per_cfm = mini_split_ducted_watts_per_cfm - else - cooling_system.fan_watts_per_cfm = mini_split_ductless_watts_per_cfm + else + case cooling_system.cooling_system_type + when HPXML::HVACTypeCentralAirConditioner + if cooling_system.cooling_efficiency_seer > 13.5 # HEScore assumption + cooling_system.fan_watts_per_cfm = ecm_watts_per_cfm + else + cooling_system.fan_watts_per_cfm = psc_watts_per_cfm + end + cooling_system.fan_watts_per_cfm_isdefaulted = true + when HPXML::HVACTypeMiniSplitAirConditioner + if not cooling_system.distribution_system.nil? + cooling_system.fan_watts_per_cfm = mini_split_ducted_watts_per_cfm + else + cooling_system.fan_watts_per_cfm = mini_split_ductless_watts_per_cfm + end + cooling_system.fan_watts_per_cfm_isdefaulted = true + when HPXML::HVACTypeEvaporativeCooler + # Depends on airflow rate, so defaulted in hvac_sizing.rb end - cooling_system.fan_watts_per_cfm_isdefaulted = true - elsif [HPXML::HVACTypeEvaporativeCooler].include? cooling_system.cooling_system_type - # Depends on airflow rate, so defaulted in hvac_sizing.rb end end hpxml_bldg.heat_pumps.each do |heat_pump| next unless heat_pump.fan_watts_per_cfm.nil? - if [HPXML::HVACTypeHeatPumpAirToAir].include? heat_pump.heat_pump_type + case heat_pump.heat_pump_type + when HPXML::HVACTypeHeatPumpAirToAir if heat_pump.heating_efficiency_hspf > 8.75 # HEScore assumption heat_pump.fan_watts_per_cfm = ecm_watts_per_cfm else heat_pump.fan_watts_per_cfm = psc_watts_per_cfm end heat_pump.fan_watts_per_cfm_isdefaulted = true - elsif [HPXML::HVACTypeHeatPumpGroundToAir].include? heat_pump.heat_pump_type + when HPXML::HVACTypeHeatPumpGroundToAir if heat_pump.heating_efficiency_cop > 8.75 / 3.2 # HEScore assumption heat_pump.fan_watts_per_cfm = ecm_watts_per_cfm else heat_pump.fan_watts_per_cfm = psc_watts_per_cfm end heat_pump.fan_watts_per_cfm_isdefaulted = true - elsif [HPXML::HVACTypeHeatPumpMiniSplit].include? heat_pump.heat_pump_type + when HPXML::HVACTypeHeatPumpMiniSplit if not heat_pump.distribution_system.nil? heat_pump.fan_watts_per_cfm = mini_split_ducted_watts_per_cfm else @@ -2234,10 +2234,9 @@ def self.apply_hvac(runner, hpxml_bldg, weather, convert_shared_systems, unit_nu # Detailed HVAC performance hpxml_bldg.cooling_systems.each do |cooling_system| clg_ap = cooling_system.additional_properties - if [HPXML::HVACTypeCentralAirConditioner, - HPXML::HVACTypeMiniSplitAirConditioner, - HPXML::HVACTypeRoomAirConditioner, - HPXML::HVACTypePTAC].include? cooling_system.cooling_system_type + case cooling_system.cooling_system_type + when HPXML::HVACTypeCentralAirConditioner, HPXML::HVACTypeMiniSplitAirConditioner, + HPXML::HVACTypeRoomAirConditioner, HPXML::HVACTypePTAC if [HPXML::HVACTypeRoomAirConditioner, HPXML::HVACTypePTAC].include? cooling_system.cooling_system_type use_eer = true @@ -2248,7 +2247,7 @@ def self.apply_hvac(runner, hpxml_bldg, weather, convert_shared_systems, unit_nu HVAC.set_fan_power_rated(cooling_system, use_eer) HVAC.set_cool_curves_central_air_source(cooling_system, use_eer) - elsif [HPXML::HVACTypeEvaporativeCooler].include? cooling_system.cooling_system_type + when HPXML::HVACTypeEvaporativeCooler clg_ap.effectiveness = 0.72 # Assumption from HEScore end @@ -2263,10 +2262,9 @@ def self.apply_hvac(runner, hpxml_bldg, weather, convert_shared_systems, unit_nu heating_system.additional_properties.heat_rated_cfm_per_ton = HVAC.get_heat_cfm_per_ton(HPXML::HVACCompressorTypeSingleStage, true) end hpxml_bldg.heat_pumps.each do |heat_pump| - if [HPXML::HVACTypeHeatPumpAirToAir, - HPXML::HVACTypeHeatPumpMiniSplit, - HPXML::HVACTypeHeatPumpPTHP, - HPXML::HVACTypeHeatPumpRoom].include? heat_pump.heat_pump_type + case heat_pump.heat_pump_type + when HPXML::HVACTypeHeatPumpAirToAir, HPXML::HVACTypeHeatPumpMiniSplit, + HPXML::HVACTypeHeatPumpPTHP, HPXML::HVACTypeHeatPumpRoom if [HPXML::HVACTypeHeatPumpPTHP, HPXML::HVACTypeHeatPumpRoom].include? heat_pump.heat_pump_type use_eer_cop = true else @@ -2277,7 +2275,7 @@ def self.apply_hvac(runner, hpxml_bldg, weather, convert_shared_systems, unit_nu HVAC.set_cool_curves_central_air_source(heat_pump, use_eer_cop) HVAC.set_heat_curves_central_air_source(heat_pump, use_eer_cop) - elsif [HPXML::HVACTypeHeatPumpGroundToAir].include? heat_pump.heat_pump_type + when HPXML::HVACTypeHeatPumpGroundToAir HVAC.set_heat_pump_temperatures(heat_pump, runner) if heat_pump.geothermal_loop.nil? @@ -2342,7 +2340,7 @@ def self.apply_hvac(runner, hpxml_bldg, weather, convert_shared_systems, unit_nu heat_pump.geothermal_loop.shank_spacing = (hp_ap.u_tube_spacing + hp_ap.pipe_od).round(2) # Distance from center of pipe to center of pipe heat_pump.geothermal_loop.shank_spacing_isdefaulted = true end - elsif [HPXML::HVACTypeHeatPumpWaterLoopToAir].include? heat_pump.heat_pump_type + when HPXML::HVACTypeHeatPumpWaterLoopToAir HVAC.set_heat_pump_temperatures(heat_pump, runner) end @@ -2993,12 +2991,13 @@ def self.apply_hot_water_distribution(hpxml_bldg, schedules_file) hot_water_distribution.pipe_r_value_isdefaulted = true end - if hot_water_distribution.system_type == HPXML::DHWDistTypeStandard + case hot_water_distribution.system_type + when HPXML::DHWDistTypeStandard if hot_water_distribution.standard_piping_length.nil? hot_water_distribution.standard_piping_length = get_std_pipe_length(has_uncond_bsmnt, has_cond_bsmnt, cfa, ncfl) hot_water_distribution.standard_piping_length_isdefaulted = true end - elsif hot_water_distribution.system_type == HPXML::DHWDistTypeRecirc + when HPXML::DHWDistTypeRecirc if hot_water_distribution.recirculation_piping_loop_length.nil? hot_water_distribution.recirculation_piping_loop_length = get_recirc_loop_length(has_uncond_bsmnt, has_cond_bsmnt, cfa, ncfl) hot_water_distribution.recirculation_piping_loop_length_isdefaulted = true @@ -3023,7 +3022,8 @@ def self.apply_hot_water_distribution(hpxml_bldg, schedules_file) if hot_water_distribution.system_type == HPXML::DHWDistTypeRecirc || hot_water_distribution.has_shared_recirculation schedules_file_includes_recirculation_pump = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:HotWaterRecirculationPump].name)) recirc_control_type = hot_water_distribution.has_shared_recirculation ? hot_water_distribution.shared_recirculation_control_type : hot_water_distribution.recirculation_control_type - if [HPXML::DHWRecircControlTypeNone, HPXML::DHWRecircControlTypeTimer].include?(recirc_control_type) + case recirc_control_type + when HPXML::DHWRecircControlTypeNone, HPXML::DHWRecircControlTypeTimer if hot_water_distribution.recirculation_pump_weekday_fractions.nil? && !schedules_file_includes_recirculation_pump hot_water_distribution.recirculation_pump_weekday_fractions = @default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_no_control"]['RecirculationPumpWeekdayScheduleFractions'] hot_water_distribution.recirculation_pump_weekday_fractions_isdefaulted = true @@ -3032,7 +3032,7 @@ def self.apply_hot_water_distribution(hpxml_bldg, schedules_file) hot_water_distribution.recirculation_pump_weekend_fractions = @default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_no_control"]['RecirculationPumpWeekendScheduleFractions'] hot_water_distribution.recirculation_pump_weekend_fractions_isdefaulted = true end - elsif [HPXML::DHWRecircControlTypeSensor, HPXML::DHWRecircControlTypeManual].include?(recirc_control_type) + when HPXML::DHWRecircControlTypeSensor, HPXML::DHWRecircControlTypeManual if hot_water_distribution.recirculation_pump_weekday_fractions.nil? && !schedules_file_includes_recirculation_pump hot_water_distribution.recirculation_pump_weekday_fractions = @default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_demand_control"]['RecirculationPumpWeekdayScheduleFractions'] hot_water_distribution.recirculation_pump_weekday_fractions_isdefaulted = true @@ -3041,7 +3041,7 @@ def self.apply_hot_water_distribution(hpxml_bldg, schedules_file) hot_water_distribution.recirculation_pump_weekend_fractions = @default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_demand_control"]['RecirculationPumpWeekendScheduleFractions'] hot_water_distribution.recirculation_pump_weekend_fractions_isdefaulted = true end - elsif [HPXML::DHWRecircControlTypeTemperature].include?(recirc_control_type) + when HPXML::DHWRecircControlTypeTemperature if hot_water_distribution.recirculation_pump_weekday_fractions.nil? && !schedules_file_includes_recirculation_pump hot_water_distribution.recirculation_pump_weekday_fractions = @default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_temperature_control"]['RecirculationPumpWeekdayScheduleFractions'] hot_water_distribution.recirculation_pump_weekday_fractions_isdefaulted = true @@ -3682,7 +3682,9 @@ def self.apply_ceiling_fans(hpxml_bldg, weather, schedules_file) # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files # @return [nil] def self.apply_pools_and_permanent_spas(hpxml_bldg, schedules_file) - nbeds_eq = hpxml_bldg.building_construction.additional_properties.equivalent_number_of_bedrooms + nbeds = hpxml_bldg.building_construction.number_of_bedrooms + n_occ = hpxml_bldg.building_occupancy.number_of_residents + unit_type = hpxml_bldg.building_construction.residential_facility_type cfa = hpxml_bldg.building_construction.conditioned_floor_area hpxml_bldg.pools.each do |pool| next if pool.type == HPXML::TypeNone @@ -3690,7 +3692,7 @@ def self.apply_pools_and_permanent_spas(hpxml_bldg, schedules_file) if pool.pump_type != HPXML::TypeNone # Pump if pool.pump_kwh_per_year.nil? - pool.pump_kwh_per_year = get_pool_pump_annual_energy(cfa, nbeds_eq) + pool.pump_kwh_per_year = get_pool_pump_annual_energy(cfa, nbeds, n_occ, unit_type) pool.pump_kwh_per_year_isdefaulted = true end if pool.pump_usage_multiplier.nil? @@ -3716,7 +3718,7 @@ def self.apply_pools_and_permanent_spas(hpxml_bldg, schedules_file) # Heater if pool.heater_load_value.nil? - default_heater_load_units, default_heater_load_value = get_pool_heater_annual_energy(cfa, nbeds_eq, pool.heater_type) + default_heater_load_units, default_heater_load_value = get_pool_heater_annual_energy(cfa, nbeds, n_occ, unit_type, pool.heater_type) pool.heater_load_units = default_heater_load_units pool.heater_load_value = default_heater_load_value pool.heater_load_value_isdefaulted = true @@ -3746,7 +3748,7 @@ def self.apply_pools_and_permanent_spas(hpxml_bldg, schedules_file) if spa.pump_type != HPXML::TypeNone # Pump if spa.pump_kwh_per_year.nil? - spa.pump_kwh_per_year = get_permanent_spa_pump_annual_energy(cfa, nbeds_eq) + spa.pump_kwh_per_year = get_permanent_spa_pump_annual_energy(cfa, nbeds, n_occ, unit_type) spa.pump_kwh_per_year_isdefaulted = true end if spa.pump_usage_multiplier.nil? @@ -3772,7 +3774,7 @@ def self.apply_pools_and_permanent_spas(hpxml_bldg, schedules_file) # Heater if spa.heater_load_value.nil? - default_heater_load_units, default_heater_load_value = get_permanent_spa_heater_annual_energy(cfa, nbeds_eq, spa.heater_type) + default_heater_load_units, default_heater_load_value = get_permanent_spa_heater_annual_energy(cfa, nbeds, n_occ, unit_type, spa.heater_type) spa.heater_load_units = default_heater_load_units spa.heater_load_value = default_heater_load_value spa.heater_load_value_isdefaulted = true @@ -3805,12 +3807,12 @@ def self.apply_pools_and_permanent_spas(hpxml_bldg, schedules_file) def self.apply_plug_loads(hpxml_bldg, schedules_file) cfa = hpxml_bldg.building_construction.conditioned_floor_area nbeds = hpxml_bldg.building_construction.number_of_bedrooms - nbeds_eq = hpxml_bldg.building_construction.additional_properties.equivalent_number_of_bedrooms - num_occ = hpxml_bldg.building_occupancy.number_of_residents + n_occ = hpxml_bldg.building_occupancy.number_of_residents unit_type = hpxml_bldg.building_construction.residential_facility_type hpxml_bldg.plug_loads.each do |plug_load| - if plug_load.plug_load_type == HPXML::PlugLoadTypeOther - default_annual_kwh, default_sens_frac, default_lat_frac = get_residual_mels_values(cfa, num_occ, unit_type) + case plug_load.plug_load_type + when HPXML::PlugLoadTypeOther + default_annual_kwh, default_sens_frac, default_lat_frac = get_residual_mels_values(cfa, n_occ, unit_type) if plug_load.kwh_per_year.nil? plug_load.kwh_per_year = default_annual_kwh plug_load.kwh_per_year_isdefaulted = true @@ -3836,8 +3838,8 @@ def self.apply_plug_loads(hpxml_bldg, schedules_file) plug_load.monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsOther].name]['MonthlyScheduleMultipliers'] plug_load.monthly_multipliers_isdefaulted = true end - elsif plug_load.plug_load_type == HPXML::PlugLoadTypeTelevision - default_annual_kwh, default_sens_frac, default_lat_frac = get_televisions_values(cfa, nbeds, num_occ, unit_type) + when HPXML::PlugLoadTypeTelevision + default_annual_kwh, default_sens_frac, default_lat_frac = get_televisions_values(cfa, nbeds, n_occ, unit_type) if plug_load.kwh_per_year.nil? plug_load.kwh_per_year = default_annual_kwh plug_load.kwh_per_year_isdefaulted = true @@ -3863,7 +3865,7 @@ def self.apply_plug_loads(hpxml_bldg, schedules_file) plug_load.monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsTV].name]['MonthlyScheduleMultipliers'] plug_load.monthly_multipliers_isdefaulted = true end - elsif plug_load.plug_load_type == HPXML::PlugLoadTypeElectricVehicleCharging + when HPXML::PlugLoadTypeElectricVehicleCharging default_annual_kwh = get_electric_vehicle_charging_annual_energy if plug_load.kwh_per_year.nil? plug_load.kwh_per_year = default_annual_kwh @@ -3890,8 +3892,8 @@ def self.apply_plug_loads(hpxml_bldg, schedules_file) plug_load.monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:PlugLoadsVehicle].name]['MonthlyScheduleMultipliers'] plug_load.monthly_multipliers_isdefaulted = true end - elsif plug_load.plug_load_type == HPXML::PlugLoadTypeWellPump - default_annual_kwh = get_detault_well_pump_annual_energy(cfa, nbeds_eq) + when HPXML::PlugLoadTypeWellPump + default_annual_kwh = get_detault_well_pump_annual_energy(cfa, nbeds, n_occ, unit_type) if plug_load.kwh_per_year.nil? plug_load.kwh_per_year = default_annual_kwh plug_load.kwh_per_year_isdefaulted = true @@ -3932,11 +3934,14 @@ def self.apply_plug_loads(hpxml_bldg, schedules_file) # @return [nil] def self.apply_fuel_loads(hpxml_bldg, schedules_file) cfa = hpxml_bldg.building_construction.conditioned_floor_area - nbeds_eq = hpxml_bldg.building_construction.additional_properties.equivalent_number_of_bedrooms + nbeds = hpxml_bldg.building_construction.number_of_bedrooms + n_occ = hpxml_bldg.building_occupancy.number_of_residents + unit_type = hpxml_bldg.building_construction.residential_facility_type hpxml_bldg.fuel_loads.each do |fuel_load| - if fuel_load.fuel_load_type == HPXML::FuelLoadTypeGrill + case fuel_load.fuel_load_type + when HPXML::FuelLoadTypeGrill if fuel_load.therm_per_year.nil? - fuel_load.therm_per_year = get_gas_grill_annual_energy(cfa, nbeds_eq) + fuel_load.therm_per_year = get_gas_grill_annual_energy(cfa, nbeds, n_occ, unit_type) fuel_load.therm_per_year_isdefaulted = true end if fuel_load.frac_sensible.nil? @@ -3960,9 +3965,9 @@ def self.apply_fuel_loads(hpxml_bldg, schedules_file) fuel_load.monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:FuelLoadsGrill].name]['MonthlyScheduleMultipliers'] fuel_load.monthly_multipliers_isdefaulted = true end - elsif fuel_load.fuel_load_type == HPXML::FuelLoadTypeLighting + when HPXML::FuelLoadTypeLighting if fuel_load.therm_per_year.nil? - fuel_load.therm_per_year = get_detault_gas_lighting_annual_energy(cfa, nbeds_eq) + fuel_load.therm_per_year = get_detault_gas_lighting_annual_energy(cfa, nbeds, n_occ, unit_type) fuel_load.therm_per_year_isdefaulted = true end if fuel_load.frac_sensible.nil? @@ -3986,9 +3991,9 @@ def self.apply_fuel_loads(hpxml_bldg, schedules_file) fuel_load.monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:FuelLoadsLighting].name]['MonthlyScheduleMultipliers'] fuel_load.monthly_multipliers_isdefaulted = true end - elsif fuel_load.fuel_load_type == HPXML::FuelLoadTypeFireplace + when HPXML::FuelLoadTypeFireplace if fuel_load.therm_per_year.nil? - fuel_load.therm_per_year = get_gas_fireplace_annual_energy(cfa, nbeds_eq) + fuel_load.therm_per_year = get_gas_fireplace_annual_energy(cfa, nbeds, n_occ, unit_type) fuel_load.therm_per_year_isdefaulted = true end if fuel_load.frac_sensible.nil? @@ -4050,21 +4055,22 @@ def self.cleanup_zones_spaces(hpxml_bldg) def self.get_azimuth_from_orientation(orientation) return if orientation.nil? - if orientation == HPXML::OrientationNorth + case orientation + when HPXML::OrientationNorth return 0 - elsif orientation == HPXML::OrientationNortheast + when HPXML::OrientationNortheast return 45 - elsif orientation == HPXML::OrientationEast + when HPXML::OrientationEast return 90 - elsif orientation == HPXML::OrientationSoutheast + when HPXML::OrientationSoutheast return 135 - elsif orientation == HPXML::OrientationSouth + when HPXML::OrientationSouth return 180 - elsif orientation == HPXML::OrientationSouthwest + when HPXML::OrientationSouthwest return 225 - elsif orientation == HPXML::OrientationWest + when HPXML::OrientationWest return 270 - elsif orientation == HPXML::OrientationNorthwest + when HPXML::OrientationNorthwest return 315 end @@ -4098,26 +4104,34 @@ def self.get_orientation_from_azimuth(azimuth) end # Gets the equivalent number of bedrooms for an operational calculation (i.e., when number - # of occupants are provided in the HPXML); this is an adjustment to the ANSI 301 or Building - # America equations, which are based on number of bedrooms. + # of occupants are provided in the HPXML); this is an adjustment to the ANSI/RESNET/ICC 301 or Building + # America equations, which are based on number of bedrooms. If an asset calculation (number + # of occupants provided), the number of bedrooms is simply returned. # # This is used to adjust occupancy-driven end uses from asset calculations (based on number # of bedrooms) to operational calculations (based on number of occupants). # - # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit + # Source: 2020 RECS weighted regressions between NBEDS and NHSHLDMEM (sample weights = NWEIGHT) + # + # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @return [Double] Equivalent number of bedrooms - def self.get_equivalent_nbeds_for_operational_calculation(hpxml_bldg) - n_occs = hpxml_bldg.building_occupancy.number_of_residents - unit_type = hpxml_bldg.building_construction.residential_facility_type - # Relations below come from 2020 RECS weighted regressions between NBEDS and NHSHLDMEM (sample weights = NWEIGHT) - if [HPXML::ResidentialTypeApartment].include? unit_type - return -1.36 + 1.49 * n_occs - elsif [HPXML::ResidentialTypeSFA].include? unit_type - return -1.98 + 1.89 * n_occs - elsif [HPXML::ResidentialTypeSFD].include? unit_type - return -2.19 + 2.08 * n_occs - elsif [HPXML::ResidentialTypeManufactured].include? unit_type - return -1.26 + 1.61 * n_occs + def self.get_equivalent_nbeds(nbeds, n_occ, unit_type) + if n_occ.nil? + # No occupants specified, asset rating + return nbeds + end + + case unit_type + when HPXML::ResidentialTypeApartment + return -1.36 + 1.49 * n_occ + when HPXML::ResidentialTypeSFA + return -1.98 + 1.89 * n_occ + when HPXML::ResidentialTypeSFD + return -2.19 + 2.08 * n_occ + when HPXML::ResidentialTypeManufactured + return -1.26 + 1.61 * n_occ else fail "Unexpected residential facility type: #{unit_type}." end @@ -4134,20 +4148,16 @@ def self.get_flue_or_chimney_in_conditioned_space(hpxml_bldg) next if heating_system.heating_system_fuel == HPXML::FuelTypeElectricity next unless HPXML::conditioned_locations_this_unit.include? heating_system.location - if [HPXML::HVACTypeFurnace, - HPXML::HVACTypeBoiler, - HPXML::HVACTypeWallFurnace, - HPXML::HVACTypeFloorFurnace, - HPXML::HVACTypeStove, - HPXML::HVACTypeSpaceHeater].include? heating_system.heating_system_type + case heating_system.heating_system_type + when HPXML::HVACTypeFurnace, HPXML::HVACTypeBoiler, HPXML::HVACTypeWallFurnace, + HPXML::HVACTypeFloorFurnace, HPXML::HVACTypeStove, HPXML::HVACTypeSpaceHeater if not heating_system.heating_efficiency_afue.nil? next if heating_system.heating_efficiency_afue >= 0.89 elsif not heating_system.heating_efficiency_percent.nil? next if heating_system.heating_efficiency_percent >= 0.89 end - return true - elsif [HPXML::HVACTypeFireplace].include? heating_system.heating_system_type + when HPXML::HVACTypeFireplace return true end end @@ -4575,11 +4585,13 @@ def self.get_clothes_washer_values(eri_version) # Gets the default piping length for a standard hot water distribution system. # - # Per ANSI 301-2022, the length of hot water piping from the hot water heater to the farthest + # The length of hot water piping from the hot water heater to the farthest # hot water fixture, measured longitudinally from plans, assuming the hot water piping does # not run diagonally, plus 10 feet of piping for each floor level, plus 5 feet of piping for # unconditioned basements (if any). # + # Source: ANSI/RESNET/ICC 301-2022 + # # @param has_uncond_bsmnt [Boolean] Whether the dwelling unit has an unconditioned basement # @param has_cond_bsmnt [Boolean] Whether the dwelling unit has a conditioned basement # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) @@ -4591,16 +4603,18 @@ def self.get_std_pipe_length(has_uncond_bsmnt, has_cond_bsmnt, cfa, ncfl) bsmnt = 1 end - return 2.0 * (cfa / ncfl)**0.5 + 10.0 * ncfl + 5.0 * bsmnt # PipeL in ANSI 301 + return 2.0 * (cfa / ncfl)**0.5 + 10.0 * ncfl + 5.0 * bsmnt # PipeL in ANSI/RESNET/ICC 301 end # Gets the default loop piping length for a recirculation hot water distribution system. # - # Per ANSI 301-2022, the recirculation loop length including both supply and return sides, + # The recirculation loop length including both supply and return sides, # measured longitudinally from plans, assuming the hot water piping does not run diagonally, # plus 20 feet of piping for each floor level greater than one plus 10 feet of piping for # unconditioned basements. # + # Source: ANSI/RESNET/ICC 301-2022 + # # @param has_uncond_bsmnt [Boolean] Whether the dwelling unit has an unconditioned basement # @param has_cond_bsmnt [Boolean] Whether the dwelling unit has a conditioned basement # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) @@ -4608,32 +4622,34 @@ def self.get_std_pipe_length(has_uncond_bsmnt, has_cond_bsmnt, cfa, ncfl) # @return [Double] Piping length (ft) def self.get_recirc_loop_length(has_uncond_bsmnt, has_cond_bsmnt, cfa, ncfl) std_pipe_length = get_std_pipe_length(has_uncond_bsmnt, has_cond_bsmnt, cfa, ncfl) - return 2.0 * std_pipe_length - 20.0 # refLoopL in ANSI 301 + return 2.0 * std_pipe_length - 20.0 # refLoopL in ANSI/RESNET/ICC 301 end # Gets the default branch piping length for a recirculation hot water distribution system. # - # Per ANSI 301-2022, the length of the branch hot water piping from the recirculation loop + # The length of the branch hot water piping from the recirculation loop # to the farthest hot water fixture from the recirculation loop, measured longitudinally # from plans, assuming the branch hot water piping does not run diagonally. # + # Source: ANSI/RESNET/ICC 301-2022 + # # @return [Double] Piping length (ft) def self.get_recirc_branch_length() - return 10.0 # See pRatio in ANSI 301 + return 10.0 # See pRatio in ANSI/RESNET/ICC 301 end # Gets the default pump power for a recirculation system. # # @return [Double] Pump power (W) def self.get_recirc_pump_power() - return 50.0 # See pumpW in ANSI 301 + return 50.0 # See pumpW in ANSI/RESNET/ICC 301 end # Gets the default pump power for a shared recirculation system. # # @return [Double] Pump power (W) def self.get_shared_recirc_pump_power() - # From ANSI/RESNET/ICC 301-2019 Equation 4.2-15b + # From ANSI/RESNET/ICC 301-2022 Eq. 4.2-43b pump_horsepower = 0.25 motor_efficiency = 0.85 pump_kw = pump_horsepower * 0.746 / motor_efficiency @@ -4667,9 +4683,11 @@ def self.get_freezer_or_extra_fridge_location(hpxml_bldg) # Window represents multiple windows, the value is calculated as the total window area # for any operable windows divided by the total window area. # + # Source: ANSI/RESNET/ICC 301-2025 + # # @return [Double] Operable fraction (frac) def self.get_fraction_of_windows_operable() - return 0.67 # 67% per ANSI 301-2025 + return 0.67 # 67% end # Gets the default specific leakage area (SLA) for a vented attic. @@ -4677,7 +4695,7 @@ def self.get_fraction_of_windows_operable() # # @return [Double] Specific leakage area (frac) def self.get_vented_attic_sla() - return (1.0 / 300.0).round(6) # ANSI 301, Table 4.2.2(1) - Attics + return (1.0 / 300.0).round(6) # ANSI/RESNET/ICC 301, Table 4.2.2(1) - Attics end # Gets the default specific leakage area (SLA) for a vented crawlspace. @@ -4685,7 +4703,7 @@ def self.get_vented_attic_sla() # # @return [Double] Specific leakage area (frac) def self.get_vented_crawl_sla() - return (1.0 / 150.0).round(6) # ANSI 301, Table 4.2.2(1) - Crawlspaces + return (1.0 / 150.0).round(6) # ANSI/RESNET/ICC 301, Table 4.2.2(1) - Crawlspaces end # Gets the default whole-home mechanical ventilation fan flow rate required to @@ -4700,11 +4718,11 @@ def self.get_vented_crawl_sla() # @param eri_version [String] Version of the ANSI/RESNET/ICC 301 Standard to use for equations/assumptions # @return [Double] Fan flow rate (cfm) def self.get_mech_vent_flow_rate_for_vent_fan(hpxml_bldg, vent_fan, weather, eri_version) - # Calculates Qfan cfm requirement per ASHRAE 62.2 / ANSI 301 + # Calculates Qfan cfm requirement per ASHRAE 62.2 / ANSI/RESNET/ICC 301 cfa = hpxml_bldg.building_construction.conditioned_floor_area nbeds = hpxml_bldg.building_construction.number_of_bedrooms infil_values = Airflow.get_values_from_air_infiltration_measurements(hpxml_bldg, weather) - bldg_type = hpxml_bldg.building_construction.residential_facility_type + unit_type = hpxml_bldg.building_construction.residential_facility_type nl = Airflow.get_infiltration_NL_from_SLA(infil_values[:sla], infil_values[:height]) q_inf = Airflow.get_infiltration_Qinf_from_NL(nl, weather, cfa) @@ -4714,23 +4732,27 @@ def self.get_mech_vent_flow_rate_for_vent_fan(hpxml_bldg, vent_fan, weather, eri else is_balanced, frac_imbal = false, 1.0 end - q_fan = Airflow.get_mech_vent_qfan_cfm(q_tot, q_inf, is_balanced, frac_imbal, infil_values[:a_ext], bldg_type, eri_version, vent_fan.hours_in_operation) + q_fan = Airflow.get_mech_vent_qfan_cfm(q_tot, q_inf, is_balanced, frac_imbal, infil_values[:a_ext], unit_type, eri_version, vent_fan.hours_in_operation) return q_fan end # Gets the default whole-home mechanical ventilation fan efficiency. # + # Source: ANSI/RESNET/ICC 301 + # # @param vent_fan [HPXML::VentilationFan] The HPXML ventilation fan of interest # @return [Double] Fan efficiency (W/cfm) def self.get_mech_vent_fan_efficiency(vent_fan) - # Returns fan power in W/cfm, based on ANSI 301 if vent_fan.is_shared_system return 1.00 # Table 4.2.2(1) Note (n) - elsif [HPXML::MechVentTypeSupply, HPXML::MechVentTypeExhaust].include? vent_fan.fan_type + end + + case vent_fan.fan_type + when HPXML::MechVentTypeSupply, HPXML::MechVentTypeExhaust return 0.35 - elsif [HPXML::MechVentTypeBalanced].include? vent_fan.fan_type + when HPXML::MechVentTypeBalanced return 0.70 - elsif [HPXML::MechVentTypeERV, HPXML::MechVentTypeHRV].include? vent_fan.fan_type + when HPXML::MechVentTypeERV, HPXML::MechVentTypeHRV return 1.00 else fail "Unexpected fan_type: '#{fan_type}'." @@ -4788,27 +4810,28 @@ def self.get_infiltration_ach50(cfa, ncfl_ag, year_built, avg_ceiling_height, in # Climate zone c_iecc = nil - if (iecc_cz == '1A') || (iecc_cz == '2A') + case iecc_cz + when '1A', '2A' c_iecc = 0.4727 - elsif iecc_cz == '3A' + when '3A' c_iecc = 0.2529 - elsif iecc_cz == '4A' + when '4A' c_iecc = 0.3261 - elsif iecc_cz == '5A' + when '5A' c_iecc = 0.1118 - elsif (iecc_cz == '6A') || (iecc_cz == '7') + when '6A', '7' c_iecc = 0.0 - elsif (iecc_cz == '2B') || (iecc_cz == '3B') + when '2B', '3B' c_iecc = -0.03755 - elsif (iecc_cz == '4B') || (iecc_cz == '5B') + when '4B', '5B' c_iecc = -0.008774 - elsif iecc_cz == '6B' + when '6B' c_iecc = 0.01944 - elsif iecc_cz == '3C' + when '3C' c_iecc = 0.04827 - elsif iecc_cz == '4C' + when '4C' c_iecc = 0.2584 - elsif iecc_cz == '8' + when '8' c_iecc = -0.5119 else fail "Unexpected IECC climate zone: #{c_iecc}" @@ -4869,7 +4892,7 @@ def self.get_infiltration_ach50(cfa, ncfl_ag, year_built, avg_ceiling_height, in # @param f_rect [Double] The fraction of duct length that is rectangular (not round) # @return [Double] Duct effective R-value (hr-ft2-F/Btu) def self.get_duct_effective_r_value(r_nominal, side, buried_level, f_rect) - # This methodology has been proposed by NREL for ANSI 301-2025. + # This methodology has been proposed by NREL for ANSI/RESNET/ICC 301-2025. if buried_level == HPXML::DuctBuriedInsulationNone if r_nominal <= 0 # Uninsulated ducts are set to R-1.7 based on ASHRAE HOF and the above paper. @@ -4898,21 +4921,23 @@ def self.get_duct_effective_r_value(r_nominal, side, buried_level, f_rect) if side == HPXML::DuctTypeSupply # Equations derived from Table 13 in https://www.nrel.gov/docs/fy13osti/55876.pdf # assuming 6-in supply diameter - if buried_level == HPXML::DuctBuriedInsulationPartial + case buried_level + when HPXML::DuctBuriedInsulationPartial return (4.28 + 0.65 * r_nominal).round(2) - elsif buried_level == HPXML::DuctBuriedInsulationFull + when HPXML::DuctBuriedInsulationFull return (6.22 + 0.89 * r_nominal).round(2) - elsif buried_level == HPXML::DuctBuriedInsulationDeep + when HPXML::DuctBuriedInsulationDeep return (13.41 + 0.63 * r_nominal).round(2) end elsif side == HPXML::DuctTypeReturn # Equations derived from Table 13 in https://www.nrel.gov/docs/fy13osti/55876.pdf # assuming 14-in return diameter - if buried_level == HPXML::DuctBuriedInsulationPartial + case buried_level + when HPXML::DuctBuriedInsulationPartial return (4.62 + 1.31 * r_nominal).round(2) - elsif buried_level == HPXML::DuctBuriedInsulationFull + when HPXML::DuctBuriedInsulationFull return (8.91 + 1.29 * r_nominal).round(2) - elsif buried_level == HPXML::DuctBuriedInsulationDeep + when HPXML::DuctBuriedInsulationDeep return (18.64 + 1.0 * r_nominal).round(2) end end @@ -4926,14 +4951,19 @@ def self.get_duct_effective_r_value(r_nominal, side, buried_level, f_rect) # @return [String] Water heater location (HPXML::LocationXXX) def self.get_water_heater_location(hpxml_bldg, iecc_zone = nil) # ANSI/RESNET/ICC 301-2022C - if ['1A', '1B', '1C', '2A', '2B', '2C', '3A', '3B', '3C'].include? iecc_zone + case iecc_zone + when '1A', '1B', '1C', '2A', '2B', '2C', '3A', '3B', '3C' location_hierarchy = [HPXML::LocationGarage, HPXML::LocationConditionedSpace] - elsif ['4A', '4B', '4C', '5A', '5B', '5C', '6A', '6B', '6C', '7', '8'].include? iecc_zone + when '4A', '4B', '4C', '5A', '5B', '5C', '6A', '6B', '6C', '7', '8' location_hierarchy = [HPXML::LocationBasementUnconditioned, HPXML::LocationBasementConditioned, HPXML::LocationConditionedSpace] - elsif iecc_zone.nil? + else + if not iecc_zone.nil? + fail "Unexpected IECC zone: #{iecc_zone}." + end + location_hierarchy = [HPXML::LocationBasementConditioned, HPXML::LocationBasementUnconditioned, HPXML::LocationConditionedSpace] @@ -4966,9 +4996,9 @@ def self.get_water_heater_temperature(eri_version) def self.get_water_heater_performance_adjustment(water_heating_system) return unless water_heating_system.water_heater_type == HPXML::WaterHeaterTypeTankless if not water_heating_system.energy_factor.nil? - return 0.92 # Applies to EF, ANSI 301-2019 + return 0.92 # Applies to EF, ANSI/RESNET/ICC 301-2022 elsif not water_heating_system.uniform_energy_factor.nil? - return 0.94 # Applies to UEF, ANSI 301-2019 + return 0.94 # Applies to UEF, ANSI/RESNET/ICC 301-2022 end end @@ -5038,15 +5068,16 @@ def self.get_water_heater_tank_volume(fuel, nbeds, nbaths = nil) end if fuel != HPXML::FuelTypeElectricity # Non-electric tank WHs - if nbeds <= 2 + case nbeds + when 0, 1, 2 return 30.0 - elsif nbeds == 3 + when 3 if nbaths <= 1.5 return 30.0 else return 40.0 end - elsif nbeds == 4 + when 4 if nbaths <= 2.5 return 40.0 else @@ -5056,27 +5087,28 @@ def self.get_water_heater_tank_volume(fuel, nbeds, nbaths = nil) return 50.0 end else - if nbeds == 1 + case nbeds + when 0, 1 return 30.0 - elsif nbeds == 2 + when 2 if nbaths <= 1.5 return 30.0 else return 40.0 end - elsif nbeds == 3 + when 3 if nbaths <= 1.5 return 40.0 else return 50.0 end - elsif nbeds == 4 + when 4 if nbaths <= 2.5 return 50.0 else return 66.0 end - elsif nbeds == 5 + when 5 return 66.0 else return 80.0 @@ -5195,37 +5227,34 @@ def self.get_wall_solar_absorptance(wall) def self.get_window_ufactor_shgc(window) type = window.is_a?(HPXML::Window) ? 'window' : 'skylight' - if window.glass_layers == HPXML::WindowLayersSinglePane + case window.glass_layers + when HPXML::WindowLayersSinglePane n_panes = 1 - elsif window.glass_layers == HPXML::WindowLayersDoublePane + when HPXML::WindowLayersDoublePane n_panes = 2 - elsif window.glass_layers == HPXML::WindowLayersTriplePane + when HPXML::WindowLayersTriplePane n_panes = 3 - elsif window.glass_layers == HPXML::WindowLayersGlassBlock + when HPXML::WindowLayersGlassBlock return [0.6, 0.6] # From https://www.federalregister.gov/documents/2016/06/17/2016-13547/energy-conservation-standards-for-manufactured-housing end - if [HPXML::WindowFrameTypeAluminum, - HPXML::WindowFrameTypeMetal].include? window.frame_type + case window.frame_type + when HPXML::WindowFrameTypeAluminum, HPXML::WindowFrameTypeMetal is_metal_frame = true - elsif [HPXML::WindowFrameTypeWood, - HPXML::WindowFrameTypeVinyl, - HPXML::WindowFrameTypeFiberglass].include? window.frame_type + when HPXML::WindowFrameTypeWood, HPXML::WindowFrameTypeVinyl, HPXML::WindowFrameTypeFiberglass is_metal_frame = false else fail "Unexpected #{type.downcase} frame type." end - if [HPXML::WindowGlassTypeClear, - HPXML::WindowGlassTypeReflective].include? window.glass_type + case window.glass_type + when HPXML::WindowGlassTypeClear, HPXML::WindowGlassTypeReflective glass_type = 'clear' - elsif [HPXML::WindowGlassTypeTinted, - HPXML::WindowGlassTypeTintedReflective].include? window.glass_type + when HPXML::WindowGlassTypeTinted, HPXML::WindowGlassTypeTintedReflective glass_type = 'tinted' - elsif [HPXML::WindowGlassTypeLowE, - HPXML::WindowGlassTypeLowEHighSolarGain].include? window.glass_type + when HPXML::WindowGlassTypeLowE, HPXML::WindowGlassTypeLowEHighSolarGain glass_type = 'low_e_insulating' - elsif [HPXML::WindowGlassTypeLowELowSolarGain].include? window.glass_type + when HPXML::WindowGlassTypeLowELowSolarGain glass_type = 'low_e_solar_control' else fail "Unexpected #{type.downcase} glass type." @@ -5233,16 +5262,19 @@ def self.get_window_ufactor_shgc(window) if window.glass_layers == HPXML::WindowLayersSinglePane gas_fill = 'none' - elsif [HPXML::WindowGasAir].include? window.gas_fill - gas_fill = 'air' - elsif [HPXML::WindowGasArgon, + else + case window.gas_fill + when HPXML::WindowGasAir + gas_fill = 'air' + when HPXML::WindowGasArgon, HPXML::WindowGasKrypton, HPXML::WindowGasXenon, HPXML::WindowGasNitrogen, - HPXML::WindowGasOther].include? window.gas_fill - gas_fill = 'gas' - else - fail "Unexpected #{type.downcase} gas type." + HPXML::WindowGasOther + gas_fill = 'gas' + else + fail "Unexpected #{type.downcase} gas type." + end end # Lookup values @@ -5300,8 +5332,9 @@ def self.get_window_ufactor_shgc(window) # @param seer [Double] Cooling efficiency # @return [String] Compressor type (HPXML::HVACCompressorTypeXXX) def self.get_hvac_compressor_type(hvac_type, seer) - if [HPXML::HVACTypeCentralAirConditioner, - HPXML::HVACTypeHeatPumpAirToAir].include? hvac_type + case hvac_type + when HPXML::HVACTypeCentralAirConditioner, + HPXML::HVACTypeHeatPumpAirToAir if seer <= 15 return HPXML::HVACCompressorTypeSingleStage elsif seer <= 21 @@ -5309,13 +5342,13 @@ def self.get_hvac_compressor_type(hvac_type, seer) elsif seer > 21 return HPXML::HVACCompressorTypeVariableSpeed end - elsif [HPXML::HVACTypeMiniSplitAirConditioner, - HPXML::HVACTypeHeatPumpMiniSplit].include? hvac_type + when HPXML::HVACTypeMiniSplitAirConditioner, + HPXML::HVACTypeHeatPumpMiniSplit return HPXML::HVACCompressorTypeVariableSpeed - elsif [HPXML::HVACTypePTAC, - HPXML::HVACTypeHeatPumpPTHP, - HPXML::HVACTypeHeatPumpRoom, - HPXML::HVACTypeRoomAirConditioner].include? hvac_type + when HPXML::HVACTypePTAC, + HPXML::HVACTypeHeatPumpPTHP, + HPXML::HVACTypeHeatPumpRoom, + HPXML::HVACTypeRoomAirConditioner return HPXML::HVACCompressorTypeSingleStage end return @@ -5323,18 +5356,20 @@ def self.get_hvac_compressor_type(hvac_type, seer) # Gets the default fan power for a ceiling fan. # + # Source: ANSI/RESNET/ICC 301 + # # @return [Double] Fan power (W) def self.get_ceiling_fan_power() - # Per ANSI/RESNET/ICC 301 return 42.6 end # Gets the default quantity of ceiling fans. # + # Source: ANSI/RESNET/ICC 301 + # # @param nbeds [Integer] Number of bedrooms in the dwelling unit # @return [Integer] Number of ceiling fans def self.get_ceiling_fan_quantity(nbeds) - # Per ANSI/RESNET/ICC 301 return nbeds + 1 end @@ -5474,8 +5509,9 @@ def self.get_boiler_eae(heating_system) end end - # Gets the default interior/garage/exterior lighting fractions per ANSI/RESNET/ICC 301. - # Used by OS-ERI, OS-HEScore, etc. + # Gets the default interior/garage/exterior lighting fractions. Used by OS-ERI, OS-HEScore, etc. + # + # Source: ANSI/RESNET/ICC 301 # # @return [Hash] Map of [HPXML::LocationXXX, HPXML::LightingTypeXXX] => lighting fraction def self.get_lighting_fractions() @@ -5492,13 +5528,14 @@ def self.get_lighting_fractions() return ltg_fracs end - # Gets the default heating setpoints per ANSI/RESNET/ICC 301. + # Gets the default heating setpoints. + # + # Source: ANSI/RESNET/ICC 301 # # @param control_type [String] Thermostat control type (HPXML::HVACControlTypeXXX) # @param eri_version [String] Version of the ANSI/RESNET/ICC 301 Standard to use for equations/assumptions # @return [Array] 24 hourly comma-separated weekday and weekend setpoints def self.get_heating_setpoint(control_type, eri_version) - # Per ANSI/RESNET/ICC 301 htg_wd_setpoints = '68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68' htg_we_setpoints = '68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68' if control_type == HPXML::HVACControlTypeProgrammable @@ -5515,13 +5552,14 @@ def self.get_heating_setpoint(control_type, eri_version) return htg_wd_setpoints, htg_we_setpoints end - # Gets the default cooling setpoints per ANSI/RESNET/ICC 301. + # Gets the default cooling setpoints. + # + # Source: ANSI/RESNET/ICC 301 # # @param control_type [String] Thermostat control type (HPXML::HVACControlTypeXXX) # @param eri_version [String] Version of the ANSI/RESNET/ICC 301 Standard to use for equations/assumptions # @return [Array] 24 hourly comma-separated weekday and weekend setpoints def self.get_cooling_setpoint(control_type, eri_version) - # Per ANSI/RESNET/ICC 301 clg_wd_setpoints = '78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78' clg_we_setpoints = '78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78' if control_type == HPXML::HVACControlTypeProgrammable @@ -5545,24 +5583,26 @@ def self.get_cooling_setpoint(control_type, eri_version) # @return [Array] Temperature (F), heating capacity retention at the temperature (frac) def self.get_heating_capacity_retention(compressor_type, hspf = nil) retention_temp = 5.0 - if [HPXML::HVACCompressorTypeSingleStage, HPXML::HVACCompressorTypeTwoStage].include? compressor_type + case compressor_type + when HPXML::HVACCompressorTypeSingleStage, HPXML::HVACCompressorTypeTwoStage retention_fraction = 0.425 - elsif [HPXML::HVACCompressorTypeVariableSpeed].include? compressor_type + when HPXML::HVACCompressorTypeVariableSpeed # Default maximum capacity maintenance based on NEEP data for all var speed heat pump types, if not provided retention_fraction = (0.0461 * hspf + 0.1594).round(4) end return retention_temp, retention_fraction end - # Gets a 12-element array of 1s and 0s that reflects months for which the ceiling fan operates - # (i.e., when the average drybulb temperature is greater than 63F, per ANSI/RESNET/ICC 301). + # Gets the monthly ceiling fan operation schedule. + # + # Source: ANSI/RESNET/ICC 301 # # @param weather [WeatherFile] Weather object containing EPW information # @return [Array] monthly array of 1s and 0s def self.get_ceiling_fan_months(weather) months = [0] * 12 weather.data.MonthlyAvgDrybulbs.each_with_index do |val, m| - next unless val > 63.0 # F + next unless val > 63.0 # Ceiling fan operates when average drybulb temperature is greater than 63F months[m] = 1 end @@ -5628,21 +5668,21 @@ def self.get_occupancy_values() # and sensible/latent fractions. # # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) - # @param num_occ [Double] Number of occupants in the dwelling unit - # @param unit_type [String] HPXML::ResidentialTypeXXX type of dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @return [Array] Plug loads annual use (kWh), sensible/latent fractions - def self.get_residual_mels_values(cfa, num_occ = nil, unit_type = nil) - if num_occ.nil? # Asset calculation + def self.get_residual_mels_values(cfa, n_occ = nil, unit_type = nil) + if n_occ.nil? # Asset calculation # ANSI/RESNET/ICC 301 annual_kwh = 0.91 * cfa else # Operational calculation # RECS 2020 if unit_type == HPXML::ResidentialTypeSFD - annual_kwh = 786.9 + 241.8 * num_occ + 0.33 * cfa + annual_kwh = 786.9 + 241.8 * n_occ + 0.33 * cfa elsif unit_type == HPXML::ResidentialTypeSFA - annual_kwh = 654.9 + 206.5 * num_occ + 0.21 * cfa + annual_kwh = 654.9 + 206.5 * n_occ + 0.21 * cfa elsif unit_type == HPXML::ResidentialTypeApartment - annual_kwh = 706.6 + 149.3 * num_occ + 0.10 * cfa + annual_kwh = 706.6 + 149.3 * n_occ + 0.10 * cfa elsif unit_type == HPXML::ResidentialTypeManufactured annual_kwh = 1795.1 # No good relationship found in RECS, so just using a constant value end @@ -5657,11 +5697,11 @@ def self.get_residual_mels_values(cfa, num_occ = nil, unit_type = nil) # # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) # @param nbeds [Integer] Number of bedrooms in the dwelling unit - # @param num_occ [Double] Number of occupants in the dwelling unit - # @param unit_type [String] HPXML::ResidentialTypeXXX type of dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @return [Array] Television annual use (kWh), sensible/latent fractions - def self.get_televisions_values(cfa, nbeds, num_occ = nil, unit_type = nil) - if num_occ.nil? # Asset calculation + def self.get_televisions_values(cfa, nbeds, n_occ = nil, unit_type = nil) + if n_occ.nil? # Asset calculation # ANSI/RESNET/ICC 301 annual_kwh = 413.0 + 69.0 * nbeds else # Operational calculation @@ -5671,14 +5711,15 @@ def self.get_televisions_values(cfa, nbeds, num_occ = nil, unit_type = nil) # - SFA: 13.3 + 251.3 * num_tv # - MF: 11.4 + 250.7 * num_tv # - MH: 12.6 + 287.5 * num_tv - if unit_type == HPXML::ResidentialTypeSFD - annual_kwh = 334.0 + 92.2 * num_occ + 0.06 * cfa - elsif unit_type == HPXML::ResidentialTypeSFA - annual_kwh = 283.9 + 80.1 * num_occ + 0.07 * cfa - elsif unit_type == HPXML::ResidentialTypeApartment - annual_kwh = 190.3 + 81.0 * num_occ + 0.11 * cfa - elsif unit_type == HPXML::ResidentialTypeManufactured - annual_kwh = 99.9 + 129.6 * num_occ + 0.21 * cfa + case unit_type + when HPXML::ResidentialTypeSFD + annual_kwh = 334.0 + 92.2 * n_occ + 0.06 * cfa + when HPXML::ResidentialTypeSFA + annual_kwh = 283.9 + 80.1 * n_occ + 0.07 * cfa + when HPXML::ResidentialTypeApartment + annual_kwh = 190.3 + 81.0 * n_occ + 0.11 * cfa + when HPXML::ResidentialTypeManufactured + annual_kwh = 99.9 + 129.6 * n_occ + 0.21 * cfa end end frac_lost = 0.0 @@ -5691,29 +5732,52 @@ def self.get_televisions_values(cfa, nbeds, num_occ = nil, unit_type = nil) # # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @return [Double] Annual energy use (kWh/yr) - def self.get_pool_pump_annual_energy(cfa, nbeds) - return 158.6 / 0.070 * (0.5 + 0.25 * nbeds / 3.0 + 0.25 * cfa / 1920.0) + def self.get_pool_pump_annual_energy(cfa, nbeds, n_occ, unit_type) + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return 0.0 + end + + nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type) + + return 158.6 / 0.070 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) end # Gets the default pool heater annual energy use. # # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @param type [String] Type of heater (HPXML::HeaterTypeXXX) # @return [Array] Energy units (HPXML::UnitsXXX), annual energy use (kWh/yr or therm/yr) - def self.get_pool_heater_annual_energy(cfa, nbeds, type) + def self.get_pool_heater_annual_energy(cfa, nbeds, n_occ, unit_type, type) + nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type) + load_units = nil load_value = nil if [HPXML::HeaterTypeElectricResistance, HPXML::HeaterTypeHeatPump].include? type load_units = HPXML::UnitsKwhPerYear - load_value = 8.3 / 0.004 * (0.5 + 0.25 * nbeds / 3.0 + 0.25 * cfa / 1920.0) # kWh/yr + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return load_type, 0.0 + end + + load_value = 8.3 / 0.004 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) # kWh/yr if type == HPXML::HeaterTypeHeatPump load_value /= 5.0 # Assume seasonal COP of 5.0 per https://www.energy.gov/energysaver/heat-pump-swimming-pool-heaters end elsif type == HPXML::HeaterTypeGas load_units = HPXML::UnitsThermPerYear - load_value = 3.0 / 0.014 * (0.5 + 0.25 * nbeds / 3.0 + 0.25 * cfa / 1920.0) # therm/yr + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return load_type, 0.0 + end + + load_value = 3.0 / 0.014 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) # therm/yr end return load_units, load_value end @@ -5722,29 +5786,52 @@ def self.get_pool_heater_annual_energy(cfa, nbeds, type) # # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @return [Double] Annual energy use (kWh/yr) - def self.get_permanent_spa_pump_annual_energy(cfa, nbeds) - return 59.5 / 0.059 * (0.5 + 0.25 * nbeds / 3.0 + 0.25 * cfa / 1920.0) # kWh/yr + def self.get_permanent_spa_pump_annual_energy(cfa, nbeds, n_occ, unit_type) + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return 0.0 + end + + nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type) + + return 59.5 / 0.059 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) # kWh/yr end # Gets the default permanent spa heater annual energy use. # # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @param type [String] Type of heater (HPXML::HeaterTypeXXX) # @return [Array] Energy units (HPXML::UnitsXXX), annual energy use (kWh/yr or therm/yr) - def self.get_permanent_spa_heater_annual_energy(cfa, nbeds, type) + def self.get_permanent_spa_heater_annual_energy(cfa, nbeds, n_occ, unit_type, type) + nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type) + load_units = nil load_value = nil if [HPXML::HeaterTypeElectricResistance, HPXML::HeaterTypeHeatPump].include? type load_units = HPXML::UnitsKwhPerYear - load_value = 49.0 / 0.048 * (0.5 + 0.25 * nbeds / 3.0 + 0.25 * cfa / 1920.0) # kWh/yr + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return load_type, 0.0 + end + + load_value = 49.0 / 0.048 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) # kWh/yr if type == HPXML::HeaterTypeHeatPump load_value /= 5.0 # Assume seasonal COP of 5.0 per https://www.energy.gov/energysaver/heat-pump-swimming-pool-heaters end elsif type == HPXML::HeaterTypeGas load_units = HPXML::UnitsThermPerYear - load_value = 0.87 / 0.011 * (0.5 + 0.25 * nbeds / 3.0 + 0.25 * cfa / 1920.0) # therm/yr + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return load_type, 0.0 + end + + load_value = 0.87 / 0.011 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) # therm/yr end return load_units, load_value end @@ -5764,44 +5851,89 @@ def self.get_electric_vehicle_charging_annual_energy() # # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @return [Double] Annual energy use (kWh/yr) - def self.get_detault_well_pump_annual_energy(cfa, nbeds) - return 50.8 / 0.127 * (0.5 + 0.25 * nbeds / 3.0 + 0.25 * cfa / 1920.0) + def self.get_detault_well_pump_annual_energy(cfa, nbeds, n_occ, unit_type) + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return 0.0 + end + + nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type) + + return 50.8 / 0.127 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) end # Gets the default gas grill annual energy use. # # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @return [Double] Annual energy use (therm/yr) - def self.get_gas_grill_annual_energy(cfa, nbeds) - return 0.87 / 0.029 * (0.5 + 0.25 * nbeds / 3.0 + 0.25 * cfa / 1920.0) + def self.get_gas_grill_annual_energy(cfa, nbeds, n_occ, unit_type) + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return 0.0 + end + + nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type) + + return 0.87 / 0.029 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) end # Gets the default gas lighting annual energy use. # # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @return [Double] Annual energy use (therm/yr) - def self.get_detault_gas_lighting_annual_energy(cfa, nbeds) - return 0.22 / 0.012 * (0.5 + 0.25 * nbeds / 3.0 + 0.25 * cfa / 1920.0) + def self.get_detault_gas_lighting_annual_energy(cfa, nbeds, n_occ, unit_type) + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return 0.0 + end + + nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type) + + return 0.22 / 0.012 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) end # Gets the default gas fireplace annual energy use. # # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @return [Double] Annual energy use (therm/yr) - def self.get_gas_fireplace_annual_energy(cfa, nbeds) - return 1.95 / 0.032 * (0.5 + 0.25 * nbeds / 3.0 + 0.25 * cfa / 1920.0) + def self.get_gas_fireplace_annual_energy(cfa, nbeds, n_occ, unit_type) + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return 0.0 + end + + nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type) + + return 1.95 / 0.032 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) end # Gets the default values associated with general water use internal gains. # - # @param nbeds_eq [Integer] Number of bedrooms (or equivalent bedrooms, as adjusted by the number of occupants) in the dwelling unit + # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @param general_water_use_usage_multiplier [Double] Usage multiplier on internal gains # @return [Array] Sensible/latent internal gains (Btu/yr) - def self.get_water_use_internal_gains(nbeds_eq, general_water_use_usage_multiplier = 1.0) + def self.get_water_use_internal_gains(nbeds, n_occ, unit_type, general_water_use_usage_multiplier = 1.0) + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out internal gains + return 0.0, 0.0 + end + + nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type) + # ANSI/RESNET/ICC 301 - Table 4.2.2(3). Internal Gains for Reference Homes sens_gains = (-1227.0 - 409.0 * nbeds_eq) * general_water_use_usage_multiplier # Btu/day lat_gains = (1245.0 + 415.0 * nbeds_eq) * general_water_use_usage_multiplier # Btu/day diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/energyplus.rb b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/energyplus.rb index 9b588d06ff..c8d5e79302 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/energyplus.rb +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/energyplus.rb @@ -59,28 +59,25 @@ def self.fuel_type(hpxml_fuel) # Name of fuel used as inputs to E+ objects if hpxml_fuel.nil? return FuelTypeNone - elsif [HPXML::FuelTypeElectricity].include? hpxml_fuel + end + + case hpxml_fuel + when HPXML::FuelTypeElectricity return FuelTypeElectricity - elsif [HPXML::FuelTypeNaturalGas].include? hpxml_fuel + when HPXML::FuelTypeNaturalGas return FuelTypeNaturalGas - elsif [HPXML::FuelTypeOil, - HPXML::FuelTypeOil1, - HPXML::FuelTypeOil2, - HPXML::FuelTypeOil4, - HPXML::FuelTypeOil5or6, - HPXML::FuelTypeDiesel, - HPXML::FuelTypeKerosene].include? hpxml_fuel + when HPXML::FuelTypeOil, HPXML::FuelTypeOil1, HPXML::FuelTypeOil2, + HPXML::FuelTypeOil4, HPXML::FuelTypeOil5or6, HPXML::FuelTypeDiesel, + HPXML::FuelTypeKerosene return FuelTypeOil - elsif [HPXML::FuelTypePropane].include? hpxml_fuel + when HPXML::FuelTypePropane return FuelTypePropane - elsif [HPXML::FuelTypeWoodCord].include? hpxml_fuel + when HPXML::FuelTypeWoodCord return FuelTypeWoodCord - elsif [HPXML::FuelTypeWoodPellets].include? hpxml_fuel + when HPXML::FuelTypeWoodPellets return FuelTypeWoodPellets - elsif [HPXML::FuelTypeCoal, - HPXML::FuelTypeCoalAnthracite, - HPXML::FuelTypeCoalBituminous, - HPXML::FuelTypeCoke].include? hpxml_fuel + when HPXML::FuelTypeCoal, HPXML::FuelTypeCoalAnthracite, + HPXML::FuelTypeCoalBituminous, HPXML::FuelTypeCoke return FuelTypeCoal else fail "Unexpected HPXML fuel '#{hpxml_fuel}'." diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/geometry.rb b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/geometry.rb index 36965be122..cc284bbddf 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/geometry.rb +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/geometry.rb @@ -1124,7 +1124,7 @@ def self.get_surface_z_values(surfaceArray:) # @param nbeds [Integer] Number of bedrooms in the dwelling unit # @return [Double] Number of occupants in the dwelling unit def self.get_occupancy_default_num(nbeds:) - return Float(nbeds) # Per ANSI 301 for an asset calculation + return Float(nbeds) # Per ANSI/RESNET/ICC 301 for an asset calculation end # Creates a space and zone based on contents of spaces and value of location. @@ -1325,7 +1325,6 @@ def self.create_floor_vertices(length, width, z_origin, default_azimuths) end # Set calculated zone volumes for all HPXML locations on OpenStudio Thermal Zone and Space objects. - # TODO why? for reporting? # # @param spaces [Hash] Map of HPXML locations => OpenStudio Space objects # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit @@ -1640,49 +1639,50 @@ def self.calculate_zone_volume(hpxml_bldg, location) # @param location [String] the general HPXML location # @return [Hash] Map of minimum temperature, indoor/outdoor/ground weights, duct regain factor def self.get_temperature_scheduled_space_values(location) - if location == HPXML::LocationOtherHeatedSpace + case location + when HPXML::LocationOtherHeatedSpace # Average of indoor/outdoor temperatures with minimum of heating setpoint return { temp_min: 68, indoor_weight: 0.5, outdoor_weight: 0.5, ground_weight: 0.0, f_regain: 0.0 } - elsif location == HPXML::LocationOtherMultifamilyBufferSpace + when HPXML::LocationOtherMultifamilyBufferSpace # Average of indoor/outdoor temperatures with minimum of 50 F return { temp_min: 50, indoor_weight: 0.5, outdoor_weight: 0.5, ground_weight: 0.0, f_regain: 0.0 } - elsif location == HPXML::LocationOtherNonFreezingSpace + when HPXML::LocationOtherNonFreezingSpace # Floating with outdoor air temperature with minimum of 40 F return { temp_min: 40, indoor_weight: 0.0, outdoor_weight: 1.0, ground_weight: 0.0, f_regain: 0.0 } - elsif location == HPXML::LocationOtherHousingUnit + when HPXML::LocationOtherHousingUnit # Indoor air temperature return { temp_min: nil, indoor_weight: 1.0, outdoor_weight: 0.0, ground_weight: 0.0, f_regain: 0.0 } - elsif location == HPXML::LocationExteriorWall + when HPXML::LocationExteriorWall # Average of indoor/outdoor temperatures return { temp_min: nil, indoor_weight: 0.5, outdoor_weight: 0.5, ground_weight: 0.0, f_regain: 0.5 } # From LBNL's "Technical Background for default values used for Forced Air Systems in Proposed ASHRAE Standard 152P" - elsif location == HPXML::LocationUnderSlab + when HPXML::LocationUnderSlab # Ground temperature return { temp_min: nil, indoor_weight: 0.0, outdoor_weight: 0.0, ground_weight: 1.0, f_regain: 0.83 } # From LBNL's "Technical Background for default values used for Forced Air Systems in Proposed ASHRAE Standard 152P" - elsif location == HPXML::LocationManufacturedHomeBelly + when HPXML::LocationManufacturedHomeBelly # From LBNL's "Technical Background for default values used for Forced Air Systems in Proposed ASHRAE Standard 152P" # 3.5 Manufactured House Belly Pan Temperatures # FUTURE: Consider modeling the belly as a separate thermal zone so that we dynamically calculate temperatures. diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hotwater_appliances.rb b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hotwater_appliances.rb index 6a6182a223..36dbfcb758 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hotwater_appliances.rb +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hotwater_appliances.rb @@ -21,8 +21,8 @@ def self.apply(runner, model, weather, spaces, hpxml_bldg, hpxml_header, schedul fixtures_usage_multiplier = hpxml_bldg.water_heating.water_fixtures_usage_multiplier conditioned_space = spaces[HPXML::LocationConditionedSpace] nbeds = hpxml_bldg.building_construction.number_of_bedrooms - nbeds_eq = hpxml_bldg.building_construction.additional_properties.equivalent_number_of_bedrooms n_occ = hpxml_bldg.building_occupancy.number_of_residents + unit_type = hpxml_bldg.building_construction.residential_facility_type eri_version = hpxml_header.eri_calculation_version unit_multiplier = hpxml_bldg.building_construction.number_of_units @@ -56,7 +56,7 @@ def self.apply(runner, model, weather, spaces, hpxml_bldg, hpxml_header, schedul # Clothes washer energy if not clothes_washer.nil? cw_space = Geometry.get_space_from_location(clothes_washer.location, spaces) - cw_annual_kwh, cw_frac_sens, cw_frac_lat, cw_gpd = calc_clothes_washer_energy_gpd(runner, eri_version, nbeds, clothes_washer, cw_space.nil?, n_occ) + cw_annual_kwh, cw_frac_sens, cw_frac_lat, cw_gpd = calc_clothes_washer_energy_gpd(runner, eri_version, nbeds, n_occ, clothes_washer, cw_space.nil?) # Create schedule cw_power_schedule = nil @@ -98,7 +98,7 @@ def self.apply(runner, model, weather, spaces, hpxml_bldg, hpxml_header, schedul # Clothes dryer energy if not clothes_dryer.nil? cd_space = Geometry.get_space_from_location(clothes_dryer.location, spaces) - cd_annual_kwh, cd_annual_therm, cd_frac_sens, cd_frac_lat = calc_clothes_dryer_energy(runner, eri_version, nbeds, clothes_dryer, clothes_washer, cd_space.nil?, n_occ) + cd_annual_kwh, cd_annual_therm, cd_frac_sens, cd_frac_lat = calc_clothes_dryer_energy(runner, eri_version, nbeds, n_occ, clothes_dryer, clothes_washer, cd_space.nil?) # Create schedule cd_schedule = nil @@ -154,7 +154,7 @@ def self.apply(runner, model, weather, spaces, hpxml_bldg, hpxml_header, schedul # Dishwasher energy if not dishwasher.nil? dw_space = Geometry.get_space_from_location(dishwasher.location, spaces) - dw_annual_kwh, dw_frac_sens, dw_frac_lat, dw_gpd = calc_dishwasher_energy_gpd(runner, eri_version, nbeds, dishwasher, dw_space.nil?, n_occ) + dw_annual_kwh, dw_frac_sens, dw_frac_lat, dw_gpd = calc_dishwasher_energy_gpd(runner, eri_version, nbeds, n_occ, dishwasher, dw_space.nil?) # Create schedule dw_power_schedule = nil @@ -300,7 +300,7 @@ def self.apply(runner, model, weather, spaces, hpxml_bldg, hpxml_header, schedul # Cooking Range energy if not cooking_range.nil? cook_space = Geometry.get_space_from_location(cooking_range.location, spaces) - cook_annual_kwh, cook_annual_therm, cook_frac_sens, cook_frac_lat = calc_range_oven_energy(runner, nbeds_eq, cooking_range, oven, cook_space.nil?) + cook_annual_kwh, cook_annual_therm, cook_frac_sens, cook_frac_lat = calc_range_oven_energy(runner, nbeds, n_occ, unit_type, cooking_range, oven, cook_space.nil?) # Create schedule cook_schedule = nil @@ -390,7 +390,7 @@ def self.apply(runner, model, weather, spaces, hpxml_bldg, hpxml_header, schedul wh_setpoint = Defaults.get_water_heater_temperature(eri_version) if wh_setpoint.nil? # using detailed schedules avg_setpoint_temp += wh_setpoint * water_heating_system.fraction_dhw_load_served end - daily_wh_inlet_temperatures = calc_water_heater_daily_inlet_temperatures(weather, nbeds_eq, hot_water_distribution, frac_low_flow_fixtures) + daily_wh_inlet_temperatures = calc_water_heater_daily_inlet_temperatures(weather, nbeds, n_occ, unit_type, hot_water_distribution, frac_low_flow_fixtures) daily_wh_inlet_temperatures_c = daily_wh_inlet_temperatures.map { |t| UnitConversions.convert(t, 'F', 'C') } daily_mw_fractions = calc_mixed_water_daily_fractions(daily_wh_inlet_temperatures, avg_setpoint_temp, t_mix) @@ -589,12 +589,21 @@ def self.apply(runner, model, weather, spaces, hpxml_bldg, hpxml_header, schedul # Calculates cooking range/oven annual energy use. # # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings - # @param nbeds_eq [Integer] Number of bedrooms (or equivalent bedrooms, as adjusted by the number of occupants) in the dwelling unit + # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @param cooking_range [HPXML::CookingRange] The HPXML cooking range of interest # @param oven [HPXML::Oven] The HPXML oven of interest # @param is_outside [Boolean] Whether the appliance is located outside the dwelling unit # @return [Array] Annual electricity use (kWh), annual fuel use (therm), sensible/latent fractions - def self.calc_range_oven_energy(runner, nbeds_eq, cooking_range, oven, is_outside = false) + def self.calc_range_oven_energy(runner, nbeds, n_occ, unit_type, cooking_range, oven, is_outside = false) + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return 0.0, 0.0, 0.0, 0.0 + end + + nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type) + if cooking_range.is_induction burner_ef = 0.91 else @@ -644,11 +653,16 @@ def self.calc_range_oven_energy(runner, nbeds_eq, cooking_range, oven, is_outsid # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings # @param eri_version [String] Version of the ANSI/RESNET/ICC 301 Standard to use for equations/assumptions # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit # @param dishwasher [HPXML::Dishwasher] The HPXML dishwasher of interest # @param is_outside [Boolean] Whether the appliance is located outside the dwelling unit - # @param n_occ [Double] Number of occupants in the dwelling unit # @return [Array] Annual electricity use (kWh), sensible/latent fractions, hot water use (gal/day) - def self.calc_dishwasher_energy_gpd(runner, eri_version, nbeds, dishwasher, is_outside = false, n_occ = nil) + def self.calc_dishwasher_energy_gpd(runner, eri_version, nbeds, n_occ, dishwasher, is_outside = false) + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return 0.0, 0.0, 0.0, 0.0 + end + if Constants::ERIVersions.index(eri_version) >= Constants::ERIVersions.index('2019A') if dishwasher.rated_annual_kwh.nil? dishwasher.rated_annual_kwh = calc_dishwasher_annual_kwh_from_ef(dishwasher.energy_factor) @@ -700,21 +714,23 @@ def self.calc_dishwasher_energy_gpd(runner, eri_version, nbeds, dishwasher, is_o return annual_kwh, frac_sens, frac_lat, gpd end - # Converts dishwasher rated annual use (kWh) to energy factor (EF). + # Calculates dishwasher rated energy factor (EF) from annual use (kWh). + # + # Source: ANSI/RESNET/ICC 301 # # @param annual_kwh [Double] Rated annual kWh # @return [Double] Energy factor def self.calc_dishwasher_ef_from_annual_kwh(annual_kwh) - # Per ANSI/RESNET/ICC 301 return 215.0 / annual_kwh end - # Converts dishwasher energy factor (EF) to rated annual use (kWh). + # Calculates dishwasher annual use (kWh) from rated energy factor (EF). + # + # Source: ANSI/RESNET/ICC 301 # # @param ef [Double] Energy factor # @return [Double] Rated annual use (kWh) def self.calc_dishwasher_annual_kwh_from_ef(ef) - # Per ANSI/RESNET/ICC 301 return 215.0 / ef end @@ -723,12 +739,17 @@ def self.calc_dishwasher_annual_kwh_from_ef(ef) # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings # @param eri_version [String] Version of the ANSI/RESNET/ICC 301 Standard to use for equations/assumptions # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit # @param clothes_dryer [HPXML::ClothesDryer] The HPXML clothes dryer of interest # @param clothes_washer [HPXML::ClothesWasher] The related HPXML clothes washer, which affects dryer use # @param is_outside [Boolean] Whether the appliance is located outside the dwelling unit - # @param n_occ [Double] Number of occupants in the dwelling unit # @return [Array] Annual electricity use (kWh), annual fuel use (therm), sensible/latent fractions - def self.calc_clothes_dryer_energy(runner, eri_version, nbeds, clothes_dryer, clothes_washer, is_outside = false, n_occ = nil) + def self.calc_clothes_dryer_energy(runner, eri_version, nbeds, n_occ, clothes_dryer, clothes_washer, is_outside = false) + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return 0.0, 0.0, 0.0, 0.0 + end + if Constants::ERIVersions.index(eri_version) >= Constants::ERIVersions.index('2019A') if clothes_dryer.combined_energy_factor.nil? clothes_dryer.combined_energy_factor = calc_clothes_dryer_cef_from_ef(clothes_dryer.energy_factor) @@ -796,15 +817,23 @@ def self.calc_clothes_dryer_energy(runner, eri_version, nbeds, clothes_dryer, cl return annual_kwh, annual_therm, frac_sens, frac_lat end - # Converts clothes dryer energy factor (EF) to combined energy factor (CEF). + # Calculates clothes dryer combined energy factor (CEF) from energy factor (EF). + # + # Source: RESNET's Interpretation on Clothes Dryer CEF + # https://www.resnet.us/wp-content/uploads/No.-301-2014-10-Section-4.2.2.5.2.8-Clothes-Dryer-CEF-Rating.pdf + # Note that this is a regression based on products on the market, not a conversion. # # @param ef [Double] Energy factor # @return [Double] Combined energy factor def self.calc_clothes_dryer_cef_from_ef(ef) - return ef / 1.15 # Interpretation on ANSI/RESNET/ICC 301-2014 Clothes Dryer CEF + return ef / 1.15 end - # Converts clothes dryer combined energy factor (CEF) to energy factor (EF). + # Calculates clothes dryer energy factor (EF) from combined energy factor (CEF). + # + # Source: RESNET's Interpretation on Clothes Dryer CEF + # https://www.resnet.us/wp-content/uploads/No.-301-2014-10-Section-4.2.2.5.2.8-Clothes-Dryer-CEF-Rating.pdf + # Note that this is a regression based on products on the market, not a conversion. # # @param cef [Double] Combined energy factor # @return [Double] Energy factor @@ -817,11 +846,16 @@ def self.calc_clothes_dryer_ef_from_cef(cef) # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings # @param eri_version [String] Version of the ANSI/RESNET/ICC 301 Standard to use for equations/assumptions # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit # @param clothes_washer [HPXML::ClothesWasher] The HPXML clothes washer of interest # @param is_outside [Boolean] Whether the appliance is located outside the dwelling unit - # @param n_occ [Double] Number of occupants in the dwelling unit # @return [Array] Annual electricity use (kWh), sensible/latent fractions, hot water use (gal/day) - def self.calc_clothes_washer_energy_gpd(runner, eri_version, nbeds, clothes_washer, is_outside = false, n_occ = nil) + def self.calc_clothes_washer_energy_gpd(runner, eri_version, nbeds, n_occ, clothes_washer, is_outside = false) + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return 0.0, 0.0, 0.0, 0.0 + end + if Constants::ERIVersions.index(eri_version) >= Constants::ERIVersions.index('2019A') gas_h20 = 0.3914 # (gal/cyc) per (therm/y) elec_h20 = 0.0178 # (gal/cyc) per (kWh/y) @@ -869,20 +903,28 @@ def self.calc_clothes_washer_energy_gpd(runner, eri_version, nbeds, clothes_wash return annual_kwh, frac_sens, frac_lat, gpd end - # Converts clothes washer modified energy factor (MEF) to integrated modified energy factor (IMEF). + # Calculates clothes washer integrated modified energy factor (IMEF) from modified energy factor (MEF). + # + # Source: RESNET's Interpretation on Clothes Washer IMEF + # https://www.resnet.us/wp-content/uploads/No.-301-2014-08-sECTION-4.2.2.5.2.8-Clothes-Washers-Eq-4.2-6.pdf + # Note that this is a regression based on products on the market, not a conversion. # # @param mef [Double] Modified energy factor # @return [Double] Integrated modified energy factor def self.calc_clothes_washer_imef_from_mef(mef) - return (mef - 0.503) / 0.95 # Interpretation on ANSI/RESNET 301-2014 Clothes Washer IMEF + return (mef - 0.503) / 0.95 end - # Converts clothes washer integrated modified energy factor (IMEF) to modified energy factor (MEF). + # Calculates clothes washer modified energy factor (MEF) from integrated modified energy factor (IMEF). # - # @param mef [Double] Modified energy factor - # @return [Double] Integrated modified energy factor + # Source: RESNET's Interpretation on Clothes Washer IMEF + # https://www.resnet.us/wp-content/uploads/No.-301-2014-08-sECTION-4.2.2.5.2.8-Clothes-Washers-Eq-4.2-6.pdf + # Note that this is a regression based on products on the market, not a conversion. + # + # @param imef [Double] Integrated modified energy factor + # @return [Double] Modified energy factor def self.calc_clothes_washer_mef_from_imef(imef) - return 0.503 + 0.95 * imef # Interpretation on ANSI/RESNET 301-2014 Clothes Washer IMEF + return 0.503 + 0.95 * imef # Interpretation on ANSI/RESNET/ICC 301-2014 Clothes Washer IMEF end # Calculates refrigerator annual energy use. @@ -995,20 +1037,20 @@ def self.get_fridge_or_freezer_coefficients_schedule(model, col_name, obj_name, return schedule end - # Calculates Drain Water Heat Recovery (DWHR) factors per ANSI/RESNET/ICC 301. + # Calculates Drain Water Heat Recovery (DWHR) factors. + # + # Source: ANSI/RESNET/ICC 301 # # @param nbeds_eq [Integer] Number of bedrooms (or equivalent bedrooms, as adjusted by the number of occupants) in the dwelling unit # @param hot_water_distribution [HPXML::HotWaterDistribution] The HPXML hot water distribution system of interest # @param frac_low_flow_fixtures [Double] The fraction of fixtures considered low-flow # @return [Array] Effectiveness (frac), fraction of water impacted by DWHR, piping loss coefficient, location factor, fixture factor def self.get_dwhr_factors(nbeds_eq, hot_water_distribution, frac_low_flow_fixtures) - # ANSI/RESNET 301-2014 Addendum A-2015 - # Amendment on Domestic Hot Water (DHW) Systems - # Eq. 4.2-14 + # ANSI/RESNET/ICC 301-2022 Eq. 4.2-42 eff_adj = 1.0 + 0.082 * frac_low_flow_fixtures - iFrac = 0.56 + 0.015 * nbeds_eq - 0.0004 * nbeds_eq**2 # fraction of hot water use impacted by DWHR + i_frac = 0.56 + 0.015 * nbeds_eq - 0.0004 * nbeds_eq**2 # fraction of hot water use impacted by DWHR if hot_water_distribution.system_type == HPXML::DHWDistTypeRecirc pLength = hot_water_distribution.recirculation_branch_piping_length @@ -1019,30 +1061,38 @@ def self.get_dwhr_factors(nbeds_eq, hot_water_distribution, frac_low_flow_fixtur # Location factors for DWHR placement if hot_water_distribution.dwhr_equal_flow - locF = 1.000 + loc_f = 1.000 else - locF = 0.777 + loc_f = 0.777 end # Fixture Factor if hot_water_distribution.dwhr_facilities_connected == HPXML::DWHRFacilitiesConnectedAll - fixF = 1.0 + fix_f = 1.0 elsif hot_water_distribution.dwhr_facilities_connected == HPXML::DWHRFacilitiesConnectedOne - fixF = 0.5 + fix_f = 0.5 end - return eff_adj, iFrac, plc, locF, fixF + return eff_adj, i_frac, plc, loc_f, fix_f end # Calculates daily water heater inlet temperatures, which includes an adjustment if # there is a drain water heat recovery device. # # @param weather [WeatherFile] Weather object containing EPW information - # @param nbeds_eq [Integer] Number of bedrooms (or equivalent bedrooms, as adjusted by the number of occupants) in the dwelling unit + # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @param hot_water_distribution [HPXML::HotWaterDistribution] The HPXML hot water distribution system of interest # @param frac_low_flow_fixtures [Double] The fraction of fixtures considered low-flow # @return [Array] Daily water heater inlet temperatures (F) - def self.calc_water_heater_daily_inlet_temperatures(weather, nbeds_eq, hot_water_distribution, frac_low_flow_fixtures) + def self.calc_water_heater_daily_inlet_temperatures(weather, nbeds, n_occ, unit_type, hot_water_distribution, frac_low_flow_fixtures) + if n_occ == 0 + # Operational calculation w/ zero occupants + nbeds_eq = 0 + else + nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type) + end wh_temps_daily = weather.data.MainsDailyTemps.dup if (not hot_water_distribution.dwhr_efficiency.nil?) # Per ANSI/RESNET/ICC 301 @@ -1093,14 +1143,14 @@ def self.get_hwdist_recirc_pump_energy(hot_water_distribution, fixtures_usage_mu # Annual electricity consumption factor for hot water recirculation system pumps # Assume the fixtures_usage_multiplier only applies for Sensor/Manual control type. if hot_water_distribution.system_type == HPXML::DHWDistTypeRecirc - if [HPXML::DHWRecircControlTypeNone, - HPXML::DHWRecircControlTypeTimer].include? hot_water_distribution.recirculation_control_type + case hot_water_distribution.recirculation_control_type + when HPXML::DHWRecircControlTypeNone, HPXML::DHWRecircControlTypeTimer dist_pump_annual_kwh += (8.76 * hot_water_distribution.recirculation_pump_power) - elsif [HPXML::DHWRecircControlTypeTemperature].include? hot_water_distribution.recirculation_control_type + when HPXML::DHWRecircControlTypeTemperature dist_pump_annual_kwh += (1.46 * hot_water_distribution.recirculation_pump_power) - elsif [HPXML::DHWRecircControlTypeSensor].include? hot_water_distribution.recirculation_control_type + when HPXML::DHWRecircControlTypeSensor dist_pump_annual_kwh += (0.15 * hot_water_distribution.recirculation_pump_power * fixtures_usage_multiplier) - elsif [HPXML::DHWRecircControlTypeManual].include? hot_water_distribution.recirculation_control_type + when HPXML::DHWRecircControlTypeManual dist_pump_annual_kwh += (0.10 * hot_water_distribution.recirculation_pump_power * fixtures_usage_multiplier) else fail "Unexpected hot water distribution system recirculation type: '#{hot_water_distribution.recirculation_control_type}'." @@ -1115,12 +1165,10 @@ def self.get_hwdist_recirc_pump_energy(hot_water_distribution, fixtures_usage_mu # Assume the fixtures_usage_multiplier only applies for Sensor/Manual control type. if hot_water_distribution.has_shared_recirculation n_bdeq = hot_water_distribution.shared_recirculation_number_of_bedrooms_served - if [HPXML::DHWRecircControlTypeNone, - HPXML::DHWRecircControlTypeTimer, - HPXML::DHWRecircControlTypeTemperature].include? hot_water_distribution.shared_recirculation_control_type + case hot_water_distribution.shared_recirculation_control_type + when HPXML::DHWRecircControlTypeNone, HPXML::DHWRecircControlTypeTimer, HPXML::DHWRecircControlTypeTemperature op_hrs = 8760.0 - elsif [HPXML::DHWRecircControlTypeSensor, - HPXML::DHWRecircControlTypeManual].include? hot_water_distribution.shared_recirculation_control_type + when HPXML::DHWRecircControlTypeSensor, HPXML::DHWRecircControlTypeManual op_hrs = 730.0 * fixtures_usage_multiplier else fail "Unexpected hot water distribution system shared recirculation type: '#{hot_water_distribution.shared_recirculation_control_type}'." @@ -1153,10 +1201,8 @@ def self.get_fixtures_effectiveness(frac_low_flow_fixtures) # @return [Double] Mixed water use (gal/day) def self.get_fixtures_gpd(eri_version, nbeds, frac_low_flow_fixtures, daily_mw_fractions, fixtures_usage_multiplier = 1.0, n_occ = nil) if Constants::ERIVersions.index(eri_version) >= Constants::ERIVersions.index('2014A') - # ANSI/RESNET 301-2014 Addendum A-2015 - # Amendment on Domestic Hot Water (DHW) Systems if n_occ.nil? # Asset calculation - ref_f_gpd = 14.6 + 10.0 * nbeds # Eq. 4.2-2 (refFgpd) + ref_f_gpd = 14.6 + 10.0 * nbeds # ANSI/RESNET/ICC 301-2022 Eq. 4.2-29 (refFgpd) else # Operational calculation ref_f_gpd = [-4.84 + 18.6 * n_occ, 0.0].max # Eq. 14 from http://www.fsec.ucf.edu/en/publications/pdf/fsec-pf-464-15.pdf end @@ -1172,6 +1218,8 @@ def self.get_fixtures_gpd(eri_version, nbeds, frac_low_flow_fixtures, daily_mw_f # Calculates the equivalent daily mixed (not hot) water use associated with the distribution system. # + # Source: ANSI/RESNET/ICC 301 + # # @param eri_version [String] Version of the ANSI/RESNET/ICC 301 Standard to use for equations/assumptions # @param nbeds [Integer] Number of bedrooms in the dwelling unit # @param has_uncond_bsmnt [Boolean] Whether the dwelling unit has an unconditioned basement @@ -1189,33 +1237,37 @@ def self.get_dist_waste_gpd(eri_version, nbeds, has_uncond_bsmnt, has_cond_bsmnt return 0.0 end - # ANSI/RESNET 301-2014 Addendum A-2015 - # Amendment on Domestic Hot Water (DHW) Systems - # 4.2.2.5.2.11 Service Hot Water Use + # ANSI/RESNET/ICC 301-2022 Section 4.2.2.7.1.4 - # Table 4.2.2.5.2.11(2) Hot Water Distribution System Insulation Factors + # Table 4.2.2.7.2.11(2) Hot Water Distribution System Insulation Factors sys_factor = nil - if (hot_water_distribution.system_type == HPXML::DHWDistTypeRecirc) && (hot_water_distribution.pipe_r_value < 3.0) - sys_factor = 1.11 - elsif (hot_water_distribution.system_type == HPXML::DHWDistTypeRecirc) && (hot_water_distribution.pipe_r_value >= 3.0) - sys_factor = 1.0 - elsif (hot_water_distribution.system_type == HPXML::DHWDistTypeStandard) && (hot_water_distribution.pipe_r_value >= 3.0) - sys_factor = 0.90 - elsif (hot_water_distribution.system_type == HPXML::DHWDistTypeStandard) && (hot_water_distribution.pipe_r_value < 3.0) - sys_factor = 1.0 + case hot_water_distribution.system_type + when HPXML::DHWDistTypeRecirc + if hot_water_distribution.pipe_r_value < 3.0 + sys_factor = 1.11 + elsif hot_water_distribution.pipe_r_value >= 3.0 + sys_factor = 1.0 + end + when HPXML::DHWDistTypeStandard + if hot_water_distribution.pipe_r_value >= 3.0 + sys_factor = 0.90 + elsif hot_water_distribution.pipe_r_value < 3.0 + sys_factor = 1.0 + end end if n_occ.nil? # Asset calculation - ref_w_gpd = 9.8 * (nbeds**0.43) # Eq. 4.2-2 (refWgpd) + ref_w_gpd = 9.8 * (nbeds**0.43) # ANSI/RESNET/ICC 301-2022 Eq. 4.2-29 (refWgpd) else # Operational calculation ref_w_gpd = 7.16 * (n_occ**0.7) # Eq. 14 from http://www.fsec.ucf.edu/en/publications/pdf/fsec-pf-464-15.pdf end o_frac = 0.25 o_cd_eff = 0.0 - if hot_water_distribution.system_type == HPXML::DHWDistTypeRecirc + case hot_water_distribution.system_type + when HPXML::DHWDistTypeRecirc p_ratio = hot_water_distribution.recirculation_branch_piping_length / 10.0 - elsif hot_water_distribution.system_type == HPXML::DHWDistTypeStandard + when HPXML::DHWDistTypeStandard ref_pipe_l = Defaults.get_std_pipe_length(has_uncond_bsmnt, has_cond_bsmnt, cfa, ncfl) p_ratio = hot_water_distribution.standard_piping_length / ref_pipe_l end @@ -1224,9 +1276,10 @@ def self.get_dist_waste_gpd(eri_version, nbeds, has_uncond_bsmnt, has_cond_bsmnt s_w_gpd = (ref_w_gpd - ref_w_gpd * o_frac) * p_ratio * sys_factor # Eq. 4.2-13 # Table 4.2.2.5.2.11(3) Distribution system water use effectiveness - if hot_water_distribution.system_type == HPXML::DHWDistTypeRecirc + case hot_water_distribution.system_type + when HPXML::DHWDistTypeRecirc wd_eff = 0.1 - elsif hot_water_distribution.system_type == HPXML::DHWDistTypeStandard + when HPXML::DHWDistTypeStandard wd_eff = 1.0 end diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml.rb b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml.rb index aa0242e034..b062fa4ca1 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml.rb +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml.rb @@ -660,40 +660,62 @@ def set_unique_hpxml_ids(hpxml_doc, last_building_only = false) # Returns a hash with whether each fuel exists in the HPXML Building or Buildings # - # @param hpxml_doc [Oga::XML::Document] HPXML object as an XML document # @param building_id [String] If provided, only search the single HPXML Building with the given ID # @return [Hash] Map of HPXML::FuelTypeXXX => boolean - def has_fuels(hpxml_doc, building_id = nil) - has_fuels = {} - - fuel_element_names = ['HeatingSystemFuel', - 'CoolingSystemFuel', - 'HeatPumpFuel', - 'BackupSystemFuel', - 'FuelType', - 'IntegratedHeatingSystemFuel', - 'Heater/Type'] + def has_fuels(building_id = nil) + has_fuel = {} + has_fuel[HPXML::FuelTypeElectricity] = true HPXML::fossil_fuels.each do |fuel| - has_fuels[fuel] = false - fuel_element_names.each do |fuel_element_name| - if fuel_element_name == 'Heater/Type' && fuel == HPXML::FuelTypeNaturalGas - fuel_element_value = HPXML::HeaterTypeGas - else - fuel_element_value = fuel + has_fuel[fuel] = false + + buildings.each do |hpxml_bldg| + next if (not building_id.nil?) && (hpxml_bldg.building_id != building_id) + + # Check HVAC systems + hpxml_bldg.hvac_systems.each do |hvac_system| + if hvac_system.respond_to?(:heating_system_fuel) && hvac_system.heating_system_fuel == fuel + has_fuel[fuel] = true + end + if hvac_system.respond_to?(:cooling_system_fuel) && hvac_system.cooling_system_fuel == fuel + has_fuel[fuel] = true + end + if hvac_system.respond_to?(:heat_pump_fuel) && hvac_system.heat_pump_fuel == fuel + has_fuel[fuel] = true + end + if hvac_system.respond_to?(:backup_heating_fuel) && hvac_system.backup_heating_fuel == fuel + has_fuel[fuel] = true + end + if hvac_system.respond_to?(:integrated_heating_system_fuel) && hvac_system.integrated_heating_system_fuel == fuel + has_fuel[fuel] = true + end end - search_str = "/HPXML/Building[BuildingID/@id='#{building_id}']//#{fuel_element_name}[text() = '#{fuel_element_value}']" - if building_id.nil? - search_str = "/HPXML/Building//#{fuel_element_name}[text() = '#{fuel_element_value}']" + + # Check other appliances + (hpxml_bldg.water_heating_systems + + hpxml_bldg.generators + + hpxml_bldg.clothes_dryers + + hpxml_bldg.cooking_ranges + + hpxml_bldg.fuel_loads).each do |appliance| + if appliance.fuel_type == fuel + has_fuel[fuel] = true + end end - if XMLHelper.has_element(hpxml_doc, search_str) - has_fuels[fuel] = true - break + + # Check pool/spa heaters + if fuel == HPXML::FuelTypeNaturalGas + (hpxml_bldg.pools + hpxml_bldg.permanent_spas).each do |pool_or_spa| + if pool_or_spa.heater_type == HPXML::HeaterTypeGas + has_fuel[fuel] = true + end + end end + + break if has_fuel[fuel] end end - return has_fuels + return has_fuel end # Object to store additional properties on an HPXML object that are not intended @@ -1714,11 +1736,9 @@ def has_fuel_access # Returns a hash with whether each fuel exists in the HPXML Building. # - # @param hpxml_doc [Oga::XML::Document] HPXML object as an XML document # @return [Hash] Map of HPXML::FuelTypeXXX => boolean - def has_fuels(hpxml_doc) - # Returns a hash with whether each fuel exists in the HPXML Building - return @parent_object.has_fuels(hpxml_doc, @building_id) + def has_fuels() + return @parent_object.has_fuels(@building_id) end # Returns the predominant heating fuel type (weighted by fraction of @@ -1828,7 +1848,7 @@ def has_walkout_basement end # Calculates above-grade and below-grade thermal boundary wall areas. - # Used to calculate the window area in the ERI Reference Home per ANSI 301. + # Used to calculate the window area in the ERI Reference Home. # # Thermal boundary wall is any wall that separates conditioned space from # unconditioned space, outside, or soil. Above-grade thermal boundary @@ -1836,6 +1856,8 @@ def has_walkout_basement # Below-grade thermal boundary wall is any portion of a thermal boundary # wall in contact with soil. # + # Source: ANSI/RESNET/ICC 301 + # # @return [Array] Above-grade and below-grade thermal boundary wall areas (ft2) def thermal_boundary_wall_areas ag_wall_area = 0.0 @@ -1881,8 +1903,9 @@ def above_grade_conditioned_volume return ag_cond_vol end - # Calculates common wall area. - # Used to calculate the window area in the ERI Reference Home per ANSI 301. + # Calculates common wall area. Used to calculate the window area in the ERI Reference Home. + # + # Source: ANSI/RESNET/ICC 301 # # Common wall is the total wall area of walls adjacent to other unit's # conditioned space, not including foundation walls. @@ -1904,12 +1927,14 @@ def common_wall_area # Returns the total and exterior compartmentalization boundary area. # Used to convert between total infiltration and exterior infiltration for - # SFA/MF dwelling units per ANSI 301. + # SFA/MF dwelling units. + # + # Source: ANSI/RESNET/ICC 301 # # @return [Array] Total and exterior compartmentalization areas (ft2) def compartmentalization_boundary_areas total_area = 0.0 # Total surface area that bounds the Infiltration Volume - exterior_area = 0.0 # Same as above excluding surfaces attached to garage, other housing units, or other multifamily spaces (see 301-2019 Addendum B) + exterior_area = 0.0 # Same as above excluding surfaces attached to garage, other housing units, or other multifamily spaces # Determine which spaces are within infiltration volume spaces_within_infil_volume = HPXML::conditioned_locations_this_unit @@ -2699,11 +2724,9 @@ def check_for_errors # @param building [Oga::XML::Element] The current Building XML element # @return [nil] def to_doc(building) - return if nil? - climate_and_risk_zones = XMLHelper.create_elements_as_needed(building, ['BuildingDetails', 'ClimateandRiskZones']) - @climate_zone_ieccs.to_doc(climate_and_risk_zones) + return if nil? if not @weather_station_id.nil? weather_station = XMLHelper.add_element(climate_and_risk_zones, 'WeatherStation') @@ -3407,11 +3430,12 @@ def attached_floors def to_location return if @attic_type.nil? - if [AtticTypeCathedral, AtticTypeConditioned, AtticTypeFlatRoof, AtticTypeBelowApartment].include? @attic_type + case @attic_type + when AtticTypeCathedral, AtticTypeConditioned, AtticTypeFlatRoof, AtticTypeBelowApartment return LocationConditionedSpace - elsif [AtticTypeUnvented].include? @attic_type + when AtticTypeUnvented return LocationAtticUnvented - elsif [AtticTypeVented].include? @attic_type + when AtticTypeVented return LocationAtticVented else fail "Unexpected attic type: '#{@attic_type}'." @@ -3450,12 +3474,13 @@ def to_doc(building) XMLHelper.add_attribute(sys_id, 'id', @id) if not @attic_type.nil? attic_type_el = XMLHelper.add_element(attic, 'AtticType') - if [AtticTypeFlatRoof, AtticTypeCathedral, AtticTypeBelowApartment].include? @attic_type + case @attic_type + when AtticTypeFlatRoof, AtticTypeCathedral, AtticTypeBelowApartment XMLHelper.add_element(attic_type_el, @attic_type) - elsif [AtticTypeUnvented].include? @attic_type + when AtticTypeUnvented attic_type_attic = XMLHelper.add_element(attic_type_el, 'Attic') XMLHelper.add_element(attic_type_attic, 'Vented', false, :boolean) - elsif [AtticTypeVented].include? @attic_type + when AtticTypeVented attic_type_attic = XMLHelper.add_element(attic_type_el, 'Attic') XMLHelper.add_element(attic_type_attic, 'Vented', true, :boolean) if not @vented_attic_sla.nil? @@ -3467,7 +3492,7 @@ def to_doc(building) XMLHelper.add_element(ventilation_rate, 'UnitofMeasure', UnitsACHNatural, :string) XMLHelper.add_element(ventilation_rate, 'Value', @vented_attic_ach, :float) end - elsif [AtticTypeConditioned].include? @attic_type + when AtticTypeConditioned attic_type_attic = XMLHelper.add_element(attic_type_el, 'Attic') XMLHelper.add_element(attic_type_attic, 'Conditioned', true, :boolean) else @@ -3648,21 +3673,22 @@ def attached_rim_joists def to_location return if @foundation_type.nil? - if [FoundationTypeSlab, FoundationTypeAboveApartment].include? @foundation_type + case @foundation_type + when FoundationTypeSlab, FoundationTypeAboveApartment return LocationConditionedSpace - elsif [FoundationTypeAmbient].include? @foundation_type + when FoundationTypeAmbient return LocationOutside - elsif [FoundationTypeBasementConditioned].include? @foundation_type + when FoundationTypeBasementConditioned return LocationBasementConditioned - elsif [FoundationTypeBasementUnconditioned].include? @foundation_type + when FoundationTypeBasementUnconditioned return LocationBasementUnconditioned - elsif [FoundationTypeCrawlspaceUnvented].include? @foundation_type + when FoundationTypeCrawlspaceUnvented return LocationCrawlspaceUnvented - elsif [FoundationTypeCrawlspaceVented].include? @foundation_type + when FoundationTypeCrawlspaceVented return LocationCrawlspaceVented - elsif @foundation_type == FoundationTypeCrawlspaceConditioned + when FoundationTypeCrawlspaceConditioned return LocationCrawlspaceConditioned - elsif @foundation_type == FoundationTypeBellyAndWing + when FoundationTypeBellyAndWing return LocationManufacturedHomeUnderBelly else fail "Unexpected foundation type: '#{@foundation_type}'." @@ -3721,15 +3747,16 @@ def to_doc(building) XMLHelper.add_attribute(sys_id, 'id', @id) if not @foundation_type.nil? foundation_type_el = XMLHelper.add_element(foundation, 'FoundationType') - if [FoundationTypeSlab, FoundationTypeAmbient, FoundationTypeAboveApartment].include? @foundation_type + case @foundation_type + when FoundationTypeSlab, FoundationTypeAmbient, FoundationTypeAboveApartment XMLHelper.add_element(foundation_type_el, @foundation_type) - elsif [FoundationTypeBasementConditioned].include? @foundation_type + when FoundationTypeBasementConditioned basement = XMLHelper.add_element(foundation_type_el, 'Basement') XMLHelper.add_element(basement, 'Conditioned', true, :boolean) - elsif [FoundationTypeBasementUnconditioned].include? @foundation_type + when FoundationTypeBasementUnconditioned basement = XMLHelper.add_element(foundation_type_el, 'Basement') XMLHelper.add_element(basement, 'Conditioned', false, :boolean) - elsif [FoundationTypeCrawlspaceVented].include? @foundation_type + when FoundationTypeCrawlspaceVented crawlspace = XMLHelper.add_element(foundation_type_el, 'Crawlspace') XMLHelper.add_element(crawlspace, 'Vented', true, :boolean) if not @vented_crawlspace_sla.nil? @@ -3737,13 +3764,13 @@ def to_doc(building) XMLHelper.add_element(ventilation_rate, 'UnitofMeasure', UnitsSLA, :string) XMLHelper.add_element(ventilation_rate, 'Value', @vented_crawlspace_sla, :float, @vented_crawlspace_sla_isdefaulted) end - elsif [FoundationTypeCrawlspaceUnvented].include? @foundation_type + when FoundationTypeCrawlspaceUnvented crawlspace = XMLHelper.add_element(foundation_type_el, 'Crawlspace') XMLHelper.add_element(crawlspace, 'Vented', false, :boolean) - elsif @foundation_type == FoundationTypeCrawlspaceConditioned + when FoundationTypeCrawlspaceConditioned crawlspace = XMLHelper.add_element(foundation_type_el, 'Crawlspace') XMLHelper.add_element(crawlspace, 'Conditioned', true, :boolean) - elsif @foundation_type == FoundationTypeBellyAndWing + when FoundationTypeBellyAndWing belly_and_wing = XMLHelper.add_element(foundation_type_el, 'BellyAndWing') XMLHelper.add_element(belly_and_wing, 'SkirtPresent', @belly_wing_skirt_present, :boolean, @belly_wing_skirt_present_isdefaulted) unless @belly_wing_skirt_present.nil? else @@ -7723,11 +7750,12 @@ def to_doc(building) hvac_distribution = XMLHelper.add_element(hvac, 'HVACDistribution') sys_id = XMLHelper.add_element(hvac_distribution, 'SystemIdentifier') XMLHelper.add_attribute(sys_id, 'id', @id) - distribution_system_type_el = XMLHelper.add_element(hvac_distribution, 'DistributionSystemType') if [HVACDistributionTypeAir, HVACDistributionTypeHydronic].include? @distribution_system_type + distribution_system_type_el = XMLHelper.add_element(hvac_distribution, 'DistributionSystemType') XMLHelper.add_element(distribution_system_type_el, @distribution_system_type) XMLHelper.add_element(hvac_distribution, 'ConditionedFloorAreaServed', @conditioned_floor_area_served, :float) unless @conditioned_floor_area_served.nil? elsif [HVACDistributionTypeDSE].include? @distribution_system_type + distribution_system_type_el = XMLHelper.add_element(hvac_distribution, 'DistributionSystemType') XMLHelper.add_element(distribution_system_type_el, 'Other', @distribution_system_type, :string) XMLHelper.add_element(hvac_distribution, 'AnnualHeatingDistributionSystemEfficiency', @annual_heating_dse, :float) unless @annual_heating_dse.nil? XMLHelper.add_element(hvac_distribution, 'AnnualCoolingDistributionSystemEfficiency', @annual_cooling_dse, :float) unless @annual_cooling_dse.nil? diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schematron/EPvalidator.xml b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schematron/EPvalidator.xml index 0379fec462..f7db0334d9 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schematron/EPvalidator.xml +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schematron/EPvalidator.xml @@ -18,6 +18,7 @@ Expected 0 or more element(s) for xpath: extension/EmissionsScenarios/EmissionsScenario Expected 0 or more element(s) for xpath: extension/UtilityBillScenarios/UtilityBillScenario Expected 0 or more element(s) for xpath: extension/UnavailablePeriods/UnavailablePeriod + Expected 0 or 1 element(s) for xpath: extension/WholeSFAorMFBuildingSimulation extension/SchedulesFilePath has been replaced by /HPXML/Building/BuildingDetails/BuildingSummary/extension/SchedulesFilePath extension/HVACSizingControl has been replaced by /HPXML/Building/BuildingDetails/BuildingSummary/extension/HVACSizingControl diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac.rb b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac.rb index 6775d0a7be..6e91052f60 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac.rb +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac.rb @@ -10,7 +10,7 @@ module HVAC AirSourceCoolRatedIWB = 67.0 # degF, Rated indoor wetbulb for air-source systems, cooling CrankcaseHeaterTemp = 50.0 # degF - # TODO + # Adds any HVAC Systems to the OpenStudio model. # # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings # @param model [OpenStudio::Model::Model] OpenStudio Model object @@ -89,16 +89,12 @@ def self.apply_cooling_system(runner, model, weather, spaces, hpxml_bldg, hpxml_ end sys_id = cooling_system.id - if [HPXML::HVACTypeCentralAirConditioner, - HPXML::HVACTypeRoomAirConditioner, - HPXML::HVACTypeMiniSplitAirConditioner, - HPXML::HVACTypePTAC].include? cooling_system.cooling_system_type - + case cooling_system.cooling_system_type + when HPXML::HVACTypeCentralAirConditioner, HPXML::HVACTypeRoomAirConditioner, + HPXML::HVACTypeMiniSplitAirConditioner, HPXML::HVACTypePTAC airloop_map[sys_id] = apply_air_source_hvac_systems(model, runner, weather, cooling_system, heating_system, hvac_sequential_load_fracs, conditioned_zone, hvac_unavailable_periods, schedules_file, hpxml_bldg, hpxml_header) - - elsif [HPXML::HVACTypeEvaporativeCooler].include? cooling_system.cooling_system_type - + when HPXML::HVACTypeEvaporativeCooler airloop_map[sys_id] = apply_evaporative_cooler(model, cooling_system, hvac_sequential_load_fracs, conditioned_zone, hvac_unavailable_periods, hpxml_bldg.building_construction.number_of_units) end @@ -154,25 +150,16 @@ def self.apply_heating_system(runner, model, weather, spaces, hpxml_bldg, hpxml_ end sys_id = heating_system.id - if [HPXML::HVACTypeFurnace].include? heating_system.heating_system_type - + case heating_system.heating_system_type + when HPXML::HVACTypeFurnace airloop_map[sys_id] = apply_air_source_hvac_systems(model, runner, weather, nil, heating_system, hvac_sequential_load_fracs, conditioned_zone, hvac_unavailable_periods, schedules_file, hpxml_bldg, hpxml_header) - - elsif [HPXML::HVACTypeBoiler].include? heating_system.heating_system_type - + when HPXML::HVACTypeBoiler airloop_map[sys_id] = apply_boiler(model, runner, heating_system, hvac_sequential_load_fracs, conditioned_zone, hvac_unavailable_periods) - - elsif [HPXML::HVACTypeElectricResistance].include? heating_system.heating_system_type - + when HPXML::HVACTypeElectricResistance apply_electric_baseboard(model, heating_system, hvac_sequential_load_fracs, conditioned_zone, hvac_unavailable_periods) - - elsif [HPXML::HVACTypeStove, - HPXML::HVACTypeSpaceHeater, - HPXML::HVACTypeWallFurnace, - HPXML::HVACTypeFloorFurnace, - HPXML::HVACTypeFireplace].include? heating_system.heating_system_type - + when HPXML::HVACTypeStove, HPXML::HVACTypeSpaceHeater, HPXML::HVACTypeWallFurnace, + HPXML::HVACTypeFloorFurnace, HPXML::HVACTypeFireplace apply_unit_heater(model, heating_system, hvac_sequential_load_fracs, conditioned_zone, hvac_unavailable_periods) end @@ -223,24 +210,17 @@ def self.apply_heat_pump(runner, model, weather, spaces, hpxml_bldg, hpxml_heade hvac_remaining_load_fracs[:clg] -= heat_pump.fraction_cool_load_served sys_id = heat_pump.id - if [HPXML::HVACTypeHeatPumpWaterLoopToAir].include? heat_pump.heat_pump_type - + case heat_pump.heat_pump_type + when HPXML::HVACTypeHeatPumpWaterLoopToAir airloop_map[sys_id] = apply_water_loop_to_air_heat_pump(model, heat_pump, hvac_sequential_load_fracs, conditioned_zone, hvac_unavailable_periods) - - elsif [HPXML::HVACTypeHeatPumpAirToAir, - HPXML::HVACTypeHeatPumpMiniSplit, - HPXML::HVACTypeHeatPumpPTHP, - HPXML::HVACTypeHeatPumpRoom].include? heat_pump.heat_pump_type - + when HPXML::HVACTypeHeatPumpAirToAir, HPXML::HVACTypeHeatPumpMiniSplit, + HPXML::HVACTypeHeatPumpPTHP, HPXML::HVACTypeHeatPumpRoom airloop_map[sys_id] = apply_air_source_hvac_systems(model, runner, weather, heat_pump, heat_pump, hvac_sequential_load_fracs, conditioned_zone, hvac_unavailable_periods, schedules_file, hpxml_bldg, hpxml_header) - - elsif [HPXML::HVACTypeHeatPumpGroundToAir].include? heat_pump.heat_pump_type - + when HPXML::HVACTypeHeatPumpGroundToAir airloop_map[sys_id] = apply_ground_to_air_heat_pump(model, runner, weather, heat_pump, hvac_sequential_load_fracs, conditioned_zone, hpxml_bldg.site.ground_conductivity, hpxml_bldg.site.ground_diffusivity, hvac_unavailable_periods, hpxml_bldg.building_construction.number_of_units) - end next if heat_pump.backup_system.nil? @@ -291,21 +271,23 @@ def self.apply_air_source_hvac_systems(model, runner, weather, cooling_system, h if not cooling_system.nil? if cooling_system.is_a? HPXML::HeatPump is_heatpump = true - if cooling_system.heat_pump_type == HPXML::HVACTypeHeatPumpAirToAir + case cooling_system.heat_pump_type + when HPXML::HVACTypeHeatPumpAirToAir obj_name = Constants::ObjectTypeAirSourceHeatPump - elsif cooling_system.heat_pump_type == HPXML::HVACTypeHeatPumpMiniSplit + when HPXML::HVACTypeHeatPumpMiniSplit obj_name = Constants::ObjectTypeMiniSplitHeatPump - elsif cooling_system.heat_pump_type == HPXML::HVACTypeHeatPumpPTHP + when HPXML::HVACTypeHeatPumpPTHP obj_name = Constants::ObjectTypePTHP fan_watts_per_cfm = 0.0 - elsif cooling_system.heat_pump_type == HPXML::HVACTypeHeatPumpRoom + when HPXML::HVACTypeHeatPumpRoom obj_name = Constants::ObjectTypeRoomHP fan_watts_per_cfm = 0.0 else fail "Unexpected heat pump type: #{cooling_system.heat_pump_type}." end elsif cooling_system.is_a? HPXML::CoolingSystem - if cooling_system.cooling_system_type == HPXML::HVACTypeCentralAirConditioner + case cooling_system.cooling_system_type + when HPXML::HVACTypeCentralAirConditioner if heating_system.nil? obj_name = Constants::ObjectTypeCentralAirConditioner else @@ -315,14 +297,14 @@ def self.apply_air_source_hvac_systems(model, runner, weather, cooling_system, h fail "Fan powers for heating system '#{heating_system.id}' and cooling system '#{cooling_system.id}' are attached to a single distribution system and therefore must be the same." end end - elsif [HPXML::HVACTypeRoomAirConditioner, HPXML::HVACTypePTAC].include? cooling_system.cooling_system_type + when HPXML::HVACTypeRoomAirConditioner, HPXML::HVACTypePTAC fan_watts_per_cfm = 0.0 if cooling_system.cooling_system_type == HPXML::HVACTypeRoomAirConditioner obj_name = Constants::ObjectTypeRoomAC else obj_name = Constants::ObjectTypePTAC end - elsif cooling_system.cooling_system_type == HPXML::HVACTypeMiniSplitAirConditioner + when HPXML::HVACTypeMiniSplitAirConditioner obj_name = Constants::ObjectTypeMiniSplitAirConditioner else fail "Unexpected cooling system type: #{cooling_system.cooling_system_type}." @@ -681,20 +663,19 @@ def self.apply_ground_to_air_heat_pump(model, runner, weather, heat_pump, hvac_s xing.setAverageSoilSurfaceTemperature(ground_heat_exch_vert.groundTemperature.get) # Plant Loop - plant_loop = OpenStudio::Model::PlantLoop.new(model) - plant_loop.setName(obj_name + ' condenser loop') - plant_loop.setFluidType(hp_ap.fluid_type) - if hp_ap.fluid_type != EPlus::FluidWater - plant_loop.setGlycolConcentration((hp_ap.frac_glycol * 100).to_i) - end - plant_loop.setMaximumLoopTemperature(48.88889) - plant_loop.setMinimumLoopTemperature(UnitConversions.convert(hp_ap.design_hw, 'F', 'C')) - plant_loop.setMinimumLoopFlowRate(0) - plant_loop.setLoadDistributionScheme('SequentialLoad') + plant_loop = Model.add_plant_loop( + model, + name: "#{obj_name} condenser loop", + fluid_type: hp_ap.fluid_type, + glycol_concentration: (hp_ap.frac_glycol * 100).to_i, + min_temp: UnitConversions.convert(hp_ap.design_hw, 'F', 'C'), + max_temp: 48.88889, + max_flow_rate: UnitConversions.convert(geothermal_loop.loop_flow, 'gal/min', 'm^3/s') + ) + plant_loop.addSupplyBranchForComponent(ground_heat_exch_vert) plant_loop.addDemandBranchForComponent(htg_coil) plant_loop.addDemandBranchForComponent(clg_coil) - plant_loop.setMaximumLoopFlowRate(UnitConversions.convert(geothermal_loop.loop_flow, 'gal/min', 'm^3/s')) sizing_plant = plant_loop.sizingPlant sizing_plant.setLoopType('Condenser') @@ -745,7 +726,7 @@ def self.apply_ground_to_air_heat_pump(model, runner, weather, heat_pump, hvac_s add_pump_power_ems_program(model, pump_w, pump, air_loop_unitary) if heat_pump.is_shared_system - # Shared pump power per ANSI/RESNET/ICC 301-2019 Section 4.4.5.1 (pump runs 8760) + # Shared pump power per ANSI/RESNET/ICC 301-2022 Section 4.4.5.1 (pump runs 8760) design_level = heat_pump.shared_loop_watts / heat_pump.number_of_units_served.to_f equip = Model.add_electric_equipment( @@ -857,13 +838,10 @@ def self.apply_boiler(model, runner, heating_system, hvac_sequential_load_fracs, end # Plant Loop - plant_loop = OpenStudio::Model::PlantLoop.new(model) - plant_loop.setName(obj_name + ' hydronic heat loop') - plant_loop.setFluidType(EPlus::FluidWater) - plant_loop.setMaximumLoopTemperature(100) - plant_loop.setMinimumLoopTemperature(0) - plant_loop.setMinimumLoopFlowRate(0) - plant_loop.autocalculatePlantLoopVolume() + plant_loop = Model.add_plant_loop( + model, + name: "#{obj_name} hydronic heat loop" + ) loop_sizing = plant_loop.sizingPlant loop_sizing.setLoopType('Heating') @@ -1311,14 +1289,14 @@ def self.apply_ceiling_fans(runner, model, spaces, weather, hpxml_bldg, hpxml_he ceiling_fan = hpxml_bldg.ceiling_fans[0] obj_name = Constants::ObjectTypeCeilingFan - hrs_per_day = 10.5 # From ANSI 301-2019 + hrs_per_day = 10.5 # From ANSI/RESNET/ICC 301-2022 cfm_per_w = ceiling_fan.efficiency label_energy_use = ceiling_fan.label_energy_use count = ceiling_fan.count if !label_energy_use.nil? # priority if both provided annual_kwh = UnitConversions.convert(count * label_energy_use * hrs_per_day * 365.0, 'Wh', 'kWh') elsif !cfm_per_w.nil? - medium_cfm = 3000.0 # cfm, per ANSI 301-2019 + medium_cfm = 3000.0 # cfm, per ANSI/RESNET/ICC 301-2019 annual_kwh = UnitConversions.convert(count * medium_cfm / cfm_per_w * hrs_per_day * 365.0, 'Wh', 'kWh') end @@ -1593,10 +1571,11 @@ def self.get_cooling_setpoints(hvac_control, has_ceiling_fan, year, weather, off # @param compressor_type [TODO] TODO # @return [TODO] TODO def self.get_cool_cap_eir_ft_spec(compressor_type) - if compressor_type == HPXML::HVACCompressorTypeSingleStage + case compressor_type + when HPXML::HVACCompressorTypeSingleStage cap_ft_spec = [[3.68637657, -0.098352478, 0.000956357, 0.005838141, -0.0000127, -0.000131702]] eir_ft_spec = [[-3.437356399, 0.136656369, -0.001049231, -0.0079378, 0.000185435, -0.0001441]] - elsif compressor_type == HPXML::HVACCompressorTypeTwoStage + when HPXML::HVACCompressorTypeTwoStage cap_ft_spec = [[3.998418659, -0.108728222, 0.001056818, 0.007512314, -0.0000139, -0.000164716], [3.466810106, -0.091476056, 0.000901205, 0.004163355, -0.00000919, -0.000110829]] eir_ft_spec = [[-4.282911381, 0.181023691, -0.001357391, -0.026310378, 0.000333282, -0.000197405], @@ -1610,17 +1589,18 @@ def self.get_cool_cap_eir_ft_spec(compressor_type) # @param compressor_type [TODO] TODO # @return [TODO] TODO def self.get_cool_cap_eir_fflow_spec(compressor_type) - if compressor_type == HPXML::HVACCompressorTypeSingleStage + case compressor_type + when HPXML::HVACCompressorTypeSingleStage # Single stage systems have PSC or constant torque ECM blowers, so the airflow rate is affected by the static pressure losses. cap_fflow_spec = [[0.718664047, 0.41797409, -0.136638137]] eir_fflow_spec = [[1.143487507, -0.13943972, -0.004047787]] - elsif compressor_type == HPXML::HVACCompressorTypeTwoStage + when HPXML::HVACCompressorTypeTwoStage # Most two stage systems have PSC or constant torque ECM blowers, so the airflow rate is affected by the static pressure losses. cap_fflow_spec = [[0.655239515, 0.511655216, -0.166894731], [0.618281092, 0.569060264, -0.187341356]] eir_fflow_spec = [[1.639108268, -0.998953996, 0.359845728], [1.570774717, -0.914152018, 0.343377302]] - elsif compressor_type == HPXML::HVACCompressorTypeVariableSpeed + when HPXML::HVACCompressorTypeVariableSpeed # Variable speed systems have constant flow ECM blowers, so the air handler can always achieve the design airflow rate by sacrificing blower power. # So we assume that there is only one corresponding airflow rate for each compressor speed. eir_fflow_spec = [[1, 0, 0]] * 2 @@ -1655,17 +1635,18 @@ def self.get_heat_cap_eir_ft_spec(compressor_type, heating_capacity_retention_te # @param compressor_type [TODO] TODO # @return [TODO] TODO def self.get_heat_cap_eir_fflow_spec(compressor_type) - if compressor_type == HPXML::HVACCompressorTypeSingleStage + case compressor_type + when HPXML::HVACCompressorTypeSingleStage # Single stage systems have PSC or constant torque ECM blowers, so the airflow rate is affected by the static pressure losses. cap_fflow_spec = [[0.694045465, 0.474207981, -0.168253446]] eir_fflow_spec = [[2.185418751, -1.942827919, 0.757409168]] - elsif compressor_type == HPXML::HVACCompressorTypeTwoStage + when HPXML::HVACCompressorTypeTwoStage # Most two stage systems have PSC or constant torque ECM blowers, so the airflow rate is affected by the static pressure losses. cap_fflow_spec = [[0.741466907, 0.378645444, -0.119754733], [0.76634609, 0.32840943, -0.094701495]] eir_fflow_spec = [[2.153618211, -1.737190609, 0.584269478], [2.001041353, -1.58869128, 0.587593517]] - elsif compressor_type == HPXML::HVACCompressorTypeVariableSpeed + when HPXML::HVACCompressorTypeVariableSpeed # Variable speed systems have constant flow ECM blowers, so the air handler can always achieve the design airflow rate by sacrificing blower power. # So we assume that there is only one corresponding airflow rate for each compressor speed. cap_fflow_spec = [[1, 0, 0]] * 3 @@ -1686,7 +1667,8 @@ def self.set_cool_curves_central_air_source(cooling_system, use_eer = false) set_cool_c_d(cooling_system) seer = cooling_system.cooling_efficiency_seer - if cooling_system.compressor_type == HPXML::HVACCompressorTypeSingleStage + case cooling_system.compressor_type + when HPXML::HVACCompressorTypeSingleStage clg_ap.cool_cap_ft_spec, clg_ap.cool_eir_ft_spec = get_cool_cap_eir_ft_spec(cooling_system.compressor_type) if not use_eer clg_ap.cool_rated_airflow_rate = clg_ap.cool_rated_cfm_per_ton[0] @@ -1699,7 +1681,7 @@ def self.set_cool_curves_central_air_source(cooling_system, use_eer = false) clg_ap.cool_eir_fflow_spec = [[1.0, 0.0, 0.0]] end - elsif cooling_system.compressor_type == HPXML::HVACCompressorTypeTwoStage + when HPXML::HVACCompressorTypeTwoStage clg_ap.cool_rated_airflow_rate = clg_ap.cool_rated_cfm_per_ton[-1] clg_ap.cool_fan_speed_ratios = calc_fan_speed_ratios(clg_ap.cool_capacity_ratios, clg_ap.cool_rated_cfm_per_ton, clg_ap.cool_rated_airflow_rate) clg_ap.cool_cap_ft_spec, clg_ap.cool_eir_ft_spec = get_cool_cap_eir_ft_spec(cooling_system.compressor_type) @@ -1707,7 +1689,7 @@ def self.set_cool_curves_central_air_source(cooling_system, use_eer = false) clg_ap.cool_rated_cops = [0.2773 * seer - 0.0018] # Regression based on inverse model clg_ap.cool_rated_cops << clg_ap.cool_rated_cops[0] * 0.91 # COP ratio based on Dylan's data as seen in BEopt 2.8 options - elsif cooling_system.compressor_type == HPXML::HVACCompressorTypeVariableSpeed + when HPXML::HVACCompressorTypeVariableSpeed clg_ap.cooling_capacity_retention_temperature = 82.0 clg_ap.cooling_capacity_retention_fraction = 1.033 # From NEEP data clg_ap.cool_rated_airflow_rate = clg_ap.cool_rated_cfm_per_ton[-1] @@ -1724,11 +1706,12 @@ def self.set_cool_curves_central_air_source(cooling_system, use_eer = false) # @return [TODO] TODO def self.get_cool_capacity_ratios(hvac_system) # For each speed, ratio of capacity to nominal capacity - if hvac_system.compressor_type == HPXML::HVACCompressorTypeSingleStage + case hvac_system.compressor_type + when HPXML::HVACCompressorTypeSingleStage return [1.0] - elsif hvac_system.compressor_type == HPXML::HVACCompressorTypeTwoStage + when HPXML::HVACCompressorTypeTwoStage return [0.72, 1.0] - elsif hvac_system.compressor_type == HPXML::HVACCompressorTypeVariableSpeed + when HPXML::HVACCompressorTypeVariableSpeed is_ducted = !hvac_system.distribution_system_idref.nil? if is_ducted return [0.394, 1.0] @@ -1753,7 +1736,8 @@ def self.set_heat_curves_central_air_source(heating_system, use_cop = false) set_heat_c_d(heating_system) hspf = heating_system.heating_efficiency_hspf - if heating_system.compressor_type == HPXML::HVACCompressorTypeSingleStage + case heating_system.compressor_type + when HPXML::HVACCompressorTypeSingleStage heating_capacity_retention_temp, heating_capacity_retention_fraction = get_heating_capacity_retention(heating_system) htg_ap.heat_cap_ft_spec, htg_ap.heat_eir_ft_spec = get_heat_cap_eir_ft_spec(heating_system.compressor_type, heating_capacity_retention_temp, heating_capacity_retention_fraction) if not use_cop @@ -1764,7 +1748,7 @@ def self.set_heat_curves_central_air_source(heating_system, use_cop = false) htg_ap.heat_fan_speed_ratios = [1.0] end - elsif heating_system.compressor_type == HPXML::HVACCompressorTypeTwoStage + when HPXML::HVACCompressorTypeTwoStage heating_capacity_retention_temp, heating_capacity_retention_fraction = get_heating_capacity_retention(heating_system) htg_ap.heat_cap_ft_spec, htg_ap.heat_eir_ft_spec = get_heat_cap_eir_ft_spec(heating_system.compressor_type, heating_capacity_retention_temp, heating_capacity_retention_fraction) htg_ap.heat_rated_airflow_rate = htg_ap.heat_rated_cfm_per_ton[-1] @@ -1772,7 +1756,7 @@ def self.set_heat_curves_central_air_source(heating_system, use_cop = false) htg_ap.heat_rated_cops = [0.0426 * hspf**2 - 0.0747 * hspf + 1.5374] # Regression based on inverse model htg_ap.heat_rated_cops << htg_ap.heat_rated_cops[0] * 0.87 # COP ratio based on Dylan's data as seen in BEopt 2.8 options - elsif heating_system.compressor_type == HPXML::HVACCompressorTypeVariableSpeed + when HPXML::HVACCompressorTypeVariableSpeed htg_ap.heat_rated_airflow_rate = htg_ap.heat_rated_cfm_per_ton[-1] htg_ap.heat_capacity_ratios = get_heat_capacity_ratios(heating_system) htg_ap.heat_fan_speed_ratios = calc_fan_speed_ratios(htg_ap.heat_capacity_ratios, htg_ap.heat_rated_cfm_per_ton, htg_ap.heat_rated_airflow_rate) @@ -1889,11 +1873,12 @@ def self.set_cool_detailed_performance_data(heat_pump) # @return [TODO] TODO def self.get_heat_capacity_ratios(heat_pump) # For each speed, ratio of capacity to nominal capacity - if heat_pump.compressor_type == HPXML::HVACCompressorTypeSingleStage + case heat_pump.compressor_type + when HPXML::HVACCompressorTypeSingleStage return [1.0] - elsif heat_pump.compressor_type == HPXML::HVACCompressorTypeTwoStage + when HPXML::HVACCompressorTypeTwoStage return [0.72, 1.0] - elsif heat_pump.compressor_type == HPXML::HVACCompressorTypeVariableSpeed + when HPXML::HVACCompressorTypeVariableSpeed is_ducted = !heat_pump.distribution_system_idref.nil? if is_ducted nominal_to_max_ratio = 0.972 @@ -1975,15 +1960,16 @@ def self.get_cool_cfm_per_ton(compressor_type, use_eer = false) # @return [TODO] TODO def self.get_heat_cfm_per_ton(compressor_type, use_cop_or_htg_sys = false) # cfm/ton of rated capacity - if compressor_type == HPXML::HVACCompressorTypeSingleStage + case compressor_type + when HPXML::HVACCompressorTypeSingleStage if not use_cop_or_htg_sys return [384.1] else return [350] end - elsif compressor_type == HPXML::HVACCompressorTypeTwoStage + when HPXML::HVACCompressorTypeTwoStage return [391.3333, 352.2] - elsif compressor_type == HPXML::HVACCompressorTypeVariableSpeed + when HPXML::HVACCompressorTypeVariableSpeed return [400.0, 400.0, 400.0] else fail 'Compressor type not supported.' @@ -4430,16 +4416,19 @@ def self.set_cool_c_d(cooling_system) if ((cooling_system.is_a? HPXML::CoolingSystem) && ([HPXML::HVACTypeRoomAirConditioner, HPXML::HVACTypePTAC].include? cooling_system.cooling_system_type)) || ((cooling_system.is_a? HPXML::HeatPump) && ([HPXML::HVACTypeHeatPumpPTHP, HPXML::HVACTypeHeatPumpRoom].include? cooling_system.heat_pump_type)) clg_ap.cool_c_d = 0.22 - elsif cooling_system.compressor_type == HPXML::HVACCompressorTypeSingleStage - if cooling_system.cooling_efficiency_seer < 13.0 - clg_ap.cool_c_d = 0.20 - else - clg_ap.cool_c_d = 0.07 + else + case cooling_system.compressor_type + when HPXML::HVACCompressorTypeSingleStage + if cooling_system.cooling_efficiency_seer < 13.0 + clg_ap.cool_c_d = 0.20 + else + clg_ap.cool_c_d = 0.07 + end + when HPXML::HVACCompressorTypeTwoStage + clg_ap.cool_c_d = 0.11 + when HPXML::HVACCompressorTypeVariableSpeed + clg_ap.cool_c_d = 0.25 end - elsif cooling_system.compressor_type == HPXML::HVACCompressorTypeTwoStage - clg_ap.cool_c_d = 0.11 - elsif cooling_system.compressor_type == HPXML::HVACCompressorTypeVariableSpeed - clg_ap.cool_c_d = 0.25 end # PLF curve @@ -4457,16 +4446,19 @@ def self.set_heat_c_d(heating_system) # Degradation coefficient for heating if (heating_system.is_a? HPXML::HeatPump) && ([HPXML::HVACTypeHeatPumpPTHP, HPXML::HVACTypeHeatPumpRoom].include? heating_system.heat_pump_type) htg_ap.heat_c_d = 0.22 - elsif heating_system.compressor_type == HPXML::HVACCompressorTypeSingleStage - if heating_system.heating_efficiency_hspf < 7.0 - htg_ap.heat_c_d = 0.20 - else + else + case heating_system.compressor_type + when HPXML::HVACCompressorTypeSingleStage + if heating_system.heating_efficiency_hspf < 7.0 + htg_ap.heat_c_d = 0.20 + else + htg_ap.heat_c_d = 0.11 + end + when HPXML::HVACCompressorTypeTwoStage htg_ap.heat_c_d = 0.11 + when HPXML::HVACCompressorTypeVariableSpeed + htg_ap.heat_c_d = 0.25 end - elsif heating_system.compressor_type == HPXML::HVACCompressorTypeTwoStage - htg_ap.heat_c_d = 0.11 - elsif heating_system.compressor_type == HPXML::HVACCompressorTypeVariableSpeed - htg_ap.heat_c_d = 0.25 end # PLF curve @@ -4544,14 +4536,15 @@ def self.set_gshp_assumptions(heat_pump, weather) end pipe_diameter = geothermal_loop.pipe_diameter # Pipe nominal size conversion to pipe outside diameter and inside diameter, - # only pipe sizes <= 2" are used here with DR11 (dimension ratio), - if pipe_diameter == 0.75 # 3/4" pipe + # only pipe sizes <= 2" are used here with DR11 (dimension ratio) + case pipe_diameter + when 0.75 # 3/4" pipe hp_ap.pipe_od = 1.050 # in hp_ap.pipe_id = 0.859 # in - elsif pipe_diameter == 1.0 # 1" pipe + when 1.0 # 1" pipe hp_ap.pipe_od = 1.315 # in hp_ap.pipe_id = 1.076 # in - elsif pipe_diameter == 1.25 # 1-1/4" pipe + when 1.25 # 1-1/4" pipe hp_ap.pipe_od = 1.660 # in hp_ap.pipe_id = 1.358 # in else @@ -4559,13 +4552,14 @@ def self.set_gshp_assumptions(heat_pump, weather) end hp_ap.u_tube_spacing_type = 'b' # Calculate distance between pipes - if hp_ap.u_tube_spacing_type == 'as' + case hp_ap.u_tube_spacing_type + when 'as' # Two tubes, spaced 1/8” apart at the center of the borehole hp_ap.u_tube_spacing = 0.125 - elsif hp_ap.u_tube_spacing_type == 'b' + when 'b' # Two tubes equally spaced between the borehole edges hp_ap.u_tube_spacing = 0.9661 - elsif hp_ap.u_tube_spacing_type == 'c' + when 'c' # Both tubes placed against outer edge of borehole hp_ap.u_tube_spacing = geothermal_loop.bore_diameter - 2 * hp_ap.pipe_od end @@ -5288,7 +5282,7 @@ def self.apply_shared_cooling_systems(hpxml_bldg) aux_dweq = cooling_system.fan_coil_watts end end - # ANSI/RESNET/ICC 301-2019 Equation 4.4-2 + # ANSI/RESNET/ICC 301-2022 Equation 4.4-2 seer_eq = (cap - 3.41 * aux - 3.41 * aux_dweq * n_dweq) / (chiller_input + aux + aux_dweq * n_dweq) elsif cooling_system.cooling_system_type == HPXML::HVACTypeCoolingTower @@ -5301,7 +5295,7 @@ def self.apply_shared_cooling_systems(hpxml_bldg) wlhp_input = wlhp_cap / wlhp.cooling_efficiency_eer end end - # ANSI/RESNET/ICC 301-2019 Equation 4.4-3 + # ANSI/RESNET/ICC 301-2022 Equation 4.4-3 seer_eq = (wlhp_cap - 3.41 * aux / n_dweq) / (wlhp_input + aux / n_dweq) else @@ -5394,7 +5388,7 @@ def self.apply_shared_heating_systems(hpxml_bldg) if heating_system.heating_system_type == HPXML::HVACTypeBoiler && hydronic_type.to_s == HPXML::HydronicTypeWaterLoop # Shared boiler w/ water loop heat pump - # Per ANSI/RESNET/ICC 301-2019 Section 4.4.7.2, model as: + # Per ANSI/RESNET/ICC 301-2022 Section 4.4.7.2, model as: # A) heat pump with constant efficiency and duct losses, fraction heat load served = 1/COP # B) boiler, fraction heat load served = 1-1/COP fraction_heat_load_served = heating_system.fraction_heat_load_served @@ -5586,7 +5580,7 @@ def self.apply_unit_multiplier(hpxml_bldg, hpxml_header) # Calculates rated SEER (older metric) from rated SEER2 (newer metric). # # Source: ANSI/RESNET/ICC 301 Table 4.4.4.1(1) SEER2/HSPF2 Conversion Factors - # This is based on a regression of products, not a translation. + # Note that this is a regression based on products on the market, not a conversion. # # @param seer2 [Double] Cooling efficiency (Btu/Wh) # @param is_ducted [Boolean] True if a ducted HVAC system diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac_sizing.rb b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac_sizing.rb index 408e380b02..400c639997 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac_sizing.rb +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac_sizing.rb @@ -260,10 +260,11 @@ def self.process_site_calcs_and_design_temps(mj, weather, hpxml_bldg) locations.uniq.each do |location| next if [HPXML::LocationGround].include? location - if [HPXML::LocationOutside, HPXML::LocationRoofDeck, HPXML::LocationManufacturedHomeUnderBelly].include? location + case location + when HPXML::LocationOutside, HPXML::LocationRoofDeck, HPXML::LocationManufacturedHomeUnderBelly mj.cool_design_temps[location] = hpxml_bldg.header.manualj_cooling_design_temp mj.heat_design_temps[location] = hpxml_bldg.header.manualj_heating_design_temp - elsif HPXML::conditioned_locations.include? location + when *HPXML::conditioned_locations mj.cool_design_temps[location] = get_design_temp_cooling(mj, weather, HPXML::LocationConditionedSpace, hpxml_bldg) mj.heat_design_temps[location] = get_design_temp_heating(mj, weather, HPXML::LocationConditionedSpace, hpxml_bldg) else @@ -423,54 +424,62 @@ def self.get_design_temp_cooling(mj, weather, location, hpxml_bldg) end else if not roof.radiant_barrier - if roof.roof_type == HPXML::RoofTypeAsphaltShingles - if [HPXML::ColorDark, HPXML::ColorMediumDark].include? roof.roof_color + case roof.roof_type + when HPXML::RoofTypeAsphaltShingles + case roof.roof_color + when HPXML::ColorDark, HPXML::ColorMediumDark cool_temp += 130.0 * roof.net_area else cool_temp += 120.0 * roof.net_area end - elsif roof.roof_type == HPXML::RoofTypeWoodShingles + when HPXML::RoofTypeWoodShingles cool_temp += 120.0 * roof.net_area - elsif roof.roof_type == HPXML::RoofTypeMetal - if [HPXML::ColorDark, HPXML::ColorMediumDark].include? roof.roof_color + when HPXML::RoofTypeMetal + case roof.roof_color + when HPXML::ColorDark, HPXML::ColorMediumDark cool_temp += 130.0 * roof.net_area - elsif [HPXML::ColorMedium, HPXML::ColorLight].include? roof.roof_color + when HPXML::ColorMedium, HPXML::ColorLight cool_temp += 120.0 * roof.net_area - elsif [HPXML::ColorReflective].include? roof.roof_color + when HPXML::ColorReflective cool_temp += 95.0 * roof.net_area end - elsif roof.roof_type == HPXML::RoofTypeClayTile - if [HPXML::ColorDark, HPXML::ColorMediumDark].include? roof.roof_color + when HPXML::RoofTypeClayTile + case roof.roof_color + when HPXML::ColorDark, HPXML::ColorMediumDark cool_temp += 110.0 * roof.net_area - elsif [HPXML::ColorMedium, HPXML::ColorLight].include? roof.roof_color + when HPXML::ColorMedium, HPXML::ColorLight cool_temp += 105.0 * roof.net_area - elsif [HPXML::ColorReflective].include? roof.roof_color + when HPXML::ColorReflective cool_temp += 95.0 * roof.net_area end end else # with a radiant barrier - if roof.roof_type == HPXML::RoofTypeAsphaltShingles - if [HPXML::ColorDark, HPXML::ColorMediumDark].include? roof.roof_color + case roof.roof_type + when HPXML::RoofTypeAsphaltShingles + case roof.roof_color + when HPXML::ColorDark, HPXML::ColorMediumDark cool_temp += 120.0 * roof.net_area else cool_temp += 110.0 * roof.net_area end - elsif roof.roof_type == HPXML::RoofTypeWoodShingles + when HPXML::RoofTypeWoodShingles cool_temp += 110.0 * roof.net_area - elsif roof.roof_type == HPXML::RoofTypeMetal - if [HPXML::ColorDark, HPXML::ColorMediumDark].include? roof.roof_color + when HPXML::RoofTypeMetal + case roof.roof_color + when HPXML::ColorDark, HPXML::ColorMediumDark cool_temp += 120.0 * roof.net_area - elsif [HPXML::ColorMedium, HPXML::ColorLight].include? roof.roof_color + when HPXML::ColorMedium, HPXML::ColorLight cool_temp += 110.0 * roof.net_area - elsif [HPXML::ColorReflective].include? roof.roof_color + when HPXML::ColorReflective cool_temp += 95.0 * roof.net_area end - elsif roof.roof_type == HPXML::RoofTypeClayTile - if [HPXML::ColorDark, HPXML::ColorMediumDark].include? roof.roof_color + when HPXML::RoofTypeClayTile + case roof.roof_color + when HPXML::ColorDark, HPXML::ColorMediumDark cool_temp += 105.0 * roof.net_area - elsif [HPXML::ColorMedium, HPXML::ColorLight].include? roof.roof_color + when HPXML::ColorMedium, HPXML::ColorLight cool_temp += 100.0 * roof.net_area - elsif [HPXML::ColorReflective].include? roof.roof_color + when HPXML::ColorReflective cool_temp += 95.0 * roof.net_area end end @@ -1070,11 +1079,12 @@ def self.process_load_walls(mj, hpxml_bldg, all_zone_loads, all_space_loads) color = HPXML::ColorDark end - if color == HPXML::ColorLight + case color + when HPXML::ColorLight color_multiplier = 0.65 # MJ8 Table 4B Notes, pg 348 - elsif color == HPXML::ColorMedium + when HPXML::ColorMedium color_multiplier = 0.83 # MJ8 Appendix 12, pg 519 - elsif color == HPXML::ColorDark + when HPXML::ColorDark color_multiplier = 1.0 end @@ -1170,17 +1180,18 @@ def self.process_load_roofs(mj, hpxml_bldg, all_zone_loads, all_space_loads) end # Base CLTD color adjustment based on notes in MJ8 Figure A12-16 - if [HPXML::ColorDark, HPXML::ColorMediumDark].include? roof.roof_color + case roof.roof_color + when HPXML::ColorDark, HPXML::ColorMediumDark if [HPXML::RoofTypeClayTile, HPXML::RoofTypeWoodShingles].include? roof.roof_type cltd *= 0.83 end - elsif [HPXML::ColorMedium, HPXML::ColorLight].include? roof.roof_color + when HPXML::ColorMedium, HPXML::ColorLight if [HPXML::RoofTypeClayTile].include? roof.roof_type cltd *= 0.65 else cltd *= 0.83 end - elsif [HPXML::ColorReflective].include? roof.roof_color + when HPXML::ColorReflective if [HPXML::RoofTypeAsphaltShingles, HPXML::RoofTypeWoodShingles].include? roof.roof_type cltd *= 0.83 else @@ -1264,17 +1275,17 @@ def self.process_load_floors(mj, hpxml_bldg, all_zone_loads, all_space_loads) zone = space.zone has_radiant_floor = get_has_radiant_floor(zone) + u_floor = 1.0 / floor.insulation_assembly_r_value if floor.is_exterior htd_adj = mj.htd htd_adj += 25.0 if has_radiant_floor # Table 4A: Radiant floor over open crawlspace: HTM = U-Value × (HTD + 25) - clg_htm = (1.0 / floor.insulation_assembly_r_value) * (mj.ctd - 5.0 + mj.daily_range_temp_adjust[mj.daily_range_num]) - htg_htm = (1.0 / floor.insulation_assembly_r_value) * htd_adj + clg_htm = u_floor * (mj.ctd - 5.0 + mj.daily_range_temp_adjust[mj.daily_range_num]) + htg_htm = u_floor * htd_adj else # Partition floor adjacent_space = floor.exterior_adjacent_to - if floor.is_floor && [HPXML::LocationCrawlspaceVented, HPXML::LocationCrawlspaceUnvented, HPXML::LocationBasementUnconditioned].include?(adjacent_space) - u_floor = 1.0 / floor.insulation_assembly_r_value + if [HPXML::LocationCrawlspaceVented, HPXML::LocationCrawlspaceUnvented, HPXML::LocationBasementUnconditioned].include?(adjacent_space) sum_ua_wall = 0.0 sum_a_wall = 0.0 @@ -1306,7 +1317,7 @@ def self.process_load_floors(mj, hpxml_bldg, all_zone_loads, all_space_loads) u_wall = sum_ua_wall / sum_a_wall htd_adj = mj.htd - htd_adj += 25.0 if has_radiant_floor && HPXML::LocationCrawlspaceVented # Table 4A: Radiant floor over open crawlspace: HTM = U-Value × (HTD + 25) + htd_adj += 25.0 if has_radiant_floor # Manual J Figure A12-6 footnote 2) # Calculate partition temperature different cooling (PTDC) per Manual J Figure A12-17 # Calculate partition temperature different heating (PTDH) per Manual J Figure A12-6 @@ -1320,19 +1331,21 @@ def self.process_load_floors(mj, hpxml_bldg, all_zone_loads, all_space_loads) ptdh_floor = u_wall * htd_adj / (4.0 * u_floor + u_wall) end - clg_htm = (1.0 / floor.insulation_assembly_r_value) * ptdc_floor - htg_htm = (1.0 / floor.insulation_assembly_r_value) * ptdh_floor + clg_htm = u_floor * ptdc_floor + htg_htm = u_floor * ptdh_floor else # E.g., floor over garage - clg_htm = (1.0 / floor.insulation_assembly_r_value) * (mj.cool_design_temps[adjacent_space] - mj.cool_setpoint) - htg_htm = (1.0 / floor.insulation_assembly_r_value) * (mj.heat_setpoint - mj.heat_design_temps[adjacent_space]) + htd_adj = mj.heat_setpoint - mj.heat_design_temps[adjacent_space] + htd_adj += 25.0 if has_radiant_floor # Manual J Figure A12-6 footnote 2), and Table 4A: Radiant floor over garage: HTM = U-Value × (HTD + 25) + clg_htm = u_floor * (mj.cool_design_temps[adjacent_space] - mj.cool_setpoint) + htg_htm = u_floor * htd_adj end end clg_loads = clg_htm * floor.net_area htg_loads = htg_htm * floor.net_area all_zone_loads[zone].Cool_Floors += clg_loads all_zone_loads[zone].Heat_Floors += htg_loads - all_space_loads[space].Cool_Roofs += clg_loads - all_space_loads[space].Heat_Roofs += htg_loads + all_space_loads[space].Cool_Floors += clg_loads + all_space_loads[space].Heat_Floors += htg_loads detailed_output_values = DetailedOutputValues.new(area: floor.net_area, heat_htm: htg_htm, cool_htm: clg_htm, @@ -1748,16 +1761,16 @@ def self.apply_hvac_loads_to_hvac_sizings(hvac_sizings, hvac_loads) def self.get_duct_regain_factor(duct, hpxml_bldg) f_regain = nil - if [HPXML::LocationOutside, HPXML::LocationRoofDeck].include? duct.duct_location + case duct.duct_location + when HPXML::LocationOutside, HPXML::LocationRoofDeck f_regain = 0.0 - elsif [HPXML::LocationOtherHousingUnit, HPXML::LocationOtherHeatedSpace, HPXML::LocationOtherMultifamilyBufferSpace, - HPXML::LocationOtherNonFreezingSpace, HPXML::LocationExteriorWall, HPXML::LocationUnderSlab, - HPXML::LocationManufacturedHomeBelly].include? duct.duct_location + when HPXML::LocationOtherHousingUnit, HPXML::LocationOtherHeatedSpace, HPXML::LocationOtherMultifamilyBufferSpace, + HPXML::LocationOtherNonFreezingSpace, HPXML::LocationExteriorWall, HPXML::LocationUnderSlab, HPXML::LocationManufacturedHomeBelly space_values = Geometry.get_temperature_scheduled_space_values(duct.duct_location) f_regain = space_values[:f_regain] - elsif [HPXML::LocationBasementUnconditioned, HPXML::LocationCrawlspaceVented, HPXML::LocationCrawlspaceUnvented].include? duct.duct_location + when HPXML::LocationBasementUnconditioned, HPXML::LocationCrawlspaceVented, HPXML::LocationCrawlspaceUnvented ceilings = hpxml_bldg.floors.select { |f| f.is_floor && [f.interior_adjacent_to, f.exterior_adjacent_to].include?(duct.duct_location) } avg_ceiling_rvalue = calculate_average_r_value(ceilings) @@ -1799,13 +1812,13 @@ def self.get_duct_regain_factor(duct, hpxml_bldg) end end - elsif [HPXML::LocationAtticVented, HPXML::LocationAtticUnvented].include? duct.duct_location + when HPXML::LocationAtticVented, HPXML::LocationAtticUnvented f_regain = 0.10 # This would likely be higher for unvented attics with roof insulation - elsif [HPXML::LocationGarage].include? duct.duct_location + when HPXML::LocationGarage f_regain = 0.05 - elsif HPXML::conditioned_locations.include? duct.duct_location + when *HPXML::conditioned_locations f_regain = 1.0 end @@ -1978,11 +1991,11 @@ def self.apply_hvac_duct_loads(mj, zone, hvac_loads, zone_loads, all_space_loads end end - # TODO + # Calculates the duct loads using Manual J Table 7 default duct tables. # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param manualj_duct_load [HPXML::ManualJDuctLoad] Manual J duct load of interest - # @return [TODO] TODO + # @return [Array] Heating loss factor, Cooling sensible gain factor, Cooling latent gain Btuh def self.get_duct_table7_factors(hpxml_bldg, manualj_duct_load) # Gather values htg_oat = hpxml_bldg.header.manualj_heating_design_temp @@ -3422,13 +3435,14 @@ def self.apply_hvac_ground_loop(mj, runner, hvac_sizings, weather, hvac_cooling, def self.get_geothermal_loop_borefield_ft_per_ton(mj, hpxml_bldg, geothermal_loop, weather, hvac_cooling) hvac_cooling_ap = hvac_cooling.additional_properties - if hvac_cooling_ap.u_tube_spacing_type == 'b' + case hvac_cooling_ap.u_tube_spacing_type + when 'b' beta_0 = 17.4427 beta_1 = -0.6052 - elsif hvac_cooling_ap.u_tube_spacing_type == 'c' + when 'c' beta_0 = 21.9059 beta_1 = -0.3796 - elsif hvac_cooling_ap.u_tube_spacing_type == 'as' + when 'as' beta_0 = 20.1004 beta_1 = -0.94467 end @@ -4358,13 +4372,14 @@ def self.calculate_space_design_temp(mj, location, weather, hpxml_bldg, setpoint sum_uat, sum_ua = 0.0, 0.0 space_UAs.each do |ua_type, ua| - if ua_type == HPXML::LocationGround + case ua_type + when HPXML::LocationGround sum_uat += ua * ground_db sum_ua += ua - elsif ua_type == HPXML::LocationOutside + when HPXML::LocationOutside sum_uat += ua * design_db sum_ua += ua - elsif ua_type == HPXML::LocationConditionedSpace + when HPXML::LocationConditionedSpace sum_uat += ua * setpoint_temp sum_ua += ua else @@ -4393,11 +4408,12 @@ def self.calculate_space_design_temp(mj, location, weather, hpxml_bldg, setpoint ua_conditioned = 0.0 ua_outside = 0.0 space_UAs.each do |ua_type, ua| - if ua_type == HPXML::LocationOutside + case ua_type + when HPXML::LocationOutside ua_outside += ua - elsif ua_type == HPXML::LocationConditionedSpace + when HPXML::LocationConditionedSpace ua_conditioned += ua - elsif ua_type != HPXML::LocationGround + when !HPXML::LocationGround fail "Unexpected space ua type: '#{ua_type}'." end end @@ -5006,35 +5022,36 @@ def self.get_window_interior_shading_coefficient(window) end else # Use physical window properties - if window.glass_layers == HPXML::WindowLayersSinglePane - if [HPXML::WindowGlassTypeTintedReflective, - HPXML::WindowGlassTypeReflective].include? window.glass_type + case window.glass_layers + when HPXML::WindowLayersSinglePane + case window.glass_type + when HPXML::WindowGlassTypeTintedReflective, HPXML::WindowGlassTypeReflective window_type = '1P Reflective' - elsif [HPXML::WindowGlassTypeTinted].include? window.glass_type + when HPXML::WindowGlassTypeTinted window_type = '1P Heat Absorbing' else window_type = '1P Clear' end - elsif window.glass_layers == HPXML::WindowLayersDoublePane - if [HPXML::WindowGlassTypeTintedReflective, - HPXML::WindowGlassTypeReflective].include? window.glass_type + when HPXML::WindowLayersDoublePane + case window.glass_type + when HPXML::WindowGlassTypeTintedReflective, HPXML::WindowGlassTypeReflective window_type = '2P Reflective' - elsif [HPXML::WindowGlassTypeTinted].include? window.glass_type + when HPXML::WindowGlassTypeTinted window_type = '2P Heat Absorbing' - elsif [HPXML::WindowGlassTypeLowELowSolarGain].include? window.glass_type + when HPXML::WindowGlassTypeLowELowSolarGain window_type = '2P Low-e Option 3' - elsif [HPXML::WindowGlassTypeLowE].include? window.glass_type + when HPXML::WindowGlassTypeLowE window_type = '2P Low-e Option 2' - elsif [HPXML::WindowGlassTypeLowEHighSolarGain].include? window.glass_type + when HPXML::WindowGlassTypeLowEHighSolarGain window_type = '2P Low-e Option 1' else window_type = '2P Clear' end - elsif window.glass_layers == HPXML::WindowLayersTriplePane - if [HPXML::WindowGlassTypeTintedReflective, - HPXML::WindowGlassTypeReflective].include? window.glass_type + when HPXML::WindowLayersTriplePane + case window.glass_type + when HPXML::WindowGlassTypeTintedReflective, HPXML::WindowGlassTypeReflective window_type = '3P Reflective' - elsif [HPXML::WindowGlassTypeTinted].include? window.glass_type + when HPXML::WindowGlassTypeTinted window_type = '3P Heat Absorbing' else window_type = '3P Clear' diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/internal_gains.rb b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/internal_gains.rb index 3480915acd..281f2c0b81 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/internal_gains.rb +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/internal_gains.rb @@ -13,11 +13,11 @@ module InternalGains # @return [nil] def self.apply_building_occupants(runner, model, hpxml_bldg, hpxml_header, spaces, schedules_file) if hpxml_bldg.building_occupancy.number_of_residents.nil? # Asset calculation - num_occ = Geometry.get_occupancy_default_num(nbeds: hpxml_bldg.building_construction.number_of_bedrooms) + n_occ = Geometry.get_occupancy_default_num(nbeds: hpxml_bldg.building_construction.number_of_bedrooms) else # Operational calculation - num_occ = hpxml_bldg.building_occupancy.number_of_residents + n_occ = hpxml_bldg.building_occupancy.number_of_residents end - return if num_occ <= 0 + return if n_occ <= 0 occ_gain, _hrs_per_day, sens_frac, _lat_frac = Defaults.get_occupancy_values() activity_per_person = UnitConversions.convert(occ_gain, 'Btu/hr', 'W') @@ -60,7 +60,7 @@ def self.apply_building_occupants(runner, model, hpxml_bldg, hpxml_header, space occ.setName(Constants::ObjectTypeOccupants) occ.setSpace(spaces[HPXML::LocationConditionedSpace]) occ_def.setName(Constants::ObjectTypeOccupants) - occ_def.setNumberofPeople(num_occ) + occ_def.setNumberofPeople(n_occ) occ_def.setFractionRadiant(occ_rad) occ_def.setSensibleHeatFraction(occ_sens) occ_def.setMeanRadiantTemperatureCalculationType('ZoneAveraged') @@ -81,11 +81,13 @@ def self.apply_building_occupants(runner, model, hpxml_bldg, hpxml_header, space # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files # @return [nil] def self.apply_general_water_use(runner, model, hpxml_bldg, hpxml_header, spaces, schedules_file) + nbeds = hpxml_bldg.building_construction.number_of_bedrooms + n_occ = hpxml_bldg.building_occupancy.number_of_residents + unit_type = hpxml_bldg.building_construction.residential_facility_type general_water_use_usage_multiplier = hpxml_bldg.building_occupancy.general_water_use_usage_multiplier - nbeds_eq = hpxml_bldg.building_construction.additional_properties.equivalent_number_of_bedrooms if not hpxml_header.apply_ashrae140_assumptions - water_sens_btu, water_lat_btu = Defaults.get_water_use_internal_gains(nbeds_eq, general_water_use_usage_multiplier) + water_sens_btu, water_lat_btu = Defaults.get_water_use_internal_gains(nbeds, n_occ, unit_type, general_water_use_usage_multiplier) # Create schedule water_schedule = nil diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/lighting.rb b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/lighting.rb index 53a0dfec1f..551f48acf4 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/lighting.rb +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/lighting.rb @@ -17,6 +17,7 @@ def self.apply(runner, model, spaces, hpxml_bldg, hpxml_header, schedules_file) unit_multiplier = hpxml_bldg.building_construction.number_of_units cfa = hpxml_bldg.building_construction.conditioned_floor_area eri_version = hpxml_header.eri_calculation_version + n_occ = hpxml_bldg.building_occupancy.number_of_residents ltg_locns = [HPXML::LocationInterior, HPXML::LocationExterior, HPXML::LocationGarage] ltg_types = [HPXML::LightingTypeCFL, HPXML::LightingTypeLFL, HPXML::LightingTypeLED] @@ -39,7 +40,7 @@ def self.apply(runner, model, spaces, hpxml_bldg, hpxml_header, schedules_file) fractions[[HPXML::LocationInterior, HPXML::LightingTypeLFL]], fractions[[HPXML::LocationInterior, HPXML::LightingTypeLED]]) end - int_kwh = 0.0 if int_kwh.nil? + int_kwh = 0.0 if int_kwh.nil? || n_occ == 0 int_kwh *= lighting.interior_usage_multiplier unless lighting.interior_usage_multiplier.nil? # Calculate exterior lighting kWh/yr @@ -50,7 +51,7 @@ def self.apply(runner, model, spaces, hpxml_bldg, hpxml_header, schedules_file) fractions[[HPXML::LocationExterior, HPXML::LightingTypeLFL]], fractions[[HPXML::LocationExterior, HPXML::LightingTypeLED]]) end - ext_kwh = 0.0 if ext_kwh.nil? + ext_kwh = 0.0 if ext_kwh.nil? || n_occ == 0 ext_kwh *= lighting.exterior_usage_multiplier unless lighting.exterior_usage_multiplier.nil? ext_kwh *= unit_multiplier # Not in a thermal zone, so needs to be explicitly multiplied @@ -69,7 +70,7 @@ def self.apply(runner, model, spaces, hpxml_bldg, hpxml_header, schedules_file) fractions[[HPXML::LocationGarage, HPXML::LightingTypeLED]]) end end - grg_kwh = 0.0 if grg_kwh.nil? + grg_kwh = 0.0 if grg_kwh.nil? || n_occ == 0 grg_kwh *= lighting.garage_usage_multiplier unless lighting.garage_usage_multiplier.nil? # Add lighting to conditioned space diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/materials.rb b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/materials.rb index 19e7241b3a..484d79b4f2 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/materials.rb +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/materials.rb @@ -272,31 +272,34 @@ def self.Concrete(thick_in) def self.ExteriorFinishMaterial(type, thick_in = nil) if (type == HPXML::SidingTypeNone) || (!thick_in.nil? && thick_in <= 0) return - elsif [HPXML::SidingTypeAsbestos].include? type + end + + case type + when HPXML::SidingTypeAsbestos thick_in = 0.25 if thick_in.nil? return new(name: type, thick_in: thick_in, k_in: 4.20, rho: 118.6, cp: 0.24) - elsif [HPXML::SidingTypeBrick].include? type + when HPXML::SidingTypeBrick thick_in = 4.0 if thick_in.nil? return new(name: type, thick_in: thick_in, mat_base: BaseMaterial.Brick) - elsif [HPXML::SidingTypeCompositeShingle].include? type + when HPXML::SidingTypeCompositeShingle thick_in = 0.25 if thick_in.nil? return new(name: type, thick_in: thick_in, k_in: 1.128, rho: 70.0, cp: 0.35) - elsif [HPXML::SidingTypeFiberCement].include? type + when HPXML::SidingTypeFiberCement thick_in = 0.375 if thick_in.nil? return new(name: type, thick_in: thick_in, k_in: 1.79, rho: 21.7, cp: 0.24) - elsif [HPXML::SidingTypeMasonite].include? type # Masonite hardboard + when HPXML::SidingTypeMasonite # Masonite hardboard thick_in = 0.5 if thick_in.nil? return new(name: type, thick_in: thick_in, k_in: 0.69, rho: 46.8, cp: 0.39) - elsif [HPXML::SidingTypeStucco].include? type + when HPXML::SidingTypeStucco thick_in = 1.0 if thick_in.nil? return new(name: type, thick_in: thick_in, mat_base: BaseMaterial.Stucco) - elsif [HPXML::SidingTypeSyntheticStucco].include? type # EIFS + when HPXML::SidingTypeSyntheticStucco # EIFS thick_in = 1.0 if thick_in.nil? return new(name: type, thick_in: thick_in, mat_base: BaseMaterial.InsulationRigid) - elsif [HPXML::SidingTypeVinyl, HPXML::SidingTypeAluminum].include? type + when HPXML::SidingTypeVinyl, HPXML::SidingTypeAluminum thick_in = 0.375 if thick_in.nil? return new(name: type, thick_in: thick_in, mat_base: BaseMaterial.Vinyl) - elsif [HPXML::SidingTypeWood].include? type + when HPXML::SidingTypeWood thick_in = 1.0 if thick_in.nil? return new(name: type, thick_in: thick_in, k_in: 0.71, rho: 34.0, cp: 0.28) end @@ -310,25 +313,26 @@ def self.ExteriorFinishMaterial(type, thick_in = nil) # @param thick_in [TODO] TODO # @return [TODO] TODO def self.FoundationWallMaterial(type, thick_in) - if type == HPXML::FoundationWallTypeSolidConcrete + case type + when HPXML::FoundationWallTypeSolidConcrete return Material.Concrete(thick_in) - elsif type == HPXML::FoundationWallTypeDoubleBrick + when HPXML::FoundationWallTypeDoubleBrick return new(name: "#{type} #{thick_in} in.", thick_in: thick_in, mat_base: BaseMaterial.Brick, tAbs: 0.9) - elsif type == HPXML::FoundationWallTypeWood + when HPXML::FoundationWallTypeWood # Open wood cavity wall, so just assume 0.5" of sheathing return new(name: "#{type} #{thick_in} in.", thick_in: 0.5, mat_base: BaseMaterial.Wood, tAbs: 0.9) # Concrete block conductivity values below derived from Table 2 of # https://ncma.org/resource/rvalues-ufactors-of-single-wythe-concrete-masonry-walls/. Values # for 6-in thickness and 115 pcf, with interior/exterior films removed (R-0.68/R-0.17). - elsif type == HPXML::FoundationWallTypeConcreteBlockSolidCore + when HPXML::FoundationWallTypeConcreteBlockSolidCore return new(name: "#{type} #{thick_in} in.", thick_in: thick_in, k_in: 8.5, rho: 115.0, cp: 0.2, tAbs: 0.9) - elsif type == HPXML::FoundationWallTypeConcreteBlock + when HPXML::FoundationWallTypeConcreteBlock return new(name: "#{type} #{thick_in} in.", thick_in: thick_in, k_in: 5.0, rho: 45.0, cp: 0.2, tAbs: 0.9) - elsif type == HPXML::FoundationWallTypeConcreteBlockPerliteCore + when HPXML::FoundationWallTypeConcreteBlockPerliteCore return new(name: "#{type} #{thick_in} in.", thick_in: thick_in, k_in: 2.0, rho: 67.0, cp: 0.2, tAbs: 0.9) - elsif type == HPXML::FoundationWallTypeConcreteBlockFoamCore + when HPXML::FoundationWallTypeConcreteBlockFoamCore return new(name: "#{type} #{thick_in} in.", thick_in: thick_in, k_in: 1.8, rho: 67.0, cp: 0.2, tAbs: 0.9) - elsif type == HPXML::FoundationWallTypeConcreteBlockVermiculiteCore + when HPXML::FoundationWallTypeConcreteBlockVermiculiteCore return new(name: "#{type} #{thick_in} in.", thick_in: thick_in, k_in: 2.1, rho: 67.0, cp: 0.2, tAbs: 0.9) end @@ -345,11 +349,10 @@ def self.InteriorFinishMaterial(type, thick_in = nil) return else thick_in = 0.5 if thick_in.nil? - if [HPXML::InteriorFinishGypsumBoard, - HPXML::InteriorFinishGypsumCompositeBoard, - HPXML::InteriorFinishPlaster].include? type + case type + when HPXML::InteriorFinishGypsumBoard, HPXML::InteriorFinishGypsumCompositeBoard, HPXML::InteriorFinishPlaster return new(name: type, thick_in: thick_in, mat_base: BaseMaterial.Gypsum) - elsif [HPXML::InteriorFinishWood].include? type + when HPXML::InteriorFinishWood return new(name: type, thick_in: thick_in, mat_base: BaseMaterial.Wood) end end @@ -435,22 +438,23 @@ def self.RadiantBarrier(grade, is_attic_floor) # @param thick_in [TODO] TODO # @return [TODO] TODO def self.RoofMaterial(type, thick_in = nil) - if [HPXML::RoofTypeMetal].include? type + case type + when HPXML::RoofTypeMetal thick_in = 0.02 if thick_in.nil? return new(name: type, thick_in: thick_in, k_in: 346.9, rho: 487.0, cp: 0.11) - elsif [HPXML::RoofTypeAsphaltShingles, HPXML::RoofTypeWoodShingles, HPXML::RoofTypeShingles, HPXML::RoofTypeCool].include? type + when HPXML::RoofTypeAsphaltShingles, HPXML::RoofTypeWoodShingles, HPXML::RoofTypeShingles, HPXML::RoofTypeCool thick_in = 0.25 if thick_in.nil? return new(name: type, thick_in: thick_in, k_in: 1.128, rho: 70.0, cp: 0.35) - elsif [HPXML::RoofTypeConcrete].include? type + when HPXML::RoofTypeConcrete thick_in = 0.75 if thick_in.nil? return new(name: type, thick_in: thick_in, k_in: 7.63, rho: 131.1, cp: 0.199) - elsif [HPXML::RoofTypeClayTile].include? type + when HPXML::RoofTypeClayTile thick_in = 0.75 if thick_in.nil? return new(name: type, thick_in: thick_in, k_in: 5.83, rho: 118.6, cp: 0.191) - elsif [HPXML::RoofTypeEPS].include? type + when HPXML::RoofTypeEPS thick_in = 1.0 if thick_in.nil? return new(name: type, thick_in: thick_in, mat_base: BaseMaterial.InsulationRigid) - elsif [HPXML::RoofTypePlasticRubber].include? type + when HPXML::RoofTypePlasticRubber thick_in = 0.25 if thick_in.nil? return new(name: type, thick_in: thick_in, k_in: 2.78, rho: 110.8, cp: 0.36) end diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/misc_loads.rb b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/misc_loads.rb index 2e31b90403..53aa99f416 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/misc_loads.rb +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/misc_loads.rb @@ -12,14 +12,20 @@ module MiscLoads # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files # @return [nil] def self.apply_plug_loads(runner, model, spaces, hpxml_bldg, hpxml_header, schedules_file) + if hpxml_bldg.building_occupancy.number_of_residents == 0 && (not hpxml_header.apply_ashrae140_assumptions) + # Operational calculation w/ zero occupants, zero out energy use + return + end + hpxml_bldg.plug_loads.each do |plug_load| - if plug_load.plug_load_type == HPXML::PlugLoadTypeOther + case plug_load.plug_load_type + when HPXML::PlugLoadTypeOther obj_name = Constants::ObjectTypeMiscPlugLoads - elsif plug_load.plug_load_type == HPXML::PlugLoadTypeTelevision + when HPXML::PlugLoadTypeTelevision obj_name = Constants::ObjectTypeMiscTelevision - elsif plug_load.plug_load_type == HPXML::PlugLoadTypeElectricVehicleCharging + when HPXML::PlugLoadTypeElectricVehicleCharging obj_name = Constants::ObjectTypeMiscElectricVehicleCharging - elsif plug_load.plug_load_type == HPXML::PlugLoadTypeWellPump + when HPXML::PlugLoadTypeWellPump obj_name = Constants::ObjectTypeMiscWellPump end if obj_name.nil? @@ -53,13 +59,14 @@ def self.apply_plug_load(runner, model, plug_load, obj_name, spaces, schedules_f # Create schedule sch = nil - if plug_load.plug_load_type == HPXML::PlugLoadTypeOther + case plug_load.plug_load_type + when HPXML::PlugLoadTypeOther col_name = SchedulesFile::Columns[:PlugLoadsOther].name - elsif plug_load.plug_load_type == HPXML::PlugLoadTypeTelevision + when HPXML::PlugLoadTypeTelevision col_name = SchedulesFile::Columns[:PlugLoadsTV].name - elsif plug_load.plug_load_type == HPXML::PlugLoadTypeElectricVehicleCharging + when HPXML::PlugLoadTypeElectricVehicleCharging col_name = SchedulesFile::Columns[:PlugLoadsVehicle].name - elsif plug_load.plug_load_type == HPXML::PlugLoadTypeWellPump + when HPXML::PlugLoadTypeWellPump col_name = SchedulesFile::Columns[:PlugLoadsWellPump].name end if not schedules_file.nil? @@ -111,11 +118,12 @@ def self.apply_plug_load(runner, model, plug_load, obj_name, spaces, schedules_f # @return [nil] def self.apply_fuel_loads(runner, model, spaces, hpxml_bldg, hpxml_header, schedules_file) hpxml_bldg.fuel_loads.each do |fuel_load| - if fuel_load.fuel_load_type == HPXML::FuelLoadTypeGrill + case fuel_load.fuel_load_type + when HPXML::FuelLoadTypeGrill obj_name = Constants::ObjectTypeMiscGrill - elsif fuel_load.fuel_load_type == HPXML::FuelLoadTypeLighting + when HPXML::FuelLoadTypeLighting obj_name = Constants::ObjectTypeMiscLighting - elsif fuel_load.fuel_load_type == HPXML::FuelLoadTypeFireplace + when HPXML::FuelLoadTypeFireplace obj_name = Constants::ObjectTypeMiscFireplace end if obj_name.nil? @@ -148,11 +156,12 @@ def self.apply_fuel_load(runner, model, fuel_load, obj_name, spaces, schedules_f # Create schedule sch = nil - if fuel_load.fuel_load_type == HPXML::FuelLoadTypeGrill + case fuel_load.fuel_load_type + when HPXML::FuelLoadTypeGrill col_name = SchedulesFile::Columns[:FuelLoadsGrill].name - elsif fuel_load.fuel_load_type == HPXML::FuelLoadTypeLighting + when HPXML::FuelLoadTypeLighting col_name = SchedulesFile::Columns[:FuelLoadsLighting].name - elsif fuel_load.fuel_load_type == HPXML::FuelLoadTypeFireplace + when HPXML::FuelLoadTypeFireplace col_name = SchedulesFile::Columns[:FuelLoadsFireplace].name end if not schedules_file.nil? diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/model.rb b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/model.rb index a30aacbbc5..5e2ba31032 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/model.rb +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/model.rb @@ -353,6 +353,35 @@ def self.add_fan_system_model(model, name:, end_use:, power_per_flow:, max_flow_ return fan end + # Adds a PlantLoop object to the OpenStudio model. + # + # @param model [OpenStudio::Model::Model] OpenStudio Model object + # @param name [String] Name for the OpenStudio object + # @param fluid_type [String] Fluid type (Eplus::FluidXXX) + # @param glycol_concentration [Integer] Percent glycol concentration, only used if fluid is propylene glycol + # @param volume [Double] Volume of the entire loop, both demand and supply side (m^3) + # @param min_temp [Double] Minimum loop temperature (C) + # @param max_temp [Double] Maximum loop temperature (C) + # @param max_flow_rate [Double] Maximum loop flow rate (m^3/s) + # @return [OpenStudio::Model::PlantLoop] The model object + def self.add_plant_loop(model, name:, fluid_type: EPlus::FluidWater, glycol_concentration: 50, volume: nil, min_temp: nil, max_temp: nil, max_flow_rate: nil) + plant_loop = OpenStudio::Model::PlantLoop.new(model) + plant_loop.setName(name) + plant_loop.setFluidType(fluid_type) + if fluid_type == EPlus::FluidPropyleneGlycol + plant_loop.setGlycolConcentration(glycol_concentration) + end + plant_loop.setMinimumLoopTemperature(min_temp) unless min_temp.nil? + plant_loop.setMaximumLoopTemperature(max_temp) unless max_temp.nil? + plant_loop.setMaximumLoopFlowRate(max_flow_rate) unless max_flow_rate.nil? + if not volume.nil? + plant_loop.setPlantLoopVolume(volume) + else + plant_loop.autocalculatePlantLoopVolume() + end + return plant_loop + end + # Adds a PumpVariableSpeed object to the OpenStudio model. # # @param model [OpenStudio::Model::Model] OpenStudio Model object @@ -859,6 +888,8 @@ def self.reset(model, runner) # @return [nil] def self.merge_unit_models(model, hpxml_osm_map) # Map of OpenStudio IDD objects => OSM class names + # Note: ZoneCapacitanceMultiplierResearchSpecial is not actually unique, but we don't assign it to + # individual thermal zones, so we'll treat it as unique here. unique_object_map = { 'OS:ConvergenceLimits' => 'ConvergenceLimits', 'OS:Foundation:Kiva:Settings' => 'FoundationKivaSettings', 'OS:OutputControl:Files' => 'OutputControlFiles', @@ -875,7 +906,8 @@ def self.merge_unit_models(model, hpxml_osm_map) 'OS:Site:WaterMainsTemperature' => 'SiteWaterMainsTemperature', 'OS:SurfaceConvectionAlgorithm:Inside' => 'InsideSurfaceConvectionAlgorithm', 'OS:SurfaceConvectionAlgorithm:Outside' => 'OutsideSurfaceConvectionAlgorithm', - 'OS:Timestep' => 'Timestep' } + 'OS:Timestep' => 'Timestep', + 'OS:ZoneCapacitanceMultiplier:ResearchSpecial' => 'ZoneCapacitanceMultiplierResearchSpecial' } # Handle unique objects first: Grab one from the first model we find the # object on (may not be the first unit). diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/pv.rb b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/pv.rb index 5a9f60a2b1..08822275c7 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/pv.rb +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/pv.rb @@ -64,22 +64,28 @@ def self.apply_pv_system(model, hpxml_bldg, pv_system) gpvwatts.setSystemLosses(pv_system.system_losses_fraction) gpvwatts.setTiltAngle(pv_system.array_tilt) gpvwatts.setAzimuthAngle(pv_system.array_azimuth) - if (pv_system.tracking == HPXML::PVTrackingTypeFixed) && (pv_system.location == HPXML::LocationRoof) - gpvwatts.setArrayType('FixedRoofMounted') - elsif (pv_system.tracking == HPXML::PVTrackingTypeFixed) && (pv_system.location == HPXML::LocationGround) - gpvwatts.setArrayType('FixedOpenRack') - elsif pv_system.tracking == HPXML::PVTrackingType1Axis + + case pv_system.tracking + when HPXML::PVTrackingTypeFixed + if pv_system.location == HPXML::LocationRoof + gpvwatts.setArrayType('FixedRoofMounted') + elsif pv_system.location == HPXML::LocationGround + gpvwatts.setArrayType('FixedOpenRack') + end + when HPXML::PVTrackingType1Axis gpvwatts.setArrayType('OneAxis') - elsif pv_system.tracking == HPXML::PVTrackingType1AxisBacktracked + when HPXML::PVTrackingType1AxisBacktracked gpvwatts.setArrayType('OneAxisBacktracking') - elsif pv_system.tracking == HPXML::PVTrackingType2Axis + when HPXML::PVTrackingType2Axis gpvwatts.setArrayType('TwoAxis') end - if pv_system.module_type == HPXML::PVModuleTypeStandard + + case pv_system.module_type + when HPXML::PVModuleTypeStandard gpvwatts.setModuleType('Standard') - elsif pv_system.module_type == HPXML::PVModuleTypePremium + when HPXML::PVModuleTypePremium gpvwatts.setModuleType('Premium') - elsif pv_system.module_type == HPXML::PVModuleTypeThinFilm + when HPXML::PVModuleTypeThinFilm gpvwatts.setModuleType('ThinFilm') end diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedules.rb b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedules.rb index f5ee36e47c..0da62c5f8a 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedules.rb +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedules.rb @@ -1434,17 +1434,19 @@ def set_unavailable_periods(runner, unavailable_periods) @tmp_schedules.keys.each do |schedule_name| next if column_names.include? schedule_name - schedule_name2 = schedule_name - if [SchedulesFile::Columns[:HotWaterDishwasher].name].include?(schedule_name) + case schedule_name + when SchedulesFile::Columns[:HotWaterDishwasher].name schedule_name2 = SchedulesFile::Columns[:Dishwasher].name - elsif [SchedulesFile::Columns[:HotWaterClothesWasher].name].include?(schedule_name) + when SchedulesFile::Columns[:HotWaterClothesWasher].name schedule_name2 = SchedulesFile::Columns[:ClothesWasher].name - elsif [SchedulesFile::Columns[:HeatingSetpoint].name].include?(schedule_name) + when SchedulesFile::Columns[:HeatingSetpoint].name schedule_name2 = SchedulesFile::Columns[:SpaceHeating].name - elsif [SchedulesFile::Columns[:CoolingSetpoint].name].include?(schedule_name) + when SchedulesFile::Columns[:CoolingSetpoint].name schedule_name2 = SchedulesFile::Columns[:SpaceCooling].name - elsif [SchedulesFile::Columns[:WaterHeaterSetpoint].name].include?(schedule_name) + when SchedulesFile::Columns[:WaterHeaterSetpoint].name schedule_name2 = SchedulesFile::Columns[:WaterHeater].name + else + schedule_name2 = schedule_name end # Skip those unaffected diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/utility_bills.rb b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/utility_bills.rb index e9fba1f567..72b851bc8d 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/utility_bills.rb +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/utility_bills.rb @@ -36,17 +36,19 @@ def self.get_rates_from_eia_data(runner, state_code, fuel_type, fixed_charge, ma end if not marginal_rate.nil? - if [HPXML::FuelTypeElectricity, HPXML::FuelTypeNaturalGas].include? fuel_type + case fuel_type + when HPXML::FuelTypeElectricity, HPXML::FuelTypeNaturalGas # Calculate average rate from user-specified marginal rate, user-specified fixed charge, and EIA data average_rate = marginal_rate_to_average_rate(marginal_rate, fixed_charge, household_consumption) - elsif [HPXML::FuelTypeOil, HPXML::FuelTypePropane, HPXML::FuelTypeCoal, HPXML::FuelTypeWoodCord, HPXML::FuelTypeWoodPellets].include? fuel_type + when HPXML::FuelTypeOil, HPXML::FuelTypePropane, HPXML::FuelTypeCoal, HPXML::FuelTypeWoodCord, HPXML::FuelTypeWoodPellets # Do nothing end else - if [HPXML::FuelTypeElectricity, HPXML::FuelTypeNaturalGas].include? fuel_type + case fuel_type + when HPXML::FuelTypeElectricity, HPXML::FuelTypeNaturalGas average_rate = get_eia_seds_rate(runner, state_code, fuel_type) marginal_rate = average_rate_to_marginal_rate(average_rate, fixed_charge, household_consumption) - elsif [HPXML::FuelTypeOil, HPXML::FuelTypePropane, HPXML::FuelTypeCoal, HPXML::FuelTypeWoodCord, HPXML::FuelTypeWoodPellets].include? fuel_type + when HPXML::FuelTypeOil, HPXML::FuelTypePropane, HPXML::FuelTypeCoal, HPXML::FuelTypeWoodCord, HPXML::FuelTypeWoodPellets marginal_rate = get_eia_seds_rate(runner, state_code, fuel_type) end end diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/version.rb b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/version.rb index 03fc5fb1a5..b56875f660 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/version.rb +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/version.rb @@ -2,7 +2,7 @@ # Collection of methods related to software versions. module Version - OS_HPXML_Version = '1.9.0' # Version of the OS-HPXML workflow + OS_HPXML_Version = '1.10.0' # Version of the OS-HPXML workflow OS_Version = '3.9.0' # Required version of OpenStudio (can be 'X.X' or 'X.X.X') HPXML_Version = '4.0' # HPXML schemaVersion diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/waterheater.rb b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/waterheater.rb index 003b113a8f..3d9ec8a762 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/waterheater.rb +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/waterheater.rb @@ -4,7 +4,7 @@ module Waterheater DefaultTankHeight = 4.0 # ft, assumption from BEopt - # TODO + # Adds any water heaters and appliances to the OpenStudio Model. # # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings # @param model [OpenStudio::Model::Model] OpenStudio Model object @@ -19,13 +19,14 @@ def self.apply_dhw_appliances(runner, model, weather, spaces, hpxml_bldg, hpxml_ plantloop_map = {} hpxml_bldg.water_heating_systems.each do |dhw_system| - if dhw_system.water_heater_type == HPXML::WaterHeaterTypeStorage + case dhw_system.water_heater_type + when HPXML::WaterHeaterTypeStorage apply_tank(model, runner, spaces, hpxml_bldg, hpxml_header, dhw_system, schedules_file, unavailable_periods, plantloop_map) - elsif dhw_system.water_heater_type == HPXML::WaterHeaterTypeTankless + when HPXML::WaterHeaterTypeTankless apply_tankless(model, runner, spaces, hpxml_bldg, hpxml_header, dhw_system, schedules_file, unavailable_periods, plantloop_map) - elsif dhw_system.water_heater_type == HPXML::WaterHeaterTypeHeatPump - apply_heatpump(model, runner, spaces, hpxml_bldg, hpxml_header, dhw_system, schedules_file, unavailable_periods, plantloop_map) - elsif [HPXML::WaterHeaterTypeCombiStorage, HPXML::WaterHeaterTypeCombiTankless].include? dhw_system.water_heater_type + when HPXML::WaterHeaterTypeHeatPump + apply_hpwh(model, runner, spaces, hpxml_bldg, hpxml_header, dhw_system, schedules_file, unavailable_periods, plantloop_map) + when HPXML::WaterHeaterTypeCombiStorage, HPXML::WaterHeaterTypeCombiTankless apply_combi(model, runner, spaces, hpxml_bldg, hpxml_header, dhw_system, schedules_file, unavailable_periods, plantloop_map) else fail "Unhandled water heater (#{dhw_system.water_heater_type})." @@ -35,12 +36,10 @@ def self.apply_dhw_appliances(runner, model, weather, spaces, hpxml_bldg, hpxml_ HotWaterAndAppliances.apply(runner, model, weather, spaces, hpxml_bldg, hpxml_header, schedules_file, plantloop_map) apply_solar_thermal(model, spaces, hpxml_bldg, plantloop_map) - - # Add combi-system EMS program with water use equipment information apply_combi_system_EMS(model, hpxml_bldg.water_heating_systems, plantloop_map) end - # TODO + # Adds a conventional storage tank water heater to the OpenStudio model. # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings @@ -57,33 +56,33 @@ def self.apply_tank(model, runner, spaces, hpxml_bldg, hpxml_header, water_heati unit_multiplier = hpxml_bldg.building_construction.number_of_units solar_fraction = get_water_heater_solar_fraction(water_heating_system, hpxml_bldg) t_set_c = get_t_set_c(water_heating_system.temperature, water_heating_system.water_heater_type) - loop = create_new_loop(model, t_set_c, hpxml_header.eri_calculation_version, unit_multiplier) + plant_loop = add_plant_loop(model, t_set_c, hpxml_header.eri_calculation_version, unit_multiplier) act_vol = calc_storage_tank_actual_vol(water_heating_system.tank_volume, water_heating_system.fuel_type) - u, ua, eta_c = calc_tank_UA(act_vol, water_heating_system, solar_fraction, hpxml_bldg.building_construction.number_of_bedrooms) - new_heater = create_new_heater(name: Constants::ObjectTypeWaterHeater, - water_heating_system: water_heating_system, - act_vol: act_vol, - t_set_c: t_set_c, - loc_space: loc_space, - loc_schedule: loc_schedule, - model: model, - runner: runner, - u: u, - ua: ua, - eta_c: eta_c, - schedules_file: schedules_file, - unavailable_periods: unavailable_periods, - unit_multiplier: unit_multiplier) - loop.addSupplyBranchForComponent(new_heater) - - add_ec_adj(model, hpxml_bldg, new_heater, loc_space, water_heating_system, unit_multiplier) - add_desuperheater(model, runner, water_heating_system, new_heater, loc_space, loc_schedule, loop, unit_multiplier) - - plantloop_map[water_heating_system.id] = loop + u, ua, eta_c = disaggregate_tank_losses_and_burner_efficiency(act_vol, water_heating_system, solar_fraction, hpxml_bldg.building_construction.number_of_bedrooms) + water_heater = apply_water_heater(name: Constants::ObjectTypeWaterHeater, + water_heating_system: water_heating_system, + act_vol: act_vol, + t_set_c: t_set_c, + loc_space: loc_space, + loc_schedule: loc_schedule, + model: model, + runner: runner, + u: u, + ua: ua, + eta_c: eta_c, + schedules_file: schedules_file, + unavailable_periods: unavailable_periods, + unit_multiplier: unit_multiplier) + plant_loop.addSupplyBranchForComponent(water_heater) + + apply_ec_adj_program(model, hpxml_bldg, water_heater, loc_space, water_heating_system, unit_multiplier) + apply_desuperheater(model, runner, water_heating_system, water_heater, loc_space, loc_schedule, plant_loop, unit_multiplier) + + plantloop_map[water_heating_system.id] = plant_loop end - # TODO + # Adds a tankless water heater to the OpenStudio model. # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings @@ -101,33 +100,33 @@ def self.apply_tankless(model, runner, spaces, hpxml_bldg, hpxml_header, water_h water_heating_system.heating_capacity = 100000000000.0 * unit_multiplier solar_fraction = get_water_heater_solar_fraction(water_heating_system, hpxml_bldg) t_set_c = get_t_set_c(water_heating_system.temperature, water_heating_system.water_heater_type) - loop = create_new_loop(model, t_set_c, hpxml_header.eri_calculation_version, unit_multiplier) + plant_loop = add_plant_loop(model, t_set_c, hpxml_header.eri_calculation_version, unit_multiplier) act_vol = 1.0 * unit_multiplier - _u, ua, eta_c = calc_tank_UA(act_vol, water_heating_system, solar_fraction, hpxml_bldg.building_construction.number_of_bedrooms) - new_heater = create_new_heater(name: Constants::ObjectTypeWaterHeater, - water_heating_system: water_heating_system, - act_vol: act_vol, - t_set_c: t_set_c, - loc_space: loc_space, - loc_schedule: loc_schedule, - model: model, - runner: runner, - ua: ua, - eta_c: eta_c, - schedules_file: schedules_file, - unavailable_periods: unavailable_periods, - unit_multiplier: unit_multiplier) - - loop.addSupplyBranchForComponent(new_heater) - - add_ec_adj(model, hpxml_bldg, new_heater, loc_space, water_heating_system, unit_multiplier) - add_desuperheater(model, runner, water_heating_system, new_heater, loc_space, loc_schedule, loop, unit_multiplier) - - plantloop_map[water_heating_system.id] = loop + _u, ua, eta_c = disaggregate_tank_losses_and_burner_efficiency(act_vol, water_heating_system, solar_fraction, hpxml_bldg.building_construction.number_of_bedrooms) + water_heater = apply_water_heater(name: Constants::ObjectTypeWaterHeater, + water_heating_system: water_heating_system, + act_vol: act_vol, + t_set_c: t_set_c, + loc_space: loc_space, + loc_schedule: loc_schedule, + model: model, + runner: runner, + ua: ua, + eta_c: eta_c, + schedules_file: schedules_file, + unavailable_periods: unavailable_periods, + unit_multiplier: unit_multiplier) + + plant_loop.addSupplyBranchForComponent(water_heater) + + apply_ec_adj_program(model, hpxml_bldg, water_heater, loc_space, water_heating_system, unit_multiplier) + apply_desuperheater(model, runner, water_heating_system, water_heater, loc_space, loc_schedule, plant_loop, unit_multiplier) + + plantloop_map[water_heating_system.id] = plant_loop end - # TODO + # Adds a heat pump water heater to the OpenStudio model. # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings @@ -139,14 +138,13 @@ def self.apply_tankless(model, runner, spaces, hpxml_bldg, hpxml_header, water_h # @param unavailable_periods [HPXML::UnavailablePeriods] Object that defines periods for, e.g., power outages or vacancies # @param plantloop_map [Hash] Map of HPXML System ID => OpenStudio PlantLoop objects # @return [nil] - def self.apply_heatpump(model, runner, spaces, hpxml_bldg, hpxml_header, water_heating_system, schedules_file, unavailable_periods, plantloop_map) + def self.apply_hpwh(model, runner, spaces, hpxml_bldg, hpxml_header, water_heating_system, schedules_file, unavailable_periods, plantloop_map) loc_space, loc_schedule = Geometry.get_space_or_schedule_from_location(water_heating_system.location, model, spaces) unit_multiplier = hpxml_bldg.building_construction.number_of_units obj_name = Constants::ObjectTypeWaterHeater - conditioned_zone = spaces[HPXML::LocationConditionedSpace].thermalZone.get solar_fraction = get_water_heater_solar_fraction(water_heating_system, hpxml_bldg) t_set_c = get_t_set_c(water_heating_system.temperature, water_heating_system.water_heater_type) - loop = create_new_loop(model, t_set_c, hpxml_header.eri_calculation_version, unit_multiplier) + plant_loop = add_plant_loop(model, t_set_c, hpxml_header.eri_calculation_version, unit_multiplier) # Add in schedules for Tamb, RHamb, and the compressor hpwh_tamb = Model.add_schedule_constant( @@ -177,22 +175,22 @@ def self.apply_heatpump(model, runner, spaces, hpxml_bldg, hpxml_header, water_h limits: EPlus::ScheduleTypeLimitsTemperature ) - setpoint_schedule = nil + # To handle variable setpoints, need one schedule that gets sensed and a new schedule that gets actuated + sensed_setpoint_schedule = nil if not schedules_file.nil? - # To handle variable setpoints, need one schedule that gets sensed and a new schedule that gets actuated # Sensed schedule - setpoint_schedule = schedules_file.create_schedule_file(model, col_name: SchedulesFile::Columns[:WaterHeaterSetpoint].name, schedule_type_limits_name: EPlus::ScheduleTypeLimitsTemperature) - if not setpoint_schedule.nil? + sensed_setpoint_schedule = schedules_file.create_schedule_file(model, col_name: SchedulesFile::Columns[:WaterHeaterSetpoint].name, schedule_type_limits_name: EPlus::ScheduleTypeLimitsTemperature) + if not sensed_setpoint_schedule.nil? # Actuated schedule control_setpoint_schedule = ScheduleConstant.new(model, "#{obj_name} ControlSetpoint", 0.0, EPlus::ScheduleTypeLimitsTemperature, unavailable_periods: unavailable_periods) control_setpoint_schedule = control_setpoint_schedule.schedule end end - if setpoint_schedule.nil? - setpoint_schedule = ScheduleConstant.new(model, Constants::ObjectTypeWaterHeaterSetpoint, t_set_c, EPlus::ScheduleTypeLimitsTemperature, unavailable_periods: unavailable_periods) - setpoint_schedule = setpoint_schedule.schedule + if sensed_setpoint_schedule.nil? + sensed_setpoint_schedule = ScheduleConstant.new(model, Constants::ObjectTypeWaterHeaterSetpoint, t_set_c, EPlus::ScheduleTypeLimitsTemperature, unavailable_periods: unavailable_periods) + sensed_setpoint_schedule = sensed_setpoint_schedule.schedule - control_setpoint_schedule = setpoint_schedule + control_setpoint_schedule = sensed_setpoint_schedule else runner.registerWarning("Both '#{SchedulesFile::Columns[:WaterHeaterSetpoint].name}' schedule file and setpoint temperature provided; the latter will be ignored.") if !t_set_c.nil? end @@ -202,13 +200,13 @@ def self.apply_heatpump(model, runner, spaces, hpxml_bldg, hpxml_header, water_h max_temp = 120.0 # F # Coil:WaterHeating:AirToWaterHeatPump:Wrapped - coil = setup_hpwh_dxcoil(model, runner, water_heating_system, hpxml_bldg.elevation, obj_name, airflow_rate, unit_multiplier) + coil = apply_hpwh_dxcoil(model, runner, water_heating_system, hpxml_bldg.elevation, obj_name, airflow_rate, unit_multiplier) # WaterHeater:Stratified - tank = setup_hpwh_stratified_tank(model, water_heating_system, obj_name, solar_fraction, hpwh_tamb, bottom_element_sp, top_element_sp, unit_multiplier, hpxml_bldg.building_construction.number_of_bedrooms) - loop.addSupplyBranchForComponent(tank) + tank = apply_hpwh_stratified_tank(model, water_heating_system, obj_name, solar_fraction, hpwh_tamb, top_element_sp, bottom_element_sp, unit_multiplier, hpxml_bldg.building_construction.number_of_bedrooms) + plant_loop.addSupplyBranchForComponent(tank) - add_desuperheater(model, runner, water_heating_system, tank, loc_space, loc_schedule, loop, unit_multiplier) + apply_desuperheater(model, runner, water_heating_system, tank, loc_space, loc_schedule, plant_loop, unit_multiplier) # Fan:SystemModel fan_power = 0.0462 # W/cfm, Based on 1st gen AO Smith HPWH, could be updated but pretty minor impact @@ -223,30 +221,33 @@ def self.apply_heatpump(model, runner, spaces, hpxml_bldg, hpxml_header, water_h fan.additionalProperties.setFeature('ObjectType', Constants::ObjectTypeWaterHeater) # Used by reporting measure # WaterHeater:HeatPump:WrappedCondenser - hpwh = setup_hpwh_wrapped_condenser(model, obj_name, coil, tank, fan, airflow_rate, hpwh_tamb, hpwh_rhamb, min_temp, max_temp, control_setpoint_schedule, unit_multiplier) + hpwh = apply_hpwh_wrapped_condenser(model, obj_name, coil, tank, fan, airflow_rate, hpwh_tamb, hpwh_rhamb, min_temp, max_temp, control_setpoint_schedule, unit_multiplier) # Amb temp & RH sensors, temp sensor shared across programs - amb_temp_sensor, amb_rh_sensors = get_loc_temp_rh_sensors(model, obj_name, loc_space, loc_schedule, conditioned_zone) - hpwh_inlet_air_program = add_hpwh_inlet_air_and_zone_heat_gain_program(model, obj_name, loc_space, hpwh_tamb, hpwh_rhamb, tank, coil, fan, amb_temp_sensor, amb_rh_sensors, unit_multiplier) + amb_temp_sensor, amb_rh_sensors = apply_hpwh_loc_temp_rh_sensors(model, obj_name, loc_space, loc_schedule, spaces) + hpwh_zone_heat_gain_program = apply_hpwh_zone_heat_gain_program(model, obj_name, loc_space, hpwh_tamb, hpwh_rhamb, tank, coil, fan, amb_temp_sensor, amb_rh_sensors, unit_multiplier) # EMS for the HPWH control logic - op_mode = water_heating_system.operating_mode - hpwh_ctrl_program = add_hpwh_control_program(model, runner, obj_name, amb_temp_sensor, top_element_sp, bottom_element_sp, min_temp, max_temp, op_mode, setpoint_schedule, control_setpoint_schedule, schedules_file) + hpwh_ctrl_program = apply_hpwh_control_program(model, runner, obj_name, water_heating_system, amb_temp_sensor, top_element_sp, bottom_element_sp, min_temp, max_temp, sensed_setpoint_schedule, control_setpoint_schedule, schedules_file) # ProgramCallingManagers Model.add_ems_program_calling_manager( model, name: "#{obj_name} ProgramManager", calling_point: 'InsideHVACSystemIterationLoop', - ems_programs: [hpwh_ctrl_program, hpwh_inlet_air_program] + ems_programs: [hpwh_ctrl_program, hpwh_zone_heat_gain_program] ) - add_ec_adj(model, hpxml_bldg, hpwh, loc_space, water_heating_system, unit_multiplier) + apply_ec_adj_program(model, hpxml_bldg, hpwh, loc_space, water_heating_system, unit_multiplier) - plantloop_map[water_heating_system.id] = loop + plantloop_map[water_heating_system.id] = plant_loop end - # TODO + # Adds a combination boiler water heater to the OpenStudio model. + # + # Note that we model two separate boilers (one for just space heating and one for just water heating). + # This makes the code much simpler and makes the EnergyPlus results more robust. + # # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings @@ -277,35 +278,35 @@ def self.apply_combi(model, runner, spaces, hpxml_bldg, hpxml_header, water_heat act_vol = calc_storage_tank_actual_vol(water_heating_system.tank_volume, nil) a_side = calc_tank_areas(act_vol)[1] - ua = calc_indirect_ua_with_standbyloss(act_vol, water_heating_system, a_side, solar_fraction, hpxml_bldg.building_construction.number_of_bedrooms) + ua = calc_combi_tank_losses(act_vol, water_heating_system, a_side, solar_fraction, hpxml_bldg.building_construction.number_of_bedrooms) else ua = 0.0 act_vol = 1.0 end t_set_c = get_t_set_c(water_heating_system.temperature, water_heating_system.water_heater_type) - loop = create_new_loop(model, t_set_c, hpxml_header.eri_calculation_version, unit_multiplier) + plant_loop = add_plant_loop(model, t_set_c, hpxml_header.eri_calculation_version, unit_multiplier) # Create water heater - new_heater = create_new_heater(name: obj_name_combi, - water_heating_system: water_heating_system, - act_vol: act_vol, - t_set_c: t_set_c, - loc_space: loc_space, - loc_schedule: loc_schedule, - model: model, - runner: runner, - ua: ua, - is_combi: true, - schedules_file: schedules_file, - unavailable_periods: unavailable_periods, - unit_multiplier: unit_multiplier) - new_heater.setSourceSideDesignFlowRate(100 * unit_multiplier) # set one large number, override by EMS + water_heater = apply_water_heater(name: obj_name_combi, + water_heating_system: water_heating_system, + act_vol: act_vol, + t_set_c: t_set_c, + loc_space: loc_space, + loc_schedule: loc_schedule, + model: model, + runner: runner, + ua: ua, + is_combi: true, + schedules_file: schedules_file, + unavailable_periods: unavailable_periods, + unit_multiplier: unit_multiplier) + water_heater.setSourceSideDesignFlowRate(100 * unit_multiplier) # set one large number, override by EMS # Create alternate setpoint schedule for source side flow request - alternate_stp_sch = new_heater.setpointTemperatureSchedule.get.clone(model).to_Schedule.get + alternate_stp_sch = water_heater.setpointTemperatureSchedule.get.clone(model).to_Schedule.get alternate_stp_sch.setName("#{obj_name_combi} Alt Spt") - new_heater.setIndirectAlternateSetpointTemperatureSchedule(alternate_stp_sch) + water_heater.setIndirectAlternateSetpointTemperatureSchedule(alternate_stp_sch) # Create setpoint schedule to specify source side temperature # tank source side inlet temperature, degree C @@ -323,28 +324,31 @@ def self.apply_combi(model, runner, spaces, hpxml_bldg, hpxml_header, water_heat # change loop equipment operation scheme to heating load scheme_dhw = OpenStudio::Model::PlantEquipmentOperationHeatingLoad.new(model) - scheme_dhw.addEquipment(1000000000, new_heater) - loop.setPrimaryPlantEquipmentOperationScheme(scheme_dhw) + scheme_dhw.addEquipment(1000000000, water_heater) + plant_loop.setPrimaryPlantEquipmentOperationScheme(scheme_dhw) # Add dhw boiler to the load distribution scheme scheme = OpenStudio::Model::PlantEquipmentOperationHeatingLoad.new(model) scheme.addEquipment(1000000000, boiler) boiler_plant_loop.setPrimaryPlantEquipmentOperationScheme(scheme) - boiler_plant_loop.addDemandBranchForComponent(new_heater) + boiler_plant_loop.addDemandBranchForComponent(water_heater) boiler_plant_loop.setPlantLoopVolume(0.001 * unit_multiplier) # Cannot be auto-calculated because of large default tank source side mfr(set to be overwritten by EMS) - loop.addSupplyBranchForComponent(new_heater) + plant_loop.addSupplyBranchForComponent(water_heater) - add_ec_adj(model, hpxml_bldg, new_heater, loc_space, water_heating_system, unit_multiplier, boiler) + apply_ec_adj_program(model, hpxml_bldg, water_heater, loc_space, water_heating_system, unit_multiplier, boiler) - plantloop_map[water_heating_system.id] = loop + plantloop_map[water_heating_system.id] = plant_loop end - # TODO + # Calculates the water heating energy consumption adjustment factor (EC_adj) due to the effectiveness of + # the hot water distribution system. + # + # Source: ANSI/RESNET/ICC 301 # # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param water_heating_system [HPXML::WaterHeatingSystem] The HPXML water heating system of interest - # @return [TODO] TODO + # @return [Double] Hot water energy consumption multiplier def self.get_dist_energy_consumption_adjustment(hpxml_bldg, water_heating_system) if water_heating_system.fraction_dhw_load_served <= 0 # No fixtures; not accounting for distribution system @@ -358,9 +362,7 @@ def self.get_dist_energy_consumption_adjustment(hpxml_bldg, water_heating_system cfa = hpxml_bldg.building_construction.conditioned_floor_area ncfl = hpxml_bldg.building_construction.number_of_conditioned_floors - # ANSI/RESNET 301-2014 Addendum A-2015 - # Amendment on Domestic Hot Water (DHW) Systems - # Eq. 4.2-16 + # ANSI/RESNET/ICC 301-2022 Eq. 4.2-44 ew_fact = get_dist_energy_waste_factor(hot_water_distribution) o_frac = 0.25 # fraction of hot water waste from standard operating conditions oew_fact = ew_fact * o_frac # standard operating condition portion of hot water energy waste @@ -377,35 +379,35 @@ def self.get_dist_energy_consumption_adjustment(hpxml_bldg, water_heating_system return (e_waste + 128.0) / 160.0 end - # TODO + # Retrieves the hot water distribution system relative annual energy waste factors. + # + # Source: ANSI/RESNET/ICC 301 # - # @param hot_water_distribution [TODO] TODO - # @return [TODO] TODO + # @param hot_water_distribution [HPXML::HotWaterDistribution] The HPXML hot water distribution system of interest + # @return [Double] Energy waste factor def self.get_dist_energy_waste_factor(hot_water_distribution) - # ANSI/RESNET 301-2014 Addendum A-2015 - # Amendment on Domestic Hot Water (DHW) Systems - # Table 4.2.2.5.2.11(6) Hot water distribution system relative annual energy waste factors + # ANSI/RESNET/ICC 301-2022 Table 4.2.2.7.2.11(6) if hot_water_distribution.system_type == HPXML::DHWDistTypeRecirc - if (hot_water_distribution.recirculation_control_type == HPXML::DHWRecircControlTypeNone) || - (hot_water_distribution.recirculation_control_type == HPXML::DHWRecircControlTypeTimer) + case hot_water_distribution.recirculation_control_type + when HPXML::DHWRecircControlTypeNone, HPXML::DHWRecircControlTypeTimer if hot_water_distribution.pipe_r_value < 3.0 return 500.0 else return 250.0 end - elsif hot_water_distribution.recirculation_control_type == HPXML::DHWRecircControlTypeTemperature + when HPXML::DHWRecircControlTypeTemperature if hot_water_distribution.pipe_r_value < 3.0 return 375.0 else return 187.5 end - elsif hot_water_distribution.recirculation_control_type == HPXML::DHWRecircControlTypeSensor + when HPXML::DHWRecircControlTypeSensor if hot_water_distribution.pipe_r_value < 3.0 return 64.8 else return 43.2 end - elsif hot_water_distribution.recirculation_control_type == HPXML::DHWRecircControlTypeManual + when HPXML::DHWRecircControlTypeManual if hot_water_distribution.pipe_r_value < 3.0 return 43.2 else @@ -422,7 +424,9 @@ def self.get_dist_energy_waste_factor(hot_water_distribution) fail 'Unexpected hot water distribution system.' end - # TODO + # Adds an EMS program to control the boiler operation based on domestic hot water demand. + # The program modulates the source side mass flow rate to achieve better control and accuracy + # compared to not having the EMS program. See https://github.com/NREL/OpenStudio-HPXML/pull/225. # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param water_heating_systems [Array] The HPXML water heaters of interest @@ -594,7 +598,7 @@ def self.apply_combi_system_EMS(model, water_heating_systems, plantloop_map) end end - # TODO + # Adds an HPXML Solar Thermal System to the OpenStudio model. # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param spaces [Hash] Map of HPXML locations => OpenStudio Space objects @@ -620,21 +624,23 @@ def self.apply_solar_thermal(model, spaces, hpxml_bldg, plantloop_map) obj_name = Constants::ObjectTypeSolarHotWater - if [HPXML::SolarThermalCollectorTypeEvacuatedTube].include? solar_thermal_system.collector_type + case solar_thermal_system.collector_type + when HPXML::SolarThermalCollectorTypeEvacuatedTube iam_coeff2 = 0.3023 # IAM coeff1=1 by definition, values based on a system listed by SRCC with values close to the average iam_coeff3 = -0.3057 - elsif [HPXML::SolarThermalCollectorTypeSingleGlazing, HPXML::SolarThermalCollectorTypeDoubleGlazing].include? solar_thermal_system.collector_type + when HPXML::SolarThermalCollectorTypeSingleGlazing, HPXML::SolarThermalCollectorTypeDoubleGlazing iam_coeff2 = 0.1 iam_coeff3 = 0 - elsif [HPXML::SolarThermalCollectorTypeICS].include? solar_thermal_system.collector_type + when HPXML::SolarThermalCollectorTypeICS iam_coeff2 = 0.1 iam_coeff3 = 0 end - if [HPXML::SolarThermalLoopTypeIndirect].include? solar_thermal_system.collector_loop_type + case solar_thermal_system.collector_loop_type + when HPXML::SolarThermalLoopTypeIndirect fluid_type = EPlus::FluidPropyleneGlycol heat_ex_eff = 0.7 - elsif [HPXML::SolarThermalLoopTypeDirect, HPXML::SolarThermalLoopTypeThermosyphon].include? solar_thermal_system.collector_loop_type + when HPXML::SolarThermalLoopTypeDirect, HPXML::SolarThermalLoopTypeThermosyphon fluid_type = EPlus::FluidWater heat_ex_eff = 1.0 end @@ -680,19 +686,11 @@ def self.apply_solar_thermal(model, spaces, hpxml_bldg, plantloop_map) end end - plant_loop = OpenStudio::Model::PlantLoop.new(model) - plant_loop.setName('solar hot water loop') - if fluid_type == EPlus::FluidWater - plant_loop.setFluidType(EPlus::FluidWater) - else - plant_loop.setFluidType(EPlus::FluidPropyleneGlycol) - plant_loop.setGlycolConcentration(50) - end - plant_loop.setMaximumLoopTemperature(100) - plant_loop.setMinimumLoopTemperature(0) - plant_loop.setMinimumLoopFlowRate(0) - plant_loop.setLoadDistributionScheme('Optimal') - plant_loop.setPlantEquipmentOperationHeatingLoadSchedule(model.alwaysOnDiscreteSchedule) + plant_loop = Model.add_plant_loop( + model, + name: 'solar hot water loop', + fluid_type: fluid_type + ) sizing_plant = plant_loop.sizingPlant sizing_plant.setLoopType('Heating') @@ -824,7 +822,7 @@ def self.apply_solar_thermal(model, spaces, hpxml_bldg, plantloop_map) storage_tank.setHeaterFuelType(EPlus::FuelTypeElectricity) storage_tank.setHeaterThermalEfficiency(1) storage_tank.ambientTemperatureSchedule.get.remove - set_wh_ambient(loc_space, loc_schedule, storage_tank) + apply_ambient_temperature(loc_space, loc_schedule, storage_tank) storage_tank.setSkinLossFractiontoZone(1.0 / unit_multiplier) # Tank losses are multiplied by E+ zone multiplier, so need to compensate here storage_tank.setOffCycleFlueLossFractiontoZone(1.0 / unit_multiplier) storage_tank.setUseSideEffectiveness(1) @@ -838,7 +836,7 @@ def self.apply_solar_thermal(model, spaces, hpxml_bldg, plantloop_map) storage_tank.setOnCycleParasiticFuelConsumptionRate(0) storage_tank.setOffCycleParasiticFuelConsumptionRate(0) storage_tank.setUseSideDesignFlowRate(UnitConversions.convert(storage_volume, 'gal', 'm^3') / 60.1) # Sized to ensure that E+ never autosizes the design flow rate to be larger than the tank volume getting drawn out in a hour (60 minutes) - set_stratified_tank_ua(storage_tank, u_tank, unit_multiplier) + apply_stratified_tank_losses(storage_tank, u_tank, unit_multiplier) storage_tank.additionalProperties.setFeature('HPXML_ID', solar_thermal_system.water_heating_system.id) # Used by reporting measure storage_tank.additionalProperties.setFeature('ObjectType', Constants::ObjectTypeSolarHotWater) # Used by reporting measure @@ -897,23 +895,23 @@ def self.apply_solar_thermal(model, spaces, hpxml_bldg, plantloop_map) ) end - # TODO + # Adds a WaterHeaterHeatPumpWrappedCondenser object for the HPWH to the OpenStudio model. # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param obj_name [String] Name for the OpenStudio object - # @param coil [TODO] TODO - # @param tank [TODO] TODO - # @param fan [TODO] TODO - # @param airflow_rate [TODO] TODO - # @param hpwh_tamb [TODO] TODO - # @param hpwh_rhamb [TODO] TODO - # @param min_temp [TODO] TODO - # @param max_temp [TODO] TODO - # @param setpoint_schedule [TODO] TODO + # @param coil [OpenStudio::Model::CoilWaterHeatingAirToWaterHeatPumpWrapped] The HPWH DX coil + # @param tank [OpenStudio::Model::WaterHeaterStratified] The HPWH storage tank + # @param fan [OpenStudio::Model::FanSystemModel] The HPWH fan + # @param airflow_rate [Double] HPWH fan airflow rate (cfm) + # @param hpwh_tamb [OpenStudio::Model::ScheduleConstant] HPWH ambient temperature (C) + # @param hpwh_rhamb [OpenStudio::Model::ScheduleConstant] HPWH ambient relative humidity + # @param min_temp [Double] Minimum temperature for compressor operation (F) + # @param max_temp [Double] Maximum temperature for compressor operation (F) + # @param control_setpoint_schedule [OpenStudio::Model::ScheduleConstant or OpenStudio::Model::ScheduleRuleset] Setpoint temperature schedule (controlled) # @param unit_multiplier [Integer] Number of similar dwelling units - # @return [TODO] TODO - def self.setup_hpwh_wrapped_condenser(model, obj_name, coil, tank, fan, airflow_rate, hpwh_tamb, hpwh_rhamb, min_temp, max_temp, setpoint_schedule, unit_multiplier) - hpwh = OpenStudio::Model::WaterHeaterHeatPumpWrappedCondenser.new(model, coil, tank, fan, setpoint_schedule, model.alwaysOnDiscreteSchedule) + # @return [OpenStudio::Model::WaterHeaterHeatPumpWrappedCondenser] The HPWH object + def self.apply_hpwh_wrapped_condenser(model, obj_name, coil, tank, fan, airflow_rate, hpwh_tamb, hpwh_rhamb, min_temp, max_temp, control_setpoint_schedule, unit_multiplier) + hpwh = OpenStudio::Model::WaterHeaterHeatPumpWrappedCondenser.new(model, coil, tank, fan, control_setpoint_schedule, model.alwaysOnDiscreteSchedule) hpwh.setName("#{obj_name} hpwh") hpwh.setDeadBandTemperatureDifference(3.89) hpwh.setCondenserBottomLocation((1.0 - (12 - 0.5) / 12.0) * tank.tankHeight.get) # in the 12th node of a 12-node tank (counting from top) @@ -938,17 +936,17 @@ def self.setup_hpwh_wrapped_condenser(model, obj_name, coil, tank, fan, airflow_ return hpwh end - # TODO + # Adds a CoilWaterHeatingAirToWaterHeatPumpWrapped object for the HPWH to the OpenStudio model. # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings # @param water_heating_system [HPXML::WaterHeatingSystem] The HPXML water heating system of interest # @param elevation [Double] Elevation of the building site (ft) # @param obj_name [String] Name for the OpenStudio object - # @param airflow_rate [TODO] TODO + # @param airflow_rate [Double] HPWH fan airflow rate (cfm) # @param unit_multiplier [Integer] Number of similar dwelling units - # @return [TODO] TODO - def self.setup_hpwh_dxcoil(model, runner, water_heating_system, elevation, obj_name, airflow_rate, unit_multiplier) + # @return [OpenStudio::Model::CoilWaterHeatingAirToWaterHeatPumpWrapped] The HPWH DX coil + def self.apply_hpwh_dxcoil(model, runner, water_heating_system, elevation, obj_name, airflow_rate, unit_multiplier) # Curves hpwh_cap = Model.add_curve_biquadratic( model, @@ -1011,32 +1009,33 @@ def self.set_heat_pump_cop(water_heating_system) cop = 1.174536058 * uef # Based on simulation of the UEF test procedure at varying COPs elsif not water_heating_system.uniform_energy_factor.nil? uef = water_heating_system.uniform_energy_factor - if water_heating_system.usage_bin == HPXML::WaterHeaterUsageBinVerySmall + case water_heating_system.usage_bin + when HPXML::WaterHeaterUsageBinVerySmall fail 'It is unlikely that a heat pump water heater falls into the very small bin of the First Hour Rating (FHR) test. Double check input.' - elsif water_heating_system.usage_bin == HPXML::WaterHeaterUsageBinLow + when HPXML::WaterHeaterUsageBinLow cop = 1.0005 * uef - 0.0789 - elsif water_heating_system.usage_bin == HPXML::WaterHeaterUsageBinMedium + when HPXML::WaterHeaterUsageBinMedium cop = 1.0909 * uef - 0.0868 - elsif water_heating_system.usage_bin == HPXML::WaterHeaterUsageBinHigh + when HPXML::WaterHeaterUsageBinHigh cop = 1.1022 * uef - 0.0877 end end water_heating_system.additional_properties.cop = cop end - # TODO + # Adds a WaterHeaterStratified object for the HPWH to the OpenStudio model. # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param water_heating_system [HPXML::WaterHeatingSystem] The HPXML water heating system of interest # @param obj_name [String] Name for the OpenStudio object - # @param solar_fraction [TODO] TODO - # @param hpwh_tamb [TODO] TODO - # @param hpwh_bottom_element_sp [TODO] TODO - # @param hpwh_top_element_sp [TODO] TODO + # @param solar_fraction [Double] Portion of hot water load served by an attached solar thermal system + # @param hpwh_tamb [OpenStudio::Model::ScheduleConstant] HPWH ambient temperature (C) + # @param hpwh_top_element_sp [OpenStudio::Model::ScheduleConstant] HPWH top element setpoint schedule + # @param hpwh_bottom_element_sp [OpenStudio::Model::ScheduleConstant] HPWH bottom element setpoint schedule # @param unit_multiplier [Integer] Number of similar dwelling units # @param nbeds [Integer] Number of bedrooms in the dwelling unit - # @return [TODO] TODO - def self.setup_hpwh_stratified_tank(model, water_heating_system, obj_name, solar_fraction, hpwh_tamb, hpwh_bottom_element_sp, hpwh_top_element_sp, unit_multiplier, nbeds) + # @return [OpenStudio::Model::WaterHeaterStratified] The HPWH storage tank + def self.apply_hpwh_stratified_tank(model, water_heating_system, obj_name, solar_fraction, hpwh_tamb, hpwh_top_element_sp, hpwh_bottom_element_sp, unit_multiplier, nbeds) h_tank = 0.0188 * water_heating_system.tank_volume + 0.0935 # m; Linear relationship that gets GE height at 50 gal and AO Smith height at 80 gal # Calculate some geometry parameters for UA, the location of sensors and heat sources in the tank @@ -1095,21 +1094,23 @@ def self.setup_hpwh_stratified_tank(model, water_heating_system, obj_name, solar tank.setSourceSideOutletHeight(0) tank.setSkinLossFractiontoZone(1.0 / unit_multiplier) # Tank losses are multiplied by E+ zone multiplier, so need to compensate here tank.setOffCycleFlueLossFractiontoZone(1.0 / unit_multiplier) - set_stratified_tank_ua(tank, u_tank, unit_multiplier) + apply_stratified_tank_losses(tank, u_tank, unit_multiplier) tank.additionalProperties.setFeature('HPXML_ID', water_heating_system.id) # Used by reporting measure return tank end - # TODO + # Adds EMS sensors for the HPWH ambient temperature and ambient relative humidity. # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param obj_name [String] Name for the OpenStudio object # @param loc_space [OpenStudio::Model::Space] The space where the water heater is located - # @param loc_schedule [OpenStudio::Model::ScheduleConstant] The temperature schedule for where the water heater is located, if not in a space - # @param conditioned_zone [TODO] TODO - # @return [TODO] TODO - def self.get_loc_temp_rh_sensors(model, obj_name, loc_space, loc_schedule, conditioned_zone) + # @param loc_schedule [OpenStudio::Model::ScheduleConstant] The temperature schedule, if not located in a space + # @param spaces [Hash] Map of HPXML locations => OpenStudio Space objects + # @return [Array>] HPWH ambient temperature sensor, One or more HPWH ambient RH sensors + def self.apply_hpwh_loc_temp_rh_sensors(model, obj_name, loc_space, loc_schedule, spaces) + conditioned_zone = spaces[HPXML::LocationConditionedSpace].thermalZone.get + rh_sensors = [] if not loc_schedule.nil? amb_temp_sensor = Model.add_ems_sensor( @@ -1179,21 +1180,21 @@ def self.get_loc_temp_rh_sensors(model, obj_name, loc_space, loc_schedule, condi return amb_temp_sensor, rh_sensors end - # TODO + # Adds an EMS program to add sensible/latent gains to the thermal zone where the HPWH is located. # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param obj_name [String] Name for the OpenStudio object # @param loc_space [OpenStudio::Model::Space] The space where the water heater is located - # @param hpwh_tamb [TODO] TODO - # @param hpwh_rhamb [TODO] TODO - # @param tank [TODO] TODO - # @param coil [TODO] TODO - # @param fan [TODO] TODO - # @param amb_temp_sensor [TODO] TODO - # @param amb_rh_sensors [TODO] TODO + # @param hpwh_tamb [OpenStudio::Model::ScheduleConstant] HPWH ambient temperature (C) + # @param hpwh_rhamb [OpenStudio::Model::ScheduleConstant] HPWH ambient relative humidity + # @param tank [OpenStudio::Model::WaterHeaterStratified] The HPWH storage tank + # @param coil [OpenStudio::Model::CoilWaterHeatingAirToWaterHeatPumpWrapped] The HPWH DX coil + # @param fan [OpenStudio::Model::FanSystemModel] The HPWH fan + # @param amb_temp_sensor [OpenStudio::Model::EnergyManagementSystemSensor] HPWH ambient temperature sensor + # @param amb_rh_sensors [Array] One or more HPWH ambient RH sensors # @param unit_multiplier [Integer] Number of similar dwelling units - # @return [TODO] TODO - def self.add_hpwh_inlet_air_and_zone_heat_gain_program(model, obj_name, loc_space, hpwh_tamb, hpwh_rhamb, tank, coil, fan, amb_temp_sensor, amb_rh_sensors, unit_multiplier) + # @return [OpenStudio::Model::EnergyManagementSystemProgram] The HPWH heat gain program + def self.apply_hpwh_zone_heat_gain_program(model, obj_name, loc_space, hpwh_tamb, hpwh_rhamb, tank, coil, fan, amb_temp_sensor, amb_rh_sensors, unit_multiplier) # EMS Actuators: Inlet T & RH, sensible and latent gains to the space tamb_act_actuator = Model.add_ems_actuator( name: "#{obj_name} Tamb act", @@ -1275,41 +1276,41 @@ def self.add_hpwh_inlet_air_and_zone_heat_gain_program(model, obj_name, loc_spac key_name: fan.name ) - hpwh_inlet_air_program = Model.add_ems_program( + hpwh_zone_heat_gain_program = Model.add_ems_program( model, name: "#{obj_name} InletAir" ) - hpwh_inlet_air_program.addLine("Set #{tamb_act_actuator.name} = #{amb_temp_sensor.name}") + hpwh_zone_heat_gain_program.addLine("Set #{tamb_act_actuator.name} = #{amb_temp_sensor.name}") # Average relative humidity for mf spaces: other multifamily buffer space & other heated space - hpwh_inlet_air_program.addLine("Set #{rhamb_act_actuator.name} = 0") + hpwh_zone_heat_gain_program.addLine("Set #{rhamb_act_actuator.name} = 0") amb_rh_sensors.each do |amb_rh_sensor| - hpwh_inlet_air_program.addLine("Set #{rhamb_act_actuator.name} = #{rhamb_act_actuator.name} + (#{amb_rh_sensor.name} / 100) / #{amb_rh_sensors.size}") + hpwh_zone_heat_gain_program.addLine("Set #{rhamb_act_actuator.name} = #{rhamb_act_actuator.name} + (#{amb_rh_sensor.name} / 100) / #{amb_rh_sensors.size}") end if not loc_space.nil? # Sensible/latent heat gain to the space # Tank losses are multiplied by E+ zone multiplier, so need to compensate here - hpwh_inlet_air_program.addLine("Set #{sens_act_actuator.name} = (0 - #{sens_cool_sensor.name} - (#{tl_sensor.name} + #{fan_power_sensor.name})) / #{unit_multiplier}") - hpwh_inlet_air_program.addLine("Set #{lat_act_actuator.name} = (0 - #{lat_cool_sensor.name}) / #{unit_multiplier}") + hpwh_zone_heat_gain_program.addLine("Set #{sens_act_actuator.name} = (0 - #{sens_cool_sensor.name} - (#{tl_sensor.name} + #{fan_power_sensor.name})) / #{unit_multiplier}") + hpwh_zone_heat_gain_program.addLine("Set #{lat_act_actuator.name} = (0 - #{lat_cool_sensor.name}) / #{unit_multiplier}") end - return hpwh_inlet_air_program + return hpwh_zone_heat_gain_program end - # TODO + # Adds an EMS program to control the HPWH upper and lower elements. # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings # @param obj_name [String] Name for the OpenStudio object - # @param amb_temp_sensor [TODO] TODO - # @param hpwh_top_element_sp [TODO] TODO - # @param hpwh_bottom_element_sp [TODO] TODO - # @param min_temp [TODO] TODO - # @param max_temp [TODO] TODO - # @param op_mode [TODO] TODO - # @param setpoint_schedule [TODO] TODO - # @param control_setpoint_schedule [TODO] TODO + # @param water_heating_system [HPXML::WaterHeatingSystem] The HPXML water heating system of interest + # @param amb_temp_sensor [OpenStudio::Model::EnergyManagementSystemSensor] HPWH ambient temperature sensor + # @param hpwh_top_element_sp [OpenStudio::Model::ScheduleConstant] HPWH top element setpoint schedule + # @param hpwh_bottom_element_sp [OpenStudio::Model::ScheduleConstant] HPWH bottom element setpoint schedule + # @param min_temp [Double] Minimum temperature for compressor operation (F) + # @param max_temp [Double] Maximum temperature for compressor operation (F) + # @param sensted_setpoint_schedule [OpenStudio::Model::ScheduleConstant or OpenStudio::Model::ScheduleRuleset] Setpoint temperature schedule (sensed) + # @param control_setpoint_schedule [OpenStudio::Model::ScheduleConstant or OpenStudio::Model::ScheduleRuleset] Setpoint temperature schedule (controlled) # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files - # @return [TODO] TODO - def self.add_hpwh_control_program(model, runner, obj_name, amb_temp_sensor, hpwh_top_element_sp, hpwh_bottom_element_sp, min_temp, max_temp, op_mode, setpoint_schedule, control_setpoint_schedule, schedules_file) + # @return [OpenStudio::Model::EnergyManagementSystemProgram] The HPWH control program + def self.apply_hpwh_control_program(model, runner, obj_name, water_heating_system, amb_temp_sensor, hpwh_top_element_sp, hpwh_bottom_element_sp, min_temp, max_temp, sensted_setpoint_schedule, control_setpoint_schedule, schedules_file) # Lower element is enabled if the ambient air temperature prevents the HP from running leschedoverride_actuator = Model.add_ems_actuator( name: "#{obj_name} LESchedOverride", @@ -1341,7 +1342,7 @@ def self.add_hpwh_control_program(model, runner, obj_name, amb_temp_sensor, hpwh model, name: "#{obj_name} T_set", output_var_or_meter_name: 'Schedule Value', - key_name: setpoint_schedule.name + key_name: sensted_setpoint_schedule.name ) op_mode_schedule = nil @@ -1358,7 +1359,9 @@ def self.add_hpwh_control_program(model, runner, obj_name, amb_temp_sensor, hpwh key_name: op_mode_schedule.name ) - runner.registerWarning("Both '#{SchedulesFile::Columns[:WaterHeaterOperatingMode].name}' schedule file and operating mode provided; the latter will be ignored.") if !op_mode.nil? + if not water_heating_system.operating_mode.nil? + runner.registerWarning("Both '#{SchedulesFile::Columns[:WaterHeaterOperatingMode].name}' schedule file and operating mode provided; the latter will be ignored.") + end end t_offset = 9.0 # C @@ -1371,42 +1374,42 @@ def self.add_hpwh_control_program(model, runner, obj_name, amb_temp_sensor, hpwh ) hpwh_ctrl_program.addLine("Set #{hpwhschedoverride_actuator.name} = #{t_set_sensor.name}") # If in HP only mode: still enable elements if ambient temperature is out of bounds, otherwise disable elements - if op_mode == HPXML::WaterHeaterOperatingModeHeatPumpOnly + if water_heating_system.operating_mode == HPXML::WaterHeaterOperatingModeHeatPumpOnly hpwh_ctrl_program.addLine("If (#{amb_temp_sensor.name}<#{min_temp_c}) || (#{amb_temp_sensor.name}>#{max_temp_c})") - hpwh_ctrl_program.addLine("Set #{leschedoverride_actuator.name} = #{t_set_sensor.name}") - hpwh_ctrl_program.addLine("Set #{ueschedoverride_actuator.name} = #{t_set_sensor.name}") + hpwh_ctrl_program.addLine(" Set #{leschedoverride_actuator.name} = #{t_set_sensor.name}") + hpwh_ctrl_program.addLine(" Set #{ueschedoverride_actuator.name} = #{t_set_sensor.name}") hpwh_ctrl_program.addLine('Else') - hpwh_ctrl_program.addLine("Set #{leschedoverride_actuator.name} = 0") - hpwh_ctrl_program.addLine("Set #{ueschedoverride_actuator.name} = 0") + hpwh_ctrl_program.addLine(" Set #{leschedoverride_actuator.name} = 0") + hpwh_ctrl_program.addLine(" Set #{ueschedoverride_actuator.name} = 0") hpwh_ctrl_program.addLine('EndIf') else # First, check if ambient temperature is out of bounds for HP operation, if so enable lower element hpwh_ctrl_program.addLine("If (#{amb_temp_sensor.name}<#{min_temp_c}) || (#{amb_temp_sensor.name}>#{max_temp_c})") - hpwh_ctrl_program.addLine("Set #{ueschedoverride_actuator.name} = #{t_set_sensor.name}") - hpwh_ctrl_program.addLine("Set #{leschedoverride_actuator.name} = #{t_set_sensor.name}") + hpwh_ctrl_program.addLine(" Set #{ueschedoverride_actuator.name} = #{t_set_sensor.name}") + hpwh_ctrl_program.addLine(" Set #{leschedoverride_actuator.name} = #{t_set_sensor.name}") hpwh_ctrl_program.addLine('Else') - hpwh_ctrl_program.addLine("Set #{ueschedoverride_actuator.name} = #{t_set_sensor.name} - #{t_offset}") - hpwh_ctrl_program.addLine("Set #{leschedoverride_actuator.name} = 0") + hpwh_ctrl_program.addLine(" Set #{ueschedoverride_actuator.name} = #{t_set_sensor.name} - #{t_offset}") + hpwh_ctrl_program.addLine(" Set #{leschedoverride_actuator.name} = 0") hpwh_ctrl_program.addLine('EndIf') # Scheduled operating mode: if in HP only mode, disable both elements (this will override prior logic) if not op_mode_schedule.nil? hpwh_ctrl_program.addLine("If #{op_mode_sensor.name} == 1") - hpwh_ctrl_program.addLine("Set #{ueschedoverride_actuator.name} = 0") + hpwh_ctrl_program.addLine(" Set #{ueschedoverride_actuator.name} = 0") hpwh_ctrl_program.addLine('Else') - hpwh_ctrl_program.addLine("Set #{ueschedoverride_actuator.name} = #{t_set_sensor.name} - #{t_offset}") + hpwh_ctrl_program.addLine(" Set #{ueschedoverride_actuator.name} = #{t_set_sensor.name} - #{t_offset}") hpwh_ctrl_program.addLine('EndIf') end end return hpwh_ctrl_program end - # TODO + # Sets the tank losses for a stratified water heater tank. # - # @param tank [TODO] TODO - # @param u_tank [TODO] TODO + # @param tank [OpenStudio::Model::WaterHeaterStratified] The stratified tank + # @param u_tank [Double] The heat loss U-factor (Btu/hr-ft^2-F) # @param unit_multiplier [Integer] Number of similar dwelling units # @return [nil] - def self.set_stratified_tank_ua(tank, u_tank, unit_multiplier) + def self.apply_stratified_tank_losses(tank, u_tank, unit_multiplier) node_ua = [0] * 12 # Max number of nodes in E+ stratified tank model if unit_multiplier == 1 tank.setUniformSkinLossCoefficientperUnitAreatoAmbientTemperature(u_tank) @@ -1448,11 +1451,11 @@ def self.set_stratified_tank_ua(tank, u_tank, unit_multiplier) tank.setNode12AdditionalLossCoefficient(node_ua[11]) end - # TODO + # Gets the combination boiler and plant loop OpenStudio objects associated with the HPXML water heating system. # # @param model [OpenStudio::Model::Model] OpenStudio Model object - # @param heating_source_id [TODO] TODO - # @return [TODO] TODO + # @param heating_source_id [String] ID of the HPXML water heating system + # @return [Array] Boiler object, PlantLoop object def self.get_combi_boiler_and_plant_loop(model, heating_source_id) # Search for the right boiler OS object boiler_hw = nil @@ -1478,38 +1481,34 @@ def self.get_combi_boiler_and_plant_loop(model, heating_source_id) return boiler_hw, plant_loop_hw end - # TODO + # Adds a desuperheater for the given HPXML water heating system to the OpenStudio model. # - # @param water_heating_system [HPXML::WaterHeatingSystem] The HPXML water heating system of interest # @param model [OpenStudio::Model::Model] OpenStudio Model object - # @return [TODO] TODO - def self.get_desuperheatercoil(water_heating_system, model) + # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings + # @param water_heating_system [HPXML::WaterHeatingSystem] The HPXML water heating system of interest + # @param tank [OpenStudio::Model::WaterHeaterMixed or OpenStudio::Model::WaterHeaterStratified] The water heater tank + # @param loc_space [OpenStudio::Model::Space] The space where the water heater is located + # @param loc_schedule [OpenStudio::Model::ScheduleConstant] The temperature schedule, if not located in a space + # @param plant_loop [OpenStudio::Model::PlantLoop] The DHW plant loop + # @param unit_multiplier [Integer] Number of similar dwelling units + # @return [nil] + def self.apply_desuperheater(model, runner, water_heating_system, tank, loc_space, loc_schedule, plant_loop, unit_multiplier) + return unless water_heating_system.uses_desuperheater + + # Get the HVAC cooling coil for the desuperheater + desuperheater_clg_coil = nil (model.getCoilCoolingDXSingleSpeeds + model.getCoilCoolingDXMultiSpeeds + model.getCoilCoolingWaterToAirHeatPumpEquationFits).each do |clg_coil| sys_id = clg_coil.additionalProperties.getFeatureAsString('HPXML_ID') if sys_id.is_initialized && sys_id.get == water_heating_system.related_hvac_idref - return clg_coil + desuperheater_clg_coil = clg_coil end end - fail "RelatedHVACSystem '#{water_heating_system.related_hvac_idref}' for water heating system '#{water_heating_system.id}' is not currently supported for desuperheaters." - end - - # TODO - # - # @param model [OpenStudio::Model::Model] OpenStudio Model object - # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings - # @param water_heating_system [HPXML::WaterHeatingSystem] The HPXML water heating system of interest - # @param tank [TODO] TODO - # @param loc_space [OpenStudio::Model::Space] The space where the water heater is located - # @param loc_schedule [OpenStudio::Model::ScheduleConstant] The temperature schedule for where the water heater is located, if not in a space - # @param loop [TODO] TODO - # @param unit_multiplier [Integer] Number of similar dwelling units - # @return [TODO] TODO - def self.add_desuperheater(model, runner, water_heating_system, tank, loc_space, loc_schedule, loop, unit_multiplier) - return unless water_heating_system.uses_desuperheater + if desuperheater_clg_coil.nil? + fail "RelatedHVACSystem '#{water_heating_system.related_hvac_idref}' for water heating system '#{water_heating_system.id}' is not currently supported for desuperheaters." + end - desuperheater_clg_coil = get_desuperheatercoil(water_heating_system, model) reclaimed_efficiency = 0.25 # default desuperheater_name = "#{tank.name} desuperheater" @@ -1518,25 +1517,26 @@ def self.add_desuperheater(model, runner, water_heating_system, tank, loc_space, storage_vol_actual = calc_storage_tank_actual_vol(vol, nil) assumed_ua = 6.0 # Btu/hr-F, tank ua calculated based on 1.0 standby_loss and 50gal nominal vol storage_tank_name = "#{tank.name} storage tank" - # reduce tank setpoint to enable desuperheater setpoint at t_set + if water_heating_system.temperature.nil? fail "Detailed setpoints for water heating system '#{water_heating_system.id}' is not currently supported for desuperheaters." else - tank_setpoint = get_t_set_c(water_heating_system.temperature - 5.0, HPXML::WaterHeaterTypeStorage) + # reduce tank setpoint to enable desuperheater setpoint at t_set + t_set_c = get_t_set_c(water_heating_system.temperature - 5.0, HPXML::WaterHeaterTypeStorage) end - storage_tank = create_new_heater(name: storage_tank_name, - act_vol: storage_vol_actual, - t_set_c: tank_setpoint, - loc_space: loc_space, - loc_schedule: loc_schedule, - model: model, - runner: runner, - ua: assumed_ua, - is_dsh_storage: true, - unit_multiplier: unit_multiplier) - - loop.addSupplyBranchForComponent(storage_tank) + storage_tank = apply_water_heater(name: storage_tank_name, + act_vol: storage_vol_actual, + t_set_c: t_set_c, + loc_space: loc_space, + loc_schedule: loc_schedule, + model: model, + runner: runner, + ua: assumed_ua, + is_dsh_storage: true, + unit_multiplier: unit_multiplier) + + plant_loop.addSupplyBranchForComponent(storage_tank) tank.addToNode(storage_tank.supplyOutletModelObject.get.to_Node.get) # Create a schedule for desuperheater @@ -1549,50 +1549,53 @@ def self.add_desuperheater(model, runner, water_heating_system, tank, loc_space, limits: EPlus::ScheduleTypeLimitsTemperature ) - # create a desuperheater object + # Create desuperheater object desuperheater = OpenStudio::Model::CoilWaterHeatingDesuperheater.new(model, new_schedule) desuperheater.setName(desuperheater_name) desuperheater.setMaximumInletWaterTemperatureforHeatReclaim(100) desuperheater.setDeadBandTemperatureDifference(0.2) desuperheater.setRatedHeatReclaimRecoveryEfficiency(reclaimed_efficiency) desuperheater.addToHeatRejectionTarget(storage_tank) - # FUTURE: Desuperheater pump power? - desuperheater.setWaterPumpPower(0) - # attach to the clg coil source + desuperheater.setWaterPumpPower(0) # FUTURE: Desuperheater pump power? desuperheater.setHeatingSource(desuperheater_clg_coil) desuperheater.setWaterFlowRate(0.0001 * unit_multiplier) desuperheater.additionalProperties.setFeature('HPXML_ID', water_heating_system.id) # Used by reporting measure end - # TODO + # Calculates an Energy Factor (EF) from a Uniform Energy Factor (UEF). + # + # Source: RESNET's Interpretation on Water Heater UEF + # https://www.resnet.us/wp-content/uploads/Interpretation-301-2014-012-Water-Heater-UEF.pdf + # Note that this is a regression based on products on the market, not a conversion. # # @param water_heating_system [HPXML::WaterHeatingSystem] The HPXML water heating system of interest - # @return [TODO] TODO + # @return [Double] The Energy Factor def self.calc_ef_from_uef(water_heating_system) - # Interpretation on Water Heater UEF if water_heating_system.fuel_type == HPXML::FuelTypeElectricity - if water_heating_system.water_heater_type == HPXML::WaterHeaterTypeStorage + case water_heating_system.water_heater_type + when HPXML::WaterHeaterTypeStorage return [2.4029 * water_heating_system.uniform_energy_factor - 1.2844, 0.96].min - elsif water_heating_system.water_heater_type == HPXML::WaterHeaterTypeTankless + when HPXML::WaterHeaterTypeTankless return water_heating_system.uniform_energy_factor - elsif water_heating_system.water_heater_type == HPXML::WaterHeaterTypeHeatPump + when HPXML::WaterHeaterTypeHeatPump return 1.2101 * water_heating_system.uniform_energy_factor - 0.6052 end else # Fuel - if water_heating_system.water_heater_type == HPXML::WaterHeaterTypeStorage + case water_heating_system.water_heater_type + when HPXML::WaterHeaterTypeStorage return 0.9066 * water_heating_system.uniform_energy_factor + 0.0711 - elsif water_heating_system.water_heater_type == HPXML::WaterHeaterTypeTankless + when HPXML::WaterHeaterTypeTankless return water_heating_system.uniform_energy_factor end end fail 'Unexpected water heater.' end - # TODO + # Calculates water heater storage tank surface areas. # - # @param act_vol [TODO] TODO - # @param height [TODO] TODO - # @return [TODO] TODO + # @param act_vol [Double] Actual tank volume (gal) + # @param height [Double] Tank height (ft) + # @return [Array] Tank total surface area (ft), Tank side surface area (ft) def self.calc_tank_areas(act_vol, height = nil) if height.nil? height = DefaultTankHeight @@ -1600,20 +1603,20 @@ def self.calc_tank_areas(act_vol, height = nil) diameter = 2.0 * (UnitConversions.convert(act_vol, 'gal', 'ft^3') / (height * Math::PI))**0.5 # feet a_top = Math::PI * diameter**2.0 / 4.0 # sqft a_side = Math::PI * diameter * height # sqft - surface_area = 2.0 * a_top + a_side # sqft + a_total = 2.0 * a_top + a_side # sqft - return surface_area, a_side + return a_total, a_side end - # TODO + # Calculates tank losses for the combination boiler given its standby loss value. # - # @param act_vol [TODO] TODO + # @param act_vol [Double] Actual tank volume (gal) # @param water_heating_system [HPXML::WaterHeatingSystem] The HPXML water heating system of interest - # @param a_side [TODO] TODO - # @param solar_fraction [TODO] TODO + # @param a_side [Double] Tank side surface area (ft^3) + # @param solar_fraction [Double] Portion of hot water load served by an attached solar thermal system # @param nbeds [Integer] Number of bedrooms in the dwelling unit - # @return [TODO] TODO - def self.calc_indirect_ua_with_standbyloss(act_vol, water_heating_system, a_side, solar_fraction, nbeds = nil) + # @return [Double] Tank loss UA factor (Btu/hr-F) + def self.calc_combi_tank_losses(act_vol, water_heating_system, a_side, solar_fraction, nbeds = nil) standby_loss_units = water_heating_system.standby_loss_units standby_loss_value = water_heating_system.standby_loss_value @@ -1641,17 +1644,18 @@ def self.calc_indirect_ua_with_standbyloss(act_vol, water_heating_system, a_side return ua end - # TODO + # Adds an EMS program to increase/decrease the energy consumption of the water heater based on + # the energy consumption adjustment factor (EC_adj). # # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @param heater [TODO] TODO + # @param water_heater [OpenStudio::Model::WaterHeaterMixed or OpenStudio::Model::WaterHeaterStratified or OpenStudio::Model::WaterHeaterHeatPumpWrappedCondenser] The water heater object # @param loc_space [OpenStudio::Model::Space] The space where the water heater is located # @param water_heating_system [HPXML::WaterHeatingSystem] The HPXML water heating system of interest # @param unit_multiplier [Integer] Number of similar dwelling units - # @param combi_boiler [TODO] TODO - # @return [TODO] TODO - def self.add_ec_adj(model, hpxml_bldg, heater, loc_space, water_heating_system, unit_multiplier, combi_boiler = nil) + # @param combi_boiler [OpenStudio::Model::BoilerHotWater] The boiler object if the HPXML water heating system is a combi boiler + # @return [nil] + def self.apply_ec_adj_program(model, hpxml_bldg, water_heater, loc_space, water_heating_system, unit_multiplier, combi_boiler = nil) ec_adj = get_dist_energy_consumption_adjustment(hpxml_bldg, water_heating_system) adjustment = ec_adj - 1.0 @@ -1660,9 +1664,9 @@ def self.add_ec_adj(model, hpxml_bldg, heater, loc_space, water_heating_system, end if water_heating_system.water_heater_type == HPXML::WaterHeaterTypeHeatPump - tank = heater.tank + tank = water_heater.tank else - tank = heater + tank = water_heater end if [HPXML::WaterHeaterTypeCombiStorage, HPXML::WaterHeaterTypeCombiTankless].include? water_heating_system.water_heater_type fuel_type = water_heating_system.related_hvac_system.heating_system_fuel @@ -1706,15 +1710,15 @@ def self.add_ec_adj(model, hpxml_bldg, heater, loc_space, water_heating_system, if water_heating_system.water_heater_type == HPXML::WaterHeaterTypeHeatPump ec_adj_hp_sensor = Model.add_ems_sensor( model, - name: "#{heater.dXCoil.name} energy", + name: "#{water_heater.dXCoil.name} energy", output_var_or_meter_name: "Cooling Coil Water Heating #{EPlus::FuelTypeElectricity} Rate", - key_name: heater.dXCoil.name + key_name: water_heater.dXCoil.name ) ec_adj_fan_sensor = Model.add_ems_sensor( model, - name: "#{heater.fan.name} energy", + name: "#{water_heater.fan.name} energy", output_var_or_meter_name: "Fan #{EPlus::FuelTypeElectricity} Rate", - key_name: heater.fan.name + key_name: water_heater.fan.name ) end end @@ -1734,7 +1738,7 @@ def self.add_ec_adj(model, hpxml_bldg, heater, loc_space, water_heating_system, # Actuators ec_adj_actuator = Model.add_ems_actuator( - name: "#{heater.name} ec adj act", + name: "#{water_heater.name} ec adj act", model_object: ec_adj_object, comp_type_and_control: EPlus::EMSActuatorOtherEquipmentPower ) @@ -1742,7 +1746,7 @@ def self.add_ec_adj(model, hpxml_bldg, heater, loc_space, water_heating_system, # Program ec_adj_program = Model.add_ems_program( model, - name: "#{heater.name} EC_adj" + name: "#{water_heater.name} EC_adj" ) ec_adj_program.addLine('If WarmupFlag == 0') # Prevent a non-zero adjustment in the first hour because of the warmup period if [HPXML::WaterHeaterTypeCombiStorage, HPXML::WaterHeaterTypeCombiTankless].include? water_heating_system.water_heater_type @@ -1763,31 +1767,30 @@ def self.add_ec_adj(model, hpxml_bldg, heater, loc_space, water_heating_system, # Program Calling Manager Model.add_ems_program_calling_manager( model, - name: "#{heater.name} EC_adj ProgramManager", + name: "#{water_heater.name} EC_adj ProgramManager", calling_point: 'EndOfSystemTimestepBeforeHVACReporting', ems_programs: [ec_adj_program] ) end - # TODO + # Gets the water heater setpoint temperature deadband. # - # @param wh_type [TODO] TODO - # @return [TODO] TODO - def self.deadband(wh_type) + # @param wh_type [String] Type of water heater (HPXML::WaterHeaterTypeXXX) + # @return [Double] Temperature deadband (C) + def self.get_deadband(wh_type) if [HPXML::WaterHeaterTypeStorage, HPXML::WaterHeaterTypeCombiStorage].include? wh_type - return 2.0 # C + return 2.0 else - return 0.0 # C + return 0.0 end end - # TODO + # Calculates the water heater actual volume from its nominal/rated volume. # - # @param vol [TODO] TODO - # @param fuel [TODO] TODO - # @return [TODO] TODO + # @param vol [Double] Nominal tank volume (gal) + # @param fuel [String] Water heater fuel type (HPXML::FuelTypeXXX) + # @return [Double] Actual tank volume (gal) def self.calc_storage_tank_actual_vol(vol, fuel) - # Convert the nominal tank volume to an actual volume if fuel.nil? act_vol = 0.95 * vol # indirect tank else @@ -1800,22 +1803,21 @@ def self.calc_storage_tank_actual_vol(vol, fuel) return act_vol end - # TODO + # Disaggregates the water heater's (uniform) energy factor into tank losses and burner efficiency. + # + # If using EF: + # Calculations based on the Energy Factor and Recovery Efficiency of the tank + # Source: Burch and Erickson 2004 - http://www.nrel.gov/docs/gen/fy04/36035.pdf + # IF using UEF: + # Calculations based on the Uniform Energy Factor, First Hour Rating, and Recovery Efficiency of the tank + # Source: Maguire and Roberts 2020 - https://www.ashrae.org/file%20library/conferences/specialty%20conferences/2020%20building%20performance/papers/d-bsc20-c039.pdf # - # @param act_vol [TODO] TODO + # @param act_vol [Double] Actual tank volume (gal) # @param water_heating_system [HPXML::WaterHeatingSystem] The HPXML water heating system of interest - # @param solar_fraction [TODO] TODO + # @param solar_fraction [Double] Portion of hot water load served by an attached solar thermal system # @param nbeds [Integer] Number of bedrooms in the dwelling unit - # @return [TODO] TODO - def self.calc_tank_UA(act_vol, water_heating_system, solar_fraction, nbeds) - # If using EF: - # Calculates the U value, UA of the tank and conversion efficiency (eta_c) - # based on the Energy Factor and recovery efficiency of the tank - # Source: Burch and Erickson 2004 - http://www.nrel.gov/docs/gen/fy04/36035.pdf - # IF using UEF: - # Calculates the U value, UA of the tank and conversion efficiency (eta_c) - # based on the Uniform Energy Factor, First Hour Rating, and Recovery Efficiency of the tank - # Source: Maguire and Roberts 2020 - https://www.ashrae.org/file%20library/conferences/specialty%20conferences/2020%20building%20performance/papers/d-bsc20-c039.pdf + # @return [Array] Tank loss U-factor (Btu/hr-ft^2-F), tank loss UA factor (Btu/hr-F), burner efficiency (frac) + def self.disaggregate_tank_losses_and_burner_efficiency(act_vol, water_heating_system, solar_fraction, nbeds) if water_heating_system.water_heater_type == HPXML::WaterHeaterTypeTankless if not water_heating_system.energy_factor.nil? eta_c = water_heating_system.energy_factor * water_heating_system.performance_adjustment @@ -1835,13 +1837,14 @@ def self.calc_tank_UA(act_vol, water_heating_system, solar_fraction, nbeds) volume_drawn = 64.3 # gal/day elsif not water_heating_system.uniform_energy_factor.nil? t = 125.0 # F - if water_heating_system.usage_bin == HPXML::WaterHeaterUsageBinVerySmall + case water_heating_system.usage_bin + when HPXML::WaterHeaterUsageBinVerySmall volume_drawn = 10.0 # gal - elsif water_heating_system.usage_bin == HPXML::WaterHeaterUsageBinLow + when HPXML::WaterHeaterUsageBinLow volume_drawn = 38.0 # gal - elsif water_heating_system.usage_bin == HPXML::WaterHeaterUsageBinMedium + when HPXML::WaterHeaterUsageBinMedium volume_drawn = 55.0 # gal - elsif water_heating_system.usage_bin == HPXML::WaterHeaterUsageBinHigh + when HPXML::WaterHeaterUsageBinHigh volume_drawn = 84.0 # gal end end @@ -1881,13 +1884,14 @@ def self.calc_tank_UA(act_vol, water_heating_system, solar_fraction, nbeds) return u, ua, eta_c end - # TODO + # Calculates an adjustment to the tank loss UA factor to account for the presence + # of a water heater jacket (insulation). # # @param water_heating_system [HPXML::WaterHeatingSystem] The HPXML water heating system of interest - # @param ua_pre [TODO] TODO - # @param a_side [TODO] TODO - # @return [TODO] TODO - def self.apply_tank_jacket(water_heating_system, ua_pre, a_side) + # @param ua [Double] Tank loss UA factor (Btu/hr-F) + # @param a_side [Double] Tank side surface area (ft^3) + # @return [Double] Adjusted tank loss UA factor (Btu/hr-F) + def self.apply_tank_jacket(water_heating_system, ua, a_side) if not water_heating_system.jacket_r_value.nil? skin_insulation_R = 5.0 # R5 if water_heating_system.fuel_type.nil? # indirect water heater, etc. Assume 2 inch skin insulation @@ -1898,58 +1902,59 @@ def self.apply_tank_jacket(water_heating_system, ua_pre, a_side) ef = calc_ef_from_uef(water_heating_system) end if ef < 0.7 - skin_insulation_t = 1.0 # inch + skin_insulation_t = 1.0 # inch, assumed else - skin_insulation_t = 2.0 # inch + skin_insulation_t = 2.0 # inch, assumed end else # electric - skin_insulation_t = 2.0 # inch + skin_insulation_t = 2.0 # inch, assumed end # water heater wrap calculation based on: # Modeling Water Heat Wraps in BEopt DRAFT Technical Note # Authors: Ben Polly and Jay Burch (NREL) u_pre_skin = 1.0 / (skin_insulation_t * skin_insulation_R + 1.0 / 1.3 + 1.0 / 52.8) # Btu/hr-ft^2-F = (1 / hout + kins / tins + t / hin)^-1 - ua = ua_pre - water_heating_system.jacket_r_value / (1.0 / u_pre_skin + water_heating_system.jacket_r_value) * u_pre_skin * a_side + ua_adj = ua - water_heating_system.jacket_r_value / (1.0 / u_pre_skin + water_heating_system.jacket_r_value) * u_pre_skin * a_side else - ua = ua_pre + ua_adj = ua end - return ua + return ua_adj end - # TODO + # Calculates an adjustment to the tank loss UA factor for a shared water heater, in which we + # apportion the tank losses to the dwelling unit. # # @param water_heating_system [HPXML::WaterHeatingSystem] The HPXML water heating system of interest - # @param ua [TODO] TODO + # @param ua [Double] Tank loss UA factor (Btu/hr-F) # @param nbeds [Integer] Number of bedrooms in the dwelling unit - # @return [TODO] TODO + # @return [Double] Adjusted tank loss UA factor (Btu/hr-F) def self.apply_shared_adjustment(water_heating_system, ua, nbeds) if water_heating_system.is_shared_system - # Apportion shared water heater energy use due to tank losses to the dwelling unit - ua = ua * [nbeds.to_f, 1.0].max / water_heating_system.number_of_bedrooms_served.to_f + return ua * [nbeds.to_f, 1.0].max / water_heating_system.number_of_bedrooms_served.to_f + else + return ua end - return ua end - # TODO + # Adds a water heater object to the OpenStudio model. # - # @param name [TODO] TODO + # @param name [String] Name for the OpenStudio object # @param water_heating_system [HPXML::WaterHeatingSystem] The HPXML water heating system of interest - # @param act_vol [TODO] TODO - # @param t_set_c [TODO] TODO + # @param act_vol [Double] Actual tank volume (gal) + # @param t_set_c [Double] Water heater setpoint including deadband (C) # @param loc_space [OpenStudio::Model::Space] The space where the water heater is located - # @param loc_schedule [OpenStudio::Model::ScheduleConstant] The temperature schedule for where the water heater is located, if not in a space + # @param loc_schedule [OpenStudio::Model::ScheduleConstant] The temperature schedule, if not located in a space # @param model [OpenStudio::Model::Model] OpenStudio Model object # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings - # @param u [TODO] TODO - # @param ua [TODO] TODO - # @param eta_c [TODO] TODO - # @param is_dsh_storage [TODO] TODO - # @param is_combi [TODO] TODO + # @param u [Double] Tank loss coefficient (FIXME) + # @param ua [Double] Tank loss UA factor (Btu/hr-F) + # @param eta_c [Double] Burner efficiency (frac) + # @param is_dsh_storage [Boolean] True if this is a desuperheater storage tank + # @param is_combi [Boolean] True if this is a combination boiler # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files # @param unavailable_periods [HPXML::UnavailablePeriods] Object that defines periods for, e.g., power outages or vacancies # @param unit_multiplier [Integer] Number of similar dwelling units - # @return [TODO] TODO - def self.create_new_heater(name:, water_heating_system: nil, act_vol:, t_set_c: nil, loc_space:, loc_schedule: nil, model:, runner:, u: nil, ua:, eta_c: nil, is_dsh_storage: false, is_combi: false, schedules_file: nil, unavailable_periods: [], unit_multiplier: 1.0) + # @return [OpenStudio::Model::WaterHeaterMixed or OpenStudio::Model::WaterHeaterStratified] Water heater object + def self.apply_water_heater(name:, water_heating_system: nil, act_vol:, t_set_c: nil, loc_space:, loc_schedule: nil, model:, runner:, u: nil, ua:, eta_c: nil, is_dsh_storage: false, is_combi: false, schedules_file: nil, unavailable_periods: [], unit_multiplier: 1.0) # storage tank doesn't require water_heating_system class argument being passed if is_dsh_storage || is_combi fuel = nil @@ -1974,44 +1979,44 @@ def self.create_new_heater(name:, water_heating_system: nil, act_vol:, t_set_c: h_tank = UnitConversions.convert(DefaultTankHeight, 'ft', 'm') # Add a WaterHeater:Stratified to the model - new_heater = OpenStudio::Model::WaterHeaterStratified.new(model) - new_heater.setEndUseSubcategory('Domestic Hot Water') - new_heater.setTankVolume(UnitConversions.convert(act_vol, 'gal', 'm^3')) - new_heater.setTankHeight(h_tank) - new_heater.setMaximumTemperatureLimit(90) - new_heater.setHeaterPriorityControl('MasterSlave') - new_heater.setHeater1Capacity(UnitConversions.convert(cap, 'kBtu/hr', 'W')) - new_heater.setHeater1Height((1.0 - (4 - 0.5) / 15) * h_tank) # in the 4th node of a 15-node tank (counting from top); height of upper element based on TRNSYS assumptions for an ERWH - new_heater.setHeater1DeadbandTemperatureDifference(5.556) - new_heater.setHeater2Capacity(UnitConversions.convert(cap, 'kBtu/hr', 'W')) - new_heater.setHeater2Height((1.0 - (13 - 0.5) / 15) * h_tank) # in the 13th node of a 15-node tank (counting from top); height of upper element based on TRNSYS assumptions for an ERWH - new_heater.setHeater2DeadbandTemperatureDifference(5.556) - new_heater.setHeaterThermalEfficiency(1.0) - new_heater.setNumberofNodes(12) - new_heater.setAdditionalDestratificationConductivity(0) - new_heater.setUseSideDesignFlowRate(UnitConversions.convert(act_vol, 'gal', 'm^3') / 60.1) - new_heater.setSourceSideDesignFlowRate(0) - new_heater.setSourceSideFlowControlMode('') - new_heater.setSourceSideInletHeight((1.0 - (1 - 0.5) / 15) * h_tank) # in the 1st node of a 15-node tank (counting from top) - new_heater.setSourceSideOutletHeight((1.0 - (15 - 0.5) / 15) * h_tank) # in the 15th node of a 15-node tank (counting from top) - new_heater.setSkinLossFractiontoZone(1.0 / unit_multiplier) # Tank losses are multiplied by E+ zone multiplier, so need to compensate here - new_heater.setOffCycleFlueLossFractiontoZone(1.0 / unit_multiplier) - set_stratified_tank_ua(new_heater, u, unit_multiplier) + water_heater = OpenStudio::Model::WaterHeaterStratified.new(model) + water_heater.setEndUseSubcategory('Domestic Hot Water') + water_heater.setTankVolume(UnitConversions.convert(act_vol, 'gal', 'm^3')) + water_heater.setTankHeight(h_tank) + water_heater.setMaximumTemperatureLimit(90) + water_heater.setHeaterPriorityControl('MasterSlave') + water_heater.setHeater1Capacity(UnitConversions.convert(cap, 'kBtu/hr', 'W')) + water_heater.setHeater1Height((1.0 - (4 - 0.5) / 15) * h_tank) # in the 4th node of a 15-node tank (counting from top); height of upper element based on TRNSYS assumptions for an ERWH + water_heater.setHeater1DeadbandTemperatureDifference(5.556) + water_heater.setHeater2Capacity(UnitConversions.convert(cap, 'kBtu/hr', 'W')) + water_heater.setHeater2Height((1.0 - (13 - 0.5) / 15) * h_tank) # in the 13th node of a 15-node tank (counting from top); height of upper element based on TRNSYS assumptions for an ERWH + water_heater.setHeater2DeadbandTemperatureDifference(5.556) + water_heater.setHeaterThermalEfficiency(1.0) + water_heater.setNumberofNodes(12) + water_heater.setAdditionalDestratificationConductivity(0) + water_heater.setUseSideDesignFlowRate(UnitConversions.convert(act_vol, 'gal', 'm^3') / 60.1) + water_heater.setSourceSideDesignFlowRate(0) + water_heater.setSourceSideFlowControlMode('') + water_heater.setSourceSideInletHeight((1.0 - (1 - 0.5) / 15) * h_tank) # in the 1st node of a 15-node tank (counting from top) + water_heater.setSourceSideOutletHeight((1.0 - (15 - 0.5) / 15) * h_tank) # in the 15th node of a 15-node tank (counting from top) + water_heater.setSkinLossFractiontoZone(1.0 / unit_multiplier) # Tank losses are multiplied by E+ zone multiplier, so need to compensate here + water_heater.setOffCycleFlueLossFractiontoZone(1.0 / unit_multiplier) + apply_stratified_tank_losses(water_heater, u, unit_multiplier) else - new_heater = OpenStudio::Model::WaterHeaterMixed.new(model) - new_heater.setTankVolume(UnitConversions.convert(act_vol, 'gal', 'm^3')) - new_heater.setHeaterThermalEfficiency(eta_c) unless eta_c.nil? - new_heater.setMaximumTemperatureLimit(99.0) + water_heater = OpenStudio::Model::WaterHeaterMixed.new(model) + water_heater.setTankVolume(UnitConversions.convert(act_vol, 'gal', 'm^3')) + water_heater.setHeaterThermalEfficiency(eta_c) unless eta_c.nil? + water_heater.setMaximumTemperatureLimit(99.0) if [HPXML::WaterHeaterTypeTankless, HPXML::WaterHeaterTypeCombiTankless].include? tank_type - new_heater.setHeaterControlType('Modulate') + water_heater.setHeaterControlType('Modulate') else - new_heater.setHeaterControlType('Cycle') + water_heater.setHeaterControlType('Cycle') end - new_heater.setDeadbandTemperatureDifference(deadband(tank_type)) + water_heater.setDeadbandTemperatureDifference(get_deadband(tank_type)) # Capacity, storage tank to be 0 - new_heater.setHeaterMaximumCapacity(UnitConversions.convert(cap, 'kBtu/hr', 'W')) - new_heater.setHeaterMinimumCapacity(0.0) + water_heater.setHeaterMaximumCapacity(UnitConversions.convert(cap, 'kBtu/hr', 'W')) + water_heater.setHeaterMinimumCapacity(0.0) # Set fraction of heat loss from tank to ambient (vs out flue) # Based on lab testing done by LBNL @@ -2032,68 +2037,68 @@ def self.create_new_heater(name:, water_heating_system: nil, act_vol:, t_set_c: skinlossfrac = 0.96 # Condensing end end - new_heater.setOffCycleLossFractiontoThermalZone(skinlossfrac / unit_multiplier) # Tank losses are multiplied by E+ zone multiplier, so need to compensate here - new_heater.setOnCycleLossFractiontoThermalZone(1.0 / unit_multiplier) # Tank losses are multiplied by E+ zone multiplier, so need to compensate here + water_heater.setOffCycleLossFractiontoThermalZone(skinlossfrac / unit_multiplier) # Tank losses are multiplied by E+ zone multiplier, so need to compensate here + water_heater.setOnCycleLossFractiontoThermalZone(1.0 / unit_multiplier) # Tank losses are multiplied by E+ zone multiplier, so need to compensate here ua_w_k = UnitConversions.convert(ua, 'Btu/(hr*F)', 'W/K') - new_heater.setOnCycleLossCoefficienttoAmbientTemperature(ua_w_k) - new_heater.setOffCycleLossCoefficienttoAmbientTemperature(ua_w_k) + water_heater.setOnCycleLossCoefficienttoAmbientTemperature(ua_w_k) + water_heater.setOffCycleLossCoefficienttoAmbientTemperature(ua_w_k) end - assign_water_heater_setpoint(runner, model, new_heater, schedules_file, t_set_c, unavailable_periods) + apply_setpoint(runner, model, water_heater, schedules_file, t_set_c, unavailable_periods) if not water_heating_system.nil? - new_heater.additionalProperties.setFeature('HPXML_ID', water_heating_system.id) # Used by reporting measure + water_heater.additionalProperties.setFeature('HPXML_ID', water_heating_system.id) # Used by reporting measure end if is_combi - new_heater.additionalProperties.setFeature('IsCombiBoiler', true) # Used by reporting measure + water_heater.additionalProperties.setFeature('IsCombiBoiler', true) # Used by reporting measure end - new_heater.setName(name) - new_heater.setHeaterFuelType(EPlus.fuel_type(fuel)) unless fuel.nil? - set_wh_ambient(loc_space, loc_schedule, new_heater) + water_heater.setName(name) + water_heater.setHeaterFuelType(EPlus.fuel_type(fuel)) unless fuel.nil? + apply_ambient_temperature(loc_space, loc_schedule, water_heater) # FUTURE: These are always zero right now; develop smart defaults. - new_heater.setOffCycleParasiticFuelType(EPlus::FuelTypeElectricity) - new_heater.setOffCycleParasiticFuelConsumptionRate(0.0) - new_heater.setOffCycleParasiticHeatFractiontoTank(0) - new_heater.setOnCycleParasiticFuelType(EPlus::FuelTypeElectricity) - new_heater.setOnCycleParasiticFuelConsumptionRate(0.0) - new_heater.setOnCycleParasiticHeatFractiontoTank(0) - - return new_heater + water_heater.setOffCycleParasiticFuelType(EPlus::FuelTypeElectricity) + water_heater.setOffCycleParasiticFuelConsumptionRate(0.0) + water_heater.setOffCycleParasiticHeatFractiontoTank(0) + water_heater.setOnCycleParasiticFuelType(EPlus::FuelTypeElectricity) + water_heater.setOnCycleParasiticFuelConsumptionRate(0.0) + water_heater.setOnCycleParasiticHeatFractiontoTank(0) + + return water_heater end - # TODO + # Applies the ambient temperature conditions to the water heater. # # @param loc_space [OpenStudio::Model::Space] The space where the water heater is located - # @param loc_schedule [OpenStudio::Model::ScheduleConstant] The temperature schedule for where the water heater is located, if not in a space - # @param wh_obj [TODO] TODO + # @param loc_schedule [OpenStudio::Model::ScheduleConstant] The temperature schedule, if not located in a space + # @param water_heater [OpenStudio::Model::WaterHeaterMixed or OpenStudio::Model::WaterHeaterStratified] Water heater object # @return [nil] - def self.set_wh_ambient(loc_space, loc_schedule, wh_obj) - if wh_obj.ambientTemperatureSchedule.is_initialized - wh_obj.ambientTemperatureSchedule.get.remove + def self.apply_ambient_temperature(loc_space, loc_schedule, water_heater) + if water_heater.ambientTemperatureSchedule.is_initialized + water_heater.ambientTemperatureSchedule.get.remove end if not loc_schedule.nil? # Temperature schedule indicator - wh_obj.setAmbientTemperatureSchedule(loc_schedule) + water_heater.setAmbientTemperatureSchedule(loc_schedule) elsif not loc_space.nil? - wh_obj.setAmbientTemperatureIndicator('ThermalZone') - wh_obj.setAmbientTemperatureThermalZone(loc_space.thermalZone.get) + water_heater.setAmbientTemperatureIndicator('ThermalZone') + water_heater.setAmbientTemperatureThermalZone(loc_space.thermalZone.get) else # Located outside - wh_obj.setAmbientTemperatureIndicator('Outdoors') + water_heater.setAmbientTemperatureIndicator('Outdoors') end end - # TODO + # Applies the temperature setpoint to the water heater. # # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings # @param model [OpenStudio::Model::Model] OpenStudio Model object - # @param water_heater [TODO] TODO + # @param water_heater [OpenStudio::Model::WaterHeaterMixed or OpenStudio::Model::WaterHeaterStratified] Water heater object # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files - # @param t_set_c [TODO] TODO + # @param t_set_c [Double] Water heater setpoint including deadband (C) # @param unavailable_periods [HPXML::UnavailablePeriods] Object that defines periods for, e.g., power outages or vacancies # @return [nil] - def self.assign_water_heater_setpoint(runner, model, water_heater, schedules_file, t_set_c, unavailable_periods) + def self.apply_setpoint(runner, model, water_heater, schedules_file, t_set_c, unavailable_periods) setpoint_sch = nil if not schedules_file.nil? setpoint_sch = schedules_file.create_schedule_file(model, col_name: SchedulesFile::Columns[:WaterHeaterSetpoint].name) @@ -2117,51 +2122,55 @@ def self.assign_water_heater_setpoint(runner, model, water_heater, schedules_fil end end - # TODO + # Returns the water heater setpoint, accounting for any deadband, in deg-C. The deadband is currently + # centered, not single-sided; see https://github.com/NREL/OpenStudio-HPXML/issues/642. # - # @param t_set [TODO] TODO - # @param wh_type [TODO] TODO - # @return [TODO] TODO + # @param t_set [Double] Water heater setpoint (F) + # @param wh_type [String] Type of water heater (HPXML::WaterHeaterTypeXXX) + # @return [Double] Water heater setpoint including deadband (C) def self.get_t_set_c(t_set, wh_type) return if t_set.nil? - return UnitConversions.convert(t_set, 'F', 'C') + deadband(wh_type) / 2.0 # Half the deadband to account for E+ deadband + return UnitConversions.convert(t_set, 'F', 'C') + get_deadband(wh_type) / 2.0 # Half the deadband to account for E+ deadband end - # TODO + # Adds a plant loop for the water heater to the OpenStudio model. # # @param model [OpenStudio::Model::Model] OpenStudio Model object - # @param t_set_c [TODO] TODO + # @param t_set_c [Double] Water heater setpoint including deadband (C) # @param eri_version [String] Version of the ANSI/RESNET/ICC 301 Standard to use for equations/assumptions # @param unit_multiplier [Integer] Number of similar dwelling units - # @return [TODO] TODO - def self.create_new_loop(model, t_set_c, eri_version, unit_multiplier) - # Create a new plant loop for the water heater + # @return [OpenStudio::Model::PlantLoop] The plant loop + def self.add_plant_loop(model, t_set_c, eri_version, unit_multiplier) name = 'dhw loop' if t_set_c.nil? t_set_c = UnitConversions.convert(Defaults.get_water_heater_temperature(eri_version), 'F', 'C') end - loop = OpenStudio::Model::PlantLoop.new(model) - loop.setName(name) - loop.sizingPlant.setDesignLoopExitTemperature(t_set_c) - loop.sizingPlant.setLoopDesignTemperatureDifference(UnitConversions.convert(10.0, 'deltaF', 'deltaC')) - loop.setPlantLoopVolume(0.003 * unit_multiplier) # ~1 gal - loop.setMaximumLoopFlowRate(0.01 * unit_multiplier) # This size represents the physical limitations to flow due to losses in the piping system. We assume that the pipes are always adequately sized. + plant_loop = Model.add_plant_loop( + model, + name: name, + volume: 0.003 * unit_multiplier, # ~1 gal + max_flow_rate: 0.01 * unit_multiplier # This size represents the physical limitations to flow due to losses in the piping system. We assume that the pipes are always adequately sized. + ) + + sizing_plant = plant_loop.sizingPlant + sizing_plant.setDesignLoopExitTemperature(t_set_c) + sizing_plant.setLoopDesignTemperatureDifference(UnitConversions.convert(10.0, 'deltaF', 'deltaC')) bypass_pipe = Model.add_pipe_adiabatic(model) out_pipe = Model.add_pipe_adiabatic(model) - loop.addSupplyBranchForComponent(bypass_pipe) - out_pipe.addToNode(loop.supplyOutletNode) + plant_loop.addSupplyBranchForComponent(bypass_pipe) + out_pipe.addToNode(plant_loop.supplyOutletNode) pump = Model.add_pump_variable_speed( model, name: "#{name} pump", rated_power: 0 ) - pump.addToNode(loop.supplyInletNode) + pump.addToNode(plant_loop.supplyInletNode) temp_schedule = Model.add_schedule_constant( model, @@ -2169,16 +2178,23 @@ def self.create_new_loop(model, t_set_c, eri_version, unit_multiplier) value: t_set_c ) setpoint_manager = OpenStudio::Model::SetpointManagerScheduled.new(model, temp_schedule) - setpoint_manager.addToNode(loop.supplyOutletNode) + setpoint_manager.addToNode(plant_loop.supplyOutletNode) - return loop + return plant_loop end - # TODO + # Gets the solar fraction, which is defined as the portion of total conventional hot water heating + # load (delivered energy plus tank standby losses) served by the solar thermal system. + # + # A value of zero will be returned unless all of these conditions are met: + # 1. There is a solar thermal system + # 2. The solar thermal system is attached to this water heater + # 3. The solar thermal system has simple inputs (i.e., solar fraction), as opposed to detailed + # inputs that would result in the solar thermal system being modeled explicitly in EnergyPlus. # # @param water_heating_system [HPXML::WaterHeatingSystem] The HPXML water heating system of interest # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit - # @return [TODO] TODO + # @return [Double] Solar fraction or zero def self.get_water_heater_solar_fraction(water_heating_system, hpxml_bldg) return 0.0 if hpxml_bldg.solar_thermal_systems.size == 0 diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/xmlhelper.rb b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/xmlhelper.rb index 05b66f4b7a..b6a9a0b731 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/resources/xmlhelper.rb +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/resources/xmlhelper.rb @@ -36,15 +36,18 @@ def self.insert_element(parent, element_name, index = 0, value = nil, datatype = parent.children.insert(index, added) end if not value.nil? - if datatype == :integer + case datatype + when :integer value = to_integer(value, parent, element_name) - elsif datatype == :float + when :float value = to_float(value, parent, element_name) - elsif datatype == :boolean + when :boolean value = to_boolean(value, parent, element_name) - elsif datatype != :string - # If value provided, datatype required - fail 'Unexpected datatype.' + else + if datatype != :string + # If value provided, datatype required + fail 'Unexpected datatype.' + end end added.inner_text = value.to_s end @@ -113,14 +116,17 @@ def self.get_value(parent, element_name, datatype) value = element.text - if datatype == :integer + case datatype + when :integer value = to_integer_or_nil(value, parent, element_name) - elsif datatype == :float + when :float value = to_float_or_nil(value, parent, element_name) - elsif datatype == :boolean + when :boolean value = to_boolean_or_nil(value, parent, element_name) - elsif datatype != :string - fail 'Unexpected datatype.' + else + if datatype != :string + fail 'Unexpected datatype.' + end end return value @@ -138,14 +144,17 @@ def self.get_values(parent, element_name, datatype) parent.xpath(element_name).each do |value| value = value.text - if datatype == :integer + case datatype + when :integer value = to_integer_or_nil(value, parent, element_name) - elsif datatype == :float + when :float value = to_float_or_nil(value, parent, element_name) - elsif datatype == :boolean + when :boolean value = to_boolean_or_nil(value, parent, element_name) - elsif datatype != :string - fail 'Unexpected datatype.' + else + if datatype != :string + fail 'Unexpected datatype.' + end end values << value diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_airflow.rb b/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_airflow.rb index d67967fa04..da1c90dbb8 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_airflow.rb +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_airflow.rb @@ -928,6 +928,26 @@ def test_duct_effective_r_values end end + def test_operational_0_occupants + args_hash = {} + args_hash['hpxml_path'] = File.absolute_path(File.join(@sample_files_path, 'base-residents-0.xml')) + model, _hpxml, _hpxml_bldg = _test_measure(args_hash) + + # Check no natural ventilation or whole house fan + program_values = get_ems_values(model.getEnergyManagementSystemPrograms, "#{Constants::ObjectTypeNaturalVentilation} program") + assert_equal(0, UnitConversions.convert(program_values['NVArea'].sum, 'cm^2', 'ft^2')) + assert_equal(0, UnitConversions.convert(program_values['WHF_Flow'].sum, 'm^3/s', 'cfm')) + + # Check no clothes dryer venting + program_values = get_ems_values(model.getEnergyManagementSystemPrograms, "#{Constants::ObjectTypeInfiltration} program") + assert_equal(0, UnitConversions.convert(program_values['Qdryer'].sum, 'm^3/s', 'cfm')) + + # Check no kitchen/bath local ventilation + program_values = get_ems_values(model.getEnergyManagementSystemPrograms, "#{Constants::ObjectTypeInfiltration} program") + assert_equal(0, UnitConversions.convert(program_values['Qrange'].sum, 'm^3/s', 'cfm')) + assert_equal(0, UnitConversions.convert(program_values['Qbath'].sum, 'm^3/s', 'cfm')) + end + def _test_measure(args_hash) # create an instance of the measure measure = HPXMLtoOpenStudio.new diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hotwater_appliance.rb b/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hotwater_appliance.rb index 20baadd275..619be06570 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hotwater_appliance.rb +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hotwater_appliance.rb @@ -952,6 +952,28 @@ def test_usage_multiplier assert_in_epsilon(1.0, get_oe_fractions(model, Constants::ObjectTypeGeneralWaterUseLatent)[1], 0.001) end + def test_operational_0_occupants + args_hash = {} + args_hash['hpxml_path'] = File.absolute_path(File.join(sample_files_dir, 'base-residents-0.xml')) + model, _hpxml, _hpxml_bldg = _test_measure(args_hash) + + # water use equipment hot water gal/day + assert_equal(0, get_wu_gpd(model, Constants::ObjectTypeClothesWasher)) + assert_equal(0, get_wu_gpd(model, Constants::ObjectTypeDishwasher)) + assert_equal(0, get_wu_gpd(model, Constants::ObjectTypeFixtures)) + assert_equal(0, get_wu_gpd(model, Constants::ObjectTypeDistributionWaste)) + + # electric equipment + assert_equal(0, get_ee_kwh_per_year(model, Constants::ObjectTypeClothesWasher)) + assert_equal(0, get_ee_kwh_per_year(model, Constants::ObjectTypeDishwasher)) + assert_equal(0, get_ee_kwh_per_year(model, Constants::ObjectTypeClothesDryer)) + assert_equal(0, get_ee_kwh_per_year(model, Constants::ObjectTypeCookingRange)) + + # other equipment + assert_equal(0, get_oe_kwh(model, Constants::ObjectTypeGeneralWaterUseSensible)) + assert_equal(0, get_oe_kwh(model, Constants::ObjectTypeGeneralWaterUseLatent)) + end + def test_operational_1_occupant args_hash = {} args_hash['hpxml_path'] = File.absolute_path(File.join(sample_files_dir, 'base-residents-1.xml')) diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_lighting.rb b/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_lighting.rb index 9c92c57028..467f8acc41 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_lighting.rb +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_lighting.rb @@ -133,6 +133,21 @@ def test_ceiling_fan assert_in_delta(200, get_kwh_per_year(model, Constants::ObjectTypeCeilingFan), 1.0) end + def test_operational_0_occupants + args_hash = {} + args_hash['hpxml_path'] = File.absolute_path(File.join(sample_files_dir, 'base-residents-0.xml')) + model, _hpxml, _hpxml_bldg = _test_measure(args_hash) + + # Check interior lighting + assert_equal(0.0, get_kwh_per_year(model, Constants::ObjectTypeLightingInterior)) + + # Check garage lighting + assert_equal(0.0, get_kwh_per_year(model, Constants::ObjectTypeLightingGarage)) + + # Check exterior lighting + assert_equal(0.0, get_kwh_per_year(model, Constants::ObjectTypeLightingExterior)) + end + def _test_measure(args_hash) # create an instance of the measure measure = HPXMLtoOpenStudio.new diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_miscloads.rb b/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_miscloads.rb index b8e0121688..66e03f7376 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_miscloads.rb +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_miscloads.rb @@ -195,7 +195,68 @@ def test_large_uncommon_loads2 assert_in_delta(55, therm_yr, 1.0) end - def test_operational_defaults + def test_operational_0_occupants + args_hash = {} + args_hash['hpxml_path'] = File.absolute_path(File.join(sample_files_dir, 'base-residents-0.xml')) + model, _hpxml, _hpxml_bldg = _test_measure(args_hash) + + # Check misc plug loads + kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscPlugLoads) + assert_equal(0, kwh_yr) + assert_equal(0, therm_yr) + + # Check television + kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscTelevision) + assert_equal(0, kwh_yr) + assert_equal(0, therm_yr) + + # Check vehicle + kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscElectricVehicleCharging) + assert_equal(0, kwh_yr) + assert_equal(0, therm_yr) + + # Check well pump + kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscWellPump) + assert_equal(0, kwh_yr) + assert_equal(0, therm_yr) + + # Check pool pump + kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscPoolPump) + assert_equal(0, kwh_yr) + assert_equal(0, therm_yr) + + # Check pool heater + kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscPoolHeater) + assert_equal(0, kwh_yr) + assert_equal(0, therm_yr) + + # Check permanent spa pump + kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscPermanentSpaPump) + assert_equal(0, kwh_yr) + assert_equal(0, therm_yr) + + # Check permanent spa heater + kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscPermanentSpaHeater) + assert_equal(0, kwh_yr) + assert_equal(0, therm_yr) + + # Check grill + kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscGrill) + assert_equal(0, kwh_yr) + assert_equal(0, therm_yr) + + # Check lighting + kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscLighting) + assert_equal(0, kwh_yr) + assert_equal(0, therm_yr) + + # Check fireplace + kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscFireplace) + assert_equal(0, kwh_yr) + assert_equal(0, therm_yr) + end + + def test_operational_5_5_occupants args_hash = {} args_hash['hpxml_path'] = File.absolute_path(File.join(sample_files_dir, 'base-residents-5-5.xml')) model, _hpxml, _hpxml_bldg = _test_measure(args_hash) diff --git a/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_validation.rb b/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_validation.rb index 485f6105de..21f4bf08e0 100644 --- a/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_validation.rb +++ b/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_validation.rb @@ -270,79 +270,80 @@ def test_schema_schematron_error_messages all_expected_errors.each_with_index do |(error_case, expected_errors), i| puts "[#{i + 1}/#{all_expected_errors.size}] Testing #{error_case}..." # Create HPXML object - if ['boiler-invalid-afue'].include? error_case + case error_case + when 'boiler-invalid-afue' hpxml, hpxml_bldg = _create_hpxml('base-hvac-boiler-oil-only.xml') hpxml_bldg.heating_systems[0].heating_efficiency_afue *= 100.0 - elsif ['clothes-dryer-location'].include? error_case + when 'clothes-dryer-location' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.clothes_dryers[0].location = HPXML::LocationGarage - elsif ['clothes-washer-location'].include? error_case + when 'clothes-washer-location' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.clothes_washers[0].location = HPXML::LocationGarage - elsif ['cooking-range-location'].include? error_case + when 'cooking-range-location' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.cooking_ranges[0].location = HPXML::LocationGarage - elsif ['dehumidifier-fraction-served'].include? error_case + when 'dehumidifier-fraction-served' hpxml, hpxml_bldg = _create_hpxml('base-appliances-dehumidifier-multiple.xml') hpxml_bldg.dehumidifiers[-1].fraction_served = 0.6 - elsif ['dhw-frac-load-served'].include? error_case + when 'dhw-frac-load-served' hpxml, hpxml_bldg = _create_hpxml('base-dhw-multiple.xml') hpxml_bldg.water_heating_systems[0].fraction_dhw_load_served = 0.35 - elsif ['dhw-invalid-ef-tank'].include? error_case + when 'dhw-invalid-ef-tank' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.water_heating_systems[0].energy_factor = 1.0 - elsif ['dhw-invalid-uef-tank-heat-pump'].include? error_case + when 'dhw-invalid-uef-tank-heat-pump' hpxml, hpxml_bldg = _create_hpxml('base-dhw-tank-heat-pump-uef.xml') hpxml_bldg.water_heating_systems[0].uniform_energy_factor = 1.0 - elsif ['dishwasher-location'].include? error_case + when 'dishwasher-location' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.dishwashers[0].location = HPXML::LocationGarage - elsif ['duct-leakage-cfm25'].include? error_case + when 'duct-leakage-cfm25' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.hvac_distributions[0].duct_leakage_measurements[0].duct_leakage_value = -2 hpxml_bldg.hvac_distributions[0].duct_leakage_measurements[1].duct_leakage_value = -3 - elsif ['duct-leakage-cfm50'].include? error_case + when 'duct-leakage-cfm50' hpxml, hpxml_bldg = _create_hpxml('base-hvac-ducts-leakage-cfm50.xml') hpxml_bldg.hvac_distributions[0].duct_leakage_measurements[0].duct_leakage_value = -2 hpxml_bldg.hvac_distributions[0].duct_leakage_measurements[1].duct_leakage_value = -3 - elsif ['duct-leakage-percent'].include? error_case + when 'duct-leakage-percent' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.hvac_distributions[0].duct_leakage_measurements[0].duct_leakage_units = HPXML::UnitsPercent hpxml_bldg.hvac_distributions[0].duct_leakage_measurements[1].duct_leakage_units = HPXML::UnitsPercent - elsif ['duct-location'].include? error_case + when 'duct-location' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.hvac_distributions[0].ducts[0].duct_location = HPXML::LocationGarage hpxml_bldg.hvac_distributions[0].ducts[1].duct_location = HPXML::LocationGarage - elsif ['duct-location-unconditioned-space'].include? error_case + when 'duct-location-unconditioned-space' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.hvac_distributions[0].ducts[0].duct_location = HPXML::LocationUnconditionedSpace hpxml_bldg.hvac_distributions[0].ducts[1].duct_location = HPXML::LocationUnconditionedSpace - elsif ['emissions-electricity-schedule'].include? error_case + when 'emissions-electricity-schedule' hpxml, hpxml_bldg = _create_hpxml('base-misc-emissions.xml') hpxml.header.emissions_scenarios[0].elec_schedule_number_of_header_rows = -1 hpxml.header.emissions_scenarios[0].elec_schedule_column_number = 0 - elsif ['enclosure-attic-missing-roof'].include? error_case + when 'enclosure-attic-missing-roof' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.roofs.reverse_each do |roof| roof.delete end - elsif ['enclosure-basement-missing-exterior-foundation-wall'].include? error_case + when 'enclosure-basement-missing-exterior-foundation-wall' hpxml, hpxml_bldg = _create_hpxml('base-foundation-unconditioned-basement.xml') hpxml_bldg.foundation_walls.reverse_each do |foundation_wall| foundation_wall.delete end - elsif ['enclosure-basement-missing-slab'].include? error_case + when 'enclosure-basement-missing-slab' hpxml, hpxml_bldg = _create_hpxml('base-foundation-unconditioned-basement.xml') hpxml_bldg.slabs.reverse_each do |slab| slab.delete end - elsif ['enclosure-floor-area-exceeds-cfa'].include? error_case + when 'enclosure-floor-area-exceeds-cfa' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.building_construction.conditioned_floor_area = 1348.8 - elsif ['enclosure-floor-area-exceeds-cfa2'].include? error_case + when 'enclosure-floor-area-exceeds-cfa2' hpxml, hpxml_bldg = _create_hpxml('base-bldgtype-mf-unit.xml') hpxml_bldg.building_construction.conditioned_floor_area = 898.8 - elsif ['enclosure-garage-missing-exterior-wall'].include? error_case + when 'enclosure-garage-missing-exterior-wall' hpxml, hpxml_bldg = _create_hpxml('base-enclosure-garage.xml') hpxml_bldg.walls.select { |w| w.interior_adjacent_to == HPXML::LocationGarage && @@ -350,7 +351,7 @@ def test_schema_schematron_error_messages }.reverse_each do |wall| wall.delete end - elsif ['enclosure-garage-missing-roof-ceiling'].include? error_case + when 'enclosure-garage-missing-roof-ceiling' hpxml, hpxml_bldg = _create_hpxml('base-enclosure-garage.xml') hpxml_bldg.floors.select { |w| w.interior_adjacent_to == HPXML::LocationGarage && @@ -358,75 +359,75 @@ def test_schema_schematron_error_messages }.reverse_each do |floor| floor.delete end - elsif ['enclosure-garage-missing-slab'].include? error_case + when 'enclosure-garage-missing-slab' hpxml, hpxml_bldg = _create_hpxml('base-enclosure-garage.xml') hpxml_bldg.slabs.select { |w| w.interior_adjacent_to == HPXML::LocationGarage }.reverse_each do |slab| slab.delete end - elsif ['enclosure-conditioned-missing-ceiling-roof'].include? error_case + when 'enclosure-conditioned-missing-ceiling-roof' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.floors.reverse_each do |floor| floor.delete end - elsif ['enclosure-conditioned-missing-exterior-wall'].include? error_case + when 'enclosure-conditioned-missing-exterior-wall' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.walls.reverse_each do |wall| next unless wall.interior_adjacent_to == HPXML::LocationConditionedSpace wall.delete end - elsif ['enclosure-conditioned-missing-floor-slab'].include? error_case + when 'enclosure-conditioned-missing-floor-slab' hpxml, hpxml_bldg = _create_hpxml('base-foundation-slab.xml') hpxml_bldg.slabs[0].delete - elsif ['frac-sensible-latent-fuel-load-values'].include? error_case + when 'frac-sensible-latent-fuel-load-values' hpxml, hpxml_bldg = _create_hpxml('base-misc-loads-large-uncommon.xml') hpxml_bldg.fuel_loads[0].frac_sensible = -0.1 hpxml_bldg.fuel_loads[0].frac_latent = -0.1 - elsif ['frac-sensible-latent-fuel-load-presence'].include? error_case + when 'frac-sensible-latent-fuel-load-presence' hpxml, hpxml_bldg = _create_hpxml('base-misc-loads-large-uncommon.xml') hpxml_bldg.fuel_loads[0].frac_sensible = 1.0 hpxml_bldg.fuel_loads[0].frac_latent = nil - elsif ['frac-sensible-latent-plug-load-values'].include? error_case + when 'frac-sensible-latent-plug-load-values' hpxml, hpxml_bldg = _create_hpxml('base-misc-loads-large-uncommon.xml') hpxml_bldg.plug_loads[0].frac_sensible = -0.1 hpxml_bldg.plug_loads[0].frac_latent = -0.1 - elsif ['frac-sensible-latent-plug-load-presence'].include? error_case + when 'frac-sensible-latent-plug-load-presence' hpxml, hpxml_bldg = _create_hpxml('base-misc-loads-large-uncommon.xml') hpxml_bldg.plug_loads[0].frac_latent = 1.0 hpxml_bldg.plug_loads[0].frac_sensible = nil - elsif ['frac-total-fuel-load'].include? error_case + when 'frac-total-fuel-load' hpxml, hpxml_bldg = _create_hpxml('base-misc-loads-large-uncommon.xml') hpxml_bldg.fuel_loads[0].frac_sensible = 0.8 hpxml_bldg.fuel_loads[0].frac_latent = 0.3 - elsif ['frac-total-plug-load'].include? error_case + when 'frac-total-plug-load' hpxml, hpxml_bldg = _create_hpxml('base-misc-loads-large-uncommon.xml') hpxml_bldg.plug_loads[1].frac_latent = 0.245 - elsif ['furnace-invalid-afue'].include? error_case + when 'furnace-invalid-afue' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.heating_systems[0].heating_efficiency_afue *= 100.0 - elsif ['generator-number-of-bedrooms-served'].include? error_case + when 'generator-number-of-bedrooms-served' hpxml, hpxml_bldg = _create_hpxml('base-bldgtype-mf-unit-shared-generator.xml') hpxml_bldg.generators[0].number_of_bedrooms_served = 3 - elsif ['generator-output-greater-than-consumption'].include? error_case + when 'generator-output-greater-than-consumption' hpxml, hpxml_bldg = _create_hpxml('base-misc-generators.xml') hpxml_bldg.generators[0].annual_consumption_kbtu = 1500 - elsif ['heat-pump-backup-sizing'].include? error_case + when 'heat-pump-backup-sizing' hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-1-speed.xml') hpxml_bldg.header.heat_pump_backup_sizing_methodology = 'foobar' - elsif ['heat-pump-separate-backup-inputs'].include? error_case + when 'heat-pump-separate-backup-inputs' hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-var-speed-backup-furnace.xml') hpxml_bldg.heat_pumps[0].backup_heating_capacity = 12345 hpxml_bldg.heat_pumps[0].backup_heating_efficiency_afue = 0.8 hpxml_bldg.heat_pumps[0].backup_heating_autosizing_factor = 1.2 - elsif ['heat-pump-capacity-17f'].include? error_case + when 'heat-pump-capacity-17f' hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-1-speed.xml') hpxml_bldg.heat_pumps[0].heating_capacity_17F = hpxml_bldg.heat_pumps[0].heating_capacity + 1000.0 hpxml_bldg.heat_pumps[0].heating_capacity_retention_fraction = nil hpxml_bldg.heat_pumps[0].heating_capacity_retention_temp = nil - elsif ['heat-pump-lockout-temperatures'].include? error_case + when 'heat-pump-lockout-temperatures' hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-1-speed-lockout-temperatures.xml') hpxml_bldg.heat_pumps[0].compressor_lockout_temp = hpxml_bldg.heat_pumps[0].backup_heating_lockout_temp + 1 - elsif ['heat-pump-multiple-backup-systems'].include? error_case + when 'heat-pump-multiple-backup-systems' hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-var-speed-backup-boiler.xml') hpxml_bldg.heating_systems << hpxml_bldg.heating_systems[0].dup hpxml_bldg.heating_systems[-1].id = 'HeatingSystem2' @@ -436,13 +437,13 @@ def test_schema_schematron_error_messages hpxml_bldg.heat_pumps[-1].id = 'HeatPump2' hpxml_bldg.heat_pumps[-1].primary_heating_system = false hpxml_bldg.heat_pumps[-1].primary_cooling_system = false - elsif ['hvac-detailed-performance-not-variable-speed'].include? error_case + when 'hvac-detailed-performance-not-variable-speed' hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-var-speed-detailed-performance.xml') hpxml_bldg.heat_pumps[0].compressor_type = HPXML::HVACCompressorTypeTwoStage - elsif ['hvac-distribution-return-duct-leakage-missing'].include? error_case + when 'hvac-distribution-return-duct-leakage-missing' hpxml, hpxml_bldg = _create_hpxml('base-hvac-evap-cooler-only-ducted.xml') hpxml_bldg.hvac_distributions[0].duct_leakage_measurements[-1].delete - elsif ['hvac-frac-load-served'].include? error_case + when 'hvac-frac-load-served' hpxml, hpxml_bldg = _create_hpxml('base-hvac-multiple.xml') hpxml_bldg.heating_systems[0].fraction_heat_load_served += 0.1 hpxml_bldg.cooling_systems[0].fraction_cool_load_served += 0.2 @@ -450,22 +451,22 @@ def test_schema_schematron_error_messages hpxml_bldg.cooling_systems[0].primary_system = true hpxml_bldg.heat_pumps[-1].primary_heating_system = false hpxml_bldg.heat_pumps[-1].primary_cooling_system = false - elsif ['hvac-research-features-timestep-ten-mins'].include? error_case + when 'hvac-research-features-timestep-ten-mins' hpxml, _hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-1-speed-research-features.xml') hpxml.header.timestep = 10 - elsif ['hvac-research-features-timestep-missing'].include? error_case + when 'hvac-research-features-timestep-missing' hpxml, _hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-1-speed-research-features.xml') hpxml.header.timestep = nil - elsif ['hvac-research-features-onoff-thermostat-heat-load-fraction-partial'].include? error_case + when 'hvac-research-features-onoff-thermostat-heat-load-fraction-partial' hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-1-speed-research-features.xml') hpxml_bldg.heat_pumps[0].fraction_heat_load_served = 0.5 - elsif ['hvac-research-features-onoff-thermostat-cool-load-fraction-partial'].include? error_case + when 'hvac-research-features-onoff-thermostat-cool-load-fraction-partial' hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-1-speed-research-features.xml') hpxml_bldg.heat_pumps[0].fraction_cool_load_served = 0.5 - elsif ['hvac-research-features-onoff-thermostat-negative-value'].include? error_case + when 'hvac-research-features-onoff-thermostat-negative-value' hpxml, _hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-1-speed-research-features.xml') hpxml.header.hvac_onoff_thermostat_deadband = -1.0 - elsif ['hvac-research-features-onoff-thermostat-two-heat-pumps'].include? error_case + when 'hvac-research-features-onoff-thermostat-two-heat-pumps' hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-1-speed-research-features.xml') hpxml_bldg.heat_pumps[0].fraction_cool_load_served = 0.5 hpxml_bldg.heat_pumps[0].fraction_heat_load_served = 0.5 @@ -473,80 +474,80 @@ def test_schema_schematron_error_messages hpxml_bldg.heat_pumps[-1].id = 'HeatPump2' hpxml_bldg.heat_pumps[-1].primary_heating_system = false hpxml_bldg.heat_pumps[-1].primary_cooling_system = false - elsif ['hvac-gshp-invalid-bore-config'].include? error_case + when 'hvac-gshp-invalid-bore-config' hpxml, hpxml_bldg = _create_hpxml('base-hvac-ground-to-air-heat-pump-detailed-geothermal-loop.xml') hpxml_bldg.geothermal_loops[0].bore_config = 'Invalid' - elsif ['hvac-gshp-invalid-bore-depth-low'].include? error_case + when 'hvac-gshp-invalid-bore-depth-low' hpxml, hpxml_bldg = _create_hpxml('base-hvac-ground-to-air-heat-pump-detailed-geothermal-loop.xml') hpxml_bldg.geothermal_loops[0].bore_length = 78 - elsif ['hvac-gshp-invalid-bore-depth-high'].include? error_case + when 'hvac-gshp-invalid-bore-depth-high' hpxml, hpxml_bldg = _create_hpxml('base-hvac-ground-to-air-heat-pump-detailed-geothermal-loop.xml') hpxml_bldg.geothermal_loops[0].bore_length = 501 - elsif ['hvac-gshp-autosized-count-not-rectangle'].include? error_case + when 'hvac-gshp-autosized-count-not-rectangle' hpxml, hpxml_bldg = _create_hpxml('base-hvac-ground-to-air-heat-pump-detailed-geothermal-loop.xml') hpxml_bldg.geothermal_loops[0].num_bore_holes = nil - elsif ['hvac-location-heating-system'].include? error_case + when 'hvac-location-heating-system' hpxml, hpxml_bldg = _create_hpxml('base-hvac-boiler-oil-only.xml') hpxml_bldg.heating_systems[0].location = HPXML::LocationBasementUnconditioned - elsif ['hvac-location-cooling-system'].include? error_case + when 'hvac-location-cooling-system' hpxml, hpxml_bldg = _create_hpxml('base-hvac-central-ac-only-1-speed.xml') hpxml_bldg.cooling_systems[0].location = HPXML::LocationBasementUnconditioned - elsif ['hvac-location-heat-pump'].include? error_case + when 'hvac-location-heat-pump' hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-1-speed.xml') hpxml_bldg.heat_pumps[0].location = HPXML::LocationBasementUnconditioned - elsif ['hvac-msac-not-var-speed'].include? error_case + when 'hvac-msac-not-var-speed' hpxml, hpxml_bldg = _create_hpxml('base-hvac-mini-split-air-conditioner-only-ductless.xml') hpxml_bldg.cooling_systems[0].compressor_type = HPXML::HVACCompressorTypeTwoStage - elsif ['hvac-mshp-not-var-speed'].include? error_case + when 'hvac-mshp-not-var-speed' hpxml, hpxml_bldg = _create_hpxml('base-hvac-mini-split-heat-pump-ductless.xml') hpxml_bldg.heat_pumps[0].compressor_type = HPXML::HVACCompressorTypeSingleStage - elsif ['hvac-shr-low'].include? error_case + when 'hvac-shr-low' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.cooling_systems[0].cooling_shr = 0.4 - elsif ['hvac-sizing-humidity-setpoint'].include? error_case + when 'hvac-sizing-humidity-setpoint' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.header.manualj_humidity_setpoint = 50 - elsif ['hvac-sizing-daily-temp-range'].include? error_case + when 'hvac-sizing-daily-temp-range' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.header.manualj_daily_temp_range = 'foobar' - elsif ['hvac-negative-crankcase-heater-watts'].include? error_case + when 'hvac-negative-crankcase-heater-watts' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.cooling_systems[0].crankcase_heater_watts = -10 - elsif ['incomplete-integrated-heating'].include? error_case + when 'incomplete-integrated-heating' hpxml, hpxml_bldg = _create_hpxml('base-hvac-ptac-with-heating-electricity.xml') hpxml_bldg.cooling_systems[0].integrated_heating_system_fraction_heat_load_served = nil - elsif ['invalid-airflow-defect-ratio'].include? error_case + when 'invalid-airflow-defect-ratio' hpxml, hpxml_bldg = _create_hpxml('base-hvac-mini-split-heat-pump-ductless.xml') hpxml_bldg.heat_pumps[0].airflow_defect_ratio = -0.25 - elsif ['invalid-assembly-effective-rvalue'].include? error_case + when 'invalid-assembly-effective-rvalue' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.walls[0].insulation_assembly_r_value = 0.0 - elsif ['invalid-battery-capacities-ah'].include? error_case + when 'invalid-battery-capacities-ah' hpxml, hpxml_bldg = _create_hpxml('base-pv-battery-ah.xml') hpxml_bldg.batteries[0].usable_capacity_ah = hpxml_bldg.batteries[0].nominal_capacity_ah - elsif ['invalid-battery-capacities-kwh'].include? error_case + when 'invalid-battery-capacities-kwh' hpxml, hpxml_bldg = _create_hpxml('base-pv-battery.xml') hpxml_bldg.batteries[0].usable_capacity_kwh = hpxml_bldg.batteries[0].nominal_capacity_kwh - elsif ['invalid-calendar-year-low'].include? error_case + when 'invalid-calendar-year-low' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml.header.sim_calendar_year = 1575 - elsif ['invalid-calendar-year-high'].include? error_case + when 'invalid-calendar-year-high' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml.header.sim_calendar_year = 20000 - elsif ['invalid-clothes-dryer-cef'].include? error_case + when 'invalid-clothes-dryer-cef' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.clothes_dryers[0].combined_energy_factor = 0 - elsif ['invalid-clothes-washer-imef'].include? error_case + when 'invalid-clothes-washer-imef' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.clothes_washers[0].integrated_modified_energy_factor = 0 - elsif ['invalid-cfis-addtl-runtime-mode'].include? error_case + when 'invalid-cfis-addtl-runtime-mode' hpxml, hpxml_bldg = _create_hpxml('base-mechvent-cfis-control-type-timer.xml') hpxml_bldg.ventilation_fans[0].cfis_addtl_runtime_operating_mode = HPXML::CFISModeNone hpxml_bldg.ventilation_fans[0].fan_power = nil - elsif ['invalid-dishwasher-ler'].include? error_case + when 'invalid-dishwasher-ler' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.dishwashers[0].label_electric_rate = 0 - elsif ['invalid-duct-area-fractions'].include? error_case + when 'invalid-duct-area-fractions' hpxml, hpxml_bldg = _create_hpxml('base-hvac-ducts-area-fractions.xml') hpxml_bldg.hvac_distributions[0].ducts[0].duct_surface_area = nil hpxml_bldg.hvac_distributions[0].ducts[1].duct_surface_area = nil @@ -556,41 +557,41 @@ def test_schema_schematron_error_messages hpxml_bldg.hvac_distributions[0].ducts[1].duct_fraction_area = 0.65 hpxml_bldg.hvac_distributions[0].ducts[2].duct_fraction_area = 0.15 hpxml_bldg.hvac_distributions[0].ducts[3].duct_fraction_area = 0.15 - elsif ['invalid-facility-type'].include? error_case + when 'invalid-facility-type' hpxml, hpxml_bldg = _create_hpxml('base-bldgtype-mf-unit-shared-laundry-room.xml') hpxml_bldg.building_construction.residential_facility_type = HPXML::ResidentialTypeSFD - elsif ['invalid-foundation-wall-properties'].include? error_case + when 'invalid-foundation-wall-properties' hpxml, hpxml_bldg = _create_hpxml('base-foundation-unconditioned-basement-wall-insulation.xml') hpxml_bldg.foundation_walls[0].depth_below_grade = 9.0 hpxml_bldg.foundation_walls[0].insulation_interior_distance_to_top = 12.0 hpxml_bldg.foundation_walls[0].insulation_interior_distance_to_bottom = 10.0 - elsif ['invalid-ground-conductivity'].include? error_case + when 'invalid-ground-conductivity' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.site.ground_conductivity = 0.0 - elsif ['invalid-ground-diffusivity'].include? error_case + when 'invalid-ground-diffusivity' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.site.ground_diffusivity = 0.0 - elsif ['invalid-heat-pump-capacity-retention'].include? error_case + when 'invalid-heat-pump-capacity-retention' hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-1-speed.xml') hpxml_bldg.heat_pumps[0].heating_capacity_17F = nil hpxml_bldg.heat_pumps[0].heating_capacity_retention_fraction = 1.5 hpxml_bldg.heat_pumps[0].heating_capacity_retention_temp = 30 - elsif ['invalid-heat-pump-capacity-retention2'].include? error_case + when 'invalid-heat-pump-capacity-retention2' hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-1-speed.xml') hpxml_bldg.heat_pumps[0].heating_capacity_17F = nil hpxml_bldg.heat_pumps[0].heating_capacity_retention_fraction = -1 hpxml_bldg.heat_pumps[0].heating_capacity_retention_temp = 5 - elsif ['invalid-hvac-installation-quality'].include? error_case + when 'invalid-hvac-installation-quality' hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-1-speed.xml') hpxml_bldg.heat_pumps[0].airflow_defect_ratio = -99 hpxml_bldg.heat_pumps[0].charge_defect_ratio = -99 - elsif ['invalid-hvac-installation-quality2'].include? error_case + when 'invalid-hvac-installation-quality2' hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-1-speed.xml') hpxml_bldg.heat_pumps[0].airflow_defect_ratio = 99 hpxml_bldg.heat_pumps[0].charge_defect_ratio = 99 - elsif ['invalid-id2'].include? error_case + when 'invalid-id2' hpxml, hpxml_bldg = _create_hpxml('base-enclosure-skylights.xml') - elsif ['invalid-input-parameters'].include? error_case + when 'invalid-input-parameters' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml.header.transaction = 'modify' hpxml_bldg.site.site_type = 'mountain' @@ -601,15 +602,15 @@ def test_schema_schematron_error_messages hpxml_bldg.roofs[0].azimuth = 365 hpxml_bldg.dishwashers[0].rated_annual_kwh = nil hpxml_bldg.dishwashers[0].energy_factor = 5.1 - elsif ['invalid-insulation-top'].include? error_case + when 'invalid-insulation-top' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.foundation_walls[0].insulation_interior_distance_to_top = -0.5 - elsif ['invalid-integrated-heating'].include? error_case + when 'invalid-integrated-heating' hpxml, hpxml_bldg = _create_hpxml('base-hvac-central-ac-only-1-speed.xml') hpxml_bldg.cooling_systems[0].integrated_heating_system_fuel = HPXML::FuelTypeElectricity hpxml_bldg.cooling_systems[0].integrated_heating_system_efficiency_percent = 0.98 hpxml_bldg.cooling_systems[0].integrated_heating_system_fraction_heat_load_served = 1.0 - elsif ['invalid-lighting-groups'].include? error_case + when 'invalid-lighting-groups' hpxml, hpxml_bldg = _create_hpxml('base-enclosure-garage.xml') [HPXML::LocationInterior, HPXML::LocationExterior, HPXML::LocationGarage].each do |ltg_loc| hpxml_bldg.lighting_groups.each do |lg| @@ -619,7 +620,7 @@ def test_schema_schematron_error_messages break end end - elsif ['invalid-lighting-groups2'].include? error_case + when 'invalid-lighting-groups2' hpxml, hpxml_bldg = _create_hpxml('base-enclosure-garage.xml') [HPXML::LocationInterior, HPXML::LocationExterior, HPXML::LocationGarage].each do |ltg_loc| hpxml_bldg.lighting_groups.each do |lg| @@ -631,75 +632,75 @@ def test_schema_schematron_error_messages break end end - elsif ['invalid-natvent-availability'].include? error_case + when 'invalid-natvent-availability' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.header.natvent_days_per_week = 8 - elsif ['invalid-natvent-availability2'].include? error_case + when 'invalid-natvent-availability2' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.header.natvent_days_per_week = -1 - elsif ['invalid-number-of-bedrooms-served-pv'].include? error_case + when 'invalid-number-of-bedrooms-served-pv' hpxml, hpxml_bldg = _create_hpxml('base-bldgtype-mf-unit-shared-pv.xml') hpxml_bldg.pv_systems[0].number_of_bedrooms_served = 3 - elsif ['invalid-number-of-bedrooms-served-recirc'].include? error_case + when 'invalid-number-of-bedrooms-served-recirc' hpxml, hpxml_bldg = _create_hpxml('base-bldgtype-mf-unit-shared-water-heater-recirc.xml') hpxml_bldg.hot_water_distributions[0].shared_recirculation_number_of_bedrooms_served = 3 - elsif ['invalid-number-of-bedrooms-served-water-heater'].include? error_case + when 'invalid-number-of-bedrooms-served-water-heater' hpxml, hpxml_bldg = _create_hpxml('base-bldgtype-mf-unit-shared-water-heater.xml') hpxml_bldg.water_heating_systems[0].number_of_bedrooms_served = 3 - elsif ['invalid-number-of-conditioned-floors'].include? error_case + when 'invalid-number-of-conditioned-floors' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.building_construction.number_of_conditioned_floors_above_grade = 3 - elsif ['invalid-number-of-conditioned-floors-above-grade'].include? error_case + when 'invalid-number-of-conditioned-floors-above-grade' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.building_construction.number_of_conditioned_floors_above_grade = 0 - elsif ['invalid-pilot-light-heating-system'].include? error_case + when 'invalid-pilot-light-heating-system' hpxml, hpxml_bldg = _create_hpxml('base-hvac-floor-furnace-propane-only.xml') hpxml_bldg.heating_systems[0].heating_system_fuel = HPXML::FuelTypeElectricity - elsif ['invalid-soil-type'].include? error_case + when 'invalid-soil-type' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.site.soil_type = HPXML::SiteSoilTypeOther - elsif ['invalid-shared-vent-in-unit-flowrate'].include? error_case + when 'invalid-shared-vent-in-unit-flowrate' hpxml, hpxml_bldg = _create_hpxml('base-bldgtype-mf-unit-shared-mechvent.xml') hpxml_bldg.ventilation_fans[0].rated_flow_rate = 80 - elsif ['invalid-timestep'].include? error_case + when 'invalid-timestep' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml.header.timestep = 45 - elsif ['invalid-timezone-utcoffset-low'].include? error_case + when 'invalid-timezone-utcoffset-low' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.time_zone_utc_offset = -13 - elsif ['invalid-timezone-utcoffset-high'].include? error_case + when 'invalid-timezone-utcoffset-high' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.time_zone_utc_offset = 15 - elsif ['invalid-ventilation-fan'].include? error_case + when 'invalid-ventilation-fan' hpxml, hpxml_bldg = _create_hpxml('base-mechvent-exhaust.xml') hpxml_bldg.ventilation_fans[0].used_for_garage_ventilation = true - elsif ['invalid-ventilation-recovery'].include? error_case + when 'invalid-ventilation-recovery' hpxml, hpxml_bldg = _create_hpxml('base-mechvent-exhaust.xml') hpxml_bldg.ventilation_fans[0].sensible_recovery_efficiency = 0.72 hpxml_bldg.ventilation_fans[0].total_recovery_efficiency = 0.48 - elsif ['invalid-water-heater-heating-capacity'].include? error_case + when 'invalid-water-heater-heating-capacity' hpxml, hpxml_bldg = _create_hpxml('base-dhw-tank-gas.xml') hpxml_bldg.water_heating_systems[0].heating_capacity = 0 - elsif ['invalid-water-heater-heating-capacity2'].include? error_case + when 'invalid-water-heater-heating-capacity2' hpxml, hpxml_bldg = _create_hpxml('base-dhw-tank-heat-pump.xml') hpxml_bldg.water_heating_systems[0].heating_capacity = 0 - elsif ['invalid-window-height'].include? error_case + when 'invalid-window-height' hpxml, hpxml_bldg = _create_hpxml('base-enclosure-overhangs.xml') hpxml_bldg.windows[1].overhangs_distance_to_bottom_of_window = 1.0 - elsif ['leakiness-description-missing-year-built'].include? error_case + when 'leakiness-description-missing-year-built' hpxml, hpxml_bldg = _create_hpxml('base-enclosure-infil-leakiness-description.xml') hpxml_bldg.building_construction.year_built = nil - elsif ['lighting-fractions'].include? error_case + when 'lighting-fractions' hpxml, hpxml_bldg = _create_hpxml('base.xml') int_cfl = hpxml_bldg.lighting_groups.find { |lg| lg.location == HPXML::LocationInterior && lg.lighting_type == HPXML::LightingTypeCFL } int_cfl.fraction_of_units_in_location = 0.8 - elsif ['manufactured-home-reference-duct'].include? error_case + when 'manufactured-home-reference-duct' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.hvac_distributions[0].ducts[1].duct_location = HPXML::LocationManufacturedHomeBelly - elsif ['manufactured-home-reference-water-heater'].include? error_case + when 'manufactured-home-reference-water-heater' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.water_heating_systems[0].location = HPXML::LocationManufacturedHomeBelly - elsif ['manufactured-home-reference-floor'].include? error_case + when 'manufactured-home-reference-floor' hpxml, hpxml_bldg = _create_hpxml('base-foundation-vented-crawlspace.xml') hpxml_bldg.floors.each do |floor| if floor.exterior_adjacent_to == HPXML::LocationCrawlspaceVented @@ -707,97 +708,97 @@ def test_schema_schematron_error_messages break end end - elsif ['missing-attached-to-space-wall'].include? error_case + when 'missing-attached-to-space-wall' hpxml, hpxml_bldg = _create_hpxml('base-zones-spaces.xml') hpxml_bldg.walls.find { |s| s.interior_adjacent_to == HPXML::LocationConditionedSpace }.attached_to_space_idref = nil - elsif ['missing-attached-to-space-slab'].include? error_case + when 'missing-attached-to-space-slab' hpxml, hpxml_bldg = _create_hpxml('base-zones-spaces.xml') hpxml_bldg.slabs.find { |s| s.interior_adjacent_to == HPXML::LocationBasementConditioned }.attached_to_space_idref = nil - elsif ['missing-attached-to-zone'].include? error_case + when 'missing-attached-to-zone' hpxml, hpxml_bldg = _create_hpxml('base-zones-spaces.xml') hpxml_bldg.hvac_systems[0].attached_to_zone_idref = nil - elsif ['missing-capacity-detailed-performance'].include? error_case + when 'missing-capacity-detailed-performance' hpxml, hpxml_bldg = _create_hpxml('base-hvac-mini-split-heat-pump-ductless-detailed-performance.xml') hpxml_bldg.heat_pumps[0].cooling_capacity = nil hpxml_bldg.heat_pumps[0].heating_capacity = nil - elsif ['missing-cfis-supplemental-fan'].include? error_case + when 'missing-cfis-supplemental-fan' hpxml, hpxml_bldg = _create_hpxml('base-mechvent-cfis-supplemental-fan-exhaust.xml') hpxml_bldg.ventilation_fans[1].delete - elsif ['missing-distribution-cfa-served'].include? error_case + when 'missing-distribution-cfa-served' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.hvac_distributions[0].ducts[1].duct_surface_area = nil hpxml_bldg.hvac_distributions[0].ducts[1].duct_location = nil - elsif ['missing-duct-area'].include? error_case + when 'missing-duct-area' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.hvac_distributions[0].conditioned_floor_area_served = hpxml_bldg.building_construction.conditioned_floor_area hpxml_bldg.hvac_distributions[0].ducts[1].duct_surface_area = nil - elsif ['missing-duct-location'].include? error_case + when 'missing-duct-location' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.hvac_distributions[0].ducts[1].duct_location = nil - elsif ['missing-elements'].include? error_case + when 'missing-elements' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.building_construction.number_of_conditioned_floors = nil hpxml_bldg.building_construction.conditioned_floor_area = nil - elsif ['missing-epw-filepath-and-zipcode'].include? error_case + when 'missing-epw-filepath-and-zipcode' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.climate_and_risk_zones.weather_station_epw_filepath = nil - elsif ['missing-skylight-floor'].include? error_case + when 'missing-skylight-floor' hpxml, hpxml_bldg = _create_hpxml('base-enclosure-skylights.xml') hpxml_bldg.skylights[0].attached_to_floor_idref = nil - elsif ['multifamily-reference-appliance'].include? error_case + when 'multifamily-reference-appliance' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.clothes_washers[0].location = HPXML::LocationOtherHousingUnit - elsif ['multifamily-reference-duct'].include? error_case + when 'multifamily-reference-duct' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.hvac_distributions[0].ducts[0].duct_location = HPXML::LocationOtherMultifamilyBufferSpace - elsif ['multifamily-reference-surface'].include? error_case + when 'multifamily-reference-surface' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.floors << hpxml_bldg.floors[0].dup hpxml_bldg.floors[1].id = "Floor#{hpxml_bldg.floors.size}" hpxml_bldg.floors[1].insulation_id = "FloorInsulation#{hpxml_bldg.floors.size}" hpxml_bldg.floors[1].exterior_adjacent_to = HPXML::LocationOtherHeatedSpace hpxml_bldg.floors[1].floor_or_ceiling = HPXML::FloorOrCeilingCeiling - elsif ['multifamily-reference-water-heater'].include? error_case + when 'multifamily-reference-water-heater' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.water_heating_systems[0].location = HPXML::LocationOtherNonFreezingSpace - elsif ['negative-autosizing-factors'].include? error_case + when 'negative-autosizing-factors' hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-1-speed-autosize-factor.xml') hpxml_bldg.heat_pumps[0].heating_autosizing_factor = -0.5 hpxml_bldg.heat_pumps[0].cooling_autosizing_factor = -1.2 hpxml_bldg.heat_pumps[0].backup_heating_autosizing_factor = -0.1 - elsif ['refrigerator-location'].include? error_case + when 'refrigerator-location' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.refrigerators[0].location = HPXML::LocationGarage - elsif ['refrigerator-schedule'].include? error_case + when 'refrigerator-schedule' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.refrigerators[0].weekday_fractions = '0.040, 0.039, 0.038, 0.037, 0.036, 0.036, 0.038, 0.040, 0.041, 0.041, 0.040, 0.040, 0.042, 0.042, 0.042, 0.041, 0.044, 0.048, 0.050, 0.048, 0.047, 0.046, 0.044, 0.041' hpxml_bldg.refrigerators[0].constant_coefficients = '-0.487, -0.340, -0.370, -0.361, -0.515, -0.684, -0.471, -0.159, -0.079, -0.417, -0.411, -0.386, -0.240, -0.314, -0.160, -0.121, -0.469, -0.412, -0.091, 0.077, -0.118, -0.247, -0.445, -0.544' - elsif ['solar-fraction-one'].include? error_case + when 'solar-fraction-one' hpxml, hpxml_bldg = _create_hpxml('base-dhw-solar-fraction.xml') hpxml_bldg.solar_thermal_systems[0].solar_fraction = 1.0 - elsif ['sum-space-floor-area'].include? error_case + when 'sum-space-floor-area' hpxml, hpxml_bldg = _create_hpxml('base-zones-spaces.xml') hpxml_bldg.conditioned_spaces.each do |space| space.floor_area /= 2.0 end - elsif ['sum-space-floor-area2'].include? error_case + when 'sum-space-floor-area2' hpxml, hpxml_bldg = _create_hpxml('base-zones-spaces.xml') hpxml_bldg.conditioned_spaces.each do |space| space.floor_area *= 2.0 end - elsif ['water-heater-location'].include? error_case + when 'water-heater-location' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.water_heating_systems[0].location = HPXML::LocationCrawlspaceVented - elsif ['water-heater-location-other'].include? error_case + when 'water-heater-location-other' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.water_heating_systems[0].location = HPXML::LocationUnconditionedSpace - elsif ['water-heater-recovery-efficiency'].include? error_case + when 'water-heater-recovery-efficiency' hpxml, hpxml_bldg = _create_hpxml('base-dhw-tank-gas.xml') hpxml_bldg.water_heating_systems[0].recovery_efficiency = hpxml_bldg.water_heating_systems[0].energy_factor - elsif ['wrong-infiltration-method-blower-door'].include? error_case + when 'wrong-infiltration-method-blower-door' hpxml, hpxml_bldg = _create_hpxml('base-enclosure-infil-leakiness-description.xml') hpxml_bldg.header.manualj_infiltration_method = HPXML::ManualJInfiltrationMethodBlowerDoor - elsif ['wrong-infiltration-method-default-table'].include? error_case + when 'wrong-infiltration-method-default-table' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.header.manualj_infiltration_method = HPXML::ManualJInfiltrationMethodDefaultTable else @@ -807,7 +808,7 @@ def test_schema_schematron_error_messages hpxml_doc = hpxml.to_doc() # Perform additional raw XML manipulation - if ['invalid-id2'].include? error_case + if error_case == 'invalid-id2' element = XMLHelper.get_element(hpxml_doc, '/HPXML/Building/BuildingDetails/Enclosure/Skylights/Skylight/SystemIdentifier') XMLHelper.delete_attribute(element, 'id') end @@ -907,19 +908,20 @@ def test_schema_schematron_warning_messages all_expected_warnings.each_with_index do |(warning_case, expected_warnings), i| puts "[#{i + 1}/#{all_expected_warnings.size}] Testing #{warning_case}..." # Create HPXML object - if ['battery-pv-output-power-low'].include? warning_case + case warning_case + when 'battery-pv-output-power-low' hpxml, hpxml_bldg = _create_hpxml('base-pv-battery.xml') hpxml_bldg.batteries[0].rated_power_output = 0.1 hpxml_bldg.pv_systems[0].max_power_output = 0.1 hpxml_bldg.pv_systems[1].max_power_output = 0.1 - elsif ['dhw-capacities-low'].include? warning_case + when 'dhw-capacities-low' hpxml, hpxml_bldg = _create_hpxml('base-dhw-multiple.xml') hpxml_bldg.water_heating_systems.each do |water_heating_system| if [HPXML::WaterHeaterTypeStorage].include? water_heating_system.water_heater_type water_heating_system.heating_capacity = 0.1 end end - elsif ['dhw-efficiencies-low'].include? warning_case + when 'dhw-efficiencies-low' hpxml, hpxml_bldg = _create_hpxml('base-dhw-multiple.xml') hpxml_bldg.water_heating_systems.each do |water_heating_system| if [HPXML::WaterHeaterTypeStorage, @@ -927,33 +929,33 @@ def test_schema_schematron_warning_messages water_heating_system.energy_factor = 0.1 end end - elsif ['dhw-setpoint-low'].include? warning_case + when 'dhw-setpoint-low' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.water_heating_systems[0].temperature = 100 - elsif ['erv-atre-low'].include? warning_case + when 'erv-atre-low' hpxml, hpxml_bldg = _create_hpxml('base-mechvent-erv-atre-asre.xml') hpxml_bldg.ventilation_fans[0].total_recovery_efficiency_adjusted = 0.1 - elsif ['fuel-load-type-other'].include? warning_case + when 'fuel-load-type-other' hpxml, hpxml_bldg = _create_hpxml('base-misc-loads-large-uncommon.xml') hpxml_bldg.fuel_loads[0].fuel_load_type = HPXML::FuelLoadTypeOther - elsif ['erv-tre-low'].include? warning_case + when 'erv-tre-low' hpxml, hpxml_bldg = _create_hpxml('base-mechvent-erv.xml') hpxml_bldg.ventilation_fans[0].total_recovery_efficiency = 0.1 - elsif ['garage-ventilation'].include? warning_case + when 'garage-ventilation' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.ventilation_fans.add(id: 'VentilationFan1', used_for_garage_ventilation: true) - elsif ['heat-pump-low-backup-switchover-temp'].include? warning_case + when 'heat-pump-low-backup-switchover-temp' hpxml, hpxml_bldg = _create_hpxml('base-hvac-dual-fuel-air-to-air-heat-pump-1-speed.xml') hpxml_bldg.heat_pumps[0].backup_heating_switchover_temp = 25.0 - elsif ['heat-pump-low-backup-lockout-temp'].include? warning_case + when 'heat-pump-low-backup-lockout-temp' hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-1-speed-lockout-temperatures.xml') hpxml_bldg.heat_pumps[0].backup_heating_lockout_temp = 25.0 - elsif ['hvac-dse-low'].include? warning_case + when 'hvac-dse-low' hpxml, hpxml_bldg = _create_hpxml('base-hvac-dse.xml') hpxml_bldg.hvac_distributions[0].annual_heating_dse = 0.1 hpxml_bldg.hvac_distributions[0].annual_cooling_dse = 0.1 - elsif ['hvac-capacities-low'].include? warning_case + when 'hvac-capacities-low' hpxml, hpxml_bldg = _create_hpxml('base-hvac-multiple.xml') hpxml_bldg.hvac_systems.each do |hvac_system| if hvac_system.is_a? HPXML::HeatingSystem @@ -966,97 +968,100 @@ def test_schema_schematron_warning_messages hvac_system.backup_heating_capacity = 0.1 end end - elsif ['hvac-efficiencies-low'].include? warning_case + when 'hvac-efficiencies-low' hpxml, hpxml_bldg = _create_hpxml('base-hvac-multiple.xml') hpxml_bldg.hvac_systems.each do |hvac_system| if hvac_system.is_a? HPXML::HeatingSystem - if [HPXML::HVACTypeElectricResistance, - HPXML::HVACTypeStove].include? hvac_system.heating_system_type + case hvac_system.heating_system_type + when HPXML::HVACTypeElectricResistance, + HPXML::HVACTypeStove hvac_system.heating_efficiency_percent = 0.1 - elsif [HPXML::HVACTypeFurnace, + when HPXML::HVACTypeFurnace, HPXML::HVACTypeWallFurnace, - HPXML::HVACTypeBoiler].include? hvac_system.heating_system_type + HPXML::HVACTypeBoiler hvac_system.heating_efficiency_afue = 0.1 end elsif hvac_system.is_a? HPXML::CoolingSystem - if [HPXML::HVACTypeCentralAirConditioner].include? hvac_system.cooling_system_type + case hvac_system.cooling_system_type + when HPXML::HVACTypeCentralAirConditioner hvac_system.cooling_efficiency_seer = 0.1 - elsif [HPXML::HVACTypeRoomAirConditioner].include? hvac_system.cooling_system_type + when HPXML::HVACTypeRoomAirConditioner hvac_system.cooling_efficiency_eer = 0.1 end elsif hvac_system.is_a? HPXML::HeatPump - if [HPXML::HVACTypeHeatPumpAirToAir, - HPXML::HVACTypeHeatPumpMiniSplit].include? hvac_system.heat_pump_type + case hvac_system.heat_pump_type + when HPXML::HVACTypeHeatPumpAirToAir, + HPXML::HVACTypeHeatPumpMiniSplit hvac_system.cooling_efficiency_seer = 0.1 hvac_system.heating_efficiency_hspf = 0.1 - elsif [HPXML::HVACTypeHeatPumpGroundToAir].include? hvac_system.heat_pump_type + when HPXML::HVACTypeHeatPumpGroundToAir hvac_system.cooling_efficiency_eer = 0.1 hvac_system.heating_efficiency_cop = 0.1 end end end - elsif ['hvac-setpoints-high'].include? warning_case + when 'hvac-setpoints-high' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.hvac_controls[0].heating_setpoint_temp = 100 hpxml_bldg.hvac_controls[0].cooling_setpoint_temp = 100 - elsif ['hvac-setpoints-low'].include? warning_case + when 'hvac-setpoints-low' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.hvac_controls[0].heating_setpoint_temp = 0 hpxml_bldg.hvac_controls[0].cooling_setpoint_temp = 0 - elsif ['integrated-heating-efficiency-low'].include? warning_case + when 'integrated-heating-efficiency-low' hpxml, hpxml_bldg = _create_hpxml('base-hvac-ptac-with-heating-electricity.xml') hpxml_bldg.cooling_systems[0].integrated_heating_system_efficiency_percent = 0.4 - elsif ['lighting-groups-missing'].include? warning_case + when 'lighting-groups-missing' hpxml, hpxml_bldg = _create_hpxml('base-enclosure-garage.xml') hpxml_bldg.lighting_groups.reverse_each do |lg| lg.delete end - elsif ['missing-attached-surfaces'].include? warning_case + when 'missing-attached-surfaces' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.building_construction.residential_facility_type = HPXML::ResidentialTypeSFA hpxml_bldg.air_infiltration_measurements[0].infiltration_type = HPXML::InfiltrationTypeUnitExterior - elsif ['hvac-research-features-onoff-thermostat-temperature-capacitance-multiplier-one'].include? warning_case + when 'hvac-research-features-onoff-thermostat-temperature-capacitance-multiplier-one' hpxml, _hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-1-speed-research-features.xml') hpxml.header.temperature_capacitance_multiplier = 1 - elsif ['plug-load-type-sauna'].include? warning_case + when 'plug-load-type-sauna' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.plug_loads[0].plug_load_type = HPXML::PlugLoadTypeSauna - elsif ['plug-load-type-aquarium'].include? warning_case + when 'plug-load-type-aquarium' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.plug_loads[0].plug_load_type = HPXML::PlugLoadTypeAquarium - elsif ['plug-load-type-water-bed'].include? warning_case + when 'plug-load-type-water-bed' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.plug_loads[0].plug_load_type = HPXML::PlugLoadTypeWaterBed - elsif ['plug-load-type-space-heater'].include? warning_case + when 'plug-load-type-space-heater' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.plug_loads[0].plug_load_type = HPXML::PlugLoadTypeSpaceHeater - elsif ['plug-load-type-computer'].include? warning_case + when 'plug-load-type-computer' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.plug_loads[0].plug_load_type = HPXML::PlugLoadTypeComputer - elsif ['plug-load-type-tv-crt'].include? warning_case + when 'plug-load-type-tv-crt' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.plug_loads[0].plug_load_type = HPXML::PlugLoadTypeTelevisionCRT - elsif ['plug-load-type-tv-plasma'].include? warning_case + when 'plug-load-type-tv-plasma' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.plug_loads[0].plug_load_type = HPXML::PlugLoadTypeTelevisionPlasma - elsif ['portable-spa'].include? warning_case + when 'portable-spa' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.portable_spas.add(id: 'PorableSpa') - elsif ['slab-zero-exposed-perimeter'].include? warning_case + when 'slab-zero-exposed-perimeter' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.slabs[0].exposed_perimeter = 0 - elsif ['slab-ext-horiz-insul-without-perim-insul'].include? warning_case + when 'slab-ext-horiz-insul-without-perim-insul' hpxml, hpxml_bldg = _create_hpxml('base-foundation-slab-exterior-horizontal-insulation.xml') hpxml_bldg.slabs[0].perimeter_insulation_r_value = 0 - elsif ['slab-large-exposed-perimeter'].include? warning_case + when 'slab-large-exposed-perimeter' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.slabs[0].exposed_perimeter = hpxml_bldg.slabs[0].area * 2 + 1 - elsif ['unit-multiplier'].include? warning_case + when 'unit-multiplier' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.building_construction.number_of_units = 5 - elsif ['window-exterior-shading-types'].include? warning_case + when 'window-exterior-shading-types' hpxml, _hpxml_bldg = _create_hpxml('base-enclosure-windows-shading-types-detailed.xml') - elsif ['wrong-units'].include? warning_case + when 'wrong-units' hpxml, hpxml_bldg = _create_hpxml('base-enclosure-overhangs.xml') hpxml_bldg.slabs[0].thickness = 0.5 hpxml_bldg.foundation_walls[0].thickness = 72.0 @@ -1197,73 +1202,74 @@ def test_ruby_error_messages puts "[#{i + 1}/#{all_expected_errors.size}] Testing #{error_case}..." building_id = nil # Create HPXML object - if ['battery-bad-values-max-greater-than-one'].include? error_case + case error_case + when 'battery-bad-values-max-greater-than-one' hpxml, hpxml_bldg = _create_hpxml('base-battery-scheduled.xml') csv_data = CSV.read(File.join(File.dirname(hpxml.hpxml_path), hpxml_bldg.header.schedules_filepaths[0])) csv_data[1][0] = 1.1 File.write(@tmp_csv_path, csv_data.map(&:to_csv).join) hpxml_bldg.header.schedules_filepaths = [@tmp_csv_path] - elsif ['battery-bad-values-min-less-than-neg-one'].include? error_case + when 'battery-bad-values-min-less-than-neg-one' hpxml, hpxml_bldg = _create_hpxml('base-battery-scheduled.xml') csv_data = CSV.read(File.join(File.dirname(hpxml.hpxml_path), hpxml_bldg.header.schedules_filepaths[0])) csv_data[1][0] = -1.1 File.write(@tmp_csv_path, csv_data.map(&:to_csv).join) hpxml_bldg.header.schedules_filepaths = [@tmp_csv_path] - elsif ['cfis-with-hydronic-distribution'].include? error_case + when 'cfis-with-hydronic-distribution' hpxml, hpxml_bldg = _create_hpxml('base-hvac-boiler-gas-only.xml') hpxml_bldg.ventilation_fans.add(id: "VentilationFan#{hpxml_bldg.ventilation_fans.size + 1}", fan_type: HPXML::MechVentTypeCFIS, used_for_whole_building_ventilation: true, distribution_system_idref: hpxml_bldg.hvac_distributions[0].id) - elsif ['cfis-invalid-supplemental-fan'].include? error_case + when 'cfis-invalid-supplemental-fan' hpxml, hpxml_bldg = _create_hpxml('base-mechvent-cfis-supplemental-fan-exhaust.xml') suppl_fan = hpxml_bldg.ventilation_fans.find { |f| f.is_cfis_supplemental_fan } suppl_fan.fan_type = HPXML::MechVentTypeBalanced - elsif ['cfis-invalid-supplemental-fan2'].include? error_case + when 'cfis-invalid-supplemental-fan2' hpxml, hpxml_bldg = _create_hpxml('base-mechvent-cfis-supplemental-fan-exhaust.xml') suppl_fan = hpxml_bldg.ventilation_fans.find { |f| f.is_cfis_supplemental_fan } suppl_fan.used_for_whole_building_ventilation = false suppl_fan.used_for_garage_ventilation = true - elsif ['cfis-invalid-supplemental-fan3'].include? error_case + when 'cfis-invalid-supplemental-fan3' hpxml, hpxml_bldg = _create_hpxml('base-mechvent-cfis-supplemental-fan-exhaust.xml') suppl_fan = hpxml_bldg.ventilation_fans.find { |f| f.is_cfis_supplemental_fan } suppl_fan.is_shared_system = true suppl_fan.fraction_recirculation = 0.0 suppl_fan.in_unit_flow_rate = suppl_fan.tested_flow_rate / 2.0 - elsif ['cfis-invalid-supplemental-fan4'].include? error_case + when 'cfis-invalid-supplemental-fan4' hpxml, hpxml_bldg = _create_hpxml('base-mechvent-cfis-supplemental-fan-exhaust.xml') suppl_fan = hpxml_bldg.ventilation_fans.find { |f| f.is_cfis_supplemental_fan } suppl_fan.hours_in_operation = 12.0 - elsif ['dehumidifier-setpoints'].include? error_case + when 'dehumidifier-setpoints' hpxml, hpxml_bldg = _create_hpxml('base-appliances-dehumidifier-multiple.xml') hpxml_bldg.dehumidifiers[-1].rh_setpoint = 0.55 - elsif ['desuperheater-with-detailed-setpoints'].include? error_case + when 'desuperheater-with-detailed-setpoints' hpxml, hpxml_bldg = _create_hpxml('base-dhw-tank-detailed-setpoints.xml') hpxml_bldg.water_heating_systems[0].uses_desuperheater = true hpxml_bldg.water_heating_systems[0].related_hvac_idref = hpxml_bldg.cooling_systems[0].id - elsif ['duplicate-id'].include? error_case + when 'duplicate-id' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.plug_loads[-1].id = hpxml_bldg.plug_loads[0].id - elsif ['emissions-duplicate-names'].include? error_case + when 'emissions-duplicate-names' hpxml, _hpxml_bldg = _create_hpxml('base-misc-emissions.xml') hpxml.header.emissions_scenarios << hpxml.header.emissions_scenarios[0].dup - elsif ['emissions-wrong-columns'].include? error_case + when 'emissions-wrong-columns' hpxml, _hpxml_bldg = _create_hpxml('base-misc-emissions.xml') scenario = hpxml.header.emissions_scenarios[1] csv_data = CSV.read(File.join(File.dirname(hpxml.hpxml_path), scenario.elec_schedule_filepath)) csv_data[10] = [431.0] * (scenario.elec_schedule_column_number - 1) File.write(@tmp_csv_path, csv_data.map(&:to_csv).join) hpxml.header.emissions_scenarios[1].elec_schedule_filepath = @tmp_csv_path - elsif ['emissions-wrong-filename'].include? error_case + when 'emissions-wrong-filename' hpxml, _hpxml_bldg = _create_hpxml('base-misc-emissions.xml') hpxml.header.emissions_scenarios[1].elec_schedule_filepath = 'invalid-wrong-filename.csv' - elsif ['emissions-wrong-rows'].include? error_case + when 'emissions-wrong-rows' hpxml, _hpxml_bldg = _create_hpxml('base-misc-emissions.xml') scenario = hpxml.header.emissions_scenarios[1] csv_data = CSV.read(File.join(File.dirname(hpxml.hpxml_path), scenario.elec_schedule_filepath)) File.write(@tmp_csv_path, csv_data[0..-2].map(&:to_csv).join) hpxml.header.emissions_scenarios[1].elec_schedule_filepath = @tmp_csv_path - elsif ['geothermal-loop-multiple-attached-hps'].include? error_case + when 'geothermal-loop-multiple-attached-hps' hpxml, hpxml_bldg = _create_hpxml('base-hvac-ground-to-air-heat-pump-detailed-geothermal-loop.xml') hpxml_bldg.heat_pumps[0].fraction_cool_load_served = 0.5 hpxml_bldg.heat_pumps[0].fraction_heat_load_served = 0.5 @@ -1276,35 +1282,35 @@ def test_ruby_error_messages annual_cooling_dse: 1.0, annual_heating_dse: 1.0) hpxml_bldg.heat_pumps[1].distribution_system_idref = hpxml_bldg.hvac_distributions[1].id - elsif ['heat-pump-backup-system-load-fraction'].include? error_case + when 'heat-pump-backup-system-load-fraction' hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-var-speed-backup-boiler.xml') hpxml_bldg.heating_systems[0].fraction_heat_load_served = 0.5 hpxml_bldg.heat_pumps[0].fraction_heat_load_served = 0.5 - elsif ['heat-pump-switchover-temp-elec-backup'].include? error_case + when 'heat-pump-switchover-temp-elec-backup' hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-1-speed.xml') hpxml_bldg.heat_pumps[0].backup_heating_switchover_temp = 35.0 - elsif ['hvac-cooling-detailed-performance-incomplete-pair'].include? error_case + when 'hvac-cooling-detailed-performance-incomplete-pair' hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-var-speed-detailed-performance.xml') hpxml_bldg.heat_pumps[0].cooling_detailed_performance_data[-1].outdoor_temperature -= 1.0 - elsif ['hvac-heating-detailed-performance-incomplete-pair'].include? error_case + when 'hvac-heating-detailed-performance-incomplete-pair' hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-var-speed-detailed-performance.xml') hpxml_bldg.heat_pumps[0].heating_detailed_performance_data[-1].outdoor_temperature -= 1.0 - elsif ['heat-pump-lockout-temps-elec-backup'].include? error_case + when 'heat-pump-lockout-temps-elec-backup' hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-1-speed.xml') hpxml_bldg.heat_pumps[0].compressor_lockout_temp = 35.0 hpxml_bldg.heat_pumps[0].backup_heating_lockout_temp = 35.0 - elsif ['hvac-invalid-distribution-system-type'].include? error_case + when 'hvac-invalid-distribution-system-type' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.hvac_distributions.add(id: "HVACDistribution#{hpxml_bldg.hvac_distributions.size + 1}", distribution_system_type: HPXML::HVACDistributionTypeHydronic, hydronic_type: HPXML::HydronicTypeBaseboard) hpxml_bldg.heating_systems[-1].distribution_system_idref = hpxml_bldg.hvac_distributions[-1].id - elsif ['hvac-attached-to-uncond-zone'].include? error_case + when 'hvac-attached-to-uncond-zone' hpxml, hpxml_bldg = _create_hpxml('base-zones-spaces.xml') hpxml_bldg.hvac_systems.each do |hvac_system| hvac_system.attached_to_zone_idref = hpxml_bldg.zones.find { |zone| zone.zone_type != HPXML::ZoneTypeConditioned }.id end - elsif ['hvac-distribution-different-zones'].include? error_case + when 'hvac-distribution-different-zones' hpxml, hpxml_bldg = _create_hpxml('base-zones-spaces.xml') hpxml_bldg.zones.add(id: 'ConditionedZoneDup', zone_type: HPXML::ZoneTypeConditioned) @@ -1313,45 +1319,45 @@ def test_ruby_error_messages floor_area: hpxml_bldg.zones[0].spaces[0].floor_area) hpxml_bldg.heating_systems[0].attached_to_zone_idref = hpxml_bldg.conditioned_zones[0].id hpxml_bldg.cooling_systems[0].attached_to_zone_idref = hpxml_bldg.conditioned_zones[-1].id - elsif ['hvac-distribution-multiple-attached-cooling'].include? error_case + when 'hvac-distribution-multiple-attached-cooling' hpxml, hpxml_bldg = _create_hpxml('base-hvac-multiple.xml') hpxml_bldg.heat_pumps[0].distribution_system_idref = 'HVACDistribution2' - elsif ['hvac-distribution-multiple-attached-heating'].include? error_case + when 'hvac-distribution-multiple-attached-heating' hpxml, hpxml_bldg = _create_hpxml('base-hvac-multiple.xml') hpxml_bldg.heat_pumps[0].distribution_system_idref = 'HVACDistribution1' - elsif ['hvac-dse-multiple-attached-cooling'].include? error_case + when 'hvac-dse-multiple-attached-cooling' hpxml, hpxml_bldg = _create_hpxml('base-hvac-dse.xml') hpxml_bldg.cooling_systems[0].fraction_cool_load_served = 0.5 hpxml_bldg.cooling_systems << hpxml_bldg.cooling_systems[0].dup hpxml_bldg.cooling_systems[1].id = "CoolingSystem#{hpxml_bldg.cooling_systems.size}" hpxml_bldg.cooling_systems[0].primary_system = false - elsif ['hvac-dse-multiple-attached-heating'].include? error_case + when 'hvac-dse-multiple-attached-heating' hpxml, hpxml_bldg = _create_hpxml('base-hvac-dse.xml') hpxml_bldg.heating_systems[0].fraction_heat_load_served = 0.5 hpxml_bldg.heating_systems << hpxml_bldg.heating_systems[0].dup hpxml_bldg.heating_systems[1].id = "HeatingSystem#{hpxml_bldg.heating_systems.size}" hpxml_bldg.heating_systems[0].primary_system = false - elsif ['hvac-research-features-onoff-thermostat-num-speeds-greater-than-two'].include? error_case + when 'hvac-research-features-onoff-thermostat-num-speeds-greater-than-two' hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-1-speed-research-features.xml') hpxml_bldg.heat_pumps[0].compressor_type = HPXML::HVACCompressorTypeVariableSpeed - elsif ['hvac-research-features-num-unit-greater-than-one'].include? error_case + when 'hvac-research-features-num-unit-greater-than-one' hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-1-speed-research-features.xml') hpxml_bldg.building_construction.number_of_units = 2 - elsif ['hvac-gshp-invalid-bore-depth-autosized'].include? error_case + when 'hvac-gshp-invalid-bore-depth-autosized' hpxml, hpxml_bldg = _create_hpxml('base-hvac-ground-to-air-heat-pump.xml') hpxml_bldg.site.ground_conductivity = 0.1 - elsif ['hvac-gshp-invalid-num-bore-holes'].include? error_case + when 'hvac-gshp-invalid-num-bore-holes' hpxml, hpxml_bldg = _create_hpxml('base-hvac-ground-to-air-heat-pump-detailed-geothermal-loop.xml') hpxml_bldg.geothermal_loops[0].num_bore_holes = 5 - elsif ['hvac-gshp-invalid-num-bore-holes-autosized'].include? error_case + when 'hvac-gshp-invalid-num-bore-holes-autosized' hpxml, hpxml_bldg = _create_hpxml('base-hvac-ground-to-air-heat-pump.xml') hpxml_bldg.heat_pumps[0].cooling_capacity *= 2 hpxml_bldg.site.ground_conductivity = 0.08 - elsif ['hvac-inconsistent-fan-powers'].include? error_case + when 'hvac-inconsistent-fan-powers' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.cooling_systems[0].fan_watts_per_cfm = 0.55 hpxml_bldg.heating_systems[0].fan_watts_per_cfm = 0.45 - elsif ['hvac-shared-boiler-multiple'].include? error_case + when 'hvac-shared-boiler-multiple' hpxml, hpxml_bldg = _create_hpxml('base-bldgtype-mf-unit-shared-boiler-only-baseboard.xml') hpxml_bldg.hvac_distributions << hpxml_bldg.hvac_distributions[0].dup hpxml_bldg.hvac_distributions[-1].id = "HVACDistribution#{hpxml_bldg.hvac_distributions.size}" @@ -1361,7 +1367,7 @@ def test_ruby_error_messages hpxml_bldg.heating_systems[1].id = "HeatingSystem#{hpxml_bldg.heating_systems.size}" hpxml_bldg.heating_systems[1].distribution_system_idref = hpxml_bldg.hvac_distributions[-1].id hpxml_bldg.heating_systems[1].primary_system = true - elsif ['hvac-shared-chiller-multiple'].include? error_case + when 'hvac-shared-chiller-multiple' hpxml, hpxml_bldg = _create_hpxml('base-bldgtype-mf-unit-shared-chiller-only-baseboard.xml') hpxml_bldg.hvac_distributions << hpxml_bldg.hvac_distributions[0].dup hpxml_bldg.hvac_distributions[-1].id = "HVACDistribution#{hpxml_bldg.hvac_distributions.size}" @@ -1371,214 +1377,214 @@ def test_ruby_error_messages hpxml_bldg.cooling_systems[1].id = "CoolingSystem#{hpxml_bldg.cooling_systems.size}" hpxml_bldg.cooling_systems[1].distribution_system_idref = hpxml_bldg.hvac_distributions[-1].id hpxml_bldg.cooling_systems[1].primary_system = true - elsif ['hvac-shared-chiller-negative-seer-eq'].include? error_case + when 'hvac-shared-chiller-negative-seer-eq' hpxml, hpxml_bldg = _create_hpxml('base-bldgtype-mf-unit-shared-chiller-only-baseboard.xml') hpxml_bldg.cooling_systems[0].shared_loop_watts *= 100.0 - elsif ['inconsistent-belly-wing-skirt-present'].include? error_case + when 'inconsistent-belly-wing-skirt-present' hpxml, hpxml_bldg = _create_hpxml('base-foundation-belly-wing-skirt.xml') fnd = hpxml_bldg.foundations.find { |f| f.foundation_type == HPXML::FoundationTypeBellyAndWing } hpxml_bldg.foundations << fnd.dup hpxml_bldg.foundations[-1].id = 'Duplicate' hpxml_bldg.foundations[-1].belly_wing_skirt_present = false - elsif ['inconsistent-cond-zone-assignment'].include? error_case + when 'inconsistent-cond-zone-assignment' hpxml, hpxml_bldg = _create_hpxml('base-zones-spaces.xml') grg_ceiling = hpxml_bldg.floors.find { |f| f.interior_adjacent_to == HPXML::LocationGarage && f.exterior_adjacent_to == HPXML::LocationAtticUnvented } grg_ceiling.attached_to_space_idref = hpxml_bldg.conditioned_spaces[0].id - elsif ['inconsistent-uncond-basement-within-infiltration-volume'].include? error_case + when 'inconsistent-uncond-basement-within-infiltration-volume' hpxml, hpxml_bldg = _create_hpxml('base-foundation-unconditioned-basement.xml') fnd = hpxml_bldg.foundations.find { |f| f.foundation_type == HPXML::FoundationTypeBasementUnconditioned } hpxml_bldg.foundations << fnd.dup hpxml_bldg.foundations[-1].id = 'Duplicate' hpxml_bldg.foundations[-1].within_infiltration_volume = true - elsif ['inconsistent-unvented-attic-within-infiltration-volume'].include? error_case + when 'inconsistent-unvented-attic-within-infiltration-volume' hpxml, hpxml_bldg = _create_hpxml('base.xml') attic = hpxml_bldg.attics.find { |a| a.attic_type == HPXML::AtticTypeUnvented } hpxml_bldg.attics << attic.dup hpxml_bldg.attics[-1].id = 'Duplicate' hpxml_bldg.attics[-1].within_infiltration_volume = true - elsif ['inconsistent-unvented-crawl-within-infiltration-volume'].include? error_case + when 'inconsistent-unvented-crawl-within-infiltration-volume' hpxml, hpxml_bldg = _create_hpxml('base-foundation-unvented-crawlspace.xml') fnd = hpxml_bldg.foundations.find { |f| f.foundation_type == HPXML::FoundationTypeCrawlspaceUnvented } hpxml_bldg.foundations << fnd.dup hpxml_bldg.foundations[-1].id = 'Duplicate' hpxml_bldg.foundations[-1].within_infiltration_volume = true - elsif ['inconsistent-vented-attic-ventilation-rate'].include? error_case + when 'inconsistent-vented-attic-ventilation-rate' hpxml, hpxml_bldg = _create_hpxml('base-atticroof-vented.xml') attic = hpxml_bldg.attics.find { |a| a.attic_type == HPXML::AtticTypeVented } hpxml_bldg.attics << attic.dup hpxml_bldg.attics[-1].id = 'Duplicate' hpxml_bldg.attics[-1].vented_attic_sla *= 2 - elsif ['inconsistent-vented-attic-ventilation-rate2'].include? error_case + when 'inconsistent-vented-attic-ventilation-rate2' hpxml, hpxml_bldg = _create_hpxml('base-atticroof-vented.xml') attic = hpxml_bldg.attics.find { |a| a.attic_type == HPXML::AtticTypeVented } hpxml_bldg.attics << attic.dup hpxml_bldg.attics[-1].id = 'Duplicate' hpxml_bldg.attics[-1].vented_attic_sla = nil hpxml_bldg.attics[-1].vented_attic_ach = 5.0 - elsif ['inconsistent-vented-crawl-ventilation-rate'].include? error_case + when 'inconsistent-vented-crawl-ventilation-rate' hpxml, hpxml_bldg = _create_hpxml('base-foundation-vented-crawlspace.xml') fnd = hpxml_bldg.foundations.find { |f| f.foundation_type == HPXML::FoundationTypeCrawlspaceVented } hpxml_bldg.foundations << fnd.dup hpxml_bldg.foundations[-1].id = 'Duplicate' hpxml_bldg.foundations[-1].vented_crawlspace_sla *= 2 - elsif ['invalid-battery-capacity-units'].include? error_case + when 'invalid-battery-capacity-units' hpxml, hpxml_bldg = _create_hpxml('base-pv-battery.xml') hpxml_bldg.batteries[0].usable_capacity_kwh = nil hpxml_bldg.batteries[0].usable_capacity_ah = 200.0 - elsif ['invalid-battery-capacity-units2'].include? error_case + when 'invalid-battery-capacity-units2' hpxml, hpxml_bldg = _create_hpxml('base-pv-battery-ah.xml') hpxml_bldg.batteries[0].usable_capacity_kwh = 10.0 hpxml_bldg.batteries[0].usable_capacity_ah = nil - elsif ['invalid-datatype-boolean'].include? error_case + when 'invalid-datatype-boolean' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.roofs[0].radiant_barrier = false - elsif ['invalid-datatype-integer'].include? error_case + when 'invalid-datatype-integer' hpxml, _hpxml_bldg = _create_hpxml('base.xml') - elsif ['invalid-datatype-float'].include? error_case + when 'invalid-datatype-float' hpxml, _hpxml_bldg = _create_hpxml('base-misc-emissions.xml') - elsif ['invalid-daylight-saving'].include? error_case + when 'invalid-daylight-saving' hpxml, hpxml_bldg = _create_hpxml('base-simcontrol-daylight-saving-custom.xml') hpxml_bldg.dst_begin_month = 3 hpxml_bldg.dst_begin_day = 10 hpxml_bldg.dst_end_month = 4 hpxml_bldg.dst_end_day = 31 - elsif ['invalid-distribution-cfa-served'].include? error_case + when 'invalid-distribution-cfa-served' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.hvac_distributions[-1].conditioned_floor_area_served = 2701.1 - elsif ['invalid-epw-filepath'].include? error_case + when 'invalid-epw-filepath' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.climate_and_risk_zones.weather_station_epw_filepath = 'foo.epw' - elsif ['invalid-holiday-lighting-dates'].include? error_case + when 'invalid-holiday-lighting-dates' hpxml, hpxml_bldg = _create_hpxml('base-lighting-holiday.xml') hpxml_bldg.lighting.holiday_period_begin_month = 11 hpxml_bldg.lighting.holiday_period_begin_day = 31 hpxml_bldg.lighting.holiday_period_end_month = 1 hpxml_bldg.lighting.holiday_period_end_day = 15 - elsif ['invalid-id'].include? error_case + when 'invalid-id' hpxml, hpxml_bldg = _create_hpxml('base-enclosure-skylights.xml') hpxml_bldg.skylights[0].id = '' - elsif ['invalid-neighbor-shading-azimuth'].include? error_case + when 'invalid-neighbor-shading-azimuth' hpxml, hpxml_bldg = _create_hpxml('base-misc-neighbor-shading.xml') hpxml_bldg.neighbor_buildings[0].azimuth = 145 - elsif ['invalid-ptac-dse'].include? error_case + when 'invalid-ptac-dse' hpxml, hpxml_bldg = _create_hpxml('base-hvac-ptac-cfis.xml') hpxml_bldg.hvac_distributions[0].annual_cooling_dse = 0.9 - elsif ['invalid-pthp-dse'].include? error_case + when 'invalid-pthp-dse' hpxml, hpxml_bldg = _create_hpxml('base-hvac-pthp-cfis.xml') hpxml_bldg.hvac_distributions[0].annual_heating_dse = 0.9 - elsif ['invalid-relatedhvac-dhw-indirect'].include? error_case + when 'invalid-relatedhvac-dhw-indirect' hpxml, hpxml_bldg = _create_hpxml('base-dhw-indirect.xml') hpxml_bldg.water_heating_systems[0].related_hvac_idref = 'HeatingSystem_bad' - elsif ['invalid-relatedhvac-desuperheater'].include? error_case + when 'invalid-relatedhvac-desuperheater' hpxml, hpxml_bldg = _create_hpxml('base-hvac-central-ac-only-1-speed.xml') hpxml_bldg.water_heating_systems[0].uses_desuperheater = true hpxml_bldg.water_heating_systems[0].related_hvac_idref = 'CoolingSystem_bad' - elsif ['invalid-runperiod'].include? error_case + when 'invalid-runperiod' hpxml, _hpxml_bldg = _create_hpxml('base.xml') hpxml.header.sim_begin_month = 3 hpxml.header.sim_begin_day = 10 hpxml.header.sim_end_month = 4 hpxml.header.sim_end_day = 31 - elsif ['invalid-shading-season'].include? error_case + when 'invalid-shading-season' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.header.shading_summer_begin_month = 3 hpxml_bldg.header.shading_summer_begin_day = 10 hpxml_bldg.header.shading_summer_end_month = 4 hpxml_bldg.header.shading_summer_end_day = 31 - elsif ['invalid-unavailable-period'].include? error_case + when 'invalid-unavailable-period' hpxml, _hpxml_bldg = _create_hpxml('base.xml') hpxml.header.unavailable_periods.add(column_name: 'Power Outage', begin_month: 3, begin_day: 10, end_month: 4, end_day: 31) - elsif ['invalid-schema-version'].include? error_case + when 'invalid-schema-version' hpxml, _hpxml_bldg = _create_hpxml('base.xml') - elsif ['invalid-skylights-physical-properties'].include? error_case + when 'invalid-skylights-physical-properties' hpxml, hpxml_bldg = _create_hpxml('base-enclosure-skylights-physical-properties.xml') hpxml_bldg.skylights[1].thermal_break = false - elsif ['invalid-windows-physical-properties'].include? error_case + when 'invalid-windows-physical-properties' hpxml, hpxml_bldg = _create_hpxml('base-enclosure-windows-physical-properties.xml') hpxml_bldg.windows[2].thermal_break = false - elsif ['inverter-unequal-efficiencies'].include? error_case + when 'inverter-unequal-efficiencies' hpxml, hpxml_bldg = _create_hpxml('base-pv.xml') hpxml_bldg.inverters.add(id: 'Inverter2', inverter_efficiency: 0.5) hpxml_bldg.pv_systems[1].inverter_idref = hpxml_bldg.inverters[-1].id - elsif ['leap-year-TMY'].include? error_case + when 'leap-year-TMY' hpxml, _hpxml_bldg = _create_hpxml('base-simcontrol-calendar-year-custom.xml') hpxml.header.sim_calendar_year = 2008 - elsif ['net-area-negative-roof-floor'].include? error_case + when 'net-area-negative-roof-floor' hpxml, hpxml_bldg = _create_hpxml('base-enclosure-skylights.xml') hpxml_bldg.skylights[0].area = 4000 - elsif ['net-area-negative-wall'].include? error_case + when 'net-area-negative-wall' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.windows[0].area = 1000 - elsif ['orphaned-geothermal-loop'].include? error_case + when 'orphaned-geothermal-loop' hpxml, hpxml_bldg = _create_hpxml('base-hvac-ground-to-air-heat-pump-detailed-geothermal-loop.xml') hpxml_bldg.heat_pumps[0].geothermal_loop_idref = nil - elsif ['orphaned-hvac-distribution'].include? error_case + when 'orphaned-hvac-distribution' hpxml, hpxml_bldg = _create_hpxml('base-hvac-furnace-gas-room-ac.xml') hpxml_bldg.heating_systems[0].delete hpxml_bldg.hvac_controls[0].heating_setpoint_temp = nil - elsif ['refrigerators-multiple-primary'].include? error_case + when 'refrigerators-multiple-primary' hpxml, hpxml_bldg = _create_hpxml('base-misc-loads-large-uncommon.xml') hpxml_bldg.refrigerators[1].primary_indicator = true - elsif ['refrigerators-no-primary'].include? error_case + when 'refrigerators-no-primary' hpxml, hpxml_bldg = _create_hpxml('base-misc-loads-large-uncommon.xml') hpxml_bldg.refrigerators[0].primary_indicator = false - elsif ['repeated-relatedhvac-dhw-indirect'].include? error_case + when 'repeated-relatedhvac-dhw-indirect' hpxml, hpxml_bldg = _create_hpxml('base-dhw-indirect.xml') hpxml_bldg.water_heating_systems[0].fraction_dhw_load_served = 0.5 hpxml_bldg.water_heating_systems << hpxml_bldg.water_heating_systems[0].dup hpxml_bldg.water_heating_systems[1].id = "WaterHeatingSystem#{hpxml_bldg.water_heating_systems.size}" - elsif ['repeated-relatedhvac-desuperheater'].include? error_case + when 'repeated-relatedhvac-desuperheater' hpxml, hpxml_bldg = _create_hpxml('base-hvac-central-ac-only-1-speed.xml') hpxml_bldg.water_heating_systems[0].fraction_dhw_load_served = 0.5 hpxml_bldg.water_heating_systems[0].uses_desuperheater = true hpxml_bldg.water_heating_systems[0].related_hvac_idref = 'CoolingSystem1' hpxml_bldg.water_heating_systems << hpxml_bldg.water_heating_systems[0].dup hpxml_bldg.water_heating_systems[1].id = "WaterHeatingSystem#{hpxml_bldg.water_heating_systems.size}" - elsif ['schedule-detailed-bad-values-max-not-one'].include? error_case + when 'schedule-detailed-bad-values-max-not-one' hpxml, hpxml_bldg = _create_hpxml('base-schedules-detailed-occupancy-stochastic.xml') csv_data = CSV.read(File.join(File.dirname(hpxml.hpxml_path), hpxml_bldg.header.schedules_filepaths[0])) csv_data[1][1] = 1.1 File.write(@tmp_csv_path, csv_data.map(&:to_csv).join) hpxml_bldg.header.schedules_filepaths = [@tmp_csv_path] - elsif ['schedule-detailed-bad-values-negative'].include? error_case + when 'schedule-detailed-bad-values-negative' hpxml, hpxml_bldg = _create_hpxml('base-schedules-detailed-occupancy-stochastic.xml') csv_data = CSV.read(File.join(File.dirname(hpxml.hpxml_path), hpxml_bldg.header.schedules_filepaths[0])) csv_data[1][1] = -0.5 File.write(@tmp_csv_path, csv_data.map(&:to_csv).join) hpxml_bldg.header.schedules_filepaths = [@tmp_csv_path] - elsif ['schedule-detailed-bad-values-non-numeric'].include? error_case + when 'schedule-detailed-bad-values-non-numeric' hpxml, hpxml_bldg = _create_hpxml('base-schedules-detailed-occupancy-stochastic.xml') csv_data = CSV.read(File.join(File.dirname(hpxml.hpxml_path), hpxml_bldg.header.schedules_filepaths[0])) csv_data[1][1] = 'NA' File.write(@tmp_csv_path, csv_data.map(&:to_csv).join) hpxml_bldg.header.schedules_filepaths = [@tmp_csv_path] - elsif ['schedule-detailed-bad-values-mode-negative'].include? error_case + when 'schedule-detailed-bad-values-mode-negative' hpxml, hpxml_bldg = _create_hpxml('base-dhw-tank-heat-pump-detailed-schedules.xml') csv_data = CSV.read(File.join(File.dirname(hpxml.hpxml_path), hpxml_bldg.header.schedules_filepaths[1])) csv_data[1][0] = -0.5 File.write(@tmp_csv_path, csv_data.map(&:to_csv).join) hpxml_bldg.header.schedules_filepaths = [@tmp_csv_path] - elsif ['schedule-detailed-duplicate-columns'].include? error_case + when 'schedule-detailed-duplicate-columns' hpxml, hpxml_bldg = _create_hpxml('base-schedules-detailed-occupancy-stochastic.xml') csv_data = CSV.read(File.join(File.dirname(hpxml.hpxml_path), hpxml_bldg.header.schedules_filepaths[0])) File.write(@tmp_csv_path, csv_data.map(&:to_csv).join) hpxml_bldg.header.schedules_filepaths = [] hpxml_bldg.header.schedules_filepaths << @tmp_csv_path hpxml_bldg.header.schedules_filepaths << @tmp_csv_path - elsif ['schedule-detailed-wrong-filename'].include? error_case + when 'schedule-detailed-wrong-filename' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.header.schedules_filepaths << 'invalid-wrong-filename.csv' - elsif ['schedule-detailed-wrong-rows'].include? error_case + when 'schedule-detailed-wrong-rows' hpxml, hpxml_bldg = _create_hpxml('base-schedules-detailed-occupancy-stochastic.xml') csv_data = CSV.read(File.join(File.dirname(hpxml.hpxml_path), hpxml_bldg.header.schedules_filepaths[0])) File.write(@tmp_csv_path, csv_data[0..-2].map(&:to_csv).join) hpxml_bldg.header.schedules_filepaths = [@tmp_csv_path] - elsif ['skylight-not-connected-to-cond-space'].include? error_case + when 'skylight-not-connected-to-cond-space' hpxml, hpxml_bldg = _create_hpxml('base-enclosure-garage.xml') hpxml_bldg.skylights.add(id: 'Skylight1', area: 15.0, @@ -1589,7 +1595,7 @@ def test_ruby_error_messages shaft_assembly_r_value: 6.25, attached_to_roof_idref: 'Roof1', attached_to_floor_idref: 'Floor1') - elsif ['solar-thermal-system-with-combi-tankless'].include? error_case + when 'solar-thermal-system-with-combi-tankless' hpxml, hpxml_bldg = _create_hpxml('base-dhw-combi-tankless.xml') hpxml_bldg.solar_thermal_systems.add(id: "SolarThermalSystem#{hpxml_bldg.solar_thermal_systems.size + 1}", system_type: HPXML::SolarThermalSystemTypeHotWater, @@ -1601,7 +1607,7 @@ def test_ruby_error_messages collector_rated_optical_efficiency: 0.77, collector_rated_thermal_losses: 0.793, water_heating_system_idref: 'WaterHeatingSystem1') - elsif ['solar-thermal-system-with-desuperheater'].include? error_case + when 'solar-thermal-system-with-desuperheater' hpxml, hpxml_bldg = _create_hpxml('base-dhw-desuperheater.xml') hpxml_bldg.solar_thermal_systems.add(id: "SolarThermalSystem#{hpxml_bldg.solar_thermal_systems.size + 1}", system_type: HPXML::SolarThermalSystemTypeHotWater, @@ -1613,7 +1619,7 @@ def test_ruby_error_messages collector_rated_optical_efficiency: 0.77, collector_rated_thermal_losses: 0.793, water_heating_system_idref: 'WaterHeatingSystem1') - elsif ['solar-thermal-system-with-dhw-indirect'].include? error_case + when 'solar-thermal-system-with-dhw-indirect' hpxml, hpxml_bldg = _create_hpxml('base-dhw-combi-tankless.xml') hpxml_bldg.solar_thermal_systems.add(id: "SolarThermalSystem#{hpxml_bldg.solar_thermal_systems.size + 1}", system_type: HPXML::SolarThermalSystemTypeHotWater, @@ -1625,88 +1631,88 @@ def test_ruby_error_messages collector_rated_optical_efficiency: 0.77, collector_rated_thermal_losses: 0.793, water_heating_system_idref: 'WaterHeatingSystem1') - elsif ['storm-windows-unexpected-window-ufactor'].include? error_case + when 'storm-windows-unexpected-window-ufactor' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.windows[0].storm_type = 'clear' - elsif ['surface-attached-to-uncond-space'].include? error_case + when 'surface-attached-to-uncond-space' hpxml, hpxml_bldg = _create_hpxml('base-zones-spaces.xml') hpxml_bldg.walls[-1].attached_to_space_idref = hpxml_bldg.zones.find { |zone| zone.zone_type != HPXML::ZoneTypeConditioned }.spaces[0].id - elsif ['surface-attached-to-uncond-space2'].include? error_case + when 'surface-attached-to-uncond-space2' hpxml, hpxml_bldg = _create_hpxml('base-zones-spaces.xml') hpxml_bldg.slabs[-1].attached_to_space_idref = hpxml_bldg.zones.find { |zone| zone.zone_type != HPXML::ZoneTypeConditioned }.spaces[0].id - elsif ['unattached-cfis'].include? error_case + when 'unattached-cfis' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.ventilation_fans.add(id: "VentilationFan#{hpxml_bldg.ventilation_fans.size + 1}", fan_type: HPXML::MechVentTypeCFIS, used_for_whole_building_ventilation: true, distribution_system_idref: hpxml_bldg.hvac_distributions[0].id) hpxml_bldg.ventilation_fans[0].distribution_system_idref = 'foobar' - elsif ['unattached-door'].include? error_case + when 'unattached-door' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.doors[0].attached_to_wall_idref = 'foobar' - elsif ['unattached-gshp'].include? error_case + when 'unattached-gshp' hpxml, hpxml_bldg = _create_hpxml('base-hvac-ground-to-air-heat-pump-detailed-geothermal-loop.xml') hpxml_bldg.heat_pumps[0].geothermal_loop_idref = 'foobar' hpxml_bldg.geothermal_loops[0].delete - elsif ['unattached-hvac-distribution'].include? error_case + when 'unattached-hvac-distribution' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.heating_systems[0].distribution_system_idref = 'foobar' - elsif ['unattached-pv-system'].include? error_case + when 'unattached-pv-system' hpxml, hpxml_bldg = _create_hpxml('base-pv.xml') hpxml_bldg.pv_systems[0].inverter_idref = 'foobar' - elsif ['unattached-skylight'].include? error_case + when 'unattached-skylight' hpxml, hpxml_bldg = _create_hpxml('base-enclosure-skylights.xml') hpxml_bldg.skylights[0].attached_to_roof_idref = 'foobar' hpxml_bldg.skylights[0].attached_to_floor_idref = 'foobar' - elsif ['unattached-solar-thermal-system'].include? error_case + when 'unattached-solar-thermal-system' hpxml, hpxml_bldg = _create_hpxml('base-dhw-solar-indirect-flat-plate.xml') hpxml_bldg.solar_thermal_systems[0].water_heating_system_idref = 'foobar' - elsif ['unattached-shared-clothes-washer-dhw-distribution'].include? error_case + when 'unattached-shared-clothes-washer-dhw-distribution' hpxml, hpxml_bldg = _create_hpxml('base-bldgtype-mf-unit-shared-laundry-room.xml') hpxml_bldg.clothes_washers[0].water_heating_system_idref = nil hpxml_bldg.clothes_washers[0].hot_water_distribution_idref = 'foobar' - elsif ['unattached-shared-clothes-washer-water-heater'].include? error_case + when 'unattached-shared-clothes-washer-water-heater' hpxml, hpxml_bldg = _create_hpxml('base-bldgtype-mf-unit-shared-laundry-room.xml') hpxml_bldg.clothes_washers[0].water_heating_system_idref = 'foobar' - elsif ['unattached-shared-dishwasher-dhw-distribution'].include? error_case + when 'unattached-shared-dishwasher-dhw-distribution' hpxml, hpxml_bldg = _create_hpxml('base-bldgtype-mf-unit-shared-laundry-room.xml') hpxml_bldg.dishwashers[0].water_heating_system_idref = nil hpxml_bldg.dishwashers[0].hot_water_distribution_idref = 'foobar' - elsif ['unattached-shared-dishwasher-water-heater'].include? error_case + when 'unattached-shared-dishwasher-water-heater' hpxml, hpxml_bldg = _create_hpxml('base-bldgtype-mf-unit-shared-laundry-room.xml') hpxml_bldg.dishwashers[0].water_heating_system_idref = 'foobar' - elsif ['unattached-window'].include? error_case + when 'unattached-window' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.windows[0].attached_to_wall_idref = 'foobar' - elsif ['unattached-zone'].include? error_case + when 'unattached-zone' hpxml, hpxml_bldg = _create_hpxml('base-zones-spaces.xml') hpxml_bldg.heating_systems[0].attached_to_zone_idref = 'foobar' hpxml_bldg.cooling_systems[0].attached_to_zone_idref = 'foobar' - elsif ['unavailable-period-missing-column'].include? error_case + when 'unavailable-period-missing-column' hpxml, _hpxml_bldg = _create_hpxml('base-schedules-simple-vacancy.xml') hpxml.header.unavailable_periods[0].column_name = 'foobar' - elsif ['unique-objects-vary-across-units-epw'].include? error_case + when 'unique-objects-vary-across-units-epw' hpxml, hpxml_bldg = _create_hpxml('base-bldgtype-mf-whole-building.xml', building_id: building_id) hpxml_bldg.climate_and_risk_zones.weather_station_epw_filepath = 'USA_AZ_Phoenix-Sky.Harbor.Intl.AP.722780_TMY3.epw' - elsif ['unique-objects-vary-across-units-dst'].include? error_case + when 'unique-objects-vary-across-units-dst' hpxml, hpxml_bldg = _create_hpxml('base-bldgtype-mf-whole-building.xml', building_id: building_id) hpxml_bldg.dst_begin_month = 3 hpxml_bldg.dst_begin_day = 15 hpxml_bldg.dst_end_month = 10 hpxml_bldg.dst_end_day = 15 - elsif ['unique-objects-vary-across-units-tmains'].include? error_case + when 'unique-objects-vary-across-units-tmains' hpxml, hpxml_bldg = _create_hpxml('base-bldgtype-mf-whole-building.xml', building_id: building_id) hpxml_bldg.hot_water_distributions[0].dwhr_facilities_connected = HPXML::DWHRFacilitiesConnectedOne hpxml_bldg.hot_water_distributions[0].dwhr_equal_flow = true hpxml_bldg.hot_water_distributions[0].dwhr_efficiency = 0.55 - elsif ['whole-mf-building-batteries'].include? error_case + when 'whole-mf-building-batteries' hpxml, hpxml_bldg = _create_hpxml('base-bldgtype-mf-whole-building.xml', building_id: building_id) hpxml_bldg.batteries.add(id: 'Battery1', type: HPXML::BatteryTypeLithiumIon) - elsif ['whole-mf-building-dehumidifiers-unit-multiplier'].include? error_case + when 'whole-mf-building-dehumidifiers-unit-multiplier' hpxml, hpxml_bldg = _create_hpxml('base-appliances-dehumidifier.xml') hpxml_bldg.building_construction.number_of_units = 2 - elsif ['whole-mf-building-gshps-unit-multiplier'].include? error_case + when 'whole-mf-building-gshps-unit-multiplier' hpxml, hpxml_bldg = _create_hpxml('base-hvac-ground-to-air-heat-pump.xml') hpxml_bldg.building_construction.number_of_units = 2 else @@ -1716,13 +1722,14 @@ def test_ruby_error_messages hpxml_doc = hpxml.to_doc() # Perform additional raw XML manipulation - if ['invalid-datatype-boolean'].include? error_case + case error_case + when 'invalid-datatype-boolean' XMLHelper.get_element(hpxml_doc, '/HPXML/Building/BuildingDetails/Enclosure/Roofs/Roof/RadiantBarrier').inner_text = 'FOOBAR' - elsif ['invalid-datatype-integer'].include? error_case + when 'invalid-datatype-integer' XMLHelper.get_element(hpxml_doc, '/HPXML/Building/BuildingDetails/BuildingSummary/BuildingConstruction/NumberofBedrooms').inner_text = '2.5' - elsif ['invalid-datatype-float'].include? error_case + when 'invalid-datatype-float' XMLHelper.get_element(hpxml_doc, '/HPXML/SoftwareInfo/extension/EmissionsScenarios/EmissionsScenario/EmissionsFactor/Value').inner_text = 'FOOBAR' - elsif ['invalid-schema-version'].include? error_case + when 'invalid-schema-version' root = XMLHelper.get_element(hpxml_doc, '/HPXML') XMLHelper.add_attribute(root, 'schemaVersion', '2.3') end @@ -1847,11 +1854,12 @@ def test_ruby_warning_messages puts "[#{i + 1}/#{all_expected_warnings.size}] Testing #{warning_case}..." building_id = nil # Create HPXML object - if ['cfis-undersized-supplemental-fan'].include? warning_case + case warning_case + when 'cfis-undersized-supplemental-fan' hpxml, hpxml_bldg = _create_hpxml('base-mechvent-cfis-supplemental-fan-exhaust.xml') suppl_fan = hpxml_bldg.ventilation_fans.find { |f| f.is_cfis_supplemental_fan } suppl_fan.tested_flow_rate = 90.0 - elsif ['duct-lto-cfm25-cond-space'].include? warning_case + when 'duct-lto-cfm25-cond-space' hpxml, hpxml_bldg = _create_hpxml('base-atticroof-conditioned.xml') hpxml_bldg.hvac_distributions[0].conditioned_floor_area_served = hpxml_bldg.building_construction.conditioned_floor_area hpxml_bldg.hvac_distributions[0].duct_leakage_measurements.each do |dlm| @@ -1862,12 +1870,12 @@ def test_ruby_warning_messages duct.duct_surface_area = nil duct.duct_location = nil end - elsif ['duct-lto-cfm25-uncond-space'].include? warning_case + when 'duct-lto-cfm25-uncond-space' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.hvac_distributions[0].duct_leakage_measurements.each do |dlm| dlm.duct_leakage_value = 800.0 end - elsif ['duct-lto-cfm50-cond-space'].include? warning_case + when 'duct-lto-cfm50-cond-space' hpxml, hpxml_bldg = _create_hpxml('base-atticroof-conditioned.xml') hpxml_bldg.hvac_distributions[0].conditioned_floor_area_served = hpxml_bldg.building_construction.conditioned_floor_area hpxml_bldg.hvac_distributions[0].duct_leakage_measurements.each do |dlm| @@ -1878,12 +1886,12 @@ def test_ruby_warning_messages duct.duct_surface_area = nil duct.duct_location = nil end - elsif ['duct-lto-cfm50-uncond-space'].include? warning_case + when 'duct-lto-cfm50-uncond-space' hpxml, hpxml_bldg = _create_hpxml('base-hvac-ducts-leakage-cfm50.xml') hpxml_bldg.hvac_distributions[0].duct_leakage_measurements.each do |dlm| dlm.duct_leakage_value = 1600.0 end - elsif ['duct-lto-percent-cond-space'].include? warning_case + when 'duct-lto-percent-cond-space' hpxml, hpxml_bldg = _create_hpxml('base-atticroof-conditioned.xml') hpxml_bldg.hvac_distributions[0].conditioned_floor_area_served = hpxml_bldg.building_construction.conditioned_floor_area hpxml_bldg.hvac_distributions[0].duct_leakage_measurements.each do |dlm| @@ -1894,59 +1902,59 @@ def test_ruby_warning_messages duct.duct_surface_area = nil duct.duct_location = nil end - elsif ['duct-lto-percent-uncond-space'].include? warning_case + when 'duct-lto-percent-uncond-space' hpxml, hpxml_bldg = _create_hpxml('base-hvac-ducts-leakage-percent.xml') hpxml_bldg.hvac_distributions[0].duct_leakage_measurements.each do |dlm| dlm.duct_leakage_value = 0.25 end - elsif ['floor-or-ceiling1'].include? warning_case + when 'floor-or-ceiling1' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.floors[0].floor_or_ceiling = HPXML::FloorOrCeilingFloor - elsif ['floor-or-ceiling2'].include? warning_case + when 'floor-or-ceiling2' hpxml, hpxml_bldg = _create_hpxml('base-foundation-unvented-crawlspace.xml') hpxml_bldg.floors[0].floor_or_ceiling = HPXML::FloorOrCeilingCeiling - elsif ['hvac-gshp-bore-depth-autosized-high'].include? warning_case + when 'hvac-gshp-bore-depth-autosized-high' hpxml, hpxml_bldg = _create_hpxml('base-hvac-ground-to-air-heat-pump.xml') hpxml_bldg.site.ground_conductivity = 0.07 - elsif ['hvac-seasons'].include? warning_case + when 'hvac-seasons' hpxml, hpxml_bldg = _create_hpxml('base-hvac-seasons.xml') - elsif ['hvac-setpoint-adjustments'].include? warning_case + when 'hvac-setpoint-adjustments' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.hvac_controls[0].heating_setpoint_temp = 76.0 hpxml_bldg.hvac_controls[0].cooling_setpoint_temp = 75.0 - elsif ['hvac-setpoint-adjustments-daily-setbacks'].include? warning_case + when 'hvac-setpoint-adjustments-daily-setbacks' hpxml, hpxml_bldg = _create_hpxml('base-hvac-setpoints-daily-setbacks.xml') hpxml_bldg.hvac_controls[0].heating_setback_temp = 76.0 hpxml_bldg.hvac_controls[0].cooling_setpoint_temp = 75.0 - elsif ['hvac-setpoint-adjustments-daily-schedules'].include? warning_case + when 'hvac-setpoint-adjustments-daily-schedules' hpxml, hpxml_bldg = _create_hpxml('base-hvac-setpoints-daily-schedules.xml') hpxml_bldg.hvac_controls[0].weekday_heating_setpoints = '64, 64, 64, 64, 64, 64, 64, 76, 70, 66, 66, 66, 66, 66, 66, 66, 66, 68, 68, 68, 68, 68, 64, 64' - elsif ['manualj-sum-space-num-occupants'].include? warning_case + when 'manualj-sum-space-num-occupants' hpxml, hpxml_bldg = _create_hpxml('base-zones-spaces.xml') hpxml_bldg.header.manualj_num_occupants = 4.8 hpxml_bldg.conditioned_spaces.each_with_index do |space, i| space.manualj_num_occupants = (i == 0 ? hpxml_bldg.header.manualj_num_occupants.round : 0) end - elsif ['manualj-sum-space-internal-loads-sensible'].include? warning_case + when 'manualj-sum-space-internal-loads-sensible' hpxml, hpxml_bldg = _create_hpxml('base-zones-spaces.xml') hpxml_bldg.header.manualj_internal_loads_sensible = 1000.0 hpxml_bldg.conditioned_spaces.each_with_index do |space, i| space.manualj_internal_loads_sensible = (i == 0 ? 1200.0 : 0) end - elsif ['manualj-sum-space-internal-loads-latent'].include? warning_case + when 'manualj-sum-space-internal-loads-latent' hpxml, hpxml_bldg = _create_hpxml('base-zones-spaces.xml') hpxml_bldg.header.manualj_internal_loads_latent = 200.0 hpxml_bldg.conditioned_spaces.each_with_index do |space, i| space.manualj_internal_loads_latent = (i == 0 ? 100.0 : 0) end - elsif ['multiple-conditioned-zone'].include? warning_case + when 'multiple-conditioned-zone' hpxml, hpxml_bldg = _create_hpxml('base-zones-spaces-multiple.xml') - elsif ['power-outage'].include? warning_case + when 'power-outage' hpxml, _hpxml_bldg = _create_hpxml('base-schedules-simple-power-outage.xml') - elsif ['multistage-backup-more-than-4-stages'].include? warning_case + when 'multistage-backup-more-than-4-stages' hpxml, _hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-1-speed-research-features.xml') hpxml.header.heat_pump_backup_heating_capacity_increment = 5000 - elsif ['schedule-file-and-weekday-weekend-multipliers'].include? warning_case + when 'schedule-file-and-weekday-weekend-multipliers' hpxml, hpxml_bldg = _create_hpxml('base-misc-loads-large-uncommon.xml') hpxml.header.utility_bill_scenarios.clear # we don't want the propane warning hpxml_bldg.header.schedules_filepaths << File.join(File.dirname(__FILE__), '../resources/schedule_files/occupancy-stochastic.csv') @@ -1956,7 +1964,7 @@ def test_ruby_warning_messages hpxml_bldg.hot_water_distributions[0].recirculation_pump_weekday_fractions = @default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_no_control"]['RecirculationPumpWeekdayScheduleFractions'] hpxml_bldg.hot_water_distributions[0].recirculation_pump_weekend_fractions = @default_schedules_csv_data["#{SchedulesFile::Columns[:HotWaterRecirculationPump].name}_no_control"]['RecirculationPumpWeekendScheduleFractions'] hpxml_bldg.hot_water_distributions[0].recirculation_pump_monthly_multipliers = @default_schedules_csv_data[SchedulesFile::Columns[:HotWaterRecirculationPump].name]['RecirculationPumpMonthlyScheduleMultipliers'] - elsif ['schedule-file-and-refrigerators-freezer-coefficients'].include? warning_case + when 'schedule-file-and-refrigerators-freezer-coefficients' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.header.schedules_filepaths << File.join(File.dirname(__FILE__), '../resources/schedule_files/occupancy-stochastic.csv') hpxml_bldg.header.schedules_filepaths << File.join(File.dirname(__FILE__), '../resources/schedule_files/occupancy-non-stochastic.csv') @@ -1969,20 +1977,20 @@ def test_ruby_warning_messages hpxml_bldg.freezers.add(id: "Freezer#{hpxml_bldg.freezers.size + 1}", constant_coefficients: '-0.487, -0.340, -0.370, -0.361, -0.515, -0.684, -0.471, -0.159, -0.079, -0.417, -0.411, -0.386, -0.240, -0.314, -0.160, -0.121, -0.469, -0.412, -0.091, 0.077, -0.118, -0.247, -0.445, -0.544', temperature_coefficients: '0.019, 0.016, 0.017, 0.016, 0.018, 0.021, 0.019, 0.015, 0.015, 0.019, 0.018, 0.018, 0.016, 0.017, 0.015, 0.015, 0.020, 0.020, 0.017, 0.014, 0.016, 0.017, 0.019, 0.020') - elsif ['schedule-file-and-setpoints'].include? warning_case + when 'schedule-file-and-setpoints' hpxml, hpxml_bldg = _create_hpxml('base.xml') hpxml_bldg.header.schedules_filepaths << File.join(File.dirname(__FILE__), '../resources/schedule_files/setpoints.csv') hpxml_bldg.header.schedules_filepaths << File.join(File.dirname(__FILE__), '../resources/schedule_files/water-heater-setpoints.csv') - elsif ['schedule-file-and-operating-mode'].include? warning_case + when 'schedule-file-and-operating-mode' hpxml, hpxml_bldg = _create_hpxml('base-dhw-tank-heat-pump-operating-mode-heat-pump-only.xml') hpxml_bldg.header.schedules_filepaths << File.join(File.dirname(__FILE__), '../resources/schedule_files/water-heater-operating-modes.csv') - elsif ['schedule-file-max-power-ratio-with-single-speed-system'].include? warning_case + when 'schedule-file-max-power-ratio-with-single-speed-system' hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-1-speed.xml') hpxml_bldg.header.schedules_filepaths << File.join(File.dirname(__FILE__), '../resources/schedule_files/hvac-variable-system-maximum-power-ratios-varied.csv') - elsif ['schedule-file-max-power-ratio-with-two-speed-system'].include? warning_case + when 'schedule-file-max-power-ratio-with-two-speed-system' hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-2-speed.xml') hpxml_bldg.header.schedules_filepaths << File.join(File.dirname(__FILE__), '../resources/schedule_files/hvac-variable-system-maximum-power-ratios-varied.csv') - elsif ['schedule-file-max-power-ratio-with-separate-backup-system'].include? warning_case + when 'schedule-file-max-power-ratio-with-separate-backup-system' hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-var-speed-backup-boiler.xml') hpxml_bldg.header.schedules_filepaths << File.join(File.dirname(__FILE__), '../resources/schedule_files/hvac-variable-system-maximum-power-ratios-varied.csv') else diff --git a/resources/hpxml-measures/README.md b/resources/hpxml-measures/README.md index d5f9c473ea..900da4515b 100644 --- a/resources/hpxml-measures/README.md +++ b/resources/hpxml-measures/README.md @@ -4,7 +4,7 @@ [![ci](https://github.com/NREL/OpenStudio-HPXML/workflows/ci/badge.svg)](https://github.com/NREL/OpenStudio-HPXML/actions) [![Documentation Status](https://readthedocs.org/projects/openstudio-hpxml/badge/?version=latest)](https://openstudio-hpxml.readthedocs.io/en/latest/?badge=latest) -OpenStudio-HPXML allows running residential EnergyPlus™ simulations using an [HPXML file](https://hpxml.nrel.gov/) for the building description. +OpenStudio-HPXML allows running residential [EnergyPlus™ simulations](https://energyplus.net/) using an [HPXML file](https://hpxml.nrel.gov/) for the building description. It is intended to be used by user interfaces or other automated software workflows that automatically produce the HPXML file. OpenStudio-HPXML can accommodate a wide range of different building technologies and geometries. @@ -31,6 +31,8 @@ OpenStudio-HPXML capabilities include: - Annual and timeseries outputs (energy, loads, temperatures, etc.) - Optional HPXML inputs with transparent defaults - Schematron and XSD Schema input validation +- Can be used for [DOE HOMES program approval](https://www.energy.gov/scep/single-family-modeling-solutions-home-efficiency-rebates-program) +- Can be used for [ACCA Manual J approval](https://www.acca.org/standards/approved-software) ## Measures diff --git a/resources/hpxml-measures/ReportSimulationOutput/measure.rb b/resources/hpxml-measures/ReportSimulationOutput/measure.rb index c342ba06c0..fcec01b1bd 100644 --- a/resources/hpxml-measures/ReportSimulationOutput/measure.rb +++ b/resources/hpxml-measures/ReportSimulationOutput/measure.rb @@ -657,13 +657,14 @@ def get_timestamps(msgpackData, hpxml_header, hpxml_bldgs, args) # Convert from EnergyPlus default (end-of-timestep) to start-of-timestep convention if args[:timeseries_timestamp_convention] == 'start' - if args[:timeseries_frequency] == 'timestep' + case args[:timeseries_frequency] + when 'timestep' ts_offset = hpxml_header.timestep * 60 # seconds - elsif args[:timeseries_frequency] == 'hourly' + when 'hourly' ts_offset = 60 * 60 # seconds - elsif args[:timeseries_frequency] == 'daily' + when 'daily' ts_offset = 60 * 60 * 24 # seconds - elsif args[:timeseries_frequency] == 'monthly' + when 'monthly' ts_offset = Calendar.num_days_in_months(year)[month - 1] * 60 * 60 * 24 # seconds else fail "Unexpected timeseries_frequency: #{args[:timeseries_frequency]}." @@ -1836,13 +1837,14 @@ def report_timeseries_output_results(runner, outputs, timeseries_output_path, ar year = @hpxml_header.sim_calendar_year start_day = Calendar.get_day_num_from_month_day(year, @hpxml_header.sim_begin_month, @hpxml_header.sim_begin_day) start_hr = (start_day - 1) * 24 - if args[:timeseries_frequency] == 'timestep' + case args[:timeseries_frequency] + when 'timestep' interval_hrs = @hpxml_header.timestep / 60.0 - elsif args[:timeseries_frequency] == 'hourly' + when 'hourly' interval_hrs = 1.0 - elsif args[:timeseries_frequency] == 'daily' + when 'daily' interval_hrs = 24.0 - elsif args[:timeseries_frequency] == 'monthly' + when 'monthly' interval_hrs = Calendar.num_days_in_year(year) * 24.0 / 12 end header_data = [['wxDVFileHeaderVer.1'], diff --git a/resources/hpxml-measures/ReportSimulationOutput/measure.xml b/resources/hpxml-measures/ReportSimulationOutput/measure.xml index 92e37b1986..3d43e4ede3 100644 --- a/resources/hpxml-measures/ReportSimulationOutput/measure.xml +++ b/resources/hpxml-measures/ReportSimulationOutput/measure.xml @@ -3,8 +3,8 @@ 3.1 report_simulation_output df9d170c-c21a-4130-866d-0d46b06073fd - 443dae63-bc28-4988-8cb0-5fc10c452c68 - 2024-10-13T19:48:30Z + 5e609cb1-8e83-479b-afda-c1de10cd62ea + 2024-11-27T02:33:41Z 9BF1E6AC ReportSimulationOutput HPXML Simulation Output Report @@ -1929,7 +1929,7 @@ measure.rb rb script - 45BFC7E3 + 4C7478A8 test_report_sim_output.rb diff --git a/resources/hpxml-measures/ReportUtilityBills/measure.rb b/resources/hpxml-measures/ReportUtilityBills/measure.rb index e2819c9420..a4e6158b79 100644 --- a/resources/hpxml-measures/ReportUtilityBills/measure.rb +++ b/resources/hpxml-measures/ReportUtilityBills/measure.rb @@ -199,8 +199,7 @@ def energyPlusOutputRequests(runner, user_arguments) FT::Coal => HPXML::FuelTypeCoal } # Check for presence of fuels once - has_fuel = hpxml.has_fuels(hpxml.to_doc) - has_fuel[HPXML::FuelTypeElectricity] = true + has_fuel = hpxml.has_fuels() # Has production has_pv = @hpxml_buildings.count { |hpxml_bldg| !hpxml_bldg.pv_systems.empty? } > 0 @@ -543,7 +542,8 @@ def get_utility_rates(hpxml_path, fuels, utility_rates, bill_scenario, pv_monthl utility_rates.each do |fuel_type, rate| next if fuels[[fuel_type, false]].timeseries.sum == 0 - if fuel_type == FT::Elec + case fuel_type + when FT::Elec if bill_scenario.elec_tariff_filepath.nil? rate.fixed_charge_monthly = bill_scenario.elec_fixed_charge rate.flat_rate = bill_scenario.elec_marginal_rate @@ -618,22 +618,22 @@ def get_utility_rates(hpxml_path, fuels, utility_rates, bill_scenario, pv_monthl # Feed-In Tariff rate.feed_in_tariff_rate = bill_scenario.pv_feed_in_tariff_rate if bill_scenario.pv_compensation_type == HPXML::PVCompensationTypeFeedInTariff - elsif fuel_type == FT::Gas + when FT::Gas rate.fixed_charge_monthly = bill_scenario.natural_gas_fixed_charge rate.flat_rate = bill_scenario.natural_gas_marginal_rate - elsif fuel_type == FT::Oil + when FT::Oil rate.fixed_charge_monthly = bill_scenario.fuel_oil_fixed_charge rate.flat_rate = bill_scenario.fuel_oil_marginal_rate - elsif fuel_type == FT::Propane + when FT::Propane rate.fixed_charge_monthly = bill_scenario.propane_fixed_charge rate.flat_rate = bill_scenario.propane_marginal_rate - elsif fuel_type == FT::WoodCord + when FT::WoodCord rate.fixed_charge_monthly = bill_scenario.wood_fixed_charge rate.flat_rate = bill_scenario.wood_marginal_rate - elsif fuel_type == FT::WoodPellets + when FT::WoodPellets rate.fixed_charge_monthly = bill_scenario.wood_pellets_fixed_charge rate.flat_rate = bill_scenario.wood_pellets_marginal_rate - elsif fuel_type == FT::Coal + when FT::Coal rate.fixed_charge_monthly = bill_scenario.coal_fixed_charge rate.flat_rate = bill_scenario.coal_marginal_rate end diff --git a/resources/hpxml-measures/ReportUtilityBills/measure.xml b/resources/hpxml-measures/ReportUtilityBills/measure.xml index cb75deec1e..eaca6d9b0e 100644 --- a/resources/hpxml-measures/ReportUtilityBills/measure.xml +++ b/resources/hpxml-measures/ReportUtilityBills/measure.xml @@ -3,8 +3,8 @@ 3.1 report_utility_bills ca88a425-e59a-4bc4-af51-c7e7d1e960fe - 6b3c51ee-095b-455c-b1f1-a1cb47e3b4a8 - 2024-11-14T00:26:10Z + 3d7e2753-fab2-4d89-bfd9-208a59523248 + 2024-11-27T02:33:42Z 15BF4E57 ReportUtilityBills Utility Bills Report @@ -180,7 +180,7 @@ measure.rb rb script - 4D23174A + 48B476E1 detailed_rates/README.md @@ -360,7 +360,7 @@ test_report_utility_bills.rb rb test - 1D59A593 + 5B90EFCE diff --git a/resources/hpxml-measures/ReportUtilityBills/tests/test_report_utility_bills.rb b/resources/hpxml-measures/ReportUtilityBills/tests/test_report_utility_bills.rb index b95a848dd5..84406d63e1 100644 --- a/resources/hpxml-measures/ReportUtilityBills/tests/test_report_utility_bills.rb +++ b/resources/hpxml-measures/ReportUtilityBills/tests/test_report_utility_bills.rb @@ -79,7 +79,7 @@ def setup fuel_oil_marginal_rate: 3.495346153846154) # Check for presence of fuels once - has_fuel = @hpxml_bldg.has_fuels(@hpxml.to_doc) + has_fuel = @hpxml_bldg.has_fuels() Defaults.apply_header(@hpxml_header, @hpxml_bldg, nil) Defaults.apply_utility_bill_scenarios(nil, @hpxml_header, @hpxml_bldg, has_fuel) @@ -1176,15 +1176,16 @@ def _load_timeseries(pv_size_kw, use_hourly_electricity) values = col[1..-1].map { |v| Float(v) } - if col_name == 'Electricity [kWh]' + case col_name + when 'Electricity [kWh]' fuels[[FT::Elec, false]].timeseries = values - elsif col_name == 'Gas [therm]' + when 'Gas [therm]' fuels[[FT::Gas, false]].timeseries = values - elsif col_name == 'Propane [gal]' + when 'Propane [gal]' fuels[[FT::Propane, false]].timeseries = values - elsif col_name == 'Oil [gal]' + when 'Oil [gal]' fuels[[FT::Oil, false]].timeseries = values - elsif col_name == "PV_#{pv_size_kw}kW [kWh]" + when "PV_#{pv_size_kw}kW [kWh]" fuels[[FT::Elec, true]].timeseries = values end end diff --git a/resources/hpxml-measures/docs/source/images/slab.png b/resources/hpxml-measures/docs/source/images/slab.png index 347cc4ee66..367be073be 100644 Binary files a/resources/hpxml-measures/docs/source/images/slab.png and b/resources/hpxml-measures/docs/source/images/slab.png differ diff --git a/resources/hpxml-measures/docs/source/intro.rst b/resources/hpxml-measures/docs/source/intro.rst index 8ffc2be114..9fff0c5d17 100644 --- a/resources/hpxml-measures/docs/source/intro.rst +++ b/resources/hpxml-measures/docs/source/intro.rst @@ -20,6 +20,14 @@ OpenStudio-HPXML capabilities include: - Optional HPXML inputs with transparent defaults - Schematron and XSD Schema input validation +.. note:: + If you are seeking `DOE HOMES program approval `_, OpenStudio-HPXML can be used to meet the `energy modeling software tests `_. + +.. note:: + + If you are seeking `ACCA Manual J approval `_ for your software, you will need to contact ACCA and go through their approval process. + OpenStudio-HPXML design load calculations can be used to obtain approval, but additional Manual J-specific HPXML inputs need to be specified; refer to the HPXML test files at ``workflow/tests/ACCA_Examples``. + Accuracy vs Speed ----------------- diff --git a/resources/hpxml-measures/docs/source/testing_framework.rst b/resources/hpxml-measures/docs/source/testing_framework.rst index 103845eb43..d6625cd8ea 100644 --- a/resources/hpxml-measures/docs/source/testing_framework.rst +++ b/resources/hpxml-measures/docs/source/testing_framework.rst @@ -10,8 +10,7 @@ The current set of tests include: - RESNET® HERS® HVAC tests - RESNET HERS DSE tests - RESNET HERS Hot Water tests - -OpenStudio-HPXML can be used to meet BPI-2400 software tests. +- ACCA Manual J tests Running Tests Locally --------------------- diff --git a/resources/hpxml-measures/docs/source/workflow_inputs.rst b/resources/hpxml-measures/docs/source/workflow_inputs.rst index 56e2b4ad2a..4b996f0805 100644 --- a/resources/hpxml-measures/docs/source/workflow_inputs.rst +++ b/resources/hpxml-measures/docs/source/workflow_inputs.rst @@ -594,7 +594,7 @@ Building occupancy is entered in ``/HPXML/Building/BuildingDetails/BuildingSumma \- **single-family attached**: NumberofBedrooms = -1.98 + 1.89 * NumberofResidents - \- **apartment unit or multifamily**: NumberofBedrooms = -1.36 + 1.49 * NumberofResidents + \- **apartment unit**: NumberofBedrooms = -1.36 + 1.49 * NumberofResidents .. [#] If WeekdayScheduleFractions or WeekendScheduleFractions not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. .. [#] If MonthlyScheduleMultipliers not provided (and :ref:`schedules_detailed` not used), then :ref:`schedules_default` are used. @@ -3523,12 +3523,12 @@ If using Manual J default duct factor tables, additional information is entered ================================ ======= ============ =========== ======== ========= ========================================================= Element Type Units Constraints Required Default Notes ================================ ======= ============ =========== ======== ========= ========================================================= - `TableNumber` string See [#]_ Yes Manual J Default Duct Factor Table number - `LookupFloorArea` double ft2 > 0 Yes Lookup floor area value for the Manual J table [#]_ - `LeakageLevel` string See [#]_ Yes Leakage tightness value for the Manual J table - `InsulationRValue` double F-ft2-hr/Btu >= 2 Yes Insulation R-value for the Manual J table - `SupplySurfaceArea` or `DSF` double ft2 or frac >= 0 No DSF=1 Surface area or estimated fraction of supply ducts in unconditioned space - `ReturnSurfaceArea` or `DSF` double ft2 or frac >= 0 No DSF=1 Surface area or estimated fraction of return ducts in unconditioned space + ``TableNumber`` string See [#]_ Yes Manual J Default Duct Factor Table number + ``LookupFloorArea`` double ft2 > 0 Yes Lookup floor area value for the Manual J table [#]_ + ``LeakageLevel`` string See [#]_ Yes Leakage tightness value for the Manual J table + ``InsulationRValue`` double F-ft2-hr/Btu >= 2 Yes Insulation R-value for the Manual J table + ``SupplySurfaceArea`` or ``DSF`` double ft2 or frac >= 0 No DSF=1 Surface area or estimated fraction of supply ducts in unconditioned space + ``ReturnSurfaceArea`` or ``DSF`` double ft2 or frac >= 0 No DSF=1 Surface area or estimated fraction of return ducts in unconditioned space ================================ ======= ============ =========== ======== ========= ========================================================= .. [#] TableNumber choices are "7A-R", "7A-T", "7B-R", "7B-T", "7A-AE", "7B-AE", "7C-AE", "7C-R", "7C-T", "7D-R", "7D-T", "7E-R", "7E-T", "7F-R", "7F-T", "7G-R", "7G-T", "7H", "7I", "7D-AE", "7J-1", "7J-2", "7K", "7L", "7M", "7N", "7O-1", "7O-2", "7O-3", "7O-4", "7P-1", "7P-2", "7P-3", or "7P-4". diff --git a/resources/hpxml-measures/tasks.rb b/resources/hpxml-measures/tasks.rb index a80bc6614a..008d2ef4ee 100644 --- a/resources/hpxml-measures/tasks.rb +++ b/resources/hpxml-measures/tasks.rb @@ -1656,18 +1656,6 @@ def apply_hpxml_modification_sample_files(hpxml_path, hpxml) hpxml_bldg.hvac_distributions[0].ducts[2].duct_surface_area = 37.5 hpxml_bldg.hvac_distributions[0].ducts[3].duct_location = HPXML::LocationConditionedSpace hpxml_bldg.hvac_distributions[0].ducts[3].duct_surface_area = 12.5 - if hpxml_file == 'base-hvac-ducts-area-fractions.xml' - hpxml_bldg.hvac_distributions[0].ducts[0].duct_surface_area = nil - hpxml_bldg.hvac_distributions[0].ducts[1].duct_surface_area = nil - hpxml_bldg.hvac_distributions[0].ducts[2].duct_surface_area = nil - hpxml_bldg.hvac_distributions[0].ducts[3].duct_surface_area = nil - hpxml_bldg.hvac_distributions[0].ducts[0].duct_fraction_area = 0.75 - hpxml_bldg.hvac_distributions[0].ducts[1].duct_fraction_area = 0.75 - hpxml_bldg.hvac_distributions[0].ducts[2].duct_fraction_area = 0.25 - hpxml_bldg.hvac_distributions[0].ducts[3].duct_fraction_area = 0.25 - hpxml_bldg.hvac_distributions[0].conditioned_floor_area_served = 4050.0 - hpxml_bldg.hvac_distributions[0].number_of_return_registers = 3 - end elsif ['base-hvac-ducts-effective-rvalue.xml'].include? hpxml_file hpxml_bldg.hvac_distributions[0].ducts[0].duct_insulation_r_value = nil hpxml_bldg.hvac_distributions[0].ducts[1].duct_insulation_r_value = nil @@ -1953,13 +1941,6 @@ def apply_hpxml_modification_sample_files(hpxml_path, hpxml) if hpxml_file.include? 'base-hvac-ground-to-air-heat-pump-detailed-geothermal-loop.xml' hpxml_bldg.geothermal_loops[0].shank_spacing = 2.5 end - if hpxml_file.include? 'HERS_HVAC' - hpxml_bldg.hvac_distributions.clear - hpxml_bldg.hvac_distributions.add(id: "HVACDistribution#{hpxml_bldg.hvac_distributions.size + 1}", - distribution_system_type: HPXML::HVACDistributionTypeDSE, - annual_heating_dse: 1.0, - annual_cooling_dse: 1.0) - end hpxml_bldg.heating_systems.each do |heating_system| if heating_system.heating_system_type == HPXML::HVACTypeBoiler && heating_system.heating_system_fuel == HPXML::FuelTypeNaturalGas && diff --git a/resources/hpxml-measures/workflow/hpxml_inputs.json b/resources/hpxml-measures/workflow/hpxml_inputs.json index 443c200788..0d0bdac382 100644 --- a/resources/hpxml-measures/workflow/hpxml_inputs.json +++ b/resources/hpxml-measures/workflow/hpxml_inputs.json @@ -3699,10 +3699,6 @@ "parent_hpxml": "sample_files/base.xml", "geometry_unit_num_occupants": 0 }, - "sample_files/base-residents-0-runperiod-1-month.xml": { - "parent_hpxml": "sample_files/base-residents-0.xml", - "simulation_control_run_period": "Feb 1 - Feb 28" - }, "sample_files/base-residents-1.xml": { "parent_hpxml": "sample_files/base.xml", "geometry_unit_num_occupants": 1, diff --git a/resources/hpxml-measures/workflow/sample_files/base-location-detailed.xml b/resources/hpxml-measures/workflow/sample_files/base-location-detailed.xml index e53ed3915f..6bf985d616 100644 --- a/resources/hpxml-measures/workflow/sample_files/base-location-detailed.xml +++ b/resources/hpxml-measures/workflow/sample_files/base-location-detailed.xml @@ -62,6 +62,12 @@ 21600.0 + + + 2006 + 5B + + diff --git a/resources/hpxml-measures/workflow/sample_files/base-residents-0-runperiod-1-month.xml b/resources/hpxml-measures/workflow/sample_files/base-residents-0-runperiod-1-month.xml deleted file mode 100644 index 0c03c64524..0000000000 --- a/resources/hpxml-measures/workflow/sample_files/base-residents-0-runperiod-1-month.xml +++ /dev/null @@ -1,558 +0,0 @@ - - - - HPXML - tasks.rb - 2000-01-01T00:00:00-07:00 - create - - - - - 60 - 2 - 1 - 2 - 28 - - - - Bills - - - - - - - - -
- CO -
-
- - proposed workscope - - - - - suburban - stand-alone - no units above or below - 180 - - electricity - natural gas - - - - 0.0 - - - single-family detached - 2.0 - 1.0 - 8.0 - 3 - 2 - 2700.0 - 21600.0 - - - - - 2006 - 5B - - - - USA_CO_Denver.Intl.AP.725650_TMY3 - - USA_CO_Denver.Intl.AP.725650_TMY3.epw - - - - - - - - 50.0 - - ACH - 3.0 - - 21600.0 - - - - - - - - false - - - false - - - - - - - - - - - true - - - - - - - - - - - attic - unvented - 1509.3 - asphalt or fiberglass shingles - 0.7 - 0.92 - 6.0 - - - 2.3 - - - - - - - outside - basement - conditioned - 115.6 - wood siding - 0.7 - 0.92 - - - 23.0 - - - - - - - outside - conditioned space - - - - 1200.0 - wood siding - 0.7 - 0.92 - - gypsum board - - - - 23.0 - - - - - outside - attic - unvented - gable - - - - 225.0 - wood siding - 0.7 - 0.92 - - - 4.0 - - - - - - - ground - basement - conditioned - 8.0 - 1200.0 - 8.0 - 7.0 - - gypsum board - - - - - continuous - exterior - 8.9 - 0.0 - 8.0 - - - continuous - interior - 0.0 - - - - - - - - attic - unvented - conditioned space - ceiling - - - - 1350.0 - - gypsum board - - - - 39.3 - - - - - - - basement - conditioned - 1350.0 - 4.0 - 150.0 - - - - 0.0 - 0.0 - - - - - - 0.0 - 0.0 - - - - 0.0 - 0.0 - - - - - - - 108.0 - 0 - 0.33 - 0.45 - - - 0.7 - 0.85 - - 0.67 - - - - - 72.0 - 90 - 0.33 - 0.45 - - - 0.7 - 0.85 - - 0.67 - - - - - 108.0 - 180 - 0.33 - 0.45 - - - 0.7 - 0.85 - - 0.67 - - - - - 72.0 - 270 - 0.33 - 0.45 - - - 0.7 - 0.85 - - 0.67 - - - - - - - - 40.0 - 180 - 4.4 - - - - - - - - - - - - - - - - - natural gas - 36000.0 - - AFUE - 0.92 - - 1.0 - - - - - central air conditioner - electricity - 24000.0 - single stage - 1.0 - - SEER - 13.0 - - 0.73 - - - - - 68.0 - 78.0 - - - - - - regular velocity - - supply - - CFM25 - 75.0 - to outside - - - - return - - CFM25 - 25.0 - to outside - - - - - supply - 4.0 - attic - unvented - 150.0 - - - - return - 0.0 - attic - unvented - 50.0 - - - - - - - - - electricity - storage water heater - conditioned space - 40.0 - 1.0 - 18767.0 - 0.95 - 125.0 - - - - - - 50.0 - - - - 0.0 - - - - - shower head - true - - - - faucet - false - - - - - - - conditioned space - 1.21 - 380.0 - 0.12 - 1.09 - 27.0 - 6.0 - 3.2 - - - - conditioned space - electricity - 3.73 - true - 150.0 - - - - conditioned space - 307.0 - 12 - 0.12 - 1.09 - 22.32 - 4.0 - - - - conditioned space - 650.0 - - - - conditioned space - electricity - false - - - - false - - - - - - interior - 0.4 - - - - - - - interior - 0.1 - - - - - - - interior - 0.25 - - - - - - - exterior - 0.4 - - - - - - - exterior - 0.1 - - - - - - - exterior - 0.25 - - - - - - - - - TV other - - kWh/year - 620.0 - - - - - other - - kWh/year - 2457.0 - - - 0.855 - 0.045 - - - - -
-
\ No newline at end of file diff --git a/resources/hpxml-measures/workflow/tests/ACCA_Examples/Bob_Ross_Residence_3-22.xml b/resources/hpxml-measures/workflow/tests/ACCA_Examples/Bob_Ross_Residence_3-22.xml index 10640b97b2..47546477c9 100644 --- a/resources/hpxml-measures/workflow/tests/ACCA_Examples/Bob_Ross_Residence_3-22.xml +++ b/resources/hpxml-measures/workflow/tests/ACCA_Examples/Bob_Ross_Residence_3-22.xml @@ -552,10 +552,10 @@ garage basement - conditioned concrete block - 8.0 - 260.0 + 6.0 + 156.0 east - 8.0 + 6.0 1.71 diff --git a/resources/hpxml-measures/workflow/tests/ACCA_Examples/Bob_Ross_Residence_3-23.xml b/resources/hpxml-measures/workflow/tests/ACCA_Examples/Bob_Ross_Residence_3-23.xml index 01170e03ac..46ce008de5 100644 --- a/resources/hpxml-measures/workflow/tests/ACCA_Examples/Bob_Ross_Residence_3-23.xml +++ b/resources/hpxml-measures/workflow/tests/ACCA_Examples/Bob_Ross_Residence_3-23.xml @@ -357,10 +357,9 @@ ground crawlspace - unvented concrete block solid core - 10.0 - 1740.0 - north - 8.0 + 2.0 + 348.0 + 0.0 7.3 @@ -371,10 +370,10 @@ garage crawlspace - unvented concrete block solid core - 10.0 - 260.0 + 2.0 + 52.0 east - 8.0 + 0.0 7.3 diff --git a/resources/hpxml-measures/workflow/tests/base_results/results_acca_hvac.csv b/resources/hpxml-measures/workflow/tests/base_results/results_acca_hvac.csv index ab0a9a96d0..5ce0c8096b 100644 --- a/resources/hpxml-measures/workflow/tests/base_results/results_acca_hvac.csv +++ b/resources/hpxml-measures/workflow/tests/base_results/results_acca_hvac.csv @@ -15,8 +15,8 @@ Bob_Ross_Residence_3-19.xml,15.0,93.0,48732.0,32721.0,0.0,48732.0,5392.0,7478.0, Bob_Ross_Residence_3-2.xml,15.0,93.0,41962.0,30966.0,0.0,41962.0,4321.0,7478.0,1615.0,808.0,18183.0,0.0,0.0,2454.0,4196.0,0.0,2908.0,0.0,25911.0,2965.0,5849.0,2945.0,470.0,4163.0,0.0,0.0,0.0,3280.0,0.0,952.0,3552.0,1707.0,27.0,2872.0,565.0,0.0,1307.0,1000.0 Bob_Ross_Residence_3-20.xml,15.0,93.0,48009.0,32360.0,0.0,48009.0,4668.0,7478.0,1615.0,808.0,18183.0,0.0,0.0,2454.0,4196.0,2791.0,5815.0,0.0,27310.0,3022.0,5810.0,2945.0,470.0,4163.0,0.0,0.0,0.0,3280.0,457.0,1903.0,3552.0,1707.0,0.0,4807.0,565.0,627.0,2614.0,1000.0 Bob_Ross_Residence_3-21.xml,15.0,93.0,44547.0,31210.0,0.0,44547.0,4929.0,7478.0,1615.0,808.0,18183.0,0.0,0.0,2454.0,4196.0,2791.0,2093.0,0.0,26323.0,3139.0,5810.0,2945.0,470.0,4163.0,0.0,0.0,0.0,3280.0,457.0,799.0,3552.0,1707.0,0.0,4807.0,565.0,627.0,2614.0,1000.0 -Bob_Ross_Residence_3-22.xml,15.0,93.0,55479.0,34561.0,0.0,55479.0,5817.0,7478.0,1615.0,808.0,29949.0,0.0,0.0,2709.0,4196.0,0.0,2908.0,0.0,28660.0,3316.0,5810.0,2945.0,470.0,6628.0,0.0,0.0,0.0,3280.0,0.0,952.0,3552.0,1707.0,0.0,2872.0,565.0,0.0,1307.0,1000.0 -Bob_Ross_Residence_3-23.xml,15.0,93.0,39373.0,32746.0,0.0,39373.0,9948.0,5597.0,1615.0,808.0,10079.0,0.0,4222.0,0.0,4196.0,0.0,2908.0,0.0,26128.0,4490.0,4616.0,2945.0,470.0,3191.0,0.0,1382.0,0.0,3280.0,0.0,952.0,3095.0,1707.0,0.0,6450.0,4539.0,0.0,1307.0,604.0 +Bob_Ross_Residence_3-22.xml,15.0,93.0,54948.0,34561.0,0.0,54948.0,5758.0,7478.0,1615.0,808.0,29422.0,0.0,0.0,2765.0,4196.0,0.0,2908.0,0.0,28660.0,3316.0,5810.0,2945.0,470.0,6628.0,0.0,0.0,0.0,3280.0,0.0,952.0,3552.0,1707.0,0.0,2872.0,565.0,0.0,1307.0,1000.0 +Bob_Ross_Residence_3-23.xml,15.0,93.0,39253.0,32708.0,0.0,39253.0,9916.0,5597.0,1615.0,808.0,10079.0,0.0,4135.0,0.0,4196.0,0.0,2908.0,0.0,26093.0,4484.0,4616.0,2945.0,470.0,3191.0,0.0,1353.0,0.0,3280.0,0.0,952.0,3095.0,1707.0,0.0,6450.0,4539.0,0.0,1307.0,604.0 Bob_Ross_Residence_3-3.xml,15.0,93.0,41962.0,32754.0,0.0,41962.0,4321.0,7478.0,1615.0,808.0,18183.0,0.0,0.0,2454.0,4196.0,0.0,2908.0,0.0,27279.0,3140.0,6752.0,2945.0,470.0,4163.0,0.0,0.0,0.0,3280.0,0.0,952.0,3552.0,1707.0,317.0,2872.0,565.0,0.0,1307.0,1000.0 Bob_Ross_Residence_3-4.xml,15.0,93.0,41962.0,29729.0,0.0,41962.0,4321.0,7478.0,1615.0,808.0,18183.0,0.0,0.0,2454.0,4196.0,0.0,2908.0,0.0,24965.0,2845.0,5051.0,2945.0,470.0,4163.0,0.0,0.0,0.0,3280.0,0.0,952.0,3552.0,1707.0,0.0,2872.0,565.0,0.0,1307.0,1000.0 Bob_Ross_Residence_3-5.xml,15.0,93.0,41962.0,36796.0,0.0,41962.0,4321.0,7478.0,1615.0,808.0,18183.0,0.0,0.0,2454.0,4196.0,0.0,2908.0,0.0,30369.0,3534.0,9693.0,2945.0,470.0,4163.0,0.0,0.0,0.0,3280.0,0.0,952.0,3552.0,1707.0,73.0,2872.0,565.0,0.0,1307.0,1000.0 diff --git a/resources/hpxml-measures/workflow/tests/base_results/results_simulations_bills.csv b/resources/hpxml-measures/workflow/tests/base_results/results_simulations_bills.csv index efd5712afc..342ba17740 100644 --- a/resources/hpxml-measures/workflow/tests/base_results/results_simulations_bills.csv +++ b/resources/hpxml-measures/workflow/tests/base_results/results_simulations_bills.csv @@ -411,7 +411,6 @@ base-pv-generators-battery-scheduled.xml,955.78,144.0,1068.19,-978.65,233.54,144 base-pv-generators-battery.xml,924.45,144.0,1036.86,-978.65,202.21,144.0,338.28,482.28,0.0,239.96,239.96,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-pv-generators.xml,892.64,144.0,1005.05,-978.65,170.4,144.0,338.28,482.28,0.0,239.96,239.96,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-pv.xml,861.79,144.0,1303.13,-978.65,468.48,144.0,249.31,393.31,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 -base-residents-0-runperiod-1-month.xml,130.03,12.0,18.35,0.0,30.35,12.0,87.68,99.68,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-residents-0.xml,915.08,144.0,268.02,0.0,412.02,144.0,359.06,503.06,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-residents-1-misc-loads-large-uncommon.xml,2674.4,144.0,1817.12,0.0,1961.12,144.0,443.44,587.44,0.0,0.0,0.0,0.0,67.32,67.32,0.0,58.52,58.52,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-residents-1-misc-loads-large-uncommon2.xml,2404.07,144.0,1731.6,0.0,1875.6,144.0,254.61,398.61,0.0,71.34,71.34,0.0,0.0,0.0,0.0,0.0,0.0,0.0,58.52,58.52,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 diff --git a/resources/hpxml-measures/workflow/tests/base_results/results_simulations_energy.csv b/resources/hpxml-measures/workflow/tests/base_results/results_simulations_energy.csv index f231923ff7..c33851605c 100644 --- a/resources/hpxml-measures/workflow/tests/base_results/results_simulations_energy.csv +++ b/resources/hpxml-measures/workflow/tests/base_results/results_simulations_energy.csv @@ -411,7 +411,6 @@ base-pv-generators-battery-scheduled.xml,78.352,43.276,37.536,2.46,32.316,8.5,0. base-pv-generators-battery.xml,77.491,42.415,36.675,1.599,32.316,8.5,0.0,0.0,0.0,0.0,0.0,0.591,0.0,0.0,4.398,0.662,9.013,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.072,0.0,0.0,0.319,0.365,1.513,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,-26.886,-8.189,0.874,23.816,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,8.5,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,8.5,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-pv-generators.xml,76.617,41.541,35.801,0.725,32.316,8.5,0.0,0.0,0.0,0.0,0.0,0.591,0.0,0.0,4.398,0.662,9.013,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.072,0.0,0.0,0.319,0.365,1.513,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,-26.886,-8.189,0.0,23.816,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,8.5,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,8.5,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-pv.xml,59.617,32.73,35.801,8.914,23.816,0.0,0.0,0.0,0.0,0.0,0.0,0.591,0.0,0.0,4.398,0.662,9.013,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.072,0.0,0.0,0.319,0.365,1.513,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,-26.886,0.0,0.0,23.816,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 -base-residents-0-runperiod-1-month.xml,8.8797,8.8797,0.504,0.504,8.3757,0.0,0.0,0.0,0.0,0.0,0.0,0.2078,0.0,0.0,0.1034,0.0,0.0468,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.146,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,8.3757,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-residents-0.xml,41.664,41.664,7.363,7.363,34.301,0.0,0.0,0.0,0.0,0.0,0.0,0.851,0.0,0.0,3.398,0.481,0.577,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2.056,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,34.301,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-residents-1-misc-loads-large-uncommon.xml,99.944,99.944,49.922,49.922,42.362,0.0,2.527,5.133,0.0,0.0,0.0,0.565,0.0,0.0,4.562,0.695,3.75,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,4.293,1.024,0.0,0.2,0.221,0.917,1.115,0.0,2.007,6.55,5.687,1.15,0.0,6.508,2.937,2.899,0.0,0.0,0.0,22.778,0.0,0.0,0.0,0.0,0.0,18.039,0.0,0.0,1.544,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2.527,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,5.133,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-residents-1-misc-loads-large-uncommon2.xml,79.555,79.555,47.572,47.572,24.322,2.527,0.0,0.0,5.133,0.0,0.0,0.565,0.0,0.0,4.562,0.695,3.75,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,4.293,1.024,0.0,0.2,0.221,0.917,1.115,0.0,2.007,6.55,5.687,1.15,0.0,6.508,0.587,2.899,0.0,0.0,0.0,22.778,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.544,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2.527,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,5.133,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 diff --git a/resources/hpxml-measures/workflow/tests/base_results/results_simulations_hvac.csv b/resources/hpxml-measures/workflow/tests/base_results/results_simulations_hvac.csv index 0377e4c151..d85488c244 100644 --- a/resources/hpxml-measures/workflow/tests/base_results/results_simulations_hvac.csv +++ b/resources/hpxml-measures/workflow/tests/base_results/results_simulations_hvac.csv @@ -411,7 +411,6 @@ base-pv-generators-battery-scheduled.xml,6.8,91.76,36000.0,24000.0,0.0,32239.0,8 base-pv-generators-battery.xml,6.8,91.76,36000.0,24000.0,0.0,32239.0,8709.0,7508.0,0.0,575.0,6918.0,0.0,0.0,1738.0,2171.0,4620.0,0.0,0.0,20039.0,6112.0,7037.0,0.0,207.0,448.0,0.0,0.0,0.0,2293.0,622.0,0.0,3320.0,0.0,0.0,139.0,0.0,-661.0,0.0,800.0 base-pv-generators.xml,6.8,91.76,36000.0,24000.0,0.0,32239.0,8709.0,7508.0,0.0,575.0,6918.0,0.0,0.0,1738.0,2171.0,4620.0,0.0,0.0,20039.0,6112.0,7037.0,0.0,207.0,448.0,0.0,0.0,0.0,2293.0,622.0,0.0,3320.0,0.0,0.0,139.0,0.0,-661.0,0.0,800.0 base-pv.xml,6.8,91.76,36000.0,24000.0,0.0,32239.0,8709.0,7508.0,0.0,575.0,6918.0,0.0,0.0,1738.0,2171.0,4620.0,0.0,0.0,20039.0,6112.0,7037.0,0.0,207.0,448.0,0.0,0.0,0.0,2293.0,622.0,0.0,3320.0,0.0,0.0,139.0,0.0,-661.0,0.0,800.0 -base-residents-0-runperiod-1-month.xml,6.8,91.76,36000.0,24000.0,0.0,32239.0,8709.0,7508.0,0.0,575.0,6918.0,0.0,0.0,1738.0,2171.0,4620.0,0.0,0.0,20039.0,6112.0,7037.0,0.0,207.0,448.0,0.0,0.0,0.0,2293.0,622.0,0.0,3320.0,0.0,0.0,139.0,0.0,-661.0,0.0,800.0 base-residents-0.xml,6.8,91.76,36000.0,24000.0,0.0,32239.0,8709.0,7508.0,0.0,575.0,6918.0,0.0,0.0,1738.0,2171.0,4620.0,0.0,0.0,20039.0,6112.0,7037.0,0.0,207.0,448.0,0.0,0.0,0.0,2293.0,622.0,0.0,3320.0,0.0,0.0,139.0,0.0,-661.0,0.0,800.0 base-residents-1-misc-loads-large-uncommon.xml,6.8,91.76,36000.0,24000.0,0.0,33431.0,8742.0,7508.0,0.0,575.0,6918.0,0.0,0.0,1738.0,2171.0,5779.0,0.0,0.0,21277.0,6150.0,7037.0,0.0,207.0,448.0,0.0,0.0,0.0,2293.0,622.0,0.0,4520.0,0.0,0.0,139.0,0.0,-661.0,0.0,800.0 base-residents-1-misc-loads-large-uncommon2.xml,6.8,91.76,36000.0,24000.0,0.0,33431.0,8742.0,7508.0,0.0,575.0,6918.0,0.0,0.0,1738.0,2171.0,5779.0,0.0,0.0,21277.0,6150.0,7037.0,0.0,207.0,448.0,0.0,0.0,0.0,2293.0,622.0,0.0,4520.0,0.0,0.0,139.0,0.0,-661.0,0.0,800.0 diff --git a/resources/hpxml-measures/workflow/tests/base_results/results_simulations_loads.csv b/resources/hpxml-measures/workflow/tests/base_results/results_simulations_loads.csv index fe9e046176..7e033826de 100644 --- a/resources/hpxml-measures/workflow/tests/base_results/results_simulations_loads.csv +++ b/resources/hpxml-measures/workflow/tests/base_results/results_simulations_loads.csv @@ -411,7 +411,6 @@ base-pv-generators-battery-scheduled.xml,22.503,0.0,13.745,9.07,0.615,0.0,0.0,0. base-pv-generators-battery.xml,22.503,0.0,13.745,9.07,0.615,0.0,0.0,0.0,3.819,3.882,0.545,7.57,0.682,10.76,-13.571,0.0,0.0,0.0,8.363,-0.116,5.259,0.0,0.77,0.0,5.323,-8.475,-2.662,0.0,0.029,-0.188,-0.014,2.827,0.035,-0.632,10.837,0.0,0.0,0.0,-6.138,-0.112,-0.847,-3.884,-0.117,0.0,3.113,7.106,1.845 base-pv-generators.xml,22.503,0.0,13.745,9.07,0.615,0.0,0.0,0.0,3.819,3.882,0.545,7.57,0.682,10.76,-13.571,0.0,0.0,0.0,8.363,-0.116,5.259,0.0,0.77,0.0,5.323,-8.475,-2.662,0.0,0.029,-0.188,-0.014,2.827,0.035,-0.632,10.837,0.0,0.0,0.0,-6.138,-0.112,-0.847,-3.884,-0.117,0.0,3.113,7.106,1.845 base-pv.xml,22.503,0.0,13.745,9.07,0.615,0.0,0.0,0.0,3.819,3.882,0.545,7.57,0.682,10.76,-13.571,0.0,0.0,0.0,8.363,-0.116,5.259,0.0,0.77,0.0,5.323,-8.475,-2.662,0.0,0.029,-0.188,-0.014,2.827,0.035,-0.632,10.837,0.0,0.0,0.0,-6.138,-0.112,-0.847,-3.884,-0.117,0.0,3.113,7.106,1.845 -base-residents-0-runperiod-1-month.xml,7.9107,0.0,0.0,0.0,0.0511,0.0,0.0,0.0,0.5914,0.643,0.0909,1.746,0.1095,1.7781,-1.988,0.0,0.0,0.0,2.2357,-0.0004,1.0461,0.0,0.0,0.0,1.8131,-0.1971,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-residents-0.xml,32.415,0.0,10.561,0.0,0.62,0.0,0.0,0.0,3.761,3.912,0.547,7.099,0.683,10.947,-14.892,0.0,0.0,0.0,8.358,-0.174,6.026,0.0,0.0,0.0,7.39,-1.573,0.0,0.0,0.311,0.056,0.019,3.03,0.087,0.17,9.539,0.0,0.0,0.0,-5.202,-0.169,-0.644,0.0,0.0,0.0,2.393,1.102,0.0 base-residents-1-misc-loads-large-uncommon.xml,21.522,0.0,14.588,3.416,0.614,0.0,0.0,0.0,3.822,3.877,0.545,7.617,0.681,10.741,-13.462,0.0,0.0,0.0,8.416,-0.111,5.233,0.0,0.766,0.0,5.114,-9.432,-2.643,0.0,-0.024,-0.232,-0.02,2.761,0.024,-0.764,10.946,0.0,0.0,0.0,-6.251,-0.107,-0.887,-4.03,-0.122,0.0,3.256,8.291,1.864 base-residents-1-misc-loads-large-uncommon2.xml,21.522,0.0,14.588,3.416,0.614,0.0,0.0,0.0,3.822,3.877,0.545,7.617,0.681,10.741,-13.462,0.0,0.0,0.0,8.416,-0.111,5.233,0.0,0.766,0.0,5.114,-9.432,-2.643,0.0,-0.024,-0.232,-0.02,2.761,0.024,-0.764,10.946,0.0,0.0,0.0,-6.251,-0.107,-0.887,-4.03,-0.122,0.0,3.256,8.291,1.864 diff --git a/resources/hpxml-measures/workflow/tests/base_results/results_simulations_misc.csv b/resources/hpxml-measures/workflow/tests/base_results/results_simulations_misc.csv index a942301e78..7babdf768c 100644 --- a/resources/hpxml-measures/workflow/tests/base_results/results_simulations_misc.csv +++ b/resources/hpxml-measures/workflow/tests/base_results/results_simulations_misc.csv @@ -411,7 +411,6 @@ base-pv-generators-battery-scheduled.xml,0.0,0.0,1354.7,998.0,11171.6,2563.5,208 base-pv-generators-battery.xml,0.0,0.0,1354.7,998.0,11171.6,2563.5,2125.8,3715.9,3715.9,23.71,18.744,80.224 base-pv-generators.xml,0.0,0.0,1354.7,998.0,11171.6,2563.5,2082.5,3612.6,3612.6,23.71,18.744,0.0 base-pv.xml,0.0,0.0,1354.7,998.0,11171.6,2563.5,2082.5,3612.6,3612.6,23.71,18.744,0.0 -base-residents-0-runperiod-1-month.xml,0.0,0.0,0.0,0.0,0.0,0.0,627.96,0.0,627.96,27.1458,0.0,0.0 base-residents-0.xml,0.0,0.0,0.0,0.0,0.0,0.0,609.5,1840.9,1840.9,25.712,14.806,0.0 base-residents-1-misc-loads-large-uncommon.xml,0.0,0.0,821.3,625.4,3446.7,1167.8,2361.4,4228.7,4228.7,23.649,19.133,0.0 base-residents-1-misc-loads-large-uncommon2.xml,0.0,0.0,821.3,625.4,3446.7,1167.8,2242.3,4045.5,4045.5,23.649,19.133,0.0