urbanopt-rnm-us 0.1.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f1db14b6e9c51f62e4ff247765fb92fa8024f032a0327af75fd5965cd4bb5572
4
- data.tar.gz: 055a8d68963b51b29151d3d71d5dafb732a98e1a94f743b1a7c734456b0e28da
3
+ metadata.gz: 843ba686ad41687f6890709b5d53d3b30ed8bac33cfe726a0e907f2c0fe1e26f
4
+ data.tar.gz: 22cf46e48542910962f8c29da8c6721b885513bdd9f130083ae48b94028a264f
5
5
  SHA512:
6
- metadata.gz: e145f3334e9188e802fe9310f4b5baa366d2b951daa5dfa1b10a8be83a9ba185eb24c837b9b209bb0378bdf9fef138274c9df2eebcbd41556bd8de2b489ed862
7
- data.tar.gz: 4e561510ff390c78df684f58beee8bfbf76e62c445c3f887d7140af05493e77c8112b696d1b316f488ccba4e610aa816b39e4d2c7c92ed9550339a163bcec632
6
+ metadata.gz: 995c88f12b677995d076315afffc5254a6a2ba321926738d754b7e8d540396353a24ac357dc34d6d8754dd763eecae75dfea3f9ce6163203e00961ce48f8ae7d
7
+ data.tar.gz: c1913789eba31eb44bf3fa4f6abfb7a11715c0ccefd2b739d739c7c92c7636187945309de5f8fb3e7783ebc8c50fe1cd1b76ef3a040c898117f937e8c47c5065
data/CHANGELOG.md CHANGED
@@ -1,10 +1,29 @@
1
1
  # Changelog
2
2
 
3
+ ## Version 0.3.0
4
+ Date Range 11/23/21 - 05/10/22
5
+
6
+ - Update copyrights
7
+
8
+ ## Version 0.2.0
9
+
10
+ Date Range 11/09/21 - 11/22/21
11
+
12
+ - Updated dependencies for OpenStudio 3.3
13
+
14
+ ## Version 0.1.3
15
+
16
+ Date Range 11/02/21 - 11/08/21
17
+
18
+ - Fix [#11](https://github.com/urbanopt/urbanopt-rnm-us-gem/issues/11), results files are not downloading in project directory for large projects
19
+
20
+ - Fix [#16](https://github.com/urbanopt/urbanopt-rnm-us-gem/issues/16), fix residential enums to be consistent across files and fix typo in multifamily
21
+
3
22
  ## Version 0.1.2
4
23
 
5
24
  Date Range 10/29/21 - 11/01/21
6
25
 
7
- - Fix [#13] (https://github.com/urbanopt/urbanopt-rnm-us-gem/issues/13), update rubyzip dependency to fix conflict
26
+ - Fix [#13](https://github.com/urbanopt/urbanopt-rnm-us-gem/issues/13), update rubyzip dependency to fix conflict
8
27
 
9
28
  ## Version 0.1.1
10
29
 
data/Gemfile CHANGED
@@ -8,3 +8,9 @@ allow_local = ENV['FAVOR_LOCAL_GEMS']
8
8
 
9
9
  # Below is an example of how to configure the gemfile for developing with local gems
10
10
  # modify as appropriate
11
+
12
+ if allow_local && File.exists?('../urbanopt-geojson-gem')
13
+ gem 'urbanopt-geojson', path: '../urbanopt-geojson-gem'
14
+ elsif allow_local
15
+ gem 'urbanopt-geojson', github: 'URBANopt/urbanopt-geojson-gem', branch: 'develop'
16
+ end
data/Jenkinsfile ADDED
@@ -0,0 +1,10 @@
1
+ //Jenkins pipelines are stored in shared libaries. Please see: https://github.com/tijcolem/nrel_cbci_jenkins_libs
2
+
3
+ @Library('cbci_shared_libs') _
4
+
5
+ // Build for PR to develop branch only.
6
+ if ((env.CHANGE_ID) && (env.CHANGE_TARGET) ) { // check if set
7
+
8
+ urbanopt_rnm_us()
9
+
10
+ }
data/LICENSE.md CHANGED
@@ -1,4 +1,4 @@
1
- URBANopt (tm), Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
1
+ URBANopt (tm), Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
2
2
  contributors. All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without modification,
@@ -35,4 +35,4 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35
35
  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
36
36
  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
37
37
  OF THE POSSIBILITY OF SUCH DAMAGE.
38
- *********************************************************************************
38
+ *********************************************************************************
data/Rakefile CHANGED
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt (tm), Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt (tm), 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,
@@ -94,7 +94,7 @@ end
94
94
  desc 'Create input files with defaults'
95
95
  task :create_inputs_default, [:scenario_csv_path, :feature_file_path] do |t, args|
96
96
  puts 'Creating input files with defaulted settings'
97
- # if no path passed in, use default:
97
+ # if no path passed in, use default:
98
98
  scenario_csv_path = args[:scenario_csv_path] || 'spec/test/example_project/baseline_scenario.csv'
99
99
  root_dir, scenario_file_name = File.split(File.expand_path(scenario_csv_path))
100
100
  scenario_name = File.basename(scenario_file_name, File.extname(scenario_file_name))
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt (tm), Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt (tm), 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,
@@ -177,52 +177,70 @@ module URBANopt
177
177
  # prepare results directory
178
178
  prepare_results_dir
179
179
 
180
- max_tries = 10
180
+ max_tries = 20
181
181
  tries = 0
182
182
  puts "attempting to retrieve results for simulation #{@sim_id}"
183
183
  while !done && (max_tries != tries)
184
- resp = conn.get("simulations/#{@sim_id}")
185
- if resp.status == 200
186
- data = JSON.parse(resp.body)
187
- if data['status'] && ['failed', 'completed'].include?(data['status'])
188
- # done
189
- done = true
190
- if data['status'] == 'failed'
191
- if data['results'] && data['results']['message']
192
- puts "Simulation Error: #{data['results']['message']}"
184
+ begin
185
+ resp = conn.get("simulations/#{@sim_id}")
186
+ if resp.status == 200
187
+ data = JSON.parse(resp.body)
188
+ if data['status'] && ['failed', 'completed'].include?(data['status'])
189
+ # done
190
+ done = true
191
+ if data['status'] == 'failed'
192
+ if data['results'] && data['results']['message']
193
+ puts "Simulation Error: #{data['results']['message']}"
194
+ else
195
+ puts 'Simulation Error!'
196
+ end
193
197
  else
194
- puts 'Simulation Error!'
198
+ # edge case, check for results
199
+ if data['results'].nil?
200
+ puts 'got a 200 but results are null...trying again'
201
+ tries += 1
202
+ sleep(3)
203
+ else
204
+ # get results
205
+ @results = data['results'] || []
206
+
207
+ puts 'downloading results'
208
+ # download results
209
+ download_results
210
+ return @results
211
+ end
195
212
  end
196
213
  else
197
- # get results
198
- @results = data['results'] || []
199
-
200
- # download results
201
- download_results
202
-
203
- return @results
214
+ puts 'no status yet...trying again'
215
+ tries += 1
216
+ sleep(3)
204
217
  end
218
+
205
219
  else
220
+ puts("ERROR retrieving: #{resp.body}")
206
221
  tries += 1
207
- sleep(1)
208
- end
209
222
 
210
- else
211
- puts("ERROR retrieving: #{resp.body}")
212
- tries += 1
213
-
214
- if tries == max_tries
215
- # now raise the error
216
- msg = "Error retrieving simulation #{@sim_id}. error code: #{resp.status}"
217
- @@logger.error(msg)
218
- raise msg
219
- else
220
- # try again
221
- puts("TRYING AGAIN...#{tries}")
222
- sleep(3)
223
+ if tries == max_tries
224
+ # now raise the error
225
+ msg = "Error retrieving simulation #{@sim_id}. error code: #{resp.status}"
226
+ @@logger.error(msg)
227
+ raise msg
228
+ else
229
+ # try again
230
+ puts("TRYING AGAIN...#{tries}")
231
+ sleep(3)
232
+ end
223
233
  end
234
+ rescue StandardError => e
235
+ @@logger.error("Error retrieving simulation #{@sim_id}.")
236
+ @@logger.error(e.message)
237
+ raise e.message
224
238
  end
225
239
  end
240
+ if !done
241
+ @@logger.error("Error retrieving simulation #{@sim_id}.")
242
+ raise 'Simulation not retrieved...maximum tries reached'
243
+ end
226
244
  end
227
245
 
228
246
  ##
@@ -243,14 +261,14 @@ module URBANopt
243
261
  streamed << chunk
244
262
  end
245
263
  end
246
- # puts("STATUS: #{resp.status}, #{resp.body}")
247
264
 
248
265
  if resp.status == 200
249
266
 
250
267
  file_path = File.join(@rnm_dir, 'results', 'results.zip')
251
268
 
252
269
  File.open(file_path, 'wb') { |f| f.write streamed.join }
253
- # puts "RNM-US results.zip downloaded to #{@rnm_dir}"
270
+ puts "RNM-US results.zip downloaded to #{@rnm_dir}"
271
+
254
272
  # unzip
255
273
  Zip::File.open(file_path) do |zip_file|
256
274
  zip_file.each do |f|
@@ -259,7 +277,7 @@ module URBANopt
259
277
  zip_file.extract(f, f_path) unless File.exist?(f_path)
260
278
  end
261
279
  end
262
-
280
+ puts 'results.zip extracted'
263
281
  # delete zip
264
282
  File.delete(file_path)
265
283
 
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt (tm), Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt (tm), 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 (tm), Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt (tm), 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 (tm), Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt (tm), 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,
@@ -79,6 +79,7 @@ module URBANopt
79
79
  yearly_profile_node_reactive = []
80
80
  nodes_per_bldg, area, medium_voltage = av_peak_cons_per_building_type(folder['building_types'])
81
81
  # the default variables are defined (i.e. type and rurality type)
82
+ puts 'consumers 82'
82
83
  closest_node = building_map[3].split('_')[1].to_i # refers to the node, found in the class above
83
84
  node = closest_node
84
85
  cont = 1
@@ -175,7 +176,7 @@ module URBANopt
175
176
  conservative_factor = 0.8 # considered as a reasonable assumption, but this value could be changed
176
177
  average_peak_folder = JSON.parse(File.read(@average_building_peak_catalog_path))
177
178
  for i in 0..feature_file.length - 1
178
- area = feature_file[i].has_key?('floor_area') ? (feature_file[i]['floor_area']).round(2) : feature_file[i]['floor_area_sqft'].round(2)
179
+ area = feature_file[i].key?('floor_area') ? (feature_file[i]['floor_area']).round(2) : feature_file[i]['floor_area_sqft'].round(2)
179
180
  building_type = feature_file[i]['building_type'] # it specifies the type of building, sometimes it is directly the sub-type
180
181
  counter = 0 # counter to find number of buildings type belonging to same "category"
181
182
  average_peak_folder.each do |building_class|
@@ -214,12 +215,13 @@ module URBANopt
214
215
  # the method passes as arguments the urbanopt json and csv output file for each feature and the building coordinates previously calculated
215
216
  # and the "extreme" hour used to plan the network
216
217
  def customer_files_load(csv_feature_report, json_feature_report, building_map, building_nodes, hour)
217
- n_timestep_per_hour = json_feature_report["timesteps_per_hour"].to_i
218
+ n_timestep_per_hour = json_feature_report['timesteps_per_hour'].to_i
218
219
  profiles = Hash.new { |h, k| h[k] = [] }
219
220
  single_values = Hash.new(0)
220
- hours = 24 * n_timestep_per_hour -1
221
+ hours = 24 * n_timestep_per_hour - 1
221
222
  feature_type = json_feature_report['program']['building_types'][0]['building_type']
222
- residential_building_types = ["Single-Family Detached", "Single-Family Attached", "Multifamily"]
223
+ residential_building_types = ['Single-Family Detached', 'Single-Family Attached', 'Multifamily', 'Single-Family', 'Multifamily Detached (2 to 4 units)', 'Multifamily Detached (5 or more units)']
224
+
223
225
  # finding the index where to start computing and saving the info, from the value of the "worst-case hour" for the max peak consumption of the district
224
226
  if residential_building_types.include? feature_type
225
227
  profile_start_max = hour.hour_index_max_res - ((hour.peak_hour_max_res.split(':')[0].to_i + (hour.peak_hour_max_res.split(':')[1].to_i / 60)) * n_timestep_per_hour)
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt (tm), Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt (tm), 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 (tm), Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt (tm), 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,
@@ -143,7 +143,7 @@ module URBANopt
143
143
  # creating a method passing the GeoJSON file from URBANopt as the argument to define options that can be modified by the user
144
144
  # streets and building and primary substation coordinates
145
145
  # and returning the street coordinates array, the building coordinates array and the tot number of buildings in the project
146
- def coordinates_feature_hash(geojson_hash,scenario_features=[])
146
+ def coordinates_feature_hash(geojson_hash, scenario_features = [])
147
147
  i = 0 # index representing the number of street_nodes
148
148
  building_number = 0 # variable created to keep track the number of buildings in the project
149
149
  street_number = 0 # variable created to keep track the number of streets in the project
@@ -209,7 +209,7 @@ module URBANopt
209
209
  end
210
210
  street_coordinates[street_number] = each_street
211
211
  street_number += 1
212
- elsif street['geometry']['type'] == 'Polygon' && street['properties']['type'] == 'Building' and scenario_features.include? street['properties']['id']
212
+ elsif street['geometry']['type'] == 'Polygon' && street['properties']['type'] == 'Building' && scenario_features.include?(street['properties']['id'])
213
213
  for k in 0..street['geometry']['coordinates'].length - 1
214
214
  h = 0 # index representing number of nodes for each single building
215
215
  building = [] # array containing every building node coordinates and id of 1 building
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt (tm), Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt (tm), 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 (tm), Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt (tm), 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 (tm), Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt (tm), 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 (tm), Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt (tm), 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,
@@ -59,7 +59,7 @@ module URBANopt
59
59
  @reopt = reopt
60
60
  end
61
61
 
62
- ##
62
+ ##
63
63
  # Post Process report and feature file
64
64
  ##
65
65
  def post_process
@@ -68,11 +68,10 @@ module URBANopt
68
68
  puts "RNM results were added to scenario report and feature file. New files can be found in #{@results_dir}"
69
69
  end
70
70
 
71
- ##
71
+ ##
72
72
  # Generate Scenario report
73
73
  ##
74
74
  def generate_report
75
-
76
75
  # calculate rnm statistics
77
76
  rnm_stats = calculate_stats
78
77
 
@@ -80,17 +79,16 @@ module URBANopt
80
79
  scenario = get_scenario
81
80
 
82
81
  # merge stats with scenario report (before feature_reports section)
83
-
82
+
84
83
  scenario['scenario_report']['rnm_results'] = rnm_stats
85
-
84
+
86
85
  # save back to scenario directory as scenario_report_rnm.json
87
- File.open(File.join(@scenario_dir, @report_filename), "w") do |f|
86
+ File.open(File.join(@scenario_dir, @report_filename), 'w') do |f|
88
87
  f.write(JSON.pretty_generate(scenario))
89
88
  end
90
-
91
89
  end
92
90
 
93
- ##
91
+ ##
94
92
  # Load Scenario Report
95
93
  ##
96
94
  def get_scenario
@@ -98,16 +96,15 @@ module URBANopt
98
96
  # get reopt scenario report
99
97
  return JSON.parse(File.read(File.join(@scenario_dir, 'feature_optimization.json')))
100
98
  else
101
- # get default scenario report
99
+ # get default scenario report
102
100
  return JSON.parse(File.read(File.join(@scenario_dir, 'default_scenario_report.json')))
103
101
  end
104
102
  end
105
103
 
106
- ##
104
+ ##
107
105
  # Generate new GeoJSON file
108
106
  ##
109
107
  def generate_feature_file
110
-
111
108
  # get results GeoJSON file and read in
112
109
  results = JSON.parse(File.read(File.join(@results_dir, 'GeoJSON', 'Distribution_system.json')))
113
110
 
@@ -117,7 +114,7 @@ module URBANopt
117
114
  end
118
115
 
119
116
  # save back to scenario directory as features_and_rnm.json
120
- File.open(File.join(@scenario_dir, @geojson_filename), "w") do |f|
117
+ File.open(File.join(@scenario_dir, @geojson_filename), 'w') do |f|
121
118
  f.write(JSON.pretty_generate(@feature_file))
122
119
  end
123
120
  end
@@ -132,6 +129,7 @@ module URBANopt
132
129
  stats['demand_generation_planning'] = []
133
130
  @results['Demand/generation and number of consumers/distributed generators'].each do |item|
134
131
  rec = {}
132
+ puts "ITEM VOLTAGE LEVEL: #{item['Voltage level']}, item type: #{item['Type'].strip}"
135
133
  case item['Voltage level']
136
134
  when 'LV'
137
135
  rec['type'] = "Low Voltage (LV) #{item['Type'].strip}"
@@ -155,7 +153,7 @@ module URBANopt
155
153
 
156
154
  # lines LV and MV
157
155
  stats['electrical_lines_length'] = {}
158
- km_to_mi = 0.621371
156
+ km_to_mi = 0.621371
159
157
  @results['Length of overhead and underground electrical lines'].each do |item|
160
158
  case item['Voltage level']
161
159
  when 'Lines LV'
@@ -181,8 +179,8 @@ module URBANopt
181
179
  @results['Summary'].each do |item|
182
180
  case item['Level']
183
181
  when 'LV'
184
- stats['costs']['investment']['low_voltage_network'] = item['Investment cost']
185
- stats['costs']['yearly_maintenance']['low_voltage_network'] = item['Preventive maintenance (yearly)']
182
+ stats['costs']['investment']['low_voltage_network'] = item['Investment cost']
183
+ stats['costs']['yearly_maintenance']['low_voltage_network'] = item['Preventive maintenance (yearly)']
186
184
  when 'MV'
187
185
  stats['costs']['investment']['medium_voltage_network'] = item['Investment cost']
188
186
  stats['costs']['yearly_maintenance']['medium_voltage_network'] = item['Preventive maintenance (yearly)']
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt (tm), Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt (tm), 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 (tm), Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt (tm), 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,
@@ -84,8 +84,8 @@ module URBANopt
84
84
  # in the hour with generation max peak
85
85
  # in the hour with storage max peak
86
86
 
87
- for i in 0..profiles_planning[:planning_profile_cust_active].length-1
88
- hourly_app_power = ((profiles_planning[:planning_profile_cust_active][i] + profiles_planning[:planning_profile_storage_active][i] - profiles_planning[:planning_profile_dg_active][i])/@power_factor).abs
87
+ for i in 0..profiles_planning[:planning_profile_cust_active].length - 1
88
+ hourly_app_power = ((profiles_planning[:planning_profile_cust_active][i] + profiles_planning[:planning_profile_storage_active][i] - profiles_planning[:planning_profile_dg_active][i]) / @power_factor).abs
89
89
  if hourly_app_power > peak_app_power_node
90
90
  peak_app_power_node = hourly_app_power
91
91
  end
@@ -103,9 +103,9 @@ module URBANopt
103
103
  @profile_customer_p.push([id, 48, profiles_planning[:planning_profile_cust_active]])
104
104
  @profile_customer_p_ext.push([id, 8760, profiles[:yearly_profile_cust_active]])
105
105
  @profile_customer_q_ext.push([id, 8760, profiles[:yearly_profile_cust_reactive]])
106
-
107
- if der_capacity[:storage] != nil && der_capacity[:storage] > 0
108
- @customers.push([building_map, id_batt, voltage_default, single_values[:peak_active_power_storage],single_values[:peak_reactive_power_storage], phases])
106
+
107
+ if !der_capacity[:storage].nil? && der_capacity[:storage] > 0
108
+ @customers.push([building_map, id_batt, voltage_default, single_values[:peak_active_power_storage], single_values[:peak_reactive_power_storage], phases])
109
109
  @customers_ext.push([building_map, id_batt, voltage_default, single_values[:peak_active_power_storage], single_values[:peak_reactive_power_storage], phases, area, height, (single_values[:energy]).round(2), single_values[:peak_active_power_storage], single_values[:peak_reactive_power_storage], users])
110
110
  @profile_customer_q.push([id_batt, 48, profiles_planning[:planning_profile_storage_reactive]])
111
111
  @profile_customer_p.push([id_batt, 48, profiles_planning[:planning_profile_storage_active]])
@@ -138,7 +138,7 @@ module URBANopt
138
138
  cont = 1
139
139
  cont_reverse = 1
140
140
  nodes_consumers = nodes_per_bldg - 1
141
-
141
+
142
142
  for i in 1..nodes_per_bldg
143
143
  coordinates = building_map
144
144
  node = closest_node + cont # to set the new nodes with enough distance among each others
@@ -146,10 +146,10 @@ module URBANopt
146
146
  if i > 1 && node <= building_nodes.length - 2
147
147
  coordinates = building_nodes[node] # take the closest building node index to the street and pass the nodes after it
148
148
  cont += 1
149
- elsif i > 1
149
+ elsif i > 1
150
150
  coordinates = building_nodes[node_reverse]
151
151
  cont_reverse += 1
152
- end
152
+ end
153
153
  # this condition is used to firstly place the building consumption nodes and then the last node
154
154
  # to be placed is the one referred to DG and battery for the building
155
155
  if i < nodes_per_bldg # considering the consumers nodes
@@ -159,11 +159,11 @@ module URBANopt
159
159
  peak_reactive_power_cons = (single_values[:peak_reactive_power_cons] / nodes_consumers).round(2)
160
160
  voltage_default, phases = voltage_values(peak_active_power_cons / @power_factor)
161
161
  for k in 0..profiles_planning[:planning_profile_cust_active].length - 1
162
- planning_profile_node_active[k] = (profiles_planning[:planning_profile_cust_active][k] / nodes_consumers).round(2)
163
- planning_profile_node_reactive[k] = (profiles_planning[:planning_profile_cust_reactive][k] / nodes_consumers).round(2)
162
+ planning_profile_node_active[k] = (profiles_planning[:planning_profile_cust_active][k] / nodes_consumers).round(2)
163
+ planning_profile_node_reactive[k] = (profiles_planning[:planning_profile_cust_reactive][k] / nodes_consumers).round(2)
164
164
  end
165
165
  for k in 0..profiles[:yearly_profile_cust_active].length - 1
166
- yearly_profile_node_active[k] = (profiles[:yearly_profile_cust_active][k] / nodes_consumers).round(2)
166
+ yearly_profile_node_active[k] = (profiles[:yearly_profile_cust_active][k] / nodes_consumers).round(2)
167
167
  yearly_profile_node_reactive[k] = (profiles[:yearly_profile_cust_reactive][k] / nodes_consumers).round(2)
168
168
  end
169
169
  @customers.push([coordinates, id, voltage_default, peak_active_power_cons, peak_reactive_power_cons, phases])
@@ -174,7 +174,7 @@ module URBANopt
174
174
  @profile_customer_q_ext.push([id, 8760, yearly_profile_node_reactive])
175
175
  else
176
176
  # considering the DG and battery
177
- voltage_default, phases = voltage_values(der_capacity[:dg]) #assuming that the pv capacity is always higher than battery capacity
177
+ voltage_default, phases = voltage_values(der_capacity[:dg]) # assuming that the pv capacity is always higher than battery capacity
178
178
  id_dg = "#{coordinates[3]}_DG"
179
179
  id_batt = "#{coordinates[3]}_battery"
180
180
  coordinates.pop
@@ -183,7 +183,7 @@ module URBANopt
183
183
  @dg_profile_q.push([id_dg, 48, profiles_planning[:planning_profile_dg_reactive]])
184
184
  @profile_dg_p_extended.push([id_dg, 8760, profiles[:yearly_profile_dg_active]])
185
185
  @profile_dg_q_extended.push([id_dg, 8760, profiles[:yearly_profile_dg_reactive]])
186
- if der_capacity[:storage] != nil && der_capacity[:storage] > 0
186
+ if !der_capacity[:storage].nil? && der_capacity[:storage] > 0
187
187
  @customers.push([coordinates, id_batt, voltage_default, single_values[:peak_active_power_storage], single_values[:peak_reactive_power_storage], phases])
188
188
  @customers_ext.push([coordinates, id_batt, voltage_default, single_values[:peak_active_power_storage], single_values[:peak_reactive_power_storage], phases, area, height, (single_values[:energy]).round(2), single_values[:peak_active_power_storage], single_values[:peak_reactive_power_storage], users])
189
189
  @profile_customer_q.push([id_batt, 48, profiles_planning[:planning_profile_storage_reactive]])
@@ -249,15 +249,15 @@ module URBANopt
249
249
  average_peak_folder = JSON.parse(File.read(@average_building_peak_catalog_path))
250
250
  for i in 0..feature_file.length - 1
251
251
  area = feature_file[i].key?('floor_area') ? (feature_file[i]['floor_area']).round(2) : (feature_file[i]['floor_area_sqft']).round(2)
252
- building_type = feature_file[i]['building_type'] #it specifies the type of building, sometimes it is directly the sub-type
252
+ building_type = feature_file[i]['building_type'] # it specifies the type of building, sometimes it is directly the sub-type
253
253
  counter = 0 # counter to find number of buildings type belonging to same "category"
254
254
  average_peak_folder.each do |building_class|
255
- if (building_type == building_class["building type"] || building_type == building_class["sub-type"])
255
+ if building_type == building_class['building type'] || building_type == building_class['sub-type']
256
256
  average_peak = (building_class['average peak demand (kW/ft2)'].to_f * area).to_f.round(4) # finding the average peak considering the floor area of the bilding under consideration
257
257
  average_peak_by_size[counter] = average_peak
258
258
  floor_area[counter] = (building_class['floor_area (ft2)'] - area).abs # minimum difference among area and area from the prototypes defined by DOE
259
259
  counter += 1
260
- # in this way I don t consider residential and I assume it s average_peak = 0, it is ok because we assume always 1 node per RES consumers, single-detached family houses
260
+ # in this way I don t consider residential and I assume it s average_peak = 0, it is ok because we assume always 1 node per RES consumers, single-detached family houses
261
261
  end
262
262
  end
263
263
  if counter > 1
@@ -273,21 +273,21 @@ module URBANopt
273
273
  average_peak = mixed_use_av_peak # average peak per mixed use considering the building types which are in this building
274
274
  area = area_mixed_use
275
275
  end
276
- nodes_per_bldg = ((average_peak / (@lv_limit[:three_phase] * @power_factor * conservative_factor)).to_f).ceil # computing number of nodes per building
277
- if nodes_per_bldg > @max_num_lv_nodes #that it is equal to how it was before
276
+ nodes_per_bldg = (average_peak / (@lv_limit[:three_phase] * @power_factor * conservative_factor)).to_f.ceil # computing number of nodes per building
277
+ if nodes_per_bldg > @max_num_lv_nodes # that it is equal to how it was before
278
278
  nodes_per_bldg = 1
279
279
  @medium_voltage = true
280
280
  end
281
-
282
- nodes_per_bldg += 1 # tacking into account the extra node for distributed generation and the battery
281
+
282
+ nodes_per_bldg += 1 # tacking into account the extra node for distributed generation and the battery
283
283
  return nodes_per_bldg, area
284
284
  end
285
285
 
286
286
  # method to order profiles consistently
287
287
  def profiles_planning_creation(profiles_planning, power, single_values, i, hours, power_factor)
288
- profiles_planning[:planning_profile_cust_active][i] = power["REopt:Electricity:Load:Total(kw)"].to_f
288
+ profiles_planning[:planning_profile_cust_active][i] = power['REopt:Electricity:Load:Total(kw)'].to_f
289
289
  profiles_planning[:planning_profile_storage_active][i] = power['REopt:Electricity:Grid:ToBattery(kw)'].to_f + power['REopt:ElectricityProduced:Generator:ToBattery(kw)'].to_f + power['REopt:ElectricityProduced:PV:ToBattery(kw)'].to_f + power['REopt:ElectricityProduced:Wind:ToBattery(kw)'].to_f - power['REopt:Electricity:Storage:ToLoad(kw)'].to_f - power['REopt:Electricity:Storage:ToGrid(kw)'].to_f
290
- profiles_planning[:planning_profile_dg_active][i] = power["REopt:ElectricityProduced:Total(kw)"].to_f
290
+ profiles_planning[:planning_profile_dg_active][i] = power['REopt:ElectricityProduced:Total(kw)'].to_f
291
291
  profiles_planning[:planning_profile_cust_reactive][i] = profiles_planning[:planning_profile_cust_active][i] * Math.tan(Math.acos(power_factor))
292
292
  profiles_planning[:planning_profile_storage_reactive][i] = profiles_planning[:planning_profile_storage_active][i] * Math.tan(Math.acos(power_factor))
293
293
  profiles_planning[:planning_profile_dg_reactive][i] = profiles_planning[:planning_profile_dg_active][i] * Math.tan(Math.acos(power_factor))
@@ -301,7 +301,7 @@ module URBANopt
301
301
  end
302
302
  if profiles_planning[:planning_profile_dg_active][i] > single_values[:peak_active_power_dg]
303
303
  single_values[:peak_active_power_dg] = profiles_planning[:planning_profile_dg_active][i]
304
- single_values[:peak_reactive_power_dg] = single_values[:peak_active_power_dg] * (Math.tan(Math.acos(power_factor)))
304
+ single_values[:peak_reactive_power_dg] = single_values[:peak_active_power_dg] * Math.tan(Math.acos(power_factor))
305
305
  end
306
306
  return profiles_planning, single_values
307
307
  end
@@ -313,14 +313,15 @@ module URBANopt
313
313
  # and the "extreme" hours used to plan the network
314
314
  def prosumer_files_load(csv_feature_report, json_feature_report, building_map, building_nodes, hour)
315
315
  # add variable to include how many timestep per hour, so the profiles become 48 * n_timestep_per_hour
316
- n_timestep_per_hour = json_feature_report["timesteps_per_hour"].to_i
317
- profiles_planning = Hash.new{|h, k| h[k] = Array.new(48*n_timestep_per_hour, 0)} # initializing each profile hash to 0 for the number of intervals considered for the planning of the network
318
- profiles = Hash.new{|h, k| h[k] = []}
316
+ n_timestep_per_hour = json_feature_report['timesteps_per_hour'].to_i
317
+ profiles_planning = Hash.new { |h, k| h[k] = Array.new(48 * n_timestep_per_hour, 0) } # initializing each profile hash to 0 for the number of intervals considered for the planning of the network
318
+ profiles = Hash.new { |h, k| h[k] = [] }
319
319
  single_values = Hash.new(0)
320
320
  @medium_voltage = false
321
- hours = 24 * n_timestep_per_hour -1 # change name, maybe to intervals
322
- feature_type = json_feature_report['program']['building_types'][0]["building_type"]
323
- residential_building_types = ["Single-Family Detached", "Single-Family Attached", "Multifamily"]
321
+ hours = 24 * n_timestep_per_hour - 1 # change name, maybe to intervals
322
+ feature_type = json_feature_report['program']['building_types'][0]['building_type']
323
+ residential_building_types = ['Single-Family Detached', 'Single-Family Attached', 'Multifamily', 'Single-Family', 'Multifamily Detached (2 to 4 units)', 'Multifamily Detached (5 or more units)']
324
+
324
325
  # finding the index where to start computing and saving the info, from the value of the "worst-case hour" for the max peak consumption of the district
325
326
  # considering num timestep per hours and the fact that each day starts from 1 am
326
327
  if residential_building_types.include? feature_type
@@ -331,49 +332,49 @@ module URBANopt
331
332
  profile_start_min = hour.hour_index_min_comm - ((hour.peak_hour_min_comm.split(':')[0].to_i + (hour.peak_hour_min_comm.split(':')[1].to_i / 60)) * n_timestep_per_hour)
332
333
  end
333
334
  # finding the index where to start computing and saving the info, from the value of the "most extreme hours" for the max peak consumption of the district
334
- k = 0 # index for each hour of the year represented in the csv file
335
- i = hours +1 # to represent the 24 hours in case of max_net_generation day
335
+ k = 0 # index for each hour of the year represented in the csv file
336
+ i = hours + 1 # to represent the 24 hours in case of max_net_generation day
336
337
  j = 0 # to represent the 24 hours in case of peak_demand_day
337
338
  h_cons_batt = 0
338
339
  h_dg_max = 0 # hour with max DG generation
339
340
  h_stor_max = 0 # hour with max storage absorption
340
341
  max_peak = 0
341
342
  CSV.foreach(csv_feature_report, headers: true) do |power|
342
- @power_factor = power["Electricity:Facility Power(kW)"].to_f / power["Electricity:Facility Apparent Power(kVA)"].to_f
343
- profiles[:yearly_profile_cust_active].push(power["REopt:Electricity:Load:Total(kw)"].to_f)
343
+ @power_factor = power['Electricity:Facility Power(kW)'].to_f / power['Electricity:Facility Apparent Power(kVA)'].to_f
344
+ profiles[:yearly_profile_cust_active].push(power['REopt:Electricity:Load:Total(kw)'].to_f)
344
345
  profiles[:yearly_profile_cust_reactive].push(profiles[:yearly_profile_cust_active][k] * Math.tan(Math.acos(@power_factor)))
345
- profiles[:yearly_profile_dg_active].push(power["REopt:ElectricityProduced:Total(kw)"].to_f)
346
+ profiles[:yearly_profile_dg_active].push(power['REopt:ElectricityProduced:Total(kw)'].to_f)
346
347
  profiles[:yearly_profile_dg_reactive].push(profiles[:yearly_profile_dg_active][k] * Math.tan(Math.acos(@power_factor)))
347
348
  profiles[:yearly_profile_storage_active].push(power['REopt:Electricity:Grid:ToBattery(kw)'].to_f + power['REopt:ElectricityProduced:Generator:ToBattery(kw)'].to_f + power['REopt:ElectricityProduced:PV:ToBattery(kw)'].to_f + power['REopt:ElectricityProduced:Wind:ToBattery(kw)'].to_f - power['REopt:Electricity:Storage:ToLoad(kw)'].to_f - power['REopt:Electricity:Storage:ToGrid(kw)'].to_f)
348
349
  profiles[:yearly_profile_storage_reactive].push(profiles[:yearly_profile_storage_active][k] * Math.tan(Math.acos(@power_factor)))
349
- single_values[:energy] += power["REopt:Electricity:Load:Total(kw)"].to_f # calculating the yearly energy consumed by each feature
350
- single_values[:energy_dg] += power["REopt:ElectricityProduced:Total(kw)"].to_f
350
+ single_values[:energy] += power['REopt:Electricity:Load:Total(kw)'].to_f # calculating the yearly energy consumed by each feature
351
+ single_values[:energy_dg] += power['REopt:ElectricityProduced:Total(kw)'].to_f
351
352
  single_values[:energy_storage] += power['REopt:Electricity:Grid:ToBattery(kw)'].to_f + power['REopt:ElectricityProduced:Generator:ToBattery(kw)'].to_f + power['REopt:ElectricityProduced:PV:ToBattery(kw)'].to_f + power['REopt:ElectricityProduced:Wind:ToBattery(kw)'].to_f - power['REopt:Electricity:Storage:ToLoad(kw)'].to_f - power['REopt:Electricity:Storage:ToGrid(kw)'].to_f
352
353
  case k
353
- when profile_start_min..profile_start_min + (hours)
354
- profiles_planning, single_values = self.profiles_planning_creation(profiles_planning, power, single_values, i, hours, power_factor)
355
- i+=1
356
- when profile_start_max..profile_start_max + (hours)
357
- profiles_planning, single_values = self.profiles_planning_creation(profiles_planning, power, single_values, j, hours, power_factor)
358
- j+=1
354
+ when profile_start_min..profile_start_min + hours
355
+ profiles_planning, single_values = profiles_planning_creation(profiles_planning, power, single_values, i, hours, power_factor)
356
+ i += 1
357
+ when profile_start_max..profile_start_max + hours
358
+ profiles_planning, single_values = profiles_planning_creation(profiles_planning, power, single_values, j, hours, power_factor)
359
+ j += 1
359
360
  end
360
- k+=1
361
+ k += 1
361
362
  end
362
363
  height = (json_feature_report['program']['maximum_roof_height_ft']).round(2)
363
364
  users = json_feature_report['program']['number_of_residential_units']
364
- der_capacity = self.sum_dg(json_feature_report['distributed_generation'])
365
+ der_capacity = sum_dg(json_feature_report['distributed_generation'])
365
366
  if @only_lv_consumers
366
- nodes_per_bldg, area = self.av_peak_cons_per_building_type(json_feature_report['program']['building_types'])
367
+ nodes_per_bldg, area = av_peak_cons_per_building_type(json_feature_report['program']['building_types'])
367
368
  if @max_num_nodes == 1
368
- self.construct_prosumer_general(profiles, profiles_planning, single_values, building_map, area, height, users, der_capacity)
369
+ construct_prosumer_general(profiles, profiles_planning, single_values, building_map, area, height, users, der_capacity)
369
370
  else
370
- self.construct_prosumer_lv(nodes_per_bldg, profiles, profiles_planning, single_values, building_map, building_nodes, area, height, users, der_capacity)
371
+ construct_prosumer_lv(nodes_per_bldg, profiles, profiles_planning, single_values, building_map, building_nodes, area, height, users, der_capacity)
371
372
  end
372
373
  else
373
- area = json_feature_report['program'].has_key?('floor_area') ? (json_feature_report['program']['floor_area']).round(2) : (json_feature_report['program']['floor_area_sqft']).round(2)
374
+ area = json_feature_report['program'].key?('floor_area') ? (json_feature_report['program']['floor_area']).round(2) : (json_feature_report['program']['floor_area_sqft']).round(2)
374
375
  # associating 2 nodes (consumers & DG and battery in the same node) per building considering the consumer, the battery and DG
375
- self.construct_prosumer_general(profiles, profiles_planning, single_values, building_map, area, height, users, der_capacity)
376
- end
376
+ construct_prosumer_general(profiles, profiles_planning, single_values, building_map, area, height, users, der_capacity)
377
+ end
377
378
  end
378
379
  end
379
380
  end
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt (tm), Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt (tm), 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,
@@ -105,7 +105,7 @@ module URBANopt
105
105
  csv << ["<#{key}>"]
106
106
  if ext_catalog[key].is_a?(Hash) # defining the section under consideration is an Hash or an Array
107
107
  if key == 'OTHERS'
108
- ext_catalog[key]["UTM Zone"] = utm_zone.to_s
108
+ ext_catalog[key]['UTM Zone'] = utm_zone.to_s
109
109
  end
110
110
  ext_catalog[key].each do |k, v|
111
111
  row = []
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt (tm), Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt (tm), 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,
@@ -126,8 +126,7 @@ module URBANopt
126
126
  def get_scenario_features
127
127
  @num_header_rows = 1
128
128
  features = []
129
- CSV.foreach(@scenario_csv_path, :headers => true) do |row|
130
-
129
+ CSV.foreach(@scenario_csv_path, headers: true) do |row|
131
130
  break if row[0].nil?
132
131
 
133
132
  # gets +feature_id+ and append to list
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt (tm), Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt (tm), 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,
@@ -109,10 +109,11 @@ module URBANopt
109
109
  end
110
110
  end
111
111
  end
112
+
112
113
  def aggregate_consumption(file_csv, file_json, n_feature)
113
114
  feature_type = file_json['program']['building_types'][0]['building_type']
114
115
  # residential_building_types = "Single-Family Detached" #add the other types
115
- residential_building_types = ['Single-Family Detached', 'Single-Family Attached', 'MultiFamily', 'Single-Family', 'Multifamily Detached (2 to 4 units)', 'Multifamily Detached (5 or more units)'] # add the other types
116
+ residential_building_types = ['Single-Family Detached', 'Single-Family Attached', 'Multifamily', 'Single-Family', 'Multifamily Detached (2 to 4 units)', 'Multifamily Detached (5 or more units)'] # add the other types
116
117
  puts feature_type
117
118
  j = 0
118
119
  CSV.foreach(file_csv, headers: true) do |power|
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt (tm), Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt (tm), 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 (tm), Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt (tm), 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 (tm), Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt (tm), 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 RNM
43
- VERSION = '0.1.2'.freeze
43
+ VERSION = '0.3.0'.freeze
44
44
  end
45
45
  end
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt (tm), Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt (tm), 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 (tm), Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt (tm), 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,
@@ -54,23 +54,23 @@ module URBANopt
54
54
  conductor.each do |k, v|
55
55
  if k.include? '(mm)'
56
56
  # new_key = "#{k.sub('(mm)', '')}(ft)"
57
- new_key = "#{k.sub(' (mm)', '').gsub(' ','_')}"
57
+ new_key = k.sub(' (mm)', '').gsub(' ', '_').to_s
58
58
  hash[new_key] = v
59
59
  elsif k.include? '(A)'
60
- new_key = "#{k.sub(' (A)', '').gsub(' ','_')}"
60
+ new_key = k.sub(' (A)', '').gsub(' ', '_').to_s
61
61
  hash[new_key] = v
62
62
  elsif k.include? '#'
63
- new_key = "#{k.sub('#', 'num').gsub(' ', '_')}"
63
+ new_key = k.sub('#', 'num').gsub(' ', '_').to_s
64
64
  hash[new_key] = v
65
65
  elsif k.include? '(ohm/km)'
66
66
  # new_key = "#{k.sub('(ohm/km)', '')}(ohm/mi)"
67
- new_key = "#{k.sub(' (ohm/km)', '').gsub(' ','_')}"
67
+ new_key = k.sub(' (ohm/km)', '').gsub(' ', '_').to_s
68
68
  hash[new_key] = v
69
69
  elsif k != 'voltage level' && k != 'type'
70
- new_key = "#{k.gsub(' ', '_')}"
70
+ new_key = k.gsub(' ', '_').to_s
71
71
  hash[new_key] = v
72
72
  else
73
- new_key = "#{k.gsub(' ', '_')}"
73
+ new_key = k.gsub(' ', '_').to_s
74
74
  hash[new_key] = v
75
75
  end
76
76
  end
@@ -82,7 +82,7 @@ module URBANopt
82
82
  elsif k.include? '(m)'
83
83
  hash.delete(k)
84
84
  k = k.split(' ')[0]
85
- new_key = "#{k.sub(' ', '_')}"
85
+ new_key = k.sub(' ', '_').to_s
86
86
  hash[new_key] = v
87
87
  end
88
88
  end
data/lib/urbanopt/rnm.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt (tm), Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt (tm), 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,
data/lib/urbanopt-rnm.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt (tm), Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt (tm), 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,
@@ -23,10 +23,11 @@ Gem::Specification.new do |spec|
23
23
  spec.require_paths = ['lib', 'catalogs']
24
24
  spec.required_ruby_version = '~> 2.7.0'
25
25
 
26
+ spec.add_dependency 'certified', '~> 1'
26
27
  spec.add_dependency 'faraday', '~> 1.0.1'
27
28
  spec.add_dependency 'geoutm', '~> 1.0.2'
28
29
  spec.add_dependency 'rubyzip', '~> 2.3.2'
29
- spec.add_dependency 'urbanopt-geojson', '~> 0.6.6'
30
+ spec.add_dependency 'urbanopt-geojson', '~> 0.8.0'
30
31
 
31
32
  spec.add_development_dependency 'bundler', '~> 2.1'
32
33
  spec.add_development_dependency 'rake', '~> 13.0'
metadata CHANGED
@@ -1,16 +1,30 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: urbanopt-rnm-us
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Katherine Fleming
8
8
  - Luca de Rosa
9
- autorequire:
9
+ autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2021-11-01 00:00:00.000000000 Z
12
+ date: 2022-05-13 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: certified
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1'
14
28
  - !ruby/object:Gem::Dependency
15
29
  name: faraday
16
30
  requirement: !ruby/object:Gem::Requirement
@@ -59,14 +73,14 @@ dependencies:
59
73
  requirements:
60
74
  - - "~>"
61
75
  - !ruby/object:Gem::Version
62
- version: 0.6.6
76
+ version: 0.8.0
63
77
  type: :runtime
64
78
  prerelease: false
65
79
  version_requirements: !ruby/object:Gem::Requirement
66
80
  requirements:
67
81
  - - "~>"
68
82
  - !ruby/object:Gem::Version
69
- version: 0.6.6
83
+ version: 0.8.0
70
84
  - !ruby/object:Gem::Dependency
71
85
  name: bundler
72
86
  requirement: !ruby/object:Gem::Requirement
@@ -164,6 +178,7 @@ files:
164
178
  - CHANGELOG.md
165
179
  - CONTRIBUTING.md
166
180
  - Gemfile
181
+ - Jenkinsfile
167
182
  - LICENSE.md
168
183
  - README.md
169
184
  - Rakefile
@@ -195,7 +210,7 @@ files:
195
210
  homepage: https://github.com/urbanopt/urbanopt-RNM-us-gem
196
211
  licenses: []
197
212
  metadata: {}
198
- post_install_message:
213
+ post_install_message:
199
214
  rdoc_options: []
200
215
  require_paths:
201
216
  - lib
@@ -212,7 +227,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
212
227
  version: '0'
213
228
  requirements: []
214
229
  rubygems_version: 3.1.4
215
- signing_key:
230
+ signing_key:
216
231
  specification_version: 4
217
232
  summary: Library to create input files for RNM-US
218
233
  test_files: []