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.
- checksums.yaml +4 -4
- data/.github/workflows/nightly_ci_build.yml +54 -0
- data/CHANGELOG.md +16 -0
- data/Gemfile +10 -5
- data/LICENSE.md +16 -11
- data/README.md +1 -0
- data/Rakefile +2 -37
- data/building_loads.csv +52561 -0
- data/doc_templates/LICENSE.md +16 -11
- data/doc_templates/copyright_erb.txt +22 -16
- data/doc_templates/copyright_js.txt +2 -2
- data/doc_templates/copyright_ruby.txt +2 -37
- data/lib/measures/.rubocop.yml +1 -2
- data/lib/measures/default_feature_reports/LICENSE.md +23 -18
- data/lib/measures/default_feature_reports/measure.rb +110 -61
- data/lib/measures/default_feature_reports/measure.xml +40 -45
- data/lib/measures/export_modelica_loads/LICENSE.md +23 -18
- data/lib/measures/export_modelica_loads/measure.rb +19 -54
- data/lib/measures/export_modelica_loads/measure.xml +31 -31
- data/lib/measures/export_time_series_modelica/LICENSE.md +23 -18
- data/lib/measures/export_time_series_modelica/measure.rb +2 -37
- data/lib/measures/export_time_series_modelica/measure.xml +48 -42
- data/lib/measures/export_time_series_modelica/resources/os_lib_helper_methods.rb +2 -37
- data/lib/urbanopt/reporting/default_reports/construction_cost.rb +2 -37
- data/lib/urbanopt/reporting/default_reports/date.rb +2 -37
- data/lib/urbanopt/reporting/default_reports/distributed_generation.rb +3 -38
- data/lib/urbanopt/reporting/default_reports/end_use.rb +2 -37
- data/lib/urbanopt/reporting/default_reports/end_uses.rb +2 -37
- data/lib/urbanopt/reporting/default_reports/extension.rb +2 -37
- data/lib/urbanopt/reporting/default_reports/feature_report.rb +7 -38
- data/lib/urbanopt/reporting/default_reports/generator.rb +2 -37
- data/lib/urbanopt/reporting/default_reports/location.rb +2 -37
- data/lib/urbanopt/reporting/default_reports/logger.rb +4 -37
- data/lib/urbanopt/reporting/default_reports/power_distribution.rb +2 -37
- data/lib/urbanopt/reporting/default_reports/program.rb +2 -37
- data/lib/urbanopt/reporting/default_reports/qaqc_flags.rb +147 -0
- data/lib/urbanopt/reporting/default_reports/reporting_period.rb +6 -41
- data/lib/urbanopt/reporting/default_reports/scenario_power_distribution.rb +2 -37
- data/lib/urbanopt/reporting/default_reports/scenario_power_distribution_cost.rb +177 -0
- data/lib/urbanopt/reporting/default_reports/scenario_report.rb +36 -52
- data/lib/urbanopt/reporting/default_reports/schema/scenario_schema.json +372 -31
- data/lib/urbanopt/reporting/default_reports/solar_pv.rb +2 -37
- data/lib/urbanopt/reporting/default_reports/storage.rb +2 -37
- data/lib/urbanopt/reporting/default_reports/thermal_storage.rb +2 -37
- data/lib/urbanopt/reporting/default_reports/timeseries_csv.rb +2 -37
- data/lib/urbanopt/reporting/default_reports/validator.rb +2 -37
- data/lib/urbanopt/reporting/default_reports/wind.rb +2 -37
- data/lib/urbanopt/reporting/default_reports.rb +2 -37
- data/lib/urbanopt/reporting/derived_extension.rb +2 -37
- data/lib/urbanopt/reporting/version.rb +3 -38
- data/lib/urbanopt/reporting.rb +2 -37
- data/urbanopt-reporting-gem.gemspec +3 -3
- metadata +14 -11
- 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
|
3
|
-
#
|
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
|
3
|
-
#
|
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
|
3
|
-
#
|
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
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
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
|
-
|
175
|
-
|
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
|
197
|
-
|
198
|
-
|
199
|
-
|
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
|
-
|
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
|
|