urbanopt-scenario 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 (84) hide show
  1. checksums.yaml +7 -0
  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 +26 -0
  7. data/.rdoc_options +36 -0
  8. data/.rspec +3 -0
  9. data/.rubocop.yml +10 -0
  10. data/.travis.yml +23 -0
  11. data/CHANGELOG.md +19 -0
  12. data/Gemfile +43 -0
  13. data/Jenkinsfile +10 -0
  14. data/LICENSE.md +27 -0
  15. data/RDOC_MAIN.md +39 -0
  16. data/README.md +39 -0
  17. data/Rakefile +51 -0
  18. data/deploy_docs.sh +5 -0
  19. data/doc_templates/LICENSE.md +27 -0
  20. data/doc_templates/README.md.erb +42 -0
  21. data/doc_templates/copyright_erb.txt +31 -0
  22. data/doc_templates/copyright_js.txt +4 -0
  23. data/doc_templates/copyright_ruby.txt +29 -0
  24. data/docs/.gitignore +3 -0
  25. data/docs/.vuepress/components/InnerJsonSchema.vue +84 -0
  26. data/docs/.vuepress/components/JsonSchema.vue +12 -0
  27. data/docs/.vuepress/components/ScenarioSchema.vue +12 -0
  28. data/docs/.vuepress/components/StaticLink.vue +8 -0
  29. data/docs/.vuepress/config.js +15 -0
  30. data/docs/.vuepress/highlight.js +8 -0
  31. data/docs/.vuepress/public/custom_rdoc_styles.css +74 -0
  32. data/docs/.vuepress/utils.js +17 -0
  33. data/docs/README.md +39 -0
  34. data/docs/package-lock.json +11817 -0
  35. data/docs/package.json +26 -0
  36. data/docs/schemas/scenario-schema.md +3 -0
  37. data/lib/change_log.rb +147 -0
  38. data/lib/measures/.rubocop.yml +5 -0
  39. data/lib/measures/default_feature_reports/LICENSE.md +27 -0
  40. data/lib/measures/default_feature_reports/README.md +56 -0
  41. data/lib/measures/default_feature_reports/README.md.erb +42 -0
  42. data/lib/measures/default_feature_reports/measure.rb +742 -0
  43. data/lib/measures/default_feature_reports/measure.xml +139 -0
  44. data/lib/measures/default_feature_reports/tests/USA_CO_Golden-NREL.724666_TMY3.epw +8768 -0
  45. data/lib/measures/default_feature_reports/tests/default_feature_reports_test.rb +238 -0
  46. data/lib/measures/default_feature_reports/tests/example_model.osm +4378 -0
  47. data/lib/urbanopt-scenario.rb +31 -0
  48. data/lib/urbanopt/scenario.rb +45 -0
  49. data/lib/urbanopt/scenario/default_reports.rb +40 -0
  50. data/lib/urbanopt/scenario/default_reports/construction_cost.rb +169 -0
  51. data/lib/urbanopt/scenario/default_reports/date.rb +97 -0
  52. data/lib/urbanopt/scenario/default_reports/distributed_generation.rb +187 -0
  53. data/lib/urbanopt/scenario/default_reports/end_use.rb +159 -0
  54. data/lib/urbanopt/scenario/default_reports/end_uses.rb +140 -0
  55. data/lib/urbanopt/scenario/default_reports/feature_report.rb +213 -0
  56. data/lib/urbanopt/scenario/default_reports/generator.rb +92 -0
  57. data/lib/urbanopt/scenario/default_reports/location.rb +99 -0
  58. data/lib/urbanopt/scenario/default_reports/logger.rb +44 -0
  59. data/lib/urbanopt/scenario/default_reports/program.rb +261 -0
  60. data/lib/urbanopt/scenario/default_reports/reporting_period.rb +298 -0
  61. data/lib/urbanopt/scenario/default_reports/scenario_report.rb +300 -0
  62. data/lib/urbanopt/scenario/default_reports/schema/README.md +34 -0
  63. data/lib/urbanopt/scenario/default_reports/schema/scenario_csv_columns.txt +13 -0
  64. data/lib/urbanopt/scenario/default_reports/schema/scenario_schema.json +830 -0
  65. data/lib/urbanopt/scenario/default_reports/solar_pv.rb +92 -0
  66. data/lib/urbanopt/scenario/default_reports/storage.rb +105 -0
  67. data/lib/urbanopt/scenario/default_reports/timeseries_csv.rb +258 -0
  68. data/lib/urbanopt/scenario/default_reports/validator.rb +97 -0
  69. data/lib/urbanopt/scenario/default_reports/wind.rb +92 -0
  70. data/lib/urbanopt/scenario/extension.rb +63 -0
  71. data/lib/urbanopt/scenario/logger.rb +42 -0
  72. data/lib/urbanopt/scenario/scenario_base.rb +79 -0
  73. data/lib/urbanopt/scenario/scenario_csv.rb +122 -0
  74. data/lib/urbanopt/scenario/scenario_datapoint_base.rb +162 -0
  75. data/lib/urbanopt/scenario/scenario_post_processor_base.rb +69 -0
  76. data/lib/urbanopt/scenario/scenario_post_processor_default.rb +98 -0
  77. data/lib/urbanopt/scenario/scenario_runner_base.rb +63 -0
  78. data/lib/urbanopt/scenario/scenario_runner_osw.rb +158 -0
  79. data/lib/urbanopt/scenario/simulation_dir_base.rb +90 -0
  80. data/lib/urbanopt/scenario/simulation_dir_osw.rb +261 -0
  81. data/lib/urbanopt/scenario/simulation_mapper_base.rb +47 -0
  82. data/lib/urbanopt/scenario/version.rb +35 -0
  83. data/urbanopt-scenario-gem.gemspec +38 -0
  84. metadata +251 -0
@@ -0,0 +1,31 @@
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_relative 'urbanopt/scenario'
@@ -0,0 +1,45 @@
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/version'
32
+ require 'urbanopt/scenario/logger'
33
+ require 'urbanopt/scenario/extension'
34
+
35
+ require 'urbanopt/scenario/scenario_base'
36
+ require 'urbanopt/scenario/scenario_csv'
37
+ require 'urbanopt/scenario/scenario_post_processor_base'
38
+ require 'urbanopt/scenario/scenario_post_processor_default'
39
+ require 'urbanopt/scenario/scenario_runner_base'
40
+ require 'urbanopt/scenario/scenario_runner_osw'
41
+ require 'urbanopt/scenario/simulation_dir_base'
42
+ require 'urbanopt/scenario/simulation_dir_osw'
43
+ require 'urbanopt/scenario/simulation_mapper_base'
44
+
45
+ require 'urbanopt/scenario/default_reports'
@@ -0,0 +1,40 @@
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
+ ##
32
+ # Retrieve all default_reports classes.
33
+ ##
34
+ require 'urbanopt/scenario/default_reports/construction_cost'
35
+ require 'urbanopt/scenario/default_reports/feature_report'
36
+ require 'urbanopt/scenario/default_reports/logger'
37
+ require 'urbanopt/scenario/default_reports/program'
38
+ require 'urbanopt/scenario/default_reports/reporting_period'
39
+ require 'urbanopt/scenario/default_reports/scenario_report'
40
+ require 'urbanopt/scenario/default_reports/timeseries_csv'
@@ -0,0 +1,169 @@
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
@@ -0,0 +1,97 @@
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
@@ -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