Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ANSI 301-2022: shared water heaters, recirc pumps #722

Merged
merged 12 commits into from
Apr 4, 2024
Merged
2 changes: 2 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

__New Features__
- Implements ANSI/RESNET/ICC Standard 301-2022 and Addendum C.
- **Breaking change**: For shared water heaters, `NumberofUnitsServed` is replaced by `extension/NumberofBedroomsServed`.
- **Breaking change**: For shared hot water recirculation systems, `NumberofUnitsServed` is replaced by `NumberofBedroomsServed`.
- `ERICalculation/Version` and `CO2IndexCalculation/Version` can now be "2022C" or "2022".
- Allows modeling electric battery storage, including shared batteries ("2022C" or newer).
- The `ElectricAuxiliaryEnergy` input for boilers is no longer used.
Expand Down
86 changes: 42 additions & 44 deletions docs/source/workflow_inputs.rst

Large diffs are not rendered by default.

10 changes: 7 additions & 3 deletions hpxml-measures/.github/workflows/add_to_project.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
name: Add issue to project
name: Add pull request or issue to project
on:
pull_request:
types:
- opened
- reopened
issues:
types:
- opened
Expand All @@ -8,10 +12,10 @@ on:

jobs:
add-to-project:
name: Add issue to project
name: Add pull request or issue to project
runs-on: ubuntu-latest
steps:
- uses: actions/add-to-project@v0.3.0
- uses: actions/add-to-project@v1.0.0
with:
project-url: https://github.com/orgs/NREL/projects/78
github-token: ${{ secrets.GHB_TOKEN }}
5 changes: 5 additions & 0 deletions hpxml-measures/.github/workflows/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ jobs:
cd docs
make html SPHINXOPTS="-W --keep-going -n"

- name: Check documentation
run: |
echo "Checking for misaligned documentation footnotes..."
for RST_FILE in docs/source/*.rst; do NUM_REFS=$(grep -F -o "[#]_" $RST_FILE | wc -l); NUM_FOOTNOTES=$(grep -F -o ".. [#]" $RST_FILE | wc -l); if [ $NUM_REFS != $NUM_FOOTNOTES ]; then echo "ERROR: Number of footnote references doesn't match number of footnotes in $RST_FILE." && exit 1; fi done

- name: Save Docs
uses: actions/upload-artifact@v4
with:
Expand Down
12 changes: 6 additions & 6 deletions hpxml-measures/BuildResidentialHPXML/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3585,16 +3585,16 @@ The setpoint temperature of water heater. If not provided, the OS-HPXML default

<br/>

**Water Heater: Number of Units Served**
**Water Heater: Number of Bedrooms Served**

Number of dwelling units served (directly or indirectly) by the water heater. Must be 1 if single-family detached. Used to apportion water heater tank losses to the unit.
Number of bedrooms served (directly or indirectly) by the water heater. Only needed if single-family attached or apartment unit and it is a shared water heater serving multiple dwelling units. Used to apportion water heater tank losses to the unit.

- **Name:** ``water_heater_num_units_served``
- **Name:** ``water_heater_num_bedrooms_served``
- **Type:** ``Integer``

- **Units:** ``#``

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

<br/>

Expand Down Expand Up @@ -4050,7 +4050,7 @@ System losses fraction of the PV system. If there are two PV systems, this will

**PV System: Number of Bedrooms Served**

Number of bedrooms served by PV system. Required if single-family attached or apartment unit. Used to apportion PV generation to the unit of a SFA/MF building. If there are two PV systems, this will apply to both.
Number of bedrooms served by PV system. Only needed if single-family attached or apartment unit and it is a shared PV system serving multiple dwelling units. Used to apportion PV generation to the unit of a SFA/MF building. If there are two PV systems, this will apply to both.

- **Name:** ``pv_system_num_bedrooms_served``
- **Type:** ``Integer``
Expand Down Expand Up @@ -4226,7 +4226,7 @@ The round trip efficiency of the lithium ion battery. If not provided, the OS-HP

**Battery: Number of Bedrooms Served**

Number of bedrooms served by the lithium ion battery. Required if single-family attached or apartment unit. Used to apportion battery charging/discharging to the unit of a SFA/MF building.
Number of bedrooms served by the lithium ion battery. Only needed if single-family attached or apartment unit and it is a shared battery serving multiple dwelling units. Used to apportion battery charging/discharging to the unit of a SFA/MF building.

- **Name:** ``battery_num_bedrooms_served``
- **Type:** ``Integer``
Expand Down
26 changes: 14 additions & 12 deletions hpxml-measures/BuildResidentialHPXML/measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2138,11 +2138,10 @@ def arguments(model) # rubocop:disable Lint/UnusedMethodArgument
arg.setUnits('deg-F')
args << arg

arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('water_heater_num_units_served', true)
arg.setDisplayName('Water Heater: Number of Units Served')
arg.setDescription("Number of dwelling units served (directly or indirectly) by the water heater. Must be 1 if #{HPXML::ResidentialTypeSFD}. Used to apportion water heater tank losses to the unit.")
arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('water_heater_num_bedrooms_served', false)
arg.setDisplayName('Water Heater: Number of Bedrooms Served')
arg.setDescription("Number of bedrooms served (directly or indirectly) by the water heater. Only needed if #{HPXML::ResidentialTypeSFA} or #{HPXML::ResidentialTypeApartment} and it is a shared water heater serving multiple dwelling units. Used to apportion water heater tank losses to the unit.")
arg.setUnits('#')
arg.setDefaultValue(1)
args << arg

arg = OpenStudio::Measure::OSArgument::makeBoolArgument('water_heater_uses_desuperheater', false)
Expand Down Expand Up @@ -2419,7 +2418,7 @@ def arguments(model) # rubocop:disable Lint/UnusedMethodArgument

arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('pv_system_num_bedrooms_served', false)
arg.setDisplayName('PV System: Number of Bedrooms Served')
arg.setDescription("Number of bedrooms served by PV system. Required if #{HPXML::ResidentialTypeSFA} or #{HPXML::ResidentialTypeApartment}. Used to apportion PV generation to the unit of a SFA/MF building. If there are two PV systems, this will apply to both.")
arg.setDescription("Number of bedrooms served by PV system. Only needed if #{HPXML::ResidentialTypeSFA} or #{HPXML::ResidentialTypeApartment} and it is a shared PV system serving multiple dwelling units. Used to apportion PV generation to the unit of a SFA/MF building. If there are two PV systems, this will apply to both.")
arg.setUnits('#')
args << arg

Expand Down Expand Up @@ -2516,7 +2515,7 @@ def arguments(model) # rubocop:disable Lint/UnusedMethodArgument

arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('battery_num_bedrooms_served', false)
arg.setDisplayName('Battery: Number of Bedrooms Served')
arg.setDescription("Number of bedrooms served by the lithium ion battery. Required if #{HPXML::ResidentialTypeSFA} or #{HPXML::ResidentialTypeApartment}. Used to apportion battery charging/discharging to the unit of a SFA/MF building.")
arg.setDescription("Number of bedrooms served by the lithium ion battery. Only needed if #{HPXML::ResidentialTypeSFA} or #{HPXML::ResidentialTypeApartment} and it is a shared battery serving multiple dwelling units. Used to apportion battery charging/discharging to the unit of a SFA/MF building.")
arg.setUnits('#')
args << arg

Expand Down Expand Up @@ -6317,10 +6316,13 @@ def self.set_water_heating_systems(hpxml_bldg, args)
end
end

if args[:water_heater_num_units_served] > 1
is_shared_system = true
number_of_units_served = args[:water_heater_num_units_served]
if [HPXML::ResidentialTypeSFA, HPXML::ResidentialTypeApartment].include? args[:geometry_unit_type]
if args[:water_heater_num_bedrooms_served].to_f > args[:geometry_unit_num_bedrooms]
is_shared_system = true
number_of_bedrooms_served = args[:water_heater_num_bedrooms_served].get
end
end

if args[:water_heater_uses_desuperheater].is_initialized
uses_desuperheater = args[:water_heater_uses_desuperheater].get
if uses_desuperheater
Expand Down Expand Up @@ -6373,7 +6375,7 @@ def self.set_water_heating_systems(hpxml_bldg, args)
temperature: temperature,
heating_capacity: heating_capacity,
is_shared_system: is_shared_system,
number_of_units_served: number_of_units_served,
number_of_bedrooms_served: number_of_bedrooms_served,
tank_model_type: tank_model_type,
operating_mode: operating_mode)
end
Expand Down Expand Up @@ -6507,7 +6509,7 @@ def self.set_pv_systems(hpxml_bldg, args, epw_file)
end

if [HPXML::ResidentialTypeSFA, HPXML::ResidentialTypeApartment].include? args[:geometry_unit_type]
if args[:pv_system_num_bedrooms_served].get > args[:geometry_unit_num_bedrooms]
if args[:pv_system_num_bedrooms_served].to_f > args[:geometry_unit_num_bedrooms]
is_shared_system = true
number_of_bedrooms_served = args[:pv_system_num_bedrooms_served].get
end
Expand Down Expand Up @@ -6566,7 +6568,7 @@ def self.set_battery(hpxml_bldg, args)
end

if [HPXML::ResidentialTypeSFA, HPXML::ResidentialTypeApartment].include? args[:geometry_unit_type]
if args[:battery_num_bedrooms_served].get > args[:geometry_unit_num_bedrooms]
if args[:battery_num_bedrooms_served].to_f > args[:geometry_unit_num_bedrooms]
is_shared_system = true
number_of_bedrooms_served = args[:battery_num_bedrooms_served].get
end
Expand Down
23 changes: 11 additions & 12 deletions hpxml-measures/BuildResidentialHPXML/measure.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<schema_version>3.1</schema_version>
<name>build_residential_hpxml</name>
<uid>a13a8983-2b01-4930-8af2-42030b6e4233</uid>
<version_id>0c0e8689-5c4d-4863-b989-2e3fcb36d265</version_id>
<version_modified>2024-03-19T14:53:03Z</version_modified>
<version_id>2994d7d6-77b2-4962-b5d1-1667a126a05f</version_id>
<version_modified>2024-03-26T16:29:07Z</version_modified>
<xml_checksum>2C38F48B</xml_checksum>
<class_name>BuildResidentialHPXML</class_name>
<display_name>HPXML Builder</display_name>
Expand Down Expand Up @@ -4456,14 +4456,13 @@
<model_dependent>false</model_dependent>
</argument>
<argument>
<name>water_heater_num_units_served</name>
<display_name>Water Heater: Number of Units Served</display_name>
<description>Number of dwelling units served (directly or indirectly) by the water heater. Must be 1 if single-family detached. Used to apportion water heater tank losses to the unit.</description>
<name>water_heater_num_bedrooms_served</name>
<display_name>Water Heater: Number of Bedrooms Served</display_name>
<description>Number of bedrooms served (directly or indirectly) by the water heater. Only needed if single-family attached or apartment unit and it is a shared water heater serving multiple dwelling units. Used to apportion water heater tank losses to the unit.</description>
<type>Integer</type>
<units>#</units>
<required>true</required>
<required>false</required>
<model_dependent>false</model_dependent>
<default_value>1</default_value>
</argument>
<argument>
<name>water_heater_uses_desuperheater</name>
Expand Down Expand Up @@ -4994,7 +4993,7 @@
<argument>
<name>pv_system_num_bedrooms_served</name>
<display_name>PV System: Number of Bedrooms Served</display_name>
<description>Number of bedrooms served by PV system. Required if single-family attached or apartment unit. Used to apportion PV generation to the unit of a SFA/MF building. If there are two PV systems, this will apply to both.</description>
<description>Number of bedrooms served by PV system. Only needed if single-family attached or apartment unit and it is a shared PV system serving multiple dwelling units. Used to apportion PV generation to the unit of a SFA/MF building. If there are two PV systems, this will apply to both.</description>
<type>Integer</type>
<units>#</units>
<required>false</required>
Expand Down Expand Up @@ -5231,7 +5230,7 @@
<argument>
<name>battery_num_bedrooms_served</name>
<display_name>Battery: Number of Bedrooms Served</display_name>
<description>Number of bedrooms served by the lithium ion battery. Required if single-family attached or apartment unit. Used to apportion battery charging/discharging to the unit of a SFA/MF building.</description>
<description>Number of bedrooms served by the lithium ion battery. Only needed if single-family attached or apartment unit and it is a shared battery serving multiple dwelling units. Used to apportion battery charging/discharging to the unit of a SFA/MF building.</description>
<type>Integer</type>
<units>#</units>
<required>false</required>
Expand Down Expand Up @@ -7245,7 +7244,7 @@
<filename>README.md</filename>
<filetype>md</filetype>
<usage_type>readme</usage_type>
<checksum>0C141E23</checksum>
<checksum>6D56CD24</checksum>
</file>
<file>
<filename>README.md.erb</filename>
Expand All @@ -7262,7 +7261,7 @@
<filename>measure.rb</filename>
<filetype>rb</filetype>
<usage_type>script</usage_type>
<checksum>AF6A8CB1</checksum>
<checksum>6E4C83C9</checksum>
</file>
<file>
<filename>geometry.rb</filename>
Expand All @@ -7274,7 +7273,7 @@
<filename>test_build_residential_hpxml.rb</filename>
<filetype>rb</filetype>
<usage_type>test</usage_type>
<checksum>15E37B7A</checksum>
<checksum>571E6145</checksum>
</file>
</files>
</measure>
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ def _set_measure_argument_values(hpxml_file, args)
args['water_heater_standby_loss'] = 0
args['water_heater_jacket_rvalue'] = 0
args['water_heater_setpoint_temperature'] = 125
args['water_heater_num_units_served'] = 1
args['water_heater_num_bedrooms_served'] = 3
args['hot_water_distribution_system_type'] = HPXML::DHWDistTypeStandard
args['hot_water_distribution_standard_piping_length'] = 50
args['hot_water_distribution_recirc_control_type'] = HPXML::DHWRecircControlTypeNone
Expand Down
6 changes: 6 additions & 0 deletions hpxml-measures/Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
__New Features__
- Updates to HPXML v4.0-rc3.
- Updates per ANSI/RESNET/ICC 301-2022 w/ Addendum C:
- **Breaking change**: Replaces `WaterHeatingSystem/NumberofUnitsServed` with `WaterHeatingSystem/extension/NumberofBedroomsServed` for apportioning shared water heater tank losses.
- **Breaking change**: Replaces `HotWaterDistribution/extension/SharedRecirculation/NumberofUnitsServed` with `HotWaterDistribution/extension/SharedRecirculation/NumberofBedroomsServed` for apportioning shared recirculation pump energy.
- Allows shared batteries (batteries serving multiple dwelling units).
- Updated default CFIS fan power to 0.58 W/cfm.
- Removed natural ventilation availability RH constraint; HR constraint remains.
Expand Down Expand Up @@ -34,6 +36,7 @@ __New Features__
- Adds window and skylight `GlassType` options of "low-e, high-solar-gain" and "low-e, low-solar-gain"; updates U-factor/SHGC lookup tables.
- BuildResidentialHPXML measure:
- **Breaking change**: Replaces `roof_radiant_barrier`/`roof_radiant_barrier_grade` arguments with `radiant_barrier_attic_location`/`radiant_barrier_grade`.
- Allows specifying number of bedrooms served by the water heater which is used for apportioning tank losses; **Breaking change**: Replaces `water_heater_num_units_served` with `water_heater_num_bedrooms_served`.
- Allows defining multiple unavailable periods; **Breaking change**: arguments renamed to `schedules_vacancy_periods`, `schedules_power_outage_periods`, and `schedules_power_outage_periods_window_natvent_availability`.
- Adds detailed performance data inputs for variable-speed air source HVAC systems.
- Adds heat pump backup sizing methodology input.
Expand Down Expand Up @@ -61,6 +64,9 @@ __Bugfixes__
- Fixes detailed schedule error-checking where schedules with MAX < 1 were incorrectly allowed.
- Fixes error if using MF space types (e.g., "other heated space") and the building has no HVAC equipment.
- Fixes `ManualJInputs/HumiditySetpoint` not being used in the design load calculation.
- Fixes possible EnergyPlus error when a `Slab` representing a crawlspace dirt floor has perimeter or under slab insulation.
- Prevents errors due to incorrect `Floor/FloorOrCeiling` input; issues a warning when detected.
- Apportion shared water heater tank losses for HPWHs and combi systems.

## OpenStudio-HPXML v1.7.0

Expand Down
8 changes: 4 additions & 4 deletions hpxml-measures/HPXMLtoOpenStudio/measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1542,14 +1542,14 @@ def add_hot_water_and_appliances(runner, model, weather, spaces)

sys_id = water_heating_system.id
if water_heating_system.water_heater_type == HPXML::WaterHeaterTypeStorage
plantloop_map[sys_id] = Waterheater.apply_tank(model, runner, loc_space, loc_schedule, water_heating_system, ec_adj, solar_thermal_system, @eri_version, @schedules_file, unavailable_periods, unit_multiplier)
plantloop_map[sys_id] = Waterheater.apply_tank(model, runner, loc_space, loc_schedule, water_heating_system, ec_adj, solar_thermal_system, @eri_version, @schedules_file, unavailable_periods, unit_multiplier, @nbeds)
elsif water_heating_system.water_heater_type == HPXML::WaterHeaterTypeTankless
plantloop_map[sys_id] = Waterheater.apply_tankless(model, runner, loc_space, loc_schedule, water_heating_system, ec_adj, solar_thermal_system, @eri_version, @schedules_file, unavailable_periods, unit_multiplier)
plantloop_map[sys_id] = Waterheater.apply_tankless(model, runner, loc_space, loc_schedule, water_heating_system, ec_adj, solar_thermal_system, @eri_version, @schedules_file, unavailable_periods, unit_multiplier, @nbeds)
elsif water_heating_system.water_heater_type == HPXML::WaterHeaterTypeHeatPump
conditioned_zone = spaces[HPXML::LocationConditionedSpace].thermalZone.get
plantloop_map[sys_id] = Waterheater.apply_heatpump(model, runner, loc_space, loc_schedule, @hpxml_bldg.elevation, water_heating_system, ec_adj, solar_thermal_system, conditioned_zone, @eri_version, @schedules_file, unavailable_periods, unit_multiplier)
plantloop_map[sys_id] = Waterheater.apply_heatpump(model, runner, loc_space, loc_schedule, @hpxml_bldg.elevation, water_heating_system, ec_adj, solar_thermal_system, conditioned_zone, @eri_version, @schedules_file, unavailable_periods, unit_multiplier, @nbeds)
elsif [HPXML::WaterHeaterTypeCombiStorage, HPXML::WaterHeaterTypeCombiTankless].include? water_heating_system.water_heater_type
plantloop_map[sys_id] = Waterheater.apply_combi(model, runner, loc_space, loc_schedule, water_heating_system, ec_adj, solar_thermal_system, @eri_version, @schedules_file, unavailable_periods, unit_multiplier)
plantloop_map[sys_id] = Waterheater.apply_combi(model, runner, loc_space, loc_schedule, water_heating_system, ec_adj, solar_thermal_system, @eri_version, @schedules_file, unavailable_periods, unit_multiplier, @nbeds)
else
fail "Unhandled water heater (#{water_heating_system.water_heater_type})."
end
Expand Down
Loading