urbanopt-scenario 0.1.0 → 0.1.1

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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CONTRIBUTING.md +58 -0
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +27 -0
  4. data/.github/ISSUE_TEMPLATE/feature_request.md +23 -0
  5. data/.github/pull_request_template.md +23 -0
  6. data/.gitignore +1 -0
  7. data/CHANGELOG.md +16 -2
  8. data/Gemfile +1 -0
  9. data/LICENSE.md +1 -1
  10. data/doc_templates/LICENSE.md +1 -1
  11. data/doc_templates/copyright_erb.txt +1 -1
  12. data/doc_templates/copyright_js.txt +1 -1
  13. data/doc_templates/copyright_ruby.txt +1 -1
  14. data/docs/package-lock.json +142 -116
  15. data/docs/package.json +5 -1
  16. data/lib/change_log.rb +147 -0
  17. data/lib/measures/default_feature_reports/measure.rb +16 -5
  18. data/lib/measures/default_feature_reports/tests/default_feature_reports_test.rb +1 -1
  19. data/lib/urbanopt-scenario.rb +1 -1
  20. data/lib/urbanopt/scenario.rb +1 -1
  21. data/lib/urbanopt/scenario/default_reports.rb +1 -1
  22. data/lib/urbanopt/scenario/default_reports/construction_cost.rb +1 -1
  23. data/lib/urbanopt/scenario/default_reports/date.rb +1 -1
  24. data/lib/urbanopt/scenario/default_reports/distributed_generation.rb +187 -0
  25. data/lib/urbanopt/scenario/default_reports/end_use.rb +1 -1
  26. data/lib/urbanopt/scenario/default_reports/end_uses.rb +1 -1
  27. data/lib/urbanopt/scenario/default_reports/feature_report.rb +8 -2
  28. data/lib/urbanopt/scenario/default_reports/generator.rb +92 -0
  29. data/lib/urbanopt/scenario/default_reports/location.rb +2 -2
  30. data/lib/urbanopt/scenario/default_reports/logger.rb +1 -1
  31. data/lib/urbanopt/scenario/default_reports/program.rb +2 -2
  32. data/lib/urbanopt/scenario/default_reports/reporting_period.rb +2 -2
  33. data/lib/urbanopt/scenario/default_reports/scenario_report.rb +36 -12
  34. data/lib/urbanopt/scenario/default_reports/schema/README.md +16 -15
  35. data/lib/urbanopt/scenario/default_reports/schema/scenario_schema.json +88 -0
  36. data/lib/urbanopt/scenario/default_reports/solar_pv.rb +92 -0
  37. data/lib/urbanopt/scenario/default_reports/storage.rb +105 -0
  38. data/lib/urbanopt/scenario/default_reports/timeseries_csv.rb +32 -5
  39. data/lib/urbanopt/scenario/default_reports/validator.rb +2 -2
  40. data/lib/urbanopt/scenario/default_reports/wind.rb +92 -0
  41. data/lib/urbanopt/scenario/extension.rb +1 -1
  42. data/lib/urbanopt/scenario/logger.rb +1 -1
  43. data/lib/urbanopt/scenario/scenario_base.rb +1 -1
  44. data/lib/urbanopt/scenario/scenario_csv.rb +1 -1
  45. data/lib/urbanopt/scenario/scenario_datapoint_base.rb +1 -1
  46. data/lib/urbanopt/scenario/scenario_post_processor_base.rb +1 -1
  47. data/lib/urbanopt/scenario/scenario_post_processor_default.rb +7 -6
  48. data/lib/urbanopt/scenario/scenario_runner_base.rb +1 -1
  49. data/lib/urbanopt/scenario/scenario_runner_osw.rb +1 -1
  50. data/lib/urbanopt/scenario/simulation_dir_base.rb +1 -1
  51. data/lib/urbanopt/scenario/simulation_dir_osw.rb +1 -1
  52. data/lib/urbanopt/scenario/simulation_mapper_base.rb +1 -1
  53. data/lib/urbanopt/scenario/version.rb +2 -2
  54. data/urbanopt-scenario-gem.gemspec +2 -0
  55. metadata +26 -2
@@ -0,0 +1,92 @@
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 'json-schema'
33
+
34
+ module URBANopt
35
+ module Scenario
36
+ module DefaultReports
37
+ ##
38
+ # Onsite generator system attributes
39
+ ##
40
+ class Generator
41
+ ##
42
+ # _Float_ - power capacity in kilowatts
43
+ #
44
+ attr_accessor :size_kw
45
+
46
+ ##
47
+ # Intialize Generator attributes from a hash. Generator attributes currently are limited to power capacity.
48
+ ##
49
+ # [parameters:]
50
+ #
51
+ # * +hash+ - _Hash_ - A hash containting a +:size_kw+ key/value pair which represents the nameplate capacity in kilowatts (kW)
52
+ #
53
+ def initialize(hash = {})
54
+ hash.delete_if { |k, v| v.nil? }
55
+
56
+ @size_kw = hash[:size_kw]
57
+
58
+ # initialize class variables @@validator and @@schema
59
+ @@validator ||= Validator.new
60
+ @@schema ||= @@validator.schema
61
+
62
+ # initialize @@logger
63
+ @@logger ||= URBANopt::Scenario::DefaultReports.logger
64
+ end
65
+
66
+ ##
67
+ # Convert to a Hash equivalent for JSON serialization
68
+ ##
69
+ def to_hash
70
+ result = {}
71
+
72
+ result[:size_kw] = @size_kw if @size_kw
73
+
74
+ return result
75
+ end
76
+
77
+ ##
78
+ # Merge Generator systems
79
+ ##
80
+ def self.add_generator(existing_generator, new_generator)
81
+ if existing_generator.size_kw.nil? && new_generator.size_kw.nil?
82
+ existing_generator.size_kw = nil
83
+ else
84
+ existing_generator.size_kw = (existing_generator.size_kw || 0) + (new_generator.size_kw || 0)
85
+ end
86
+
87
+ return existing_generator
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt, Copyright (c) 2019, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt, Copyright (c) 2019-2020, 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,
@@ -41,7 +41,7 @@ module URBANopt
41
41
  class Location
42
42
  attr_accessor :latitude, :longitude, :surface_elevation, :weather_filename #:nodoc:
43
43
  ##
44
- # Location class intialize location attributes: +:latitude+ , +:longitude+ , +:surface_elevation+ , +:weather_filename+
44
+ # Location class initialize location attributes: +:latitude+ , +:longitude+ , +:surface_elevation+ , +:weather_filename+
45
45
  ##
46
46
  # [parameters:]
47
47
  # +hash+ - _Hash_ - A hash which may contain a deserialized location.
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt, Copyright (c) 2019, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
  #
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt, Copyright (c) 2019, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
  #
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -45,7 +45,7 @@ module URBANopt
45
45
  :maximum_number_of_parking_stories_above_ground, :number_of_residential_units, :building_types, :building_type, :maximum_occupancy,
46
46
  :area, :window_area, :north_window_area, :south_window_area, :east_window_area, :west_window_area, :wall_area, :roof_area, :equipment_roof_area,
47
47
  :photovoltaic_roof_area, :available_roof_area, :total_roof_area, :orientation, :aspect_ratio # :nodoc:
48
- # Program class intialize building program attributes: +:site_area+ , +:floor_area+ , +:conditioned_area+ , +:unconditioned_area+ ,
48
+ # Program class initialize building program attributes: +:site_area+ , +:floor_area+ , +:conditioned_area+ , +:unconditioned_area+ ,
49
49
  # +:footprint_area+ , +:maximum_roof_height, +:maximum_number_of_stories+ , +:maximum_number_of_stories_above_ground+ , +:parking_area+ ,
50
50
  # +:number_of_parking_spaces+ , +:number_of_parking_spaces_charging+ , +:parking_footprint_area+ , +:maximum_parking_height+ , +:maximum_number_of_parking_stories+ ,
51
51
  # +:maximum_number_of_parking_stories_above_ground+ , +:number_of_residential_units+ , +:building_types+ , +:building_type+ , +:maximum_occupancy+ ,
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt, Copyright (c) 2019, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
  #
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -47,7 +47,7 @@ module URBANopt
47
47
  :district_heating, :water, :electricity_produced, :end_uses, :energy_production, :photovoltaic, :utility_costs,
48
48
  :fuel_type, :total_cost, :usage_cost, :demand_cost, :comfort_result, :time_setpoint_not_met_during_occupied_cooling,
49
49
  :time_setpoint_not_met_during_occupied_heating, :time_setpoint_not_met_during_occupied_hours #:nodoc:
50
- # ReportingPeriod class intializes the reporting period attributes:
50
+ # ReportingPeriod class initializes the reporting period attributes:
51
51
  # +:id+ , +:name+ , +:multiplier+ , +:start_date+ , +:end_date+ , +:month+ , +:day_of_month+ , +:year+ , +:total_site_energy+ , +:total_source_energy+ ,
52
52
  # +:net_site_energy+ , +:net_source_energy+ , +:net_utility_cost+ , +:electricity+ , +:natural_gas+ , +:additional_fuel+ , +:district_cooling+ ,
53
53
  # +:district_heating+ , +:water+ , +:electricity_produced+ , +:end_uses+ , +:energy_production+ , +:photovoltaic+ , +:utility_costs+ ,
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt, Copyright (c) 2019, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt, Copyright (c) 2019-2020, 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,
@@ -34,6 +34,7 @@ require 'urbanopt/scenario/default_reports/logger'
34
34
  require 'urbanopt/scenario/default_reports/program'
35
35
  require 'urbanopt/scenario/default_reports/reporting_period'
36
36
  require 'urbanopt/scenario/default_reports/timeseries_csv'
37
+ require 'urbanopt/scenario/default_reports/distributed_generation'
37
38
  require 'urbanopt/scenario/default_reports/validator'
38
39
  require 'json-schema'
39
40
 
@@ -51,7 +52,7 @@ module URBANopt
51
52
  class ScenarioReport
52
53
  attr_accessor :id, :name, :directory_name, :timesteps_per_hour, :number_of_not_started_simulations,
53
54
  :number_of_started_simulations, :number_of_complete_simulations, :number_of_failed_simulations,
54
- :timeseries_csv, :location, :program, :construction_costs, :reporting_periods, :feature_reports # :nodoc:
55
+ :timeseries_csv, :location, :program, :construction_costs, :reporting_periods, :feature_reports, :distributed_generation # :nodoc:
55
56
  # ScenarioReport class intializes the scenario report attributes:
56
57
  # +:id+ , +:name+ , +:directory_name+, +:timesteps_per_hour+ , +:number_of_not_started_simulations+ ,
57
58
  # +:number_of_started_simulations+ , +:number_of_complete_simulations+ , +:number_of_failed_simulations+ ,
@@ -88,12 +89,14 @@ module URBANopt
88
89
  @reporting_periods << ReportingPeriod.new(rp)
89
90
  end
90
91
 
91
- # intialized here to be used in the add_feature_report method
92
+ # feature_report is intialized here to be used in the add_feature_report method
92
93
  @feature_reports = []
93
94
  hash[:feature_reports].each do |fr|
94
95
  @feature_reports << FeatureReport.new(fr)
95
96
  end
96
97
 
98
+ @distributed_generation = DistributedGeneration.new(hash[:distributed_generation] || {})
99
+ @file_name = 'default_scenario_report'
97
100
  # initialize class variables @@validator and @@schema
98
101
  @@validator ||= Validator.new
99
102
  @@schema ||= @@validator.schema
@@ -128,20 +131,34 @@ module URBANopt
128
131
  # Gets the saved JSON file path.
129
132
  ##
130
133
  def json_path
131
- File.join(@directory_name, 'default_scenario_report.json')
134
+ File.join(@directory_name, @file_name + '.json')
132
135
  end
133
136
 
134
137
  ##
135
138
  # Gets the saved CSV file path.
136
139
  ##
137
140
  def csv_path
138
- File.join(@directory_name, 'default_scenario_report.csv')
141
+ File.join(@directory_name, @file_name + '.csv')
139
142
  end
140
143
 
141
144
  ##
142
145
  # Saves the 'default_feature_report.json' and 'default_scenario_report.csv' files
143
146
  ##
144
- def save
147
+ # [parameters]:
148
+ # +file_name+ - _String_ - Assign a name to the saved scenario results file
149
+ def save(file_name = 'default_scenario_report')
150
+ # reassign the initialize local variable @file_name to the file name input.
151
+ @file_name = file_name
152
+
153
+ # save the csv data
154
+ old_timeseries_path = nil
155
+ if !@timeseries_csv.path.nil?
156
+ old_timeseries_path = @timeseries_csv.path
157
+ end
158
+
159
+ @timeseries_csv.path = File.join(@directory_name, file_name + '.csv')
160
+ @timeseries_csv.save_data
161
+
145
162
  hash = {}
146
163
  hash[:scenario_report] = to_hash
147
164
  hash[:feature_reports] = []
@@ -149,9 +166,11 @@ module URBANopt
149
166
  hash[:feature_reports] << feature_report.to_hash
150
167
  end
151
168
 
152
- File.open(json_path, 'w') do |f|
169
+ json_name_path = File.join(@directory_name, file_name + '.json')
170
+
171
+ File.open(json_name_path, 'w') do |f|
153
172
  f.puts JSON.pretty_generate(hash)
154
- # make sure data is written to the disk one way or the other #:nodoc:
173
+ # make sure data is written to the disk one way or the other
155
174
  begin
156
175
  f.fsync
157
176
  rescue StandardError
@@ -159,9 +178,11 @@ module URBANopt
159
178
  end
160
179
  end
161
180
 
162
- # save the csv data #:nodoc:
163
- timeseries_csv.save_data(csv_path)
164
-
181
+ if !old_timeseries_path.nil?
182
+ @timeseries_csv.path = old_timeseries_path
183
+ else
184
+ @timeseries_csv.path = File.join(@directory_name, 'default_scenario_report.csv')
185
+ end
165
186
  return true
166
187
  end
167
188
 
@@ -184,6 +205,7 @@ module URBANopt
184
205
  result[:timeseries_csv] = @timeseries_csv.to_hash if @timeseries_csv
185
206
  result[:location] = @location.to_hash if @location
186
207
  result[:program] = @program.to_hash if @program
208
+ result[:distributed_generation] = @distributed_generation.to_hash if @distributed_generation
187
209
 
188
210
  result[:construction_costs] = []
189
211
  @construction_costs.each { |cc| result[:construction_costs] << cc.to_hash } if @construction_costs
@@ -264,7 +286,9 @@ module URBANopt
264
286
  # merge reporting_periods information
265
287
  @reporting_periods = ReportingPeriod.merge_reporting_periods(@reporting_periods, feature_report.reporting_periods)
266
288
 
267
- # add the array of feature_reports
289
+ @distributed_generation = DistributedGeneration.merge_distributed_generation(@distributed_generation, feature_report.distributed_generation)
290
+
291
+ # add feature_report
268
292
  @feature_reports << feature_report
269
293
 
270
294
  # scenario report location takes the location of the first feature in the list
@@ -16,18 +16,19 @@ The URBANopt Scenario Gem includes functionality for defining scenarios, running
16
16
 
17
17
  **CSV Output Units**
18
18
 
19
- | output | unit |
20
- | ----------------------------------- | ------- |
21
- | Electricity:Facility | kbtu |
22
- | ElectricityProduced:Facility | kbtu |
23
- | Gas:Facility | kbtu |
24
- | DistrictCooling:Facility | kbtu |
25
- | DistrictHeating:Facility | kbtu |
26
- | District Cooling Chilled Water Rate | GPM |
27
- | District Cooling Mass Flow Rate | lbs/min |
28
- | District Cooling Inlet Temperature | &deg;F |
29
- | District Cooling Outlet Temperature | &deg;F |
30
- | District Heating Hot Water Rate | GPM |
31
- | District Heating Mass Flow Rate | lbs/min |
32
- | District Heating Inlet Temperature | &deg;F |
33
- | District Heating Outlet Temperature | &deg;F |
19
+ | output | unit |
20
+ | -----------------------------------------| ------- |
21
+ | Electricity:Facility | kbtu |
22
+ | ElectricityProduced:Facility | kbtu |
23
+ | Gas:Facility | kbtu |
24
+ | DistrictCooling:Facility | kbtu |
25
+ | DistrictHeating:Facility | kbtu |
26
+ | District Cooling Chilled Water Rate | GPM |
27
+ | District Cooling Mass Flow Rate | lbs/min |
28
+ | District Cooling Inlet Temperature | &deg;F |
29
+ | District Cooling Outlet Temperature | &deg;F |
30
+ | District Heating Hot Water Rate | GPM |
31
+ | District Heating Mass Flow Rate | lbs/min |
32
+ | District Heating Inlet Temperature | &deg;F |
33
+ | District Heating Outlet Temperature | &deg;F |
34
+ | Electricity:Grid:ToLoad | kWh. |
@@ -60,7 +60,11 @@
60
60
  },
61
61
  "reporting_periods": {
62
62
  "$ref": "#/definitions/ReportingPeriods"
63
+ },
64
+ "distributed_generation": {
65
+ "$ref": "#/definitions/DistributedGeneration"
63
66
  }
67
+
64
68
  },
65
69
  "required": [
66
70
  "id",
@@ -75,6 +79,87 @@
75
79
  ],
76
80
  "additionalProperties": false
77
81
  },
82
+ "DistributedGeneration": {
83
+ "type": "object",
84
+ "properties": {
85
+ "lcc_us_dollars": {
86
+ "type": "number",
87
+ "description": "Optimal lifecycle cost"
88
+ },
89
+ "npv_us_dollars": {
90
+ "type": "number",
91
+ "description": "Net present value of savings realized by the project"
92
+ },
93
+ "year_one_energy_cost_us_dollars": {
94
+ "type": "number",
95
+ "description": "Optimal year one utility energy cost"
96
+ },
97
+ "year_one_demand_cost_us_dollars": {
98
+ "type": "number",
99
+ "description": "Optimal year one utility demand cost"
100
+ },
101
+ "year_one_bill_us_dollars": {
102
+ "type": "number",
103
+ "description": "Optimal year one utility bill"
104
+ },
105
+ "total_energy_cost_us_dollars": {
106
+ "type": "number",
107
+ "description": "Total utility energy cost over the lifecycle, after-tax"
108
+ },
109
+ "SolarPV" : {
110
+ "$ref": "#/definitions/SolarPV"
111
+ },
112
+ "Wind" : {
113
+ "$ref": "#/definitions/Wind"
114
+ },
115
+ "Generator" : {
116
+ "$ref": "#/definitions/Generator"
117
+ },
118
+ "Storage" : {
119
+ "$ref": "#/definitions/Storage"
120
+ }
121
+ }
122
+ },
123
+ "SolarPV": {
124
+ "type": "object",
125
+ "properties": {
126
+ "size_kw": {
127
+ "description": "rated power in kW",
128
+ "type": "string"
129
+ }
130
+ }
131
+ },
132
+ "Wind": {
133
+ "type": "object",
134
+ "properties": {
135
+ "size_kw": {
136
+ "description": "rated power in kW",
137
+ "type": "string"
138
+ }
139
+ }
140
+ },
141
+ "Generator": {
142
+ "type": "object",
143
+ "properties": {
144
+ "size_kw": {
145
+ "description": "rated power in kW",
146
+ "type": "string"
147
+ }
148
+ }
149
+ },
150
+ "Storage": {
151
+ "type": "object",
152
+ "properties": {
153
+ "size_kw": {
154
+ "description": "rated power in kW",
155
+ "type": "string"
156
+ },
157
+ "size_kw": {
158
+ "description": "rated capacity in kWh",
159
+ "type": "string"
160
+ }
161
+ }
162
+ },
78
163
  "FeatureReport": {
79
164
  "type": "object",
80
165
  "properties": {
@@ -126,6 +211,9 @@
126
211
  },
127
212
  "reporting_periods": {
128
213
  "$ref": "#/definitions/ReportingPeriods"
214
+ },
215
+ "distributed_generation": {
216
+ "$ref": "#/definitions/DistributedGeneration"
129
217
  }
130
218
  },
131
219
  "required": [
@@ -0,0 +1,92 @@
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 'json-schema'
33
+
34
+ module URBANopt
35
+ module Scenario
36
+ module DefaultReports
37
+ ##
38
+ # Onsite solar PV system attributes
39
+ ##
40
+ class SolarPV
41
+ ##
42
+ # _Float_ - power capacity in kilowatts
43
+ #
44
+ attr_accessor :size_kw
45
+
46
+ ##
47
+ # Initialize SolarPV attributes from a hash. Solar PV attributes currently are limited to power capacity.
48
+ ##
49
+ # [parameters:]
50
+ #
51
+ # * +hash+ - _Hash_ - A hash containting a +:size_kw+ key/value pair which represents the nameplate capacity in kilowatts (kW)
52
+ #
53
+ def initialize(hash = {})
54
+ hash.delete_if { |k, v| v.nil? }
55
+
56
+ @size_kw = hash[:size_kw]
57
+
58
+ # initialize class variables @@validator and @@schema
59
+ @@validator ||= Validator.new
60
+ @@schema ||= @@validator.schema
61
+
62
+ # initialize @@logger
63
+ @@logger ||= URBANopt::Scenario::DefaultReports.logger
64
+ end
65
+
66
+ ##
67
+ # Convert to a Hash equivalent for JSON serialization
68
+ ##
69
+ def to_hash
70
+ result = {}
71
+
72
+ result[:size_kw] = @size_kw if @size_kw
73
+
74
+ return result
75
+ end
76
+
77
+ ##
78
+ # Merge PV systems
79
+ ##
80
+ def self.add_pv(existing_pv, new_pv)
81
+ if existing_pv.size_kw.nil? && new_pv.size_kw.nil?
82
+ existing_pv.size_kw = nil
83
+ else
84
+ existing_pv.size_kw = (existing_pv.size_kw || 0) + (new_pv.size_kw || 0)
85
+ end
86
+
87
+ return existing_pv
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end