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
@@ -17,6 +17,10 @@
17
17
  "webpack-dev-middleware": "^3.6.0"
18
18
  },
19
19
  "devDependencies": {
20
- "gh-pages": "^2.0.1"
20
+ "braces": ">=2.3.1",
21
+ "gh-pages": "^2.0.1",
22
+ "js-yaml": ">=3.13.1",
23
+ "serialize-javascript": ">=2.1.1",
24
+ "set-value": ">=2.0.1"
21
25
  }
22
26
  }
@@ -0,0 +1,147 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'github_api'
4
+ require 'date'
5
+ require 'optparse'
6
+ require 'optparse/date'
7
+
8
+ # Instructions:
9
+ # Get a token from github's settings (https://github.com/settings/tokens)
10
+ #
11
+ # Example:
12
+ # ruby change_log.rb -t abcdefghijklmnopqrstuvwxyz -s 2017-09-06
13
+ #
14
+
15
+ options = {}
16
+ OptionParser.new do |opts|
17
+ opts.banner = "Usage: change_log.rb [options]\n" \
18
+ 'Prints New, Open, Closed Issues, and number of accepted PRs'
19
+ opts.separator ''
20
+
21
+ # defaults, go back 90 days
22
+ options[:start_date] = Date.today - 90
23
+ options[:end_date] = Date.today
24
+
25
+ opts.on('-s', '--start-date [DATE]', Date, 'Start of data (e.g. 2017-09-06)') do |v|
26
+ options[:start_date] = v
27
+ end
28
+ opts.on('-e', '--end-date [DATE]', Date, 'End of data (e.g. 2017-09-13)') do |v|
29
+ options[:end_date] = v
30
+ end
31
+ opts.on('-t', '--token [String]', String, 'Github API Token') do |v|
32
+ options[:token] = v
33
+ end
34
+ end.parse!
35
+
36
+ # Convert dates to time objects
37
+ options[:start_date] = Time.parse(options[:start_date].to_s)
38
+ options[:end_date] = Time.parse(options[:end_date].to_s)
39
+ puts options
40
+
41
+ ### Repository options
42
+ repo_owner = 'URBANopt'
43
+ repo = 'urbanopt-scenario-gem'
44
+
45
+ github = Github.new
46
+ if options[:token]
47
+ puts 'Using github token'
48
+ github = Github.new oauth_token: options[:token]
49
+ end
50
+
51
+ total_open_issues = []
52
+ total_open_pull_requests = []
53
+ new_issues = []
54
+ closed_issues = []
55
+ accepted_pull_requests = []
56
+
57
+ def get_num(issue)
58
+ issue.html_url.split('/')[-1].to_i
59
+ end
60
+
61
+ def get_issue_num(issue)
62
+ "\##{get_num(issue)}"
63
+ end
64
+
65
+ def get_html_url(issue)
66
+ issue.html_url
67
+ end
68
+
69
+ def get_title(issue)
70
+ issue.title
71
+ end
72
+
73
+ def print_issue(issue)
74
+ is_feature = false
75
+ issue.labels.each { |label| is_feature = true if label.name == 'Feature Request' }
76
+
77
+ if is_feature
78
+ "- Improved [#{get_issue_num(issue)}]( #{get_html_url(issue)} ), #{get_title(issue)}"
79
+ else
80
+ "- Fixed [#{get_issue_num(issue)}]( #{get_html_url(issue)} ), #{get_title(issue)}"
81
+ end
82
+ end
83
+
84
+ # Process Open Issues
85
+ results = -1
86
+ page = 1
87
+ while results != 0
88
+ resp = github.issues.list user: repo_owner, repo: repo, sort: 'created', direction: 'asc',
89
+ state: 'open', per_page: 100, page: page
90
+ results = resp.length
91
+ resp.env[:body].each do |issue, _index|
92
+ created = Time.parse(issue.created_at)
93
+ if !issue.key?(:pull_request)
94
+ total_open_issues << issue
95
+ if created >= options[:start_date] && created <= options[:end_date]
96
+ new_issues << issue
97
+ end
98
+ else
99
+ total_open_pull_requests << issue
100
+ end
101
+ end
102
+
103
+ page += 1
104
+ end
105
+
106
+ # Process Closed Issues
107
+ results = -1
108
+ page = 1
109
+ while results != 0
110
+ resp = github.issues.list user: repo_owner, repo: repo, sort: 'created', direction: 'asc',
111
+ state: 'closed', per_page: 100, page: page
112
+ results = resp.length
113
+ resp.env[:body].each do |issue, _index|
114
+ created = Time.parse(issue.created_at)
115
+ closed = Time.parse(issue.closed_at)
116
+ if !issue.key?(:pull_request)
117
+ if created >= options[:start_date] && created <= options[:end_date]
118
+ new_issues << issue
119
+ end
120
+ if closed >= options[:start_date] && closed <= options[:end_date]
121
+ closed_issues << issue
122
+ end
123
+ elsif closed >= options[:start_date] && closed <= options[:end_date]
124
+ accepted_pull_requests << issue
125
+ end
126
+ end
127
+
128
+ page += 1
129
+ end
130
+
131
+ closed_issues.sort! { |x, y| get_num(x) <=> get_num(y) }
132
+ new_issues.sort! { |x, y| get_num(x) <=> get_num(y) }
133
+ accepted_pull_requests.sort! { |x, y| get_num(x) <=> get_num(y) }
134
+ total_open_pull_requests.sort! { |x, y| get_num(x) <=> get_num(y) }
135
+
136
+ puts "Total Open Issues: #{total_open_issues.length}"
137
+ puts "Total Open Pull Requests: #{total_open_pull_requests.length}"
138
+ puts "\nDate Range: #{options[:start_date].strftime('%m/%d/%y')} - #{options[:end_date].strftime('%m/%d/%y')}:"
139
+ puts "\nNew Issues: #{new_issues.length} (" + new_issues.map { |issue| get_issue_num(issue) }.join(', ') + ')'
140
+
141
+ puts "\nClosed Issues: #{closed_issues.length}"
142
+ closed_issues.each { |issue| puts print_issue(issue) }
143
+
144
+ puts "\nAccepted Pull Requests: #{accepted_pull_requests.length}"
145
+ accepted_pull_requests.each { |issue| puts print_issue(issue) }
146
+
147
+ puts "\nAll Open Issues: #{total_open_issues.length} (" + total_open_issues.map { |issue| get_issue_num(issue) }.join(', ') + ')'
@@ -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,
@@ -576,10 +576,21 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
576
576
  end
577
577
 
578
578
  # timeseries we want to report
579
- requested_timeseries_names = ['Electricity:Facility', 'ElectricityProduced:Facility', 'Gas:Facility',
580
- 'DistrictCooling:Facility', 'DistrictHeating:Facility', 'District Cooling Chilled Water Rate',
581
- 'District Cooling Mass Flow Rate', 'District Cooling Inlet Temperature', 'District Cooling Outlet Temperature',
582
- 'District Heating Hot Water Rate', 'District Heating Mass Flow Rate', 'District Heating Inlet Temperature', 'District Heating Outlet Temperature']
579
+ requested_timeseries_names = [
580
+ 'Electricity:Facility',
581
+ 'ElectricityProduced:Facility',
582
+ 'Gas:Facility',
583
+ 'DistrictCooling:Facility',
584
+ 'DistrictHeating:Facility',
585
+ 'District Cooling Chilled Water Rate',
586
+ 'District Cooling Mass Flow Rate',
587
+ 'District Cooling Inlet Temperature',
588
+ 'District Cooling Outlet Temperature',
589
+ 'District Heating Hot Water Rate',
590
+ 'District Heating Mass Flow Rate',
591
+ 'District Heating Inlet Temperature',
592
+ 'District Heating Outlet Temperature'
593
+ ]
583
594
 
584
595
  # number of values in each timeseries
585
596
  n = nil
@@ -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,
@@ -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,
@@ -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,
@@ -0,0 +1,187 @@
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
+ # _SolarPV_ - Installed \solar PV attributes
77
+ #
78
+ attr_accessor :solar_pv
79
+
80
+ ##
81
+ # _Wind_ - Installed \wind attributes
82
+ #
83
+ attr_accessor :wind
84
+
85
+ ##
86
+ # _Generator_ - Installed \generator attributes
87
+ #
88
+ attr_accessor :generator
89
+
90
+ ##
91
+ # _Storage_ - Installed \storage attributes
92
+ #
93
+ attr_accessor :storage
94
+
95
+ ##
96
+ # Initialize distributed generation system design and financial metrics.
97
+ #
98
+ # * Technologies include +:solar_pv+, +:wind+, +:generator+, and +:storage+.
99
+ # * Financial metrics include +:lcc_us_dollars+, +:npv_us_dollars+, +:year_one_energy_cost_us_dollars+, +:year_one_demand_cost_us_dollars+,
100
+ # +:year_one_bill_us_dollars+, and +:total_energy_cost_us_dollars+
101
+ ##
102
+ # [parameters:]
103
+ #
104
+ # * +hash+ - _Hash_ - A hash containting key/value pairs for the distributed generation system attributes listed above.
105
+ #
106
+ def initialize(hash = {})
107
+ hash.delete_if { |k, v| v.nil? }
108
+
109
+ @lcc_us_dollars = hash[:lcc_us_dollars]
110
+ @npv_us_dollars = hash[:npv_us_dollars]
111
+ @year_one_energy_cost_us_dollars = hash[:year_one_energy_cost_us_dollars]
112
+ @year_one_demand_cost_us_dollars = hash[:year_one_demand_cost_us_dollars]
113
+ @year_one_bill_us_dollars = hash[:year_one_bill_us_dollars]
114
+ @total_energy_cost_us_dollars = hash[:total_energy_cost_us_dollars]
115
+
116
+ @solar_pv = SolarPV.new(hash[:solar_pv] || {})
117
+ @wind = Wind.new(hash[:wind] || {})
118
+ @generator = Generator.new(hash[:generator] || {})
119
+ @storage = Storage.new(hash[:storage] || {})
120
+
121
+ # initialize class variables @@validator and @@schema
122
+ @@validator ||= Validator.new
123
+ @@schema ||= @@validator.schema
124
+
125
+ # initialize @@logger
126
+ @@logger ||= URBANopt::Scenario::DefaultReports.logger
127
+ end
128
+
129
+ ##
130
+ # Convert to a Hash equivalent for JSON serialization
131
+ ##
132
+ def to_hash
133
+ result = {}
134
+
135
+ result[:lcc_us_dollars] = @lcc_us_dollars if @lcc_us_dollars
136
+ result[:npv_us_dollars] = @npv_us_dollars if @npv_us_dollars
137
+ result[:year_one_energy_cost_us_dollars] = @year_one_energy_cost_us_dollars if @year_one_energy_cost_us_dollars
138
+ result[:year_one_demand_cost_us_dollars] = @year_one_demand_cost_us_dollars if @year_one_demand_cost_us_dollars
139
+ result[:year_one_bill_us_dollars] = @year_one_bill_us_dollars if @year_one_bill_us_dollars
140
+ result[:total_energy_cost_us_dollars] = @total_energy_cost_us_dollars if @total_energy_cost_us_dollars
141
+ result[:solar_pv] = @solar_pv.to_hash if @solar_pv
142
+ result[:wind] = @wind.to_hash if @wind
143
+ result[:generator] = @generator.to_hash if @generator
144
+ result[:storage] = @storage.to_hash if @storage
145
+
146
+ return result
147
+ end
148
+
149
+ ### get keys ...not needed
150
+ # def self.get_all_keys(h)
151
+ # h.each_with_object([]){|(k,v),a| v.is_a?(Hash) ? a.push(k,*get_all_keys(v)) : a << k }
152
+ # end
153
+
154
+ ##
155
+ # Add up old and new values
156
+ ##
157
+ def self.add_values(existing_value, new_value) #:nodoc:
158
+ if existing_value && new_value
159
+ existing_value += new_value
160
+ elsif new_value
161
+ existing_value = new_value
162
+ end
163
+ return existing_value
164
+ end
165
+
166
+ ##
167
+ # Merge a distributed generation system with a new system
168
+ ##
169
+ def self.merge_distributed_generation(existing_dgen, new_dgen)
170
+ existing_dgen.lcc_us_dollars = add_values(existing_dgen.lcc_us_dollars, new_dgen.lcc_us_dollars)
171
+ existing_dgen.npv_us_dollars = add_values(existing_dgen.npv_us_dollars, new_dgen.npv_us_dollars)
172
+ 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)
173
+ 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)
174
+ existing_dgen.year_one_bill_us_dollars = add_values(existing_dgen.year_one_bill_us_dollars, new_dgen.year_one_bill_us_dollars)
175
+ existing_dgen.total_energy_cost_us_dollars = add_values(existing_dgen.total_energy_cost_us_dollars, new_dgen.total_energy_cost_us_dollars)
176
+
177
+ existing_dgen.solar_pv = SolarPV.add_pv existing_dgen.solar_pv, new_dgen.solar_pv
178
+ existing_dgen.wind = Wind.add_wind existing_dgen.wind, new_dgen.wind
179
+ existing_dgen.generator = Generator.add_generator existing_dgen.generator, new_dgen.generator
180
+ existing_dgen.storage = Storage.add_storage existing_dgen.storage, new_dgen.storage
181
+
182
+ return existing_dgen
183
+ end
184
+ end
185
+ end
186
+ end
187
+ 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,
@@ -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,
@@ -34,6 +34,8 @@ require 'urbanopt/scenario/default_reports/location'
34
34
  require 'urbanopt/scenario/default_reports/reporting_period'
35
35
  require 'urbanopt/scenario/default_reports/timeseries_csv'
36
36
  require 'urbanopt/scenario/default_reports/validator'
37
+ require 'urbanopt/scenario/default_reports/distributed_generation'
38
+
37
39
  require 'json-schema'
38
40
 
39
41
  require 'json'
@@ -50,7 +52,7 @@ module URBANopt
50
52
  ##
51
53
  class FeatureReport
52
54
  attr_accessor :id, :name, :directory_name, :feature_type, :timesteps_per_hour, :simulation_status,
53
- :timeseries_csv, :location, :program, :design_parameters, :construction_costs, :reporting_periods # :nodoc:
55
+ :timeseries_csv, :location, :program, :design_parameters, :construction_costs, :reporting_periods, :distributed_generation # :nodoc:
54
56
  ##
55
57
  # Each FeatureReport object corresponds to a single Feature.
56
58
  ##
@@ -82,6 +84,8 @@ module URBANopt
82
84
  @reporting_periods << ReportingPeriod.new(rp)
83
85
  end
84
86
 
87
+ @distributed_generation = DistributedGeneration.new(hash[:distributed_generation] || {})
88
+
85
89
  # initialize class variables @@validator and @@schema
86
90
  @@validator ||= Validator.new
87
91
  @@schema ||= @@validator.schema
@@ -194,6 +198,8 @@ module URBANopt
194
198
  result[:reporting_periods] = []
195
199
  @reporting_periods.each { |rp| result[:reporting_periods] << rp.to_hash }
196
200
 
201
+ result[:distributed_generation] = @distributed_generation.to_hash if @distributed_generation
202
+
197
203
  # validate feature_report properties against schema
198
204
  if @@validator.validate(@@schema[:definitions][:FeatureReport][:properties], result).any?
199
205
  raise "feature_report properties does not match schema: #{@@validator.validate(@@schema[:definitions][:FeatureReport][:properties], result)}"