urbanopt-scenario 0.7.0 → 0.9.0
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/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,
|