urbanopt-scenario 0.1.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- 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/.rubocop.yml +1 -1
- data/CHANGELOG.md +45 -1
- data/{.github/CONTRIBUTING.md → CONTRIBUTING.md} +0 -0
- data/Gemfile +8 -12
- data/Jenkinsfile +2 -2
- data/Rakefile +2 -2
- data/docs/package-lock.json +4607 -6451
- data/docs/package.json +1 -1
- data/lib/measures/.rubocop.yml +1 -1
- data/lib/measures/default_feature_reports/LICENSE.md +1 -1
- data/lib/measures/default_feature_reports/README.md +5 -35
- data/lib/measures/default_feature_reports/measure.rb +315 -44
- data/lib/measures/default_feature_reports/measure.xml +38 -17
- data/lib/urbanopt/scenario.rb +1 -0
- data/lib/urbanopt/scenario/default_reports/distributed_generation.rb +209 -17
- data/lib/urbanopt/scenario/default_reports/feature_report.rb +57 -3
- data/lib/urbanopt/scenario/default_reports/power_distribution.rb +102 -0
- data/lib/urbanopt/scenario/default_reports/program.rb +6 -2
- data/lib/urbanopt/scenario/default_reports/reporting_period.rb +15 -9
- data/lib/urbanopt/scenario/default_reports/scenario_report.rb +24 -7
- data/lib/urbanopt/scenario/default_reports/schema/README.md +11 -12
- data/lib/urbanopt/scenario/default_reports/schema/scenario_csv_columns.txt +33 -12
- data/lib/urbanopt/scenario/default_reports/schema/scenario_schema.json +52 -25
- data/lib/urbanopt/scenario/default_reports/solar_pv.rb +1 -0
- data/lib/urbanopt/scenario/default_reports/timeseries_csv.rb +62 -21
- data/lib/urbanopt/scenario/scenario_post_processor_opendss.rb +276 -0
- data/lib/urbanopt/scenario/scenario_runner_osw.rb +21 -5
- data/lib/urbanopt/scenario/simulation_dir_osw.rb +0 -4
- data/lib/urbanopt/scenario/version.rb +1 -1
- data/urbanopt-scenario-gem.gemspec +10 -12
- metadata +31 -48
- data/.travis.yml +0 -23
- data/lib/change_log.rb +0 -147
- data/lib/measures/default_feature_reports/tests/USA_CO_Golden-NREL.724666_TMY3.epw +0 -8768
- data/lib/measures/default_feature_reports/tests/default_feature_reports_test.rb +0 -238
- data/lib/measures/default_feature_reports/tests/example_model.osm +0 -4378
@@ -1,47 +1,61 @@
|
|
1
|
+
<?xml version="1.0"?>
|
1
2
|
<measure>
|
2
3
|
<schema_version>3.0</schema_version>
|
3
4
|
<name>default_feature_reports</name>
|
4
5
|
<uid>9ee3135a-8070-4408-bfa1-b75fecf9dd4f</uid>
|
5
|
-
<version_id>
|
6
|
-
<version_modified>
|
6
|
+
<version_id>95706c7a-88ab-433b-b897-00435181a6dd</version_id>
|
7
|
+
<version_modified>20200603T001228Z</version_modified>
|
7
8
|
<xml_checksum>FB304155</xml_checksum>
|
8
9
|
<class_name>DefaultFeatureReports</class_name>
|
9
10
|
<display_name>DefaultFeatureReports</display_name>
|
10
|
-
<description>Writes default_feature_reports.json
|
11
|
+
<description>Writes default_feature_reports.json and default_feature_reports.csv files used by URBANopt Scenario Default Post Processor</description>
|
11
12
|
<modeler_description>This measure only allows for one feature_report per simulation. If multiple features are simulated in a single simulation, a new measure must be written to disaggregate simulation results to multiple features.</modeler_description>
|
12
13
|
<arguments>
|
13
14
|
<argument>
|
14
15
|
<name>feature_id</name>
|
15
16
|
<display_name>Feature unique identifier</display_name>
|
17
|
+
<description></description>
|
16
18
|
<type>String</type>
|
19
|
+
<units></units>
|
17
20
|
<required>false</required>
|
18
21
|
<model_dependent>false</model_dependent>
|
19
22
|
<default_value>1</default_value>
|
23
|
+
<min_value></min_value>
|
24
|
+
<max_value></max_value>
|
20
25
|
</argument>
|
21
26
|
<argument>
|
22
27
|
<name>feature_name</name>
|
23
28
|
<display_name>Feature scenario specific name</display_name>
|
29
|
+
<description></description>
|
24
30
|
<type>String</type>
|
31
|
+
<units></units>
|
25
32
|
<required>false</required>
|
26
33
|
<model_dependent>false</model_dependent>
|
27
34
|
<default_value>name</default_value>
|
35
|
+
<min_value></min_value>
|
36
|
+
<max_value></max_value>
|
28
37
|
</argument>
|
29
38
|
<argument>
|
30
39
|
<name>feature_type</name>
|
31
40
|
<display_name>URBANopt Feature Type</display_name>
|
41
|
+
<description></description>
|
32
42
|
<type>String</type>
|
43
|
+
<units></units>
|
33
44
|
<required>false</required>
|
34
45
|
<model_dependent>false</model_dependent>
|
35
46
|
<default_value>Building</default_value>
|
47
|
+
<min_value></min_value>
|
48
|
+
<max_value></max_value>
|
36
49
|
</argument>
|
37
50
|
<argument>
|
38
51
|
<name>reporting_frequency</name>
|
39
52
|
<display_name>Reporting Frequency</display_name>
|
40
53
|
<description>The frequency at which to report timeseries output data.</description>
|
41
54
|
<type>Choice</type>
|
55
|
+
<units></units>
|
42
56
|
<required>true</required>
|
43
57
|
<model_dependent>false</model_dependent>
|
44
|
-
<default_value>
|
58
|
+
<default_value>Timestep</default_value>
|
45
59
|
<choices>
|
46
60
|
<choice>
|
47
61
|
<value>Detailed</value>
|
@@ -59,6 +73,10 @@
|
|
59
73
|
<value>Daily</value>
|
60
74
|
<display_name>Daily</display_name>
|
61
75
|
</choice>
|
76
|
+
<choice>
|
77
|
+
<value>BillingPeriod</value>
|
78
|
+
<display_name>BillingPeriod</display_name>
|
79
|
+
</choice>
|
62
80
|
<choice>
|
63
81
|
<value>Monthly</value>
|
64
82
|
<display_name>Monthly</display_name>
|
@@ -68,10 +86,12 @@
|
|
68
86
|
<display_name>Runperiod</display_name>
|
69
87
|
</choice>
|
70
88
|
</choices>
|
89
|
+
<min_value></min_value>
|
90
|
+
<max_value></max_value>
|
71
91
|
</argument>
|
72
92
|
</arguments>
|
73
|
-
<outputs/>
|
74
|
-
<provenances/>
|
93
|
+
<outputs />
|
94
|
+
<provenances />
|
75
95
|
<tags>
|
76
96
|
<tag>Reporting.QAQC</tag>
|
77
97
|
</tags>
|
@@ -94,12 +114,6 @@
|
|
94
114
|
<usage_type>test</usage_type>
|
95
115
|
<checksum>BDF687C1</checksum>
|
96
116
|
</file>
|
97
|
-
<file>
|
98
|
-
<filename>LICENSE.md</filename>
|
99
|
-
<filetype>md</filetype>
|
100
|
-
<usage_type>license</usage_type>
|
101
|
-
<checksum>B646B327</checksum>
|
102
|
-
</file>
|
103
117
|
<file>
|
104
118
|
<filename>README.md.erb</filename>
|
105
119
|
<filetype>erb</filetype>
|
@@ -113,16 +127,16 @@
|
|
113
127
|
<checksum>CC4BFFAF</checksum>
|
114
128
|
</file>
|
115
129
|
<file>
|
116
|
-
<filename>
|
130
|
+
<filename>LICENSE.md</filename>
|
117
131
|
<filetype>md</filetype>
|
118
|
-
<usage_type>
|
119
|
-
<checksum>
|
132
|
+
<usage_type>license</usage_type>
|
133
|
+
<checksum>EA283B74</checksum>
|
120
134
|
</file>
|
121
135
|
<file>
|
122
136
|
<filename>default_feature_reports_test.rb</filename>
|
123
137
|
<filetype>rb</filetype>
|
124
138
|
<usage_type>test</usage_type>
|
125
|
-
<checksum>
|
139
|
+
<checksum>56E0804B</checksum>
|
126
140
|
</file>
|
127
141
|
<file>
|
128
142
|
<version>
|
@@ -133,7 +147,14 @@
|
|
133
147
|
<filename>measure.rb</filename>
|
134
148
|
<filetype>rb</filetype>
|
135
149
|
<usage_type>script</usage_type>
|
136
|
-
<checksum>
|
150
|
+
<checksum>A00C8077</checksum>
|
151
|
+
</file>
|
152
|
+
<file>
|
153
|
+
<filename>README.md</filename>
|
154
|
+
<filetype>md</filetype>
|
155
|
+
<usage_type>readme</usage_type>
|
156
|
+
<checksum>0B68E96D</checksum>
|
137
157
|
</file>
|
138
158
|
</files>
|
139
159
|
</measure>
|
160
|
+
<error>wrong number of arguments (given 1, expected 0)</error>
|
data/lib/urbanopt/scenario.rb
CHANGED
@@ -36,6 +36,7 @@ require 'urbanopt/scenario/scenario_base'
|
|
36
36
|
require 'urbanopt/scenario/scenario_csv'
|
37
37
|
require 'urbanopt/scenario/scenario_post_processor_base'
|
38
38
|
require 'urbanopt/scenario/scenario_post_processor_default'
|
39
|
+
require 'urbanopt/scenario/scenario_post_processor_opendss'
|
39
40
|
require 'urbanopt/scenario/scenario_runner_base'
|
40
41
|
require 'urbanopt/scenario/scenario_runner_osw'
|
41
42
|
require 'urbanopt/scenario/simulation_dir_base'
|
@@ -73,25 +73,50 @@ 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 storage capacity
|
112
|
+
#
|
113
|
+
attr_accessor :total_storage_kwh
|
114
|
+
|
115
|
+
##
|
116
|
+
# _Float_ - Installed generator capacity
|
117
|
+
#
|
118
|
+
attr_accessor :total_generator_kw
|
119
|
+
|
95
120
|
##
|
96
121
|
# Initialize distributed generation system design and financial metrics.
|
97
122
|
#
|
@@ -113,10 +138,85 @@ module URBANopt
|
|
113
138
|
@year_one_bill_us_dollars = hash[:year_one_bill_us_dollars]
|
114
139
|
@total_energy_cost_us_dollars = hash[:total_energy_cost_us_dollars]
|
115
140
|
|
116
|
-
@
|
117
|
-
@
|
118
|
-
@
|
119
|
-
@
|
141
|
+
@total_solar_pv_kw = nil
|
142
|
+
@total_wind_kw = nil
|
143
|
+
@total_generator_kw = nil
|
144
|
+
@total_storage_kw = nil
|
145
|
+
@total_storage_kwh = nil
|
146
|
+
|
147
|
+
@solar_pv = []
|
148
|
+
if hash[:solar_pv].class == Hash
|
149
|
+
hash[:solar_pv] = [hash[:solar_pv]]
|
150
|
+
elsif hash[:solar_pv].nil?
|
151
|
+
hash[:solar_pv] = []
|
152
|
+
end
|
153
|
+
|
154
|
+
hash[:solar_pv].each do |s|
|
155
|
+
if !s[:size_kw].nil? && (s[:size_kw] != 0)
|
156
|
+
@solar_pv.push SolarPV.new(s)
|
157
|
+
if @total_solar_pv_kw.nil?
|
158
|
+
@total_solar_pv_kw = @solar_pv[-1].size_kw
|
159
|
+
else
|
160
|
+
@total_solar_pv_kw += @solar_pv[-1].size_kw
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
@wind = []
|
166
|
+
if hash[:wind].class == Hash
|
167
|
+
hash[:wind] = [hash[:wind]]
|
168
|
+
elsif hash[:wind].nil?
|
169
|
+
hash[:wind] = []
|
170
|
+
end
|
171
|
+
|
172
|
+
hash[:wind].each do |s|
|
173
|
+
if !s[:size_kw].nil? && (s[:size_kw] != 0)
|
174
|
+
@wind.push Wind.new(s)
|
175
|
+
if @total_wind_kw.nil?
|
176
|
+
@total_wind_kw = @wind[-1].size_kw
|
177
|
+
else
|
178
|
+
@total_wind_kw += @wind[-1].size_kw
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
@generator = []
|
184
|
+
if hash[:generator].class == Hash
|
185
|
+
hash[:generator] = [hash[:generator]]
|
186
|
+
elsif hash[:generator].nil?
|
187
|
+
hash[:generator] = []
|
188
|
+
end
|
189
|
+
|
190
|
+
hash[:generator].each do |s|
|
191
|
+
if !s[:size_kw].nil? && (s[:size_kw] != 0)
|
192
|
+
@generator.push Generator.new(s)
|
193
|
+
if @total_generator_kw.nil?
|
194
|
+
@total_generator_kw = @generator[-1].size_kw
|
195
|
+
else
|
196
|
+
@total_generator_kw += @generator[-1].size_kw
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
@storage = []
|
202
|
+
if hash[:storage].class == Hash
|
203
|
+
hash[:storage] = [hash[:storage]]
|
204
|
+
elsif hash[:storage].nil?
|
205
|
+
hash[:storage] = []
|
206
|
+
end
|
207
|
+
|
208
|
+
hash[:storage].each do |s|
|
209
|
+
if !s[:size_kw].nil? && (s[:size_kw] != 0)
|
210
|
+
@storage.push Storage.new(s)
|
211
|
+
if @total_storage_kw.nil?
|
212
|
+
@total_storage_kw = @storage[-1].size_kw
|
213
|
+
@total_storage_kwh = @storage[-1].size_kwh
|
214
|
+
else
|
215
|
+
@total_storage_kw += @storage[-1].size_kw
|
216
|
+
@total_storage_kwh += @storage[-1].size_kwh
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
120
220
|
|
121
221
|
# initialize class variables @@validator and @@schema
|
122
222
|
@@validator ||= Validator.new
|
@@ -126,6 +226,49 @@ module URBANopt
|
|
126
226
|
@@logger ||= URBANopt::Scenario::DefaultReports.logger
|
127
227
|
end
|
128
228
|
|
229
|
+
##
|
230
|
+
# Add a tech
|
231
|
+
##
|
232
|
+
def add_tech(name, tech)
|
233
|
+
if name == 'solar_pv'
|
234
|
+
@solar_pv.push tech
|
235
|
+
if @total_solar_pv_kw.nil?
|
236
|
+
@total_solar_pv_kw = tech.size_kw
|
237
|
+
else
|
238
|
+
@total_solar_pv_kw += tech.size_kw
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
if name == 'wind'
|
243
|
+
@wind.push tech
|
244
|
+
if @total_wind_kw.nil?
|
245
|
+
@total_wind_kw = tech.size_kw
|
246
|
+
else
|
247
|
+
@total_wind_kw += tech.size_kw
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
if name == 'storage'
|
252
|
+
@storage.push tech
|
253
|
+
if @total_storage_kw.nil?
|
254
|
+
@total_storage_kw = tech.size_kw
|
255
|
+
@total_storage_kwh = tech.size_kwh
|
256
|
+
else
|
257
|
+
@total_storage_kw += tech.size_kw
|
258
|
+
@total_storage_kwh += tech.size_kwh
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
if name == 'generator'
|
263
|
+
@generator.push tech
|
264
|
+
if @total_generator_kw.nil?
|
265
|
+
@total_generator_kw = tech.size_kw
|
266
|
+
else
|
267
|
+
@total_generator_kw += tech.size_kw
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
129
272
|
##
|
130
273
|
# Convert to a Hash equivalent for JSON serialization
|
131
274
|
##
|
@@ -137,12 +280,28 @@ module URBANopt
|
|
137
280
|
result[:year_one_energy_cost_us_dollars] = @year_one_energy_cost_us_dollars if @year_one_energy_cost_us_dollars
|
138
281
|
result[:year_one_demand_cost_us_dollars] = @year_one_demand_cost_us_dollars if @year_one_demand_cost_us_dollars
|
139
282
|
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[:
|
283
|
+
result[:total_solar_pv_kw] = @total_solar_pv_kw if @total_solar_pv_kw
|
284
|
+
result[:total_wind_kw] = @total_wind_kw if @total_wind_kw
|
285
|
+
result[:total_generator_kw] = @total_generator_kw if @total_generator_kw
|
286
|
+
result[:total_storage_kw] = @total_storage_kw if @total_storage_kw
|
287
|
+
result[:total_storage_kwh] = @total_storage_kwh if @total_storage_kwh
|
145
288
|
|
289
|
+
result[:solar_pv] = []
|
290
|
+
@solar_pv.each do |pv|
|
291
|
+
result[:solar_pv].push pv.to_hash
|
292
|
+
end
|
293
|
+
result[:wind] = []
|
294
|
+
@wind.each do |wind|
|
295
|
+
result[:wind].push wind.to_hash
|
296
|
+
end
|
297
|
+
result[:generator] = []
|
298
|
+
@generator.each do |generator|
|
299
|
+
result[:generator].push generator.to_hash
|
300
|
+
end
|
301
|
+
result[:storage] = []
|
302
|
+
@storage.each do |storage|
|
303
|
+
result[:storage].push storage.to_hash
|
304
|
+
end
|
146
305
|
return result
|
147
306
|
end
|
148
307
|
|
@@ -174,10 +333,43 @@ module URBANopt
|
|
174
333
|
existing_dgen.year_one_bill_us_dollars = add_values(existing_dgen.year_one_bill_us_dollars, new_dgen.year_one_bill_us_dollars)
|
175
334
|
existing_dgen.total_energy_cost_us_dollars = add_values(existing_dgen.total_energy_cost_us_dollars, new_dgen.total_energy_cost_us_dollars)
|
176
335
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
336
|
+
new_dgen.solar_pv.each do |pv|
|
337
|
+
existing_dgen.solar_pv.push pv
|
338
|
+
if existing_dgen.total_solar_pv_kw.nil?
|
339
|
+
existing_dgen.total_solar_pv_kw = pv.size_kw
|
340
|
+
else
|
341
|
+
existing_dgen.total_solar_pv_kw += pv.size_kw
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
new_dgen.wind.each do |wind|
|
346
|
+
existing_dgen.wind.push wind
|
347
|
+
if existing_dgen.total_wind_kw.nil?
|
348
|
+
existing_dgen.total_wind_kw = wind.size_kw
|
349
|
+
else
|
350
|
+
existing_dgen.total_wind_kw += wind.size_kw
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
new_dgen.storage.each do |storage|
|
355
|
+
existing_dgen.storage.push storage
|
356
|
+
if existing_dgen.total_wind_kw.nil?
|
357
|
+
existing_dgen.total_storage_kw = storage.size_kw
|
358
|
+
existing_dgen.total_storage_kwh = storage.size_kwh
|
359
|
+
else
|
360
|
+
existing_dgen.total_storage_kw += storage.size_kw
|
361
|
+
existing_dgen.total_storage_kwh += storage.size_kwh
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
new_dgen.generator.each do |generator|
|
366
|
+
existing_dgen.generator.push generator
|
367
|
+
if existing_dgen.total_wind_kw.nil?
|
368
|
+
existing_dgen.total_generator_kw = generator.size_kw
|
369
|
+
else
|
370
|
+
existing_dgen.total_generator_kw += generator.size_kw
|
371
|
+
end
|
372
|
+
end
|
181
373
|
|
182
374
|
return existing_dgen
|
183
375
|
end
|
@@ -33,9 +33,10 @@ require 'urbanopt/scenario/default_reports/program'
|
|
33
33
|
require 'urbanopt/scenario/default_reports/location'
|
34
34
|
require 'urbanopt/scenario/default_reports/reporting_period'
|
35
35
|
require 'urbanopt/scenario/default_reports/timeseries_csv'
|
36
|
-
require 'urbanopt/scenario/default_reports/validator'
|
37
36
|
require 'urbanopt/scenario/default_reports/distributed_generation'
|
37
|
+
require 'urbanopt/scenario/default_reports/power_distribution'
|
38
38
|
|
39
|
+
require 'urbanopt/scenario/default_reports/validator'
|
39
40
|
require 'json-schema'
|
40
41
|
|
41
42
|
require 'json'
|
@@ -52,7 +53,7 @@ module URBANopt
|
|
52
53
|
##
|
53
54
|
class FeatureReport
|
54
55
|
attr_accessor :id, :name, :directory_name, :feature_type, :timesteps_per_hour, :simulation_status,
|
55
|
-
:timeseries_csv, :location, :program, :design_parameters, :construction_costs, :reporting_periods, :distributed_generation # :nodoc:
|
56
|
+
:timeseries_csv, :location, :program, :design_parameters, :construction_costs, :reporting_periods, :distributed_generation, :power_distribution # :nodoc:
|
56
57
|
##
|
57
58
|
# Each FeatureReport object corresponds to a single Feature.
|
58
59
|
##
|
@@ -84,11 +85,16 @@ module URBANopt
|
|
84
85
|
@reporting_periods << ReportingPeriod.new(rp)
|
85
86
|
end
|
86
87
|
|
87
|
-
@distributed_generation = DistributedGeneration.new(hash[:distributed_generation]
|
88
|
+
@distributed_generation = DistributedGeneration.new(hash[:distributed_generation])
|
89
|
+
|
90
|
+
@power_distribution = PowerDistribution.new(hash[:power_distribution])
|
88
91
|
|
89
92
|
# initialize class variables @@validator and @@schema
|
90
93
|
@@validator ||= Validator.new
|
91
94
|
@@schema ||= @@validator.schema
|
95
|
+
|
96
|
+
# initialize feature report file name to be saved.
|
97
|
+
@file_name = 'default_feature_report'
|
92
98
|
end
|
93
99
|
|
94
100
|
##
|
@@ -101,6 +107,8 @@ module URBANopt
|
|
101
107
|
hash[:program] = {}
|
102
108
|
hash[:construction_costs] = []
|
103
109
|
hash[:reporting_periods] = []
|
110
|
+
hash[:distributed_generation] = {}
|
111
|
+
hash[:power_distribution] = {}
|
104
112
|
return hash
|
105
113
|
end
|
106
114
|
|
@@ -200,6 +208,8 @@ module URBANopt
|
|
200
208
|
|
201
209
|
result[:distributed_generation] = @distributed_generation.to_hash if @distributed_generation
|
202
210
|
|
211
|
+
result[:power_distribution] = @power_distribution.to_hash if @power_distribution
|
212
|
+
|
203
213
|
# validate feature_report properties against schema
|
204
214
|
if @@validator.validate(@@schema[:definitions][:FeatureReport][:properties], result).any?
|
205
215
|
raise "feature_report properties does not match schema: #{@@validator.validate(@@schema[:definitions][:FeatureReport][:properties], result)}"
|
@@ -207,6 +217,50 @@ module URBANopt
|
|
207
217
|
|
208
218
|
return result
|
209
219
|
end
|
220
|
+
|
221
|
+
##
|
222
|
+
# Saves the 'default_feature_report.json' and 'default_feature_report.csv' files
|
223
|
+
##
|
224
|
+
# [parameters]:
|
225
|
+
# +file_name+ - _String_ - Assign a name to the saved feature report results file without an extension
|
226
|
+
def save_feature_report(file_name = 'default_feature_report')
|
227
|
+
# reassign the initialize local variable @file_name to the file name input.
|
228
|
+
@file_name = file_name
|
229
|
+
|
230
|
+
# create feature reports directory
|
231
|
+
Dir.mkdir(File.join(@directory_name, 'feature_reports')) unless Dir.exist?(File.join(@directory_name, 'feature_reports'))
|
232
|
+
|
233
|
+
# save the csv data
|
234
|
+
old_timeseries_path = nil
|
235
|
+
if !@timeseries_csv.path.nil?
|
236
|
+
old_timeseries_path = @timeseries_csv.path
|
237
|
+
end
|
238
|
+
|
239
|
+
@timeseries_csv.path = File.join(@directory_name, 'feature_reports', file_name + '.csv')
|
240
|
+
@timeseries_csv.save_data
|
241
|
+
|
242
|
+
# feature_hash
|
243
|
+
feature_hash = to_hash
|
244
|
+
|
245
|
+
json_name_path = File.join(@directory_name, 'feature_reports', file_name + '.json')
|
246
|
+
|
247
|
+
File.open(json_name_path, 'w') do |f|
|
248
|
+
f.puts JSON.pretty_generate(feature_hash)
|
249
|
+
# make sure data is written to the disk one way or the other
|
250
|
+
begin
|
251
|
+
f.fsync
|
252
|
+
rescue StandardError
|
253
|
+
f.flush
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
if !old_timeseries_path.nil?
|
258
|
+
@timeseries_csv.path = old_timeseries_path
|
259
|
+
else
|
260
|
+
@timeseries_csv.path = File.join(@directory_name, 'feature_reports', file_name + '.csv')
|
261
|
+
end
|
262
|
+
return true
|
263
|
+
end
|
210
264
|
end
|
211
265
|
end
|
212
266
|
end
|