urbanopt-scenario 0.7.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/nightly_build.yml +40 -0
- data/CHANGELOG.md +31 -1
- data/Gemfile +2 -2
- data/LICENSE.md +1 -3
- data/README.md +5 -3
- data/doc_templates/LICENSE.md +37 -0
- data/doc_templates/README.md.erb +42 -0
- data/doc_templates/copyright_erb.txt +41 -0
- data/doc_templates/copyright_js.txt +4 -0
- data/doc_templates/copyright_ruby.txt +39 -0
- data/docs/package-lock.json +4712 -3863
- data/docs/package.json +1 -1
- data/lib/urbanopt/scenario/default_reports.rb +1 -1
- data/lib/urbanopt/scenario/extension.rb +1 -1
- data/lib/urbanopt/scenario/logger.rb +1 -1
- data/lib/urbanopt/scenario/scenario_base.rb +1 -1
- data/lib/urbanopt/scenario/scenario_csv.rb +1 -1
- data/lib/urbanopt/scenario/scenario_datapoint_base.rb +1 -1
- data/lib/urbanopt/scenario/scenario_post_processor_base.rb +1 -1
- data/lib/urbanopt/scenario/scenario_post_processor_default.rb +1 -1
- data/lib/urbanopt/scenario/scenario_post_processor_disco.rb +159 -0
- data/lib/urbanopt/scenario/scenario_post_processor_opendss.rb +159 -4
- data/lib/urbanopt/scenario/scenario_runner_base.rb +1 -1
- data/lib/urbanopt/scenario/scenario_runner_osw.rb +1 -1
- data/lib/urbanopt/scenario/scenario_visualization.rb +24 -7
- data/lib/urbanopt/scenario/simulation_dir_base.rb +1 -1
- data/lib/urbanopt/scenario/simulation_dir_osw.rb +1 -4
- data/lib/urbanopt/scenario/simulation_mapper_base.rb +1 -1
- data/lib/urbanopt/scenario/version.rb +2 -2
- data/lib/urbanopt/scenario.rb +2 -1
- data/lib/urbanopt-scenario.rb +1 -1
- data/urbanopt-scenario-gem.gemspec +4 -11
- metadata +41 -6
data/docs/package.json
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# *********************************************************************************
|
2
|
-
# URBANopt™, Copyright (c) 2019-
|
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-
|
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-
|
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-
|
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-
|
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-
|
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-
|
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-
|
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,
|
@@ -0,0 +1,159 @@
|
|
1
|
+
# *********************************************************************************
|
2
|
+
# URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
|
3
|
+
# contributors. All rights reserved.
|
4
|
+
|
5
|
+
# Redistribution and use in source and binary forms, with or without modification,
|
6
|
+
# are permitted provided that the following conditions are met:
|
7
|
+
|
8
|
+
# Redistributions of source code must retain the above copyright notice, this list
|
9
|
+
# of conditions and the following disclaimer.
|
10
|
+
|
11
|
+
# Redistributions in binary form must reproduce the above copyright notice, this
|
12
|
+
# list of conditions and the following disclaimer in the documentation and/or other
|
13
|
+
# materials provided with the distribution.
|
14
|
+
|
15
|
+
# Neither the name of the copyright holder nor the names of its contributors may be
|
16
|
+
# used to endorse or promote products derived from this software without specific
|
17
|
+
# prior written permission.
|
18
|
+
|
19
|
+
# Redistribution of this software, without modification, must refer to the software
|
20
|
+
# by the same designation. Redistribution of a modified version of this software
|
21
|
+
# (i) may not refer to the modified version by the same designation, or by any
|
22
|
+
# confusingly similar designation, and (ii) must refer to the underlying software
|
23
|
+
# originally provided by Alliance as “URBANopt”. Except to comply with the foregoing,
|
24
|
+
# the term “URBANopt”, or any confusingly similar designation may not be used to
|
25
|
+
# refer to any modified version of this software or any modified version of the
|
26
|
+
# underlying software originally provided by Alliance without the prior written
|
27
|
+
# consent of Alliance.
|
28
|
+
|
29
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
30
|
+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
31
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
32
|
+
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
33
|
+
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
34
|
+
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
35
|
+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
36
|
+
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
37
|
+
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
38
|
+
# OF THE POSSIBILITY OF SUCH DAMAGE.
|
39
|
+
# *********************************************************************************
|
40
|
+
|
41
|
+
require 'urbanopt/reporting/default_reports'
|
42
|
+
|
43
|
+
require 'csv'
|
44
|
+
require 'json'
|
45
|
+
require 'fileutils'
|
46
|
+
|
47
|
+
module URBANopt
|
48
|
+
module Scenario
|
49
|
+
class DISCOPostProcessor
|
50
|
+
##
|
51
|
+
# DISCOPostProcessor post-processes DISCO results to selected DISCO results and
|
52
|
+
# integrate them in scenario and feature reports.
|
53
|
+
##
|
54
|
+
# [parameters:]
|
55
|
+
# * +scenaro_report+ - _ScenarioBase_ - An object of Scenario_report class.
|
56
|
+
# * +disco_results_dir_name+ - _directory name of disco results
|
57
|
+
def initialize(scenario_report, disco_results_dir_name = 'disco')
|
58
|
+
if !scenario_report.nil?
|
59
|
+
@scenario_report = scenario_report
|
60
|
+
@disco_results_dir = File.join(@scenario_report.directory_name, disco_results_dir_name)
|
61
|
+
else
|
62
|
+
raise 'scenario_report is not valid'
|
63
|
+
end
|
64
|
+
|
65
|
+
# initialize disco data
|
66
|
+
@disco_data = {}
|
67
|
+
|
68
|
+
# initialize disco json results
|
69
|
+
@disco_json_results = {}
|
70
|
+
|
71
|
+
# initialize logger
|
72
|
+
@@logger ||= URBANopt::Reporting::DefaultReports.logger
|
73
|
+
end
|
74
|
+
|
75
|
+
# load disco data (if exists)
|
76
|
+
def load_disco_data
|
77
|
+
|
78
|
+
# load disco upgrade summary
|
79
|
+
disco_json_filename = File.join(@disco_results_dir, 'upgrade_summary.json')
|
80
|
+
if File.exist?(disco_json_filename)
|
81
|
+
@disco_json_results = JSON.parse(File.read(disco_json_filename))
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
# load disco data
|
87
|
+
def load_data
|
88
|
+
# load selected disco data
|
89
|
+
load_disco_data
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
##
|
94
|
+
# save disco scenario fields
|
95
|
+
##
|
96
|
+
def save_disco_scenario
|
97
|
+
@scenario_report.scenario_power_distribution_cost = URBANopt::Reporting::DefaultReports::ScenarioPowerDistributionCost.new
|
98
|
+
|
99
|
+
# RESULTS
|
100
|
+
|
101
|
+
res = []
|
102
|
+
# read result from JSON report
|
103
|
+
res = @disco_json_results['results']
|
104
|
+
@scenario_report.scenario_power_distribution_cost.results = res
|
105
|
+
|
106
|
+
|
107
|
+
|
108
|
+
# OUTPUTS
|
109
|
+
|
110
|
+
out = {}
|
111
|
+
# read result from JSON report
|
112
|
+
out[:log_file] = @disco_json_results['outputs']['log_file']
|
113
|
+
out[:jobs] = []
|
114
|
+
@disco_json_results['outputs']['jobs'].each do |job|
|
115
|
+
out[:jobs] << job
|
116
|
+
end
|
117
|
+
@scenario_report.scenario_power_distribution_cost.outputs = out
|
118
|
+
|
119
|
+
# VIOLATION SUMMARY
|
120
|
+
|
121
|
+
vio = []
|
122
|
+
# read result from JSON report
|
123
|
+
vio = @disco_json_results['violation_summary']
|
124
|
+
@scenario_report.scenario_power_distribution_cost.violation_summary = vio
|
125
|
+
|
126
|
+
# COSTS PER EQUIPMENT
|
127
|
+
cos = []
|
128
|
+
# read result from JSON report
|
129
|
+
cos = @disco_json_results['costs_per_equipment']
|
130
|
+
@scenario_report.scenario_power_distribution_cost.costs_per_equipment = cos
|
131
|
+
|
132
|
+
# EQUIPMENT
|
133
|
+
equ = []
|
134
|
+
# read result from JSON report
|
135
|
+
equ = @disco_json_results['equipment']
|
136
|
+
@scenario_report.scenario_power_distribution_cost.equipment = equ
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
##
|
141
|
+
# run disco post_processor
|
142
|
+
##
|
143
|
+
def run
|
144
|
+
|
145
|
+
# load data
|
146
|
+
load_data
|
147
|
+
|
148
|
+
# save additional global disco fields
|
149
|
+
save_disco_scenario
|
150
|
+
|
151
|
+
# save the updated scenario reports
|
152
|
+
# set save_feature_reports to false since only the scenario reports should be saved
|
153
|
+
# now, set save csv reports to false
|
154
|
+
@scenario_report.save(file_name = 'scenario_report_disco', save_feature_reports = false, save_csv_reports = false)
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# *********************************************************************************
|
2
|
-
# URBANopt™, Copyright (c) 2019-
|
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,
|
@@ -71,6 +71,9 @@ module URBANopt
|
|
71
71
|
# initialize feature_reports data
|
72
72
|
@feature_reports_data = {}
|
73
73
|
|
74
|
+
# initialize opendss json results
|
75
|
+
@opendss_json_results = {}
|
76
|
+
|
74
77
|
# initialize logger
|
75
78
|
@@logger ||= URBANopt::Reporting::DefaultReports.logger
|
76
79
|
end
|
@@ -85,6 +88,12 @@ module URBANopt
|
|
85
88
|
@opendss_data[feature_report.id] = opendss_csv
|
86
89
|
end
|
87
90
|
|
91
|
+
# load Model.json results (if exists)
|
92
|
+
opendss_json_filename = File.join(@opendss_results_dir, 'json_files', 'Model.json')
|
93
|
+
if File.exist?(opendss_json_filename)
|
94
|
+
@opendss_json_results = JSON.parse(File.read(opendss_json_filename))
|
95
|
+
end
|
96
|
+
|
88
97
|
## load transformers data
|
89
98
|
|
90
99
|
# transformers results directory path
|
@@ -140,11 +149,46 @@ module URBANopt
|
|
140
149
|
return output
|
141
150
|
end
|
142
151
|
|
152
|
+
# computer transformer results
|
153
|
+
def compute_transformer_results
|
154
|
+
# using values from opendss Model.json
|
155
|
+
results = {}
|
156
|
+
# retrieve all transformers
|
157
|
+
trsfmrs = @opendss_json_results['model'].select { |d| d['class'] == 'PowerTransformer' }
|
158
|
+
trsfmrs.each do |item|
|
159
|
+
t = { 'nominal_capacity': nil, 'reactance_resistance_ratio': nil }
|
160
|
+
name = item['name']['value']
|
161
|
+
|
162
|
+
# nominal capacity in kVA (Model.json stores it in VA)
|
163
|
+
# TODO: assuming that all windings would have the same rated power, so grabbing first one
|
164
|
+
begin
|
165
|
+
t['nominal_capacity'] = item['windings']['value'][0]['rated_power']['value'] / 1000
|
166
|
+
rescue StandardError
|
167
|
+
end
|
168
|
+
|
169
|
+
# reactance to resistance ratio:
|
170
|
+
begin
|
171
|
+
# TODO: grabbing the first one for now. Handle when there are multiple reactances and winding resistances
|
172
|
+
reactance = item['reactances']['value'][0]['value']
|
173
|
+
resistance = item['windings']['value'][0]['resistance']['value']
|
174
|
+
|
175
|
+
t['reactance_resistance_ratio'] = reactance / resistance
|
176
|
+
rescue StandardError
|
177
|
+
end
|
178
|
+
|
179
|
+
results[name] = t
|
180
|
+
end
|
181
|
+
|
182
|
+
return results
|
183
|
+
end
|
184
|
+
|
143
185
|
# add feature reports for transformers
|
144
186
|
def save_transformers_reports
|
187
|
+
t_res = compute_transformer_results
|
188
|
+
|
145
189
|
@opendss_data.each_key do |k|
|
146
190
|
if k.include? 'Transformer'
|
147
|
-
|
191
|
+
t_key = k.sub('Transformer.', '')
|
148
192
|
# create transformer directory
|
149
193
|
transformer_dir = File.join(@scenario_report.directory_name, k)
|
150
194
|
FileUtils.mkdir_p(File.join(transformer_dir, 'feature_reports'))
|
@@ -153,6 +197,13 @@ module URBANopt
|
|
153
197
|
# store under voltages and over voltages
|
154
198
|
under_voltage_hrs = 0
|
155
199
|
over_voltage_hrs = 0
|
200
|
+
nominal_capacity = nil
|
201
|
+
r_r_ratio = nil
|
202
|
+
begin
|
203
|
+
nominal_capacity = t_res[t_key]['nominal_capacity']
|
204
|
+
r_r_ratio = t_res[t_key]['reactance_resistance_ratio']
|
205
|
+
rescue StandardError
|
206
|
+
end
|
156
207
|
|
157
208
|
transformer_csv = CSV.generate do |csv|
|
158
209
|
@opendss_data[k].each_with_index do |row, i|
|
@@ -178,9 +229,11 @@ module URBANopt
|
|
178
229
|
timesteps_per_hour: @scenario_report.timesteps_per_hour,
|
179
230
|
simulation_status: 'complete')
|
180
231
|
|
181
|
-
# assign results to
|
232
|
+
# assign results to transformer report
|
182
233
|
transformer_report.power_distribution.over_voltage_hours = over_voltage_hrs
|
183
234
|
transformer_report.power_distribution.under_voltage_hours = under_voltage_hrs
|
235
|
+
transformer_report.power_distribution.nominal_capacity = nominal_capacity
|
236
|
+
transformer_report.power_distribution.reactance_resistance_ratio = r_r_ratio
|
184
237
|
|
185
238
|
## save transformer JSON file
|
186
239
|
# transformer_hash
|
@@ -226,6 +279,9 @@ module URBANopt
|
|
226
279
|
def add_summary_results(feature_report)
|
227
280
|
under_voltage_hrs = 0
|
228
281
|
over_voltage_hrs = 0
|
282
|
+
kw = nil
|
283
|
+
kvar = nil
|
284
|
+
nominal_voltage = nil
|
229
285
|
|
230
286
|
id = feature_report.id
|
231
287
|
@opendss_data[id].each_with_index do |row, i|
|
@@ -242,13 +298,109 @@ module URBANopt
|
|
242
298
|
end
|
243
299
|
end
|
244
300
|
|
301
|
+
# also add additional keys for OpenDSS Loads
|
302
|
+
loads = @opendss_json_results['model'].select { |d| d['class'] == 'Load' }
|
303
|
+
if loads
|
304
|
+
bld_load = loads.select { |d| d['name']['value'] == id }
|
305
|
+
if bld_load
|
306
|
+
if bld_load.is_a?(Array)
|
307
|
+
bld_load = bld_load[0]
|
308
|
+
end
|
309
|
+
kw = 0
|
310
|
+
kvar = 0
|
311
|
+
# nominal_voltage (V)
|
312
|
+
nominal_voltage = bld_load['nominal_voltage']['value']
|
313
|
+
if nominal_voltage < 300
|
314
|
+
nominal_voltage *= Math.sqrt(3)
|
315
|
+
end
|
316
|
+
nominal_voltage = nominal_voltage
|
317
|
+
|
318
|
+
# max_power_kw
|
319
|
+
# max_reactive_power_kvar
|
320
|
+
pls = bld_load['phase_loads']['value']
|
321
|
+
pls.each do |pl|
|
322
|
+
kw += pl['p']['value']
|
323
|
+
kvar += pl['q']['value']
|
324
|
+
end
|
325
|
+
|
326
|
+
kw /= 1000
|
327
|
+
kvar /= 1000
|
328
|
+
else
|
329
|
+
@@logger.info("No load matching id #{id} found in OpenDSS Model.json results")
|
330
|
+
end
|
331
|
+
else
|
332
|
+
@@logger.info('No loads information found in OpenDSS Model.json results file')
|
333
|
+
end
|
245
334
|
# assign results to feature report
|
246
335
|
feature_report.power_distribution.over_voltage_hours = over_voltage_hrs
|
247
336
|
feature_report.power_distribution.under_voltage_hours = under_voltage_hrs
|
337
|
+
feature_report.power_distribution.nominal_voltage = nominal_voltage
|
338
|
+
feature_report.power_distribution.max_power_kw = kw
|
339
|
+
feature_report.power_distribution.max_reactive_power_kvar = kvar
|
248
340
|
|
249
341
|
return feature_report
|
250
342
|
end
|
251
343
|
|
344
|
+
##
|
345
|
+
# save opendss scenario fields
|
346
|
+
##
|
347
|
+
def save_opendss_scenario
|
348
|
+
@scenario_report.scenario_power_distribution = URBANopt::Reporting::DefaultReports::ScenarioPowerDistribution.new
|
349
|
+
|
350
|
+
## SUBSTATION
|
351
|
+
subs = []
|
352
|
+
feeders = @opendss_json_results['model'].select { |d| d['class'] == 'Feeder_metadata' }
|
353
|
+
|
354
|
+
feeders.each do |item|
|
355
|
+
# nominal_voltage - RMS voltage low side (V)
|
356
|
+
substation = { nominal_voltage: item['nominal_voltage']['value'] }
|
357
|
+
subs.append(substation)
|
358
|
+
end
|
359
|
+
@scenario_report.scenario_power_distribution.substations = subs
|
360
|
+
|
361
|
+
## LINES
|
362
|
+
# retrieve all lines
|
363
|
+
dist_lines = []
|
364
|
+
lines = @opendss_json_results['model'].select { |d| d['class'] == 'Line' }
|
365
|
+
lines.each do |item|
|
366
|
+
line = {}
|
367
|
+
# length (m)
|
368
|
+
line['length'] = item['length']['value']
|
369
|
+
|
370
|
+
# max ampacity: iterate through N-1 wires and add up ampacity
|
371
|
+
amps = 0
|
372
|
+
num_wires = item['wires']['value'].length
|
373
|
+
(0..(num_wires - 1)).each do |i|
|
374
|
+
amps += item['wires']['value'][i]['ampacity']['value']
|
375
|
+
end
|
376
|
+
line['ampacity'] = amps
|
377
|
+
|
378
|
+
# commercial line type
|
379
|
+
line['commercial_line_type'] = []
|
380
|
+
item['wires']['value'].each do |wire|
|
381
|
+
line['commercial_line_type'].append(wire['nameclass']['value'])
|
382
|
+
end
|
383
|
+
dist_lines.append(line)
|
384
|
+
end
|
385
|
+
@scenario_report.scenario_power_distribution.distribution_lines = dist_lines
|
386
|
+
|
387
|
+
# CAPACITORS
|
388
|
+
caps = []
|
389
|
+
capacitors = @opendss_json_results['model'].select { |d| d['class'] == 'Capacitors' }
|
390
|
+
capacitors.each do |item|
|
391
|
+
cap = 0
|
392
|
+
item['phase_capacitors']['value'].each do |pc|
|
393
|
+
if pc['var']['value']
|
394
|
+
cap += pc['var']['value']
|
395
|
+
end
|
396
|
+
end
|
397
|
+
caps.append({ nominal_capacity: cap })
|
398
|
+
end
|
399
|
+
@scenario_report.scenario_power_distribution.capacitors = caps
|
400
|
+
end
|
401
|
+
|
402
|
+
|
403
|
+
|
252
404
|
##
|
253
405
|
# run opendss post_processor
|
254
406
|
##
|
@@ -266,7 +418,7 @@ module URBANopt
|
|
266
418
|
id = feature_report.id
|
267
419
|
updated_feature_csv = merge_data(@feature_reports_data[id], @opendss_data[id])
|
268
420
|
|
269
|
-
# save
|
421
|
+
# save feature reports
|
270
422
|
feature_report.save_json_report('default_feature_report_opendss')
|
271
423
|
|
272
424
|
# resave updated csv report
|
@@ -276,6 +428,9 @@ module URBANopt
|
|
276
428
|
# add transformer reports
|
277
429
|
save_transformers_reports
|
278
430
|
|
431
|
+
# save additional global opendss fields
|
432
|
+
save_opendss_scenario
|
433
|
+
|
279
434
|
# save the updated scenario reports
|
280
435
|
# set save_feature_reports to false since only the scenario reports should be saved now
|
281
436
|
@scenario_report.save(file_name = 'scenario_report_opendss', save_feature_reports = false)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# *********************************************************************************
|
2
|
-
# URBANopt™, Copyright (c) 2019-
|
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-
|
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-
|
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,
|
@@ -45,10 +45,11 @@ require 'json'
|
|
45
45
|
module URBANopt
|
46
46
|
module Scenario
|
47
47
|
class ResultVisualization
|
48
|
-
def self.create_visualization(
|
48
|
+
def self.create_visualization(default_report_list, feature = true, feature_names = false)
|
49
49
|
@all_results = []
|
50
50
|
name = nil
|
51
|
-
|
51
|
+
|
52
|
+
default_report_list.each do |folder|
|
52
53
|
# create visualization for scenarios
|
53
54
|
case feature
|
54
55
|
when false
|
@@ -57,11 +58,14 @@ module URBANopt
|
|
57
58
|
|
58
59
|
# create visualization for features
|
59
60
|
when true
|
60
|
-
index =
|
61
|
+
index = default_report_list.index(folder)
|
61
62
|
name = "#{folder.split('/')[-3]}-#{feature_names[index]}"
|
62
63
|
csv_dir = folder
|
63
64
|
end
|
64
65
|
|
66
|
+
# get JSON report
|
67
|
+
json_report = folder.gsub('.csv', '.json')
|
68
|
+
|
65
69
|
if File.exist?(csv_dir)
|
66
70
|
size = CSV.open(csv_dir).readlines.size
|
67
71
|
|
@@ -210,6 +214,7 @@ module URBANopt
|
|
210
214
|
results['name'] = name
|
211
215
|
results['monthly_values'] = {}
|
212
216
|
results['annual_values'] = {}
|
217
|
+
results['qaqc_flags'] = {}
|
213
218
|
|
214
219
|
if @jan_next_year_index.nil? || @feb_index.nil? || @mar_index.nil? || @apr_index.nil? || @may_index.nil? || @jun_index.nil? || @jul_index.nil? || @aug_index.nil? || @sep_index.nil? || @oct_index.nil? || @nov_index.nil? || @dec_index.nil?
|
215
220
|
results['complete_simulation'] = false
|
@@ -230,6 +235,18 @@ module URBANopt
|
|
230
235
|
end
|
231
236
|
end
|
232
237
|
|
238
|
+
# QAQC flags by category (if present)
|
239
|
+
if File.exist?(json_report)
|
240
|
+
report_data = JSON.parse(File.read(json_report))
|
241
|
+
if feature == false
|
242
|
+
# adjust nesting for scenario report
|
243
|
+
report_data = report_data['scenario_report']
|
244
|
+
end
|
245
|
+
|
246
|
+
if report_data.key?('qaqc_flags')
|
247
|
+
results['qaqc_flags'] = report_data['qaqc_flags']
|
248
|
+
end
|
249
|
+
end
|
233
250
|
end
|
234
251
|
|
235
252
|
unless results.nil?
|
@@ -237,13 +254,13 @@ module URBANopt
|
|
237
254
|
end
|
238
255
|
end
|
239
256
|
|
240
|
-
# create
|
257
|
+
# create js file with required data stored in a variable
|
241
258
|
if feature == false
|
242
259
|
# In case of scenario visualization store result at top of the run folder
|
243
|
-
results_path = File.expand_path('../../scenarioData.js',
|
260
|
+
results_path = File.expand_path('../../scenarioData.js', default_report_list[0])
|
244
261
|
else
|
245
262
|
# In case of feature visualization store result at top of scenario folder folder
|
246
|
-
results_path = File.expand_path('../../../scenarioData.js',
|
263
|
+
results_path = File.expand_path('../../../scenarioData.js', default_report_list[0])
|
247
264
|
end
|
248
265
|
File.open(results_path, 'w') do |file|
|
249
266
|
file << "var scenarioData = #{JSON.pretty_generate(@all_results)};"
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# *********************************************************************************
|
2
|
-
# URBANopt™, Copyright (c) 2019-
|
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-
|
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,
|
@@ -174,9 +174,6 @@ module URBANopt
|
|
174
174
|
# depends on the feature file
|
175
175
|
dependencies << scenario.feature_file.path
|
176
176
|
|
177
|
-
# depends on the csv file
|
178
|
-
dependencies << scenario.csv_file
|
179
|
-
|
180
177
|
# depends on the mapper classes
|
181
178
|
Dir.glob(File.join(scenario.mapper_files_dir, '*')).each do |f|
|
182
179
|
dependencies << f
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# *********************************************************************************
|
2
|
-
# URBANopt™, Copyright (c) 2019-
|
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-
|
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,6 +40,6 @@
|
|
40
40
|
|
41
41
|
module URBANopt
|
42
42
|
module Scenario
|
43
|
-
VERSION = '0.
|
43
|
+
VERSION = '0.9.0'.freeze
|
44
44
|
end
|
45
45
|
end
|
data/lib/urbanopt/scenario.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# *********************************************************************************
|
2
|
-
# URBANopt™, Copyright (c) 2019-
|
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,
|
@@ -47,6 +47,7 @@ require 'urbanopt/scenario/scenario_csv'
|
|
47
47
|
require 'urbanopt/scenario/scenario_post_processor_base'
|
48
48
|
require 'urbanopt/scenario/scenario_post_processor_default'
|
49
49
|
require 'urbanopt/scenario/scenario_post_processor_opendss'
|
50
|
+
require 'urbanopt/scenario/scenario_post_processor_disco'
|
50
51
|
require 'urbanopt/scenario/scenario_runner_base'
|
51
52
|
require 'urbanopt/scenario/scenario_runner_osw'
|
52
53
|
require 'urbanopt/scenario/simulation_dir_base'
|
data/lib/urbanopt-scenario.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# *********************************************************************************
|
2
|
-
# URBANopt™, Copyright (c) 2019-
|
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,
|