urbanopt-scenario 0.2.0.pre1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +5 -5
  2. data/.github/pull_request_template.md +2 -2
  3. data/.gitignore +2 -0
  4. data/.rubocop.yml +1 -1
  5. data/CHANGELOG.md +77 -1
  6. data/CONTRIBUTING.md +1 -1
  7. data/Gemfile +28 -18
  8. data/Jenkinsfile +1 -1
  9. data/LICENSE.md +1 -1
  10. data/RDOC_MAIN.md +1 -1
  11. data/README.md +1 -1
  12. data/Rakefile +2 -2
  13. data/docs/README.md +1 -1
  14. data/docs/package-lock.json +2499 -2322
  15. data/docs/package.json +13 -9
  16. data/lib/urbanopt-scenario.rb +1 -1
  17. data/lib/urbanopt/scenario.rb +3 -1
  18. data/lib/urbanopt/scenario/default_reports.rb +3 -8
  19. data/lib/urbanopt/scenario/extension.rb +1 -1
  20. data/lib/urbanopt/scenario/logger.rb +1 -1
  21. data/lib/urbanopt/scenario/scenario_base.rb +1 -1
  22. data/lib/urbanopt/scenario/scenario_csv.rb +22 -9
  23. data/lib/urbanopt/scenario/scenario_datapoint_base.rb +8 -1
  24. data/lib/urbanopt/scenario/scenario_post_processor_base.rb +1 -1
  25. data/lib/urbanopt/scenario/scenario_post_processor_default.rb +81 -8
  26. data/lib/urbanopt/scenario/scenario_post_processor_opendss.rb +275 -0
  27. data/lib/urbanopt/scenario/scenario_runner_base.rb +2 -2
  28. data/lib/urbanopt/scenario/scenario_runner_osw.rb +23 -9
  29. data/lib/urbanopt/scenario/scenario_visualization.rb +236 -0
  30. data/lib/urbanopt/scenario/simulation_dir_base.rb +1 -1
  31. data/lib/urbanopt/scenario/simulation_dir_osw.rb +2 -9
  32. data/lib/urbanopt/scenario/simulation_mapper_base.rb +1 -1
  33. data/lib/urbanopt/scenario/version.rb +2 -2
  34. data/package-lock.json +3 -0
  35. data/urbanopt-scenario-gem.gemspec +15 -15
  36. metadata +78 -82
  37. data/doc_templates/LICENSE.md +0 -27
  38. data/doc_templates/README.md.erb +0 -42
  39. data/doc_templates/copyright_erb.txt +0 -31
  40. data/doc_templates/copyright_js.txt +0 -4
  41. data/doc_templates/copyright_ruby.txt +0 -29
  42. data/lib/change_log.rb +0 -147
  43. data/lib/measures/.rubocop.yml +0 -5
  44. data/lib/measures/default_feature_reports/LICENSE.md +0 -27
  45. data/lib/measures/default_feature_reports/README.md +0 -56
  46. data/lib/measures/default_feature_reports/README.md.erb +0 -42
  47. data/lib/measures/default_feature_reports/measure.rb +0 -957
  48. data/lib/measures/default_feature_reports/measure.xml +0 -143
  49. data/lib/measures/default_feature_reports/tests/USA_CO_Golden-NREL.724666_TMY3.epw +0 -8768
  50. data/lib/measures/default_feature_reports/tests/default_feature_reports_test.rb +0 -238
  51. data/lib/measures/default_feature_reports/tests/example_model.osm +0 -4378
  52. data/lib/urbanopt/scenario/default_reports/construction_cost.rb +0 -169
  53. data/lib/urbanopt/scenario/default_reports/date.rb +0 -97
  54. data/lib/urbanopt/scenario/default_reports/distributed_generation.rb +0 -374
  55. data/lib/urbanopt/scenario/default_reports/end_use.rb +0 -159
  56. data/lib/urbanopt/scenario/default_reports/end_uses.rb +0 -140
  57. data/lib/urbanopt/scenario/default_reports/feature_report.rb +0 -260
  58. data/lib/urbanopt/scenario/default_reports/generator.rb +0 -92
  59. data/lib/urbanopt/scenario/default_reports/location.rb +0 -99
  60. data/lib/urbanopt/scenario/default_reports/logger.rb +0 -44
  61. data/lib/urbanopt/scenario/default_reports/program.rb +0 -266
  62. data/lib/urbanopt/scenario/default_reports/reporting_period.rb +0 -301
  63. data/lib/urbanopt/scenario/default_reports/scenario_report.rb +0 -311
  64. data/lib/urbanopt/scenario/default_reports/schema/README.md +0 -33
  65. data/lib/urbanopt/scenario/default_reports/schema/scenario_csv_columns.txt +0 -21
  66. data/lib/urbanopt/scenario/default_reports/schema/scenario_schema.json +0 -839
  67. data/lib/urbanopt/scenario/default_reports/solar_pv.rb +0 -93
  68. data/lib/urbanopt/scenario/default_reports/storage.rb +0 -105
  69. data/lib/urbanopt/scenario/default_reports/timeseries_csv.rb +0 -284
  70. data/lib/urbanopt/scenario/default_reports/validator.rb +0 -97
  71. data/lib/urbanopt/scenario/default_reports/wind.rb +0 -92
@@ -1,169 +0,0 @@
1
- # *********************************************************************************
2
- # URBANopt, Copyright (c) 2019-2020, 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
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20
- # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
- # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
- # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23
- # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24
- # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
- # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
- # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
- # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28
- # OF THE POSSIBILITY OF SUCH DAMAGE.
29
- # *********************************************************************************
30
-
31
- require 'json'
32
- require 'urbanopt/scenario/default_reports/validator'
33
- require 'json-schema'
34
-
35
- module URBANopt
36
- module Scenario
37
- module DefaultReports
38
- ##
39
- # ConstructionCost include construction cost information.
40
- ##
41
- class ConstructionCost
42
- attr_accessor :category, :item_name, :unit_cost, :cost_units, :item_quantity, :total_cost # :nodoc:
43
- ##
44
- # ConstructionCost class intialize all construction_cost attributes:
45
- # +:category+ , +:item_name+ , +:unit_cost+ , +:cost_units+ , +:item_quantity+ , +:total_cost+
46
- ##
47
- # [parameters:]
48
- # +hash+ - _Hash_ - A hash which may contain a deserialized construction_cost.
49
- ##
50
- def initialize(hash = {})
51
- hash.delete_if { |k, v| v.nil? }
52
- hash = defaults.merge(hash)
53
-
54
- @category = hash[:category]
55
- @item_name = hash[:item_name]
56
- @unit_cost = hash[:unit_cost]
57
- @cost_units = hash[:cost_units]
58
- @item_quantity = hash[:item_quantity]
59
- @total_cost = hash[:total_cost]
60
-
61
- # initialize class variables @@validator and @@schema
62
- @@validator ||= Validator.new
63
- @@schema ||= @@validator.schema
64
- end
65
-
66
- ##
67
- # Assigns default values if attribute values do not exist.
68
- ##
69
- def defaults
70
- hash = {}
71
- hash[:category] = nil
72
- hash[:item_name] = nil
73
- hash[:unit_cost] = nil
74
- hash[:cost_units] = nil
75
- hash[:item_quantity] = nil
76
- hash[:total_cost] = nil
77
-
78
- return hash
79
- end
80
-
81
- ##
82
- # Converts to a Hash equivalent for JSON serialization.
83
- ##
84
- # - Exclude attributes with nil values.
85
- # - Validate construct_cost hash properties against schema.
86
- ##
87
- def to_hash
88
- result = {}
89
- result[:category] = @category if @category
90
- result[:item_name] = @item_name if @item_name
91
- result[:unit_cost] = @unit_cost if @unit_cost
92
- result[:cost_units] = @cost_units if @cost_units
93
- result[:item_quantity] = @item_quantity if @item_quantity
94
- result[:total_cost] = @total_cost if @total_cost
95
-
96
- # validate construct_cost properties against schema
97
- if @@validator.validate(@@schema[:definitions][:ConstructionCost][:properties], result).any?
98
- raise "construction_cost properties does not match schema: #{@@validator.validate(@@schema[:definitions][:ConstructionCost][:properties], result)}"
99
- end
100
-
101
- return result
102
- end
103
-
104
- ##
105
- # Merges an +existing_cost+ with a +new_cost+:
106
- # - modify the existing_cost by summing the +:total_cost+ and +:item_quantity+ of new_cost and existing_cost.
107
- # - raise an error if +:category+ , +:cost_units+ and +:unit_cost+ are not identical
108
- ##
109
- # [Parameters:]
110
- # +existing_cost+ - _ConstructionCost_ - An object of ConstructionCost class.
111
- ##
112
- # +new_cost+ - _ConstructionCost_ - An object of ConstructionCost class.
113
- ##
114
- def self.merge_construction_cost(existing_cost, new_cost)
115
- # modify the existing_cost by adding the :total_cost and :item_quantity
116
- existing_cost.total_cost += new_cost.total_cost
117
- existing_cost.item_quantity += new_cost.item_quantity
118
-
119
- if existing_cost.category != new_cost.category
120
- raise "Cannot merge existing cost of category \"#{existing_cost.category}\" with new cost of category \"#{new_cost.category}\"."
121
- end
122
-
123
- if existing_cost.cost_units != new_cost.cost_units
124
- raise "Cannot merge existing cost with cost units \"#{existing_cost.cost_units}\" with new cost with cost units \"#{new_cost.cost_units}\". "
125
- end
126
-
127
- if existing_cost.unit_cost != new_cost.unit_cost
128
- raise "Cannot merge existing cost with unit cost \"#{existing_cost.unit_cost}\" with new cost with unit cost \"#{new_cost.unit_cost}\"; identical items should have identical unit cost."
129
- end
130
-
131
- return existing_cost
132
- end
133
-
134
- ##
135
- # Merges muliple construction costs together.
136
- # - loops over the new_costs and find the index of the cost with identical +:item_name+.
137
- # - if +item_name+ is identical then modify the existing_cost array by summing the :total_cost and :item_quantity. Else add the new_cost to existing_costs array.
138
- ##
139
- # [Parameters:]
140
- # +existing_costs+ - _Array_ - An array of ConstructionCost objects.
141
- ##
142
- # +new_costs+ - _Array_ - An array of ConstructionCost objects.
143
- def self.merge_construction_costs(existing_costs, new_costs)
144
- item_name_list = []
145
- item_name_list = existing_costs.collect(&:item_name)
146
-
147
- new_costs.each do |x_new|
148
- if item_name_list.include?(x_new.item_name)
149
-
150
- # when looping over the new_cost item_names find the index of the item_name_list with the same item name
151
- id = item_name_list.find_index(x_new.item_name) # the order of the item_name_list is the same as the order of the existing_cost hash-array
152
-
153
- # modify the existing_cost array by adding the :total_cost and :item_quantity when looping over costs
154
- existing_costs[id] = merge_construction_cost(existing_costs[id], x_new)
155
-
156
- else
157
-
158
- # insert the new hash in to the array
159
- existing_costs << x_new
160
-
161
- end
162
- end
163
-
164
- return existing_costs
165
- end
166
- end
167
- end
168
- end
169
- end
@@ -1,97 +0,0 @@
1
- # *********************************************************************************
2
- # URBANopt, Copyright (c) 2019-2020, 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
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20
- # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
- # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
- # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23
- # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24
- # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
- # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
- # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
- # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28
- # OF THE POSSIBILITY OF SUCH DAMAGE.
29
- # *********************************************************************************
30
-
31
- require 'urbanopt/scenario/default_reports/validator'
32
- require 'json-schema'
33
- require 'json'
34
-
35
- module URBANopt
36
- module Scenario
37
- module DefaultReports
38
- ##
39
- # Date class include information of simulation run date.
40
- ##
41
- class Date
42
- attr_accessor :month, :day_of_month, :year #:nodoc:
43
- ##
44
- # Date class intialize all date attributes:
45
- # +:month+ , +:day_of_month+ , +:year+
46
- ##
47
- # [parameters:]
48
- # +hash+ - _Hash_ - A hash which may contain a deserialized date.
49
- ##
50
- def initialize(hash = {})
51
- hash.delete_if { |k, v| v.nil? }
52
- hash = defaults.merge(hash)
53
-
54
- @month = hash[:month].to_i
55
- @day_of_month = hash[:day_of_month].to_i
56
- @year = hash[:year].to_i
57
-
58
- # initialize class variables @@validator and @@schema
59
- @@validator ||= Validator.new
60
- @@schema ||= @@validator.schema
61
- end
62
-
63
- ##
64
- # Converts to a hash equivalent for JSON serialization.
65
- ##
66
- # - Exclude attributes with nil values.
67
- # - Validate date properties against schema.
68
- ##
69
- def to_hash
70
- result = {}
71
- result[:month] = @month if @month
72
- result[:day_of_month] = @day_of_month if @day_of_month
73
- result[:year] = @year if @year
74
-
75
- # validate date hash properties against schema
76
- if @@validator.validate(@@schema[:definitions][:Date][:properties], result).any?
77
- raise "end_uses properties does not match schema: #{@@validator.validate(@@schema[:definitions][:Date][:properties], result)}"
78
- end
79
-
80
- return result
81
- end
82
-
83
- ##
84
- # Assigns default values if values do not exist.
85
- ##
86
- def defaults
87
- hash = {}
88
- hash[:month] = nil
89
- hash[:day_of_month] = nil
90
- hash[:year] = nil
91
-
92
- return hash
93
- end
94
- end
95
- end
96
- end
97
- end
@@ -1,374 +0,0 @@
1
- # *********************************************************************************
2
- # URBANopt, Copyright (c) 2019-2020, 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
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20
- # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
- # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
- # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23
- # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24
- # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
- # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
- # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
- # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28
- # OF THE POSSIBILITY OF SUCH DAMAGE.
29
- # *********************************************************************************
30
-
31
- require 'json'
32
- require 'urbanopt/scenario/default_reports/solar_pv'
33
- require 'urbanopt/scenario/default_reports/wind'
34
- require 'urbanopt/scenario/default_reports/generator'
35
- require 'urbanopt/scenario/default_reports/storage'
36
- require 'json-schema'
37
-
38
- module URBANopt
39
- module Scenario
40
- module DefaultReports
41
- ##
42
- # Onsite distributed generation system (i.e. SolarPV, Wind, Storage, Generator) design attributes and financial metrics.
43
- ##
44
- class DistributedGeneration
45
- ##
46
- # _Float_ - Lifecycle costs for the complete distributed generation system in US Dollars
47
- #
48
- attr_accessor :lcc_us_dollars
49
-
50
- ##
51
- # _Float_ - Net present value of the complete distributed generation system in US Dollars
52
- #
53
- attr_accessor :npv_us_dollars
54
-
55
- ##
56
- # _Float_ - Total amount paid for utility energy in US Dollars in the first year of operation
57
- #
58
- attr_accessor :year_one_energy_cost_us_dollars
59
-
60
- ##
61
- # _Float_ - Total amount paid in utility demand charges in US Dollars in the first year of operation
62
- #
63
- attr_accessor :year_one_demand_cost_us_dollars
64
-
65
- ##
66
- # _Float_ - Total amount paid to the utility in US Dollars in the first year of operation
67
- #
68
- attr_accessor :year_one_bill_us_dollars
69
-
70
- ##
71
- # _Float_ - Total amount paid to the utility in US Dollars over the life of the system
72
- #
73
- attr_accessor :total_energy_cost_us_dollars
74
-
75
- ##
76
- # _Array_ - List of _SolarPV_ systems
77
- #
78
- attr_accessor :solar_pv
79
-
80
- ##
81
- # _Array_ - List of _Wind_ systems
82
- #
83
- attr_accessor :wind
84
-
85
- ##
86
- # _Array_ - List of _Generator_ systems
87
- #
88
- attr_accessor :generator
89
-
90
- ##
91
- # _Array_ - List of _Storage_ systems
92
- #
93
- attr_accessor :storage
94
-
95
- ##
96
- # _Float_ - Installed solar PV capacity
97
- #
98
- attr_accessor :total_solar_pv_kw
99
-
100
- ##
101
- # _Float_ - Installed wind capacity
102
- #
103
- attr_accessor :total_wind_kw
104
-
105
- ##
106
- # _Float_ - Installed storage capacity
107
- #
108
- attr_accessor :total_storage_kw
109
-
110
- ##
111
- # _Float_ - Installed generator capacity
112
- #
113
- attr_accessor :total_generator_kw
114
-
115
- ##
116
- # Initialize distributed generation system design and financial metrics.
117
- #
118
- # * Technologies include +:solar_pv+, +:wind+, +:generator+, and +:storage+.
119
- # * Financial metrics include +:lcc_us_dollars+, +:npv_us_dollars+, +:year_one_energy_cost_us_dollars+, +:year_one_demand_cost_us_dollars+,
120
- # +:year_one_bill_us_dollars+, and +:total_energy_cost_us_dollars+
121
- ##
122
- # [parameters:]
123
- #
124
- # * +hash+ - _Hash_ - A hash containting key/value pairs for the distributed generation system attributes listed above.
125
- #
126
- def initialize(hash = {})
127
- hash.delete_if { |k, v| v.nil? }
128
-
129
- @lcc_us_dollars = hash[:lcc_us_dollars]
130
- @npv_us_dollars = hash[:npv_us_dollars]
131
- @year_one_energy_cost_us_dollars = hash[:year_one_energy_cost_us_dollars]
132
- @year_one_demand_cost_us_dollars = hash[:year_one_demand_cost_us_dollars]
133
- @year_one_bill_us_dollars = hash[:year_one_bill_us_dollars]
134
- @total_energy_cost_us_dollars = hash[:total_energy_cost_us_dollars]
135
-
136
- @total_solar_pv_kw = nil
137
- @total_wind_kw = nil
138
- @total_generator_kw = nil
139
- @total_storage_kw = nil
140
- @total_storage_kwh = nil
141
-
142
- @solar_pv = []
143
- if hash[:solar_pv].class == Hash
144
- hash[:solar_pv] = [hash[:solar_pv]]
145
- elsif hash[:solar_pv].nil?
146
- hash[:solar_pv] = []
147
- end
148
-
149
- hash[:solar_pv].each do |s|
150
- if !s[:size_kw].nil? && (s[:size_kw] != 0)
151
- @solar_pv.push SolarPV.new(s)
152
- if @total_solar_pv_kw.nil?
153
- @total_solar_pv_kw = @solar_pv[-1].size_kw
154
- else
155
- @total_solar_pv_kw += @solar_pv[-1].size_kw
156
- end
157
- end
158
- end
159
-
160
- @wind = []
161
- if hash[:wind].class == Hash
162
- hash[:wind] = [hash[:wind]]
163
- elsif hash[:wind].nil?
164
- hash[:wind] = []
165
- end
166
-
167
- hash[:wind].each do |s|
168
- if !s[:size_kw].nil? && (s[:size_kw] != 0)
169
- @wind.push Wind.new(s)
170
- if @total_wind_kw.nil?
171
- @total_wind_kw = @wind[-1].size_kw
172
- else
173
- @total_wind_kw += @wind[-1].size_kw
174
- end
175
- end
176
- end
177
-
178
- @generator = []
179
- if hash[:generator].class == Hash
180
- hash[:generator] = [hash[:generator]]
181
- elsif hash[:generator].nil?
182
- hash[:generator] = []
183
- end
184
-
185
- hash[:generator].each do |s|
186
- if !s[:size_kw].nil? && (s[:size_kw] != 0)
187
- @generator.push Generator.new(s)
188
- if @total_generator_kw.nil?
189
- @total_generator_kw = @generator[-1].size_kw
190
- else
191
- @total_generator_kw += @generator[-1].size_kw
192
- end
193
- end
194
- end
195
-
196
- @storage = []
197
- if hash[:storage].class == Hash
198
- hash[:storage] = [hash[:storage]]
199
- elsif hash[:storage].nil?
200
- hash[:storage] = []
201
- end
202
-
203
- hash[:storage].each do |s|
204
- if !s[:size_kw].nil? && (s[:size_kw] != 0)
205
- @storage.push Storage.new(s)
206
- if @total_storage_kw.nil?
207
- @total_storage_kw = @storage[-1].size_kw
208
- @total_storage_kwh = @storage[-1].size_kwh
209
- else
210
- @total_storage_kw += @storage[-1].size_kw
211
- @total_storage_kwh += @storage[-1].size_kwh
212
- end
213
- end
214
- end
215
-
216
- # initialize class variables @@validator and @@schema
217
- @@validator ||= Validator.new
218
- @@schema ||= @@validator.schema
219
-
220
- # initialize @@logger
221
- @@logger ||= URBANopt::Scenario::DefaultReports.logger
222
- end
223
-
224
- ##
225
- # Add a tech
226
- ##
227
- def add_tech(name, tech)
228
- if name == 'solar_pv'
229
- @solar_pv.push tech
230
- if @total_solar_pv_kw.nil?
231
- @total_solar_pv_kw = tech.size_kw
232
- else
233
- @total_solar_pv_kw += tech.size_kw
234
- end
235
- end
236
-
237
- if name == 'wind'
238
- @wind.push tech
239
- if @total_wind_kw.nil?
240
- @total_wind_kw = tech.size_kw
241
- else
242
- @total_wind_kw += tech.size_kw
243
- end
244
- end
245
-
246
- if name == 'storage'
247
- @storage.push tech
248
- if @total_storage_kw.nil?
249
- @total_storage_kw = tech.size_kw
250
- @total_storage_kwh = tech.size_kwh
251
- else
252
- @total_storage_kw += tech.size_kw
253
- @total_storage_kwh += tech.size_kwh
254
- end
255
- end
256
-
257
- if name == 'generator'
258
- @generator.push tech
259
- if @total_generator_kw.nil?
260
- @total_generator_kw = tech.size_kw
261
- else
262
- @total_generator_kw += tech.size_kw
263
- end
264
- end
265
- end
266
-
267
- ##
268
- # Convert to a Hash equivalent for JSON serialization
269
- ##
270
- def to_hash
271
- result = {}
272
-
273
- result[:lcc_us_dollars] = @lcc_us_dollars if @lcc_us_dollars
274
- result[:npv_us_dollars] = @npv_us_dollars if @npv_us_dollars
275
- result[:year_one_energy_cost_us_dollars] = @year_one_energy_cost_us_dollars if @year_one_energy_cost_us_dollars
276
- result[:year_one_demand_cost_us_dollars] = @year_one_demand_cost_us_dollars if @year_one_demand_cost_us_dollars
277
- result[:year_one_bill_us_dollars] = @year_one_bill_us_dollars if @year_one_bill_us_dollars
278
- result[:total_solar_pv_kw] = @total_solar_pv_kw if @total_solar_pv_kw
279
- result[:total_wind_kw] = @total_wind_kw if @total_wind_kw
280
- result[:total_generator_kw] = @total_generator_kw if @total_generator_kw
281
- result[:total_storage_kw] = @total_storage_kw if @total_storage_kw
282
- result[:total_storage_kwh] = @total_storage_kwh if @total_storage_kwh
283
-
284
- result[:solar_pv] = []
285
- @solar_pv.each do |pv|
286
- result[:solar_pv].push pv.to_hash
287
- end
288
- result[:wind] = []
289
- @wind.each do |pv|
290
- result[:wind].push wind.to_hash
291
- end
292
- result[:generator] = []
293
- @generator.each do |pv|
294
- result[:generator].push generator.to_hash
295
- end
296
- result[:storage] = []
297
- @storage.each do |pv|
298
- result[:storage].push storage.to_hash
299
- end
300
- return result
301
- end
302
-
303
- ### get keys ...not needed
304
- # def self.get_all_keys(h)
305
- # h.each_with_object([]){|(k,v),a| v.is_a?(Hash) ? a.push(k,*get_all_keys(v)) : a << k }
306
- # end
307
-
308
- ##
309
- # Add up old and new values
310
- ##
311
- def self.add_values(existing_value, new_value) #:nodoc:
312
- if existing_value && new_value
313
- existing_value += new_value
314
- elsif new_value
315
- existing_value = new_value
316
- end
317
- return existing_value
318
- end
319
-
320
- ##
321
- # Merge a distributed generation system with a new system
322
- ##
323
- def self.merge_distributed_generation(existing_dgen, new_dgen)
324
- existing_dgen.lcc_us_dollars = add_values(existing_dgen.lcc_us_dollars, new_dgen.lcc_us_dollars)
325
- existing_dgen.npv_us_dollars = add_values(existing_dgen.npv_us_dollars, new_dgen.npv_us_dollars)
326
- existing_dgen.year_one_energy_cost_us_dollars = add_values(existing_dgen.year_one_energy_cost_us_dollars, new_dgen.year_one_energy_cost_us_dollars)
327
- existing_dgen.year_one_demand_cost_us_dollars = add_values(existing_dgen.year_one_demand_cost_us_dollars, new_dgen.year_one_demand_cost_us_dollars)
328
- existing_dgen.year_one_bill_us_dollars = add_values(existing_dgen.year_one_bill_us_dollars, new_dgen.year_one_bill_us_dollars)
329
- existing_dgen.total_energy_cost_us_dollars = add_values(existing_dgen.total_energy_cost_us_dollars, new_dgen.total_energy_cost_us_dollars)
330
-
331
- new_dgen.solar_pv.each do |pv|
332
- existing_dgen.solar_pv.push pv
333
- if existing_dgen.total_solar_pv_kw.nil?
334
- existing_dgen.total_solar_pv_kw = pv.size_kw
335
- else
336
- existing_dgen.total_solar_pv_kw += pv.size_kw
337
- end
338
- end
339
-
340
- new_dgen.wind.each do |wind|
341
- existing_dgen.wind.push wind
342
- if existing_dgen.total_wind_kw.nil?
343
- existing_dgen.total_wind_kw = wind.size_kw
344
- else
345
- existing_dgen.total_wind_kw += wind.size_kw
346
- end
347
- end
348
-
349
- new_dgen.storage.each do |storage|
350
- existing_dgen.storage.push storage
351
- if existing_dgen.total_wind_kw.nil?
352
- existing_dgen.total_storage_kw = storage.size_kw
353
- existing_dgen.total_storage_kwh = storage.size_kwh
354
- else
355
- existing_dgen.total_storage_kw += storage.size_kw
356
- existing_dgen.total_storage_kwh += storage.size_kwh
357
- end
358
- end
359
-
360
- new_dgen.generator.each do |generator|
361
- existing_dgen.generator.push generator
362
- if existing_dgen.total_wind_kw.nil?
363
- existing_dgen.total_generator_kw = generator.size_kw
364
- else
365
- existing_dgen.total_generator_kw += generator.size_kw
366
- end
367
- end
368
-
369
- return existing_dgen
370
- end
371
- end
372
- end
373
- end
374
- end