Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
0b20bdb
Add dehumidifier to Rated Home
bpark1327 May 8, 2026
d5e658d
Bugfix
bpark1327 May 9, 2026
42527ca
Merge commit 'c9b018d135875d6b49bb2e08949e7ed787c81c60' into add_dh_t…
bpark1327 May 15, 2026
c9b018d
Squashed 'hpxml-measures/' changes from 552bb776cf..ef4dbd827c
bpark1327 May 15, 2026
4a4840c
Merge branch 'master' of https://github.com/NREL/OpenStudio-ERI into …
bpark1327 May 15, 2026
c24c895
add dehumidifier sizing method
bpark1327 Jun 13, 2026
c7149aa
Squashed 'hpxml-measures/' changes from ef4dbd827c..ebbfb275ac
bpark1327 Jun 13, 2026
5541849
Merge commit 'c7149aa548bdf6a251e333fa452adb2b5e55688f' into add_dh_t…
bpark1327 Jun 13, 2026
3c15bdc
Bugfix
bpark1327 Jun 13, 2026
73f4b32
cleanup
bpark1327 Jun 13, 2026
f886690
Refactor dehumidifier design-condition handling in 301 ruleset
bpark1327 Jun 13, 2026
c5abc69
Merge branch 'master' of https://github.com/NREL/OpenStudio-ERI into …
bpark1327 Jun 13, 2026
b8464be
Remove unnecessary flag and placeholders
bpark1327 Jun 15, 2026
d10ab91
Fix CI errors
shorowit Jun 15, 2026
cb2fa79
Similar fix for clothes dryer.
shorowit Jun 15, 2026
b64d8ef
Handle homes w/o garages
shorowit Jun 15, 2026
b95f1de
Skip a couple checks/tests
shorowit Jun 15, 2026
3e2eaac
Latest results. [skip ci]
Jun 16, 2026
aca57ab
Fix internal latent load unit in dehumidification
bpark1327 Jun 18, 2026
f4db860
Merge branch 'add_dh_to_rated_home' of https://github.com/NREL/OpenSt…
bpark1327 Jun 18, 2026
a5cf234
Round dehumidifier capacity to two decimal places
bpark1327 Jun 18, 2026
2df24bc
Add a dehumidifier to Ref Home
bpark1327 Jun 22, 2026
1ab168c
Refactor dehumidification calculations and update design conditions i…
bpark1327 Jun 23, 2026
f0b87c9
Add dehumidifier check for Index Adj Reference Home calculation
bpark1327 Jun 23, 2026
d68e578
change IAD reference home to not have a dehumidifier
bpark1327 Jun 23, 2026
e5c9da8
Add ventilation latent load sizing for dehumidification capacity
bpark1327 Jun 23, 2026
9c97952
Limit the total dehumidification load to 0 and limit the dehumidifier…
bpark1327 Jun 24, 2026
01bb5d9
Skip this home for now
shorowit Jun 24, 2026
5644e84
Latest results. [skip ci]
Jun 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions hpxml-measures/.github/workflows/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ jobs:
path: workflow/tests/test_results
name: results-workflow2-tests

- name: Store release package
uses: actions/upload-artifact@v7
with:
path: OpenStudio-HPXML-*.zip
archive: false

run-windows-tests:
runs-on: windows-latest
steps:
Expand Down
2 changes: 1 addition & 1 deletion hpxml-measures/BuildResidentialHPXML/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ The foundation type of the building. Garages are assumed to be over slab-on-grad

- **Required:** ``true``

- **Choices:** <br/> - `Slab-on-Grade`<br/> - `Crawlspace, Vented`<br/> - `Crawlspace, Unvented`<br/> - `Crawlspace, Conditioned`<br/> - `Basement, Unconditioned`<br/> - `Basement, Unconditioned, Half Above-Grade`<br/> - `Basement, Conditioned`<br/> - `Basement, Conditioned, Half Above-Grade`<br/> - `Ambient`<br/> - `Above Apartment`<br/> - `Belly and Wing, With Skirt`<br/> - `Belly and Wing, No Skirt`<br/> - `Detailed Example: Crawlspace, Vented, Above-Grade`<br/> - `ASHRAE 140 Tests: Basement, Conditioned`<br/> - `ASHRAE 140 Tests: Basement, Unconditioned`
- **Choices:** <br/> - `Slab-on-Grade`<br/> - `Crawlspace, Vented`<br/> - `Crawlspace, Unvented`<br/> - `Basement, Unconditioned`<br/> - `Basement, Unconditioned, Half Above-Grade`<br/> - `Basement, Conditioned`<br/> - `Basement, Conditioned, Half Above-Grade`<br/> - `Ambient`<br/> - `Above Apartment`<br/> - `Belly and Wing, With Skirt`<br/> - `Belly and Wing, No Skirt`<br/> - `Detailed Example: Crawlspace, Vented, Above-Grade`<br/> - `ASHRAE 140 Tests: Basement, Conditioned`<br/> - `ASHRAE 140 Tests: Basement, Unconditioned`


- **Default:** `Crawlspace, Vented`
Expand Down
39 changes: 14 additions & 25 deletions hpxml-measures/BuildResidentialHPXML/measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -943,8 +943,8 @@ def argument_errors(args)
error = ![HPXML::FoundationTypeSlab, HPXML::FoundationTypeAboveApartment].include?(args[:geometry_foundation_type_type]) && (args[:geometry_foundation_type_height] == 0)
errors << "Foundation type of '#{args[:geometry_foundation_type_type]}' cannot have a height of zero." if error

error = (args[:geometry_unit_type_facility_type] == HPXML::ResidentialTypeApartment) && ([HPXML::FoundationTypeBasementConditioned, HPXML::FoundationTypeCrawlspaceConditioned].include? args[:geometry_foundation_type_type])
errors << 'Conditioned basement/crawlspace foundation type for apartment units is not currently supported.' if error
error = (args[:geometry_unit_type_facility_type] == HPXML::ResidentialTypeApartment) && (args[:geometry_foundation_type_type] == HPXML::FoundationTypeBasementConditioned)
errors << 'Conditioned basement foundation type for apartment units is not currently supported.' if error

error = (args[:hvac_heating_system] == 'None') && (args[:hvac_heat_pump] == 'None') && (args[:hvac_heating_system_2] != 'None')
errors << 'A second heating system was specified without a primary heating system.' if error
Expand Down Expand Up @@ -1716,8 +1716,7 @@ def set_rim_joists(hpxml_bldg, model, args, sorted_surfaces)
next unless [HPXML::LocationBasementConditioned,
HPXML::LocationBasementUnconditioned,
HPXML::LocationCrawlspaceUnvented,
HPXML::LocationCrawlspaceVented,
HPXML::LocationCrawlspaceConditioned].include? interior_adjacent_to
HPXML::LocationCrawlspaceVented].include? interior_adjacent_to

exterior_adjacent_to = HPXML::LocationOutside
if surface.outsideBoundaryCondition == EPlus::BoundaryConditionAdiabatic # can be adjacent to foundation space
Expand Down Expand Up @@ -1893,8 +1892,7 @@ def set_foundation_walls(hpxml_bldg, model, args, sorted_surfaces)
next unless [HPXML::LocationBasementConditioned,
HPXML::LocationBasementUnconditioned,
HPXML::LocationCrawlspaceUnvented,
HPXML::LocationCrawlspaceVented,
HPXML::LocationCrawlspaceConditioned].include? interior_adjacent_to
HPXML::LocationCrawlspaceVented].include? interior_adjacent_to

exterior_adjacent_to = HPXML::LocationGround
if surface.outsideBoundaryCondition == EPlus::BoundaryConditionAdiabatic # can be adjacent to foundation space
Expand Down Expand Up @@ -1990,8 +1988,7 @@ def set_floors(hpxml_bldg, args, sorted_surfaces)
next if interior_adjacent_to == exterior_adjacent_to
next if (surface.surfaceType == EPlus::SurfaceTypeRoofCeiling) && (exterior_adjacent_to == HPXML::LocationOutside)
next if [HPXML::LocationConditionedSpace,
HPXML::LocationBasementConditioned,
HPXML::LocationCrawlspaceConditioned].include? exterior_adjacent_to
HPXML::LocationBasementConditioned].include? exterior_adjacent_to

hpxml_bldg.floors.add(id: "Floor#{hpxml_bldg.floors.size + 1}",
exterior_adjacent_to: exterior_adjacent_to,
Expand Down Expand Up @@ -2064,7 +2061,6 @@ def set_slabs(hpxml_bldg, model, args, sorted_surfaces)
has_foundation_walls = false
if [HPXML::LocationCrawlspaceVented,
HPXML::LocationCrawlspaceUnvented,
HPXML::LocationCrawlspaceConditioned,
HPXML::LocationBasementUnconditioned,
HPXML::LocationBasementConditioned].include? interior_adjacent_to
has_foundation_walls = true
Expand Down Expand Up @@ -2115,12 +2111,6 @@ def set_slabs(hpxml_bldg, model, args, sorted_surfaces)
hpxml_slab.carpet_fraction = args[:enclosure_carpet_fraction]
hpxml_slab.carpet_r_value = args[:enclosure_carpet_r_value]
end

next unless interior_adjacent_to == HPXML::LocationCrawlspaceConditioned

# Increase Conditioned Building Volume
conditioned_crawlspace_volume = hpxml_slab.area * args[:geometry_foundation_type_height]
hpxml_bldg.building_construction.conditioned_building_volume += conditioned_crawlspace_volume
end
end

Expand Down Expand Up @@ -2325,8 +2315,7 @@ def set_foundations(hpxml_bldg, args)
foundation_locations = [HPXML::LocationBasementConditioned,
HPXML::LocationBasementUnconditioned,
HPXML::LocationCrawlspaceUnvented,
HPXML::LocationCrawlspaceVented,
HPXML::LocationCrawlspaceConditioned]
HPXML::LocationCrawlspaceVented]

surf_ids.each do |surf_type, surf_hash|
surf_hash['surfaces'].each do |surface|
Expand Down Expand Up @@ -2864,24 +2853,23 @@ def set_duct_leakages(args, hvac_distribution)
#
# @param building_component [String] the building component of interest
# @param location [String] the location of interest (HPXML::LocationCrawlspace or HPXML::LocationAttic)
# @param foundation_type [String] the specific HPXML foundation type (unvented crawlspace, vented crawlspace, conditioned crawlspace)
# @param attic_type [String] the specific HPXML attic type (unvented attic, vented attic, conditioned attic)
# @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit
# @return [nil]
def get_location(building_component, location, foundation_type, attic_type)
def get_location(building_component, location, hpxml_bldg)
return if location.nil?

if location == HPXML::LocationCrawlspace
foundation_type = hpxml_bldg.foundations[-1].foundation_type
case foundation_type
when HPXML::FoundationTypeCrawlspaceUnvented
return HPXML::LocationCrawlspaceUnvented
when HPXML::FoundationTypeCrawlspaceVented
return HPXML::LocationCrawlspaceVented
when HPXML::FoundationTypeCrawlspaceConditioned
return HPXML::LocationCrawlspaceConditioned
else
fail "Specified '#{location}' for #{building_component} location but foundation type is '#{foundation_type}'."
end
elsif location == HPXML::LocationAttic
attic_type = hpxml_bldg.attics[-1].attic_type
case attic_type
when HPXML::AtticTypeUnvented
return HPXML::LocationAtticUnvented
Expand All @@ -2893,6 +2881,7 @@ def get_location(building_component, location, foundation_type, attic_type)
fail "Specified '#{location}' for #{building_component} location but attic type is '#{attic_type}'."
end
elsif location == HPXML::LocationBasement
foundation_type = hpxml_bldg.foundations[-1].foundation_type
case foundation_type
when HPXML::FoundationTypeBasementConditioned
return HPXML::LocationBasementConditioned
Expand All @@ -2912,8 +2901,8 @@ def get_location(building_component, location, foundation_type, attic_type)
# @param hvac_distribution [HPXML::HVACDistribution] HPXML HVAC Distribution object
# @return [nil]
def set_ducts(hpxml_bldg, args, hvac_distribution)
ducts_supply_location = get_location('supply ducts', args[:hvac_ducts_supply_location_location], hpxml_bldg.foundations[-1].foundation_type, hpxml_bldg.attics[-1].attic_type)
ducts_return_location = get_location('return ducts', args[:hvac_ducts_return_location_location], hpxml_bldg.foundations[-1].foundation_type, hpxml_bldg.attics[-1].attic_type)
ducts_supply_location = get_location('supply ducts', args[:hvac_ducts_supply_location_location], hpxml_bldg)
ducts_return_location = get_location('return ducts', args[:hvac_ducts_return_location_location], hpxml_bldg)

ncfl = hpxml_bldg.building_construction.number_of_conditioned_floors
ncfl_ag = hpxml_bldg.building_construction.number_of_conditioned_floors_above_grade
Expand Down Expand Up @@ -3146,7 +3135,7 @@ def set_ventilation_fans(hpxml_bldg, args)
def set_water_heating_systems(hpxml_bldg, args)
return if args[:dhw_water_heater] == 'None'

location = get_location('water heater', args[:dhw_water_heater_location_location], hpxml_bldg.foundations[-1].foundation_type, hpxml_bldg.attics[-1].attic_type)
location = get_location('water heater', args[:dhw_water_heater_location_location], hpxml_bldg)

if not [HPXML::WaterHeaterTypeCombiStorage, HPXML::WaterHeaterTypeCombiTankless].include? args[:dhw_water_heater_type]
case args[:dhw_water_heater_efficiency_type]
Expand Down
14 changes: 7 additions & 7 deletions hpxml-measures/BuildResidentialHPXML/measure.xml
Original file line number Diff line number Diff line change
Expand Up @@ -921,10 +921,6 @@
<value>Crawlspace, Unvented</value>
<display_name>Crawlspace, Unvented</display_name>
</choice>
<choice>
<value>Crawlspace, Conditioned</value>
<display_name>Crawlspace, Conditioned</display_name>
</choice>
<choice>
<value>Basement, Unconditioned</value>
<display_name>Basement, Unconditioned</display_name>
Expand Down Expand Up @@ -11454,7 +11450,11 @@
<filename>measure.rb</filename>
<filetype>rb</filetype>
<usage_type>script</usage_type>
<<<<<<< HEAD
<checksum>FE0CEC87</checksum>
=======
<checksum>E3E200DA</checksum>
>>>>>>> c7149aa548bdf6a251e333fa452adb2b5e55688f
</file>
<file>
<filename>constants.rb</filename>
Expand All @@ -11466,7 +11466,7 @@
<filename>geometry.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>7B56FACC</checksum>
<checksum>84C42F03</checksum>
</file>
<file>
<filename>options/advanced_feature.tsv</filename>
Expand Down Expand Up @@ -11766,7 +11766,7 @@
<filename>options/geometry_foundation_type.tsv</filename>
<filetype>tsv</filetype>
<usage_type>resource</usage_type>
<checksum>A0ED3FC0</checksum>
<checksum>647701C8</checksum>
</file>
<file>
<filename>options/geometry_garage_type.tsv</filename>
Expand Down Expand Up @@ -12096,7 +12096,7 @@
<filename>test_build_residential_hpxml.rb</filename>
<filetype>rb</filetype>
<usage_type>test</usage_type>
<checksum>819DB64D</checksum>
<checksum>E0DC52BC</checksum>
</file>
</files>
</measure>
76 changes: 11 additions & 65 deletions hpxml-measures/BuildResidentialHPXML/resources/geometry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -322,11 +322,7 @@ def self.create_single_family_detached(runner, model,
# create attic zone
attic_zone = OpenStudio::Model::ThermalZone.new(model)
attic_space.setThermalZone(attic_zone)
if attic_type == HPXML::AtticTypeVented
attic_space_name = HPXML::LocationAtticVented
elsif attic_type == HPXML::AtticTypeUnvented
attic_space_name = HPXML::LocationAtticUnvented
end
attic_space_name = HPXML::get_location_from_attic_type(attic_type)
attic_zone.setName(attic_space_name)
when HPXML::AtticTypeConditioned
attic_space.setThermalZone(conditioned_zone)
Expand All @@ -344,12 +340,15 @@ def self.create_single_family_detached(runner, model,
end

# Foundation
if foundation_type.start_with? HPXML::FoundationTypeBellyAndWing
foundation_type = HPXML::FoundationTypeBellyAndWing
end
if [HPXML::FoundationTypeCrawlspaceVented,
HPXML::FoundationTypeCrawlspaceUnvented,
HPXML::FoundationTypeCrawlspaceConditioned,
HPXML::FoundationTypeBasementUnconditioned,
HPXML::FoundationTypeBasementConditioned,
HPXML::FoundationTypeAmbient].include?(foundation_type) || foundation_type.start_with?(HPXML::FoundationTypeBellyAndWing)
HPXML::FoundationTypeAmbient,
HPXML::FoundationTypeBellyAndWing].include?(foundation_type)

z = -foundation_height

Expand All @@ -367,24 +366,7 @@ def self.create_single_family_detached(runner, model,
foundation_space = OpenStudio::Model::Space::fromFloorPrint(foundation_polygon, foundation_height, model)
foundation_space = foundation_space.get
assign_indexes(model, footprint_polygon: foundation_polygon, space: foundation_space)
case foundation_type
when HPXML::FoundationTypeCrawlspaceVented
foundation_space_name = HPXML::LocationCrawlspaceVented
when HPXML::FoundationTypeCrawlspaceUnvented
foundation_space_name = HPXML::LocationCrawlspaceUnvented
when HPXML::FoundationTypeCrawlspaceConditioned
foundation_space_name = HPXML::LocationCrawlspaceConditioned
when HPXML::FoundationTypeBasementUnconditioned
foundation_space_name = HPXML::LocationBasementUnconditioned
when HPXML::FoundationTypeBasementConditioned
foundation_space_name = HPXML::LocationBasementConditioned
when HPXML::FoundationTypeAmbient
foundation_space_name = HPXML::LocationOutside
else
if foundation_type.start_with? HPXML::FoundationTypeBellyAndWing
foundation_space_name = HPXML::LocationManufacturedHomeUnderBelly
end
end
foundation_space_name = HPXML::get_location_from_foundation_type(foundation_type)
foundation_zone.setName(foundation_space_name)
foundation_space.setName(foundation_space_name)
foundation_space_type = OpenStudio::Model::SpaceType.new(model)
Expand Down Expand Up @@ -804,21 +786,7 @@ def self.create_single_family_attached(model,

# create foundation zone
foundation_zone = OpenStudio::Model::ThermalZone.new(model)

case foundation_type
when HPXML::FoundationTypeCrawlspaceVented
foundation_space_name = HPXML::LocationCrawlspaceVented
when HPXML::FoundationTypeCrawlspaceUnvented
foundation_space_name = HPXML::LocationCrawlspaceUnvented
when HPXML::FoundationTypeCrawlspaceConditioned
foundation_space_name = HPXML::LocationCrawlspaceConditioned
when HPXML::FoundationTypeBasementUnconditioned
foundation_space_name = HPXML::LocationBasementUnconditioned
when HPXML::FoundationTypeBasementConditioned
foundation_space_name = HPXML::LocationBasementConditioned
when HPXML::FoundationTypeAmbient
foundation_space_name = HPXML::LocationOutside
end
foundation_space_name = HPXML::get_location_from_foundation_type(foundation_type)
foundation_zone.setName(foundation_space_name)
foundation_space.setName(foundation_space_name)
foundation_space_type = OpenStudio::Model::SpaceType.new(model)
Expand Down Expand Up @@ -886,11 +854,7 @@ def self.create_single_family_attached(model,
# create attic zone
attic_zone = OpenStudio::Model::ThermalZone.new(model)
attic_space.setThermalZone(attic_zone)
if attic_type == HPXML::AtticTypeVented
attic_space_name = HPXML::LocationAtticVented
elsif attic_type == HPXML::AtticTypeUnvented
attic_space_name = HPXML::LocationAtticUnvented
end
attic_space_name = HPXML::get_location_from_attic_type(attic_type)
attic_zone.setName(attic_space_name)
end
attic_space.setName(attic_space_name)
Expand Down Expand Up @@ -1098,21 +1062,7 @@ def self.create_apartment(model,

# create foundation zone
foundation_zone = OpenStudio::Model::ThermalZone.new(model)

case foundation_type
when HPXML::FoundationTypeCrawlspaceVented
foundation_space_name = HPXML::LocationCrawlspaceVented
when HPXML::FoundationTypeCrawlspaceUnvented
foundation_space_name = HPXML::LocationCrawlspaceUnvented
when HPXML::FoundationTypeCrawlspaceConditioned
foundation_space_name = HPXML::LocationCrawlspaceConditioned
when HPXML::FoundationTypeBasementUnconditioned
foundation_space_name = HPXML::LocationBasementUnconditioned
when HPXML::FoundationTypeBasementConditioned
foundation_space_name = HPXML::LocationBasementConditioned
when HPXML::FoundationTypeAmbient
foundation_space_name = HPXML::LocationOutside
end
foundation_space_name = HPXML::get_location_from_foundation_type(foundation_type)
foundation_zone.setName(foundation_space_name)
foundation_space.setName(foundation_space_name)
foundation_space_type = OpenStudio::Model::SpaceType.new(model)
Expand Down Expand Up @@ -1178,11 +1128,7 @@ def self.create_apartment(model,
# create attic zone
attic_zone = OpenStudio::Model::ThermalZone.new(model)
attic_space.setThermalZone(attic_zone)
if attic_type == HPXML::AtticTypeVented
attic_space_name = HPXML::LocationAtticVented
elsif attic_type == HPXML::AtticTypeUnvented
attic_space_name = HPXML::LocationAtticUnvented
end
attic_space_name = HPXML::get_location_from_attic_type(attic_type)
attic_zone.setName(attic_space_name)
end
attic_space.setName(attic_space_name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ Option Name Type Height [ft] Height Above Grade [ft] Rim Joist Height [in]
Slab-on-Grade SlabOnGrade 0 0 0
"Crawlspace, Vented" VentedCrawlspace 4 1 9.25
"Crawlspace, Unvented" UnventedCrawlspace 4 1 9.25
"Crawlspace, Conditioned" ConditionedCrawlspace 4 1 9.25
"Basement, Unconditioned" UnconditionedBasement 8 1 9.25
"Basement, Unconditioned, Half Above-Grade" UnconditionedBasement 8 4 9.25
"Basement, Conditioned" ConditionedBasement 8 1 9.25
Expand Down
Loading