urbanopt-reporting 0.1.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +19 -0
  3. data/.github/ISSUE_TEMPLATE/feature_request.md +15 -0
  4. data/.github/pull_request_template.md +13 -0
  5. data/.rdoc_options +36 -0
  6. data/CHANGELOG.md +39 -0
  7. data/CONTRIBUTING.md +1 -1
  8. data/LICENSE.md +1 -1
  9. data/RDOC_MAIN.md +10 -0
  10. data/README.md +1 -1
  11. data/Rakefile +1 -1
  12. data/deploy_docs.sh +5 -0
  13. data/doc_templates/LICENSE.md +1 -1
  14. data/doc_templates/copyright_erb.txt +1 -1
  15. data/doc_templates/copyright_js.txt +1 -1
  16. data/doc_templates/copyright_ruby.txt +1 -1
  17. data/docs/.gitignore +3 -0
  18. data/docs/.vuepress/components/InnerJsonSchema.vue +76 -0
  19. data/docs/.vuepress/components/JsonSchema.vue +12 -0
  20. data/docs/.vuepress/components/ScenarioSchema.vue +12 -0
  21. data/docs/.vuepress/components/StaticLink.vue +8 -0
  22. data/docs/.vuepress/config.js +25 -0
  23. data/docs/.vuepress/highlight.js +8 -0
  24. data/docs/.vuepress/json-schema-deref-loader.js +22 -0
  25. data/docs/.vuepress/public/custom_rdoc_styles.css +78 -0
  26. data/docs/.vuepress/styles/palette.styl +1 -0
  27. data/docs/.vuepress/utils.js +17 -0
  28. data/docs/README.md +9 -0
  29. data/docs/package-lock.json +10018 -0
  30. data/docs/package.json +30 -0
  31. data/docs/schemas/scenario-schema.md +3 -0
  32. data/lib/measures/default_feature_reports/LICENSE.md +1 -1
  33. data/lib/measures/default_feature_reports/measure.rb +261 -88
  34. data/lib/measures/default_feature_reports/measure.xml +11 -11
  35. data/lib/urbanopt/reporting.rb +1 -1
  36. data/lib/urbanopt/reporting/default_reports.rb +1 -1
  37. data/lib/urbanopt/reporting/default_reports/construction_cost.rb +1 -1
  38. data/lib/urbanopt/reporting/default_reports/date.rb +1 -1
  39. data/lib/urbanopt/reporting/default_reports/distributed_generation.rb +119 -6
  40. data/lib/urbanopt/reporting/default_reports/end_use.rb +1 -1
  41. data/lib/urbanopt/reporting/default_reports/end_uses.rb +53 -39
  42. data/lib/urbanopt/reporting/default_reports/extension.rb +30 -0
  43. data/lib/urbanopt/reporting/default_reports/feature_report.rb +52 -21
  44. data/lib/urbanopt/reporting/default_reports/generator.rb +2 -2
  45. data/lib/urbanopt/reporting/default_reports/location.rb +12 -12
  46. data/lib/urbanopt/reporting/default_reports/logger.rb +1 -1
  47. data/lib/urbanopt/reporting/default_reports/power_distribution.rb +1 -1
  48. data/lib/urbanopt/reporting/default_reports/program.rb +87 -87
  49. data/lib/urbanopt/reporting/default_reports/reporting_period.rb +87 -79
  50. data/lib/urbanopt/reporting/default_reports/scenario_report.rb +1 -1
  51. data/lib/urbanopt/reporting/default_reports/schema/README.md +1 -1
  52. data/lib/urbanopt/reporting/default_reports/schema/scenario_csv_columns.txt +18 -1
  53. data/lib/urbanopt/reporting/default_reports/schema/scenario_schema.json +117 -82
  54. data/lib/urbanopt/reporting/default_reports/solar_pv.rb +2 -2
  55. data/lib/urbanopt/reporting/default_reports/storage.rb +2 -2
  56. data/lib/urbanopt/reporting/default_reports/thermal_storage.rb +111 -0
  57. data/lib/urbanopt/reporting/default_reports/timeseries_csv.rb +1 -1
  58. data/lib/urbanopt/reporting/default_reports/validator.rb +1 -1
  59. data/lib/urbanopt/reporting/default_reports/wind.rb +2 -2
  60. data/lib/urbanopt/reporting/derived_extension.rb +1 -1
  61. data/lib/urbanopt/reporting/version.rb +2 -2
  62. data/urbanopt-reporting-gem.gemspec +4 -4
  63. metadata +37 -15
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "urbanopt-reporting-gem-docs",
3
+ "version": "0.0.1",
4
+ "description": "",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "dev": "vuepress dev",
8
+ "build": "vuepress build",
9
+ "deploy": "gh-pages -d .vuepress/dist"
10
+ },
11
+ "author": "NREL",
12
+ "dependencies": {
13
+ "highlight.js": "^10.3.1",
14
+ "json-schema-ref-parser": "^9.0.6",
15
+ "json-schema-view-js": "git+https://git@github.com/bgschiller/json-schema-view-js.git",
16
+ "vuepress": "^1.7.1",
17
+ "webpack-dev-middleware": "^3.6.0"
18
+ },
19
+ "devDependencies": {
20
+ "braces": "^3.0.2",
21
+ "dot-prop": "^5.3.0",
22
+ "gh-pages": "^3.1.0",
23
+ "js-yaml": "^3.14.0",
24
+ "minimist": ">=1.2.3",
25
+ "node-forge": ">=0.10.0",
26
+ "serialize-javascript": "^5.0.1",
27
+ "set-value": "^3.0.2",
28
+ "yargs-parser": "^20.2.3"
29
+ }
30
+ }
@@ -0,0 +1,3 @@
1
+ # Scenario Schema
2
+
3
+ <ScenarioSchema />
@@ -1,4 +1,4 @@
1
- URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
1
+ URBANopt (tm), Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
2
2
  contributors. All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without modification,
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt (tm), Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
  #
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -71,6 +71,11 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
71
71
  feature_type.setDefaultValue('Building')
72
72
  args << feature_type
73
73
 
74
+ feature_location = OpenStudio::Measure::OSArgument.makeStringArgument('feature_location', false)
75
+ feature_location.setDisplayName('URBANopt Feature Location')
76
+ feature_location.setDefaultValue('0')
77
+ args << feature_location
78
+
74
79
  # make an argument for the frequency
75
80
  reporting_frequency_chs = OpenStudio::StringVector.new
76
81
  reporting_frequency_chs << 'Detailed'
@@ -94,37 +99,39 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
94
99
 
95
100
  # define fuel types
96
101
  def fuel_types
97
- fuel_types = [
98
- 'Electricity',
99
- 'Gas',
100
- 'AdditionalFuel',
101
- 'DistrictCooling',
102
- 'DistrictHeating',
103
- 'Water'
104
- ]
102
+ fuel_types = {
103
+ 'Electricity' => 'Electricity',
104
+ 'Gas' => 'Natural Gas',
105
+ 'FuelOil#2' => 'Fuel Oil #2',
106
+ 'Propane' => 'Propane',
107
+ 'AdditionalFuel' => 'Additional Fuel',
108
+ 'DistrictCooling' => 'District Cooling',
109
+ 'DistrictHeating' => 'District Heating',
110
+ 'Water' => 'Water'
111
+ }
105
112
 
106
113
  return fuel_types
107
114
  end
108
115
 
109
116
  # define enduses
110
117
  def end_uses
111
- end_uses = [
112
- 'Heating',
113
- 'Cooling',
114
- 'InteriorLights',
115
- 'ExteriorLights',
116
- 'InteriorEquipment',
117
- 'ExteriorEquipment',
118
- 'Fans',
119
- 'Pumps',
120
- 'HeatRejection',
121
- 'Humidifier',
122
- 'HeatRecovery',
123
- 'WaterSystems',
124
- 'Refrigeration',
125
- 'Generators',
126
- 'Facility'
127
- ]
118
+ end_uses = {
119
+ 'Heating' => 'Heating',
120
+ 'Cooling' => 'Cooling',
121
+ 'InteriorLights' => 'Interior Lighting',
122
+ 'ExteriorLights' => 'Exterior Lighting',
123
+ 'InteriorEquipment' => 'Interior Equipment',
124
+ 'ExteriorEquipment' => 'Exterior Equipment',
125
+ 'Fans' => 'Fans',
126
+ 'Pumps' => 'Pumps',
127
+ 'HeatRejection' => 'Heat Rejection',
128
+ 'Humidifier' => 'Humidification',
129
+ 'HeatRecovery' => 'Heat Recovery',
130
+ 'WaterSystems' => 'Water Systems',
131
+ 'Refrigeration' => 'Refrigeration',
132
+ 'Generators' => 'Generators',
133
+ 'Facility' => 'Facility'
134
+ }
128
135
 
129
136
  return end_uses
130
137
  end
@@ -158,7 +165,9 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
158
165
 
159
166
  # Request the output for each end use/fuel type combination
160
167
  end_uses.each do |end_use|
168
+ end_use, _ = end_use
161
169
  fuel_types.each do |fuel_type|
170
+ fuel_type, _ = fuel_type
162
171
  variable_name = if end_use == 'Facility'
163
172
  "#{fuel_type}:#{end_use}"
164
173
  else
@@ -168,6 +177,24 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
168
177
  end
169
178
  end
170
179
 
180
+ # OtherFuels
181
+ other_fuels = ["FuelOil#1", "Diesel", "Gasoline", "Coal", "Steam"]
182
+ other_fuel_uses = ["HeatRejection", "Heating", "WaterSystems", "InteriorEquipment"]
183
+ custom_meter_facility = "Meter:Custom,OtherFuels:Facility,OtherFuel1"
184
+ other_fuel_uses.each do |end_use|
185
+ custom_meter = "Meter:Custom,#{end_use}:OtherFuels,OtherFuel1"
186
+ other_fuels.each do |other_fuel|
187
+ result << OpenStudio::IdfObject.load("Output:Meter,#{end_use}:#{other_fuel},#{reporting_frequency};").get
188
+ custom_meter_facility += ",,#{end_use}:#{other_fuel}"
189
+ custom_meter += ",,#{end_use}:#{other_fuel}"
190
+ end
191
+ custom_meter += ";"
192
+ result << OpenStudio::IdfObject.load(custom_meter).get
193
+ result << OpenStudio::IdfObject.load("Output:Meter,#{end_use}:OtherFuels,#{reporting_frequency};").get
194
+ end
195
+ result << OpenStudio::IdfObject.load("#{custom_meter_facility};").get
196
+ result << OpenStudio::IdfObject.load("Output:Meter,OtherFuels:Facility,#{reporting_frequency};").get
197
+
171
198
  # Request the output for each end use/fuel type combination
172
199
  result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,Electricity:Facility,#{reporting_frequency};").get
173
200
  result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,ElectricityProduced:Facility,#{reporting_frequency};").get
@@ -193,6 +220,9 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
193
220
  'District Heating Inlet Temperature', 'District Heating Outlet Temperature', 'Cooling Coil Total Cooling Rate',
194
221
  'Heating Coil Heating Rate']
195
222
 
223
+ tes_timeseries_data = ['Ice Thermal Storage End Fraction', 'Cooling coil Ice Thermal Storage End Fraction']
224
+ timeseries_data += tes_timeseries_data
225
+
196
226
  timeseries_data.each do |ts|
197
227
  result << OpenStudio::IdfObject.load("Output:Variable,*,#{ts},#{reporting_frequency};").get
198
228
  end
@@ -220,11 +250,14 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
220
250
  end
221
251
  end
222
252
 
223
- val
253
+ return val
224
254
  end
225
255
 
226
256
  # unit conversion method
227
257
  def convert_units(value, from_units, to_units)
258
+ if value.nil?
259
+ return nil
260
+ end
228
261
  # apply unit conversion
229
262
  value_converted = OpenStudio.convert(value, from_units, to_units)
230
263
  if value_converted.is_initialized
@@ -254,6 +287,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
254
287
  feature_id = runner.getStringArgumentValue('feature_id', user_arguments)
255
288
  feature_name = runner.getStringArgumentValue('feature_name', user_arguments)
256
289
  feature_type = runner.getStringArgumentValue('feature_type', user_arguments)
290
+ feature_location = runner.getStringArgumentValue('feature_location', user_arguments)
257
291
 
258
292
  # Assign the user inputs to variables
259
293
  reporting_frequency = runner.getStringArgumentValue('reporting_frequency', user_arguments)
@@ -318,37 +352,41 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
318
352
  # Get Location information and store in the feature_report
319
353
  ##
320
354
 
321
- # latitude
322
- latitude = epw_file.latitude
323
- feature_report.location.latitude = latitude
324
-
325
- # longitude
326
- longitude = epw_file.longitude
327
- feature_report.location.longitude = longitude
355
+ if feature_location.include? '['
356
+ # get latitude from feature_location
357
+ latitude = (feature_location.split(',')[0].delete! '[]').to_f
358
+ # get longitude from feature_location
359
+ longitude = (feature_location.split(',')[1].delete! '[]').to_f
360
+ # latitude
361
+ feature_report.location.latitude_deg = latitude
362
+ # longitude
363
+ feature_report.location.longitude_deg = longitude
364
+ end
328
365
 
329
366
  # surface_elevation
330
367
  elev = sql_query(runner, sql_file, 'InputVerificationandResultsSummary', "TableName='General' AND RowName='Elevation' AND ColumnName='Value'")
331
- feature_report.location.surface_elevation = elev
368
+ feature_report.location.surface_elevation_ft = elev
332
369
 
333
370
  ##########################################################################
334
371
  ##
372
+
335
373
  # Get program information and store in the feature_report
336
374
  ##
337
375
 
338
376
  # floor_area
339
377
  floor_area = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Building Area' AND RowName='Total Building Area' AND ColumnName='Area'")
340
- feature_report.program.floor_area = convert_units(floor_area, 'm^2', 'ft^2')
378
+ feature_report.program.floor_area_sqft = convert_units(floor_area, 'm^2', 'ft^2')
341
379
 
342
380
  # conditioned_area
343
381
  conditioned_area = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Building Area' AND RowName='Net Conditioned Building Area' AND ColumnName='Area'")
344
- feature_report.program.conditioned_area = convert_units(conditioned_area, 'm^2', 'ft^2')
382
+ feature_report.program.conditioned_area_sqft = convert_units(conditioned_area, 'm^2', 'ft^2')
345
383
 
346
384
  # unconditioned_area
347
385
  unconditioned_area = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Building Area' AND RowName='Unconditioned Building Area' AND ColumnName='Area'")
348
- feature_report.program.unconditioned_area = convert_units(unconditioned_area, 'm^2', 'ft^2')
386
+ feature_report.program.unconditioned_area_sqft = convert_units(unconditioned_area, 'm^2', 'ft^2')
349
387
 
350
388
  # footprint_area
351
- feature_report.program.footprint_area = convert_units(floor_area, 'm^2', 'ft^2')
389
+ feature_report.program.footprint_area_sqft = convert_units(floor_area, 'm^2', 'ft^2')
352
390
 
353
391
  # maximum_number_of_stories
354
392
  number_of_stories = building.standardsNumberOfStories.get if building.standardsNumberOfStories.is_initialized
@@ -358,7 +396,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
358
396
  # maximum_roof_height
359
397
  floor_to_floor_height = building.nominalFloortoFloorHeight.to_f
360
398
  maximum_roof_height = number_of_stories * floor_to_floor_height
361
- feature_report.program.maximum_roof_height = maximum_roof_height
399
+ feature_report.program.maximum_roof_height_ft = maximum_roof_height
362
400
 
363
401
  # maximum_number_of_stories_above_ground
364
402
  number_of_stories_above_ground = building.standardsNumberOfAboveGroundStories.get if building.standardsNumberOfAboveGroundStories.is_initialized
@@ -419,36 +457,36 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
419
457
  ## window_area
420
458
  # north_window_area
421
459
  north_window_area = sql_query(runner, sql_file, 'InputVerificationandResultsSummary', "TableName='Window-Wall Ratio' AND RowName='Window Opening Area' AND ColumnName='North (315 to 45 deg)'").to_f
422
- feature_report.program.window_area[:north_window_area] = convert_units(north_window_area, 'm^2', 'ft^2')
460
+ feature_report.program.window_area_sqft[:north_window_area_sqft] = convert_units(north_window_area, 'm^2', 'ft^2')
423
461
  # south_window_area
424
462
  south_window_area = sql_query(runner, sql_file, 'InputVerificationandResultsSummary', "TableName='Window-Wall Ratio' AND RowName='Window Opening Area' AND ColumnName='South (135 to 225 deg)'").to_f
425
- feature_report.program.window_area[:south_window_area] = convert_units(south_window_area, 'm^2', 'ft^2')
463
+ feature_report.program.window_area_sqft[:south_window_area_sqft] = convert_units(south_window_area, 'm^2', 'ft^2')
426
464
  # east_window_area
427
465
  east_window_area = sql_query(runner, sql_file, 'InputVerificationandResultsSummary', "TableName='Window-Wall Ratio' AND RowName='Window Opening Area' AND ColumnName='East (45 to 135 deg)'").to_f
428
- feature_report.program.window_area[:east_window_area] = convert_units(east_window_area, 'm^2', 'ft^2')
466
+ feature_report.program.window_area_sqft[:east_window_area_sqft] = convert_units(east_window_area, 'm^2', 'ft^2')
429
467
  # west_window_area
430
468
  west_window_area = sql_query(runner, sql_file, 'InputVerificationandResultsSummary', "TableName='Window-Wall Ratio' AND RowName='Window Opening Area' AND ColumnName='West (225 to 315 deg)'").to_f
431
- feature_report.program.window_area[:west_window_area] = convert_units(west_window_area, 'm^2', 'ft^2')
469
+ feature_report.program.window_area_sqft[:west_window_area_sqft] = convert_units(west_window_area, 'm^2', 'ft^2')
432
470
  # total_window_area
433
471
  total_window_area = north_window_area + south_window_area + east_window_area + west_window_area
434
- feature_report.program.window_area[:total_window_area] = convert_units(total_window_area, 'm^2', 'ft^2')
472
+ feature_report.program.window_area_sqft[:total_window_area_sqft] = convert_units(total_window_area, 'm^2', 'ft^2')
435
473
 
436
474
  ## wall_area
437
475
  # north_wall_area
438
476
  north_wall_area = sql_query(runner, sql_file, 'InputVerificationandResultsSummary', "TableName='Window-Wall Ratio' AND RowName='Gross Wall Area' AND ColumnName='North (315 to 45 deg)'").to_f
439
- feature_report.program.wall_area[:north_wall_area] = convert_units(north_wall_area, 'm^2', 'ft^2')
477
+ feature_report.program.wall_area_sqft[:north_wall_area_sqft] = convert_units(north_wall_area, 'm^2', 'ft^2')
440
478
  # south_wall_area
441
479
  south_wall_area = sql_query(runner, sql_file, 'InputVerificationandResultsSummary', "TableName='Window-Wall Ratio' AND RowName='Gross Wall Area' AND ColumnName='South (135 to 225 deg)'").to_f
442
- feature_report.program.wall_area[:south_wall_area] = convert_units(south_wall_area, 'm^2', 'ft^2')
480
+ feature_report.program.wall_area_sqft[:south_wall_area_sqft] = convert_units(south_wall_area, 'm^2', 'ft^2')
443
481
  # east_wall_area
444
482
  east_wall_area = sql_query(runner, sql_file, 'InputVerificationandResultsSummary', "TableName='Window-Wall Ratio' AND RowName='Gross Wall Area' AND ColumnName='East (45 to 135 deg)'").to_f
445
- feature_report.program.wall_area[:east_wall_area] = convert_units(east_wall_area, 'm^2', 'ft^2')
483
+ feature_report.program.wall_area_sqft[:east_wall_area_sqft] = convert_units(east_wall_area, 'm^2', 'ft^2')
446
484
  # west_wall_area
447
485
  west_wall_area = sql_query(runner, sql_file, 'InputVerificationandResultsSummary', "TableName='Window-Wall Ratio' AND RowName='Gross Wall Area' AND ColumnName='West (225 to 315 deg)'").to_f
448
- feature_report.program.wall_area[:west_wall_area] = convert_units(west_wall_area, 'm^2', 'ft^2')
486
+ feature_report.program.wall_area_sqft[:west_wall_area_sqft] = convert_units(west_wall_area, 'm^2', 'ft^2')
449
487
  # total_wall_area
450
488
  total_wall_area = north_wall_area + south_wall_area + east_wall_area + west_wall_area
451
- feature_report.program.wall_area[:total_wall_area] = convert_units(total_wall_area, 'm^2', 'ft^2')
489
+ feature_report.program.wall_area_sqft[:total_wall_area_sqft] = convert_units(total_wall_area, 'm^2', 'ft^2')
452
490
 
453
491
  # total_roof_area
454
492
  total_roof_area = 0.0
@@ -457,12 +495,12 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
457
495
  total_roof_area += surface.netArea
458
496
  end
459
497
  end
460
- feature_report.program.roof_area[:total_roof_area] = convert_units(total_roof_area, 'm^2', 'ft^2')
498
+ feature_report.program.roof_area_sqft[:total_roof_area_sqft] = convert_units(total_roof_area, 'm^2', 'ft^2')
461
499
 
462
500
  # orientation
463
501
  # RK: a more robust method should be implemented to find orientation(finding main axis of the building using aspect ratio)
464
502
  building_rotation = model.getBuilding.northAxis
465
- feature_report.program.orientation = building_rotation
503
+ feature_report.program.orientation_deg = building_rotation
466
504
 
467
505
  # aspect_ratio
468
506
  north_wall_area = sql_query(runner, sql_file, 'InputVerificationandResultsSummary', "TableName='Window-Wall Ratio' AND RowName='Gross Wall Area' AND ColumnName='North (315 to 45 deg)'")
@@ -473,7 +511,40 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
473
511
 
474
512
  # total_construction_cost
475
513
  total_construction_cost = sql_query(runner, sql_file, 'Life-Cycle Cost Report', "TableName='Present Value for Recurring, Nonrecurring and Energy Costs (Before Tax)' AND RowName='LCC_MAT - BUILDING - LIFE CYCLE COSTS' AND ColumnName='Cost'")
476
- feature_report.program.total_construction_cost = total_construction_cost
514
+ feature_report.program.total_construction_cost_dollar = total_construction_cost
515
+
516
+ # packaged thermal storage capacities by cooling coil
517
+ ptes_keys = sql_file.availableKeyValues('RUN Period 1', 'Zone Timestep', 'Cooling Coil Ice Thermal Storage End Fraction')
518
+ if ptes_keys.empty?
519
+ ptes_size = nil
520
+ runner.registerWarning('Query failed for Packaged Ice Thermal Storage Capacity')
521
+ else
522
+ begin
523
+ ptes_size = 0
524
+ ptes_keys.each do |pk|
525
+ ptes_size += sql_query(runner, sql_file, 'ComponentSizingSummary', "TableName='Coil:Cooling:DX:SingleSpeed:ThermalStorage' AND RowName='#{pk}' AND ColumnName='Ice Storage Capacity'").to_f
526
+ end
527
+ ptes_size = convert_units(ptes_size, 'GJ', 'kWh')
528
+ rescue StandardError
529
+ runner.registerWarning('Query ptes_size.get failed')
530
+ end
531
+ end
532
+ feature_report.thermal_storage.ptes_size_kwh = ptes_size
533
+
534
+ # get the central tank thermal storage capacity
535
+ its_size = nil
536
+ its_size_index = sql_file.execAndReturnFirstDouble("SELECT ReportVariableDataDictionaryIndex FROM ReportVariableDataDictionary WHERE VariableName='Ice Thermal Storage Capacity'")
537
+ if its_size_index.empty?
538
+ runner.registerWarning('Query failed for Ice Thermal Storage Capacity')
539
+ else
540
+ begin
541
+ its_size = sql_file.execAndReturnFirstDouble("SELECT VariableValue FROM ReportVariableData WHERE ReportVariableDataDictionaryIndex=#{its_size_index}").get
542
+ its_size = convert_units(its_size.to_f, 'GJ', 'kWh')
543
+ rescue StandardError
544
+ runner.registerWarning('Query its_size.get failed')
545
+ end
546
+ end
547
+ feature_report.thermal_storage.its_size_kwh = its_size
477
548
 
478
549
  ############################################################################
479
550
  ##
@@ -504,78 +575,132 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
504
575
 
505
576
  # total_site_energy
506
577
  total_site_energy = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Site and Source Energy' AND RowName='Total Site Energy' AND ColumnName='Total Energy'")
507
- feature_report.reporting_periods[0].total_site_energy = convert_units(total_site_energy, 'GJ', 'kBtu')
578
+ feature_report.reporting_periods[0].total_site_energy_kwh = convert_units(total_site_energy, 'GJ', 'kWh')
508
579
 
509
580
  # total_source_energy
510
581
  total_source_energy = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Site and Source Energy' AND RowName='Total Source Energy' AND ColumnName='Total Energy'")
511
- feature_report.reporting_periods[0].total_source_energy = convert_units(total_source_energy, 'GJ', 'kBtu')
582
+ feature_report.reporting_periods[0].total_source_energy_kwh = convert_units(total_source_energy, 'GJ', 'kWh')
512
583
 
513
584
  # net_site_energy
514
585
  net_site_energy = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Site and Source Energy' AND RowName='Net Site Energy' AND ColumnName='Total Energy'")
515
- feature_report.reporting_periods[0].net_site_energy = convert_units(net_site_energy, 'GJ', 'kBtu')
586
+ feature_report.reporting_periods[0].net_site_energy_kwh = convert_units(net_site_energy, 'GJ', 'kWh')
516
587
 
517
588
  # net_source_energy
518
589
  net_source_energy = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Site and Source Energy' AND RowName='Net Source Energy' AND ColumnName='Total Energy'")
519
- feature_report.reporting_periods[0].net_source_energy = convert_units(net_source_energy, 'GJ', 'kBtu')
590
+ feature_report.reporting_periods[0].net_source_energy_kwh = convert_units(net_source_energy, 'GJ', 'kWh')
520
591
 
521
592
  # electricity
522
593
  electricity = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='End Uses' AND RowName='Total End Uses' AND ColumnName='Electricity'")
523
- feature_report.reporting_periods[0].electricity = convert_units(electricity, 'GJ', 'kBtu')
594
+ feature_report.reporting_periods[0].electricity_kwh = convert_units(electricity, 'GJ', 'kWh')
524
595
 
525
596
  # natural_gas
526
597
  natural_gas = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='End Uses' AND RowName='Total End Uses' AND ColumnName='Natural Gas'")
527
- feature_report.reporting_periods[0].natural_gas = convert_units(natural_gas, 'GJ', 'kBtu')
598
+ feature_report.reporting_periods[0].natural_gas_kwh = convert_units(natural_gas, 'GJ', 'kWh')
599
+
600
+ # propane
601
+ propane = sql_query(runner, sql_file, 'EnergyMeters', "TableName='Annual and Peak Values - Other' AND RowName='Propane:Facility' AND ColumnName='Annual Value'")
602
+ feature_report.reporting_periods[0].propane_kwh = 0.0
603
+ feature_report.reporting_periods[0].propane_kwh = convert_units(propane, 'GJ', 'kWh') unless propane.nil?
604
+
605
+ # fuel_oil
606
+ fuel_oil = sql_query(runner, sql_file, 'EnergyMeters', "TableName='Annual and Peak Values - Other' AND RowName='FuelOil#2:Facility' AND ColumnName='Annual Value'")
607
+ feature_report.reporting_periods[0].fuel_oil_kwh = 0.0
608
+ feature_report.reporting_periods[0].fuel_oil_kwh = convert_units(fuel_oil, 'GJ', 'kWh') unless fuel_oil.nil?
528
609
 
529
- # additional_fuel
610
+ # other_fuels
530
611
  additional_fuel = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='End Uses' AND RowName='Total End Uses' AND ColumnName='Additional Fuel'")
531
- feature_report.reporting_periods[0].additional_fuel = convert_units(additional_fuel, 'GJ', 'kBtu')
612
+ # ensure additional fuel is not nil
613
+ feature_report.reporting_periods[0].other_fuels_kwh = 0.0
614
+ feature_report.reporting_periods[0].other_fuels_kwh = convert_units(additional_fuel, 'GJ', 'kWh') unless additional_fuel.nil?
615
+ feature_report.reporting_periods[0].other_fuels_kwh -= feature_report.reporting_periods[0].propane_kwh
616
+ feature_report.reporting_periods[0].other_fuels_kwh -= feature_report.reporting_periods[0].fuel_oil_kwh
532
617
 
533
618
  # district_cooling
534
619
  district_cooling = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='End Uses' AND RowName='Total End Uses' AND ColumnName='District Cooling'")
535
- feature_report.reporting_periods[0].district_cooling = convert_units(district_cooling, 'GJ', 'kBtu')
620
+ feature_report.reporting_periods[0].district_cooling_kwh = convert_units(district_cooling, 'GJ', 'kWh')
621
+ building_types.each do |i|
622
+ feature_report.reporting_periods[0].district_cooling_kwh = 0.0 if i[:building_type].include?('Single-Family Detached')
623
+ end
536
624
 
537
625
  # district_heating
538
626
  district_heating = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='End Uses' AND RowName='Total End Uses' AND ColumnName='District Heating'")
539
- feature_report.reporting_periods[0].district_heating = convert_units(district_heating, 'GJ', 'kBtu')
627
+ feature_report.reporting_periods[0].district_heating_kwh = convert_units(district_heating, 'GJ', 'kWh')
628
+ building_types.each do |i|
629
+ feature_report.reporting_periods[0].district_heating_kwh = 0.0 if i[:building_type].include?('Single-Family Detached')
630
+ end
540
631
 
541
632
  # water
542
633
  water = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='End Uses' AND RowName='Total End Uses' AND ColumnName='Water'")
543
634
  # feature_report.reporting_periods[0].water = convert_units(water, 'm3', 'ft3')
544
- feature_report.reporting_periods[0].water = water
635
+ feature_report.reporting_periods[0].water_qbft = water
545
636
 
546
637
  # electricity_produced
547
638
  electricity_produced = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Electric Loads Satisfied' AND RowName='Total On-Site and Utility Electric Sources' AND ColumnName='Electricity'")
548
- feature_report.reporting_periods[0].electricity_produced = convert_units(electricity_produced, 'GJ', 'kBtu')
639
+ feature_report.reporting_periods[0].electricity_produced_kwh = convert_units(electricity_produced, 'GJ', 'kWh')
549
640
 
550
641
  ## end_uses
551
642
 
552
643
  # get fuel type as listed in the sql file
553
- fuel_type = ['Electricity', 'Natural Gas', 'Additional Fuel', 'District Cooling', 'District Heating', 'Water']
644
+ fueltypes = fuel_types.values
645
+ fueltypes.delete('Propane')
646
+ fueltypes.delete('Fuel Oil #2')
554
647
 
555
648
  # get enduses as listed in the sql file
556
- enduses = ['Heating', 'Cooling', 'Interior Lighting', 'Exterior Lighting', 'Interior Equipment', 'Exterior Equipment', 'Fans', 'Pumps',
557
- 'Heat Rejection', 'Humidification', 'Heat Recovery', 'Water Systems', 'Refrigeration', 'Generators']
649
+ enduses = end_uses.values
650
+ enduses.delete('Facility')
651
+
652
+ # propane / fuel_oil
653
+ ['Propane', 'Fuel Oil #2'].each do |ft|
654
+ end_uses.keys.each do |eu|
655
+ next if eu == 'Facility'
656
+
657
+ sql_r = sql_query(runner, sql_file, 'EnergyMeters', "TableName='Annual and Peak Values - Other' AND RowName='#{eu}:#{ft.tr(' ', '')}' AND ColumnName='Annual Value'")
658
+
659
+ # report each query in its corresponding feature report obeject
660
+ x = ft.tr(' ', '_').downcase
661
+ x = x.gsub('_#2', '')
662
+ x_u = x + '_kwh'
663
+ m = feature_report.reporting_periods[0].end_uses.send(x_u)
664
+
665
+ y = end_uses[eu].tr(' ', '_').downcase
666
+ if sql_r.nil?
667
+ sql_r = 0.0
668
+ end
669
+ m.send("#{y}=", convert_units(sql_r, 'GJ', 'kWh'))
670
+ end
671
+ end
558
672
 
559
673
  # loop through fuel types and enduses to fill in sql_query method
560
- fuel_type.each do |ft|
674
+ fueltypes.each do |ft|
561
675
  enduses.each do |eu|
562
676
  sql_r = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='End Uses' AND RowName='#{eu}' AND ColumnName='#{ft}'")
563
677
 
564
678
  # report each query in its corresponding feature report obeject
565
- if ft.include? ' '
566
- x = ft.tr(' ', '_').downcase
567
- m = feature_report.reporting_periods[0].end_uses.send(x)
679
+ x = ft.tr(' ', '_').downcase
680
+ if x.include? 'water'
681
+ x_u = x + '_qbft'
568
682
  else
569
- m = feature_report.reporting_periods[0].end_uses.send(ft.downcase)
570
-
683
+ x_u = x + '_kwh'
684
+ end
685
+ if x_u == 'additional_fuel_kwh'
686
+ x_u = 'other_fuels_kwh'
571
687
  end
688
+ m = feature_report.reporting_periods[0].end_uses.send(x_u)
572
689
 
573
- if eu.include? ' '
574
- y = eu.tr(' ', '_').downcase
575
- m.send("#{y}=", convert_units(sql_r, 'GJ', 'kBtu'))
576
- else
577
- m.send("#{eu.downcase}=", convert_units(sql_r, 'GJ', 'kBtu'))
690
+ y = eu.tr(' ', '_').downcase
691
+ # ensure not nil so the equations below don't error out
692
+ if sql_r.nil?
693
+ sql_r = 0.0
694
+ end
695
+ sql_r = convert_units(sql_r, 'GJ', 'kWh')
696
+ if x_u == 'other_fuels_kwh'
697
+ sql_r -= feature_report.reporting_periods[0].end_uses.propane_kwh.send(y)
698
+ sql_r -= feature_report.reporting_periods[0].end_uses.fuel_oil_kwh.send(y)
578
699
  end
700
+ building_types.each do |i|
701
+ sql_r = 0.0 if (i[:building_type].include?('Single-Family Detached') && x_u.include?('district'))
702
+ end
703
+ m.send("#{y}=", sql_r)
579
704
  end
580
705
  end
581
706
 
@@ -583,20 +708,20 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
583
708
  ## electricity_produced
584
709
  # photovoltaic
585
710
  photovoltaic_power = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Electric Loads Satisfied' AND RowName='Photovoltaic Power' AND ColumnName='Electricity'")
586
- feature_report.reporting_periods[0].energy_production[:electricity_produced][:photovoltaic] = convert_units(photovoltaic_power, 'GJ', 'kBtu')
711
+ feature_report.reporting_periods[0].energy_production_kwh[:electricity_produced][:photovoltaic] = convert_units(photovoltaic_power, 'GJ', 'kWh')
587
712
 
588
713
  ## Total utility cost
589
714
  total_utility_cost = sql_query(runner, sql_file, 'Economics Results Summary Report', "TableName='Annual Cost' AND RowName='Cost' AND ColumnName='Total'")
590
- feature_report.reporting_periods[0].total_utility_cost = total_utility_cost
715
+ feature_report.reporting_periods[0].total_utility_cost_dollar = total_utility_cost
591
716
 
592
717
  ## Utility Costs
593
718
  # electricity utility cost
594
719
  elec_utility_cost = sql_query(runner, sql_file, 'Economics Results Summary Report', "TableName='Annual Cost' AND RowName='Cost' AND ColumnName='Electric'")
595
- feature_report.reporting_periods[0].utility_costs[0][:fuel_type] = 'Electricity'
596
- feature_report.reporting_periods[0].utility_costs[0][:total_cost] = elec_utility_cost
720
+ feature_report.reporting_periods[0].utility_costs_dollar[0][:fuel_type] = 'Electricity'
721
+ feature_report.reporting_periods[0].utility_costs_dollar[0][:total_cost] = elec_utility_cost
597
722
  # gas utility cost
598
723
  gas_utility_cost = sql_query(runner, sql_file, 'Economics Results Summary Report', "TableName='Annual Cost' AND RowName='Cost' AND ColumnName='Gas'")
599
- feature_report.reporting_periods[0].utility_costs << { fuel_type: 'Natural Gas', total_cost: gas_utility_cost }
724
+ feature_report.reporting_periods[0].utility_costs_dollar << { fuel_type: 'Natural Gas', total_cost: gas_utility_cost }
600
725
 
601
726
  ## comfort_result
602
727
  # time_setpoint_not_met_during_occupied_cooling
@@ -634,6 +759,9 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
634
759
  'Electricity:Facility',
635
760
  'ElectricityProduced:Facility',
636
761
  'Gas:Facility',
762
+ 'Propane:Facility',
763
+ 'FuelOil#2:Facility',
764
+ 'OtherFuels:Facility',
637
765
  'Cooling:Electricity',
638
766
  'Heating:Electricity',
639
767
  'InteriorLights:Electricity',
@@ -647,6 +775,18 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
647
775
  'Heating:Gas',
648
776
  'WaterSystems:Gas',
649
777
  'InteriorEquipment:Gas',
778
+ 'HeatRejection:Propane',
779
+ 'Heating:Propane',
780
+ 'WaterSystems:Propane',
781
+ 'InteriorEquipment:Propane',
782
+ 'HeatRejection:FuelOil#2',
783
+ 'Heating:FuelOil#2',
784
+ 'WaterSystems:FuelOil#2',
785
+ 'InteriorEquipment:FuelOil#2',
786
+ 'HeatRejection:OtherFuels',
787
+ 'Heating:OtherFuels',
788
+ 'WaterSystems:OtherFuels',
789
+ 'InteriorEquipment:OtherFuels',
650
790
  'DistrictCooling:Facility',
651
791
  'DistrictHeating:Facility',
652
792
  'District Cooling Chilled Water Rate',
@@ -669,6 +809,10 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
669
809
  powerTimeseries = ['Net Electric Energy', 'Electricity:Facility Power', 'ElectricityProduced:Facility Power', 'Electricity:Facility Apparent Power', 'ElectricityProduced:Facility Apparent Power', 'Net Power', 'Net Apparent Power']
670
810
  requested_timeseries_names += powerTimeseries
671
811
 
812
+ # add additional thermal storage timeseries
813
+ tesTimeseries = ['Ice Thermal Storage End Fraction', 'Cooling Coil Ice Thermal Storage End Fraction']
814
+ requested_timeseries_names += tesTimeseries
815
+
672
816
  # register info all timeseries
673
817
  runner.registerInfo("All timeseries: #{requested_timeseries_names}")
674
818
 
@@ -706,8 +850,12 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
706
850
  puts " *********timeseries_name = #{timeseries_name}******************"
707
851
  runner.registerInfo("TIMESERIES: #{timeseries_name}")
708
852
 
709
- # get all the key values that this timeseries can be reported for (e.g. if PMV is requested for each zone)
710
- key_values = sql_file.availableKeyValues('RUN PERIOD 1', 'Zone Timestep', timeseries_name)
853
+ # get all the key values that this timeseries can be reported for (e.g. if PMV is requested for each zone)
854
+ if timeseries_name.include?('OtherFuels')
855
+ key_values = sql_file.availableKeyValues('RUN PERIOD 1', 'Zone Timestep', timeseries_name.upcase)
856
+ else
857
+ key_values = sql_file.availableKeyValues('RUN PERIOD 1', 'Zone Timestep', timeseries_name)
858
+ end
711
859
  runner.registerInfo("KEY VALUES: #{key_values}")
712
860
  if key_values.empty?
713
861
  key_values = ['']
@@ -751,7 +899,11 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
751
899
  # final_timeseries_names << new_timeseries_name
752
900
 
753
901
  # get the actual timeseries
754
- ts = sql_file.timeSeries(ann_env_pd.to_s, reporting_frequency.to_s, timeseries_name, key_value)
902
+ if timeseries_name.include?('OtherFuels')
903
+ ts = sql_file.timeSeries(ann_env_pd.to_s, reporting_frequency.to_s, timeseries_name.upcase, key_value)
904
+ else
905
+ ts = sql_file.timeSeries(ann_env_pd.to_s, reporting_frequency.to_s, timeseries_name, key_value)
906
+ end
755
907
 
756
908
  if n.nil?
757
909
  # first timeseries should always be set
@@ -766,10 +918,15 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
766
918
  values[key_cnt] = Array.new(n, 0)
767
919
  end
768
920
 
921
+ # residential considerations
922
+ building_types.each do |i|
923
+ values[key_cnt] = Array.new(n, 0) if ['DistrictCooling:Facility', 'DistrictHeating:Facility'].include?(timeseries_name) && i[:building_type].include?('Single-Family Detached')
924
+ end
925
+
769
926
  # unit conversion
770
927
  old_unit = ts.get.units if ts.is_initialized
771
928
 
772
- if timeseries_name.include? 'Gas'
929
+ if timeseries_name.include?('Gas') || timeseries_name.include?('Propane') || timeseries_name.include?('FuelOil#2') || timeseries_name.include?('OtherFuels')
773
930
  new_unit = 'kBtu'
774
931
  else
775
932
  new_unit = case old_unit.to_s
@@ -870,6 +1027,22 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
870
1027
  # puts "units = #{new_unit}"
871
1028
  # end
872
1029
 
1030
+ # thermal storage ice end fractions have multiple timeseries, aggregate into a single series with consistent name and use the average value at each timestep
1031
+ if tesTimeseries.include? timeseries_name
1032
+
1033
+ # set up array if 1st key_value
1034
+ if key_i == 0
1035
+ runner.registerInfo("SETTING UP NEW ARRAY FOR: #{timeseries_name}")
1036
+ tmpArray = Array.new(n, 1)
1037
+ end
1038
+
1039
+ # add to array (keep min value at each timestep)
1040
+ (0..(n - 1)).each do |ind|
1041
+ tVal = values[key_cnt][ind].to_f
1042
+ tmpArray[ind] = [tVal, tmpArray[ind]].min
1043
+ end
1044
+ end
1045
+
873
1046
  # comfort results usually have multiple timeseries (per zone), aggregate into a single series with consistent name and use worst value at each timestep
874
1047
  if comfortTimeseries.include? timeseries_name
875
1048