urbanopt-scenario 0.2.0.pre1 → 0.4.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.
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