urbanopt-scenario 0.1.1 → 0.2.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -8
- data/.github/ISSUE_TEMPLATE/feature_request.md +2 -10
- data/.github/pull_request_template.md +5 -15
- data/{.github/CONTRIBUTING.md → CONTRIBUTING.md} +0 -0
- data/Gemfile +4 -2
- data/Jenkinsfile +2 -2
- data/Rakefile +1 -1
- data/docs/package-lock.json +4607 -6451
- data/docs/package.json +1 -1
- data/lib/measures/default_feature_reports/LICENSE.md +1 -1
- data/lib/measures/default_feature_reports/README.md +1 -1
- data/lib/measures/default_feature_reports/measure.rb +256 -41
- data/lib/measures/default_feature_reports/measure.xml +19 -15
- data/lib/urbanopt/scenario/default_reports/distributed_generation.rb +204 -17
- data/lib/urbanopt/scenario/default_reports/feature_report.rb +47 -0
- data/lib/urbanopt/scenario/default_reports/program.rb +6 -1
- data/lib/urbanopt/scenario/default_reports/reporting_period.rb +5 -2
- data/lib/urbanopt/scenario/default_reports/scenario_report.rb +17 -6
- data/lib/urbanopt/scenario/default_reports/schema/README.md +11 -12
- data/lib/urbanopt/scenario/default_reports/schema/scenario_csv_columns.txt +14 -6
- data/lib/urbanopt/scenario/default_reports/schema/scenario_schema.json +27 -18
- data/lib/urbanopt/scenario/default_reports/solar_pv.rb +1 -0
- data/lib/urbanopt/scenario/default_reports/timeseries_csv.rb +29 -3
- data/lib/urbanopt/scenario/scenario_runner_osw.rb +21 -5
- data/lib/urbanopt/scenario/version.rb +1 -1
- data/urbanopt-scenario-gem.gemspec +7 -5
- metadata +39 -25
- data/.travis.yml +0 -23
@@ -73,25 +73,45 @@ module URBANopt
|
|
73
73
|
attr_accessor :total_energy_cost_us_dollars
|
74
74
|
|
75
75
|
##
|
76
|
-
#
|
76
|
+
# _Array_ - List of _SolarPV_ systems
|
77
77
|
#
|
78
78
|
attr_accessor :solar_pv
|
79
79
|
|
80
80
|
##
|
81
|
-
#
|
81
|
+
# _Array_ - List of _Wind_ systems
|
82
82
|
#
|
83
83
|
attr_accessor :wind
|
84
84
|
|
85
85
|
##
|
86
|
-
#
|
86
|
+
# _Array_ - List of _Generator_ systems
|
87
87
|
#
|
88
88
|
attr_accessor :generator
|
89
89
|
|
90
90
|
##
|
91
|
-
#
|
91
|
+
# _Array_ - List of _Storage_ systems
|
92
92
|
#
|
93
93
|
attr_accessor :storage
|
94
94
|
|
95
|
+
##
|
96
|
+
# _Float_ - Installed solar PV capacity
|
97
|
+
#
|
98
|
+
attr_accessor :total_solar_pv_kw
|
99
|
+
|
100
|
+
##
|
101
|
+
# _Float_ - Installed wind capacity
|
102
|
+
#
|
103
|
+
attr_accessor :total_wind_kw
|
104
|
+
|
105
|
+
##
|
106
|
+
# _Float_ - Installed storage capacity
|
107
|
+
#
|
108
|
+
attr_accessor :total_storage_kw
|
109
|
+
|
110
|
+
##
|
111
|
+
# _Float_ - Installed generator capacity
|
112
|
+
#
|
113
|
+
attr_accessor :total_generator_kw
|
114
|
+
|
95
115
|
##
|
96
116
|
# Initialize distributed generation system design and financial metrics.
|
97
117
|
#
|
@@ -113,10 +133,85 @@ module URBANopt
|
|
113
133
|
@year_one_bill_us_dollars = hash[:year_one_bill_us_dollars]
|
114
134
|
@total_energy_cost_us_dollars = hash[:total_energy_cost_us_dollars]
|
115
135
|
|
116
|
-
@
|
117
|
-
@
|
118
|
-
@
|
119
|
-
@
|
136
|
+
@total_solar_pv_kw = nil
|
137
|
+
@total_wind_kw = nil
|
138
|
+
@total_generator_kw = nil
|
139
|
+
@total_storage_kw = nil
|
140
|
+
@total_storage_kwh = nil
|
141
|
+
|
142
|
+
@solar_pv = []
|
143
|
+
if hash[:solar_pv].class == Hash
|
144
|
+
hash[:solar_pv] = [hash[:solar_pv]]
|
145
|
+
elsif hash[:solar_pv].nil?
|
146
|
+
hash[:solar_pv] = []
|
147
|
+
end
|
148
|
+
|
149
|
+
hash[:solar_pv].each do |s|
|
150
|
+
if !s[:size_kw].nil? && (s[:size_kw] != 0)
|
151
|
+
@solar_pv.push SolarPV.new(s)
|
152
|
+
if @total_solar_pv_kw.nil?
|
153
|
+
@total_solar_pv_kw = @solar_pv[-1].size_kw
|
154
|
+
else
|
155
|
+
@total_solar_pv_kw += @solar_pv[-1].size_kw
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
@wind = []
|
161
|
+
if hash[:wind].class == Hash
|
162
|
+
hash[:wind] = [hash[:wind]]
|
163
|
+
elsif hash[:wind].nil?
|
164
|
+
hash[:wind] = []
|
165
|
+
end
|
166
|
+
|
167
|
+
hash[:wind].each do |s|
|
168
|
+
if !s[:size_kw].nil? && (s[:size_kw] != 0)
|
169
|
+
@wind.push Wind.new(s)
|
170
|
+
if @total_wind_kw.nil?
|
171
|
+
@total_wind_kw = @wind[-1].size_kw
|
172
|
+
else
|
173
|
+
@total_wind_kw += @wind[-1].size_kw
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
@generator = []
|
179
|
+
if hash[:generator].class == Hash
|
180
|
+
hash[:generator] = [hash[:generator]]
|
181
|
+
elsif hash[:generator].nil?
|
182
|
+
hash[:generator] = []
|
183
|
+
end
|
184
|
+
|
185
|
+
hash[:generator].each do |s|
|
186
|
+
if !s[:size_kw].nil? && (s[:size_kw] != 0)
|
187
|
+
@generator.push Generator.new(s)
|
188
|
+
if @total_generator_kw.nil?
|
189
|
+
@total_generator_kw = @generator[-1].size_kw
|
190
|
+
else
|
191
|
+
@total_generator_kw += @generator[-1].size_kw
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
@storage = []
|
197
|
+
if hash[:storage].class == Hash
|
198
|
+
hash[:storage] = [hash[:storage]]
|
199
|
+
elsif hash[:storage].nil?
|
200
|
+
hash[:storage] = []
|
201
|
+
end
|
202
|
+
|
203
|
+
hash[:storage].each do |s|
|
204
|
+
if !s[:size_kw].nil? && (s[:size_kw] != 0)
|
205
|
+
@storage.push Storage.new(s)
|
206
|
+
if @total_storage_kw.nil?
|
207
|
+
@total_storage_kw = @storage[-1].size_kw
|
208
|
+
@total_storage_kwh = @storage[-1].size_kwh
|
209
|
+
else
|
210
|
+
@total_storage_kw += @storage[-1].size_kw
|
211
|
+
@total_storage_kwh += @storage[-1].size_kwh
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
120
215
|
|
121
216
|
# initialize class variables @@validator and @@schema
|
122
217
|
@@validator ||= Validator.new
|
@@ -126,6 +221,49 @@ module URBANopt
|
|
126
221
|
@@logger ||= URBANopt::Scenario::DefaultReports.logger
|
127
222
|
end
|
128
223
|
|
224
|
+
##
|
225
|
+
# Add a tech
|
226
|
+
##
|
227
|
+
def add_tech(name, tech)
|
228
|
+
if name == 'solar_pv'
|
229
|
+
@solar_pv.push tech
|
230
|
+
if @total_solar_pv_kw.nil?
|
231
|
+
@total_solar_pv_kw = tech.size_kw
|
232
|
+
else
|
233
|
+
@total_solar_pv_kw += tech.size_kw
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
if name == 'wind'
|
238
|
+
@wind.push tech
|
239
|
+
if @total_wind_kw.nil?
|
240
|
+
@total_wind_kw = tech.size_kw
|
241
|
+
else
|
242
|
+
@total_wind_kw += tech.size_kw
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
if name == 'storage'
|
247
|
+
@storage.push tech
|
248
|
+
if @total_storage_kw.nil?
|
249
|
+
@total_storage_kw = tech.size_kw
|
250
|
+
@total_storage_kwh = tech.size_kwh
|
251
|
+
else
|
252
|
+
@total_storage_kw += tech.size_kw
|
253
|
+
@total_storage_kwh += tech.size_kwh
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
if name == 'generator'
|
258
|
+
@generator.push tech
|
259
|
+
if @total_generator_kw.nil?
|
260
|
+
@total_generator_kw = tech.size_kw
|
261
|
+
else
|
262
|
+
@total_generator_kw += tech.size_kw
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
129
267
|
##
|
130
268
|
# Convert to a Hash equivalent for JSON serialization
|
131
269
|
##
|
@@ -137,12 +275,28 @@ module URBANopt
|
|
137
275
|
result[:year_one_energy_cost_us_dollars] = @year_one_energy_cost_us_dollars if @year_one_energy_cost_us_dollars
|
138
276
|
result[:year_one_demand_cost_us_dollars] = @year_one_demand_cost_us_dollars if @year_one_demand_cost_us_dollars
|
139
277
|
result[:year_one_bill_us_dollars] = @year_one_bill_us_dollars if @year_one_bill_us_dollars
|
140
|
-
result[:
|
141
|
-
result[:
|
142
|
-
result[:
|
143
|
-
result[:
|
144
|
-
result[:
|
278
|
+
result[:total_solar_pv_kw] = @total_solar_pv_kw if @total_solar_pv_kw
|
279
|
+
result[:total_wind_kw] = @total_wind_kw if @total_wind_kw
|
280
|
+
result[:total_generator_kw] = @total_generator_kw if @total_generator_kw
|
281
|
+
result[:total_storage_kw] = @total_storage_kw if @total_storage_kw
|
282
|
+
result[:total_storage_kwh] = @total_storage_kwh if @total_storage_kwh
|
145
283
|
|
284
|
+
result[:solar_pv] = []
|
285
|
+
@solar_pv.each do |pv|
|
286
|
+
result[:solar_pv].push pv.to_hash
|
287
|
+
end
|
288
|
+
result[:wind] = []
|
289
|
+
@wind.each do |pv|
|
290
|
+
result[:wind].push wind.to_hash
|
291
|
+
end
|
292
|
+
result[:generator] = []
|
293
|
+
@generator.each do |pv|
|
294
|
+
result[:generator].push generator.to_hash
|
295
|
+
end
|
296
|
+
result[:storage] = []
|
297
|
+
@storage.each do |pv|
|
298
|
+
result[:storage].push storage.to_hash
|
299
|
+
end
|
146
300
|
return result
|
147
301
|
end
|
148
302
|
|
@@ -174,10 +328,43 @@ module URBANopt
|
|
174
328
|
existing_dgen.year_one_bill_us_dollars = add_values(existing_dgen.year_one_bill_us_dollars, new_dgen.year_one_bill_us_dollars)
|
175
329
|
existing_dgen.total_energy_cost_us_dollars = add_values(existing_dgen.total_energy_cost_us_dollars, new_dgen.total_energy_cost_us_dollars)
|
176
330
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
331
|
+
new_dgen.solar_pv.each do |pv|
|
332
|
+
existing_dgen.solar_pv.push pv
|
333
|
+
if existing_dgen.total_solar_pv_kw.nil?
|
334
|
+
existing_dgen.total_solar_pv_kw = pv.size_kw
|
335
|
+
else
|
336
|
+
existing_dgen.total_solar_pv_kw += pv.size_kw
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
new_dgen.wind.each do |wind|
|
341
|
+
existing_dgen.wind.push wind
|
342
|
+
if existing_dgen.total_wind_kw.nil?
|
343
|
+
existing_dgen.total_wind_kw = wind.size_kw
|
344
|
+
else
|
345
|
+
existing_dgen.total_wind_kw += wind.size_kw
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
new_dgen.storage.each do |storage|
|
350
|
+
existing_dgen.storage.push storage
|
351
|
+
if existing_dgen.total_wind_kw.nil?
|
352
|
+
existing_dgen.total_storage_kw = storage.size_kw
|
353
|
+
existing_dgen.total_storage_kwh = storage.size_kwh
|
354
|
+
else
|
355
|
+
existing_dgen.total_storage_kw += storage.size_kw
|
356
|
+
existing_dgen.total_storage_kwh += storage.size_kwh
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
new_dgen.generator.each do |generator|
|
361
|
+
existing_dgen.generator.push generator
|
362
|
+
if existing_dgen.total_wind_kw.nil?
|
363
|
+
existing_dgen.total_generator_kw = generator.size_kw
|
364
|
+
else
|
365
|
+
existing_dgen.total_generator_kw += generator.size_kw
|
366
|
+
end
|
367
|
+
end
|
181
368
|
|
182
369
|
return existing_dgen
|
183
370
|
end
|
@@ -89,6 +89,9 @@ module URBANopt
|
|
89
89
|
# initialize class variables @@validator and @@schema
|
90
90
|
@@validator ||= Validator.new
|
91
91
|
@@schema ||= @@validator.schema
|
92
|
+
|
93
|
+
# initialize feature report file name to be saved.
|
94
|
+
@file_name = 'default_feature_report'
|
92
95
|
end
|
93
96
|
|
94
97
|
##
|
@@ -207,6 +210,50 @@ module URBANopt
|
|
207
210
|
|
208
211
|
return result
|
209
212
|
end
|
213
|
+
|
214
|
+
##
|
215
|
+
# Saves the 'default_feature_report.json' and 'default_feature_report.csv' files
|
216
|
+
##
|
217
|
+
# [parameters]:
|
218
|
+
# +file_name+ - _String_ - Assign a name to the saved feature report results file without an extension
|
219
|
+
def save_feature_report(file_name = 'updated_default_feature_report')
|
220
|
+
# reassign the initialize local variable @file_name to the file name input.
|
221
|
+
@file_name = file_name
|
222
|
+
|
223
|
+
# create feature reports directory
|
224
|
+
Dir.mkdir(File.join(@directory_name, 'feature_reports')) unless Dir.exist?(File.join(@directory_name, 'feature_reports'))
|
225
|
+
|
226
|
+
# save the csv data
|
227
|
+
old_timeseries_path = nil
|
228
|
+
if !@timeseries_csv.path.nil?
|
229
|
+
old_timeseries_path = @timeseries_csv.path
|
230
|
+
end
|
231
|
+
|
232
|
+
@timeseries_csv.path = File.join(@directory_name, 'feature_reports', file_name + '.csv')
|
233
|
+
@timeseries_csv.save_data
|
234
|
+
|
235
|
+
hash = {}
|
236
|
+
hash[:feature_report] = to_hash
|
237
|
+
|
238
|
+
json_name_path = File.join(@directory_name, 'feature_reports', file_name + '.json')
|
239
|
+
|
240
|
+
File.open(json_name_path, 'w') do |f|
|
241
|
+
f.puts JSON.pretty_generate(hash)
|
242
|
+
# make sure data is written to the disk one way or the other
|
243
|
+
begin
|
244
|
+
f.fsync
|
245
|
+
rescue StandardError
|
246
|
+
f.flush
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
if !old_timeseries_path.nil?
|
251
|
+
@timeseries_csv.path = old_timeseries_path
|
252
|
+
else
|
253
|
+
@timeseries_csv.path = File.join(@directory_name, 'feature_reports', file_name + '.csv')
|
254
|
+
end
|
255
|
+
return true
|
256
|
+
end
|
210
257
|
end
|
211
258
|
end
|
212
259
|
end
|
@@ -44,7 +44,7 @@ module URBANopt
|
|
44
44
|
:number_of_parking_spaces_charging, :parking_footprint_area, :maximum_parking_height, :maximum_number_of_parking_stories,
|
45
45
|
:maximum_number_of_parking_stories_above_ground, :number_of_residential_units, :building_types, :building_type, :maximum_occupancy,
|
46
46
|
:area, :window_area, :north_window_area, :south_window_area, :east_window_area, :west_window_area, :wall_area, :roof_area, :equipment_roof_area,
|
47
|
-
:photovoltaic_roof_area, :available_roof_area, :total_roof_area, :orientation, :aspect_ratio # :nodoc:
|
47
|
+
:photovoltaic_roof_area, :available_roof_area, :total_roof_area, :orientation, :aspect_ratio, :total_construction_cost # :nodoc:
|
48
48
|
# Program class initialize building program attributes: +:site_area+ , +:floor_area+ , +:conditioned_area+ , +:unconditioned_area+ ,
|
49
49
|
# +:footprint_area+ , +:maximum_roof_height, +:maximum_number_of_stories+ , +:maximum_number_of_stories_above_ground+ , +:parking_area+ ,
|
50
50
|
# +:number_of_parking_spaces+ , +:number_of_parking_spaces_charging+ , +:parking_footprint_area+ , +:maximum_parking_height+ , +:maximum_number_of_parking_stories+ ,
|
@@ -81,6 +81,7 @@ module URBANopt
|
|
81
81
|
@roof_area = hash[:roof_area]
|
82
82
|
@orientation = hash[:orientation]
|
83
83
|
@aspect_ratio = hash[:aspect_ratio]
|
84
|
+
@total_construction_cost = hash[:total_construction_cost]
|
84
85
|
|
85
86
|
# initialize class variables @@validator and @@schema
|
86
87
|
@@validator ||= Validator.new
|
@@ -114,6 +115,7 @@ module URBANopt
|
|
114
115
|
hash[:roof_area] = { equipment_roof_area: nil, photovoltaic_roof_area: nil, available_roof_area: nil, total_roof_area: nil }
|
115
116
|
hash[:orientation] = nil
|
116
117
|
hash[:aspect_ratio] = nil
|
118
|
+
hash[:total_construction_cost] = nil
|
117
119
|
return hash
|
118
120
|
end
|
119
121
|
|
@@ -167,6 +169,8 @@ module URBANopt
|
|
167
169
|
result[:orientation] = @orientation if @orientation
|
168
170
|
result[:aspect_ratio] = @aspect_ratio if @aspect_ratio
|
169
171
|
|
172
|
+
result[:total_construction_cost] = @total_construction_cost if @total_construction_cost
|
173
|
+
|
170
174
|
# validate program properties against schema
|
171
175
|
if @@validator.validate(@@schema[:definitions][:Program][:properties], result).any?
|
172
176
|
raise "program properties does not match schema: #{@@validator.validate(@@schema[:definitions][:Program][:properties], result)}"
|
@@ -234,6 +238,7 @@ module URBANopt
|
|
234
238
|
@maximum_number_of_parking_stories = max_value(@maximum_number_of_parking_stories, other.maximum_number_of_parking_stories)
|
235
239
|
@maximum_number_of_parking_stories_above_ground = max_value(maximum_number_of_parking_stories_above_ground, other.maximum_number_of_parking_stories_above_ground)
|
236
240
|
@number_of_residential_units = add_values(@number_of_residential_units, other.number_of_residential_units)
|
241
|
+
@total_construction_cost = add_values(@total_construction_cost, other.total_construction_cost)
|
237
242
|
|
238
243
|
@building_types = other.building_types
|
239
244
|
|
@@ -46,7 +46,7 @@ module URBANopt
|
|
46
46
|
:net_site_energy, :net_source_energy, :net_utility_cost, :electricity, :natural_gas, :additional_fuel, :district_cooling,
|
47
47
|
:district_heating, :water, :electricity_produced, :end_uses, :energy_production, :photovoltaic, :utility_costs,
|
48
48
|
:fuel_type, :total_cost, :usage_cost, :demand_cost, :comfort_result, :time_setpoint_not_met_during_occupied_cooling,
|
49
|
-
:time_setpoint_not_met_during_occupied_heating, :time_setpoint_not_met_during_occupied_hours #:nodoc:
|
49
|
+
:time_setpoint_not_met_during_occupied_heating, :time_setpoint_not_met_during_occupied_hours, :hours_out_of_comfort_bounds_PMV, :hours_out_of_comfort_bounds_PPD #:nodoc:
|
50
50
|
# ReportingPeriod class initializes the reporting period attributes:
|
51
51
|
# +:id+ , +:name+ , +:multiplier+ , +:start_date+ , +:end_date+ , +:month+ , +:day_of_month+ , +:year+ , +:total_site_energy+ , +:total_source_energy+ ,
|
52
52
|
# +:net_site_energy+ , +:net_source_energy+ , +:net_utility_cost+ , +:electricity+ , +:natural_gas+ , +:additional_fuel+ , +:district_cooling+ ,
|
@@ -119,7 +119,8 @@ module URBANopt
|
|
119
119
|
hash[:end_uses] = EndUses.new.to_hash
|
120
120
|
hash[:energy_production] = { electricity_produced: { photovoltaic: nil } }
|
121
121
|
hash[:utility_costs] = [{ fuel_type: nil, total_cost: nil, usage_cost: nil, demand_cost: nil }]
|
122
|
-
hash[:comfort_result] = { time_setpoint_not_met_during_occupied_cooling: nil, time_setpoint_not_met_during_occupied_heating: nil,
|
122
|
+
hash[:comfort_result] = { time_setpoint_not_met_during_occupied_cooling: nil, time_setpoint_not_met_during_occupied_heating: nil,
|
123
|
+
time_setpoint_not_met_during_occupied_hours: nil, hours_out_of_comfort_bounds_PMV: nil, hours_out_of_comfort_bounds_PPD: nil }
|
123
124
|
|
124
125
|
return hash
|
125
126
|
end
|
@@ -244,6 +245,8 @@ module URBANopt
|
|
244
245
|
existing_period.comfort_result[:time_setpoint_not_met_during_occupied_cooling] = add_values(existing_period.comfort_result[:time_setpoint_not_met_during_occupied_cooling], new_period.comfort_result[:time_setpoint_not_met_during_occupied_cooling])
|
245
246
|
existing_period.comfort_result[:time_setpoint_not_met_during_occupied_heating] = add_values(existing_period.comfort_result[:time_setpoint_not_met_during_occupied_heating], new_period.comfort_result[:time_setpoint_not_met_during_occupied_heating])
|
246
247
|
existing_period.comfort_result[:time_setpoint_not_met_during_occupied_hours] = add_values(existing_period.comfort_result[:time_setpoint_not_met_during_occupied_hours], new_period.comfort_result[:time_setpoint_not_met_during_occupied_hours])
|
248
|
+
existing_period.comfort_result[:hours_out_of_comfort_bounds_PMV] = add_values(existing_period.comfort_result[:hours_out_of_comfort_bounds_PMV], new_period.comfort_result[:hours_out_of_comfort_bounds_PMV])
|
249
|
+
existing_period.comfort_result[:hours_out_of_comfort_bounds_PPD] = add_values(existing_period.comfort_result[:hours_out_of_comfort_bounds_PPD], new_period.comfort_result[:hours_out_of_comfort_bounds_PPD])
|
247
250
|
end
|
248
251
|
|
249
252
|
return existing_period
|
@@ -78,6 +78,7 @@ module URBANopt
|
|
78
78
|
@timeseries_csv = TimeseriesCSV.new(hash[:timeseries_csv])
|
79
79
|
@location = Location.new(hash[:location])
|
80
80
|
@program = Program.new(hash[:program])
|
81
|
+
@distributed_generation = DistributedGeneration.new(hash[:distributed_generation] || {})
|
81
82
|
|
82
83
|
@construction_costs = []
|
83
84
|
hash[:construction_costs].each do |cc|
|
@@ -95,8 +96,8 @@ module URBANopt
|
|
95
96
|
@feature_reports << FeatureReport.new(fr)
|
96
97
|
end
|
97
98
|
|
98
|
-
@distributed_generation = DistributedGeneration.new(hash[:distributed_generation] || {})
|
99
99
|
@file_name = 'default_scenario_report'
|
100
|
+
|
100
101
|
# initialize class variables @@validator and @@schema
|
101
102
|
@@validator ||= Validator.new
|
102
103
|
@@schema ||= @@validator.schema
|
@@ -142,10 +143,10 @@ module URBANopt
|
|
142
143
|
end
|
143
144
|
|
144
145
|
##
|
145
|
-
# Saves the '
|
146
|
+
# Saves the 'default_scenario_report.json' and 'default_scenario_report.csv' files
|
146
147
|
##
|
147
148
|
# [parameters]:
|
148
|
-
# +file_name+ - _String_ - Assign a name to the saved scenario results file
|
149
|
+
# +file_name+ - _String_ - Assign a name to the saved scenario results file without an extension
|
149
150
|
def save(file_name = 'default_scenario_report')
|
150
151
|
# reassign the initialize local variable @file_name to the file name input.
|
151
152
|
@file_name = file_name
|
@@ -181,7 +182,7 @@ module URBANopt
|
|
181
182
|
if !old_timeseries_path.nil?
|
182
183
|
@timeseries_csv.path = old_timeseries_path
|
183
184
|
else
|
184
|
-
@timeseries_csv.path = File.join(@directory_name, '
|
185
|
+
@timeseries_csv.path = File.join(@directory_name, file_name + '.csv')
|
185
186
|
end
|
186
187
|
return true
|
187
188
|
end
|
@@ -243,14 +244,24 @@ module URBANopt
|
|
243
244
|
# +feature_report+ - _FeatureReport_ - An object of FeatureReport class.
|
244
245
|
##
|
245
246
|
def add_feature_report(feature_report)
|
246
|
-
if
|
247
|
+
# check if the timesteps_per_hour are identical
|
248
|
+
if @timesteps_per_hour.nil? || @timesteps_per_hour == ''
|
247
249
|
@timesteps_per_hour = feature_report.timesteps_per_hour
|
248
250
|
else
|
249
|
-
if feature_report.timesteps_per_hour != @timesteps_per_hour
|
251
|
+
if feature_report.timesteps_per_hour.is_a?(Integer) && feature_report.timesteps_per_hour != @timesteps_per_hour
|
250
252
|
raise "FeatureReport timesteps_per_hour = '#{feature_report.timesteps_per_hour}' does not match scenario timesteps_per_hour '#{@timesteps_per_hour}'"
|
251
253
|
end
|
252
254
|
end
|
253
255
|
|
256
|
+
# check if first report_report_datetime are identical.
|
257
|
+
if @timeseries_csv.first_report_datetime.nil? || @timeseries_csv.first_report_datetime == ''
|
258
|
+
@timeseries_csv.first_report_datetime = feature_report.timeseries_csv.first_report_datetime
|
259
|
+
else
|
260
|
+
if feature_report.timeseries_csv.first_report_datetime != @timeseries_csv.first_report_datetime
|
261
|
+
raise "first_report_datetime '#{@first_report_datetime}' does not match other.first_report_datetime '#{feature_report.timeseries_csv.first_report_datetime}'"
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
254
265
|
# check that we have not already added this feature
|
255
266
|
id = feature_report.id
|
256
267
|
@feature_reports.each do |existing_feature_report|
|