urbanopt-reopt 0.5.0 → 0.6.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/CHANGELOG.md +52 -0
- data/Gemfile +1 -1
- data/LICENSE.md +33 -21
- data/Rakefile +16 -6
- data/docs/package-lock.json +17551 -6268
- data/docs/package.json +10 -2
- data/lib/urbanopt-reopt.rb +16 -6
- data/lib/urbanopt/reopt.rb +16 -6
- data/lib/urbanopt/reopt/extension.rb +16 -6
- data/lib/urbanopt/reopt/feature_report_adapter.rb +90 -70
- data/lib/urbanopt/reopt/reopt_lite_api.rb +29 -17
- data/lib/urbanopt/reopt/reopt_logger.rb +16 -6
- data/lib/urbanopt/reopt/reopt_post_processor.rb +18 -10
- data/lib/urbanopt/reopt/scenario/reopt_scenario_csv.rb +16 -6
- data/lib/urbanopt/reopt/scenario_report_adapter.rb +84 -72
- data/lib/urbanopt/reopt/utilities.rb +111 -0
- data/lib/urbanopt/reopt/version.rb +17 -7
- data/lib/urbanopt/reopt_scenario.rb +16 -6
- data/urbanopt-reopt.gemspec +3 -3
- metadata +10 -10
- data/a.txt +0 -1
data/docs/package.json
CHANGED
@@ -13,10 +13,18 @@
|
|
13
13
|
"highlight.js": "^10.4.1",
|
14
14
|
"json-schema-ref-parser": "^6.1.0",
|
15
15
|
"json-schema-view-js": "git+https://git@github.com/bgschiller/json-schema-view-js.git",
|
16
|
-
"vuepress": "^
|
16
|
+
"vuepress": "^1.8.2",
|
17
17
|
"webpack-dev-middleware": "^3.6.0"
|
18
18
|
},
|
19
19
|
"devDependencies": {
|
20
|
-
"
|
20
|
+
"braces": "^3.0.2",
|
21
|
+
"chokidar": ">=3.5.1",
|
22
|
+
"fsevents": ">=2.3.2",
|
23
|
+
"gh-pages": "^2.0.1",
|
24
|
+
"ini": "^2.0.0",
|
25
|
+
"is-svg": "4.3.1",
|
26
|
+
"serialize-javascript": "^5.0.1",
|
27
|
+
"ssri": "8.0.1",
|
28
|
+
"yargs-parser": "^18.1.1"
|
21
29
|
}
|
22
30
|
}
|
data/lib/urbanopt-reopt.rb
CHANGED
@@ -1,21 +1,31 @@
|
|
1
1
|
# *********************************************************************************
|
2
|
-
# URBANopt
|
2
|
+
# URBANopt™, Copyright (c) 2019-2021, 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,
|
6
6
|
# are permitted provided that the following conditions are met:
|
7
|
-
|
7
|
+
|
8
8
|
# Redistributions of source code must retain the above copyright notice, this list
|
9
9
|
# of conditions and the following disclaimer.
|
10
|
-
|
10
|
+
|
11
11
|
# Redistributions in binary form must reproduce the above copyright notice, this
|
12
12
|
# list of conditions and the following disclaimer in the documentation and/or other
|
13
13
|
# materials provided with the distribution.
|
14
|
-
|
14
|
+
|
15
15
|
# Neither the name of the copyright holder nor the names of its contributors may be
|
16
16
|
# used to endorse or promote products derived from this software without specific
|
17
17
|
# prior written permission.
|
18
|
-
|
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
|
+
|
19
29
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
20
30
|
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
21
31
|
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
data/lib/urbanopt/reopt.rb
CHANGED
@@ -1,21 +1,31 @@
|
|
1
1
|
# *********************************************************************************
|
2
|
-
# URBANopt
|
2
|
+
# URBANopt™, Copyright (c) 2019-2021, 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,
|
6
6
|
# are permitted provided that the following conditions are met:
|
7
|
-
|
7
|
+
|
8
8
|
# Redistributions of source code must retain the above copyright notice, this list
|
9
9
|
# of conditions and the following disclaimer.
|
10
|
-
|
10
|
+
|
11
11
|
# Redistributions in binary form must reproduce the above copyright notice, this
|
12
12
|
# list of conditions and the following disclaimer in the documentation and/or other
|
13
13
|
# materials provided with the distribution.
|
14
|
-
|
14
|
+
|
15
15
|
# Neither the name of the copyright holder nor the names of its contributors may be
|
16
16
|
# used to endorse or promote products derived from this software without specific
|
17
17
|
# prior written permission.
|
18
|
-
|
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
|
+
|
19
29
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
20
30
|
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
21
31
|
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
@@ -1,21 +1,31 @@
|
|
1
1
|
# *********************************************************************************
|
2
|
-
# URBANopt
|
2
|
+
# URBANopt™, Copyright (c) 2019-2021, 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,
|
6
6
|
# are permitted provided that the following conditions are met:
|
7
|
-
|
7
|
+
|
8
8
|
# Redistributions of source code must retain the above copyright notice, this list
|
9
9
|
# of conditions and the following disclaimer.
|
10
|
-
|
10
|
+
|
11
11
|
# Redistributions in binary form must reproduce the above copyright notice, this
|
12
12
|
# list of conditions and the following disclaimer in the documentation and/or other
|
13
13
|
# materials provided with the distribution.
|
14
|
-
|
14
|
+
|
15
15
|
# Neither the name of the copyright holder nor the names of its contributors may be
|
16
16
|
# used to endorse or promote products derived from this software without specific
|
17
17
|
# prior written permission.
|
18
|
-
|
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
|
+
|
19
29
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
20
30
|
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
21
31
|
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
@@ -1,21 +1,31 @@
|
|
1
1
|
# *********************************************************************************
|
2
|
-
# URBANopt
|
2
|
+
# URBANopt™, Copyright (c) 2019-2021, 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,
|
6
6
|
# are permitted provided that the following conditions are met:
|
7
|
-
|
7
|
+
|
8
8
|
# Redistributions of source code must retain the above copyright notice, this list
|
9
9
|
# of conditions and the following disclaimer.
|
10
|
-
|
10
|
+
|
11
11
|
# Redistributions in binary form must reproduce the above copyright notice, this
|
12
12
|
# list of conditions and the following disclaimer in the documentation and/or other
|
13
13
|
# materials provided with the distribution.
|
14
|
-
|
14
|
+
|
15
15
|
# Neither the name of the copyright holder nor the names of its contributors may be
|
16
16
|
# used to endorse or promote products derived from this software without specific
|
17
17
|
# prior written permission.
|
18
|
-
|
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
|
+
|
19
29
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
20
30
|
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
21
31
|
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
@@ -32,6 +42,7 @@ require 'urbanopt/reporting/default_reports'
|
|
32
42
|
require 'urbanopt/reopt/reopt_logger'
|
33
43
|
require 'csv'
|
34
44
|
require 'matrix'
|
45
|
+
require_relative 'utilities'
|
35
46
|
require 'time'
|
36
47
|
|
37
48
|
module URBANopt # :nodoc:
|
@@ -87,24 +98,30 @@ module URBANopt # :nodoc:
|
|
87
98
|
reopt_inputs[:Scenario][:Site][:latitude] = feature_report.location.latitude_deg
|
88
99
|
reopt_inputs[:Scenario][:Site][:longitude] = feature_report.location.longitude_deg
|
89
100
|
|
90
|
-
# Parse Optional FeatureReport metrics
|
91
|
-
|
92
|
-
|
101
|
+
# Parse Optional FeatureReport metrics - do not overwrite from assumptions file
|
102
|
+
if reopt_inputs[:Scenario][:Site][:roof_squarefeet].nil?
|
103
|
+
unless feature_report.program.roof_area_sqft.nil?
|
104
|
+
reopt_inputs[:Scenario][:Site][:roof_squarefeet] = feature_report.program.roof_area_sqft[:available_roof_area_sqft]
|
105
|
+
end
|
93
106
|
end
|
94
107
|
|
95
|
-
|
96
|
-
|
108
|
+
if reopt_inputs[:Scenario][:Site][:land_acres].nil?
|
109
|
+
unless feature_report.program.site_area_sqft.nil?
|
110
|
+
reopt_inputs[:Scenario][:Site][:land_acres] = feature_report.program.site_area_sqft * 1.0 / 43560 # acres/sqft
|
111
|
+
end
|
97
112
|
end
|
98
113
|
|
99
|
-
|
100
|
-
reopt_inputs[:Scenario][:time_steps_per_hour] =
|
114
|
+
if reopt_inputs[:Scenario][:time_steps_per_hour].nil?
|
115
|
+
reopt_inputs[:Scenario][:time_steps_per_hour] = 1
|
101
116
|
end
|
102
117
|
|
103
118
|
# Parse Load Profile
|
104
119
|
begin
|
120
|
+
#Convert kWh values in the timeseries CSV to kW
|
105
121
|
col_num = feature_report.timeseries_csv.column_names.index('Electricity:Facility(kWh)')
|
106
122
|
t = CSV.read(feature_report.timeseries_csv.path, headers: true, converters: :numeric)
|
107
123
|
energy_timeseries_kw = t.by_col[col_num].map { |e| ((e * feature_report.timesteps_per_hour || 0) ) }
|
124
|
+
#Fill in missing timestep values with 0 if a full year is not provided
|
108
125
|
if energy_timeseries_kw.length < (feature_report.timesteps_per_hour * 8760)
|
109
126
|
start_date = Time.parse(t.by_col["Datetime"][0])
|
110
127
|
start_ts = (((start_date.yday * 60.0 * 60.0 * 24) + (start_date.hour * 60.0 * 60.0) + (start_date.min * 60.0) + start_date.sec) /
|
@@ -114,14 +131,41 @@ module URBANopt # :nodoc:
|
|
114
131
|
(( 60 / feature_report.timesteps_per_hour ) * 60)).to_int
|
115
132
|
energy_timeseries_kw = [0.0]*(start_ts-1) + energy_timeseries_kw + [0.0]*((feature_report.timesteps_per_hour * 8760) - end_ts)
|
116
133
|
end
|
117
|
-
|
134
|
+
#Clip to one non-leap year's worth of data
|
135
|
+
energy_timeseries_kw = energy_timeseries_kw.map { |e| e ? e : 0 }[0,(feature_report.timesteps_per_hour * 8760)]
|
136
|
+
#Convert from the OpenDSS resolution to the REopt Lite resolution, if necessary
|
118
137
|
rescue StandardError
|
119
138
|
@@logger.error("Could not parse the annual electric load from the timeseries csv - #{feature_report.timeseries_csv.path}")
|
120
139
|
raise "Could not parse the annual electric load from the timeseries csv - #{feature_report.timeseries_csv.path}"
|
121
140
|
end
|
141
|
+
|
142
|
+
# Convert load to REopt Resolution
|
143
|
+
begin
|
144
|
+
reopt_inputs[:Scenario][:Site][:LoadProfile][:loads_kw] = convert_powerflow_resolution(energy_timeseries_kw, feature_report.timesteps_per_hour, reopt_inputs[:Scenario][:time_steps_per_hour])
|
145
|
+
|
146
|
+
rescue
|
147
|
+
@@logger.error("Could not convert the annual electric load from a resolution of #{feature_report.timesteps_per_hour} to #{reopt_inputs[:Scenario][:time_steps_per_hour]}")
|
148
|
+
raise "Could not convert the annual electric load from a resolution of #{feature_report.timesteps_per_hour} to #{reopt_inputs[:Scenario][:time_steps_per_hour]}"
|
149
|
+
end
|
150
|
+
|
151
|
+
if reopt_inputs[:Scenario][:Site][:ElectricTariff][:coincident_peak_load_active_timesteps].nil?
|
152
|
+
n_top_values = 100
|
153
|
+
tmp1 = reopt_inputs[:Scenario][:Site][:LoadProfile][:loads_kw]
|
154
|
+
tmp2 = tmp1.each_index.max_by(n_top_values*reopt_inputs[:Scenario][:time_steps_per_hour]){|i| tmp1[i]}
|
155
|
+
for i in (0...tmp2.count)
|
156
|
+
tmp2[i] += 1
|
157
|
+
end
|
158
|
+
reopt_inputs[:Scenario][:Site][:ElectricTariff][:coincident_peak_load_active_timesteps] = tmp2
|
159
|
+
end
|
160
|
+
|
161
|
+
if reopt_inputs[:Scenario][:Site][:ElectricTariff][:coincident_peak_load_charge_us_dollars_per_kw].nil?
|
162
|
+
reopt_inputs[:Scenario][:Site][:ElectricTariff][:coincident_peak_load_charge_us_dollars_per_kw] = 0
|
163
|
+
end
|
164
|
+
|
122
165
|
return reopt_inputs
|
123
166
|
end
|
124
167
|
|
168
|
+
|
125
169
|
##
|
126
170
|
# Update a FeatureReport from a \REopt Lite response
|
127
171
|
#
|
@@ -140,33 +184,10 @@ module URBANopt # :nodoc:
|
|
140
184
|
return feature_report
|
141
185
|
end
|
142
186
|
|
143
|
-
$ts_per_hour = feature_report.timesteps_per_hour
|
144
|
-
def scale_timeseries(input, ts_per_hr=$ts_per_hour)
|
145
|
-
if input.nil?
|
146
|
-
return nil
|
147
|
-
end
|
148
|
-
if input.length ==0
|
149
|
-
return nil
|
150
|
-
end
|
151
|
-
if input.length == (8760 * ts_per_hr)
|
152
|
-
return input
|
153
|
-
end
|
154
|
-
result = []
|
155
|
-
input.each do |val|
|
156
|
-
(1..ts_per_hr).each do |x|
|
157
|
-
result.push(val/ts_per_hr.to_f)
|
158
|
-
end
|
159
|
-
end
|
160
|
-
return result
|
161
|
-
end
|
162
|
-
|
163
187
|
# Update location
|
164
188
|
feature_report.location.latitude_deg = reopt_output['inputs']['Scenario']['Site']['latitude']
|
165
189
|
feature_report.location.longitude_deg = reopt_output['inputs']['Scenario']['Site']['longitude']
|
166
190
|
|
167
|
-
# Update timeseries csv from \REopt Lite dispatch data
|
168
|
-
feature_report.timesteps_per_hour = reopt_output['inputs']['Scenario']['time_steps_per_hour']
|
169
|
-
|
170
191
|
# Update distributed generation sizing and financials
|
171
192
|
feature_report.distributed_generation.lcc_us_dollars = reopt_output['outputs']['Scenario']['Site']['Financial']['lcc_us_dollars'] || 0
|
172
193
|
feature_report.distributed_generation.npv_us_dollars = reopt_output['outputs']['Scenario']['Site']['Financial']['npv_us_dollars'] || 0
|
@@ -186,9 +207,9 @@ module URBANopt # :nodoc:
|
|
186
207
|
feature_report.distributed_generation.resilience_hours_avg = resilience_stats['resilience_hours_avg']
|
187
208
|
feature_report.distributed_generation.probs_of_surviving = resilience_stats['probs_of_surviving']
|
188
209
|
feature_report.distributed_generation.probs_of_surviving_by_month = resilience_stats['probs_of_surviving_by_month']
|
189
|
-
feature_report.distributed_generation.probs_of_surviving_by_hour_of_the_day = resilience_stats['probs_of_surviving_by_hour_of_the_day']
|
210
|
+
feature_report.distributed_generation.probs_of_surviving_by_hour_of_the_day = resilience_stats['probs_of_surviving_by_hour_of_the_day']
|
190
211
|
end
|
191
|
-
|
212
|
+
|
192
213
|
if reopt_output['outputs']['Scenario']['Site']['PV'].class == Hash
|
193
214
|
reopt_output['outputs']['Scenario']['Site']['PV'] = [reopt_output['outputs']['Scenario']['Site']['PV']]
|
194
215
|
elsif reopt_output['outputs']['Scenario']['Site']['PV'].nil?
|
@@ -215,29 +236,22 @@ module URBANopt # :nodoc:
|
|
215
236
|
end
|
216
237
|
|
217
238
|
generation_timeseries_kwh = Matrix[[0] * (8760 * feature_report.timesteps_per_hour)]
|
239
|
+
reopt_resolution = reopt_output['inputs']['Scenario']['time_steps_per_hour']
|
218
240
|
|
219
241
|
unless reopt_output['outputs']['Scenario']['Site']['PV'].nil?
|
220
242
|
reopt_output['outputs']['Scenario']['Site']['PV'].each do |pv|
|
221
243
|
if (pv['size_kw'] || 0) > 0
|
222
244
|
if !pv['year_one_power_production_series_kw'].nil?
|
223
|
-
generation_timeseries_kwh += Matrix[pv['year_one_power_production_series_kw']]
|
245
|
+
generation_timeseries_kwh += Matrix[convert_powerflow_resolution(pv['year_one_power_production_series_kw'], reopt_resolution, feature_report.timesteps_per_hour)]
|
224
246
|
end
|
225
247
|
end
|
226
248
|
end
|
227
249
|
end
|
228
250
|
|
229
|
-
unless reopt_output['outputs']['Scenario']['Site']['Storage'].nil?
|
230
|
-
if (reopt_output['outputs']['Scenario']['Site']['Storage']['size_kw'] or 0) > 0
|
231
|
-
if !reopt_output['outputs']['Scenario']['Site']['Storage']['year_one_to_grid_series_kw'].nil?
|
232
|
-
generation_timeseries_kwh = generation_timeseries_kwh + Matrix[reopt_output['outputs']['Scenario']['Site']['Storage']['year_one_to_grid_series_kw']]
|
233
|
-
end
|
234
|
-
end
|
235
|
-
end
|
236
|
-
|
237
251
|
unless reopt_output['outputs']['Scenario']['Site']['Wind'].nil?
|
238
252
|
if (reopt_output['outputs']['Scenario']['Site']['Wind']['size_kw'] || 0) > 0
|
239
253
|
if !reopt_output['outputs']['Scenario']['Site']['Wind']['year_one_power_production_series_kw'].nil?
|
240
|
-
generation_timeseries_kwh += Matrix[reopt_output['outputs']['Scenario']['Site']['Wind']['year_one_power_production_series_kw']]
|
254
|
+
generation_timeseries_kwh += Matrix[convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Wind']['year_one_power_production_series_kw'], reopt_resolution, feature_report.timesteps_per_hour)]
|
241
255
|
end
|
242
256
|
end
|
243
257
|
end
|
@@ -245,7 +259,7 @@ module URBANopt # :nodoc:
|
|
245
259
|
unless reopt_output['outputs']['Scenario']['Site']['Generator'].nil?
|
246
260
|
if (reopt_output['outputs']['Scenario']['Site']['Generator']['size_kw'] || 0) > 0
|
247
261
|
if !reopt_output['outputs']['Scenario']['Site']['Generator']['year_one_power_production_series_kw'].nil?
|
248
|
-
generation_timeseries_kwh += Matrix[reopt_output['outputs']['Scenario']['Site']['Generator']['year_one_power_production_series_kw']]
|
262
|
+
generation_timeseries_kwh += Matrix[convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Generator']['year_one_power_production_series_kw'], reopt_resolution, feature_report.timesteps_per_hour)]
|
249
263
|
end
|
250
264
|
end
|
251
265
|
end
|
@@ -257,70 +271,70 @@ module URBANopt # :nodoc:
|
|
257
271
|
feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Total(kw)')
|
258
272
|
end
|
259
273
|
|
260
|
-
$load =
|
274
|
+
$load = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['LoadProfile']['year_one_electric_load_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
|
261
275
|
$load_col = feature_report.timeseries_csv.column_names.index('REopt:Electricity:Load:Total(kw)')
|
262
276
|
if $load_col.nil?
|
263
277
|
$load_col = feature_report.timeseries_csv.column_names.length
|
264
278
|
feature_report.timeseries_csv.column_names.push('REopt:Electricity:Load:Total(kw)')
|
265
279
|
end
|
266
280
|
|
267
|
-
$utility_to_load =
|
281
|
+
$utility_to_load = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['ElectricTariff']['year_one_to_load_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
|
268
282
|
$utility_to_load_col = feature_report.timeseries_csv.column_names.index('REopt:Electricity:Grid:ToLoad(kw)')
|
269
283
|
if $utility_to_load_col.nil?
|
270
284
|
$utility_to_load_col = feature_report.timeseries_csv.column_names.length
|
271
285
|
feature_report.timeseries_csv.column_names.push('REopt:Electricity:Grid:ToLoad(kw)')
|
272
286
|
end
|
273
287
|
|
274
|
-
$utility_to_battery =
|
288
|
+
$utility_to_battery = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['ElectricTariff']['year_one_to_battery_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
|
275
289
|
$utility_to_battery_col = feature_report.timeseries_csv.column_names.index('REopt:Electricity:Grid:ToBattery(kw)')
|
276
290
|
if $utility_to_battery_col.nil?
|
277
291
|
$utility_to_battery_col = feature_report.timeseries_csv.column_names.length
|
278
292
|
feature_report.timeseries_csv.column_names.push('REopt:Electricity:Grid:ToBattery(kw)')
|
279
293
|
end
|
280
294
|
|
281
|
-
$storage_to_load =
|
295
|
+
$storage_to_load = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Storage']['year_one_to_load_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
|
282
296
|
$storage_to_load_col = feature_report.timeseries_csv.column_names.index('REopt:Electricity:Storage:ToLoad(kw)')
|
283
297
|
if $storage_to_load_col.nil?
|
284
298
|
$storage_to_load_col = feature_report.timeseries_csv.column_names.length
|
285
299
|
feature_report.timeseries_csv.column_names.push('REopt:Electricity:Storage:ToLoad(kw)')
|
286
300
|
end
|
287
301
|
|
288
|
-
$storage_to_grid =
|
302
|
+
$storage_to_grid = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Storage']['year_one_to_grid_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
|
289
303
|
$storage_to_grid_col = feature_report.timeseries_csv.column_names.index('REopt:Electricity:Storage:ToGrid(kw)')
|
290
304
|
if $storage_to_grid_col.nil?
|
291
305
|
$storage_to_grid_col = feature_report.timeseries_csv.column_names.length
|
292
306
|
feature_report.timeseries_csv.column_names.push('REopt:Electricity:Storage:ToGrid(kw)')
|
293
307
|
end
|
294
308
|
|
295
|
-
$storage_soc =
|
309
|
+
$storage_soc = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Storage']['year_one_soc_series_pct'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
|
296
310
|
$storage_soc_col = feature_report.timeseries_csv.column_names.index('REopt:Electricity:Storage:StateOfCharge(pct)')
|
297
311
|
if $storage_soc_col.nil?
|
298
312
|
$storage_soc_col = feature_report.timeseries_csv.column_names.length
|
299
313
|
feature_report.timeseries_csv.column_names.push('REopt:Electricity:Storage:StateOfCharge(pct)')
|
300
314
|
end
|
301
315
|
|
302
|
-
$generator_total =
|
316
|
+
$generator_total = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Generator']['year_one_power_production_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
|
303
317
|
$generator_total_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Generator:Total(kw)')
|
304
318
|
if $generator_total_col.nil?
|
305
319
|
$generator_total_col = feature_report.timeseries_csv.column_names.length
|
306
320
|
feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Generator:Total(kw)')
|
307
321
|
end
|
308
322
|
|
309
|
-
$generator_to_battery =
|
323
|
+
$generator_to_battery = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Generator']['year_one_to_battery_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
|
310
324
|
$generator_to_battery_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Generator:ToBattery(kw)')
|
311
325
|
if $generator_to_battery_col.nil?
|
312
326
|
$generator_to_battery_col = feature_report.timeseries_csv.column_names.length
|
313
327
|
feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Generator:ToBattery(kw)')
|
314
328
|
end
|
315
329
|
|
316
|
-
$generator_to_load =
|
330
|
+
$generator_to_load = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Generator']['year_one_to_load_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
|
317
331
|
$generator_to_load_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Generator:ToLoad(kw)')
|
318
332
|
if $generator_to_load_col.nil?
|
319
333
|
$generator_to_load_col = feature_report.timeseries_csv.column_names.length
|
320
334
|
feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Generator:ToLoad(kw)')
|
321
335
|
end
|
322
336
|
|
323
|
-
$generator_to_grid =
|
337
|
+
$generator_to_grid = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Generator']['year_one_to_grid_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
|
324
338
|
$generator_to_grid_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Generator:ToGrid(kw)')
|
325
339
|
if $generator_to_grid_col.nil?
|
326
340
|
$generator_to_grid_col = feature_report.timeseries_csv.column_names.length
|
@@ -359,10 +373,10 @@ module URBANopt # :nodoc:
|
|
359
373
|
|
360
374
|
reopt_output['outputs']['Scenario']['Site']['PV'].each_with_index do |pv, i|
|
361
375
|
if (pv['size_kw'] || 0) > 0
|
362
|
-
$pv_total += Matrix[
|
363
|
-
$pv_to_battery += Matrix[
|
364
|
-
$pv_to_load += Matrix[
|
365
|
-
$pv_to_grid += Matrix[
|
376
|
+
$pv_total += Matrix[convert_powerflow_resolution(pv['year_one_power_production_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)]
|
377
|
+
$pv_to_battery += Matrix[convert_powerflow_resolution(pv['year_one_to_battery_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)]
|
378
|
+
$pv_to_load += Matrix[convert_powerflow_resolution(pv['year_one_to_load_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)]
|
379
|
+
$pv_to_grid += Matrix[convert_powerflow_resolution(pv['year_one_to_grid_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)]
|
366
380
|
end
|
367
381
|
end
|
368
382
|
|
@@ -371,28 +385,28 @@ module URBANopt # :nodoc:
|
|
371
385
|
$pv_to_load = $pv_to_load.to_a[0]
|
372
386
|
$pv_to_grid = $pv_to_grid.to_a[0]
|
373
387
|
|
374
|
-
$wind_total =
|
388
|
+
$wind_total = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Wind']['year_one_power_production_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
|
375
389
|
$wind_total_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Wind:Total(kw)')
|
376
390
|
if $wind_total_col.nil?
|
377
391
|
$wind_total_col = feature_report.timeseries_csv.column_names.length
|
378
392
|
feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Wind:Total(kw)')
|
379
393
|
end
|
380
394
|
|
381
|
-
$wind_to_battery =
|
395
|
+
$wind_to_battery = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Wind']['year_one_to_battery_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
|
382
396
|
$wind_to_battery_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Wind:ToBattery(kw)')
|
383
397
|
if $wind_to_battery_col.nil?
|
384
398
|
$wind_to_battery_col = feature_report.timeseries_csv.column_names.length
|
385
399
|
feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Wind:ToBattery(kw)')
|
386
400
|
end
|
387
401
|
|
388
|
-
$wind_to_load =
|
402
|
+
$wind_to_load = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Wind']['year_one_to_load_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
|
389
403
|
$wind_to_load_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Wind:ToLoad(kw)')
|
390
404
|
if $wind_to_load_col.nil?
|
391
405
|
$wind_to_load_col = feature_report.timeseries_csv.column_names.length
|
392
406
|
feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Wind:ToLoad(kw)')
|
393
407
|
end
|
394
408
|
|
395
|
-
$wind_to_grid =
|
409
|
+
$wind_to_grid = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Wind']['year_one_to_grid_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
|
396
410
|
$wind_to_grid_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Wind:ToGrid(kw)')
|
397
411
|
if $wind_to_grid_col.nil?
|
398
412
|
$wind_to_grid_col = feature_report.timeseries_csv.column_names.length
|
@@ -424,11 +438,17 @@ module URBANopt # :nodoc:
|
|
424
438
|
|
425
439
|
old_data = CSV.open(feature_report.timeseries_csv.path).read
|
426
440
|
start_date = Time.parse(old_data[1][0])
|
427
|
-
start_ts = (
|
441
|
+
start_ts = (
|
442
|
+
(
|
443
|
+
((start_date.yday - 1) * 60.0 * 60.0 * 24) +
|
444
|
+
(((start_date.hour) - 1) * 60.0 * 60.0) +
|
445
|
+
(start_date.min * 60.0) + start_date.sec ) /
|
446
|
+
(( 60 / feature_report.timesteps_per_hour ) * 60)
|
447
|
+
).to_int
|
428
448
|
|
429
449
|
mod_data = old_data.map.with_index do |x, i|
|
430
450
|
if i > 0
|
431
|
-
modrow(x, start_ts + i -
|
451
|
+
modrow(x, start_ts + i -1)
|
432
452
|
else
|
433
453
|
x
|
434
454
|
end
|