urbanopt-reporting 0.6.2 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|