urbanopt-scenario 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/CONTRIBUTING.md +58 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +27 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +23 -0
- data/.github/pull_request_template.md +23 -0
- data/.gitignore +1 -0
- data/CHANGELOG.md +16 -2
- data/Gemfile +1 -0
- data/LICENSE.md +1 -1
- data/doc_templates/LICENSE.md +1 -1
- data/doc_templates/copyright_erb.txt +1 -1
- data/doc_templates/copyright_js.txt +1 -1
- data/doc_templates/copyright_ruby.txt +1 -1
- data/docs/package-lock.json +142 -116
- data/docs/package.json +5 -1
- data/lib/change_log.rb +147 -0
- data/lib/measures/default_feature_reports/measure.rb +16 -5
- data/lib/measures/default_feature_reports/tests/default_feature_reports_test.rb +1 -1
- data/lib/urbanopt-scenario.rb +1 -1
- data/lib/urbanopt/scenario.rb +1 -1
- data/lib/urbanopt/scenario/default_reports.rb +1 -1
- data/lib/urbanopt/scenario/default_reports/construction_cost.rb +1 -1
- data/lib/urbanopt/scenario/default_reports/date.rb +1 -1
- data/lib/urbanopt/scenario/default_reports/distributed_generation.rb +187 -0
- data/lib/urbanopt/scenario/default_reports/end_use.rb +1 -1
- data/lib/urbanopt/scenario/default_reports/end_uses.rb +1 -1
- data/lib/urbanopt/scenario/default_reports/feature_report.rb +8 -2
- data/lib/urbanopt/scenario/default_reports/generator.rb +92 -0
- data/lib/urbanopt/scenario/default_reports/location.rb +2 -2
- data/lib/urbanopt/scenario/default_reports/logger.rb +1 -1
- data/lib/urbanopt/scenario/default_reports/program.rb +2 -2
- data/lib/urbanopt/scenario/default_reports/reporting_period.rb +2 -2
- data/lib/urbanopt/scenario/default_reports/scenario_report.rb +36 -12
- data/lib/urbanopt/scenario/default_reports/schema/README.md +16 -15
- data/lib/urbanopt/scenario/default_reports/schema/scenario_schema.json +88 -0
- data/lib/urbanopt/scenario/default_reports/solar_pv.rb +92 -0
- data/lib/urbanopt/scenario/default_reports/storage.rb +105 -0
- data/lib/urbanopt/scenario/default_reports/timeseries_csv.rb +32 -5
- data/lib/urbanopt/scenario/default_reports/validator.rb +2 -2
- data/lib/urbanopt/scenario/default_reports/wind.rb +92 -0
- data/lib/urbanopt/scenario/extension.rb +1 -1
- data/lib/urbanopt/scenario/logger.rb +1 -1
- data/lib/urbanopt/scenario/scenario_base.rb +1 -1
- data/lib/urbanopt/scenario/scenario_csv.rb +1 -1
- data/lib/urbanopt/scenario/scenario_datapoint_base.rb +1 -1
- data/lib/urbanopt/scenario/scenario_post_processor_base.rb +1 -1
- data/lib/urbanopt/scenario/scenario_post_processor_default.rb +7 -6
- data/lib/urbanopt/scenario/scenario_runner_base.rb +1 -1
- data/lib/urbanopt/scenario/scenario_runner_osw.rb +1 -1
- data/lib/urbanopt/scenario/simulation_dir_base.rb +1 -1
- data/lib/urbanopt/scenario/simulation_dir_osw.rb +1 -1
- data/lib/urbanopt/scenario/simulation_mapper_base.rb +1 -1
- data/lib/urbanopt/scenario/version.rb +2 -2
- data/urbanopt-scenario-gem.gemspec +2 -0
- 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
|
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
|
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
|
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, '
|
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, '
|
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
|
-
|
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.
|
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
|
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
|
-
|
163
|
-
|
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
|
-
|
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
|
20
|
-
|
|
21
|
-
| Electricity:Facility
|
22
|
-
| ElectricityProduced:Facility
|
23
|
-
| Gas:Facility
|
24
|
-
| DistrictCooling:Facility
|
25
|
-
| DistrictHeating:Facility
|
26
|
-
| District Cooling Chilled Water Rate
|
27
|
-
| District Cooling Mass Flow Rate
|
28
|
-
| District Cooling Inlet Temperature
|
29
|
-
| District Cooling Outlet Temperature
|
30
|
-
| District Heating Hot Water Rate
|
31
|
-
| District Heating Mass Flow Rate
|
32
|
-
| District Heating Inlet Temperature
|
33
|
-
| District Heating Outlet Temperature
|
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 | °F |
|
29
|
+
| District Cooling Outlet Temperature | °F |
|
30
|
+
| District Heating Hot Water Rate | GPM |
|
31
|
+
| District Heating Mass Flow Rate | lbs/min |
|
32
|
+
| District Heating Inlet Temperature | °F |
|
33
|
+
| District Heating Outlet Temperature | °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
|