urbanopt-reporting 0.6.2 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/nightly_build.yml +1 -1
- data/CHANGELOG.md +9 -0
- data/Gemfile +5 -5
- data/lib/measures/default_feature_reports/measure.rb +111 -24
- data/lib/urbanopt/reporting/default_reports/distributed_generation.rb +1 -1
- data/lib/urbanopt/reporting/default_reports/feature_report.rb +5 -1
- data/lib/urbanopt/reporting/default_reports/logger.rb +2 -0
- data/lib/urbanopt/reporting/default_reports/qaqc_flags.rb +182 -0
- data/lib/urbanopt/reporting/default_reports/scenario_power_distribution_cost.rb +212 -0
- data/lib/urbanopt/reporting/default_reports/scenario_report.rb +34 -15
- data/lib/urbanopt/reporting/default_reports/schema/scenario_schema.json +372 -31
- data/lib/urbanopt/reporting/version.rb +1 -1
- data/urbanopt-reporting-gem.gemspec +1 -1
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 186e2233b38a2f167fadd907eb6d768a589ca55dfc0a11e238b363bbc9574c27
|
4
|
+
data.tar.gz: 5cdb0f89a17ea078ef7ed61ed5710892ae956620a5370fe140fd4c8107ab73e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2bce9e36d7098ceb88b559d01b4e2eeeb5a30b78c0cacfd476a9501592df3b65b2d9807c45203fb3b2bccb53b3e8334e35acd362f5c848ac089635ce3f9ff932
|
7
|
+
data.tar.gz: 218468f4c8beb0b2dc4c4afa7ef4b7e05410d42bf7898236e58de93048f32c1b3be290a47260bd7d457811821562223e3fbd49845cb77334c5a7e3a9a256bdea
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
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
|
+
|
3
12
|
## Version 0.6.2
|
4
13
|
Date Range: 06/28/22 - 08/17/22
|
5
14
|
|
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
|
-
|
16
|
-
elsif allow_local
|
17
|
-
|
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
|
@@ -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
|
-
|
256
|
-
|
257
|
-
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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)}"
|
@@ -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
|