Skip to content

Commit c120027

Browse files
committed
Merge commit 'cf604c042954eb1476e3780ec008b50a1df3d1af' into latest-os-hpxml
2 parents 70469c7 + cf604c0 commit c120027

16 files changed

Lines changed: 567 additions & 37 deletions

hpxml-measures/BuildResidentialHPXML/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ Path to the EPW file. Either this or the Zip Code input above must be provided.
7676

7777
**Location: Site Type**
7878

79-
The terrain/shielding of the home, for the infiltration model. Defaults to 'Suburban, Normal' for single-family detached and manufactured home and 'Suburban, Well-Shielded' for single-family attached and apartment units.
79+
The terrain/shielding of the home, for the infiltration model.
8080

8181
- **Name:** ``location_site_type``
8282
- **Type:** ``Choice``
@@ -209,7 +209,7 @@ The number of bedrooms in the unit.
209209

210210
**Geometry: Unit Number of Bathrooms**
211211

212-
The number of bathrooms in the unit. Defaults to NumberofBedrooms/2 + 0.5.
212+
The number of bathrooms in the unit.
213213

214214
- **Name:** ``geometry_unit_num_bathrooms``
215215
- **Type:** ``Choice``

hpxml-measures/BuildResidentialHPXML/measure.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def arguments(model) # rubocop:disable Lint/UnusedMethodArgument
8080

8181
arg = OpenStudio::Measure::OSArgument.makeChoiceArgument('location_site_type', choices[:location_site_type], false)
8282
arg.setDisplayName('Location: Site Type')
83-
arg.setDescription("The terrain/shielding of the home, for the infiltration model. Defaults to 'Suburban, Normal' for single-family detached and manufactured home and 'Suburban, Well-Shielded' for single-family attached and apartment units.")
83+
arg.setDescription('The terrain/shielding of the home, for the infiltration model.')
8484
arg.setDefaultValue('Default')
8585
args << arg
8686

@@ -136,7 +136,7 @@ def arguments(model) # rubocop:disable Lint/UnusedMethodArgument
136136

137137
arg = OpenStudio::Measure::OSArgument.makeChoiceArgument('geometry_unit_num_bathrooms', choices[:geometry_unit_num_bathrooms], false)
138138
arg.setDisplayName('Geometry: Unit Number of Bathrooms')
139-
arg.setDescription('The number of bathrooms in the unit. Defaults to NumberofBedrooms/2 + 0.5.')
139+
arg.setDescription('The number of bathrooms in the unit.')
140140
arg.setDefaultValue('Default')
141141
args << arg
142142

hpxml-measures/BuildResidentialHPXML/measure.xml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
<schema_version>3.1</schema_version>
44
<name>build_residential_hpxml</name>
55
<uid>a13a8983-2b01-4930-8af2-42030b6e4233</uid>
6-
<version_id>f4f37f65-5e30-41a0-b3dc-7a4a1fa57f44</version_id>
7-
<version_modified>2026-05-22T21:28:29Z</version_modified>
6+
<version_id>8c6a6855-95e8-491e-8fb6-6820b622531e</version_id>
7+
<version_modified>2026-07-17T21:33:32Z</version_modified>
88
<xml_checksum>2C38F48B</xml_checksum>
99
<class_name>BuildResidentialHPXML</class_name>
1010
<display_name>HPXML Builder</display_name>
@@ -108,7 +108,7 @@
108108
<argument>
109109
<name>location_site_type</name>
110110
<display_name>Location: Site Type</display_name>
111-
<description>The terrain/shielding of the home, for the infiltration model. Defaults to 'Suburban, Normal' for single-family detached and manufactured home and 'Suburban, Well-Shielded' for single-family attached and apartment units.</description>
111+
<description>The terrain/shielding of the home, for the infiltration model.</description>
112112
<type>Choice</type>
113113
<required>false</required>
114114
<model_dependent>false</model_dependent>
@@ -595,7 +595,7 @@
595595
<argument>
596596
<name>geometry_unit_num_bathrooms</name>
597597
<display_name>Geometry: Unit Number of Bathrooms</display_name>
598-
<description>The number of bathrooms in the unit. Defaults to NumberofBedrooms/2 + 0.5.</description>
598+
<description>The number of bathrooms in the unit.</description>
599599
<type>Choice</type>
600600
<required>false</required>
601601
<model_dependent>false</model_dependent>
@@ -11433,7 +11433,7 @@
1143311433
<filename>README.md</filename>
1143411434
<filetype>md</filetype>
1143511435
<usage_type>readme</usage_type>
11436-
<checksum>40789597</checksum>
11436+
<checksum>E343E87E</checksum>
1143711437
</file>
1143811438
<file>
1143911439
<filename>README.md.erb</filename>
@@ -11450,7 +11450,7 @@
1145011450
<filename>measure.rb</filename>
1145111451
<filetype>rb</filetype>
1145211452
<usage_type>script</usage_type>
11453-
<checksum>E3E200DA</checksum>
11453+
<checksum>93E3B4F6</checksum>
1145411454
</file>
1145511455
<file>
1145611456
<filename>constants.rb</filename>

hpxml-measures/Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ __Bugfixes__
1010
- **Breaking change**: HPWH `EnergyFactor`/`UniformEnergyFactor` must now be >= 1.45 (previously > 1).
1111
- Fixes ERV supply outlet enthalpy calculation used to calculate latent effectiveness.
1212
- Removes duplicated ceiling/floor internal mass surfaces between conditioned stories.
13+
- Fixes error if `NumberofBedrooms=0` and `NumberofBathrooms` is omitted.
1314

1415
## OpenStudio-HPXML v1.12.0
1516

hpxml-measures/HPXMLtoOpenStudio/measure.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
<schema_version>3.1</schema_version>
44
<name>hpxml_to_openstudio</name>
55
<uid>b1543b30-9465-45ff-ba04-1d1f85e763bc</uid>
6-
<version_id>b5a80774-bddd-4161-b29c-68607900018d</version_id>
7-
<version_modified>2026-07-16T19:57:35Z</version_modified>
6+
<version_id>5116048e-a294-48a6-9d6e-0176fe080069</version_id>
7+
<version_modified>2026-07-20T20:17:08Z</version_modified>
88
<xml_checksum>D8922A73</xml_checksum>
99
<class_name>HPXMLToOpenStudio</class_name>
1010
<display_name>HPXML to OpenStudio Translator</display_name>
@@ -367,7 +367,7 @@
367367
<filename>defaults.rb</filename>
368368
<filetype>rb</filetype>
369369
<usage_type>resource</usage_type>
370-
<checksum>4350A1B4</checksum>
370+
<checksum>13035117</checksum>
371371
</file>
372372
<file>
373373
<filename>electric_panel.rb</filename>
@@ -751,7 +751,7 @@
751751
<filename>test_defaults.rb</filename>
752752
<filetype>rb</filetype>
753753
<usage_type>test</usage_type>
754-
<checksum>2C65B351</checksum>
754+
<checksum>F470D66D</checksum>
755755
</file>
756756
<file>
757757
<filename>test_electric_panel.rb</filename>

hpxml-measures/HPXMLtoOpenStudio/resources/defaults.rb

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -922,7 +922,7 @@ def self.apply_building_construction(hpxml_header, hpxml_bldg)
922922
hpxml_bldg.building_construction.conditioned_building_volume_isdefaulted = true
923923
end
924924
if hpxml_bldg.building_construction.number_of_bathrooms.nil?
925-
hpxml_bldg.building_construction.number_of_bathrooms = Float(get_num_bathrooms(nbeds)).to_i
925+
hpxml_bldg.building_construction.number_of_bathrooms = get_num_bathrooms(nbeds)
926926
hpxml_bldg.building_construction.number_of_bathrooms_isdefaulted = true
927927
end
928928
if hpxml_bldg.building_construction.number_of_units.nil?
@@ -2820,7 +2820,7 @@ def self.apply_hvac_control(hpxml_bldg, schedules_file, eri_version)
28202820
schedules_file_includes_cooling_setpoint_temp = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:CoolingSetpoint].name))
28212821
if hvac_control.cooling_setpoint_temp.nil? && hvac_control.weekday_cooling_setpoints.nil? && !schedules_file_includes_cooling_setpoint_temp
28222822
# No cooling setpoints; set a default cooling setpoint for, e.g., natural ventilation
2823-
clg_weekday_setpoints, clg_weekend_setpoints = Defaults.get_cooling_setpoint(HPXML::HVACControlTypeManual, eri_version)
2823+
clg_weekday_setpoints, clg_weekend_setpoints = get_cooling_setpoint(HPXML::HVACControlTypeManual, eri_version)
28242824
if clg_weekday_setpoints.split(', ').uniq.size == 1 && clg_weekend_setpoints.split(', ').uniq.size == 1 && clg_weekday_setpoints.split(', ').uniq == clg_weekend_setpoints.split(', ').uniq
28252825
hvac_control.cooling_setpoint_temp = clg_weekend_setpoints.split(', ').uniq[0].to_f
28262826
else
@@ -4603,7 +4603,7 @@ def self.apply_ceiling_fans(hpxml_bldg, weather, schedules_file)
46034603
ceiling_fan.weekend_fractions_isdefaulted = true
46044604
end
46054605
if ceiling_fan.monthly_multipliers.nil? && !schedules_file_includes_ceiling_fan
4606-
ceiling_fan.monthly_multipliers = Defaults.get_ceiling_fan_months(weather).join(', ')
4606+
ceiling_fan.monthly_multipliers = get_ceiling_fan_months(weather).join(', ')
46074607
ceiling_fan.monthly_multipliers_isdefaulted = true
46084608
end
46094609
end
@@ -5483,10 +5483,15 @@ def self.lookup_weather_data_from_wmo(wmo)
54835483
# Gets the default number of bathrooms in the dwelling unit.
54845484
#
54855485
# @param nbeds [Integer] Number of bedrooms in the dwelling unit
5486-
# @return [Double] Number of bathrooms
5486+
# @return [Integer] Number of bathrooms
54875487
def self.get_num_bathrooms(nbeds)
54885488
nbaths = nbeds / 2.0 + 0.5 # From BA HSP
5489-
return nbaths
5489+
5490+
# Ensure at least 1 bathroom (which the HPXML schema requires).
5491+
# Even a studio apartment w/ zero bedrooms would have a bathroom.
5492+
nbaths = [nbaths, 1].max
5493+
5494+
return nbaths.to_i
54905495
end
54915496

54925497
# Gets the default properties for cooking ranges/ovens.
@@ -6144,10 +6149,6 @@ def self.get_water_heater_performance_adjustment(water_heating_system)
61446149
# @param nbaths [Integer] Number of bathrooms in the dwelling unit
61456150
# @return [Double] Water heater heating capacity (Btu/hr)
61466151
def self.get_water_heater_heating_capacity(fuel, nbeds, num_water_heaters, nbaths = nil)
6147-
if nbaths.nil?
6148-
nbaths = Defaults.get_num_bathrooms(nbeds)
6149-
end
6150-
61516152
# Adjust the heating capacity if there are multiple water heaters in the home
61526153
nbaths /= num_water_heaters.to_f
61536154

@@ -6195,10 +6196,6 @@ def self.get_water_heater_tank_volume(fuel, is_hpwh, nbeds, nbaths, n_occ)
61956196
# FUTURE: Take into account usage multipliers
61966197
# FUTURE: Incorporate number of occupants for conventional elec/gas storage WHs.
61976198

6198-
if nbaths.nil?
6199-
nbaths = Defaults.get_num_bathrooms(nbeds)
6200-
end
6201-
62026199
if is_hpwh && !n_occ.nil? # Heat pump water heater
62036200
# Source: Jeff Maguire recommendation for ResStock when num occupants is known
62046201
if (nbeds <= 2) && (n_occ <= 3)
@@ -7555,7 +7552,7 @@ def self.get_pool_pump_annual_energy(cfa, nbeds, n_occ, unit_type)
75557552
return 0.0
75567553
end
75577554

7558-
nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type)
7555+
nbeds_eq = get_equivalent_nbeds(nbeds, n_occ, unit_type)
75597556

75607557
return 158.6 / 0.070 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0)
75617558
end
@@ -7569,7 +7566,7 @@ def self.get_pool_pump_annual_energy(cfa, nbeds, n_occ, unit_type)
75697566
# @param type [String] Type of heater (HPXML::HeaterTypeXXX)
75707567
# @return [Array<String, Double>] Energy units (HPXML::UnitsXXX), annual energy use (kWh/yr or therm/yr)
75717568
def self.get_pool_heater_annual_energy(cfa, nbeds, n_occ, unit_type, type)
7572-
nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type)
7569+
nbeds_eq = get_equivalent_nbeds(nbeds, n_occ, unit_type)
75737570

75747571
load_units = nil
75757572
load_value = nil
@@ -7609,7 +7606,7 @@ def self.get_permanent_spa_pump_annual_energy(cfa, nbeds, n_occ, unit_type)
76097606
return 0.0
76107607
end
76117608

7612-
nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type)
7609+
nbeds_eq = get_equivalent_nbeds(nbeds, n_occ, unit_type)
76137610

76147611
return 59.5 / 0.059 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) # kWh/yr
76157612
end
@@ -7623,7 +7620,7 @@ def self.get_permanent_spa_pump_annual_energy(cfa, nbeds, n_occ, unit_type)
76237620
# @param type [String] Type of heater (HPXML::HeaterTypeXXX)
76247621
# @return [Array<String, Double>] Energy units (HPXML::UnitsXXX), annual energy use (kWh/yr or therm/yr)
76257622
def self.get_permanent_spa_heater_annual_energy(cfa, nbeds, n_occ, unit_type, type)
7626-
nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type)
7623+
nbeds_eq = get_equivalent_nbeds(nbeds, n_occ, unit_type)
76277624

76287625
load_units = nil
76297626
load_value = nil
@@ -7683,7 +7680,7 @@ def self.get_default_well_pump_annual_energy(cfa, nbeds, n_occ, unit_type)
76837680
return 0.0
76847681
end
76857682

7686-
nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type)
7683+
nbeds_eq = get_equivalent_nbeds(nbeds, n_occ, unit_type)
76877684

76887685
return 50.8 / 0.127 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0)
76897686
end
@@ -7701,7 +7698,7 @@ def self.get_gas_grill_annual_energy(cfa, nbeds, n_occ, unit_type)
77017698
return 0.0
77027699
end
77037700

7704-
nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type)
7701+
nbeds_eq = get_equivalent_nbeds(nbeds, n_occ, unit_type)
77057702

77067703
return 0.87 / 0.029 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0)
77077704
end
@@ -7719,7 +7716,7 @@ def self.get_default_gas_lighting_annual_energy(cfa, nbeds, n_occ, unit_type)
77197716
return 0.0
77207717
end
77217718

7722-
nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type)
7719+
nbeds_eq = get_equivalent_nbeds(nbeds, n_occ, unit_type)
77237720

77247721
return 0.22 / 0.012 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0)
77257722
end
@@ -7737,7 +7734,7 @@ def self.get_gas_fireplace_annual_energy(cfa, nbeds, n_occ, unit_type)
77377734
return 0.0
77387735
end
77397736

7740-
nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type)
7737+
nbeds_eq = get_equivalent_nbeds(nbeds, n_occ, unit_type)
77417738

77427739
return 1.95 / 0.032 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0)
77437740
end
@@ -7755,7 +7752,7 @@ def self.get_water_use_internal_gains(nbeds, n_occ, unit_type, general_water_use
77557752
return 0.0, 0.0
77567753
end
77577754

7758-
nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type)
7755+
nbeds_eq = get_equivalent_nbeds(nbeds, n_occ, unit_type)
77597756

77607757
# ANSI/RESNET/ICC 301 - Table 4.2.2(3). Internal Gains for Reference Homes
77617758
sens_gains = (-1227.0 - 409.0 * nbeds_eq) * general_water_use_usage_multiplier # Btu/day

hpxml-measures/HPXMLtoOpenStudio/tests/test_defaults.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,12 @@ def test_building_construction
530530
_default_hpxml, default_hpxml_bldg = _test_measure()
531531
_test_default_building_construction_values(default_hpxml_bldg, 21600, 8.0, 2, 1, -7)
532532

533+
# Test defaults w/ zero bedrooms
534+
hpxml_bldg.building_construction.number_of_bedrooms = 0
535+
XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path)
536+
_default_hpxml, default_hpxml_bldg = _test_measure()
537+
_test_default_building_construction_values(default_hpxml_bldg, 21600, 8.0, 1, 1, -7)
538+
533539
# Test defaults w/ belly-and-wing foundation
534540
hpxml, hpxml_bldg = _create_hpxml('base-foundation-belly-wing-skirt.xml')
535541
hpxml_bldg.building_construction.conditioned_building_volume = nil

hpxml-measures/docs/source/workflow_inputs.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,7 @@ Building construction is entered in ``/HPXML/Building/BuildingDetails/BuildingSu
651651

652652
.. [#] If AverageCeilingHeight not provided, defaults to (ConditionedBuildingVolume - ConditionedCrawlspaceVolume) / ConditionedFloorArea if ConditionedBuildingVolume is provided.
653653
If ConditionedBuildingVolume not provided, AverageCeilingHeight defaults to 8.0 ft (unless there is a cathedral ceiling, in which case the value is adjusted).
654-
.. [#] If NumberofBathrooms not provided, calculated as NumberofBedrooms/2 + 0.5 based on the `2010 BAHSP <https://www1.eere.energy.gov/buildings/publications/pdfs/building_america/house_simulation.pdf>`_.
654+
.. [#] If NumberofBathrooms not provided, calculated as NumberofBedrooms/2 + 0.5 (rounded down, with a minimum of 1) based on the `2010 BAHSP <https://www1.eere.energy.gov/buildings/publications/pdfs/building_america/house_simulation.pdf>`_.
655655
.. [#] If ConditionedBuildingVolume not provided, defaults to ConditionedFloorArea * AverageCeilingHeight + ConditionedCrawlspaceVolume.
656656

657657
HPXML Schedules

hpxml-measures/workflow/hpxml_inputs.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,6 +1092,11 @@
10921092
"enclosure_floor_over_garage": "Wood Frame, R-38",
10931093
"enclosure_carpet": "80% Carpet"
10941094
},
1095+
"sample_files/base-enclosure-beds-0.xml": {
1096+
"parent_hpxml": "sample_files/base.xml",
1097+
"geometry_unit_num_bedrooms": "0",
1098+
"geometry_unit_num_bathrooms": "Default"
1099+
},
10951100
"sample_files/base-enclosure-beds-1.xml": {
10961101
"parent_hpxml": "sample_files/base.xml",
10971102
"geometry_unit_num_bedrooms": "1",

0 commit comments

Comments
 (0)