Skip to content

Commit

Permalink
Merge pull request #1872 from NREL/fix_dl_detailed_results
Browse files Browse the repository at this point in the history
Bugfix for results_design_load_details.csv
  • Loading branch information
shorowit authored Oct 30, 2024
2 parents 76951e1 + 4d4fc47 commit 1d56ca3
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 28 deletions.
27 changes: 16 additions & 11 deletions HPXMLtoOpenStudio/measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def run(model, runner, user_arguments)
# Do these once upfront for the entire HPXML object
epw_path, weather = process_weather(runner, hpxml, args)
process_whole_sfa_mf_inputs(hpxml)
hpxml_sch_map, hpxml_all_zone_loads, hpxml_all_space_loads = process_defaults_schedules_emissions_files(runner, weather, hpxml, args)
hpxml_sch_map, design_loads_results_out = process_defaults_schedules_emissions_files(runner, weather, hpxml, args)

# Write updated HPXML object (w/ defaults) to file for inspection
XMLHelper.write_file(hpxml.to_doc, args[:hpxml_defaults_path])
Expand Down Expand Up @@ -157,16 +157,13 @@ def run(model, runner, user_arguments)

# Write annual results output file
# This is helpful if the user wants to get these results right away (e.g.,
# they might be using the run_simulation.rb --skip-simulation argument.
results_out = []
Outputs.append_sizing_results(hpxml.buildings, results_out)
Outputs.write_results_out_to_file(results_out, args[:output_format], args[:annual_output_file_path])
# they might be using the run_simulation.rb --skip-simulation argument).
annual_results_out = []
Outputs.append_sizing_results(hpxml.buildings, annual_results_out)
Outputs.write_results_out_to_file(annual_results_out, args[:output_format], args[:annual_output_file_path])

# Write design load details output file
hpxml.buildings.each do |hpxml_bldg|
HVACSizing.write_detailed_output(args[:output_format], args[:design_load_details_output_file_path],
hpxml_bldg, hpxml_all_zone_loads[hpxml_bldg], hpxml_all_space_loads[hpxml_bldg])
end
HVACSizing.write_detailed_output(design_loads_results_out, args[:output_format], args[:design_load_details_output_file_path])
rescue Exception => e
runner.registerError("#{e.message}\n#{e.backtrace.join("\n")}")
return false
Expand Down Expand Up @@ -273,7 +270,7 @@ def process_whole_sfa_mf_inputs(hpxml)
# @param weather [WeatherFile] Weather object containing EPW information
# @param hpxml [HPXML] HPXML object
# @param args [Hash] Map of :argument_name => value
# @return [Array<Hash, Hash, Hash>] Maps of HPXML Building => SchedulesFile object, HPXML Building => (Map of HPXML::Zones => DesignLoadValues object), HPXML Building => (Map of HPXML::Spaces => DesignLoadValues object)
# @return [Array<Hash, Array>] Maps of HPXML Building => SchedulesFile object, Rows of design loads output data
def process_defaults_schedules_emissions_files(runner, weather, hpxml, args)
hpxml_sch_map = {}
hpxml_all_zone_loads = {}
Expand All @@ -300,7 +297,15 @@ def process_defaults_schedules_emissions_files(runner, weather, hpxml, args)
Schedule.check_emissions_references(hpxml.header, args[:hpxml_path])
Schedule.validate_emissions_files(hpxml.header)

return hpxml_sch_map, hpxml_all_zone_loads, hpxml_all_space_loads
# Compile design load outputs for subsequent writing
# This needs to come before we collapse enclosure surfaces
design_loads_results_out = []
hpxml.buildings.each do |hpxml_bldg|
HVACSizing.append_detailed_output(args[:output_format], hpxml_bldg, hpxml_all_zone_loads[hpxml_bldg],
hpxml_all_space_loads[hpxml_bldg], design_loads_results_out)
end

return hpxml_sch_map, design_loads_results_out
end

# Creates a full OpenStudio model that represents the given HPXML individual dwelling by
Expand Down
10 changes: 5 additions & 5 deletions 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>64c3bdea-b4b3-4254-9b2a-23987ae4e9f3</version_id>
<version_modified>2024-10-25T00:51:54Z</version_modified>
<version_id>af21de2e-e4ba-4fda-9f29-f4ad94d0475c</version_id>
<version_modified>2024-10-30T04:55:55Z</version_modified>
<xml_checksum>D8922A73</xml_checksum>
<class_name>HPXMLtoOpenStudio</class_name>
<display_name>HPXML to OpenStudio Translator</display_name>
Expand Down Expand Up @@ -183,7 +183,7 @@
<filename>measure.rb</filename>
<filetype>rb</filetype>
<usage_type>script</usage_type>
<checksum>E1E63AE7</checksum>
<checksum>D7F18DFB</checksum>
</file>
<file>
<filename>airflow.rb</filename>
Expand Down Expand Up @@ -393,7 +393,7 @@
<filename>hvac_sizing.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>CD77F9C7</checksum>
<checksum>10626CF1</checksum>
</file>
<file>
<filename>internal_gains.rb</filename>
Expand Down Expand Up @@ -693,7 +693,7 @@
<filename>test_hvac_sizing.rb</filename>
<filetype>rb</filetype>
<usage_type>test</usage_type>
<checksum>C88CFFFC</checksum>
<checksum>475611E3</checksum>
</file>
<file>
<filename>test_lighting.rb</filename>
Expand Down
30 changes: 18 additions & 12 deletions HPXMLtoOpenStudio/resources/hvac_sizing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4892,17 +4892,22 @@ def self.assign_to_hpxml_obj(hpxml_object, loads)
end
end

# Writes a output file with additional detailed information needed to fill out, e.g., an ACCA Form J1.
# Appends additional detailed information needed to fill out, e.g., an ACCA Form J1 to the provided array
# for eventual writing to an output file.
#
# @param output_format [String] Detailed output file format ('csv', 'json', or 'msgpack')
# @param output_file_path [String] Detailed output file path
# @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit
# @param all_zone_loads [Hash] Map of HPXML::Zones => DesignLoadValues object
# @param all_space_loads [Hash] Map of HPXML::Spaces => DesignLoadValues object
# @param results_out [Array] Rows of output data
# @return [nil]
def self.write_detailed_output(output_format, output_file_path, hpxml_bldg, all_zone_loads, all_space_loads)
def self.append_detailed_output(output_format, hpxml_bldg, all_zone_loads, all_space_loads, results_out)
line_break = nil
results_out = []

if (output_format == 'csv') && (not results_out.empty?)
# Separate from existing data with line break
results_out << [line_break]
end

orientation_map = { HPXML::OrientationEast => 'E',
HPXML::OrientationNorth => 'N',
Expand Down Expand Up @@ -5048,12 +5053,17 @@ def self.get_surfaces_with_property(obj, additional_property_type)
all_space_loads.values.each_with_index do |space_loads, i|
results_out << [space_col_names[i]] + space_loads.HourlyFenestrationLoads.map { |l| l.round }
end
end

# Writes an output file for the given rows of output data.
#
# @param results_out [Array] Rows of output data
# @param output_format [String] Detailed output file format ('csv', 'json', or 'msgpack')
# @param output_file_path [String] Detailed output file path
# @return [nil]
def self.write_detailed_output(results_out, output_format, output_file_path)
line_break = nil
if ['csv'].include? output_format
if File.exist? output_file_path
# Separate from existing data
results_out.insert(0, [line_break])
end
CSV.open(output_file_path, 'a') { |csv| results_out.to_a.each { |elem| csv << elem } }
elsif ['json', 'msgpack'].include? output_format
h = {}
Expand Down Expand Up @@ -5081,10 +5091,6 @@ def self.get_surfaces_with_property(obj, additional_property_type)
h[report][name] = items
end

if File.exist? output_file_path
h = JSON.parse(File.read(output_file_path)).merge(h)
end

if output_format == 'json'
require 'json'
File.open(output_file_path, 'w') { |json| json.write(JSON.pretty_generate(h)) }
Expand Down
34 changes: 34 additions & 0 deletions HPXMLtoOpenStudio/tests/test_hvac_sizing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1800,6 +1800,40 @@ def test_gshp_all_g_function_configs_exist
end
end

def test_detailed_design_load_output_file
args_hash = { 'output_format' => 'json',
'hpxml_path' => File.absolute_path(File.join(@test_files_path, 'ACCA_Examples', 'Bob_Ross_Residence.xml')) }
_model, _hpxml, hpxml_bldg = _test_measure(args_hash)
design_load_details_path = File.absolute_path(File.join(File.dirname(__FILE__), 'results_design_load_details.json'))
json = JSON.parse(File.read(design_load_details_path))

tol = 10 # Btuh, allow some tolerance due to rounding

num_reports = 0
json.keys.each do |report|
next unless report.include? 'Loads'

sum_htg = 0
sum_clg_sens = 0
sum_clg_lat = 0
json[report].keys.each do |component|
if component == 'Total'
num_reports += 1
assert_in_delta(sum_htg, json[report][component]['Heating (Btuh)'].to_f, tol)
assert_in_delta(sum_clg_sens, json[report][component]['Cooling Sensible (Btuh)'].to_f, tol)
assert_in_delta(sum_clg_lat, json[report][component]['Cooling Latent (Btuh)'].to_f, tol)
else
sum_htg += json[report][component]['Heating (Btuh)'].to_f
sum_clg_sens += json[report][component]['Cooling Sensible (Btuh)'].to_f
sum_clg_lat += json[report][component]['Cooling Latent (Btuh)'].to_f
end
end
end

num_expected_reports = hpxml_bldg.conditioned_zones.size + hpxml_bldg.conditioned_spaces.size
assert_equal(num_expected_reports, num_reports)
end

def _test_measure(args_hash)
# create an instance of the measure
measure = HPXMLtoOpenStudio.new
Expand Down

0 comments on commit 1d56ca3

Please sign in to comment.