urbanopt-reporting 0.2.0 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) 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 +43 -1
  7. data/LICENSE.md +1 -1
  8. data/RDOC_MAIN.md +10 -0
  9. data/deploy_docs.sh +5 -0
  10. data/doc_templates/LICENSE.md +1 -1
  11. data/doc_templates/copyright_erb.txt +1 -1
  12. data/doc_templates/copyright_js.txt +1 -1
  13. data/doc_templates/copyright_ruby.txt +1 -1
  14. data/docs/.gitignore +3 -0
  15. data/docs/.vuepress/components/InnerJsonSchema.vue +76 -0
  16. data/docs/.vuepress/components/JsonSchema.vue +12 -0
  17. data/docs/.vuepress/components/ScenarioSchema.vue +12 -0
  18. data/docs/.vuepress/components/StaticLink.vue +8 -0
  19. data/docs/.vuepress/config.js +25 -0
  20. data/docs/.vuepress/highlight.js +8 -0
  21. data/docs/.vuepress/json-schema-deref-loader.js +22 -0
  22. data/docs/.vuepress/public/custom_rdoc_styles.css +78 -0
  23. data/docs/.vuepress/styles/palette.styl +1 -0
  24. data/docs/.vuepress/utils.js +17 -0
  25. data/docs/README.md +9 -0
  26. data/docs/package-lock.json +10018 -0
  27. data/docs/package.json +30 -0
  28. data/docs/schemas/scenario-schema.md +3 -0
  29. data/lib/measures/default_feature_reports/LICENSE.md +1 -1
  30. data/lib/measures/default_feature_reports/measure.rb +231 -87
  31. data/lib/measures/default_feature_reports/measure.xml +11 -11
  32. data/lib/measures/export_modelica_loads/LICENSE.md +27 -0
  33. data/lib/measures/export_modelica_loads/README.md +26 -0
  34. data/lib/measures/export_modelica_loads/README.md.erb +42 -0
  35. data/lib/measures/export_modelica_loads/docs/.gitkeep +0 -0
  36. data/lib/measures/export_modelica_loads/measure.rb +367 -0
  37. data/lib/measures/export_modelica_loads/measure.xml +92 -0
  38. data/lib/measures/export_modelica_loads/resources/report.html.in +13 -0
  39. data/lib/measures/export_time_series_modelica/LICENSE.md +1 -0
  40. data/lib/measures/export_time_series_modelica/README.md +59 -0
  41. data/lib/measures/export_time_series_modelica/README.md.erb +42 -0
  42. data/lib/measures/export_time_series_modelica/docs/.gitkeep +0 -0
  43. data/lib/measures/export_time_series_modelica/measure.rb +433 -0
  44. data/lib/measures/export_time_series_modelica/measure.xml +147 -0
  45. data/lib/measures/export_time_series_modelica/resources/os_lib_helper_methods.rb +399 -0
  46. data/lib/measures/export_time_series_modelica/resources/report.html.in +13 -0
  47. data/lib/urbanopt/reporting/default_reports/end_uses.rb +52 -38
  48. data/lib/urbanopt/reporting/default_reports/feature_report.rb +79 -8
  49. data/lib/urbanopt/reporting/default_reports/location.rb +11 -11
  50. data/lib/urbanopt/reporting/default_reports/program.rb +86 -86
  51. data/lib/urbanopt/reporting/default_reports/reporting_period.rb +98 -78
  52. data/lib/urbanopt/reporting/default_reports/scenario_report.rb +7 -4
  53. data/lib/urbanopt/reporting/default_reports/schema/scenario_csv_columns.txt +15 -0
  54. data/lib/urbanopt/reporting/default_reports/schema/scenario_schema.json +108 -80
  55. data/lib/urbanopt/reporting/default_reports/thermal_storage.rb +10 -10
  56. data/lib/urbanopt/reporting/version.rb +1 -1
  57. data/urbanopt-reporting-gem.gemspec +4 -4
  58. metadata +50 -13
@@ -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.4.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,
@@ -99,37 +99,39 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
99
99
 
100
100
  # define fuel types
101
101
  def fuel_types
102
- fuel_types = [
103
- 'Electricity',
104
- 'Gas',
105
- 'AdditionalFuel',
106
- 'DistrictCooling',
107
- 'DistrictHeating',
108
- 'Water'
109
- ]
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
+ }
110
112
 
111
113
  return fuel_types
112
114
  end
113
115
 
114
116
  # define enduses
115
117
  def end_uses
116
- end_uses = [
117
- 'Heating',
118
- 'Cooling',
119
- 'InteriorLights',
120
- 'ExteriorLights',
121
- 'InteriorEquipment',
122
- 'ExteriorEquipment',
123
- 'Fans',
124
- 'Pumps',
125
- 'HeatRejection',
126
- 'Humidifier',
127
- 'HeatRecovery',
128
- 'WaterSystems',
129
- 'Refrigeration',
130
- 'Generators',
131
- 'Facility'
132
- ]
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
+ }
133
135
 
134
136
  return end_uses
135
137
  end
@@ -163,7 +165,9 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
163
165
 
164
166
  # Request the output for each end use/fuel type combination
165
167
  end_uses.each do |end_use|
168
+ end_use, = end_use
166
169
  fuel_types.each do |fuel_type|
170
+ fuel_type, = fuel_type
167
171
  variable_name = if end_use == 'Facility'
168
172
  "#{fuel_type}:#{end_use}"
169
173
  else
@@ -173,6 +177,24 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
173
177
  end
174
178
  end
175
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
+
176
198
  # Request the output for each end use/fuel type combination
177
199
  result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,Electricity:Facility,#{reporting_frequency};").get
178
200
  result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,ElectricityProduced:Facility,#{reporting_frequency};").get
@@ -228,11 +250,19 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
228
250
  end
229
251
  end
230
252
 
231
- val
253
+ return val
232
254
  end
233
255
 
234
256
  # unit conversion method
235
257
  def convert_units(value, from_units, to_units)
258
+ if value.nil?
259
+ return nil
260
+ end
261
+ if from_units.nil? || to_units.nil?
262
+ @runner.registerError("Cannot convert units...from_units: #{from_units} or to_units: #{to_units} left blank.")
263
+ return nil
264
+ end
265
+
236
266
  # apply unit conversion
237
267
  value_converted = OpenStudio.convert(value, from_units, to_units)
238
268
  if value_converted.is_initialized
@@ -328,19 +358,19 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
328
358
  ##
329
359
 
330
360
  if feature_location.include? '['
331
- # get latitude from feature_location
332
- latitude = (feature_location.split(',')[0].delete! '[]').to_f
333
361
  # get longitude from feature_location
334
- longitude = (feature_location.split(',')[1].delete! '[]').to_f
362
+ longitude = (feature_location.split(',')[0].delete! '[]').to_f
363
+ # get latitude from feature_location
364
+ latitude = (feature_location.split(',')[1].delete! '[]').to_f
335
365
  # latitude
336
- feature_report.location.latitude = latitude
366
+ feature_report.location.latitude_deg = latitude
337
367
  # longitude
338
- feature_report.location.longitude = longitude
368
+ feature_report.location.longitude_deg = longitude
339
369
  end
340
370
 
341
371
  # surface_elevation
342
372
  elev = sql_query(runner, sql_file, 'InputVerificationandResultsSummary', "TableName='General' AND RowName='Elevation' AND ColumnName='Value'")
343
- feature_report.location.surface_elevation = elev
373
+ feature_report.location.surface_elevation_ft = elev
344
374
 
345
375
  ##########################################################################
346
376
  ##
@@ -350,18 +380,18 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
350
380
 
351
381
  # floor_area
352
382
  floor_area = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Building Area' AND RowName='Total Building Area' AND ColumnName='Area'")
353
- feature_report.program.floor_area = convert_units(floor_area, 'm^2', 'ft^2')
383
+ feature_report.program.floor_area_sqft = convert_units(floor_area, 'm^2', 'ft^2')
354
384
 
355
385
  # conditioned_area
356
386
  conditioned_area = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Building Area' AND RowName='Net Conditioned Building Area' AND ColumnName='Area'")
357
- feature_report.program.conditioned_area = convert_units(conditioned_area, 'm^2', 'ft^2')
387
+ feature_report.program.conditioned_area_sqft = convert_units(conditioned_area, 'm^2', 'ft^2')
358
388
 
359
389
  # unconditioned_area
360
390
  unconditioned_area = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Building Area' AND RowName='Unconditioned Building Area' AND ColumnName='Area'")
361
- feature_report.program.unconditioned_area = convert_units(unconditioned_area, 'm^2', 'ft^2')
391
+ feature_report.program.unconditioned_area_sqft = convert_units(unconditioned_area, 'm^2', 'ft^2')
362
392
 
363
393
  # footprint_area
364
- feature_report.program.footprint_area = convert_units(floor_area, 'm^2', 'ft^2')
394
+ feature_report.program.footprint_area_sqft = convert_units(floor_area, 'm^2', 'ft^2')
365
395
 
366
396
  # maximum_number_of_stories
367
397
  number_of_stories = building.standardsNumberOfStories.get if building.standardsNumberOfStories.is_initialized
@@ -371,7 +401,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
371
401
  # maximum_roof_height
372
402
  floor_to_floor_height = building.nominalFloortoFloorHeight.to_f
373
403
  maximum_roof_height = number_of_stories * floor_to_floor_height
374
- feature_report.program.maximum_roof_height = maximum_roof_height
404
+ feature_report.program.maximum_roof_height_ft = maximum_roof_height
375
405
 
376
406
  # maximum_number_of_stories_above_ground
377
407
  number_of_stories_above_ground = building.standardsNumberOfAboveGroundStories.get if building.standardsNumberOfAboveGroundStories.is_initialized
@@ -432,36 +462,36 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
432
462
  ## window_area
433
463
  # north_window_area
434
464
  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
435
- feature_report.program.window_area[:north_window_area] = convert_units(north_window_area, 'm^2', 'ft^2')
465
+ feature_report.program.window_area_sqft[:north_window_area_sqft] = convert_units(north_window_area, 'm^2', 'ft^2')
436
466
  # south_window_area
437
467
  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
438
- feature_report.program.window_area[:south_window_area] = convert_units(south_window_area, 'm^2', 'ft^2')
468
+ feature_report.program.window_area_sqft[:south_window_area_sqft] = convert_units(south_window_area, 'm^2', 'ft^2')
439
469
  # east_window_area
440
470
  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
441
- feature_report.program.window_area[:east_window_area] = convert_units(east_window_area, 'm^2', 'ft^2')
471
+ feature_report.program.window_area_sqft[:east_window_area_sqft] = convert_units(east_window_area, 'm^2', 'ft^2')
442
472
  # west_window_area
443
473
  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
444
- feature_report.program.window_area[:west_window_area] = convert_units(west_window_area, 'm^2', 'ft^2')
474
+ feature_report.program.window_area_sqft[:west_window_area_sqft] = convert_units(west_window_area, 'm^2', 'ft^2')
445
475
  # total_window_area
446
476
  total_window_area = north_window_area + south_window_area + east_window_area + west_window_area
447
- feature_report.program.window_area[:total_window_area] = convert_units(total_window_area, 'm^2', 'ft^2')
477
+ feature_report.program.window_area_sqft[:total_window_area_sqft] = convert_units(total_window_area, 'm^2', 'ft^2')
448
478
 
449
479
  ## wall_area
450
480
  # north_wall_area
451
481
  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
452
- feature_report.program.wall_area[:north_wall_area] = convert_units(north_wall_area, 'm^2', 'ft^2')
482
+ feature_report.program.wall_area_sqft[:north_wall_area_sqft] = convert_units(north_wall_area, 'm^2', 'ft^2')
453
483
  # south_wall_area
454
484
  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
455
- feature_report.program.wall_area[:south_wall_area] = convert_units(south_wall_area, 'm^2', 'ft^2')
485
+ feature_report.program.wall_area_sqft[:south_wall_area_sqft] = convert_units(south_wall_area, 'm^2', 'ft^2')
456
486
  # east_wall_area
457
487
  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
458
- feature_report.program.wall_area[:east_wall_area] = convert_units(east_wall_area, 'm^2', 'ft^2')
488
+ feature_report.program.wall_area_sqft[:east_wall_area_sqft] = convert_units(east_wall_area, 'm^2', 'ft^2')
459
489
  # west_wall_area
460
490
  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
461
- feature_report.program.wall_area[:west_wall_area] = convert_units(west_wall_area, 'm^2', 'ft^2')
491
+ feature_report.program.wall_area_sqft[:west_wall_area_sqft] = convert_units(west_wall_area, 'm^2', 'ft^2')
462
492
  # total_wall_area
463
493
  total_wall_area = north_wall_area + south_wall_area + east_wall_area + west_wall_area
464
- feature_report.program.wall_area[:total_wall_area] = convert_units(total_wall_area, 'm^2', 'ft^2')
494
+ feature_report.program.wall_area_sqft[:total_wall_area_sqft] = convert_units(total_wall_area, 'm^2', 'ft^2')
465
495
 
466
496
  # total_roof_area
467
497
  total_roof_area = 0.0
@@ -470,12 +500,28 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
470
500
  total_roof_area += surface.netArea
471
501
  end
472
502
  end
473
- feature_report.program.roof_area[:total_roof_area] = convert_units(total_roof_area, 'm^2', 'ft^2')
503
+
504
+ total_roof_area_sqft = convert_units(total_roof_area, 'm^2', 'ft^2')
505
+ feature_report.program.roof_area_sqft[:total_roof_area_sqft] = total_roof_area_sqft
506
+
507
+ # available_roof_area_sqft
508
+ # RK: a more robust method should be implemented to find the available_roof_area
509
+ # assign available roof area to be a percentage of the total roof area
510
+
511
+ if building_types[0][:building_type].include? 'Single-Family Detached'
512
+ feature_report.program.roof_area_sqft[:available_roof_area_sqft] = 0.45 * total_roof_area_sqft
513
+ else
514
+ feature_report.program.roof_area_sqft[:available_roof_area_sqft] = 0.75 * total_roof_area_sqft
515
+ end
516
+
517
+ # RK: Temporary solution: assign available roof area to be equal to total roof area
518
+ #feature_report.program.roof_area_sqft[:available_roof_area_sqft] = total_roof_area_sqft
519
+
474
520
 
475
521
  # orientation
476
522
  # RK: a more robust method should be implemented to find orientation(finding main axis of the building using aspect ratio)
477
523
  building_rotation = model.getBuilding.northAxis
478
- feature_report.program.orientation = building_rotation
524
+ feature_report.program.orientation_deg = building_rotation
479
525
 
480
526
  # aspect_ratio
481
527
  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)'")
@@ -486,7 +532,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
486
532
 
487
533
  # total_construction_cost
488
534
  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'")
489
- feature_report.program.total_construction_cost = total_construction_cost
535
+ feature_report.program.total_construction_cost_dollar = total_construction_cost
490
536
 
491
537
  # packaged thermal storage capacities by cooling coil
492
538
  ptes_keys = sql_file.availableKeyValues('RUN Period 1', 'Zone Timestep', 'Cooling Coil Ice Thermal Storage End Fraction')
@@ -504,7 +550,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
504
550
  runner.registerWarning('Query ptes_size.get failed')
505
551
  end
506
552
  end
507
- feature_report.thermal_storage.ptes_size = ptes_size
553
+ feature_report.thermal_storage.ptes_size_kwh = ptes_size
508
554
 
509
555
  # get the central tank thermal storage capacity
510
556
  its_size = nil
@@ -519,7 +565,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
519
565
  runner.registerWarning('Query its_size.get failed')
520
566
  end
521
567
  end
522
- feature_report.thermal_storage.its_size = its_size
568
+ feature_report.thermal_storage.its_size_kwh = its_size
523
569
 
524
570
  ############################################################################
525
571
  ##
@@ -550,78 +596,148 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
550
596
 
551
597
  # total_site_energy
552
598
  total_site_energy = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Site and Source Energy' AND RowName='Total Site Energy' AND ColumnName='Total Energy'")
553
- feature_report.reporting_periods[0].total_site_energy = convert_units(total_site_energy, 'GJ', 'kBtu')
599
+ feature_report.reporting_periods[0].total_site_energy_kwh = convert_units(total_site_energy, 'GJ', 'kWh')
554
600
 
555
601
  # total_source_energy
556
602
  total_source_energy = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Site and Source Energy' AND RowName='Total Source Energy' AND ColumnName='Total Energy'")
557
- feature_report.reporting_periods[0].total_source_energy = convert_units(total_source_energy, 'GJ', 'kBtu')
603
+ feature_report.reporting_periods[0].total_source_energy_kwh = convert_units(total_source_energy, 'GJ', 'kWh')
604
+
605
+ # EUI is only valid with a full year of energy data
606
+ if begin_month == 1 && begin_day_of_month == 1 && end_month == 12 && end_day_of_month == 31
607
+ # calculate site EUI
608
+ site_EUI_kwh_per_m2 = feature_report.reporting_periods[0].total_site_energy_kwh / floor_area
609
+ site_EUI_kbtu_per_ft2 = convert_units(total_site_energy, 'GJ', 'kBtu') / feature_report.program.floor_area_sqft
610
+ # add site EUI to feature report
611
+ feature_report.reporting_periods[0].site_EUI_kwh_per_m2 = site_EUI_kwh_per_m2
612
+ feature_report.reporting_periods[0].site_EUI_kbtu_per_ft2 = site_EUI_kbtu_per_ft2
613
+ # calculate source EUI
614
+ source_EUI_kwh_per_m2 = feature_report.reporting_periods[0].total_source_energy_kwh / floor_area
615
+ source_EUI_kbtu_per_ft2 = convert_units(total_source_energy, 'GJ', 'kBtu') / feature_report.program.floor_area_sqft
616
+ # add source EUI to feature report
617
+ feature_report.reporting_periods[0].source_EUI_kwh_per_m2 = source_EUI_kwh_per_m2
618
+ feature_report.reporting_periods[0].source_EUI_kbtu_per_ft2 = source_EUI_kbtu_per_ft2
619
+ end
558
620
 
559
621
  # net_site_energy
560
622
  net_site_energy = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Site and Source Energy' AND RowName='Net Site Energy' AND ColumnName='Total Energy'")
561
- feature_report.reporting_periods[0].net_site_energy = convert_units(net_site_energy, 'GJ', 'kBtu')
623
+ feature_report.reporting_periods[0].net_site_energy_kwh = convert_units(net_site_energy, 'GJ', 'kWh')
562
624
 
563
625
  # net_source_energy
564
626
  net_source_energy = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Site and Source Energy' AND RowName='Net Source Energy' AND ColumnName='Total Energy'")
565
- feature_report.reporting_periods[0].net_source_energy = convert_units(net_source_energy, 'GJ', 'kBtu')
627
+ feature_report.reporting_periods[0].net_source_energy_kwh = convert_units(net_source_energy, 'GJ', 'kWh')
566
628
 
567
629
  # electricity
568
630
  electricity = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='End Uses' AND RowName='Total End Uses' AND ColumnName='Electricity'")
569
- feature_report.reporting_periods[0].electricity = convert_units(electricity, 'GJ', 'kBtu')
631
+ feature_report.reporting_periods[0].electricity_kwh = convert_units(electricity, 'GJ', 'kWh')
570
632
 
571
633
  # natural_gas
572
634
  natural_gas = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='End Uses' AND RowName='Total End Uses' AND ColumnName='Natural Gas'")
573
- feature_report.reporting_periods[0].natural_gas = convert_units(natural_gas, 'GJ', 'kBtu')
635
+ feature_report.reporting_periods[0].natural_gas_kwh = convert_units(natural_gas, 'GJ', 'kWh')
636
+
637
+ # propane
638
+ propane = sql_query(runner, sql_file, 'EnergyMeters', "TableName='Annual and Peak Values - Other' AND RowName='Propane:Facility' AND ColumnName='Annual Value'")
639
+ feature_report.reporting_periods[0].propane_kwh = 0.0
640
+ feature_report.reporting_periods[0].propane_kwh = convert_units(propane, 'GJ', 'kWh') unless propane.nil?
574
641
 
575
- # additional_fuel
642
+ # fuel_oil
643
+ fuel_oil = sql_query(runner, sql_file, 'EnergyMeters', "TableName='Annual and Peak Values - Other' AND RowName='FuelOil#2:Facility' AND ColumnName='Annual Value'")
644
+ feature_report.reporting_periods[0].fuel_oil_kwh = 0.0
645
+ feature_report.reporting_periods[0].fuel_oil_kwh = convert_units(fuel_oil, 'GJ', 'kWh') unless fuel_oil.nil?
646
+
647
+ # other_fuels
576
648
  additional_fuel = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='End Uses' AND RowName='Total End Uses' AND ColumnName='Additional Fuel'")
577
- feature_report.reporting_periods[0].additional_fuel = convert_units(additional_fuel, 'GJ', 'kBtu')
649
+ # ensure additional fuel is not nil
650
+ feature_report.reporting_periods[0].other_fuels_kwh = 0.0
651
+ feature_report.reporting_periods[0].other_fuels_kwh = convert_units(additional_fuel, 'GJ', 'kWh') unless additional_fuel.nil?
652
+ feature_report.reporting_periods[0].other_fuels_kwh -= feature_report.reporting_periods[0].propane_kwh
653
+ feature_report.reporting_periods[0].other_fuels_kwh -= feature_report.reporting_periods[0].fuel_oil_kwh
578
654
 
579
655
  # district_cooling
580
656
  district_cooling = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='End Uses' AND RowName='Total End Uses' AND ColumnName='District Cooling'")
581
- feature_report.reporting_periods[0].district_cooling = convert_units(district_cooling, 'GJ', 'kBtu')
657
+ feature_report.reporting_periods[0].district_cooling_kwh = convert_units(district_cooling, 'GJ', 'kWh')
658
+ building_types.each do |i|
659
+ feature_report.reporting_periods[0].district_cooling_kwh = 0.0 if i[:building_type].include?('Single-Family Detached')
660
+ end
582
661
 
583
662
  # district_heating
584
663
  district_heating = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='End Uses' AND RowName='Total End Uses' AND ColumnName='District Heating'")
585
- feature_report.reporting_periods[0].district_heating = convert_units(district_heating, 'GJ', 'kBtu')
664
+ feature_report.reporting_periods[0].district_heating_kwh = convert_units(district_heating, 'GJ', 'kWh')
665
+ building_types.each do |i|
666
+ feature_report.reporting_periods[0].district_heating_kwh = 0.0 if i[:building_type].include?('Single-Family Detached')
667
+ end
586
668
 
587
669
  # water
588
670
  water = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='End Uses' AND RowName='Total End Uses' AND ColumnName='Water'")
589
671
  # feature_report.reporting_periods[0].water = convert_units(water, 'm3', 'ft3')
590
- feature_report.reporting_periods[0].water = water
672
+ feature_report.reporting_periods[0].water_qbft = water
591
673
 
592
674
  # electricity_produced
593
675
  electricity_produced = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Electric Loads Satisfied' AND RowName='Total On-Site and Utility Electric Sources' AND ColumnName='Electricity'")
594
- feature_report.reporting_periods[0].electricity_produced = convert_units(electricity_produced, 'GJ', 'kBtu')
676
+ feature_report.reporting_periods[0].electricity_produced_kwh = convert_units(electricity_produced, 'GJ', 'kWh')
595
677
 
596
678
  ## end_uses
597
679
 
598
680
  # get fuel type as listed in the sql file
599
- fuel_type = ['Electricity', 'Natural Gas', 'Additional Fuel', 'District Cooling', 'District Heating', 'Water']
681
+ fueltypes = fuel_types.values
682
+ fueltypes.delete('Propane')
683
+ fueltypes.delete('Fuel Oil #2')
600
684
 
601
685
  # get enduses as listed in the sql file
602
- enduses = ['Heating', 'Cooling', 'Interior Lighting', 'Exterior Lighting', 'Interior Equipment', 'Exterior Equipment', 'Fans', 'Pumps',
603
- 'Heat Rejection', 'Humidification', 'Heat Recovery', 'Water Systems', 'Refrigeration', 'Generators']
686
+ enduses = end_uses.values
687
+ enduses.delete('Facility')
688
+
689
+ # propane / fuel_oil
690
+ ['Propane', 'Fuel Oil #2'].each do |ft|
691
+ end_uses.keys.each do |eu|
692
+ next if eu == 'Facility'
693
+
694
+ sql_r = sql_query(runner, sql_file, 'EnergyMeters', "TableName='Annual and Peak Values - Other' AND RowName='#{eu}:#{ft.tr(' ', '')}' AND ColumnName='Annual Value'")
695
+
696
+ # report each query in its corresponding feature report obeject
697
+ x = ft.tr(' ', '_').downcase
698
+ x = x.gsub('_#2', '')
699
+ x_u = x + '_kwh'
700
+ m = feature_report.reporting_periods[0].end_uses.send(x_u)
701
+
702
+ y = end_uses[eu].tr(' ', '_').downcase
703
+ if sql_r.nil?
704
+ sql_r = 0.0
705
+ end
706
+ m.send("#{y}=", convert_units(sql_r, 'GJ', 'kWh'))
707
+ end
708
+ end
604
709
 
605
710
  # loop through fuel types and enduses to fill in sql_query method
606
- fuel_type.each do |ft|
711
+ fueltypes.each do |ft|
607
712
  enduses.each do |eu|
608
713
  sql_r = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='End Uses' AND RowName='#{eu}' AND ColumnName='#{ft}'")
609
714
 
610
715
  # report each query in its corresponding feature report obeject
611
- if ft.include? ' '
612
- x = ft.tr(' ', '_').downcase
613
- m = feature_report.reporting_periods[0].end_uses.send(x)
716
+ x = ft.tr(' ', '_').downcase
717
+ if x.include? 'water'
718
+ x_u = x + '_qbft'
614
719
  else
615
- m = feature_report.reporting_periods[0].end_uses.send(ft.downcase)
616
-
720
+ x_u = x + '_kwh'
721
+ end
722
+ if x_u == 'additional_fuel_kwh'
723
+ x_u = 'other_fuels_kwh'
617
724
  end
725
+ m = feature_report.reporting_periods[0].end_uses.send(x_u)
618
726
 
619
- if eu.include? ' '
620
- y = eu.tr(' ', '_').downcase
621
- m.send("#{y}=", convert_units(sql_r, 'GJ', 'kBtu'))
622
- else
623
- m.send("#{eu.downcase}=", convert_units(sql_r, 'GJ', 'kBtu'))
727
+ y = eu.tr(' ', '_').downcase
728
+ # ensure not nil so the equations below don't error out
729
+ if sql_r.nil?
730
+ sql_r = 0.0
731
+ end
732
+ sql_r = convert_units(sql_r, 'GJ', 'kWh')
733
+ if x_u == 'other_fuels_kwh'
734
+ sql_r -= feature_report.reporting_periods[0].end_uses.propane_kwh.send(y)
735
+ sql_r -= feature_report.reporting_periods[0].end_uses.fuel_oil_kwh.send(y)
736
+ end
737
+ building_types.each do |i|
738
+ sql_r = 0.0 if i[:building_type].include?('Single-Family Detached') && x_u.include?('district')
624
739
  end
740
+ m.send("#{y}=", sql_r)
625
741
  end
626
742
  end
627
743
 
@@ -629,20 +745,20 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
629
745
  ## electricity_produced
630
746
  # photovoltaic
631
747
  photovoltaic_power = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Electric Loads Satisfied' AND RowName='Photovoltaic Power' AND ColumnName='Electricity'")
632
- feature_report.reporting_periods[0].energy_production[:electricity_produced][:photovoltaic] = convert_units(photovoltaic_power, 'GJ', 'kBtu')
748
+ feature_report.reporting_periods[0].energy_production_kwh[:electricity_produced][:photovoltaic] = convert_units(photovoltaic_power, 'GJ', 'kWh')
633
749
 
634
750
  ## Total utility cost
635
751
  total_utility_cost = sql_query(runner, sql_file, 'Economics Results Summary Report', "TableName='Annual Cost' AND RowName='Cost' AND ColumnName='Total'")
636
- feature_report.reporting_periods[0].total_utility_cost = total_utility_cost
752
+ feature_report.reporting_periods[0].total_utility_cost_dollar = total_utility_cost
637
753
 
638
754
  ## Utility Costs
639
755
  # electricity utility cost
640
756
  elec_utility_cost = sql_query(runner, sql_file, 'Economics Results Summary Report', "TableName='Annual Cost' AND RowName='Cost' AND ColumnName='Electric'")
641
- feature_report.reporting_periods[0].utility_costs[0][:fuel_type] = 'Electricity'
642
- feature_report.reporting_periods[0].utility_costs[0][:total_cost] = elec_utility_cost
757
+ feature_report.reporting_periods[0].utility_costs_dollar[0][:fuel_type] = 'Electricity'
758
+ feature_report.reporting_periods[0].utility_costs_dollar[0][:total_cost] = elec_utility_cost
643
759
  # gas utility cost
644
760
  gas_utility_cost = sql_query(runner, sql_file, 'Economics Results Summary Report', "TableName='Annual Cost' AND RowName='Cost' AND ColumnName='Gas'")
645
- feature_report.reporting_periods[0].utility_costs << { fuel_type: 'Natural Gas', total_cost: gas_utility_cost }
761
+ feature_report.reporting_periods[0].utility_costs_dollar << { fuel_type: 'Natural Gas', total_cost: gas_utility_cost }
646
762
 
647
763
  ## comfort_result
648
764
  # time_setpoint_not_met_during_occupied_cooling
@@ -680,6 +796,9 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
680
796
  'Electricity:Facility',
681
797
  'ElectricityProduced:Facility',
682
798
  'Gas:Facility',
799
+ 'Propane:Facility',
800
+ 'FuelOil#2:Facility',
801
+ 'OtherFuels:Facility',
683
802
  'Cooling:Electricity',
684
803
  'Heating:Electricity',
685
804
  'InteriorLights:Electricity',
@@ -693,6 +812,18 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
693
812
  'Heating:Gas',
694
813
  'WaterSystems:Gas',
695
814
  'InteriorEquipment:Gas',
815
+ 'HeatRejection:Propane',
816
+ 'Heating:Propane',
817
+ 'WaterSystems:Propane',
818
+ 'InteriorEquipment:Propane',
819
+ 'HeatRejection:FuelOil#2',
820
+ 'Heating:FuelOil#2',
821
+ 'WaterSystems:FuelOil#2',
822
+ 'InteriorEquipment:FuelOil#2',
823
+ 'HeatRejection:OtherFuels',
824
+ 'Heating:OtherFuels',
825
+ 'WaterSystems:OtherFuels',
826
+ 'InteriorEquipment:OtherFuels',
696
827
  'DistrictCooling:Facility',
697
828
  'DistrictHeating:Facility',
698
829
  'District Cooling Chilled Water Rate',
@@ -757,7 +888,11 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
757
888
  runner.registerInfo("TIMESERIES: #{timeseries_name}")
758
889
 
759
890
  # get all the key values that this timeseries can be reported for (e.g. if PMV is requested for each zone)
760
- key_values = sql_file.availableKeyValues('RUN PERIOD 1', 'Zone Timestep', timeseries_name)
891
+ if timeseries_name.include?('OtherFuels')
892
+ key_values = sql_file.availableKeyValues('RUN PERIOD 1', 'Zone Timestep', timeseries_name.upcase)
893
+ else
894
+ key_values = sql_file.availableKeyValues('RUN PERIOD 1', 'Zone Timestep', timeseries_name)
895
+ end
761
896
  runner.registerInfo("KEY VALUES: #{key_values}")
762
897
  if key_values.empty?
763
898
  key_values = ['']
@@ -801,7 +936,11 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
801
936
  # final_timeseries_names << new_timeseries_name
802
937
 
803
938
  # get the actual timeseries
804
- ts = sql_file.timeSeries(ann_env_pd.to_s, reporting_frequency.to_s, timeseries_name, key_value)
939
+ if timeseries_name.include?('OtherFuels')
940
+ ts = sql_file.timeSeries(ann_env_pd.to_s, reporting_frequency.to_s, timeseries_name.upcase, key_value)
941
+ else
942
+ ts = sql_file.timeSeries(ann_env_pd.to_s, reporting_frequency.to_s, timeseries_name, key_value)
943
+ end
805
944
 
806
945
  if n.nil?
807
946
  # first timeseries should always be set
@@ -816,10 +955,15 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
816
955
  values[key_cnt] = Array.new(n, 0)
817
956
  end
818
957
 
958
+ # residential considerations
959
+ building_types.each do |i|
960
+ values[key_cnt] = Array.new(n, 0) if ['DistrictCooling:Facility', 'DistrictHeating:Facility'].include?(timeseries_name) && i[:building_type].include?('Single-Family Detached')
961
+ end
962
+
819
963
  # unit conversion
820
964
  old_unit = ts.get.units if ts.is_initialized
821
965
 
822
- if timeseries_name.include? 'Gas'
966
+ if timeseries_name.include?('Gas') || timeseries_name.include?('Propane') || timeseries_name.include?('FuelOil#2') || timeseries_name.include?('OtherFuels')
823
967
  new_unit = 'kBtu'
824
968
  else
825
969
  new_unit = case old_unit.to_s