Skip to content

Commit db86b47

Browse files
authored
Merge pull request #1171 from NREL/bill-scenario-total-fix
Consolidate write vs report methods
2 parents 9d6a994 + 3de62d5 commit db86b47

10 files changed

Lines changed: 279 additions & 309 deletions

File tree

ReportHPXMLOutput/measure.rb

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -135,26 +135,20 @@ def run(runner, user_arguments)
135135
bldg_output.units = BO.get_units(bldg_type)
136136
end
137137

138-
# Report results
139-
bldg_outputs.each do |bldg_type, bldg_output|
140-
bldg_type_str = OpenStudio::toUnderscoreCase("#{bldg_type} #{bldg_output.units}")
141-
bldg_output = bldg_output.output.round(2)
142-
runner.registerValue(bldg_type_str, bldg_output)
143-
runner.registerInfo("Registering #{bldg_output} for #{bldg_type_str}.")
144-
end
145-
146-
# Write results
147-
write_output(runner, bldg_outputs, output_format, output_path)
138+
# Write/report results
139+
report_output_results(runner, bldg_outputs, output_format, output_path)
148140

149141
return true
150142
end
151143

152-
def write_output(runner, bldg_outputs, output_format, output_path)
144+
def report_output_results(runner, bldg_outputs, output_format, output_path)
153145
line_break = nil
154146

155147
segment, _ = bldg_outputs.keys[0].split(':', 2)
156148
segment = segment.strip
149+
157150
results_out = []
151+
158152
bldg_outputs.each do |key, bldg_output|
159153
new_segment, _ = key.split(':', 2)
160154
new_segment = new_segment.strip
@@ -185,6 +179,15 @@ def write_output(runner, bldg_outputs, output_format, output_path)
185179
end
186180
end
187181
runner.registerInfo("Wrote hpxml output to #{output_path}.")
182+
183+
results_out.each do |name, value|
184+
next if name.nil? || value.nil?
185+
186+
name = OpenStudio::toUnderscoreCase(name).chomp('_')
187+
188+
runner.registerValue(name, value)
189+
runner.registerInfo("Registering #{value} for #{name}.")
190+
end
188191
end
189192

190193
class BaseOutput

ReportHPXMLOutput/measure.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
<schema_version>3.0</schema_version>
44
<name>report_hpxml_output</name>
55
<uid>9561a0d7-60ad-48c5-8337-2461df044d80</uid>
6-
<version_id>512f039e-15bf-4b97-ab56-790dd285cc67</version_id>
7-
<version_modified>20220902T212513Z</version_modified>
6+
<version_id>7bb635bd-994a-4f18-a40a-8cd4bdf44a2a</version_id>
7+
<version_modified>20220912T215712Z</version_modified>
88
<xml_checksum>9BF1E6AC</xml_checksum>
99
<class_name>ReportHPXMLOutput</class_name>
1010
<display_name>HPXML Output Report</display_name>
@@ -68,7 +68,7 @@
6868
<filename>hpxml_output_report_test.rb</filename>
6969
<filetype>rb</filetype>
7070
<usage_type>test</usage_type>
71-
<checksum>511FCAD9</checksum>
71+
<checksum>C0E4766D</checksum>
7272
</file>
7373
<file>
7474
<version>
@@ -79,7 +79,7 @@
7979
<filename>measure.rb</filename>
8080
<filetype>rb</filetype>
8181
<usage_type>script</usage_type>
82-
<checksum>9FC923C3</checksum>
82+
<checksum>642666E6</checksum>
8383
</file>
8484
</files>
8585
</measure>

ReportHPXMLOutput/tests/hpxml_output_report_test.rb

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@
1313
class ReportHPXMLOutputTest < MiniTest::Test
1414
def test_hpxml_with_primary_systems
1515
args_hash = { 'hpxml_path' => '../../../workflow/sample_files/base-hvac-multiple.xml' }
16-
hpxml_csv = _test_measure(args_hash)
17-
assert(File.exist?(hpxml_csv))
18-
actual_rows = File.readlines(hpxml_csv).map { |x| x.split(',')[0].strip }.select { |x| !x.empty? }
16+
actual_multipliers = _test_measure(args_hash)
17+
actual_rows = actual_multipliers.keys
1918
assert_includes(actual_rows, 'Systems: Heating Capacity (Btu/h)')
2019
assert_includes(actual_rows, 'Systems: Cooling Capacity (Btu/h)')
2120
assert_includes(actual_rows, 'Primary Systems: Cooling Capacity (Btu/h)')
@@ -34,10 +33,9 @@ def test_hpxml_without_primary_systems
3433
tmp_hpxml_path = File.join(File.dirname(__FILE__), 'tmp.xml')
3534
XMLHelper.write_file(hpxml.to_oga(), tmp_hpxml_path)
3635
args_hash = { 'hpxml_path' => '../../../ReportHPXMLOutput/tests/tmp.xml' }
37-
hpxml_csv = _test_measure(args_hash)
36+
actual_multipliers = _test_measure(args_hash)
37+
actual_rows = actual_multipliers.keys
3838
File.delete(tmp_hpxml_path) if File.exist?(tmp_hpxml_path)
39-
assert(File.exist?(hpxml_csv))
40-
actual_rows = File.readlines(hpxml_csv).map { |x| x.split(',')[0].strip }.select { |x| !x.empty? }
4139
assert_includes(actual_rows, 'Systems: Heating Capacity (Btu/h)')
4240
assert_includes(actual_rows, 'Systems: Cooling Capacity (Btu/h)')
4341
refute_includes(actual_rows, 'Primary Systems: Cooling Capacity (Btu/h)')
@@ -50,8 +48,7 @@ def test_hpxml_without_primary_systems
5048

5149
def test_furnace_and_central_air_conditioner_xml
5250
args_hash = {}
53-
hpxml_csv = _test_measure(args_hash)
54-
assert(File.exist?(hpxml_csv))
51+
actual_multipliers = _test_measure(args_hash)
5552

5653
expected_multipliers = {
5754
'Enclosure: Wall Area Thermal Boundary (ft^2)' => 1200.0,
@@ -104,7 +101,6 @@ def test_furnace_and_central_air_conditioner_xml
104101
'Design Loads Cooling Latent: Internal Gains (Btu/h)' => 0.0
105102
}
106103

107-
actual_multipliers = _get_actual_multipliers(hpxml_csv)
108104
assert_equal(expected_multipliers, actual_multipliers)
109105
end
110106

@@ -113,8 +109,7 @@ def test_air_source_heat_pump_xml
113109
'base-hvac-air-to-air-heat-pump-var-speed-backup-boiler.xml']
114110
hpxml_files.each do |hpxml_file|
115111
args_hash = { 'hpxml_path' => "../../../workflow/sample_files/#{hpxml_file}" }
116-
hpxml_csv = _test_measure(args_hash)
117-
assert(File.exist?(hpxml_csv))
112+
actual_multipliers = _test_measure(args_hash)
118113

119114
if hpxml_file == 'base-hvac-air-to-air-heat-pump-1-speed.xml'
120115
hp_capacity = 36000.0
@@ -175,7 +170,6 @@ def test_air_source_heat_pump_xml
175170
'Design Loads Cooling Latent: Internal Gains (Btu/h)' => 0.0
176171
}
177172

178-
actual_multipliers = _get_actual_multipliers(hpxml_csv)
179173
assert_equal(expected_multipliers, actual_multipliers)
180174
end
181175
end
@@ -192,8 +186,7 @@ def test_foundations
192186
'base-foundation-walkout-basement.xml']
193187
hpxml_files.each do |hpxml_file|
194188
args_hash = { 'hpxml_path' => "../../../workflow/sample_files/#{hpxml_file}" }
195-
hpxml_csv = _test_measure(args_hash)
196-
assert(File.exist?(hpxml_csv))
189+
actual_multipliers = _test_measure(args_hash)
197190

198191
foundation_wall_area_exterior = 1200.0
199192
floor_area_foundation = 1350.0
@@ -232,24 +225,12 @@ def test_foundations
232225
'Enclosure: Slab Exposed Perimeter Thermal Boundary (ft)' => slab_exposed_perimeter_thermal_boundary
233226
}
234227

235-
actual_multipliers = _get_actual_multipliers(hpxml_csv)
236228
expected_multipliers.each do |multiplier_name, expected_multiplier|
237229
assert_equal(expected_multiplier, actual_multipliers[multiplier_name])
238230
end
239231
end
240232
end
241233

242-
def _get_actual_multipliers(hpxml_csv)
243-
actual_multipliers = {}
244-
File.readlines(hpxml_csv).each do |line|
245-
next if line.strip.empty?
246-
247-
key, value = line.split(',').map { |x| x.strip }
248-
actual_multipliers[key] = Float(value)
249-
end
250-
return actual_multipliers
251-
end
252-
253234
def _test_measure(args_hash)
254235
# Run measure via OSW
255236
require 'json'
@@ -285,6 +266,37 @@ def _test_measure(args_hash)
285266
File.delete(osw_path)
286267

287268
hpxml_csv = File.join(File.dirname(template_osw), 'run', 'results_hpxml.csv')
288-
return hpxml_csv
269+
270+
# Check written values exist and are registered
271+
assert(File.exist?(hpxml_csv))
272+
actual_multipliers = _get_actual_multipliers(hpxml_csv)
273+
274+
_check_for_runner_registered_values(File.join(File.dirname(hpxml_csv), 'results.json'), actual_multipliers)
275+
276+
return actual_multipliers
277+
end
278+
279+
def _get_actual_multipliers(hpxml_csv)
280+
actual_multipliers = {}
281+
File.readlines(hpxml_csv).each do |line|
282+
next if line.strip.empty?
283+
284+
key, value = line.split(',').map { |x| x.strip }
285+
actual_multipliers[key] = Float(value)
286+
end
287+
return actual_multipliers
288+
end
289+
290+
def _check_for_runner_registered_values(results_json, actual_multipliers)
291+
require 'json'
292+
runner_multipliers = JSON.parse(File.read(results_json))
293+
runner_multipliers = runner_multipliers['ReportHPXMLOutput']
294+
295+
actual_multipliers.each do |name, value|
296+
name = OpenStudio::toUnderscoreCase(name).chomp('_')
297+
298+
assert_includes(runner_multipliers.keys, name)
299+
assert_equal(value, runner_multipliers[name])
300+
end
289301
end
290302
end

ReportSimulationOutput/measure.rb

Lines changed: 50 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -567,29 +567,28 @@ def run(runner, user_arguments)
567567
end
568568

569569
# Write/report results
570-
write_runperiod_output_results(runner, outputs, output_format, annual_output_path, runperiod_n_digits, generate_eri_outputs)
571-
report_runperiod_output_results(runner, outputs, runperiod_n_digits)
572-
write_timeseries_output_results(runner, outputs, output_format,
573-
timeseries_output_path,
574-
timeseries_frequency,
575-
include_timeseries_total_consumptions,
576-
include_timeseries_fuel_consumptions,
577-
include_timeseries_end_use_consumptions,
578-
include_timeseries_emissions,
579-
include_timeseries_emission_fuels,
580-
include_timeseries_emission_end_uses,
581-
include_timeseries_hot_water_uses,
582-
include_timeseries_total_loads,
583-
include_timeseries_component_loads,
584-
include_timeseries_unmet_hours,
585-
include_timeseries_zone_temperatures,
586-
include_timeseries_airflows,
587-
include_timeseries_weather,
588-
add_dst_column,
589-
add_utc_column,
590-
timestamps_dst,
591-
timestamps_utc,
592-
use_dview_format)
570+
report_runperiod_output_results(runner, outputs, output_format, annual_output_path, runperiod_n_digits, generate_eri_outputs)
571+
report_timeseries_output_results(runner, outputs, output_format,
572+
timeseries_output_path,
573+
timeseries_frequency,
574+
include_timeseries_total_consumptions,
575+
include_timeseries_fuel_consumptions,
576+
include_timeseries_end_use_consumptions,
577+
include_timeseries_emissions,
578+
include_timeseries_emission_fuels,
579+
include_timeseries_emission_end_uses,
580+
include_timeseries_hot_water_uses,
581+
include_timeseries_total_loads,
582+
include_timeseries_component_loads,
583+
include_timeseries_unmet_hours,
584+
include_timeseries_zone_temperatures,
585+
include_timeseries_airflows,
586+
include_timeseries_weather,
587+
add_dst_column,
588+
add_utc_column,
589+
timestamps_dst,
590+
timestamps_utc,
591+
use_dview_format)
593592

594593
return true
595594
end
@@ -1154,7 +1153,7 @@ def check_for_errors(runner, outputs)
11541153
return true
11551154
end
11561155

1157-
def write_runperiod_output_results(runner, outputs, output_format, annual_output_path, n_digits, generate_eri_outputs)
1156+
def report_runperiod_output_results(runner, outputs, output_format, annual_output_path, n_digits, generate_eri_outputs)
11581157
line_break = nil
11591158

11601159
results_out = []
@@ -1244,59 +1243,14 @@ def write_runperiod_output_results(runner, outputs, output_format, annual_output
12441243
end
12451244
end
12461245
runner.registerInfo("Wrote annual output results to #{annual_output_path}.")
1247-
end
12481246

1249-
def report_runperiod_output_results(runner, outputs, n_digits)
1250-
all_outputs = []
1251-
all_outputs << @totals
1252-
all_outputs << @fuels
1253-
all_outputs << @end_uses
1254-
all_outputs << @emissions
1255-
all_outputs << @loads
1256-
all_outputs << @unmet_hours
1257-
all_outputs << @peak_fuels
1258-
all_outputs << @peak_loads
1259-
if @component_loads.values.map { |load| load.annual_output.to_f }.sum != 0 # Skip if component loads not calculated
1260-
all_outputs << @component_loads
1261-
end
1262-
all_outputs << @hot_water_uses
1247+
results_out.each do |name, value|
1248+
next if name.nil? || value.nil?
12631249

1264-
all_outputs.each do |o|
1265-
o.each do |key, obj|
1266-
if obj.is_a?(Emission)
1267-
runner_output_name = get_runner_output_name("#{obj.name}: Total", obj.annual_units)
1268-
else
1269-
runner_output_name = get_runner_output_name(obj.name, obj.annual_units)
1270-
end
1271-
output_name = OpenStudio::toUnderscoreCase(runner_output_name)
1272-
output_val = obj.annual_output.to_f.round(n_digits)
1273-
runner.registerValue(output_name, output_val)
1274-
runner.registerInfo("Registering #{output_val} for #{output_name}.")
1275-
1276-
if obj.is_a?(Emission)
1277-
# Include disaggregated by fuel
1278-
obj.annual_output_by_fuel.each do |fuel, annual_output|
1279-
output_name = OpenStudio::toUnderscoreCase(get_runner_output_name("#{obj.name}: #{fuel}: Total", obj.annual_units))
1280-
output_val = annual_output.to_f.round(n_digits)
1281-
runner.registerValue(output_name, output_val)
1282-
runner.registerInfo("Registering #{output_val} for #{output_name}.")
1283-
end
1284-
# Include disaggregated by end use
1285-
obj.annual_output_by_end_use.each do |key, annual_output|
1286-
fuel_type, end_use_type = key
1287-
output_name = OpenStudio::toUnderscoreCase(get_runner_output_name("#{obj.name}: #{fuel_type}: #{end_use_type}", obj.annual_units))
1288-
output_val = annual_output.to_f.round(n_digits)
1289-
runner.registerValue(output_name, output_val)
1290-
runner.registerInfo("Registering #{output_val} for #{output_name}.")
1291-
end
1292-
elsif key == FT::Elec && obj.is_a?(Fuel)
1293-
# Also add Net Electricity
1294-
output_name = OpenStudio::toUnderscoreCase('Fuel Use: Electricity: Net (MBtu)')
1295-
output_val = outputs[:elec_net_annual].round(n_digits)
1296-
runner.registerValue(output_name, output_val)
1297-
runner.registerInfo("Registering #{output_val} for #{output_name}.")
1298-
end
1299-
end
1250+
name = OpenStudio::toUnderscoreCase(name).chomp('_')
1251+
1252+
runner.registerValue(name, value)
1253+
runner.registerInfo("Registering #{value} for #{name}.")
13001254
end
13011255
end
13021256

@@ -1563,27 +1517,27 @@ def get_ids(ids, seed_id_map = {})
15631517
return results_out
15641518
end
15651519

1566-
def write_timeseries_output_results(runner, outputs, output_format,
1567-
timeseries_output_path,
1568-
timeseries_frequency,
1569-
include_timeseries_total_consumptions,
1570-
include_timeseries_fuel_consumptions,
1571-
include_timeseries_end_use_consumptions,
1572-
include_timeseries_emissions,
1573-
include_timeseries_emission_fuels,
1574-
include_timeseries_emission_end_uses,
1575-
include_timeseries_hot_water_uses,
1576-
include_timeseries_total_loads,
1577-
include_timeseries_component_loads,
1578-
include_timeseries_unmet_hours,
1579-
include_timeseries_zone_temperatures,
1580-
include_timeseries_airflows,
1581-
include_timeseries_weather,
1582-
add_dst_column,
1583-
add_utc_column,
1584-
timestamps_dst,
1585-
timestamps_utc,
1586-
use_dview_format)
1520+
def report_timeseries_output_results(runner, outputs, output_format,
1521+
timeseries_output_path,
1522+
timeseries_frequency,
1523+
include_timeseries_total_consumptions,
1524+
include_timeseries_fuel_consumptions,
1525+
include_timeseries_end_use_consumptions,
1526+
include_timeseries_emissions,
1527+
include_timeseries_emission_fuels,
1528+
include_timeseries_emission_end_uses,
1529+
include_timeseries_hot_water_uses,
1530+
include_timeseries_total_loads,
1531+
include_timeseries_component_loads,
1532+
include_timeseries_unmet_hours,
1533+
include_timeseries_zone_temperatures,
1534+
include_timeseries_airflows,
1535+
include_timeseries_weather,
1536+
add_dst_column,
1537+
add_utc_column,
1538+
timestamps_dst,
1539+
timestamps_utc,
1540+
use_dview_format)
15871541
return if @timestamps.nil?
15881542

15891543
if not ['timestep', 'hourly', 'daily', 'monthly'].include? timeseries_frequency

0 commit comments

Comments
 (0)