Skip to content

Commit

Permalink
Merge commit '7bc3a39fa60f0cc429fbf271f40b63fcbab74332' into latest-o…
Browse files Browse the repository at this point in the history
…s-hpxml
  • Loading branch information
shorowit committed May 24, 2024
2 parents 1b817a7 + 7bc3a39 commit 155822a
Show file tree
Hide file tree
Showing 30 changed files with 2,671 additions and 1,984 deletions.
3 changes: 3 additions & 0 deletions hpxml-measures/Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ __New Features__
- Adds optional `Slab/extension/GapInsulationRValue` input for cases where a slab has horizontal (under slab) insulation.
- Allows radiant barriers for additional locations (attic gable walls and floor); reduced emissivity due to dust assumed for radiant barriers on attic floor.
- Adds window and skylight `GlassType` options of "low-e, high-solar-gain" and "low-e, low-solar-gain"; updates U-factor/SHGC lookup tables.
- Updates default temperature capacitance multiplier from 1 to 7, an average value found in the literature when calibrating timeseries EnergyPlus indoor temperatures to field data.
- 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`.
Expand Down Expand Up @@ -74,6 +75,7 @@ __New Features__
- Advanced research features:
- **Breaking change**: Replaces `SimulationControl/TemperatureCapacitanceMultiplier` with `SimulationControl/AdvancedResearchFeatures/TemperatureCapacitanceMultiplier`.
- Allows an optional boolean input `SimulationControl/AdvancedResearchFeatures/DefrostModelType` for heat pump advanced defrost model.
- ReportUtilityBills measure: adds new optional arguments for registering (with the OpenStudio runner) annual or monthly utility bills.

__Bugfixes__
- Fixes error if using AllowIncreasedFixedCapacities=true w/ HP detailed performance data.
Expand All @@ -87,6 +89,7 @@ __Bugfixes__
- Apportion shared water heater tank losses for HPWHs and combi systems.
- Fixes buried duct effective R-values.
- Fixes shared boiler default location (which could result in assuming there's a flue in conditioned space impacting infiltration).
- Fixes timeseries hot water energy consumption adjustment lag (associated with hot water distribution).

## OpenStudio-HPXML v1.7.0

Expand Down
14 changes: 7 additions & 7 deletions hpxml-measures/HPXMLtoOpenStudio/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>hpxm_lto_openstudio</name>
<uid>b1543b30-9465-45ff-ba04-1d1f85e763bc</uid>
<version_id>a3010ed3-bfec-4d89-b425-0ec627863167</version_id>
<version_modified>2024-05-18T15:40:55Z</version_modified>
<version_id>74afbf86-1597-475c-9d85-162dda013201</version_id>
<version_modified>2024-05-24T00:01:31Z</version_modified>
<xml_checksum>D8922A73</xml_checksum>
<class_name>HPXMLtoOpenStudio</class_name>
<display_name>HPXML to OpenStudio Translator</display_name>
Expand Down Expand Up @@ -351,7 +351,7 @@
<filename>hpxml_defaults.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>DCEA4986</checksum>
<checksum>ACA8684E</checksum>
</file>
<file>
<filename>hpxml_schema/HPXML.xsd</filename>
Expand Down Expand Up @@ -381,13 +381,13 @@
<filename>hvac.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>0370F183</checksum>
<checksum>FC8B73E3</checksum>
</file>
<file>
<filename>hvac_sizing.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>8526074F</checksum>
<checksum>E9C68804</checksum>
</file>
<file>
<filename>lighting.rb</filename>
Expand Down Expand Up @@ -603,7 +603,7 @@
<filename>waterheater.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>E1F1BEAF</checksum>
<checksum>817CCE94</checksum>
</file>
<file>
<filename>weather.rb</filename>
Expand Down Expand Up @@ -639,7 +639,7 @@
<filename>test_defaults.rb</filename>
<filetype>rb</filetype>
<usage_type>test</usage_type>
<checksum>A84FE910</checksum>
<checksum>FC67054F</checksum>
</file>
<file>
<filename>test_enclosure.rb</filename>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ def self.apply_header(hpxml_header, epw_file, hpxml_bldg)
end

if hpxml_header.temperature_capacitance_multiplier.nil?
hpxml_header.temperature_capacitance_multiplier = 1.0
hpxml_header.temperature_capacitance_multiplier = 7.0
hpxml_header.temperature_capacitance_multiplier_isdefaulted = true
end

Expand Down
2 changes: 1 addition & 1 deletion hpxml-measures/HPXMLtoOpenStudio/resources/hvac.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3625,9 +3625,9 @@ def self.apply_advanced_defrost(model, htg_coil, air_loop_unitary, conditioned_s
supp_sys_power_level = [supp_sys_capacity, q_dot_defrost].min / supp_sys_efficiency # Assume perfect tempering
end
else
supp_sys_fuel = heat_pump.backup_heating_fuel
is_ducted = !heat_pump.distribution_system_idref.nil?
if is_ducted
supp_sys_fuel = heat_pump.backup_heating_fuel
supp_sys_capacity = UnitConversions.convert(heat_pump.backup_heating_capacity, 'Btu/hr', 'W')
supp_sys_efficiency = heat_pump.backup_heating_efficiency_percent
supp_sys_efficiency = heat_pump.backup_heating_efficiency_afue if supp_sys_efficiency.nil?
Expand Down
3 changes: 1 addition & 2 deletions hpxml-measures/HPXMLtoOpenStudio/resources/hvac_sizing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3919,8 +3919,7 @@ def self.write_detailed_output(output_format, output_file_path, hpxml_bldg, all_
HPXML::OrientationSouth => 'S',
HPXML::OrientationSoutheast => 'SE',
HPXML::OrientationSouthwest => 'SW',
HPXML::OrientationWest => 'W',
nil => 'N/S/E/W' }
HPXML::OrientationWest => 'W' }

def self.windows(obj)
return obj.windows.select { |s| s.additional_properties.respond_to?(:formj1_values) }
Expand Down
2 changes: 2 additions & 0 deletions hpxml-measures/HPXMLtoOpenStudio/resources/waterheater.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1406,6 +1406,7 @@ def self.add_ec_adj(model, heater, ec_adj, loc_space, water_heating_system, unit
# Program
ec_adj_program = OpenStudio::Model::EnergyManagementSystemProgram.new(model)
ec_adj_program.setName("#{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
ec_adj_program.addLine("Set dhw_e_cons = #{ec_adj_oncyc_sensor.name} + #{ec_adj_offcyc_sensor.name}")
ec_adj_program.addLine("If #{ec_adj_sensor_boiler.name} > 0")
Expand All @@ -1419,6 +1420,7 @@ def self.add_ec_adj(model, heater, ec_adj, loc_space, water_heating_system, unit
# Since the water heater has been multiplied by the unit_multiplier, and this OtherEquipment object will be adding
# load to a thermal zone with an E+ multiplier, we would double-count the multiplier if we didn't divide by it here.
ec_adj_program.addLine("Set #{ec_adj_actuator.name} = #{adjustment} * dhw_e_cons / #{unit_multiplier}")
ec_adj_program.addLine('EndIf')

# Program Calling Manager
program_calling_manager = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(model)
Expand Down
4 changes: 2 additions & 2 deletions hpxml-measures/HPXMLtoOpenStudio/tests/test_defaults.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def test_header
hpxml.header.sim_calendar_year = 2020
XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path)
default_hpxml, _default_hpxml_bldg = _test_measure()
_test_default_header_values(default_hpxml, 60, 1, 1, 12, 31, 2012, 1.0, nil, nil, nil)
_test_default_header_values(default_hpxml, 60, 1, 1, 12, 31, 2012, 7.0, nil, nil, nil)

# Test defaults - southern hemisphere
hpxml, _hpxml_bldg = _create_hpxml('base-location-capetown-zaf.xml')
Expand All @@ -68,7 +68,7 @@ def test_header
hpxml.header.temperature_capacitance_multiplier = nil
XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path)
default_hpxml, _default_hpxml_bldg = _test_measure()
_test_default_header_values(default_hpxml, 60, 1, 1, 12, 31, 2007, 1.0, nil, nil, nil)
_test_default_header_values(default_hpxml, 60, 1, 1, 12, 31, 2007, 7.0, nil, nil, nil)
end

def test_emissions_factors
Expand Down
2 changes: 1 addition & 1 deletion hpxml-measures/ReportSimulationOutput/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ Determines whether timeseries timestamps use the start-of-period or end-of-perio

**Generate Timeseries Output: Number of Decimal Places**

Allows overriding the default number of decimal places for timeseries output. Does not apply if output format is msgpack, where no rounding is performed because there is no file size penalty to storing full precision.
Allows overriding the default number of decimal places for timeseries output.

- **Name:** ``timeseries_num_decimal_places``
- **Type:** ``Integer``
Expand Down
50 changes: 30 additions & 20 deletions hpxml-measures/ReportSimulationOutput/measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ def arguments(model) # rubocop:disable Lint/UnusedMethodArgument

arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('timeseries_num_decimal_places', false)
arg.setDisplayName('Generate Timeseries Output: Number of Decimal Places')
arg.setDescription('Allows overriding the default number of decimal places for timeseries output. Does not apply if output format is msgpack, where no rounding is performed because there is no file size penalty to storing full precision.')
arg.setDescription('Allows overriding the default number of decimal places for timeseries output.')
args << arg

arg = OpenStudio::Measure::OSArgument::makeBoolArgument('add_timeseries_dst_column', false)
Expand Down Expand Up @@ -1599,11 +1599,11 @@ def report_timeseries_output_results(runner, outputs, timeseries_output_path, ar
fail "Unexpected timeseries_frequency: #{args[:timeseries_frequency]}."
end

if args[:output_format] == 'msgpack'
if not args[:timeseries_num_decimal_places].nil?
n_digits = args[:timeseries_num_decimal_places]
elsif args[:output_format] == 'msgpack'
# No need to round; no file size penalty to storing full precision
n_digits = 100
elsif not args[:timeseries_num_decimal_places].nil?
n_digits = args[:timeseries_num_decimal_places]
else
# Set rounding precision for timeseries (e.g., hourly) outputs.
# Note: Make sure to round outputs with sufficient resolution for the worst case -- i.e., 1 minute date instead of hourly data.
Expand Down Expand Up @@ -1921,14 +1921,17 @@ def get_report_meter_data_timeseries(meter_names, unit_conv, unit_adder, timeser
cols = timeseries_data['Cols']
rows = timeseries_data['Rows']
indexes = cols.each_index.select { |i| meter_names.include? cols[i]['Variable'] }
vals = []
rows.each_with_index do |row, _idx|
vals = [0.0] * rows.size
rows.each_with_index do |row, row_idx|
row = row[row.keys[0]]
val = 0.0
indexes.each do |i|
val += row[i] * unit_conv + unit_adder
indexes.each_with_index do |i, idx|
if meter_names[idx].include?(Constants.ObjectNameWaterHeaterAdjustment) && apply_ems_shift(timeseries_frequency)
# Shift energy use adjustment to allow with hot water energy use
vals[row_idx - 1] += row[i] * unit_conv + unit_adder
else
vals[row_idx] += row[i] * unit_conv + unit_adder
end
end
vals << val
end
return vals
end
Expand Down Expand Up @@ -1960,29 +1963,36 @@ def get_report_variable_data_timeseries(key_values, variables, unit_conv, unit_a
cols = msgpack_data['Cols']
rows = msgpack_data['Rows']
indexes = cols.each_index.select { |i| keys_vars.include? cols[i]['Variable'] }
vals = []
rows.each_with_index do |row, _idx|
vals = [0.0] * rows.size
rows.each_with_index do |row, row_idx|
row = row[row.keys[0]]
val = 0.0
indexes.each do |i|
val += (row[i] * unit_conv + unit_adder) * neg
vals[row_idx] += (row[i] * unit_conv + unit_adder) * neg
end
vals << val
end

return vals unless ems_shift

# Remove this code if we ever figure out a better way to handle when EMS output should shift
if (key_values.size == 1) && (key_values[0] == 'EMS') && (@timestamps.size > 0)
if (timeseries_frequency == 'timestep' || (timeseries_frequency == 'hourly' && @model.getTimestep.numberOfTimestepsPerHour == 1))
# Shift all values by 1 timestep due to EMS reporting lag
return vals[1..-1] + [vals[0]]
end
if (key_values.size == 1) && (key_values[0] == 'EMS') && (@timestamps.size > 0) && apply_ems_shift(timeseries_frequency)
# Shift all values by 1 timestep due to EMS reporting lag
return vals[1..-1] + [vals[0]]
end

return vals
end

def apply_ems_shift(timeseries_frequency)
# Only shift if we reporting timestep values (i.e., not daily, monthly, or hourly w/ a sub-hourly timestep)
if (timeseries_frequency == 'timestep')
return true
elsif (timeseries_frequency == 'hourly') && (@model.getTimestep.numberOfTimestepsPerHour == 1)
return true
end

return false
end

def get_report_variable_data_timeseries_key_values_and_units(var)
keys = []
units = ''
Expand Down
12 changes: 6 additions & 6 deletions hpxml-measures/ReportSimulationOutput/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>report_simulation_output</name>
<uid>df9d170c-c21a-4130-866d-0d46b06073fd</uid>
<version_id>ed19a212-e363-4767-a721-201bc1f56936</version_id>
<version_modified>2024-05-17T20:22:37Z</version_modified>
<version_id>ec111528-5b18-43ad-ae95-0a41f5aaec05</version_id>
<version_modified>2024-05-24T00:08:38Z</version_modified>
<xml_checksum>9BF1E6AC</xml_checksum>
<class_name>ReportSimulationOutput</class_name>
<display_name>HPXML Simulation Output Report</display_name>
Expand Down Expand Up @@ -661,7 +661,7 @@
<argument>
<name>timeseries_num_decimal_places</name>
<display_name>Generate Timeseries Output: Number of Decimal Places</display_name>
<description>Allows overriding the default number of decimal places for timeseries output. Does not apply if output format is msgpack, where no rounding is performed because there is no file size penalty to storing full precision.</description>
<description>Allows overriding the default number of decimal places for timeseries output.</description>
<type>Integer</type>
<required>false</required>
<model_dependent>false</model_dependent>
Expand Down Expand Up @@ -1912,7 +1912,7 @@
<filename>README.md</filename>
<filetype>md</filetype>
<usage_type>readme</usage_type>
<checksum>86FD2C61</checksum>
<checksum>CDB2D617</checksum>
</file>
<file>
<filename>README.md.erb</filename>
Expand All @@ -1929,13 +1929,13 @@
<filename>measure.rb</filename>
<filetype>rb</filetype>
<usage_type>script</usage_type>
<checksum>04252AFC</checksum>
<checksum>BA579923</checksum>
</file>
<file>
<filename>test_report_sim_output.rb</filename>
<filetype>rb</filetype>
<usage_type>test</usage_type>
<checksum>75F6B186</checksum>
<checksum>29FACAA4</checksum>
</file>
</files>
</measure>
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,8 @@ def test_timeseries_hourly_enduses_vacancy
_check_for_zero_timeseries_values(timeseries_csv, ["End Use: #{FT::Elec}: #{EUT::PlugLoads}"], 0, 31 * 24 - 1) # Jan
_check_for_zero_timeseries_values(timeseries_csv, ["End Use: #{FT::Elec}: #{EUT::PlugLoads}"], (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30) * 24 + 1, -1) # Dec
_check_for_nonzero_timeseries_values(timeseries_csv, ["End Use: #{FT::Elec}: #{EUT::Refrigerator}"])
positive_cols = actual_timeseries_cols.select { |col| col.start_with?('End Use:') }
_check_for_positive_timeseries_values(timeseries_csv, positive_cols)
end

def test_timeseries_hourly_system_uses
Expand Down Expand Up @@ -1051,6 +1053,10 @@ def test_timeseries_hourly_ALL
assert_equal(1, _check_for_constant_timeseries_step(timeseries_cols[0]))
_check_for_nonzero_avg_timeseries_value(timeseries_csv, emissions_timeseries_cols[0..2])
_check_for_nonzero_timeseries_values(timeseries_csv, ["End Use: #{FT::Elec}: #{EUT::Refrigerator}"])
negative_cols = ["End Use: #{FT::Elec}: #{EUT::PV}"]
positive_cols = actual_timeseries_cols.select { |col| col.start_with?('End Use:') } - negative_cols - ["End Use: #{FT::Elec}: #{EUT::Battery}"]
_check_for_negative_timeseries_values(timeseries_csv, negative_cols)
_check_for_positive_timeseries_values(timeseries_csv, positive_cols)
end

def test_timeseries_daily_ALL
Expand Down Expand Up @@ -1438,12 +1444,26 @@ def _check_for_zero_timeseries_values(timeseries_csv, timeseries_cols, start_ix,
end

def _check_for_nonzero_timeseries_values(timeseries_csv, timeseries_cols)
# check that every day has non zero values for baseload equipment (e.g., refrigerator)
values = _get_timeseries_values(timeseries_csv, timeseries_cols)

timeseries_cols.each do |col|
has_no_zero_timeseries_value = !values[col].include?(0.0)
assert(has_no_zero_timeseries_value)
refute(values[col].include?(0.0))
end
end

def _check_for_positive_timeseries_values(timeseries_csv, timeseries_cols)
values = _get_timeseries_values(timeseries_csv, timeseries_cols)

timeseries_cols.each do |col|
assert_operator(values[col].min, :>=, 0)
end
end

def _check_for_negative_timeseries_values(timeseries_csv, timeseries_cols)
values = _get_timeseries_values(timeseries_csv, timeseries_cols)

timeseries_cols.each do |col|
assert_operator(values[col].max, :<=, 0)
end
end

Expand Down
26 changes: 24 additions & 2 deletions hpxml-measures/ReportUtilityBills/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ The file format of the annual (and timeseries, if requested) outputs.

**Generate Annual Utility Bills**

Generates annual utility bills.
Generates output file containing annual utility bills.

- **Name:** ``include_annual_bills``
- **Type:** ``Boolean``
Expand All @@ -37,7 +37,7 @@ Generates annual utility bills.

**Generate Monthly Utility Bills**

Generates monthly utility bills.
Generates output file containing monthly utility bills.

- **Name:** ``include_monthly_bills``
- **Type:** ``Boolean``
Expand Down Expand Up @@ -81,6 +81,28 @@ If not provided, defaults to 'results_bills_monthly.csv' (or 'results_bills_mont

<br/>

**Register Annual Utility Bills**

Registers annual utility bills with the OpenStudio runner for downstream processing.

- **Name:** ``register_annual_bills``
- **Type:** ``Boolean``

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

<br/>

**Register Monthly Utility Bills**

Registers monthly utility bills with the OpenStudio runner for downstream processing.

- **Name:** ``register_monthly_bills``
- **Type:** ``Boolean``

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

<br/>




Expand Down
Loading

0 comments on commit 155822a

Please sign in to comment.