urbanopt-scenario 0.2.0 → 0.4.2

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 (72) hide show
  1. checksums.yaml +5 -5
  2. data/.github/pull_request_template.md +2 -2
  3. data/.gitignore +2 -0
  4. data/.rubocop.yml +1 -1
  5. data/CHANGELOG.md +53 -0
  6. data/CONTRIBUTING.md +1 -1
  7. data/Gemfile +27 -14
  8. data/Jenkinsfile +1 -1
  9. data/LICENSE.md +1 -1
  10. data/RDOC_MAIN.md +1 -1
  11. data/README.md +1 -1
  12. data/Rakefile +2 -2
  13. data/docs/README.md +1 -1
  14. data/docs/package-lock.json +2499 -2322
  15. data/docs/package.json +13 -9
  16. data/lib/urbanopt-scenario.rb +1 -1
  17. data/lib/urbanopt/scenario.rb +2 -1
  18. data/lib/urbanopt/scenario/default_reports.rb +3 -8
  19. data/lib/urbanopt/scenario/extension.rb +1 -1
  20. data/lib/urbanopt/scenario/logger.rb +1 -1
  21. data/lib/urbanopt/scenario/scenario_base.rb +1 -1
  22. data/lib/urbanopt/scenario/scenario_csv.rb +22 -9
  23. data/lib/urbanopt/scenario/scenario_datapoint_base.rb +8 -1
  24. data/lib/urbanopt/scenario/scenario_post_processor_base.rb +1 -1
  25. data/lib/urbanopt/scenario/scenario_post_processor_default.rb +110 -8
  26. data/lib/urbanopt/scenario/scenario_post_processor_opendss.rb +6 -7
  27. data/lib/urbanopt/scenario/scenario_runner_base.rb +2 -2
  28. data/lib/urbanopt/scenario/scenario_runner_osw.rb +23 -9
  29. data/lib/urbanopt/scenario/scenario_visualization.rb +236 -0
  30. data/lib/urbanopt/scenario/simulation_dir_base.rb +1 -1
  31. data/lib/urbanopt/scenario/simulation_dir_osw.rb +2 -9
  32. data/lib/urbanopt/scenario/simulation_mapper_base.rb +1 -1
  33. data/lib/urbanopt/scenario/version.rb +2 -2
  34. data/package-lock.json +3 -0
  35. data/urbanopt-scenario-gem.gemspec +14 -14
  36. metadata +71 -77
  37. data/doc_templates/LICENSE.md +0 -27
  38. data/doc_templates/README.md.erb +0 -42
  39. data/doc_templates/copyright_erb.txt +0 -31
  40. data/doc_templates/copyright_js.txt +0 -4
  41. data/doc_templates/copyright_ruby.txt +0 -29
  42. data/lib/change_log.rb +0 -147
  43. data/lib/measures/.rubocop.yml +0 -5
  44. data/lib/measures/default_feature_reports/LICENSE.md +0 -27
  45. data/lib/measures/default_feature_reports/README.md +0 -56
  46. data/lib/measures/default_feature_reports/README.md.erb +0 -42
  47. data/lib/measures/default_feature_reports/measure.rb +0 -979
  48. data/lib/measures/default_feature_reports/measure.xml +0 -143
  49. data/lib/measures/default_feature_reports/tests/USA_CO_Golden-NREL.724666_TMY3.epw +0 -8768
  50. data/lib/measures/default_feature_reports/tests/default_feature_reports_test.rb +0 -238
  51. data/lib/measures/default_feature_reports/tests/example_model.osm +0 -4378
  52. data/lib/urbanopt/scenario/default_reports/construction_cost.rb +0 -169
  53. data/lib/urbanopt/scenario/default_reports/date.rb +0 -97
  54. data/lib/urbanopt/scenario/default_reports/distributed_generation.rb +0 -379
  55. data/lib/urbanopt/scenario/default_reports/end_use.rb +0 -159
  56. data/lib/urbanopt/scenario/default_reports/end_uses.rb +0 -140
  57. data/lib/urbanopt/scenario/default_reports/feature_report.rb +0 -267
  58. data/lib/urbanopt/scenario/default_reports/generator.rb +0 -92
  59. data/lib/urbanopt/scenario/default_reports/location.rb +0 -99
  60. data/lib/urbanopt/scenario/default_reports/logger.rb +0 -44
  61. data/lib/urbanopt/scenario/default_reports/power_distribution.rb +0 -102
  62. data/lib/urbanopt/scenario/default_reports/program.rb +0 -266
  63. data/lib/urbanopt/scenario/default_reports/reporting_period.rb +0 -301
  64. data/lib/urbanopt/scenario/default_reports/scenario_report.rb +0 -317
  65. data/lib/urbanopt/scenario/default_reports/schema/README.md +0 -33
  66. data/lib/urbanopt/scenario/default_reports/schema/scenario_csv_columns.txt +0 -32
  67. data/lib/urbanopt/scenario/default_reports/schema/scenario_schema.json +0 -853
  68. data/lib/urbanopt/scenario/default_reports/solar_pv.rb +0 -93
  69. data/lib/urbanopt/scenario/default_reports/storage.rb +0 -105
  70. data/lib/urbanopt/scenario/default_reports/timeseries_csv.rb +0 -299
  71. data/lib/urbanopt/scenario/default_reports/validator.rb +0 -97
  72. data/lib/urbanopt/scenario/default_reports/wind.rb +0 -92
@@ -1,159 +0,0 @@
1
- # *********************************************************************************
2
- # URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
3
- # contributors. All rights reserved.
4
- #
5
- # Redistribution and use in source and binary forms, with or without modification,
6
- # are permitted provided that the following conditions are met:
7
- #
8
- # Redistributions of source code must retain the above copyright notice, this list
9
- # of conditions and the following disclaimer.
10
- #
11
- # Redistributions in binary form must reproduce the above copyright notice, this
12
- # list of conditions and the following disclaimer in the documentation and/or other
13
- # materials provided with the distribution.
14
- #
15
- # Neither the name of the copyright holder nor the names of its contributors may be
16
- # used to endorse or promote products derived from this software without specific
17
- # prior written permission.
18
- #
19
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20
- # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
- # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
- # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23
- # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24
- # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
- # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
- # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
- # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28
- # OF THE POSSIBILITY OF SUCH DAMAGE.
29
- # *********************************************************************************
30
-
31
- require 'urbanopt/scenario/default_reports/validator'
32
- require 'json-schema'
33
-
34
- module URBANopt
35
- module Scenario
36
- module DefaultReports
37
- ##
38
- # Enduse class all enduse energy consumption results.
39
- ##
40
- class EndUse
41
- attr_accessor :heating, :cooling, :interior_lighting, :exterior_lighting, :interior_equipment, :exterior_equipment,
42
- :fans, :pumps, :heat_rejection, :humidification, :heat_recovery, :water_systems, :refrigeration, :generators # :nodoc:
43
-
44
- ##
45
- # EndUse class intialize all enduse atributes: +:heating+ , +:cooling+ , +:interior_lighting+ ,
46
- # +:exterior_lighting+ , +:interior_equipment+ , +:exterior_equipment+ ,
47
- # +:fans+ , +:pumps+ , +:heat_rejection+ , +:humidification+ , +:heat_recovery+ , +:water_systems+ , +:refrigeration+ , +:generators+
48
- ##
49
- # [parameters:]
50
- # +hash+ - _Hash_ - A hash which may contain a deserialized end_use.
51
- ##
52
- def initialize(hash = {})
53
- hash.delete_if { |k, v| v.nil? }
54
- hash = defaults.merge(hash)
55
-
56
- @heating = hash[:heating]
57
- @cooling = hash[:cooling]
58
- @interior_lighting = hash[:interior_lighting]
59
- @exterior_lighting = hash[:exterior_lighting]
60
- @interior_equipment = hash[:interior_equipment]
61
- @exterior_equipment = hash[:exterior_equipment]
62
- @fans = hash[:fans]
63
- @pumps = hash[:pumps]
64
- @heat_rejection = hash[:heat_rejection]
65
- @humidification = hash[:humidification]
66
- @heat_recovery = hash[:heat_recovery]
67
- @water_systems = hash[:water_systems]
68
- @refrigeration = hash[:refrigeration]
69
- @generators = hash[:generators]
70
-
71
- # initialize class variables @@validator and @@schema
72
- @@validator ||= Validator.new
73
- @@schema ||= @@validator.schema
74
- end
75
-
76
- ##
77
- # Assign default values if values does not exist
78
- ##
79
- def defaults
80
- hash = {}
81
-
82
- hash[:heating] = nil
83
- hash[:cooling] = nil
84
- hash[:interior_lighting] = nil
85
- hash[:exterior_lighting] = nil
86
- hash[:interior_equipment] = nil
87
- hash[:exterior_equipment] = nil
88
- hash[:fans] = nil
89
- hash[:pumps] = nil
90
- hash[:heat_rejection] = nil
91
- hash[:humidification] = nil
92
- hash[:heat_recovery] = nil
93
- hash[:water_systems] = nil
94
- hash[:refrigeration] = nil
95
- hash[:generators] = nil
96
-
97
- return hash
98
- end
99
-
100
- ##
101
- # Convert to a Hash equivalent for JSON serialization.
102
- ##
103
- # - Exclude attributes with nil values.
104
- # - Validate end_use hash properties against schema.
105
- ##
106
- def to_hash
107
- result = {}
108
-
109
- result[:heating] = @heating
110
- result[:cooling] = @cooling
111
- result[:interior_lighting] = @interior_lighting
112
- result[:exterior_lighting] = @exterior_lighting
113
- result[:interior_equipment] = @interior_equipment
114
- result[:exterior_equipment] = @exterior_equipment
115
- result[:fans] = @fans
116
- result[:pumps] = @pumps
117
- result[:heat_rejection] = @heat_rejection
118
- result[:humidification] = @humidification
119
- result[:heat_recovery] = @heat_recovery
120
- result[:water_systems] = @water_systems
121
- result[:refrigeration] = @refrigeration
122
- result[:generators] = @generators
123
-
124
- # validate end_use properties against schema
125
- if @@validator.validate(@@schema[:definitions][:EndUse][:properties], result).any?
126
- raise "end_use properties does not match schema: #{@@validator.validate(@@schema[:definitions][:EndUse][:properties], result)}"
127
- end
128
-
129
- return result
130
- end
131
-
132
- ##
133
- # Aggregate values of each EndUse attribute.
134
- ##
135
- # [Parameters:]
136
- # +new_end_use+ - _EndUse_ - An object of EndUse class.
137
- ##
138
- def merge_end_use!(new_end_use)
139
- @heating += new_end_use.heating if new_end_use.heating
140
- @cooling += new_end_use.cooling if new_end_use.cooling
141
- @interior_lighting += new_end_use.interior_lighting if new_end_use.interior_lighting
142
- @exterior_lighting += new_end_use.exterior_lighting if new_end_use.exterior_lighting
143
- @interior_equipment += new_end_use.interior_equipment if new_end_use.interior_equipment
144
- @exterior_equipment += new_end_use.exterior_equipment if new_end_use.exterior_equipment
145
- @fans += new_end_use.fans if new_end_use.fans
146
- @pumps += new_end_use.pumps if new_end_use.pumps
147
- @heat_rejection += new_end_use.heat_rejection if new_end_use.heat_rejection
148
- @humidification += new_end_use.humidification if new_end_use.humidification
149
- @heat_recovery += new_end_use.heat_recovery if new_end_use.heat_recovery
150
- @water_systems += new_end_use.water_systems if new_end_use.water_systems
151
- @refrigeration += new_end_use.refrigeration if new_end_use.refrigeration
152
- @generators += new_end_use.generators if new_end_use.generators
153
-
154
- return self
155
- end
156
- end
157
- end
158
- end
159
- end
@@ -1,140 +0,0 @@
1
- # *********************************************************************************
2
- # URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
3
- # contributors. All rights reserved.
4
- #
5
- # Redistribution and use in source and binary forms, with or without modification,
6
- # are permitted provided that the following conditions are met:
7
- #
8
- # Redistributions of source code must retain the above copyright notice, this list
9
- # of conditions and the following disclaimer.
10
- #
11
- # Redistributions in binary form must reproduce the above copyright notice, this
12
- # list of conditions and the following disclaimer in the documentation and/or other
13
- # materials provided with the distribution.
14
- #
15
- # Neither the name of the copyright holder nor the names of its contributors may be
16
- # used to endorse or promote products derived from this software without specific
17
- # prior written permission.
18
- #
19
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20
- # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
- # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
- # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23
- # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24
- # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
- # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
- # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
- # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28
- # OF THE POSSIBILITY OF SUCH DAMAGE.
29
- # *********************************************************************************
30
-
31
- require 'urbanopt/scenario/default_reports/end_use'
32
- require 'urbanopt/scenario/default_reports/validator'
33
- require 'json-schema'
34
-
35
- module URBANopt
36
- module Scenario
37
- module DefaultReports
38
- ##
39
- # Enduses class inlclude results for each fuel type.
40
- ##
41
- class EndUses
42
- attr_accessor :electricity, :natural_gas, :additional_fuel, :district_cooling, :district_heating, :water # :nodoc:
43
- ##
44
- # EndUses class intialize end_uses(fuel type) attributes: +:electricity+ , +:natural_gas+ , +:additional_fuel+ ,
45
- # +:district_cooling+ , +:district_heating+ , +:water+
46
- ##
47
- # [parameters:]
48
- # +hash+ - _Hash_ - A hash which may contain a deserialized end_uses.
49
- ##
50
- def initialize(hash = {})
51
- hash.delete_if { |k, v| v.nil? }
52
- hash = defaults.merge(hash)
53
-
54
- @electricity = EndUse.new(hash[:electricity])
55
- @natural_gas = EndUse.new(hash[:natural_gas])
56
- @additional_fuel = EndUse.new(hash[:additional_fuel])
57
- @district_cooling = EndUse.new(hash[:district_cooling])
58
- @district_heating = EndUse.new(hash[:district_heating])
59
- @water = EndUse.new(hash[:water])
60
-
61
- # initialize class variables @@validator and @@schema
62
- @@validator ||= Validator.new
63
- @@schema ||= @@validator.schema
64
- end
65
-
66
- ##
67
- # Converts to a Hash equivalent for JSON serialization.
68
- ##
69
- # - Exclude attributes with nil values.
70
- # - Validate end_uses hash properties against schema.
71
- ##
72
- def to_hash
73
- result = {}
74
-
75
- electricity_hash = @electricity.to_hash if @electricity.to_hash
76
- electricity_hash.delete_if { |k, v| v.nil? }
77
- result[:electricity] = electricity_hash if @electricity
78
-
79
- natural_gas_hash = @natural_gas.to_hash if @natural_gas
80
- natural_gas_hash.delete_if { |k, v| v.nil? }
81
- result[:natural_gas] = natural_gas_hash if @natural_gas
82
-
83
- additional_fuel_hash = @additional_fuel.to_hash if @additional_fuel
84
- additional_fuel_hash.delete_if { |k, v| v.nil? }
85
- result[:additional_fuel] = additional_fuel_hash if @additional_fuel
86
-
87
- district_cooling_hash = @district_cooling.to_hash if @district_cooling
88
- district_cooling_hash.delete_if { |k, v| v.nil? }
89
- result[:district_cooling] = district_cooling_hash if @district_cooling
90
-
91
- district_heating_hash = @district_heating.to_hash if @district_heating
92
- district_heating_hash.delete_if { |k, v| v.nil? }
93
- result[:district_heating] = district_heating_hash if @district_heating
94
-
95
- water_hash = @water.to_hash if @water
96
- water_hash.delete_if { |k, v| v.nil? }
97
- result[:water] = water_hash if @water
98
-
99
- # validate end_uses properties against schema
100
- if @@validator.validate(@@schema[:definitions][:EndUses][:properties], result).any?
101
- raise "end_uses properties does not match schema: #{@@validator.validate(@@schema[:definitions][:EndUses][:properties], result)}"
102
- end
103
-
104
- return result
105
- end
106
-
107
- ##
108
- # Assigns default values if values do not exist.
109
- ##
110
- def defaults
111
- hash = {}
112
- hash[:electricity] = EndUse.new.to_hash
113
- hash[:natural_gas] = EndUse.new.to_hash
114
- hash[:additional_fuel] = EndUse.new.to_hash
115
- hash[:district_cooling] = EndUse.new.to_hash
116
- hash[:district_heating] = EndUse.new.to_hash
117
- hash[:water] = EndUse.new.to_hash
118
-
119
- return hash
120
- end
121
-
122
- ##
123
- # Aggregates the values of each EndUse attribute.
124
- ##
125
- # [Parameters:]
126
- # +new_end_uses+ - _EndUses_ - An object of EndUses class.
127
- ##
128
- def merge_end_uses!(new_end_uses)
129
- # modify the existing_period by summing up the results ; # sum results only if they exist
130
- @electricity.merge_end_use!(new_end_uses.electricity)
131
- @natural_gas.merge_end_use!(new_end_uses.natural_gas)
132
- @additional_fuel.merge_end_use!(new_end_uses.additional_fuel)
133
- @district_cooling.merge_end_use!(new_end_uses.district_cooling)
134
- @district_heating.merge_end_use!(new_end_uses.district_heating)
135
- return self
136
- end
137
- end
138
- end
139
- end
140
- end
@@ -1,267 +0,0 @@
1
- # *********************************************************************************
2
- # URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
3
- # contributors. All rights reserved.
4
- #
5
- # Redistribution and use in source and binary forms, with or without modification,
6
- # are permitted provided that the following conditions are met:
7
- #
8
- # Redistributions of source code must retain the above copyright notice, this list
9
- # of conditions and the following disclaimer.
10
- #
11
- # Redistributions in binary form must reproduce the above copyright notice, this
12
- # list of conditions and the following disclaimer in the documentation and/or other
13
- # materials provided with the distribution.
14
- #
15
- # Neither the name of the copyright holder nor the names of its contributors may be
16
- # used to endorse or promote products derived from this software without specific
17
- # prior written permission.
18
- #
19
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20
- # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
- # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
- # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23
- # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24
- # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
- # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
- # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
- # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28
- # OF THE POSSIBILITY OF SUCH DAMAGE.
29
- # *********************************************************************************
30
-
31
- require 'urbanopt/scenario/default_reports/construction_cost'
32
- require 'urbanopt/scenario/default_reports/program'
33
- require 'urbanopt/scenario/default_reports/location'
34
- require 'urbanopt/scenario/default_reports/reporting_period'
35
- require 'urbanopt/scenario/default_reports/timeseries_csv'
36
- require 'urbanopt/scenario/default_reports/distributed_generation'
37
- require 'urbanopt/scenario/default_reports/power_distribution'
38
-
39
- require 'urbanopt/scenario/default_reports/validator'
40
- require 'json-schema'
41
-
42
- require 'json'
43
-
44
- module URBANopt
45
- module Scenario
46
- module DefaultReports
47
- ##
48
- # FeatureReport generates two types of reports in a simulation_dir.
49
- # The default_feature_reports measure writes a 'default_feature_reports.json' file containing
50
- # information on all features in the simulation. It also writes a 'default_feature_reports.csv'
51
- # containing timeseries data for all features in the simulation.
52
- # The DefaultPostProcessor reads these feature reports and aggregates them to create a ScenarioReport.
53
- ##
54
- class FeatureReport
55
- attr_accessor :id, :name, :directory_name, :feature_type, :timesteps_per_hour, :simulation_status,
56
- :timeseries_csv, :location, :program, :design_parameters, :construction_costs, :reporting_periods, :distributed_generation, :power_distribution # :nodoc:
57
- ##
58
- # Each FeatureReport object corresponds to a single Feature.
59
- ##
60
- # [parameters:]
61
- # +hash+ - _Hash_ - A hash which may contain a deserialized feature_report.
62
- ##
63
- def initialize(hash = {})
64
- hash.delete_if { |k, v| v.nil? }
65
- hash = defaults.merge(hash)
66
-
67
- @id = hash[:id]
68
- @name = hash[:name]
69
- @directory_name = hash[:directory_name]
70
- @feature_type = hash[:feature_type]
71
- @timesteps_per_hour = hash[:timesteps_per_hour]
72
- @simulation_status = hash[:simulation_status]
73
- @timeseries_csv = TimeseriesCSV.new(hash[:timeseries_csv])
74
- @timeseries_csv.run_dir_name(@directory_name)
75
- @location = Location.new(hash[:location])
76
- @program = Program.new(hash[:program])
77
- # design_parameters to add later
78
- @construction_costs = []
79
- hash[:construction_costs].each do |cc|
80
- @constructiion_costs << ConstructionCost.new(cc)
81
- end
82
-
83
- @reporting_periods = []
84
- hash[:reporting_periods].each do |rp|
85
- @reporting_periods << ReportingPeriod.new(rp)
86
- end
87
-
88
- @distributed_generation = DistributedGeneration.new(hash[:distributed_generation])
89
-
90
- @power_distribution = PowerDistribution.new(hash[:power_distribution])
91
-
92
- # initialize class variables @@validator and @@schema
93
- @@validator ||= Validator.new
94
- @@schema ||= @@validator.schema
95
-
96
- # initialize feature report file name to be saved.
97
- @file_name = 'default_feature_report'
98
- end
99
-
100
- ##
101
- # Assign default values if values does not exist.
102
- ##
103
- def defaults
104
- hash = {}
105
- hash[:timeseries_csv] = {}
106
- hash[:location] = {}
107
- hash[:program] = {}
108
- hash[:construction_costs] = []
109
- hash[:reporting_periods] = []
110
- hash[:distributed_generation] = {}
111
- hash[:power_distribution] = {}
112
- return hash
113
- end
114
-
115
- ##
116
- # Return an Array of FeatureReports for the simulation_dir as multiple Features can be simulated together in a single simulation directory.
117
- ##
118
- # - Ensure that +simulation_dir+ include only one feature.
119
- # - Read in the reports written by measure if they exist.
120
- ##
121
- # [parameters:]
122
- # +simulation_dir+ - _SimulationDirOSW_ - A simulation directory from an OSW simulation, must include 'default_feature_reports' measure.
123
- ##
124
- def self.from_simulation_dir(simulation_dir)
125
- result = []
126
-
127
- # simulation dir can include only one feature
128
- features = simulation_dir.features
129
- if features.size != 1
130
- raise 'FeatureReport cannot support multiple features per OSW'
131
- end
132
-
133
- # read in the reports written by measure
134
- default_feature_reports_json = nil
135
- default_feature_reports_csv = nil
136
-
137
- simulation_status = simulation_dir.simulation_status
138
- if simulation_status == 'Complete' || simulation_status == 'Failed'
139
-
140
- # read in the scenario reports JSON and CSV
141
- Dir.glob(File.join(simulation_dir.run_dir, '*_default_feature_reports/')).each do |dir|
142
- scenario_reports_json_path = File.join(dir, 'default_feature_reports.json')
143
- if File.exist?(scenario_reports_json_path)
144
- File.open(scenario_reports_json_path, 'r') do |file|
145
- default_feature_reports_json = JSON.parse(file.read, symbolize_names: true)
146
- end
147
- end
148
- scenario_reports_csv_path = File.join(dir, 'default_feature_reports.csv')
149
- if File.exist?(scenario_reports_csv_path)
150
- default_feature_reports_csv = scenario_reports_csv_path
151
- end
152
- end
153
-
154
- end
155
-
156
- # if we loaded the json
157
- if default_feature_reports_json # && default_feature_reports_json[:feature_reports]
158
- # default_feature_reports_json.each do |feature_report|
159
- # result << FeatureReport.new(feature_report)
160
- # end
161
- result << FeatureReport.new(default_feature_reports_json) # should we keep it as an array !? or each each report can only include 1 feature
162
-
163
- else
164
- # we did not find a report
165
- features.each do |feature|
166
- hash = {}
167
- hash[:id] = feature.id
168
- hash[:name] = feature.name
169
- hash[:directory_name] = simulation_dir.run_dir
170
- hash[:simulation_status] = simulation_status
171
- result << FeatureReport.new(hash)
172
- end
173
- end
174
-
175
- # validate feature_report json against schema
176
- if @@validator.validate(@@schema[:definitions][:FeatureReport][:properties], default_feature_reports_json).any?
177
- raise "default_feature_report_json properties does not match schema: #{@@validator.validate(@@schema[:definitions][:FeatureReport][:properties], default_feature_reports_json)}"
178
- end
179
-
180
- return result
181
- end
182
-
183
- ##
184
- # Convert to a Hash equivalent for JSON serialization
185
- ##
186
- # - Exclude attributes with nil values.
187
- # - Validate feature_report hash properties against schema.
188
- ##
189
- def to_hash
190
- result = {}
191
- result[:id] = @id if @id
192
- result[:name] = @name if @name
193
- result[:directory_name] = @directory_name if @directory_name
194
- result[:feature_type] = @feature_type if @feature_type
195
- result[:timesteps_per_hour] = @timesteps_per_hour if @timesteps_per_hour
196
- result[:simulation_status] = @simulation_status if @simulation_status
197
- result[:timeseries_csv] = @timeseries_csv.to_hash
198
-
199
- result[:location] = @location.to_hash if @location
200
-
201
- result[:program] = @program.to_hash
202
-
203
- result[:construction_costs] = []
204
- @construction_costs.each { |cc| result[:construction_costs] << cc.to_hash }
205
-
206
- result[:reporting_periods] = []
207
- @reporting_periods.each { |rp| result[:reporting_periods] << rp.to_hash }
208
-
209
- result[:distributed_generation] = @distributed_generation.to_hash if @distributed_generation
210
-
211
- result[:power_distribution] = @power_distribution.to_hash if @power_distribution
212
-
213
- # validate feature_report properties against schema
214
- if @@validator.validate(@@schema[:definitions][:FeatureReport][:properties], result).any?
215
- raise "feature_report properties does not match schema: #{@@validator.validate(@@schema[:definitions][:FeatureReport][:properties], result)}"
216
- end
217
-
218
- return result
219
- end
220
-
221
- ##
222
- # Saves the 'default_feature_report.json' and 'default_feature_report.csv' files
223
- ##
224
- # [parameters]:
225
- # +file_name+ - _String_ - Assign a name to the saved feature report results file without an extension
226
- def save_feature_report(file_name = 'default_feature_report')
227
- # reassign the initialize local variable @file_name to the file name input.
228
- @file_name = file_name
229
-
230
- # create feature reports directory
231
- Dir.mkdir(File.join(@directory_name, 'feature_reports')) unless Dir.exist?(File.join(@directory_name, 'feature_reports'))
232
-
233
- # save the csv data
234
- old_timeseries_path = nil
235
- if !@timeseries_csv.path.nil?
236
- old_timeseries_path = @timeseries_csv.path
237
- end
238
-
239
- @timeseries_csv.path = File.join(@directory_name, 'feature_reports', file_name + '.csv')
240
- @timeseries_csv.save_data
241
-
242
- # feature_hash
243
- feature_hash = to_hash
244
-
245
- json_name_path = File.join(@directory_name, 'feature_reports', file_name + '.json')
246
-
247
- File.open(json_name_path, 'w') do |f|
248
- f.puts JSON.pretty_generate(feature_hash)
249
- # make sure data is written to the disk one way or the other
250
- begin
251
- f.fsync
252
- rescue StandardError
253
- f.flush
254
- end
255
- end
256
-
257
- if !old_timeseries_path.nil?
258
- @timeseries_csv.path = old_timeseries_path
259
- else
260
- @timeseries_csv.path = File.join(@directory_name, 'feature_reports', file_name + '.csv')
261
- end
262
- return true
263
- end
264
- end
265
- end
266
- end
267
- end