urbanopt-reporting 0.6.2 → 0.8.0

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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/nightly_ci_build.yml +54 -0
  3. data/CHANGELOG.md +16 -0
  4. data/Gemfile +10 -5
  5. data/LICENSE.md +16 -11
  6. data/README.md +1 -0
  7. data/Rakefile +2 -37
  8. data/building_loads.csv +52561 -0
  9. data/doc_templates/LICENSE.md +16 -11
  10. data/doc_templates/copyright_erb.txt +22 -16
  11. data/doc_templates/copyright_js.txt +2 -2
  12. data/doc_templates/copyright_ruby.txt +2 -37
  13. data/lib/measures/.rubocop.yml +1 -2
  14. data/lib/measures/default_feature_reports/LICENSE.md +23 -18
  15. data/lib/measures/default_feature_reports/measure.rb +110 -61
  16. data/lib/measures/default_feature_reports/measure.xml +40 -45
  17. data/lib/measures/export_modelica_loads/LICENSE.md +23 -18
  18. data/lib/measures/export_modelica_loads/measure.rb +19 -54
  19. data/lib/measures/export_modelica_loads/measure.xml +31 -31
  20. data/lib/measures/export_time_series_modelica/LICENSE.md +23 -18
  21. data/lib/measures/export_time_series_modelica/measure.rb +2 -37
  22. data/lib/measures/export_time_series_modelica/measure.xml +48 -42
  23. data/lib/measures/export_time_series_modelica/resources/os_lib_helper_methods.rb +2 -37
  24. data/lib/urbanopt/reporting/default_reports/construction_cost.rb +2 -37
  25. data/lib/urbanopt/reporting/default_reports/date.rb +2 -37
  26. data/lib/urbanopt/reporting/default_reports/distributed_generation.rb +3 -38
  27. data/lib/urbanopt/reporting/default_reports/end_use.rb +2 -37
  28. data/lib/urbanopt/reporting/default_reports/end_uses.rb +2 -37
  29. data/lib/urbanopt/reporting/default_reports/extension.rb +2 -37
  30. data/lib/urbanopt/reporting/default_reports/feature_report.rb +7 -38
  31. data/lib/urbanopt/reporting/default_reports/generator.rb +2 -37
  32. data/lib/urbanopt/reporting/default_reports/location.rb +2 -37
  33. data/lib/urbanopt/reporting/default_reports/logger.rb +4 -37
  34. data/lib/urbanopt/reporting/default_reports/power_distribution.rb +2 -37
  35. data/lib/urbanopt/reporting/default_reports/program.rb +2 -37
  36. data/lib/urbanopt/reporting/default_reports/qaqc_flags.rb +147 -0
  37. data/lib/urbanopt/reporting/default_reports/reporting_period.rb +6 -41
  38. data/lib/urbanopt/reporting/default_reports/scenario_power_distribution.rb +2 -37
  39. data/lib/urbanopt/reporting/default_reports/scenario_power_distribution_cost.rb +177 -0
  40. data/lib/urbanopt/reporting/default_reports/scenario_report.rb +36 -52
  41. data/lib/urbanopt/reporting/default_reports/schema/scenario_schema.json +372 -31
  42. data/lib/urbanopt/reporting/default_reports/solar_pv.rb +2 -37
  43. data/lib/urbanopt/reporting/default_reports/storage.rb +2 -37
  44. data/lib/urbanopt/reporting/default_reports/thermal_storage.rb +2 -37
  45. data/lib/urbanopt/reporting/default_reports/timeseries_csv.rb +2 -37
  46. data/lib/urbanopt/reporting/default_reports/validator.rb +2 -37
  47. data/lib/urbanopt/reporting/default_reports/wind.rb +2 -37
  48. data/lib/urbanopt/reporting/default_reports.rb +2 -37
  49. data/lib/urbanopt/reporting/derived_extension.rb +2 -37
  50. data/lib/urbanopt/reporting/version.rb +3 -38
  51. data/lib/urbanopt/reporting.rb +2 -37
  52. data/urbanopt-reporting-gem.gemspec +3 -3
  53. metadata +14 -11
  54. data/.github/workflows/nightly_build.yml +0 -41
@@ -0,0 +1,147 @@
1
+ # *********************************************************************************
2
+ # URBANopt (tm), Copyright (c) Alliance for Sustainable Energy, LLC.
3
+ # See also https://github.com/urbanopt/urbanopt-reporting-gem/blob/develop/LICENSE.md
4
+ # *********************************************************************************
5
+
6
+ require 'json'
7
+ require 'json-schema'
8
+
9
+ module URBANopt
10
+ module Reporting
11
+ module DefaultReports
12
+ ##
13
+ # QAQC flags for each feature
14
+ ##
15
+ class QAQC
16
+ ##
17
+ # _Hash_ - Hash of flags raised by QAQC measure for this feature during this reporting period
18
+ #
19
+ attr_accessor :eui_reasonableness,:end_use_by_category,:mechanical_system_part_load_efficiency,
20
+ :simultaneous_heating_and_cooling , :internal_loads , :schedules, :envelope_r_value,
21
+ :domestic_hot_water , :mechanical_system_efficiency , :supply_and_zone_air_temperature,
22
+ :total_qaqc_flags
23
+
24
+ ##
25
+ # QAQC class initialize quaqc attributes: +:eui_reasonableness,+:end_use_by_category,+:mechanical_system_part_load_efficiency,
26
+ # +:simultaneous_heating_and_cooling , +:internal_loads , +:schedules, +:envelope_r_value,
27
+ # +:domestic_hot_water , +:mechanical_system_efficiency , +:supply_and_zone_air_temperature, +:total_qaqc_flags
28
+ ##
29
+ # [parameters:]
30
+ #
31
+ # * +hash+ - _Hash_ - A hash containing qaqc attributes listed above.
32
+ #
33
+ def initialize(hash = {})
34
+ hash.delete_if { |k, v| v.nil? }
35
+ hash = defaults.merge(hash)
36
+
37
+ @eui_reasonableness = hash[:eui_reasonableness]
38
+ @end_use_by_category = hash[:end_use_by_category]
39
+ @mechanical_system_part_load_efficiency = hash[:mechanical_system_part_load_efficiency]
40
+ @simultaneous_heating_and_cooling = hash[:simultaneous_heating_and_cooling]
41
+ @supply_and_zone_air_temperature = hash[:supply_and_zone_air_temperature]
42
+ @internal_loads = hash[:internal_loads]
43
+ @schedules = hash[:schedules]
44
+ @envelope_r_value = hash[:envelope_r_value]
45
+ @domestic_hot_water = hash[:domestic_hot_water]
46
+ @mechanical_system_efficiency = hash[:mechanical_system_efficiency]
47
+ @total_qaqc_flags = hash[:total_qaqc_flags]
48
+
49
+
50
+ # initialize class variables @@validator and @@schema
51
+ @@validator ||= Validator.new
52
+ @@schema ||= @@validator.schema
53
+
54
+ end
55
+
56
+
57
+ ##
58
+ # Assigns default values if values do not exist.
59
+ ##
60
+ def defaults
61
+ hash = {}
62
+
63
+ hash[:eui_reasonableness] = nil
64
+ hash[:end_use_by_category] = nil
65
+ hash[:mechanical_system_part_load_efficiency] = nil
66
+ hash[:simultaneous_heating_and_cooling] = nil
67
+ hash[:supply_and_zone_air_temperature] = nil
68
+ hash[:internal_loads] = nil
69
+ hash[:schedules] = nil
70
+ hash[:envelope_r_value] = nil
71
+ hash[:domestic_hot_water] = nil
72
+ hash[:mechanical_system_efficiency] = nil
73
+ hash[:total_qaqc_flags] = nil
74
+
75
+
76
+ return hash
77
+ end
78
+ ##
79
+ # Convert to a Hash equivalent for JSON serialization
80
+ ##
81
+ def to_hash
82
+ result = {}
83
+
84
+ result[:eui_reasonableness] = @eui_reasonableness
85
+ result[:end_use_by_category] = @end_use_by_category
86
+ result[:mechanical_system_part_load_efficiency] = @mechanical_system_part_load_efficiency
87
+ result[:simultaneous_heating_and_cooling] = @simultaneous_heating_and_cooling
88
+ result[:supply_and_zone_air_temperature] = @supply_and_zone_air_temperature
89
+ result[:internal_loads] = @internal_loads
90
+ result[:schedules] = @schedules
91
+ result[:envelope_r_value] = @envelope_r_value
92
+ result[:domestic_hot_water] = @domestic_hot_water
93
+ result[:mechanical_system_efficiency] = @mechanical_system_efficiency
94
+ result[:total_qaqc_flags] = @total_qaqc_flags
95
+
96
+ # validate program properties against schema
97
+ if @@validator.validate(@@schema[:definitions][:qaqc_flags][:properties], result).any?
98
+ raise "qaqc properties does not match schema: #{@@validator.validate(@@schema[:definitions][:qaqc_flags][:properties], result)}"
99
+ end
100
+
101
+ return result
102
+
103
+ end
104
+
105
+ ##
106
+ # Adds up +existing_value+ and +new_values+ if not nill.
107
+ ##
108
+ # [parameters:]
109
+ # +existing_value+ - _Float_ - A value corresponding to a qaqc_flags attribute.
110
+ ##
111
+ # +new_value+ - _Float_ - A value corresponding to a qaqc_flags attribute.
112
+ ##
113
+ def add_values(existing_value, new_value) #:nodoc:
114
+ if existing_value && new_value
115
+ existing_value += new_value
116
+ elsif new_value
117
+ existing_value = new_value
118
+ end
119
+ return existing_value
120
+ end
121
+
122
+ ##
123
+ # Merges qaqc_flags objects to each other by summing up values.
124
+ ##
125
+ # [parameters:]
126
+ # +other+ - _QAQC_ - An object of Program class.
127
+ ##
128
+ def add_qaqc_flags(other)
129
+
130
+ @eui_reasonableness = add_values(@eui_reasonableness, other.eui_reasonableness)
131
+ @end_use_by_category = add_values(@end_use_by_category, other.end_use_by_category)
132
+ @mechanical_system_part_load_efficiency = add_values(@mechanical_system_part_load_efficiency, other.mechanical_system_part_load_efficiency)
133
+ @simultaneous_heating_and_cooling = add_values(@simultaneous_heating_and_cooling, other.simultaneous_heating_and_cooling)
134
+ @supply_and_zone_air_temperature = add_values(@supply_and_zone_air_temperature, other.supply_and_zone_air_temperature)
135
+ @internal_loads = add_values(@internal_loads, other.internal_loads)
136
+ @schedules = add_values(@schedules, other.schedules)
137
+ @envelope_r_value = add_values(@envelope_r_value, other.envelope_r_value)
138
+ @domestic_hot_water = add_values(@domestic_hot_water, other.domestic_hot_water)
139
+ @mechanical_system_efficiency = add_values(@mechanical_system_efficiency, other.mechanical_system_efficiency)
140
+ @total_qaqc_flags = add_values(@total_qaqc_flags, other.total_qaqc_flags)
141
+
142
+ end
143
+
144
+ end
145
+ end
146
+ end
147
+ end
@@ -1,41 +1,6 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2022, 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
- # Redistribution of this software, without modification, must refer to the software
20
- # by the same designation. Redistribution of a modified version of this software
21
- # (i) may not refer to the modified version by the same designation, or by any
22
- # confusingly similar designation, and (ii) must refer to the underlying software
23
- # originally provided by Alliance as “URBANopt”. Except to comply with the foregoing,
24
- # the term “URBANopt”, or any confusingly similar designation may not be used to
25
- # refer to any modified version of this software or any modified version of the
26
- # underlying software originally provided by Alliance without the prior written
27
- # consent of Alliance.
28
-
29
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
30
- # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
31
- # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
32
- # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33
- # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
- # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35
- # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
36
- # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
37
- # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
38
- # OF THE POSSIBILITY OF SUCH DAMAGE.
2
+ # URBANopt (tm), Copyright (c) Alliance for Sustainable Energy, LLC.
3
+ # See also https://github.com/urbanopt/urbanopt-reporting-gem/blob/develop/LICENSE.md
39
4
  # *********************************************************************************
40
5
 
41
6
  require_relative 'end_uses'
@@ -60,7 +25,7 @@ module URBANopt
60
25
  :time_setpoint_not_met_during_occupied_heating, :time_setpoint_not_met_during_occupied_hours, :hours_out_of_comfort_bounds_PMV, :hours_out_of_comfort_bounds_PPD,
61
26
  :emissions, :future_annual_electricity_emissions_mt, :future_hourly_electricity_emissions_mt, :historical_annual_electricity_emissions_mt, :historical_hourly_electricity_emissions_mt,
62
27
  :future_annual_electricity_emissions_intensity_kg_per_ft2, :future_hourly_electricity_emissions_intensity_kg_per_ft2, :historical_annual_electricity_emissions_intensity_kg_per_ft2, :historical_hourly_electricity_emissions_intensity_kg_per_ft2 ,
63
- :natural_gas_emissions_mt, :natural_gas_emissions_intensity_kg_per_ft2, :propane_emissions_mt, :propane_emissions_intensity_kg_per_ft2,
28
+ :natural_gas_emissions_mt, :natural_gas_emissions_intensity_kg_per_ft2, :propane_emissions_mt, :propane_emissions_intensity_kg_per_ft2,
64
29
  :fueloil_no2_emissions_mt, :fueloil_no2_emissions_intensity_kg_per_ft2 #:nodoc:
65
30
 
66
31
  # ReportingPeriod class initializes the reporting period attributes:
@@ -71,7 +36,7 @@ module URBANopt
71
36
  # +:time_setpoint_not_met_during_occupied_heating+ , +:time_setpoint_not_met_during_occupied_hours+ , +:hours_out_of_comfort_bounds_PMV+ , +:hours_out_of_comfort_bounds_PPD+ ,
72
37
  # +:emissions, +:future_annual_electricity_emissions_mt+, +:future_hourly_electricity_emissions_mt+, +:historical_annual_electricity_emissions_mt+, +:historical_hourly_electricity_emissions_mt+,
73
38
  # +:future_annual_electricity_emissions_intensity_kg_per_ft2+, +:future_hourly_electricity_emissions_intensity_kg_per_ft2+, +:historical_annual_electricity_emissions_intensity_kg_per_ft2+, +:historical_hourly_electricity_emissions_intensity_kg_per_ft2+,
74
- # +:natural_gas_emissions_mt+, +:natural_gas_emissions_intensity_kg_per_ft2+, +:propane_emissions_mt+, +:propane_emissions_intensity_kg_per_ft2+,
39
+ # +:natural_gas_emissions_mt+, +:natural_gas_emissions_intensity_kg_per_ft2+, +:propane_emissions_mt+, +:propane_emissions_intensity_kg_per_ft2+,
75
40
  # +:fueloil_no2_emissions_mt+, +:fueloil_no2_emissions_intensity_kg_per_ft2+
76
41
  ##
77
42
  # [parameters:]
@@ -157,7 +122,7 @@ module URBANopt
157
122
  hash[:utility_costs_dollar] = [{ fuel_type: nil, total_cost_dollar: nil, usage_cost_dollar: nil, demand_cost_dollar: nil }]
158
123
  hash[:comfort_result] = { time_setpoint_not_met_during_occupied_cooling: nil, time_setpoint_not_met_during_occupied_heating: nil,
159
124
  time_setpoint_not_met_during_occupied_hours: nil, hours_out_of_comfort_bounds_PMV: nil, hours_out_of_comfort_bounds_PPD: nil }
160
- hash[:emissions] = { future_annual_electricity_emissions_mt: nil, future_hourly_electricity_emissions_mt: nil, historical_annual_electricity_emissions_mt: nil,
125
+ hash[:emissions] = { future_annual_electricity_emissions_mt: nil, future_hourly_electricity_emissions_mt: nil, historical_annual_electricity_emissions_mt: nil,
161
126
  historical_hourly_electricity_emissions_mt: nil, future_annual_electricity_emissions_intensity_kg_per_ft2: nil,
162
127
  future_hourly_electricity_emissions_intensity_kg_per_ft2: nil, historical_annual_electricity_emissions_intensity_kg_per_ft2: nil,
163
128
  historical_hourly_electricity_emissions_intensity_kg_per_ft2: nil, natural_gas_emissions_mt: nil,
@@ -307,7 +272,7 @@ module URBANopt
307
272
  existing_period.emissions[:natural_gas_emissions_mt] = add_values(existing_period.emissions[:natural_gas_emissions_mt], new_period.emissions[:natural_gas_emissions_mt])
308
273
  existing_period.emissions[:propane_emissions_mt] = add_values(existing_period.emissions[:propane_emissions_mt], new_period.emissions[:propane_emissions_mt])
309
274
  existing_period.emissions[:fueloil_no2_emissions_mt] = add_values(existing_period.emissions[:fueloil_no2_emissions_mt], new_period.emissions[:fueloil_no2_emissions_mt])
310
-
275
+
311
276
  existing_period.emissions[:future_annual_electricity_emissions_intensity_kg_per_ft2] = add_values(existing_period.emissions[:future_annual_electricity_emissions_intensity_kg_per_ft2], new_period.emissions[:future_annual_electricity_emissions_intensity_kg_per_ft2])
312
277
  existing_period.emissions[:future_hourly_electricity_emissions_intensity_kg_per_ft2] = add_values(existing_period.emissions[:future_hourly_electricity_emissions_intensity_kg_per_ft2], new_period.emissions[:future_hourly_electricity_emissions_intensity_kg_per_ft2])
313
278
  existing_period.emissions[:historical_annual_electricity_emissions_intensity_kg_per_ft2] = add_values(existing_period.emissions[:historical_annual_electricity_emissions_intensity_kg_per_ft2], new_period.emissions[:historical_annual_electricity_emissions_intensity_kg_per_ft2])
@@ -1,41 +1,6 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2022, 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
- # Redistribution of this software, without modification, must refer to the software
20
- # by the same designation. Redistribution of a modified version of this software
21
- # (i) may not refer to the modified version by the same designation, or by any
22
- # confusingly similar designation, and (ii) must refer to the underlying software
23
- # originally provided by Alliance as “URBANopt”. Except to comply with the foregoing,
24
- # the term “URBANopt”, or any confusingly similar designation may not be used to
25
- # refer to any modified version of this software or any modified version of the
26
- # underlying software originally provided by Alliance without the prior written
27
- # consent of Alliance.
28
-
29
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
30
- # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
31
- # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
32
- # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33
- # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
- # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35
- # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
36
- # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
37
- # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
38
- # OF THE POSSIBILITY OF SUCH DAMAGE.
2
+ # URBANopt (tm), Copyright (c) Alliance for Sustainable Energy, LLC.
3
+ # See also https://github.com/urbanopt/urbanopt-reporting-gem/blob/develop/LICENSE.md
39
4
  # *********************************************************************************
40
5
 
41
6
  require_relative 'validator'
@@ -0,0 +1,177 @@
1
+ # *********************************************************************************
2
+ # URBANopt (tm), Copyright (c) Alliance for Sustainable Energy, LLC.
3
+ # See also https://github.com/urbanopt/urbanopt-reporting-gem/blob/develop/LICENSE.md
4
+ # *********************************************************************************
5
+
6
+ require_relative 'validator'
7
+
8
+ require 'json'
9
+ require 'json-schema'
10
+
11
+ module URBANopt
12
+ module Reporting
13
+ module DefaultReports
14
+ ##
15
+ # scenario_power_distribution_cost include eletrical power distribution system violation and
16
+ # upgrade cost information.
17
+ ##
18
+ class ScenarioPowerDistributionCost
19
+ attr_accessor :results, :outputs, :violation_summary, :costs_per_equipment, :equipment
20
+
21
+ ##
22
+ # ScenarioPowerDistributionCost class initializes all
23
+ # scenario_power_distribution_cost attributes:
24
+ # +:results+, +:outputs+, +:violation_summary+, +:costs_per_equipment+, +:equipment+
25
+ ##
26
+ def initialize(hash = {})
27
+ hash.delete_if { |k, v| v.nil? }
28
+ hash = defaults.merge(hash)
29
+
30
+ @results = hash[:results]
31
+ @outputs = hash[:outputs]
32
+ @violation_summary = hash[:violation_summary]
33
+ @costs_per_equipment = hash[:costs_per_equipment]
34
+ @equipment = hash[:equipment]
35
+
36
+ # initialize class variables @@validator and @@schema
37
+ @@validator ||= Validator.new
38
+ @@schema ||= @@validator.schema
39
+ end
40
+
41
+ ##
42
+ # Assigns default values if attribute values do not exist.##
43
+ def defaults
44
+ hash = {}
45
+ hash[:results] = []
46
+ hash[:outputs] = {}
47
+ hash[:violation_summary] = []
48
+ hash[:costs_per_equipment] = []
49
+ hash[:equipment] = []
50
+
51
+ return hash
52
+ end
53
+
54
+ ##
55
+ # Converts to a Hash equivalent for JSON serialization.
56
+ ##
57
+ # - Exclude attributes with nil values.
58
+ # - Validate power_distribution_cost hash properties against schema.
59
+ ##
60
+ def to_hash
61
+ result = {}
62
+ result[:results] = @results if @results
63
+ result[:outputs] = @outputs if !@outputs.empty?
64
+ result[:violation_summary] = @violation_summary if @violation_summary
65
+ result[:costs_per_equipment] = @costs_per_equipment if @costs_per_equipment
66
+ result[:equipment] = @equipment if @equipment
67
+
68
+ # validate power_distribution_cost properties against schema
69
+ if @@validator.validate(@@schema[:definitions][:ScenarioPowerDistributionCost][:properties], result).any?
70
+ raise "scenario_power_distribution_cost properties does not match schema: #{@@validator.validate(@@schema[:definitions][:ScenarioPowerDistributionCost][:properties], result)}"
71
+ end
72
+
73
+ return result
74
+ end
75
+
76
+ ##
77
+ # Add a result
78
+ ##
79
+ def add_result(hash = {})
80
+ hash.delete_if { |k, v| v.nil? }
81
+ hash = defaults.merge(hash)
82
+ result = {}
83
+ result['num_violations'] = hash[:num_violations]
84
+ @results << result
85
+ end
86
+
87
+ ##
88
+ ## Add outputs
89
+ ##
90
+ def add_outputs(hash = {})
91
+ hash.delete_if { |k, v| v.nil? }
92
+ hash = defaults.merge(hash)
93
+ output = {}
94
+ output['log_file'] = hash[:log_file]
95
+ output['jobs'] = []
96
+ hash[:jobs].each do |job|
97
+ output['jobs'] << job
98
+ end
99
+ @outputs = output
100
+ end
101
+
102
+ ##
103
+ ## Add a violation summary
104
+ ##
105
+ def add_violation_summary(hash = {})
106
+ hash.delete_if { |k, v| v.nil? }
107
+ hash = defaults.merge(hash)
108
+ violation_summary = {}
109
+ violation_summary['scenario'] = hash[:scenario]
110
+ violation_summary['stage'] = hash[:stage]
111
+ violation_summary['upgrade_type'] = hash[:upgrade_type]
112
+ violation_summary['simulation_time_s'] = hash[:simulation_time_s]
113
+ violation_summary['thermal_violations_present'] = hash[:thermal_violations_present]
114
+ violation_summary['voltage_violations_present'] = hash[:voltage_violations_present]
115
+ violation_summary['max_bus_voltage'] = hash[:max_bus_voltage]
116
+ violation_summary['min_bus_voltage'] = hash[:min_bus_voltage]
117
+ violation_summary['num_voltage_violation_buses'] = hash[:num_voltage_violation_buses]
118
+ violation_summary['num_overvoltage_violation_buses'] = hash[:num_overvoltage_violation_buses]
119
+ violation_summary['voltage_upper_limit'] = hash[:voltage_upper_limit]
120
+ violation_summary['num_undervoltage_violation_buses'] = hash[:num_undervoltage_violation_buses]
121
+ violation_summary['voltage_lower_limit'] = hash[:voltage_lower_limit]
122
+ violation_summary['max_line_loading'] = hash[:max_line_loading]
123
+ violation_summary['max_transformer_loading'] = hash[:max_transformer_loading]
124
+ violation_summary['num_line_violations'] = hash[:num_line_violations]
125
+ violation_summary['line_upper_limit'] = hash[:line_upper_limit]
126
+ violation_summary['num_transformer_violations'] = hash[:num_transformer_violations]
127
+ violation_summary['transformer_upper_limit'] = hash[:transformer_upper_limit]
128
+
129
+ @violation_summary << violation_summary
130
+ end
131
+
132
+ ##
133
+ # Add costs per equipment
134
+ ##
135
+ def add_costs_per_equipment
136
+ hash.delete_if { |k, v| v.nil? }
137
+ hash = defaults.merge(hash)
138
+ costs_per_equipment = {}
139
+ costs_per_equipment['name'] = hash[:name]
140
+ costs_per_equipment['type'] = hash[:type]
141
+ costs_per_equipment['count'] = hash[:count]
142
+ costs_per_equipment['total_cost_usd'] = hash[:costs_per_equipment]
143
+
144
+ @costs_per_equipment << costs_per_equipment
145
+ end
146
+
147
+ ##
148
+ # Add equipment
149
+ ##
150
+ def add_equipment
151
+ hash.delete_if { |k, v| v.nil? }
152
+ hash = defaults.merge(hash)
153
+ equipment = {}
154
+ equipment['equipment_type'] = hash[:equipment_type]
155
+ equipment['equipment_name'] = hash[:equipment_name]
156
+ equipment['status'] = hash[:status]
157
+ equipment['parameter1_name'] = hash[:parameter1_name]
158
+ equipment['parameter1_original'] = hash[:parameter1_original]
159
+ equipment['parameter1_upgraded'] = hash[:parameter1_upgraded]
160
+ equipment['parameter2_name'] = hash[:parameter2_name]
161
+ equipment['parameter2_original'] = hash[:parameter2_original]
162
+ equipment['parameter2_upgraded'] = hash[:parameter2_upgraded]
163
+ equipment['parameter3_name'] = hash[:parameter3_name]
164
+ equipment['parameter3_original'] = hash[:parameter3_original]
165
+ equipment['parameter3_upgraded'] = hash[:parameter3_upgraded]
166
+ equipment['name'] = hash[:name]
167
+
168
+ @equipment << equipment
169
+ end
170
+
171
+
172
+
173
+ end # ScenarioPowerDistributionCost
174
+
175
+ end # DefaultReports
176
+ end # Reporting
177
+ end # URBANopt
@@ -1,41 +1,6 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2022, 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
- # Redistribution of this software, without modification, must refer to the software
20
- # by the same designation. Redistribution of a modified version of this software
21
- # (i) may not refer to the modified version by the same designation, or by any
22
- # confusingly similar designation, and (ii) must refer to the underlying software
23
- # originally provided by Alliance as “URBANopt”. Except to comply with the foregoing,
24
- # the term “URBANopt”, or any confusingly similar designation may not be used to
25
- # refer to any modified version of this software or any modified version of the
26
- # underlying software originally provided by Alliance without the prior written
27
- # consent of Alliance.
28
-
29
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
30
- # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
31
- # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
32
- # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33
- # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
- # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35
- # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
36
- # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
37
- # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
38
- # OF THE POSSIBILITY OF SUCH DAMAGE.
2
+ # URBANopt (tm), Copyright (c) Alliance for Sustainable Energy, LLC.
3
+ # See also https://github.com/urbanopt/urbanopt-reporting-gem/blob/develop/LICENSE.md
39
4
  # *********************************************************************************
40
5
 
41
6
  require_relative 'construction_cost'
@@ -47,6 +12,8 @@ require_relative 'timeseries_csv'
47
12
  require_relative 'distributed_generation'
48
13
  require_relative 'validator'
49
14
  require_relative 'scenario_power_distribution'
15
+ require_relative 'scenario_power_distribution_cost'
16
+ require_relative 'qaqc_flags'
50
17
 
51
18
  require 'json'
52
19
  require 'json-schema'
@@ -64,12 +31,13 @@ module URBANopt
64
31
  attr_accessor :id, :name, :directory_name, :timesteps_per_hour, :number_of_not_started_simulations,
65
32
  :number_of_started_simulations, :number_of_complete_simulations, :number_of_failed_simulations,
66
33
  :timeseries_csv, :location, :program, :construction_costs, :reporting_periods, :feature_reports, :distributed_generation,
67
- :scenario_power_distribution # :nodoc:
34
+ :scenario_power_distribution, :scenario_power_distribution_cost, :qaqc_flags # :nodoc:
68
35
 
69
36
  # ScenarioReport class intializes the scenario report attributes:
70
37
  # +:id+ , +:name+ , +:directory_name+, +:timesteps_per_hour+ , +:number_of_not_started_simulations+ ,
71
38
  # +:number_of_started_simulations+ , +:number_of_complete_simulations+ , +:number_of_failed_simulations+ ,
72
- # +:timeseries_csv+ , +:location+ , +:program+ , +:construction_costs+ , +:reporting_periods+ , +:feature_reports+
39
+ # +:timeseries_csv+ , +:location+ , +:program+ , +:construction_costs+ , +:reporting_periods+ , +:feature_reports+,
40
+ # +:distributed_generation+, +:scenario_power_distribution+, +:qaqc_flags+
73
41
  ##
74
42
  # Each ScenarioReport object corresponds to a single Scenario.
75
43
  ##
@@ -93,6 +61,8 @@ module URBANopt
93
61
  @program = Program.new(hash[:program])
94
62
  @distributed_generation = DistributedGeneration.new(hash[:distributed_generation] || {})
95
63
  @scenario_power_distribution = ScenarioPowerDistribution.new(hash[:scenario_power_distribution] || {})
64
+ @scenario_power_distribution_cost = ScenarioPowerDistributionCost.new(hash[:scenario_power_distribution_cost] || {})
65
+ @qaqc_flags = QAQC.new(hash[:qaqc_flags])
96
66
 
97
67
  @construction_costs = []
98
68
  hash[:construction_costs].each do |cc|
@@ -136,6 +106,7 @@ module URBANopt
136
106
  hash[:timeseries_csv] = TimeseriesCSV.new.to_hash
137
107
  hash[:location] = Location.new.defaults
138
108
  hash[:program] = Program.new.to_hash
109
+ hash[:qaqc_flags] = QAQC.new.to_hash
139
110
  hash[:construction_costs] = []
140
111
  hash[:reporting_periods] = []
141
112
  hash[:feature_reports] = []
@@ -161,18 +132,20 @@ module URBANopt
161
132
  ##
162
133
  # [parameters]:
163
134
  # +file_name+ - _String_ - Assign a name to the saved scenario results file without an extension
164
- def save(file_name = 'default_scenario_report', save_feature_reports = true)
135
+ def save(file_name = 'default_scenario_report', save_feature_reports = true, save_csv_reports = true)
165
136
  # reassign the initialize local variable @file_name to the file name input.
166
137
  @file_name = file_name
167
138
 
168
- # save the scenario reports csv and json data
169
- old_timeseries_path = nil
170
- if !@timeseries_csv.path.nil?
171
- old_timeseries_path = @timeseries_csv.path
172
- end
139
+ if save_csv_reports == true
140
+ # save the scenario reports csv and json data
141
+ old_timeseries_path = nil
142
+ if !@timeseries_csv.path.nil?
143
+ old_timeseries_path = @timeseries_csv.path
144
+ end
173
145
 
174
- @timeseries_csv.path = File.join(@directory_name, "#{file_name}.csv")
175
- @timeseries_csv.save_data
146
+ @timeseries_csv.path = File.join(@directory_name, "#{file_name}.csv")
147
+ @timeseries_csv.save_data
148
+ end
176
149
 
177
150
  hash = {}
178
151
  hash[:scenario_report] = to_hash
@@ -193,10 +166,12 @@ module URBANopt
193
166
  end
194
167
  end
195
168
 
196
- if !old_timeseries_path.nil?
197
- @timeseries_csv.path = old_timeseries_path
198
- else
199
- @timeseries_csv.path = File.join(@directory_name, "#{file_name}.csv")
169
+ if save_csv_reports == true
170
+ if !old_timeseries_path.nil?
171
+ @timeseries_csv.path = old_timeseries_path
172
+ else
173
+ @timeseries_csv.path = File.join(@directory_name, "#{file_name}.csv")
174
+ end
200
175
  end
201
176
 
202
177
  if save_feature_reports
@@ -233,6 +208,8 @@ module URBANopt
233
208
  result[:program] = @program.to_hash if @program
234
209
  result[:distributed_generation] = @distributed_generation.to_hash if @distributed_generation
235
210
  result[:scenario_power_distribution] = @scenario_power_distribution.to_hash if @scenario_power_distribution
211
+ result[:scenario_power_distribution_cost] = @scenario_power_distribution_cost.to_hash if @scenario_power_distribution_cost
212
+ result[:qaqc_flags] = @qaqc_flags.to_hash if @qaqc_flags
236
213
 
237
214
  result[:construction_costs] = []
238
215
  @construction_costs&.each { |cc| result[:construction_costs] << cc.to_hash }
@@ -249,7 +226,9 @@ module URBANopt
249
226
  end
250
227
 
251
228
  # have to use the module method because we have not yet initialized the class one
252
- @@logger.info("Scenario name: #{@name}")
229
+ unless @name == '' || @name.nil?
230
+ @@logger.info("Scenario name: #{@name}")
231
+ end
253
232
 
254
233
  return result
255
234
  end
@@ -261,6 +240,7 @@ module URBANopt
261
240
  # - check feature simulation status
262
241
  # - merge timeseries_csv information
263
242
  # - merge program information
243
+ # - merge qaqc_flags information
264
244
  # - merge construction_cost information
265
245
  # - merge reporting_periods information
266
246
  # - add the array of feature_reports
@@ -324,8 +304,12 @@ module URBANopt
324
304
  # merge reporting_periods information
325
305
  @reporting_periods = ReportingPeriod.merge_reporting_periods(@reporting_periods, feature_report.reporting_periods)
326
306
 
307
+ # merge distributed_generation information
327
308
  @distributed_generation = DistributedGeneration.merge_distributed_generation(@distributed_generation, feature_report.distributed_generation)
328
309
 
310
+ # merge qaqc_flags information
311
+ @qaqc_flags.add_qaqc_flags(feature_report.qaqc_flags)
312
+
329
313
  # add feature_report
330
314
  @feature_reports << feature_report
331
315