urbanopt-scenario 0.1.1 → 0.2.0.pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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|
|