urbanopt-reporting 0.4.3 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +21 -1
  3. data/LICENSE.md +17 -17
  4. data/doc_templates/LICENSE.md +17 -17
  5. data/doc_templates/copyright_erb.txt +2 -2
  6. data/doc_templates/copyright_js.txt +2 -2
  7. data/doc_templates/copyright_ruby.txt +1 -1
  8. data/docs/package-lock.json +15720 -1410
  9. data/lib/measures/.rubocop.yml +4 -2
  10. data/lib/measures/default_feature_reports/measure.rb +242 -36
  11. data/lib/measures/export_modelica_loads/measure.rb +2 -1
  12. data/lib/measures/export_time_series_modelica/measure.rb +58 -59
  13. data/lib/measures/export_time_series_modelica/resources/os_lib_helper_methods.rb +3 -5
  14. data/lib/urbanopt/reporting/default_reports/construction_cost.rb +2 -1
  15. data/lib/urbanopt/reporting/default_reports/date.rb +2 -1
  16. data/lib/urbanopt/reporting/default_reports/distributed_generation.rb +24 -6
  17. data/lib/urbanopt/reporting/default_reports/end_use.rb +1 -1
  18. data/lib/urbanopt/reporting/default_reports/end_uses.rb +2 -1
  19. data/lib/urbanopt/reporting/default_reports/extension.rb +1 -1
  20. data/lib/urbanopt/reporting/default_reports/feature_report.rb +9 -8
  21. data/lib/urbanopt/reporting/default_reports/generator.rb +1 -2
  22. data/lib/urbanopt/reporting/default_reports/location.rb +2 -1
  23. data/lib/urbanopt/reporting/default_reports/logger.rb +2 -2
  24. data/lib/urbanopt/reporting/default_reports/power_distribution.rb +22 -6
  25. data/lib/urbanopt/reporting/default_reports/program.rb +2 -1
  26. data/lib/urbanopt/reporting/default_reports/reporting_period.rb +47 -7
  27. data/lib/urbanopt/reporting/default_reports/scenario_power_distribution.rb +148 -0
  28. data/lib/urbanopt/reporting/default_reports/scenario_report.rb +20 -14
  29. data/lib/urbanopt/reporting/default_reports/schema/scenario_csv_columns.txt +24 -0
  30. data/lib/urbanopt/reporting/default_reports/schema/scenario_schema.json +265 -6
  31. data/lib/urbanopt/reporting/default_reports/solar_pv.rb +42 -3
  32. data/lib/urbanopt/reporting/default_reports/storage.rb +1 -1
  33. data/lib/urbanopt/reporting/default_reports/thermal_storage.rb +1 -1
  34. data/lib/urbanopt/reporting/default_reports/timeseries_csv.rb +2 -1
  35. data/lib/urbanopt/reporting/default_reports/validator.rb +1 -1
  36. data/lib/urbanopt/reporting/default_reports/wind.rb +11 -2
  37. data/lib/urbanopt/reporting/default_reports.rb +1 -1
  38. data/lib/urbanopt/reporting/derived_extension.rb +1 -1
  39. data/lib/urbanopt/reporting/version.rb +2 -2
  40. data/lib/urbanopt/reporting.rb +1 -1
  41. data/urbanopt-reporting-gem.gemspec +3 -4
  42. metadata +16 -15
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, 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,
@@ -40,11 +40,10 @@
40
40
 
41
41
  require 'erb'
42
42
 
43
-
44
43
  # This measure is originally from https://github.com/urbanopt/DES_HVAC
45
44
  # start the measure
46
45
  class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
47
- Dir[File.dirname(__FILE__) + '/resources/*.rb'].each { |file| require file }
46
+ Dir["#{File.dirname(__FILE__)}/resources/*.rb"].sort.each { |file| require file }
48
47
  include OsLib_HelperMethods
49
48
  # human readable name
50
49
  def name
@@ -75,12 +74,12 @@ class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
75
74
  hhw_loop_name.setDefaultValue('hot')
76
75
  args << hhw_loop_name
77
76
 
78
- chw_loop_name = OpenStudio::Measure::OSArgument.makeStringArgument('chw_loop_name', true)
77
+ chw_loop_name = OpenStudio::Measure::OSArgument.makeStringArgument('chw_loop_name', true)
79
78
  chw_loop_name.setDisplayName('Name or Partial Name of Chilled Water Loop, non-case-sensitive')
80
79
  chw_loop_name.setDefaultValue('chilled')
81
80
  args << chw_loop_name
82
81
 
83
- dec_places_mass_flow = OpenStudio::Measure::OSArgument.makeIntegerArgument('dec_places_mass_flow', true)
82
+ dec_places_mass_flow = OpenStudio::Measure::OSArgument.makeIntegerArgument('dec_places_mass_flow', true)
84
83
  dec_places_mass_flow.setDisplayName('Number of Decimal Places to Round Mass Flow Rate')
85
84
  dec_places_mass_flow.setDescription('Number of decimal places to which mass flow rate will be rounded')
86
85
  dec_places_mass_flow.setDefaultValue(3)
@@ -113,11 +112,11 @@ class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
113
112
  # use the built-in error checking
114
113
  return false unless runner.validateUserArguments(arguments(model), user_arguments)
115
114
 
116
- ##Read in argumetns related to variables for output requests
115
+ # #Read in argumetns related to variables for output requests
117
116
  hhw_loop_name = runner.getStringArgumentValue('hhw_loop_name', user_arguments)
118
117
  chw_loop_name = runner.getStringArgumentValue('chw_loop_name', user_arguments)
119
118
 
120
- #Identify key names for output variables.
119
+ # Identify key names for output variables.
121
120
  plantloops = model.getPlantLoops
122
121
 
123
122
  selected_plant_loops = []
@@ -128,19 +127,19 @@ class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
128
127
  reporting_frequency = 'timestep'
129
128
 
130
129
  plantloops.each do |plantLoop|
131
- log "plant loop name #{plantLoop.name.get.to_s}"
130
+ log "plant loop name #{plantLoop.name.get}"
132
131
  if plantLoop.name.get.to_s.downcase.include? chw_loop_name.to_s
133
- #Extract plant loop information
134
- selected_plant_loops[0]=plantLoop
132
+ # Extract plant loop information
133
+ selected_plant_loops[0] = plantLoop
135
134
  key_value_chw_outlet = selected_plant_loops[0].demandOutletNode.name.to_s
136
135
  key_value_chw_inlet = selected_plant_loops[0].demandInletNode.name.to_s
137
136
  result << OpenStudio::IdfObject.load("Output:Variable,#{key_value_chw_outlet},#{variable_name2},timestep;").get
138
137
  result << OpenStudio::IdfObject.load("Output:Variable,#{key_value_chw_inlet},#{variable_name2},timestep;").get
139
138
  result << OpenStudio::IdfObject.load("Output:Variable,#{key_value_chw_outlet},#{variable_name1},timestep;").get
140
139
  end
141
- if plantLoop.name.get.to_s.downcase.include? hhw_loop_name.to_s and !plantLoop.name.get.to_s.downcase.include? "service" and !plantLoop.name.get.to_s.downcase.include? "domestic"
142
- #Extract plant loop information
143
- selected_plant_loops[1]=plantLoop
140
+ if plantLoop.name.get.to_s.downcase.include?(hhw_loop_name.to_s) && !plantLoop.name.get.to_s.downcase.include?('service') && !plantLoop.name.get.to_s.downcase.include?('domestic')
141
+ # Extract plant loop information
142
+ selected_plant_loops[1] = plantLoop
144
143
  key_value_hhw_outlet = selected_plant_loops[1].demandOutletNode.name.to_s
145
144
  key_value_hhw_inlet = selected_plant_loops[1].demandInletNode.name.to_s
146
145
  result << OpenStudio::IdfObject.load("Output:Variable,#{key_value_hhw_outlet},#{variable_name2},timestep;").get
@@ -153,7 +152,7 @@ class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
153
152
  result << OpenStudio::IdfObject.load('Output:Variable,,Site Outdoor Air Drybulb Temperature,hourly;').get
154
153
  result << OpenStudio::IdfObject.load('Output:Variable,,Site Outdoor Air Relative Humidity,hourly;').get
155
154
  result << OpenStudio::IdfObject.load('Output:Meter,Cooling:Electricity,hourly;').get
156
- result << OpenStudio::IdfObject.load('Output:Meter,Electricity:Facility,timestep;').get ##Using this for data at timestep interval
155
+ result << OpenStudio::IdfObject.load('Output:Meter,Electricity:Facility,timestep;').get # #Using this for data at timestep interval
157
156
  result << OpenStudio::IdfObject.load('Output:Meter,Heating:Electricity,hourly;').get
158
157
  result << OpenStudio::IdfObject.load('Output:Meter,Heating:NaturalGas,hourly;').get
159
158
  result << OpenStudio::IdfObject.load('Output:Meter,InteriorLights:Electricity,hourly;').get
@@ -171,15 +170,15 @@ class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
171
170
  result
172
171
  end
173
172
 
174
- def extract_timeseries_into_matrix(sqlfile, data, variable_name, str, key_value = nil, default_if_empty = 0,dec_places, timestep)
173
+ def extract_timeseries_into_matrix(sqlfile, data, variable_name, str, key_value = nil, default_if_empty = 0, dec_places, timestep)
175
174
  log "Executing query for #{variable_name}"
176
- #column_name = variable_name
175
+ # column_name = variable_name
177
176
  if key_value
178
177
  ts = sqlfile.timeSeries('RUN PERIOD 1', 'Zone Timestep', variable_name, key_value)
179
- #column_name += "_#{key_value}"
180
- column_name=str
178
+ # column_name += "_#{key_value}"
179
+ column_name = str
181
180
  else
182
- #ts = sqlfile.timeSeries('RUN PERIOD 1', 'Hourly', variable_name)
181
+ # ts = sqlfile.timeSeries('RUN PERIOD 1', 'Hourly', variable_name)
183
182
  ts = sqlfile.timeSeries('RUN PERIOD 1', 'Zone Timestep', variable_name)
184
183
  end
185
184
  log 'Iterating over timeseries'
@@ -201,16 +200,16 @@ class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
201
200
  # end
202
201
 
203
202
  quick_proc = ts.values.to_s.split(',')
204
- quick_proc[0]=quick_proc[0].split('(', 2).last #cleanup necessary to remove opening paren
205
- quick_proc=quick_proc.map(&:to_f)
203
+ quick_proc[0] = quick_proc[0].split('(', 2).last # cleanup necessary to remove opening paren
204
+ quick_proc = quick_proc.map(&:to_f)
206
205
  x = 0
207
206
  len = quick_proc.length
208
- log "quick proc #{quick_proc}"
209
- while(x < len) #Round to the # of decimal places specified
210
- quick_proc[x]=(quick_proc[x]).round(dec_places)
211
- x=x+1
212
- end
213
- quick_proc=quick_proc.map(&:to_s)
207
+ log "quick proc #{quick_proc}"
208
+ while x < len # Round to the # of decimal places specified
209
+ quick_proc[x] = (quick_proc[x]).round(dec_places)
210
+ x += 1
211
+ end
212
+ quick_proc = quick_proc.map(&:to_s)
214
213
 
215
214
  # the first and last have some cleanup items because of the Vector method
216
215
  quick_proc[0] = quick_proc[0].gsub(/^.*\(/, '')
@@ -232,7 +231,7 @@ class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
232
231
  log "Finished extracting #{variable_name}"
233
232
  end
234
233
 
235
- def create_new_variable_sum(data, new_var_name, include_str, options=nil)
234
+ def create_new_variable_sum(data, new_var_name, include_str, options = nil)
236
235
  var_info = {
237
236
  name: new_var_name,
238
237
  var_indexes: []
@@ -285,16 +284,18 @@ class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
285
284
 
286
285
  # lookup and replace argument values from upstream measures
287
286
  if args['use_upstream_args'] == true
288
- args.each do |arg,value|
287
+ args.each do |arg, value|
289
288
  next if arg == 'use_upstream_args' # this argument should not be changed
289
+
290
290
  value_from_osw = OsLib_HelperMethods.check_upstream_measure_for_arg(runner, arg)
291
291
  if !value_from_osw.empty?
292
292
  runner.registerInfo("Replacing argument named #{arg} from current measure with a value of #{value_from_osw[:value]} from #{value_from_osw[:measure_name]}.")
293
293
  new_val = value_from_osw[:value]
294
294
  # TODO: make code to handle non strings more robust. check_upstream_measure_for_arg could pass back the argument type
295
- if arg == 'hhw_loop_name'
295
+ case arg
296
+ when 'hhw_loop_name'
296
297
  args[arg] = new_val.to_s
297
- elsif arg == 'chw_loop_name'
298
+ when 'chw_loop_name'
298
299
  args[arg] = new_val.to_s
299
300
  else
300
301
  args[arg] = new_val
@@ -314,8 +315,8 @@ class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
314
315
  end
315
316
  model = model.get
316
317
 
317
- timesteps_per_hour=model.getTimestep.numberOfTimestepsPerHour.to_i
318
- timestep=60/timesteps_per_hour #timestep in minutes
318
+ timesteps_per_hour = model.getTimestep.numberOfTimestepsPerHour.to_i
319
+ timestep = 60 / timesteps_per_hour # timestep in minutes
319
320
 
320
321
  sqlFile = runner.lastEnergyPlusSqlFile
321
322
  if sqlFile.empty?
@@ -342,7 +343,7 @@ class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
342
343
  ts = sqlFile.timeSeries('RUN PERIOD 1', 'Zone Timestep', attribute_name)
343
344
  if ts.empty?
344
345
  runner.registerError("This feature does not have the attribute '#{attribute_name}' to enable this measure to work." \
345
- "To resolve, simulate a building with electricity or remove this measure from your workflow.")
346
+ 'To resolve, simulate a building with electricity or remove this measure from your workflow.')
346
347
  else
347
348
  ts = ts.first
348
349
  dt_base = nil
@@ -357,7 +358,7 @@ class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
357
358
  dt.date.dayOfWeek.value,
358
359
  dt.time.hours,
359
360
  dt.time.minutes,
360
- dt_current.to_time.to_i - dt_base.to_time.to_i + timestep*60
361
+ dt_current.to_time.to_i - dt_base.to_time.to_i + timestep * 60
361
362
  ]
362
363
  end
363
364
  end
@@ -367,52 +368,51 @@ class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
367
368
  selected_plant_loops = []
368
369
  i = 0
369
370
 
370
- key_var={}
371
+ key_var = {}
371
372
 
372
373
  plantloops.each do |plantLoop|
373
374
  if plantLoop.name.get.to_s.downcase.include? chw_loop_name.to_str
374
- #Extract plant loop information
375
- selected_plant_loops[0]=plantLoop
375
+ # Extract plant loop information
376
+ selected_plant_loops[0] = plantLoop
376
377
  end
377
378
  if plantLoop.name.get.to_s.downcase.include? hhw_loop_name.to_str
378
- #Get plant loop information
379
- selected_plant_loops[1]=plantLoop
379
+ # Get plant loop information
380
+ selected_plant_loops[1] = plantLoop
380
381
  end
381
382
  end
382
383
 
383
384
  if !selected_plant_loops[1].nil?
384
- #Set up variables for output
385
+ # Set up variables for output
385
386
  key_value_hhw_outlet = selected_plant_loops[1].demandOutletNode.name.to_s
386
387
  key_value_hhw_inlet = selected_plant_loops[1].demandInletNode.name.to_s
387
- key_var['hhw_outlet_massflow']='massFlowRateHeating'
388
- key_var['hhw_outlet_temp']='heatingReturnTemperature[C]'
389
- key_var['hhw_inlet_temp']='heatingSupplyTemperature[C]'
390
- #Extract time series
388
+ key_var['hhw_outlet_massflow'] = 'massFlowRateHeating'
389
+ key_var['hhw_outlet_temp'] = 'heatingReturnTemperature[C]'
390
+ key_var['hhw_inlet_temp'] = 'heatingSupplyTemperature[C]'
391
+ # Extract time series
391
392
  extract_timeseries_into_matrix(sqlFile, rows, 'System Node Temperature', key_var['hhw_outlet_temp'], key_value_hhw_outlet, 0, dec_places_temp, timestep)
392
393
  extract_timeseries_into_matrix(sqlFile, rows, 'System Node Temperature', key_var['hhw_inlet_temp'], key_value_hhw_inlet, 0, dec_places_temp, timestep)
393
394
  extract_timeseries_into_matrix(sqlFile, rows, 'System Node Mass Flow Rate', key_var['hhw_outlet_massflow'], key_value_hhw_outlet, 0, dec_places_mass_flow, timestep)
394
395
  else
395
- runner.registerWarning("No hot water loop found. If one is expected, make sure the hot water loop name argument provides a string present in its name.")
396
+ runner.registerWarning('No hot water loop found. If one is expected, make sure the hot water loop name argument provides a string present in its name.')
396
397
  end
397
398
 
398
399
  if !selected_plant_loops[0].nil?
399
- #Set up variables for outputs
400
+ # Set up variables for outputs
400
401
  key_value_chw_outlet = selected_plant_loops[0].demandOutletNode.name.to_s
401
402
  key_value_chw_inlet = selected_plant_loops[0].demandInletNode.name.to_s
402
- key_var['chw_outlet_massflow']='massFlowRateCooling'
403
- key_var['chw_outlet_temp']='ChilledWaterReturnTemperature[C]'
404
- key_var['chw_inlet_temp']='ChilledWaterSupplyTemperature[C]'
405
- #Extract time series
406
- extract_timeseries_into_matrix(sqlFile, rows, 'System Node Temperature', key_var['chw_outlet_temp'], key_value_chw_outlet, 0, dec_places_temp,timestep)
407
- extract_timeseries_into_matrix(sqlFile, rows, 'System Node Temperature', key_var['chw_inlet_temp'], key_value_chw_inlet, 0, dec_places_temp,timestep)
408
- extract_timeseries_into_matrix(sqlFile, rows, 'System Node Mass Flow Rate', key_var['chw_outlet_massflow'], key_value_chw_outlet, 0, dec_places_mass_flow,timestep)
403
+ key_var['chw_outlet_massflow'] = 'massFlowRateCooling'
404
+ key_var['chw_outlet_temp'] = 'ChilledWaterReturnTemperature[C]'
405
+ key_var['chw_inlet_temp'] = 'ChilledWaterSupplyTemperature[C]'
406
+ # Extract time series
407
+ extract_timeseries_into_matrix(sqlFile, rows, 'System Node Temperature', key_var['chw_outlet_temp'], key_value_chw_outlet, 0, dec_places_temp, timestep)
408
+ extract_timeseries_into_matrix(sqlFile, rows, 'System Node Temperature', key_var['chw_inlet_temp'], key_value_chw_inlet, 0, dec_places_temp, timestep)
409
+ extract_timeseries_into_matrix(sqlFile, rows, 'System Node Mass Flow Rate', key_var['chw_outlet_massflow'], key_value_chw_outlet, 0, dec_places_mass_flow, timestep)
409
410
  else
410
- runner.registerWarning("No chilled water loop found. If one is expected, make sure the chilled water loop name argument provides a string present in its name.")
411
+ runner.registerWarning('No chilled water loop found. If one is expected, make sure the chilled water loop name argument provides a string present in its name.')
411
412
  end
412
413
 
413
-
414
- if selected_plant_loops[0].nil? and selected_plant_loops[1].nil?
415
- runner.registerWarning("No HVAC plant loops found. If one or more plant loops are expected, make sure they follow the naming conventions mentioned in the previous warnings.")
414
+ if selected_plant_loops[0].nil? && selected_plant_loops[1].nil?
415
+ runner.registerWarning('No HVAC plant loops found. If one or more plant loops are expected, make sure they follow the naming conventions mentioned in the previous warnings.')
416
416
  end
417
417
 
418
418
  if !selected_plant_loops.nil?
@@ -430,6 +430,5 @@ class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
430
430
  end
431
431
  end
432
432
 
433
-
434
433
  # register the measure to be used by the application
435
434
  ExportTimeSeriesLoadsCSV.new.registerWithApplication
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, 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,
@@ -358,10 +358,8 @@ module OsLib_HelperMethods
358
358
  objectArray.each do |object|
359
359
  object_LCCs = object.lifeCycleCosts
360
360
  object_LCCs.each do |object_LCC|
361
- if object_LCC.category == category
362
- if onlyYearFromStartZero == false || object_LCC.yearsFromStart == 0
363
- counter += object_LCC.totalCost
364
- end
361
+ if object_LCC.category == category && (onlyYearFromStartZero == false || object_LCC.yearsFromStart == 0)
362
+ counter += object_LCC.totalCost
365
363
  end
366
364
  end
367
365
  end
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, 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,
@@ -50,6 +50,7 @@ module URBANopt
50
50
  ##
51
51
  class ConstructionCost
52
52
  attr_accessor :category, :item_name, :unit_cost, :cost_units, :item_quantity, :total_cost # :nodoc:
53
+
53
54
  ##
54
55
  # ConstructionCost class intialize all construction_cost attributes:
55
56
  # +:category+ , +:item_name+ , +:unit_cost+ , +:cost_units+ , +:item_quantity+ , +:total_cost+
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, 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,
@@ -50,6 +50,7 @@ module URBANopt
50
50
  ##
51
51
  class Date
52
52
  attr_accessor :month, :day_of_month, :year #:nodoc:
53
+
53
54
  ##
54
55
  # Date class intialize all date attributes:
55
56
  # +:month+ , +:day_of_month+ , +:year+
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, 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,
@@ -192,6 +192,15 @@ module URBANopt
192
192
  #
193
193
  attr_accessor :probs_of_surviving_by_hour_of_the_day
194
194
 
195
+ ##
196
+ # _String_ - Filepath of reopt assumptions file used, if known
197
+ attr_accessor :reopt_assumptions_file_path
198
+
199
+ ##
200
+ # _Float_ - Annual percentage of electricity supplied by renewable sources
201
+ #
202
+ attr_accessor :annual_renewable_electricity_pct
203
+
195
204
  ##
196
205
  # Initialize distributed generation system design and financial metrics.
197
206
  #
@@ -206,6 +215,7 @@ module URBANopt
206
215
  def initialize(hash = {})
207
216
  hash.delete_if { |k, v| v.nil? }
208
217
 
218
+ @annual_renewable_electricity_pct = hash[:annual_renewable_electricity_pct]
209
219
  @lcc_us_dollars = hash[:lcc_us_dollars]
210
220
  @lcc_bau_us_dollars = hash[:lcc_bau_us_dollars]
211
221
  @npv_us_dollars = hash[:npv_us_dollars]
@@ -227,6 +237,12 @@ module URBANopt
227
237
  @probs_of_surviving_by_month = hash[:probs_of_surviving_by_month]
228
238
  @probs_of_surviving_by_hour_of_the_day = hash[:probs_of_surviving_by_hour_of_the_day]
229
239
 
240
+ # optional
241
+ @reopt_assumptions_file_path = nil
242
+ if hash[:reopt_assumptions_file_path]
243
+ @reopt_assumptions_file_path = hash[:reopt_assumptions_file_path]
244
+ end
245
+
230
246
  @total_solar_pv_kw = nil
231
247
  @total_wind_kw = nil
232
248
  @total_generator_kw = nil
@@ -234,7 +250,7 @@ module URBANopt
234
250
  @total_storage_kwh = nil
235
251
 
236
252
  @solar_pv = []
237
- if hash[:solar_pv].class == Hash
253
+ if hash[:solar_pv].instance_of?(Hash)
238
254
  hash[:solar_pv] = [hash[:solar_pv]]
239
255
  elsif hash[:solar_pv].nil?
240
256
  hash[:solar_pv] = []
@@ -252,7 +268,7 @@ module URBANopt
252
268
  end
253
269
 
254
270
  @wind = []
255
- if hash[:wind].class == Hash
271
+ if hash[:wind].instance_of?(Hash)
256
272
  hash[:wind] = [hash[:wind]]
257
273
  elsif hash[:wind].nil?
258
274
  hash[:wind] = []
@@ -270,7 +286,7 @@ module URBANopt
270
286
  end
271
287
 
272
288
  @generator = []
273
- if hash[:generator].class == Hash
289
+ if hash[:generator].instance_of?(Hash)
274
290
  hash[:generator] = [hash[:generator]]
275
291
  elsif hash[:generator].nil?
276
292
  hash[:generator] = []
@@ -288,7 +304,7 @@ module URBANopt
288
304
  end
289
305
 
290
306
  @storage = []
291
- if hash[:storage].class == Hash
307
+ if hash[:storage].instance_of?(Hash)
292
308
  hash[:storage] = [hash[:storage]]
293
309
  elsif hash[:storage].nil?
294
310
  hash[:storage] = []
@@ -363,7 +379,8 @@ module URBANopt
363
379
  ##
364
380
  def to_hash
365
381
  result = {}
366
-
382
+ result[:reopt_assumptions_file_path] = @reopt_assumptions_file_path if @reopt_assumptions_file_path
383
+ result[:annual_renewable_electricity_pct] = @annual_renewable_electricity_pct if @annual_renewable_electricity_pct
367
384
  result[:lcc_us_dollars] = @lcc_us_dollars if @lcc_us_dollars
368
385
  result[:lcc_bau_us_dollars] = @lcc_bau_us_dollars if @lcc_bau_us_dollars
369
386
  result[:npv_us_dollars] = @npv_us_dollars if @npv_us_dollars
@@ -433,6 +450,7 @@ module URBANopt
433
450
  # Merge a distributed generation system with a new system
434
451
  ##
435
452
  def self.merge_distributed_generation(existing_dgen, new_dgen)
453
+ existing_dgen.annual_renewable_electricity_pct = add_values(existing_dgen.annual_renewable_electricity_pct, new_dgen.annual_renewable_electricity_pct)
436
454
  existing_dgen.lcc_us_dollars = add_values(existing_dgen.lcc_us_dollars, new_dgen.lcc_us_dollars)
437
455
  existing_dgen.lcc_bau_us_dollars = add_values(existing_dgen.lcc_bau_us_dollars, new_dgen.lcc_bau_us_dollars)
438
456
  existing_dgen.npv_us_dollars = add_values(existing_dgen.npv_us_dollars, new_dgen.npv_us_dollars)
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, 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,
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, 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,
@@ -50,6 +50,7 @@ module URBANopt
50
50
  ##
51
51
  class EndUses
52
52
  attr_accessor :electricity_kwh, :natural_gas_kwh, :propane_kwh, :fuel_oil_kwh, :other_fuels_kwh, :district_cooling_kwh, :district_heating_kwh, :water_qbft # :nodoc:
53
+
53
54
  ##
54
55
  # EndUses class intialize end_uses(fuel type) attributes: +:electricity_kwh+ , +:natural_gas_kwh+ , +:propane_kwh+ , +:fuel_oil_kwh+ , +:other_fuels_kwh+ ,
55
56
  # +:district_cooling_kwh+ , +:district_heating_kwh+ , +:water_qbft+
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, 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,
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, 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,
@@ -65,6 +65,7 @@ module URBANopt
65
65
  class FeatureReport
66
66
  attr_accessor :id, :name, :directory_name, :feature_type, :timesteps_per_hour, :simulation_status,
67
67
  :timeseries_csv, :location, :program, :design_parameters, :construction_costs, :reporting_periods, :distributed_generation, :power_distribution, :thermal_storage # :nodoc:
68
+
68
69
  ##
69
70
  # Each FeatureReport object corresponds to a single Feature.
70
71
  ##
@@ -254,15 +255,15 @@ module URBANopt
254
255
  # create feature reports directory
255
256
  Dir.mkdir(results_dir_path) unless Dir.exist?(File.join(@directory_name, 'feature_reports'))
256
257
 
257
- @timeseries_csv.path = File.join(@directory_name, 'feature_reports', file_name + '.csv')
258
+ @timeseries_csv.path = File.join(@directory_name, 'feature_reports', "#{file_name}.csv")
258
259
  FileUtils.mkdir_p File.dirname(@timeseries_csv.path)
259
260
  @timeseries_csv.save_data
260
261
 
261
- ## save json rport
262
+ ## save json report
262
263
  # feature_hash
263
264
  feature_hash = to_hash
264
265
 
265
- json_name_path = File.join(results_dir_path, file_name + '.json')
266
+ json_name_path = File.join(results_dir_path, "#{file_name}.json")
266
267
 
267
268
  File.open(json_name_path, 'w') do |f|
268
269
  f.puts JSON.pretty_generate(feature_hash)
@@ -277,7 +278,7 @@ module URBANopt
277
278
  if !old_timeseries_path.nil?
278
279
  @timeseries_csv.path = old_timeseries_path
279
280
  else
280
- @timeseries_csv.path = File.join(@directory_name, file_name + '.csv')
281
+ @timeseries_csv.path = File.join(@directory_name, "#{file_name}.csv")
281
282
  end
282
283
 
283
284
  return true
@@ -312,7 +313,7 @@ module URBANopt
312
313
  # feature_hash
313
314
  feature_hash = to_hash
314
315
 
315
- json_name_path = File.join(results_dir_path, file_name + '.json')
316
+ json_name_path = File.join(results_dir_path, "#{file_name}.json")
316
317
 
317
318
  File.open(json_name_path, 'w') do |f|
318
319
  f.puts JSON.pretty_generate(feature_hash)
@@ -327,7 +328,7 @@ module URBANopt
327
328
 
328
329
  ##
329
330
  # Saves the 'default_feature_report.csv' file to the results directory
330
- # This method only copies the CSV feature reports from the folder generated by the reporting measure
331
+ # This method only copies the CSV feature reports from the folder generated by the reporting measure
331
332
  # (<meausure number>_default_feature_reports/) to the new feature_reports/ folder
332
333
  ##
333
334
  # [parameters]:
@@ -347,7 +348,7 @@ module URBANopt
347
348
  # copy the CSV report to the new feature_reports folder
348
349
  directory_folders.each do |f|
349
350
  if f.include? '_default_feature_reports'
350
- FileUtils.cp(File.join(f, 'default_feature_reports.csv'), File.join(results_dir_path, @file_name + '.csv'))
351
+ FileUtils.cp(File.join(f, 'default_feature_reports.csv'), File.join(results_dir_path, "#{@file_name}.csv"))
351
352
  end
352
353
  end
353
354
  end
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, 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,
@@ -80,7 +80,6 @@ module URBANopt
80
80
  result = {}
81
81
 
82
82
  result[:size_kw] = @size_kw if @size_kw
83
-
84
83
  return result
85
84
  end
86
85
 
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, 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,
@@ -50,6 +50,7 @@ module URBANopt
50
50
  ##
51
51
  class Location
52
52
  attr_accessor :latitude_deg, :longitude_deg, :surface_elevation_ft, :weather_filename #:nodoc:
53
+
53
54
  ##
54
55
  # Location class initialize location attributes: +:latitude_deg+ , +:longitude_deg+ , +:surface_elevation_ft+ , +:weather_filename+
55
56
  ##
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, 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,
@@ -43,7 +43,7 @@ require 'logger'
43
43
  module URBANopt
44
44
  module Reporting
45
45
  module DefaultReports
46
- @@logger = Logger.new(STDOUT)
46
+ @@logger = Logger.new($stdout)
47
47
  ##
48
48
  # Definining class variable "@@logger" to log errors, info and warning messages.
49
49
  def self.logger
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, 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,
@@ -50,10 +50,12 @@ module URBANopt
50
50
  # power_distributio include eletrical power distribution systems information.
51
51
  ##
52
52
  class PowerDistribution
53
- attr_accessor :under_voltage_hours, :over_voltage_hours # :nodoc:
53
+ attr_accessor :under_voltage_hours, :over_voltage_hours, :nominal_capacity,
54
+ :reactance_resistance_ratio, :nominal_voltage, :max_power_kw, :max_reactive_power_kvar # :nodoc:
55
+
54
56
  ##
55
- # PowerDistrinution class intialize all power_distribution attributes:
56
- # +:under_voltage_hours+ , +:over_voltage_hours+
57
+ # PowerDistribution class initialize all power_distribution attributes:
58
+ # +:under_voltage_hours+ , +:over_voltage_hours+, +:nominal_capacity+, +:reactance_resistance_ratio+
57
59
  ##
58
60
  # [parameters:]
59
61
  # +hash+ - _Hash_ - A hash which may contain a deserialized power_distribution.
@@ -64,7 +66,11 @@ module URBANopt
64
66
 
65
67
  @under_voltage_hours = hash[:under_voltage_hours]
66
68
  @over_voltage_hours = hash[:over_voltage_hours]
67
-
69
+ @nominal_capacity = hash[:nominal_capacity]
70
+ @reactance_resistance_ratio = hash[:reactance_resistance_ratio]
71
+ @nominal_voltage = hash[:nominal_voltage] # in V
72
+ @max_power_kw = hash[:max_power_kw]
73
+ @max_reactive_power_kvar = hash[:max_reactive_power_kvar]
68
74
  # initialize class variables @@validator and @@schema
69
75
  @@validator ||= Validator.new
70
76
  @@schema ||= @@validator.schema
@@ -77,6 +83,11 @@ module URBANopt
77
83
  hash = {}
78
84
  hash[:under_voltage_hours] = nil
79
85
  hash[:over_voltage_hours] = nil
86
+ hash[:nominal_capacity] = nil
87
+ hash[:reactance_resistance_ratio] = nil
88
+ hash[:nominal_voltage] = nil
89
+ hash[:max_power_kw] = nil
90
+ hash[:max_reactive_power_kvar] = nil
80
91
 
81
92
  return hash
82
93
  end
@@ -91,6 +102,11 @@ module URBANopt
91
102
  result = {}
92
103
  result[:under_voltage_hours] = @under_voltage_hours if @under_voltage_hours
93
104
  result[:over_voltage_hours] = @over_voltage_hours if @over_voltage_hours
105
+ result[:nominal_capacity] = @nominal_capacity if @nominal_capacity
106
+ result[:reactance_resistance_ratio] = @reactance_resistance_ratio if @reactance_resistance_ratio
107
+ result[:nominal_voltage] = @nominal_voltage if @nominal_voltage
108
+ result[:max_power_kw] = @max_power_kw if @max_power_kw
109
+ result[:max_reactive_power_kvar] = @max_reactive_power_kvar if @max_reactive_power_kvar
94
110
 
95
111
  # validate power_distribution properties against schema
96
112
  if @@validator.validate(@@schema[:definitions][:PowerDistribution][:properties], result).any?
@@ -104,7 +120,7 @@ module URBANopt
104
120
  # Merges muliple power distribution results together.
105
121
  ##
106
122
  # +new_costs+ - _Array_ - An array of ConstructionCost objects.
107
- def merge_power_distribition
123
+ def merge_power_distribution
108
124
  # method to be developed for any attributes to be aggregated or merged
109
125
  end
110
126
  end
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, 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,
@@ -56,6 +56,7 @@ module URBANopt
56
56
  :maximum_number_of_parking_stories_above_ground, :number_of_residential_units, :building_types, :building_type, :maximum_occupancy,
57
57
  :area_sqft, :window_area_sqft, :north_window_area_sqft, :south_window_area_sqft, :east_window_area_sqft, :west_window_area_sqft, :wall_area_sqft, :roof_area_sqft, :equipment_roof_area_sqft,
58
58
  :photovoltaic_roof_area_sqft, :available_roof_area_sqft, :total_roof_area_sqft, :orientation_deg, :aspect_ratio, :total_construction_cost_dollar # :nodoc:
59
+
59
60
  # Program class initialize building program attributes: +:site_area_sqft+ , +:floor_area_sqft+ , +:conditioned_area_sqft+ , +:unconditioned_area_sqft+ ,
60
61
  # +:footprint_area_sqft+ , +:maximum_roof_height_ft, +:maximum_number_of_stories+ , +:maximum_number_of_stories_above_ground+ , +:parking_area_sqft+ ,
61
62
  # +:number_of_parking_spaces+ , +:number_of_parking_spaces_charging+ , +:parking_footprint_area_sqft+ , +:maximum_parking_height_ft+ , +:maximum_number_of_parking_stories+ ,