urbanopt-reporting 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 88fd3280248540278799a2b19f5d970ad199bf75acab0efe08bd3c4c11d7ec75
4
- data.tar.gz: 32acb1d1523bcbd7bbcf86c8eeec200f4c03bd86ee12ccefd4f936888a3bdb4b
3
+ metadata.gz: 186e2233b38a2f167fadd907eb6d768a589ca55dfc0a11e238b363bbc9574c27
4
+ data.tar.gz: 5cdb0f89a17ea078ef7ed61ed5710892ae956620a5370fe140fd4c8107ab73e8
5
5
  SHA512:
6
- metadata.gz: 5520b1958d1037868b5daf041d618bf0be93673235bf65d21ccb8e7f5354ea52ac12e1b4b0d39bb9f6dcf09c6f648c8eeb53136365162bfd0f31858f826a9822
7
- data.tar.gz: f0b2ddc2128321e99b3590924db5b2ac29c7deb9f31f326f2639ff9efcaf44aa86e223e1b56801ba24e05333e38d5cd4be80983f48d997e61f2451f1617a6ee9
6
+ metadata.gz: 2bce9e36d7098ceb88b559d01b4e2eeeb5a30b78c0cacfd476a9501592df3b65b2d9807c45203fb3b2bccb53b3e8334e35acd362f5c848ac089635ce3f9ff932
7
+ data.tar.gz: 218468f4c8beb0b2dc4c4afa7ef4b7e05410d42bf7898236e58de93048f32c1b3be290a47260bd7d457811821562223e3fbd49845cb77334c5a7e3a9a256bdea
@@ -0,0 +1,41 @@
1
+ name: nightly_build
2
+
3
+ on:
4
+ # push:
5
+ schedule:
6
+ # https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#schedule
7
+ # 5 am UTC (11pm MDT the day before) every weekday night in MDT
8
+ - cron: '22 5 * * 2-6'
9
+
10
+ # Cancels an existing job (of the same workflow) if it is still running
11
+ # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#example-only-cancel-in-progress-jobs-or-runs-for-the-current-workflow
12
+ # concurrency:
13
+ # group: ${{ github.workflow }}-${{ github.ref }}
14
+ # cancel-in-progress: true
15
+
16
+ env:
17
+ # This env var should enforce develop branch of all dependencies
18
+ # FAVOR_LOCAL_GEMS: true
19
+ GEM_DEVELOPER_KEY: ${{ secrets.GEM_DEVELOPER_KEY }}
20
+
21
+ jobs:
22
+ weeknight-tests:
23
+ # Pinned to `ubuntu-20.04`. When ubuntu-latest adopts 22.04 it would break for us since 22 only supports Ruby 3.1
24
+ # https://github.com/ruby/setup-ruby#supported-platforms
25
+ runs-on: ubuntu-20.04
26
+ container:
27
+ image: docker://nrel/openstudio:3.4.0
28
+ steps:
29
+ - name: Checkout code
30
+ uses: actions/checkout@v3
31
+ - name: Update gems
32
+ run: |
33
+ bundle update
34
+ - name: Run Rspec
35
+ run: bundle exec rspec
36
+ # coveralls action docs: https://github.com/marketplace/actions/coveralls-github-action
37
+ - name: Coveralls
38
+ uses: coverallsapp/github-action@master
39
+ with:
40
+ github-token: ${{ secrets.GITHUB_TOKEN }}
41
+ path-to-lcov: "./coverage/lcov/urbanopt-reporting-gem.lcov"
data/CHANGELOG.md CHANGED
@@ -1,12 +1,27 @@
1
1
  # URBANopt Reporting Gem
2
2
 
3
+ ## Version 0.7.0
4
+ Date Range: 08/18/22 - 12/12/22
5
+
6
+ - Update Dependencies for OpenStudio 3.5.0
7
+ - Fixed [#106]( https://github.com/urbanopt/urbanopt-reporting-gem/issues/106 ), Update UO reporting schema to include DISCO outputs
8
+ - Fixed [#107]( https://github.com/urbanopt/urbanopt-reporting-gem/issues/107 ), QAQC reporting rollup in feature report and scenario report
9
+ - Fixed [#127]( https://github.com/urbanopt/urbanopt-reporting-gem/issues/127 ), Clean up log output to stdout
10
+
11
+
12
+ ## Version 0.6.2
13
+ Date Range: 06/28/22 - 08/17/22
14
+
15
+ - Fixed [#118]( https://github.com/urbanopt/urbanopt-reporting-gem/pull/118 ), set up actions with coveralls
16
+ - Fixed [#119]( https://github.com/urbanopt/urbanopt-reporting-gem/pull/119 ), emissions bug fix
17
+
3
18
  ## Version 0.6.1
4
- Date Range: 05/10-22 - 06/27/22:
19
+ Date Range: 05/10-22 - 06/27/22
5
20
 
6
21
  - Fixed [#114]( https://github.com/urbanopt/urbanopt-reporting-gem/pull/114 ), added natural gas, propane and fuel oil emissions reporting
7
22
 
8
23
  ## Version 0.6.0
9
- Date Range: 11/22/21 - 05/09/22:
24
+ Date Range: 11/22/21 - 05/09/22
10
25
 
11
26
  - Fixed [#95]( https://github.com/urbanopt/urbanopt-reporting-gem/pull/95 ), adding additional PV fields to UO output reports
12
27
  - Fixed [#98]( https://github.com/urbanopt/urbanopt-reporting-gem/issues/98 ), add RNM results fields to schema
data/Gemfile CHANGED
@@ -11,8 +11,8 @@ gemspec
11
11
  # checkout the latest version (develop) from github.
12
12
  allow_local = ENV['FAVOR_LOCAL_GEMS']
13
13
 
14
- if allow_local && File.exist?('../openstudio-extension-gem')
15
- gem 'openstudio-extension', path: '../openstudio-extension-gem'
16
- elsif allow_local
17
- gem 'openstudio-extension', github: 'NREL/openstudio-extension-gem', branch: 'develop'
18
- end
14
+ # if allow_local && File.exist?('../openstudio-extension-gem')
15
+ # gem 'openstudio-extension', path: '../openstudio-extension-gem'
16
+ # elsif allow_local
17
+ # gem 'openstudio-extension', github: 'NREL/openstudio-extension-gem', branch: 'develop'
18
+ # end
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # URBANopt Reporting Gem
2
2
 
3
+ [![Coverage Status](https://coveralls.io/repos/github/urbanopt/urbanopt-reporting-gem/badge.svg?branch=develop)](https://coveralls.io/github/urbanopt/urbanopt-reporting-gem?branch=develop)
4
+
3
5
  The URBANopt<sup>&trade;</sup> Reporting Gem defines the URABNopt reports (Scenario and Feature reports). It also includes the default reporting measure which query results from the energyplus sql database and reports it in the Feature reports.
4
6
 
5
7
 
@@ -27,9 +29,9 @@ Or install it yourself as:
27
29
  Check out the repository and then execute:
28
30
 
29
31
  $ bundle install
30
- $ bundle update
32
+ $ bundle update
31
33
  $ bundle exec rake
32
-
34
+
33
35
  ## Releasing
34
36
 
35
37
  * Update CHANGELOG.md
@@ -41,12 +41,12 @@
41
41
  require 'urbanopt/reporting/default_reports'
42
42
  require 'csv'
43
43
  require 'benchmark'
44
+ require 'json'
44
45
  require 'logger'
45
46
 
46
- @@logger = Logger.new($stdout)
47
-
48
47
  # start the measure
49
48
  class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
49
+ @@logger = Logger.new($stdout)
50
50
  # human readable name
51
51
  def name
52
52
  return 'DefaultFeatureReports'
@@ -233,7 +233,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
233
233
  # result << OpenStudio::IdfObject.load("Output:Variable,*,Exterior Equipment:Electric Vehicles,#{reporting_frequency};").get
234
234
 
235
235
  ## add environmental factor outputs
236
- #result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,Output:EnvironmentalImpactFactors,#{reporting_frequency};").get
236
+ # result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,Output:EnvironmentalImpactFactors,#{reporting_frequency};").get
237
237
  # result << OpenStudio::IdfObject.load("Output:Variable,*,Environmental Impact Total N2O Emissions Carbon Equivalent Mass,#{reporting_frequency}; !- HVAC Sum [kg];").get
238
238
  # result << OpenStudio::IdfObject.load("Output:Variable,*,Environmental Impact Total CH4 Emissions Carbon Equivalent Mass,#{reporting_frequency}; !- HVAC Sum [kg];").get
239
239
  # result << OpenStudio::IdfObject.load("Output:Variable,*,Environmental Impact Total CO2 Emissions Carbon Equivalent Mass,#{reporting_frequency}; !- HVAC Sum [kg];").get
@@ -252,11 +252,9 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
252
252
  ev_timeseries_data = ['Exterior Equipment:Electric Vehicles']
253
253
 
254
254
  emissions_timeseries_data = ['Future_Annual_Electricity_Emissions', 'Future_Hourly_Electricity_Emissions',
255
- 'Historical_Annual_Electricity_Emissions', 'Historical_Hourly_Electricity_Emissions',
256
- 'Future_Annual_Electricity_Emissions_Intensity', 'Future_Hourly_Electricity_Emissions_Intensity',
257
- 'Historical_Annual_Electricity_Emissions_Intensity', 'Historical_Hourly_Electricity_Emissions_Intensity']
258
-
259
-
255
+ 'Historical_Annual_Electricity_Emissions', 'Historical_Hourly_Electricity_Emissions',
256
+ 'Future_Annual_Electricity_Emissions_Intensity', 'Future_Hourly_Electricity_Emissions_Intensity',
257
+ 'Historical_Annual_Electricity_Emissions_Intensity', 'Historical_Hourly_Electricity_Emissions_Intensity']
260
258
 
261
259
  timeseries_data += tes_timeseries_data
262
260
  timeseries_data += emissions_timeseries_data
@@ -291,6 +289,85 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
291
289
  return val
292
290
  end
293
291
 
292
+ def feature_qaqc_flags(runner)
293
+ # QAQC flags by category
294
+ qaqc_flags_hash = {} # Make a hash for count of flags of each category
295
+
296
+ runner.workflow.workflowSteps.each do |step| # Go through all the steps
297
+
298
+ if step.to_MeasureStep.is_initialized
299
+ measure_step = step.to_MeasureStep.get
300
+
301
+ measure_name = measure_step.measureDirName
302
+
303
+ if measure_step.name.is_initialized
304
+ measure_name = measure_step.name.get
305
+ end
306
+
307
+ if measure_name.include? 'qaqc'
308
+ puts "measure_name = #{measure_name}"
309
+ if measure_step.result.is_initialized
310
+ result = measure_step.result.get
311
+ puts " result = #{result}"
312
+
313
+ ## Adding quaqc_flags_list to check the step value name since units key is missing from the result
314
+ ## It does show in the out.osw but not in the runner.workflow.workflowSteps object
315
+ # use this list to define the flags you want to report
316
+ qaqc_flags_list = ['eui_reasonableness' , 'end_use_by_category',
317
+ 'mechanical_system_part_load_efficiency', 'simultaneous_heating_and_cooling',
318
+ 'internal_loads', 'schedules', 'envelope_r_value', 'domestic_hot_water',
319
+ 'mechanical_system_efficiency', 'supply_and_zone_air_temperature', 'total_qaqc_flags' ]
320
+
321
+ result.stepValues.each do |step_value|
322
+
323
+ #get name
324
+ name = step_value.name
325
+
326
+ if qaqc_flags_list.include? name
327
+
328
+ # get value
329
+ # check if value, double, int, or bool
330
+ value_type = step_value.variantType.valueDescription
331
+ if value_type == "Double"
332
+ value = step_value.valueAsDouble
333
+ elsif value_type == "Integer"
334
+ value = step_value.valueAsInteger
335
+ elsif value_type == "Boolean"
336
+ value = step_value.valueAsBoolean
337
+ elsif value_type == "String"
338
+ value = step_value.valueAsString
339
+ else
340
+ # catchall for unexpected value types
341
+ value = step_value.valueAsVariant.to_s
342
+ end
343
+
344
+ if qaqc_flags_hash[name]
345
+ qaqc_flags_hash[name] += value
346
+ else
347
+ qaqc_flags_hash[name] = value
348
+ end
349
+
350
+ end
351
+
352
+ end
353
+
354
+ puts "qaqc_flags_hash = #{qaqc_flags_hash}"
355
+
356
+ # Hack to put 'total_qaqc_flags' at the end of the hash
357
+ temp_hash_for_ordering = { 'total_qaqc_flags' => qaqc_flags_hash['total_qaqc_flags'] }
358
+ qaqc_flags_hash.delete('total_qaqc_flags')
359
+ qaqc_flags_hash['total_qaqc_flags'] = temp_hash_for_ordering['total_qaqc_flags']
360
+
361
+ end
362
+
363
+ end
364
+
365
+ end
366
+
367
+ end
368
+ return qaqc_flags_hash
369
+ end
370
+
294
371
  # unit conversion method
295
372
  def convert_units(value, from_units, to_units)
296
373
  if value.nil?
@@ -836,7 +913,6 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
836
913
 
837
914
  # electricity emissions
838
915
  begin
839
-
840
916
  # future_annual_emissions
841
917
  future_annual_emissions_ts = sql_file.timeSeries(ann_env_pd.to_s, reporting_frequency.to_s, 'Future_Annual_Electricity_Emissions', 'EMS')
842
918
  feature_report.reporting_periods[0].emissions[:future_annual_electricity_emissions_mt] = future_annual_emissions_ts.get.values.sum
@@ -868,11 +944,24 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
868
944
  # historical_hourly_emissions_intensity
869
945
  historical_hourly_emissions_intensity_ts = sql_file.timeSeries(ann_env_pd.to_s, reporting_frequency.to_s, 'Historical_Hourly_Electricity_Emissions_Intensity', 'EMS')
870
946
  feature_report.reporting_periods[0].emissions[:historical_hourly_electricity_emissions_intensity_kg_per_ft2] = historical_hourly_emissions_intensity_ts.get.values.sum
871
-
872
947
  rescue StandardError
873
948
  @@logger.info('Emissions are not reported for this feature')
874
949
  end
875
950
 
951
+ # add qaqc results to feature report
952
+ qaqc_flags_hash = feature_qaqc_flags(runner)
953
+ feature_report.qaqc_flags.eui_reasonableness = qaqc_flags_hash['eui_reasonableness']
954
+ feature_report.qaqc_flags.end_use_by_category = qaqc_flags_hash['end_use_by_category']
955
+ feature_report.qaqc_flags.mechanical_system_part_load_efficiency = qaqc_flags_hash['mechanical_system_part_load_efficiency']
956
+ feature_report.qaqc_flags.simultaneous_heating_and_cooling = qaqc_flags_hash['simultaneous_heating_and_cooling']
957
+ feature_report.qaqc_flags.internal_loads = qaqc_flags_hash['internal_loads']
958
+ feature_report.qaqc_flags.schedules = qaqc_flags_hash['schedules']
959
+ feature_report.qaqc_flags.envelope_r_value = qaqc_flags_hash['envelope_r_value']
960
+ feature_report.qaqc_flags.domestic_hot_water = qaqc_flags_hash['domestic_hot_water']
961
+ feature_report.qaqc_flags.mechanical_system_efficiency = qaqc_flags_hash['mechanical_system_efficiency']
962
+ feature_report.qaqc_flags.supply_and_zone_air_temperature = qaqc_flags_hash['supply_and_zone_air_temperature']
963
+ feature_report.qaqc_flags.total_qaqc_flags = qaqc_flags_hash['total_qaqc_flags']
964
+
876
965
  ##########################################################################################################################
877
966
  # set conversion variables
878
967
  conv_J_mwh = 1000000 * 60 * 60 # J to MWh (1000000J/MJ * 60hr/min * 60 min/sec)
@@ -888,7 +977,6 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
888
977
  fo1_val = 294.962046
889
978
  fo2_val = 294.962046
890
979
 
891
-
892
980
  ##########################################################################################################################
893
981
  ######################################## Reporting TImeseries Results FOR CSV File #######################################
894
982
 
@@ -948,7 +1036,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
948
1036
  'Historical_Hourly_Electricity_Emissions_Intensity',
949
1037
  'Natural_Gas_Emissions',
950
1038
  'Natural_Gas_Emissions_Intensity',
951
- 'Propane_Emissions',
1039
+ 'Propane_Emissions',
952
1040
  'Propane_Emissions_Intensity',
953
1041
  'FuelOilNo2_Emissions',
954
1042
  'FuelOilNo2_Emissions_Intensity',
@@ -980,7 +1068,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
980
1068
  runner.registerInfo("All timeseries: #{requested_timeseries_names}")
981
1069
 
982
1070
  # timeseries variables to keep to calculate power
983
- tsToKeep = ['Electricity:Facility', 'ElectricityProduced:Facility','Propane:Facility', 'NaturalGas:Facility', 'FuelOilNo2:Facility', 'FuelOilNo1:Facility']
1071
+ tsToKeep = ['Electricity:Facility', 'ElectricityProduced:Facility', 'Propane:Facility', 'NaturalGas:Facility', 'FuelOilNo2:Facility', 'FuelOilNo1:Facility']
984
1072
  tsToKeepIndexes = {}
985
1073
 
986
1074
  ### powerFactor ###
@@ -1145,7 +1233,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
1145
1233
  if timeseries_name == 'Natural_Gas_Emissions'
1146
1234
  newVals = Array.new(n, 0)
1147
1235
  (0..n - 1).each do |j|
1148
- newVals[j] = (nat_gas_val * (values[tsToKeepIndexes['NaturalGas:Facility']][j].to_f * conv_kbtu_J.to_f) / conv_J_mwh.to_f ) * conv_kg_mt.to_f
1236
+ newVals[j] = (nat_gas_val * (values[tsToKeepIndexes['NaturalGas:Facility']][j].to_f * conv_kbtu_J.to_f) / conv_J_mwh.to_f) * conv_kg_mt.to_f
1149
1237
  j += 1
1150
1238
  end
1151
1239
  new_unit = 'MT'
@@ -1158,7 +1246,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
1158
1246
  if timeseries_name == 'Propane_Emissions'
1159
1247
  newVals = Array.new(n, 0)
1160
1248
  (0..n - 1).each do |j|
1161
- newVals[j] = (lpg_val * (values[tsToKeepIndexes['Propane:Facility']][j].to_f * conv_kbtu_J.to_f) / conv_J_mwh.to_f ) * conv_kg_mt.to_f
1249
+ newVals[j] = (lpg_val * (values[tsToKeepIndexes['Propane:Facility']][j].to_f * conv_kbtu_J.to_f) / conv_J_mwh.to_f) * conv_kg_mt.to_f
1162
1250
  j += 1
1163
1251
  end
1164
1252
  new_unit = 'MT'
@@ -1171,7 +1259,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
1171
1259
  if timeseries_name == 'FuelOilNo2_Emissions'
1172
1260
  newVals = Array.new(n, 0)
1173
1261
  (0..n - 1).each do |j|
1174
- newVals[j] = (fo2_val * (values[tsToKeepIndexes['FuelOilNo2:Facility']][j].to_f * conv_kbtu_J.to_f) / conv_J_mwh.to_f ) * conv_kg_mt.to_f
1262
+ newVals[j] = (fo2_val * (values[tsToKeepIndexes['FuelOilNo2:Facility']][j].to_f * conv_kbtu_J.to_f) / conv_J_mwh.to_f) * conv_kg_mt.to_f
1175
1263
  j += 1
1176
1264
  end
1177
1265
  new_unit = 'MT'
@@ -1183,12 +1271,12 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
1183
1271
 
1184
1272
  ### calculate emissions intensity metric
1185
1273
  # get flr_area
1186
- flr_area = building.floorArea * 10.764 #change from m2 to ft2
1274
+ flr_area = building.floorArea * 10.764 # change from m2 to ft2
1187
1275
 
1188
1276
  if timeseries_name == 'Natural_Gas_Emissions_Intensity'
1189
1277
  newVals = Array.new(n, 0)
1190
1278
  (0..n - 1).each do |j|
1191
- newVals[j] = (((nat_gas_val * (values[tsToKeepIndexes['NaturalGas:Facility']][j].to_f * conv_kbtu_J.to_f) / conv_J_mwh.to_f ) * conv_kg_mt.to_f ) * 1000 / flr_area) # unit: kg/ft2 - changed mt to kg
1279
+ newVals[j] = (((nat_gas_val * (values[tsToKeepIndexes['NaturalGas:Facility']][j].to_f * conv_kbtu_J.to_f) / conv_J_mwh.to_f) * conv_kg_mt.to_f) * 1000 / flr_area) # unit: kg/ft2 - changed mt to kg
1192
1280
  j += 1
1193
1281
  end
1194
1282
  new_unit = 'KG/FT2'
@@ -1201,7 +1289,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
1201
1289
  if timeseries_name == 'Propane_Emissions_Intensity'
1202
1290
  newVals = Array.new(n, 0)
1203
1291
  (0..n - 1).each do |j|
1204
- newVals[j] = (((lpg_val * (values[tsToKeepIndexes['Propane:Facility']][j].to_f * conv_kbtu_J.to_f) / conv_J_mwh.to_f ) * conv_kg_mt.to_f ) * 1000 / flr_area) # unit: kg/ft2 - changed mt to kg
1292
+ newVals[j] = (((lpg_val * (values[tsToKeepIndexes['Propane:Facility']][j].to_f * conv_kbtu_J.to_f) / conv_J_mwh.to_f) * conv_kg_mt.to_f) * 1000 / flr_area) # unit: kg/ft2 - changed mt to kg
1205
1293
  j += 1
1206
1294
  end
1207
1295
  new_unit = 'KG/FT2'
@@ -1214,7 +1302,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
1214
1302
  if timeseries_name == 'FuelOilNo2_Emissions_Intensity'
1215
1303
  newVals = Array.new(n, 0)
1216
1304
  (0..n - 1).each do |j|
1217
- newVals[j] = (((fo2_val * (values[tsToKeepIndexes['FuelOilNo2:Facility']][j].to_f * conv_kbtu_J.to_f) / conv_J_mwh.to_f ) * conv_kg_mt.to_f ) * 1000 / flr_area) # unit: kg/ft2 - changed mt to kg
1305
+ newVals[j] = (((fo2_val * (values[tsToKeepIndexes['FuelOilNo2:Facility']][j].to_f * conv_kbtu_J.to_f) / conv_J_mwh.to_f) * conv_kg_mt.to_f) * 1000 / flr_area) # unit: kg/ft2 - changed mt to kg
1218
1306
  j += 1
1219
1307
  end
1220
1308
  new_unit = 'KG/FT2'
@@ -1280,8 +1368,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
1280
1368
  end
1281
1369
  end
1282
1370
  end
1283
- end
1284
-
1371
+ end
1285
1372
 
1286
1373
  # append units to headers
1287
1374
  new_timeseries_name += "(#{new_unit})"
@@ -1414,7 +1501,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
1414
1501
  end
1415
1502
  end
1416
1503
 
1417
- puts "values = #{values}"
1504
+ #puts "values = #{values}"
1418
1505
 
1419
1506
  # closing the sql file
1420
1507
  sql_file.close
@@ -1425,8 +1512,8 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
1425
1512
  feature_report.timeseries_csv.first_report_datetime = '0'
1426
1513
  feature_report.timeseries_csv.column_names = final_timeseries_names
1427
1514
 
1428
- ##### Save the 'default_feature_reports.json' file
1429
1515
 
1516
+ ##### Save the 'default_feature_reports.json' file
1430
1517
  feature_report_hash = feature_report.to_hash
1431
1518
 
1432
1519
  File.open('default_feature_reports.json', 'w') do |f|
@@ -210,7 +210,7 @@ module URBANopt
210
210
  ##
211
211
  # [parameters:]
212
212
  #
213
- # * +hash+ - _Hash_ - A hash containting key/value pairs for the distributed generation system attributes listed above.
213
+ # * +hash+ - _Hash_ - A hash containing key/value pairs for the distributed generation system attributes listed above.
214
214
  #
215
215
  def initialize(hash = {})
216
216
  hash.delete_if { |k, v| v.nil? }
@@ -63,7 +63,7 @@ module URBANopt
63
63
  # The DefaultPostProcessor reads these feature reports and aggregates them to create a ScenarioReport.
64
64
  ##
65
65
  class FeatureReport
66
- attr_accessor :id, :name, :directory_name, :feature_type, :timesteps_per_hour, :simulation_status,
66
+ attr_accessor :id, :name, :directory_name, :feature_type, :timesteps_per_hour, :simulation_status, :qaqc_flags,
67
67
  :timeseries_csv, :location, :program, :design_parameters, :construction_costs, :reporting_periods, :distributed_generation, :power_distribution, :thermal_storage # :nodoc:
68
68
 
69
69
  ##
@@ -82,6 +82,7 @@ module URBANopt
82
82
  @feature_type = hash[:feature_type]
83
83
  @timesteps_per_hour = hash[:timesteps_per_hour]
84
84
  @simulation_status = hash[:simulation_status]
85
+ @qaqc_flags = QAQC.new(hash[:qaqc_flags])
85
86
  @timeseries_csv = TimeseriesCSV.new(hash[:timeseries_csv])
86
87
  @timeseries_csv.run_dir_name(@directory_name)
87
88
  @location = Location.new(hash[:location])
@@ -124,6 +125,7 @@ module URBANopt
124
125
  hash[:distributed_generation] = {}
125
126
  hash[:power_distribution] = {}
126
127
  hash[:thermal_storage] = {}
128
+ hash[:qaqc_flags] = {}
127
129
  return hash
128
130
  end
129
131
 
@@ -227,6 +229,8 @@ module URBANopt
227
229
 
228
230
  result[:thermal_storage] = @thermal_storage.to_hash if @thermal_storage
229
231
 
232
+ result[:qaqc_flags] = @qaqc_flags.to_hash if @qaqc_flags
233
+
230
234
  # validate feature_report properties against schema
231
235
  if @@validator.validate(@@schema[:definitions][:FeatureReport][:properties], result).any?
232
236
  raise "feature_report properties does not match schema: #{@@validator.validate(@@schema[:definitions][:FeatureReport][:properties], result)}"
@@ -44,6 +44,8 @@ module URBANopt
44
44
  module Reporting
45
45
  module DefaultReports
46
46
  @@logger = Logger.new($stdout)
47
+
48
+ @@logger.level = Logger::WARN
47
49
  ##
48
50
  # Definining class variable "@@logger" to log errors, info and warning messages.
49
51
  def self.logger
@@ -0,0 +1,182 @@
1
+ # *********************************************************************************
2
+ # URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
3
+ # contributors. All rights reserved.
4
+
5
+ # Redistribution and use in source and binary forms, with or without modification,
6
+ # are permitted provided that the following conditions are met:
7
+
8
+ # Redistributions of source code must retain the above copyright notice, this list
9
+ # of conditions and the following disclaimer.
10
+
11
+ # Redistributions in binary form must reproduce the above copyright notice, this
12
+ # list of conditions and the following disclaimer in the documentation and/or other
13
+ # materials provided with the distribution.
14
+
15
+ # Neither the name of the copyright holder nor the names of its contributors may be
16
+ # used to endorse or promote products derived from this software without specific
17
+ # prior written permission.
18
+
19
+ # Redistribution of this software, without modification, must refer to the software
20
+ # by the same designation. Redistribution of a modified version of this software
21
+ # (i) may not refer to the modified version by the same designation, or by any
22
+ # confusingly similar designation, and (ii) must refer to the underlying software
23
+ # originally provided by Alliance as “URBANopt”. Except to comply with the foregoing,
24
+ # the term “URBANopt”, or any confusingly similar designation may not be used to
25
+ # refer to any modified version of this software or any modified version of the
26
+ # underlying software originally provided by Alliance without the prior written
27
+ # consent of Alliance.
28
+
29
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
30
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
31
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
32
+ # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33
+ # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
+ # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
36
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
37
+ # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
38
+ # OF THE POSSIBILITY OF SUCH DAMAGE.
39
+ # *********************************************************************************
40
+
41
+ require 'json'
42
+ require 'json-schema'
43
+
44
+ module URBANopt
45
+ module Reporting
46
+ module DefaultReports
47
+ ##
48
+ # QAQC flags for each feature
49
+ ##
50
+ class QAQC
51
+ ##
52
+ # _Hash_ - Hash of flags raised by QAQC measure for this feature during this reporting period
53
+ #
54
+ attr_accessor :eui_reasonableness,:end_use_by_category,:mechanical_system_part_load_efficiency,
55
+ :simultaneous_heating_and_cooling , :internal_loads , :schedules, :envelope_r_value,
56
+ :domestic_hot_water , :mechanical_system_efficiency , :supply_and_zone_air_temperature,
57
+ :total_qaqc_flags
58
+
59
+ ##
60
+ # QAQC class initialize quaqc attributes: +:eui_reasonableness,+:end_use_by_category,+:mechanical_system_part_load_efficiency,
61
+ # +:simultaneous_heating_and_cooling , +:internal_loads , +:schedules, +:envelope_r_value,
62
+ # +:domestic_hot_water , +:mechanical_system_efficiency , +:supply_and_zone_air_temperature, +:total_qaqc_flags
63
+ ##
64
+ # [parameters:]
65
+ #
66
+ # * +hash+ - _Hash_ - A hash containing qaqc attributes listed above.
67
+ #
68
+ def initialize(hash = {})
69
+ hash.delete_if { |k, v| v.nil? }
70
+ hash = defaults.merge(hash)
71
+
72
+ @eui_reasonableness = hash[:eui_reasonableness]
73
+ @end_use_by_category = hash[:end_use_by_category]
74
+ @mechanical_system_part_load_efficiency = hash[:mechanical_system_part_load_efficiency]
75
+ @simultaneous_heating_and_cooling = hash[:simultaneous_heating_and_cooling]
76
+ @supply_and_zone_air_temperature = hash[:supply_and_zone_air_temperature]
77
+ @internal_loads = hash[:internal_loads]
78
+ @schedules = hash[:schedules]
79
+ @envelope_r_value = hash[:envelope_r_value]
80
+ @domestic_hot_water = hash[:domestic_hot_water]
81
+ @mechanical_system_efficiency = hash[:mechanical_system_efficiency]
82
+ @total_qaqc_flags = hash[:total_qaqc_flags]
83
+
84
+
85
+ # initialize class variables @@validator and @@schema
86
+ @@validator ||= Validator.new
87
+ @@schema ||= @@validator.schema
88
+
89
+ end
90
+
91
+
92
+ ##
93
+ # Assigns default values if values do not exist.
94
+ ##
95
+ def defaults
96
+ hash = {}
97
+
98
+ hash[:eui_reasonableness] = nil
99
+ hash[:end_use_by_category] = nil
100
+ hash[:mechanical_system_part_load_efficiency] = nil
101
+ hash[:simultaneous_heating_and_cooling] = nil
102
+ hash[:supply_and_zone_air_temperature] = nil
103
+ hash[:internal_loads] = nil
104
+ hash[:schedules] = nil
105
+ hash[:envelope_r_value] = nil
106
+ hash[:domestic_hot_water] = nil
107
+ hash[:mechanical_system_efficiency] = nil
108
+ hash[:total_qaqc_flags] = nil
109
+
110
+
111
+ return hash
112
+ end
113
+ ##
114
+ # Convert to a Hash equivalent for JSON serialization
115
+ ##
116
+ def to_hash
117
+ result = {}
118
+
119
+ result[:eui_reasonableness] = @eui_reasonableness
120
+ result[:end_use_by_category] = @end_use_by_category
121
+ result[:mechanical_system_part_load_efficiency] = @mechanical_system_part_load_efficiency
122
+ result[:simultaneous_heating_and_cooling] = @simultaneous_heating_and_cooling
123
+ result[:supply_and_zone_air_temperature] = @supply_and_zone_air_temperature
124
+ result[:internal_loads] = @internal_loads
125
+ result[:schedules] = @schedules
126
+ result[:envelope_r_value] = @envelope_r_value
127
+ result[:domestic_hot_water] = @domestic_hot_water
128
+ result[:mechanical_system_efficiency] = @mechanical_system_efficiency
129
+ result[:total_qaqc_flags] = @total_qaqc_flags
130
+
131
+ # validate program properties against schema
132
+ if @@validator.validate(@@schema[:definitions][:qaqc_flags][:properties], result).any?
133
+ raise "qaqc properties does not match schema: #{@@validator.validate(@@schema[:definitions][:qaqc_flags][:properties], result)}"
134
+ end
135
+
136
+ return result
137
+
138
+ end
139
+
140
+ ##
141
+ # Adds up +existing_value+ and +new_values+ if not nill.
142
+ ##
143
+ # [parameters:]
144
+ # +existing_value+ - _Float_ - A value corresponding to a qaqc_flags attribute.
145
+ ##
146
+ # +new_value+ - _Float_ - A value corresponding to a qaqc_flags attribute.
147
+ ##
148
+ def add_values(existing_value, new_value) #:nodoc:
149
+ if existing_value && new_value
150
+ existing_value += new_value
151
+ elsif new_value
152
+ existing_value = new_value
153
+ end
154
+ return existing_value
155
+ end
156
+
157
+ ##
158
+ # Merges qaqc_flags objects to each other by summing up values.
159
+ ##
160
+ # [parameters:]
161
+ # +other+ - _QAQC_ - An object of Program class.
162
+ ##
163
+ def add_qaqc_flags(other)
164
+
165
+ @eui_reasonableness = add_values(@eui_reasonableness, other.eui_reasonableness)
166
+ @end_use_by_category = add_values(@end_use_by_category, other.end_use_by_category)
167
+ @mechanical_system_part_load_efficiency = add_values(@mechanical_system_part_load_efficiency, other.mechanical_system_part_load_efficiency)
168
+ @simultaneous_heating_and_cooling = add_values(@simultaneous_heating_and_cooling, other.simultaneous_heating_and_cooling)
169
+ @supply_and_zone_air_temperature = add_values(@supply_and_zone_air_temperature, other.supply_and_zone_air_temperature)
170
+ @internal_loads = add_values(@internal_loads, other.internal_loads)
171
+ @schedules = add_values(@schedules, other.schedules)
172
+ @envelope_r_value = add_values(@envelope_r_value, other.envelope_r_value)
173
+ @domestic_hot_water = add_values(@domestic_hot_water, other.domestic_hot_water)
174
+ @mechanical_system_efficiency = add_values(@mechanical_system_efficiency, other.mechanical_system_efficiency)
175
+ @total_qaqc_flags = add_values(@total_qaqc_flags, other.total_qaqc_flags)
176
+
177
+ end
178
+
179
+ end
180
+ end
181
+ end
182
+ end
@@ -222,7 +222,7 @@ module URBANopt
222
222
  result[:comfort_result] = comfort_result_hash if @comfort_result
223
223
 
224
224
  emissions_hash = @emissions if @emissions
225
- #emissions_hash.delete_if { |k, v| v.nil? }
225
+ emissions_hash.delete_if { |k, v| v.nil? }
226
226
  result[:emissions] = emissions_hash if @emissions
227
227
 
228
228
  # validates +reporting_period+ properties against schema for reporting period.