Skip to content

Commit

Permalink
Introduce new building_id argument and test it.
Browse files Browse the repository at this point in the history
  • Loading branch information
joseph-robertson committed Sep 5, 2023
1 parent 0e09786 commit 74ad7be
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 16 deletions.
29 changes: 17 additions & 12 deletions BuildResidentialScheduleFile/measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@ def arguments(model) # rubocop:disable Lint/UnusedMethodArgument
arg.setDefaultValue(false)
args << arg

# arg = OpenStudio::Measure::OSArgument.makeStringArgument('building_id', false)
# arg.setDisplayName('BuildingID')
# arg.setDescription("The ID of the HPXML Building. Only required if there are multiple Building elements in the HPXML file. Use 'ALL' to run all the HPXML Buildings (dwelling units) of a multifamily building in a single model.")
# args << arg
arg = OpenStudio::Measure::OSArgument.makeStringArgument('building_id', false)
arg.setDisplayName('BuildingID')
arg.setDescription("The ID of the HPXML Building. Only required if there are multiple Building elements in the HPXML file. Use 'ALL' to apply schedules to all the HPXML Buildings (dwelling units) of a multifamily building.")
args << arg

return args
end
Expand Down Expand Up @@ -104,22 +104,27 @@ def run(model, runner, user_arguments)

hpxml = HPXML.new(hpxml_path: hpxml_path, building_id: 'ALL')

# FIXME: Relax this constraint (using a new building_id measure argument?)
# if hpxml.buildings.size > 1
# runner.registerError('Cannot currently handle an HPXML with multiple Building elements.')
# return false
# end
# hpxml_bldg = hpxml.buildings[0]

debug = false
if args[:debug].is_initialized
debug = args[:debug].get
end
args[:debug] = debug

if hpxml.buildings.size > 1 && !args[:building_id].is_initialized
fail "Argument 'building_id' required if there are multiple Building elements in the HPXML file."
end

doc = XMLHelper.parse_file(hpxml_path)
hpxml_doc = XMLHelper.get_element(doc, '/HPXML')
hpxml.buildings.each do |hpxml_bldg|
building_id = hpxml_bldg.building_id

if hpxml.buildings.size > 1
if args[:building_id].get != 'ALL'
next if args[:building_id].get != building_id
end
end

# exit if number of occupants is zero
if hpxml_bldg.building_occupancy.number_of_residents == 0
runner.registerInfo('Number of occupants set to zero; skipping generation of stochastic schedules.')
Expand All @@ -135,7 +140,7 @@ def run(model, runner, user_arguments)
return false if not success

XMLHelper.get_elements(hpxml_doc, 'Building').each do |building|
next if XMLHelper.get_attribute_value(XMLHelper.get_element(building, 'BuildingID'), 'id') != hpxml_bldg.building_id
next if XMLHelper.get_attribute_value(XMLHelper.get_element(building, 'BuildingID'), 'id') != building_id

# modify the hpxml with the schedules path
extension = XMLHelper.create_elements_as_needed(building, ['BuildingDetails', 'BuildingSummary', 'extension'])
Expand Down
16 changes: 12 additions & 4 deletions BuildResidentialScheduleFile/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_schedule_file</name>
<uid>f770b2db-1a9f-4e99-99a7-7f3161a594b1</uid>
<version_id>eef5a8ee-8396-415f-b0b2-04d0f3e4e108</version_id>
<version_modified>2023-09-05T20:47:06Z</version_modified>
<version_id>be54fce8-de7a-46b1-a1ba-ec86f5cb12a7</version_id>
<version_modified>2023-09-05T21:27:45Z</version_modified>
<xml_checksum>03F02484</xml_checksum>
<class_name>BuildResidentialScheduleFile</class_name>
<display_name>Schedule File Builder</display_name>
Expand Down Expand Up @@ -71,6 +71,14 @@
</choice>
</choices>
</argument>
<argument>
<name>building_id</name>
<display_name>BuildingID</display_name>
<description>The ID of the HPXML Building. Only required if there are multiple Building elements in the HPXML file. Use 'ALL' to apply schedules to all the HPXML Buildings (dwelling units) of a multifamily building.</description>
<type>String</type>
<required>false</required>
<model_dependent>false</model_dependent>
</argument>
</arguments>
<outputs />
<provenances />
Expand All @@ -94,7 +102,7 @@
<filename>measure.rb</filename>
<filetype>rb</filetype>
<usage_type>script</usage_type>
<checksum>50A182A0</checksum>
<checksum>A1DF0987</checksum>
</file>
<file>
<filename>README.md</filename>
Expand Down Expand Up @@ -892,7 +900,7 @@
<filename>build_residential_schedule_file_test.rb</filename>
<filetype>rb</filetype>
<usage_type>test</usage_type>
<checksum>5E289C51</checksum>
<checksum>7BA678BD</checksum>
</file>
</files>
</measure>
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ def test_multiple_buildings
XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path)

@args_hash['output_csv_path'] = File.absolute_path(File.join(@tmp_output_path, 'occupancy-stochastic.csv'))
@args_hash['building_id'] = 'ALL'
model, hpxml, result = _test_measure()

info_msgs = result.info.map { |x| x.logMessage }
Expand Down Expand Up @@ -320,6 +321,51 @@ def test_multiple_buildings
end
end

def test_multiple_buildings_id
hpxml = _create_hpxml('base-multiple-buildings.xml')
XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path)

@args_hash['output_csv_path'] = File.absolute_path(File.join(@tmp_output_path, 'occupancy-stochastic.csv'))
@args_hash['building_id'] = 'MyBuilding_2'
model, hpxml, result = _test_measure()

info_msgs = result.info.map { |x| x.logMessage }
assert(info_msgs.any? { |info_msg| info_msg.include?('stochastic schedule') })
assert(info_msgs.any? { |info_msg| info_msg.include?('SimYear=2007') })
assert(info_msgs.any? { |info_msg| info_msg.include?('MinutesPerStep=60') })
assert(info_msgs.any? { |info_msg| info_msg.include?('State=CO') })
assert(!info_msgs.any? { |info_msg| info_msg.include?('RandomSeed') })
assert(info_msgs.any? { |info_msg| info_msg.include?('GeometryNumOccupants=3.0') })

hpxml.buildings.each do |hpxml_bldg|
building_id = hpxml_bldg.building_id

if building_id == @args_hash['building_id']
sf = SchedulesFile.new(model: model,
schedules_paths: hpxml_bldg.schedules.schedules_filepaths,
year: 2007,
output_path: @tmp_schedule_file_path)

assert_in_epsilon(6689, sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::ColumnOccupants, schedules: sf.tmp_schedules), 0.1)
assert_in_epsilon(2086, sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::ColumnLightingInterior, schedules: sf.tmp_schedules), 0.1)
assert_in_epsilon(2086, sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::ColumnLightingGarage, schedules: sf.tmp_schedules), 0.1)
assert_in_epsilon(534, sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::ColumnCookingRange, schedules: sf.tmp_schedules), 0.1)
assert_in_epsilon(213, sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::ColumnDishwasher, schedules: sf.tmp_schedules), 0.1)
assert_in_epsilon(134, sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::ColumnClothesWasher, schedules: sf.tmp_schedules), 0.1)
assert_in_epsilon(151, sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::ColumnClothesDryer, schedules: sf.tmp_schedules), 0.1)
assert_in_epsilon(3250, sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::ColumnCeilingFan, schedules: sf.tmp_schedules), 0.1)
assert_in_epsilon(4840, sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::ColumnPlugLoadsOther, schedules: sf.tmp_schedules), 0.1)
assert_in_epsilon(4840, sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::ColumnPlugLoadsTV, schedules: sf.tmp_schedules), 0.1)
assert_in_epsilon(298, sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::ColumnHotWaterDishwasher, schedules: sf.tmp_schedules), 0.1)
assert_in_epsilon(325, sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::ColumnHotWaterClothesWasher, schedules: sf.tmp_schedules), 0.1)
assert_in_epsilon(887, sf.annual_equivalent_full_load_hrs(col_name: SchedulesFile::ColumnHotWaterFixtures, schedules: sf.tmp_schedules), 0.1)
assert(!sf.schedules.keys.include?(SchedulesFile::ColumnSleeping))
else
assert_empty(hpxml_bldg.schedules.schedules_filepaths)
end
end
end

def _test_measure(expect_fail: false)
# create an instance of the measure
measure = BuildResidentialScheduleFile.new
Expand Down

0 comments on commit 74ad7be

Please sign in to comment.