urbanopt-scenario 0.1.1 → 0.3.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 +5 -5
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -8
- data/.github/ISSUE_TEMPLATE/feature_request.md +2 -10
- data/.github/pull_request_template.md +5 -15
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +45 -1
- data/{.github/CONTRIBUTING.md → CONTRIBUTING.md} +0 -0
- data/Gemfile +8 -12
- data/Jenkinsfile +2 -2
- data/Rakefile +2 -2
- data/docs/package-lock.json +4607 -6451
- data/docs/package.json +1 -1
- data/lib/measures/.rubocop.yml +1 -1
- data/lib/measures/default_feature_reports/LICENSE.md +1 -1
- data/lib/measures/default_feature_reports/README.md +5 -35
- data/lib/measures/default_feature_reports/measure.rb +315 -44
- data/lib/measures/default_feature_reports/measure.xml +38 -17
- data/lib/urbanopt/scenario.rb +1 -0
- data/lib/urbanopt/scenario/default_reports/distributed_generation.rb +209 -17
- data/lib/urbanopt/scenario/default_reports/feature_report.rb +57 -3
- data/lib/urbanopt/scenario/default_reports/power_distribution.rb +102 -0
- data/lib/urbanopt/scenario/default_reports/program.rb +6 -2
- data/lib/urbanopt/scenario/default_reports/reporting_period.rb +15 -9
- data/lib/urbanopt/scenario/default_reports/scenario_report.rb +24 -7
- data/lib/urbanopt/scenario/default_reports/schema/README.md +11 -12
- data/lib/urbanopt/scenario/default_reports/schema/scenario_csv_columns.txt +33 -12
- data/lib/urbanopt/scenario/default_reports/schema/scenario_schema.json +52 -25
- data/lib/urbanopt/scenario/default_reports/solar_pv.rb +1 -0
- data/lib/urbanopt/scenario/default_reports/timeseries_csv.rb +62 -21
- data/lib/urbanopt/scenario/scenario_post_processor_opendss.rb +276 -0
- data/lib/urbanopt/scenario/scenario_runner_osw.rb +21 -5
- data/lib/urbanopt/scenario/simulation_dir_osw.rb +0 -4
- data/lib/urbanopt/scenario/version.rb +1 -1
- data/urbanopt-scenario-gem.gemspec +10 -12
- metadata +31 -48
- data/.travis.yml +0 -23
- data/lib/change_log.rb +0 -147
- data/lib/measures/default_feature_reports/tests/USA_CO_Golden-NREL.724666_TMY3.epw +0 -8768
- data/lib/measures/default_feature_reports/tests/default_feature_reports_test.rb +0 -238
- data/lib/measures/default_feature_reports/tests/example_model.osm +0 -4378
@@ -0,0 +1,102 @@
|
|
1
|
+
# *********************************************************************************
|
2
|
+
# URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
|
3
|
+
# contributors. All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without modification,
|
6
|
+
# are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# Redistributions of source code must retain the above copyright notice, this list
|
9
|
+
# of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# Redistributions in binary form must reproduce the above copyright notice, this
|
12
|
+
# list of conditions and the following disclaimer in the documentation and/or other
|
13
|
+
# materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# Neither the name of the copyright holder nor the names of its contributors may be
|
16
|
+
# used to endorse or promote products derived from this software without specific
|
17
|
+
# prior written permission.
|
18
|
+
#
|
19
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
20
|
+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
21
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
22
|
+
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
23
|
+
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
24
|
+
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
25
|
+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
26
|
+
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
27
|
+
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
28
|
+
# OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
|
+
# *********************************************************************************
|
30
|
+
|
31
|
+
require 'json'
|
32
|
+
require 'urbanopt/scenario/default_reports/validator'
|
33
|
+
require 'json-schema'
|
34
|
+
|
35
|
+
module URBANopt
|
36
|
+
module Scenario
|
37
|
+
module DefaultReports
|
38
|
+
##
|
39
|
+
# power_distributio include eletrical power distribution systems information.
|
40
|
+
##
|
41
|
+
class PowerDistribution
|
42
|
+
attr_accessor :under_voltage_hours, :over_voltage_hours # :nodoc:
|
43
|
+
##
|
44
|
+
# PowerDistrinution class intialize all power_distribution attributes:
|
45
|
+
# +:under_voltage_hours+ , +:over_voltage_hours+
|
46
|
+
##
|
47
|
+
# [parameters:]
|
48
|
+
# +hash+ - _Hash_ - A hash which may contain a deserialized power_distribution.
|
49
|
+
##
|
50
|
+
def initialize(hash = {})
|
51
|
+
hash.delete_if { |k, v| v.nil? }
|
52
|
+
hash = defaults.merge(hash)
|
53
|
+
|
54
|
+
@under_voltage_hours = hash[:under_voltage_hours]
|
55
|
+
@over_voltage_hours = hash[:over_voltage_hours]
|
56
|
+
|
57
|
+
# initialize class variables @@validator and @@schema
|
58
|
+
@@validator ||= Validator.new
|
59
|
+
@@schema ||= @@validator.schema
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
# Assigns default values if attribute values do not exist.
|
64
|
+
##
|
65
|
+
def defaults
|
66
|
+
hash = {}
|
67
|
+
hash[:under_voltage_hours] = nil
|
68
|
+
hash[:over_voltage_hours] = nil
|
69
|
+
|
70
|
+
return hash
|
71
|
+
end
|
72
|
+
|
73
|
+
##
|
74
|
+
# Converts to a Hash equivalent for JSON serialization.
|
75
|
+
##
|
76
|
+
# - Exclude attributes with nil values.
|
77
|
+
# - Validate power_distribution hash properties against schema.
|
78
|
+
##
|
79
|
+
def to_hash
|
80
|
+
result = {}
|
81
|
+
result[:under_voltage_hours] = @under_voltage_hours if @under_voltage_hours
|
82
|
+
result[:over_voltage_hours] = @over_voltage_hours if @over_voltage_hours
|
83
|
+
|
84
|
+
# validate power_distribution properties against schema
|
85
|
+
if @@validator.validate(@@schema[:definitions][:PowerDistribution][:properties], result).any?
|
86
|
+
raise "power_distribution properties does not match schema: #{@@validator.validate(@@schema[:definitions][:PowerDistribution][:properties], result)}"
|
87
|
+
end
|
88
|
+
|
89
|
+
return result
|
90
|
+
end
|
91
|
+
|
92
|
+
##
|
93
|
+
# Merges muliple power distribution results together.
|
94
|
+
##
|
95
|
+
# +new_costs+ - _Array_ - An array of ConstructionCost objects.
|
96
|
+
def merge_power_distribition
|
97
|
+
# method to be developed for any attributes to be aggregated or merged
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -44,7 +44,7 @@ module URBANopt
|
|
44
44
|
:number_of_parking_spaces_charging, :parking_footprint_area, :maximum_parking_height, :maximum_number_of_parking_stories,
|
45
45
|
:maximum_number_of_parking_stories_above_ground, :number_of_residential_units, :building_types, :building_type, :maximum_occupancy,
|
46
46
|
:area, :window_area, :north_window_area, :south_window_area, :east_window_area, :west_window_area, :wall_area, :roof_area, :equipment_roof_area,
|
47
|
-
:photovoltaic_roof_area, :available_roof_area, :total_roof_area, :orientation, :aspect_ratio # :nodoc:
|
47
|
+
:photovoltaic_roof_area, :available_roof_area, :total_roof_area, :orientation, :aspect_ratio, :total_construction_cost # :nodoc:
|
48
48
|
# Program class initialize building program attributes: +:site_area+ , +:floor_area+ , +:conditioned_area+ , +:unconditioned_area+ ,
|
49
49
|
# +:footprint_area+ , +:maximum_roof_height, +:maximum_number_of_stories+ , +:maximum_number_of_stories_above_ground+ , +:parking_area+ ,
|
50
50
|
# +:number_of_parking_spaces+ , +:number_of_parking_spaces_charging+ , +:parking_footprint_area+ , +:maximum_parking_height+ , +:maximum_number_of_parking_stories+ ,
|
@@ -81,6 +81,7 @@ module URBANopt
|
|
81
81
|
@roof_area = hash[:roof_area]
|
82
82
|
@orientation = hash[:orientation]
|
83
83
|
@aspect_ratio = hash[:aspect_ratio]
|
84
|
+
@total_construction_cost = hash[:total_construction_cost]
|
84
85
|
|
85
86
|
# initialize class variables @@validator and @@schema
|
86
87
|
@@validator ||= Validator.new
|
@@ -114,6 +115,7 @@ module URBANopt
|
|
114
115
|
hash[:roof_area] = { equipment_roof_area: nil, photovoltaic_roof_area: nil, available_roof_area: nil, total_roof_area: nil }
|
115
116
|
hash[:orientation] = nil
|
116
117
|
hash[:aspect_ratio] = nil
|
118
|
+
hash[:total_construction_cost] = nil
|
117
119
|
return hash
|
118
120
|
end
|
119
121
|
|
@@ -167,6 +169,8 @@ module URBANopt
|
|
167
169
|
result[:orientation] = @orientation if @orientation
|
168
170
|
result[:aspect_ratio] = @aspect_ratio if @aspect_ratio
|
169
171
|
|
172
|
+
result[:total_construction_cost] = @total_construction_cost if @total_construction_cost
|
173
|
+
|
170
174
|
# validate program properties against schema
|
171
175
|
if @@validator.validate(@@schema[:definitions][:Program][:properties], result).any?
|
172
176
|
raise "program properties does not match schema: #{@@validator.validate(@@schema[:definitions][:Program][:properties], result)}"
|
@@ -215,7 +219,6 @@ module URBANopt
|
|
215
219
|
# [parameters:]
|
216
220
|
# +other+ - _Program_ - An object of Program class.
|
217
221
|
##
|
218
|
-
# rubocop:disable Metrics/AbcSize # :nodoc:
|
219
222
|
def add_program(other)
|
220
223
|
@site_area = add_values(@site_area, other.site_area)
|
221
224
|
|
@@ -234,6 +237,7 @@ module URBANopt
|
|
234
237
|
@maximum_number_of_parking_stories = max_value(@maximum_number_of_parking_stories, other.maximum_number_of_parking_stories)
|
235
238
|
@maximum_number_of_parking_stories_above_ground = max_value(maximum_number_of_parking_stories_above_ground, other.maximum_number_of_parking_stories_above_ground)
|
236
239
|
@number_of_residential_units = add_values(@number_of_residential_units, other.number_of_residential_units)
|
240
|
+
@total_construction_cost = add_values(@total_construction_cost, other.total_construction_cost)
|
237
241
|
|
238
242
|
@building_types = other.building_types
|
239
243
|
|
@@ -43,14 +43,14 @@ module URBANopt
|
|
43
43
|
##
|
44
44
|
class ReportingPeriod
|
45
45
|
attr_accessor :id, :name, :multiplier, :start_date, :end_date, :month, :day_of_month, :year, :total_site_energy, :total_source_energy,
|
46
|
-
:net_site_energy, :net_source_energy, :net_utility_cost, :electricity, :natural_gas, :additional_fuel, :district_cooling,
|
47
|
-
:district_heating, :water, :electricity_produced, :end_uses, :energy_production, :photovoltaic,
|
46
|
+
:net_site_energy, :net_source_energy, :total_utility_cost, :net_utility_cost, :utility_costs, :electricity, :natural_gas, :additional_fuel, :district_cooling,
|
47
|
+
:district_heating, :water, :electricity_produced, :end_uses, :energy_production, :photovoltaic,
|
48
48
|
:fuel_type, :total_cost, :usage_cost, :demand_cost, :comfort_result, :time_setpoint_not_met_during_occupied_cooling,
|
49
|
-
:time_setpoint_not_met_during_occupied_heating, :time_setpoint_not_met_during_occupied_hours #:nodoc:
|
49
|
+
: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 #:nodoc:
|
50
50
|
# ReportingPeriod class initializes the reporting period attributes:
|
51
51
|
# +:id+ , +:name+ , +:multiplier+ , +:start_date+ , +:end_date+ , +:month+ , +:day_of_month+ , +:year+ , +:total_site_energy+ , +:total_source_energy+ ,
|
52
|
-
# +:net_site_energy+ , +:net_source_energy+ , +:net_utility_cost+ , +:electricity+ , +:natural_gas+ , +:additional_fuel+ , +:district_cooling+ ,
|
53
|
-
# +:district_heating+ , +:water+ , +:electricity_produced+ , +:end_uses+ , +:energy_production+ , +:photovoltaic+ ,
|
52
|
+
# +:net_site_energy+ , +:net_source_energy+ , +:total_utility_cost , +:net_utility_cost+ , +:utility_costs+ , +:electricity+ , +:natural_gas+ , +:additional_fuel+ , +:district_cooling+ ,
|
53
|
+
# +:district_heating+ , +:water+ , +:electricity_produced+ , +:end_uses+ , +:energy_production+ , +:photovoltaic+ ,
|
54
54
|
# +:fuel_type+ , +:total_cost+ , +:usage_cost+ , +:demand_cost+ , +:comfort_result+ , +:time_setpoint_not_met_during_occupied_cooling+ ,
|
55
55
|
# +:time_setpoint_not_met_during_occupied_heating+ , +:time_setpoint_not_met_during_occupied_hours+
|
56
56
|
##
|
@@ -72,6 +72,7 @@ module URBANopt
|
|
72
72
|
@net_site_energy = hash [:net_site_energy]
|
73
73
|
@net_source_energy = hash [:net_source_energy]
|
74
74
|
@net_utility_cost = hash [:net_utility_cost]
|
75
|
+
@total_utility_cost = hash [:total_utility_cost]
|
75
76
|
@electricity = hash [:electricity]
|
76
77
|
@natural_gas = hash [:natural_gas]
|
77
78
|
@additional_fuel = hash [:additional_fuel]
|
@@ -109,6 +110,7 @@ module URBANopt
|
|
109
110
|
hash [:net_site_energy] = nil
|
110
111
|
hash [:net_source_energy] = nil
|
111
112
|
hash [:net_utility_cost] = nil
|
113
|
+
hash [:total_utility_cost] = nil
|
112
114
|
hash [:electricity] = nil
|
113
115
|
hash [:natural_gas] = nil
|
114
116
|
hash [:additional_fuel] = nil
|
@@ -119,7 +121,8 @@ module URBANopt
|
|
119
121
|
hash[:end_uses] = EndUses.new.to_hash
|
120
122
|
hash[:energy_production] = { electricity_produced: { photovoltaic: nil } }
|
121
123
|
hash[:utility_costs] = [{ fuel_type: nil, total_cost: nil, usage_cost: nil, demand_cost: nil }]
|
122
|
-
hash[:comfort_result] = { time_setpoint_not_met_during_occupied_cooling: nil, time_setpoint_not_met_during_occupied_heating: nil,
|
124
|
+
hash[:comfort_result] = { time_setpoint_not_met_during_occupied_cooling: nil, time_setpoint_not_met_during_occupied_heating: nil,
|
125
|
+
time_setpoint_not_met_during_occupied_hours: nil, hours_out_of_comfort_bounds_PMV: nil, hours_out_of_comfort_bounds_PPD: nil }
|
123
126
|
|
124
127
|
return hash
|
125
128
|
end
|
@@ -143,6 +146,7 @@ module URBANopt
|
|
143
146
|
result[:net_site_energy] = @net_site_energy if @net_site_energy
|
144
147
|
result[:net_source_energy] = @net_source_energy if @net_source_energy
|
145
148
|
result[:net_utility_cost] = @net_utility_cost if @net_utility_cost
|
149
|
+
result[:total_utility_cost] = @total_utility_cost if @total_utility_cost
|
146
150
|
result[:electricity] = @electricity if @electricity
|
147
151
|
result[:natural_gas] = @natural_gas if @natural_gas
|
148
152
|
result[:additional_fuel] = @additional_fuel if @additional_fuel
|
@@ -204,13 +208,13 @@ module URBANopt
|
|
204
208
|
##
|
205
209
|
# +new_period+ - _ReportingPeriod_ - An object of ReportingPeriod class.
|
206
210
|
##
|
207
|
-
# rubocop: disable Metrics/AbcSize
|
208
211
|
def self.merge_reporting_period(existing_period, new_period)
|
209
212
|
# modify the existing_period by summing up the results
|
210
213
|
existing_period.total_site_energy = add_values(existing_period.total_site_energy, new_period.total_site_energy)
|
211
214
|
existing_period.total_source_energy = add_values(existing_period.total_source_energy, new_period.total_source_energy)
|
212
215
|
existing_period.net_source_energy = add_values(existing_period.net_source_energy, new_period.net_source_energy)
|
213
216
|
existing_period.net_utility_cost = add_values(existing_period.net_utility_cost, new_period.net_utility_cost)
|
217
|
+
existing_period.total_utility_cost = add_values(existing_period.total_utility_cost, new_period.total_utility_cost)
|
214
218
|
existing_period.electricity = add_values(existing_period.electricity, new_period.electricity)
|
215
219
|
existing_period.natural_gas = add_values(existing_period.natural_gas, new_period.natural_gas)
|
216
220
|
existing_period.additional_fuel = add_values(existing_period.additional_fuel, new_period.additional_fuel)
|
@@ -230,9 +234,9 @@ module URBANopt
|
|
230
234
|
end
|
231
235
|
|
232
236
|
if existing_period.utility_costs
|
233
|
-
|
237
|
+
# RK: this need to be updated
|
234
238
|
existing_period.utility_costs.each_with_index do |item, i|
|
235
|
-
existing_period.utility_costs[i][:fuel_type] =
|
239
|
+
existing_period.utility_costs[i][:fuel_type] = existing_period.utility_costs[i][:fuel_type]
|
236
240
|
existing_period.utility_costs[i][:total_cost] = add_values(existing_period.utility_costs[i][:total_cost], new_period.utility_costs[i][:total_cost])
|
237
241
|
existing_period.utility_costs[i][:usage_cost] = add_values(existing_period.utility_costs[i][:usage_cost], new_period.utility_costs[i][:usage_cost])
|
238
242
|
existing_period.utility_costs[i][:demand_cost] = add_values(existing_period.utility_costs[i][:demand_cost], new_period.utility_costs[i][:demand_cost])
|
@@ -244,6 +248,8 @@ module URBANopt
|
|
244
248
|
existing_period.comfort_result[:time_setpoint_not_met_during_occupied_cooling] = add_values(existing_period.comfort_result[:time_setpoint_not_met_during_occupied_cooling], new_period.comfort_result[:time_setpoint_not_met_during_occupied_cooling])
|
245
249
|
existing_period.comfort_result[:time_setpoint_not_met_during_occupied_heating] = add_values(existing_period.comfort_result[:time_setpoint_not_met_during_occupied_heating], new_period.comfort_result[:time_setpoint_not_met_during_occupied_heating])
|
246
250
|
existing_period.comfort_result[:time_setpoint_not_met_during_occupied_hours] = add_values(existing_period.comfort_result[:time_setpoint_not_met_during_occupied_hours], new_period.comfort_result[:time_setpoint_not_met_during_occupied_hours])
|
251
|
+
existing_period.comfort_result[:hours_out_of_comfort_bounds_PMV] = add_values(existing_period.comfort_result[:hours_out_of_comfort_bounds_PMV], new_period.comfort_result[:hours_out_of_comfort_bounds_PMV])
|
252
|
+
existing_period.comfort_result[:hours_out_of_comfort_bounds_PPD] = add_values(existing_period.comfort_result[:hours_out_of_comfort_bounds_PPD], new_period.comfort_result[:hours_out_of_comfort_bounds_PPD])
|
247
253
|
end
|
248
254
|
|
249
255
|
return existing_period
|
@@ -78,6 +78,7 @@ module URBANopt
|
|
78
78
|
@timeseries_csv = TimeseriesCSV.new(hash[:timeseries_csv])
|
79
79
|
@location = Location.new(hash[:location])
|
80
80
|
@program = Program.new(hash[:program])
|
81
|
+
@distributed_generation = DistributedGeneration.new(hash[:distributed_generation] || {})
|
81
82
|
|
82
83
|
@construction_costs = []
|
83
84
|
hash[:construction_costs].each do |cc|
|
@@ -95,8 +96,8 @@ module URBANopt
|
|
95
96
|
@feature_reports << FeatureReport.new(fr)
|
96
97
|
end
|
97
98
|
|
98
|
-
@distributed_generation = DistributedGeneration.new(hash[:distributed_generation] || {})
|
99
99
|
@file_name = 'default_scenario_report'
|
100
|
+
|
100
101
|
# initialize class variables @@validator and @@schema
|
101
102
|
@@validator ||= Validator.new
|
102
103
|
@@schema ||= @@validator.schema
|
@@ -142,15 +143,15 @@ module URBANopt
|
|
142
143
|
end
|
143
144
|
|
144
145
|
##
|
145
|
-
# Saves the '
|
146
|
+
# Saves the 'default_scenario_report.json' and 'default_scenario_report.csv' files
|
146
147
|
##
|
147
148
|
# [parameters]:
|
148
|
-
# +file_name+ - _String_ - Assign a name to the saved scenario results file
|
149
|
+
# +file_name+ - _String_ - Assign a name to the saved scenario results file without an extension
|
149
150
|
def save(file_name = 'default_scenario_report')
|
150
151
|
# reassign the initialize local variable @file_name to the file name input.
|
151
152
|
@file_name = file_name
|
152
153
|
|
153
|
-
# save the csv data
|
154
|
+
# save the scenario reports csv and json data
|
154
155
|
old_timeseries_path = nil
|
155
156
|
if !@timeseries_csv.path.nil?
|
156
157
|
old_timeseries_path = @timeseries_csv.path
|
@@ -181,8 +182,14 @@ module URBANopt
|
|
181
182
|
if !old_timeseries_path.nil?
|
182
183
|
@timeseries_csv.path = old_timeseries_path
|
183
184
|
else
|
184
|
-
@timeseries_csv.path = File.join(@directory_name, '
|
185
|
+
@timeseries_csv.path = File.join(@directory_name, file_name + '.csv')
|
185
186
|
end
|
187
|
+
|
188
|
+
# save the feature reports csv and json data
|
189
|
+
# @feature_reports.each do |feature_report|
|
190
|
+
# feature_report.save_feature_report()
|
191
|
+
# end
|
192
|
+
|
186
193
|
return true
|
187
194
|
end
|
188
195
|
|
@@ -243,14 +250,24 @@ module URBANopt
|
|
243
250
|
# +feature_report+ - _FeatureReport_ - An object of FeatureReport class.
|
244
251
|
##
|
245
252
|
def add_feature_report(feature_report)
|
246
|
-
if
|
253
|
+
# check if the timesteps_per_hour are identical
|
254
|
+
if @timesteps_per_hour.nil? || @timesteps_per_hour == ''
|
247
255
|
@timesteps_per_hour = feature_report.timesteps_per_hour
|
248
256
|
else
|
249
|
-
if feature_report.timesteps_per_hour != @timesteps_per_hour
|
257
|
+
if feature_report.timesteps_per_hour.is_a?(Integer) && feature_report.timesteps_per_hour != @timesteps_per_hour
|
250
258
|
raise "FeatureReport timesteps_per_hour = '#{feature_report.timesteps_per_hour}' does not match scenario timesteps_per_hour '#{@timesteps_per_hour}'"
|
251
259
|
end
|
252
260
|
end
|
253
261
|
|
262
|
+
# check if first report_report_datetime are identical.
|
263
|
+
if @timeseries_csv.first_report_datetime.nil? || @timeseries_csv.first_report_datetime == ''
|
264
|
+
@timeseries_csv.first_report_datetime = feature_report.timeseries_csv.first_report_datetime
|
265
|
+
else
|
266
|
+
if feature_report.timeseries_csv.first_report_datetime != @timeseries_csv.first_report_datetime
|
267
|
+
raise "first_report_datetime '#{@first_report_datetime}' does not match other.first_report_datetime '#{feature_report.timeseries_csv.first_report_datetime}'"
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
254
271
|
# check that we have not already added this feature
|
255
272
|
id = feature_report.id
|
256
273
|
@feature_reports.each do |existing_feature_report|
|
@@ -18,17 +18,16 @@ The URBANopt Scenario Gem includes functionality for defining scenarios, running
|
|
18
18
|
|
19
19
|
| output | unit |
|
20
20
|
| -----------------------------------------| ------- |
|
21
|
-
| Electricity:Facility |
|
22
|
-
| ElectricityProduced:Facility |
|
23
|
-
| Gas:Facility |
|
24
|
-
| DistrictCooling:Facility |
|
25
|
-
| DistrictHeating:Facility |
|
21
|
+
| Electricity:Facility | kWh |
|
22
|
+
| ElectricityProduced:Facility | kWh |
|
23
|
+
| Gas:Facility | kBtu |
|
24
|
+
| DistrictCooling:Facility | kWh |
|
25
|
+
| DistrictHeating:Facility | kWh |
|
26
26
|
| District Cooling Chilled Water Rate | GPM |
|
27
|
-
| District Cooling Mass Flow Rate |
|
28
|
-
| District Cooling Inlet Temperature | °
|
29
|
-
| District Cooling Outlet Temperature | °
|
27
|
+
| District Cooling Mass Flow Rate | kg/s |
|
28
|
+
| District Cooling Inlet Temperature | °C |
|
29
|
+
| District Cooling Outlet Temperature | °C |
|
30
30
|
| District Heating Hot Water Rate | GPM |
|
31
|
-
| District Heating Mass Flow Rate |
|
32
|
-
| District Heating Inlet Temperature | °
|
33
|
-
| District Heating Outlet Temperature | °
|
34
|
-
| Electricity:Grid:ToLoad | kWh. |
|
31
|
+
| District Heating Mass Flow Rate | kg/s |
|
32
|
+
| District Heating Inlet Temperature | °C |
|
33
|
+
| District Heating Outlet Temperature | °C |
|
@@ -1,13 +1,34 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
1
|
+
Datetime
|
2
|
+
Electricity:Facility
|
3
|
+
ElectricityProduced:Facility
|
4
|
+
Gas:Facility
|
5
|
+
Cooling:Electricity
|
6
|
+
Heating:Electricity
|
7
|
+
InteriorLights:Electricity
|
8
|
+
ExteriorLights:Electricity
|
9
|
+
InteriorEquipment:Electricity
|
10
|
+
Fans:Electricity
|
11
|
+
Pumps:Electricity
|
12
|
+
WaterSystems:Electricity
|
13
|
+
HeatRejection:Electricity
|
14
|
+
HeatRejection:Gas
|
15
|
+
Heating:Gas
|
16
|
+
WaterSystems:Gas
|
17
|
+
InteriorEquipment:Gas
|
18
|
+
DistrictCooling:Facility
|
19
|
+
DistrictHeating:Facility
|
20
|
+
District Cooling Chilled Water Rate
|
21
|
+
District Cooling Mass Flow Rate
|
22
|
+
District Cooling Inlet Temperature
|
23
|
+
District Cooling Outlet Temperature
|
24
|
+
District Heating Hot Water Rate
|
25
|
+
District Heating Mass Flow Rate
|
26
|
+
District Heating Inlet Temperature
|
13
27
|
District Heating Outlet Temperature
|
28
|
+
Net Electric Energy
|
29
|
+
Electricity:Facility Power
|
30
|
+
ElectricityProduced:Facility Power
|
31
|
+
Electricity:Facility Apparent Power
|
32
|
+
ElectricityProduced:Facility Apparent Power
|
33
|
+
Net Power
|
34
|
+
Net Apparent Power
|
@@ -64,7 +64,6 @@
|
|
64
64
|
"distributed_generation": {
|
65
65
|
"$ref": "#/definitions/DistributedGeneration"
|
66
66
|
}
|
67
|
-
|
68
67
|
},
|
69
68
|
"required": [
|
70
69
|
"id",
|
@@ -83,42 +82,42 @@
|
|
83
82
|
"type": "object",
|
84
83
|
"properties": {
|
85
84
|
"lcc_us_dollars": {
|
86
|
-
"
|
87
|
-
"
|
85
|
+
"description": "Optimal lifecycle cost",
|
86
|
+
"type": "number"
|
88
87
|
},
|
89
88
|
"npv_us_dollars": {
|
90
|
-
"
|
91
|
-
"
|
89
|
+
"description": "Net present value of savings realized by the project",
|
90
|
+
"type": "number"
|
92
91
|
},
|
93
92
|
"year_one_energy_cost_us_dollars": {
|
94
|
-
"
|
95
|
-
"
|
93
|
+
"description": "Optimal year one utility energy cost",
|
94
|
+
"type": "number"
|
96
95
|
},
|
97
96
|
"year_one_demand_cost_us_dollars": {
|
98
|
-
"
|
99
|
-
"
|
97
|
+
"description": "Optimal year one utility demand cost",
|
98
|
+
"type": "number"
|
100
99
|
},
|
101
100
|
"year_one_bill_us_dollars": {
|
102
|
-
"
|
103
|
-
"
|
101
|
+
"description": "Optimal year one utility bill",
|
102
|
+
"type": "number"
|
104
103
|
},
|
105
104
|
"total_energy_cost_us_dollars": {
|
106
|
-
"
|
107
|
-
"
|
105
|
+
"description": "Total utility energy cost over the lifecycle, after-tax",
|
106
|
+
"type": "number"
|
108
107
|
},
|
109
|
-
"SolarPV"
|
108
|
+
"SolarPV": {
|
110
109
|
"$ref": "#/definitions/SolarPV"
|
111
110
|
},
|
112
|
-
"Wind"
|
111
|
+
"Wind": {
|
113
112
|
"$ref": "#/definitions/Wind"
|
114
113
|
},
|
115
|
-
"Generator"
|
114
|
+
"Generator": {
|
116
115
|
"$ref": "#/definitions/Generator"
|
117
116
|
},
|
118
|
-
"Storage"
|
117
|
+
"Storage": {
|
119
118
|
"$ref": "#/definitions/Storage"
|
120
119
|
}
|
121
|
-
|
120
|
+
}
|
122
121
|
},
|
123
122
|
"SolarPV": {
|
124
123
|
"type": "object",
|
@@ -214,6 +213,9 @@
|
|
214
213
|
},
|
215
214
|
"distributed_generation": {
|
216
215
|
"$ref": "#/definitions/DistributedGeneration"
|
216
|
+
},
|
217
|
+
"power_distribution": {
|
218
|
+
"$ref": "#/definitions/PowerDistribution"
|
217
219
|
}
|
218
220
|
},
|
219
221
|
"required": [
|
@@ -271,10 +273,20 @@
|
|
271
273
|
"description": "Net source energy (kBtu)",
|
272
274
|
"type": "number"
|
273
275
|
},
|
276
|
+
"total_utility_cost": {
|
277
|
+
"description": "Total utility cost",
|
278
|
+
"type": "number"
|
279
|
+
},
|
274
280
|
"net_utility_cost": {
|
275
|
-
"description": "
|
281
|
+
"description": "Net utility cost for reporting period includes generation",
|
276
282
|
"type": "number"
|
277
283
|
},
|
284
|
+
"utility_costs": {
|
285
|
+
"type": "array",
|
286
|
+
"items": {
|
287
|
+
"$ref": "#/definitions/UtilityCost"
|
288
|
+
}
|
289
|
+
},
|
278
290
|
"electricity": {
|
279
291
|
"description": "Sum of all electricity used, does not include electricity produced (kWh)",
|
280
292
|
"type": "number"
|
@@ -322,12 +334,6 @@
|
|
322
334
|
},
|
323
335
|
"additionalProperties": false
|
324
336
|
},
|
325
|
-
"utility_costs": {
|
326
|
-
"type": "array",
|
327
|
-
"items": {
|
328
|
-
"$ref": "#/definitions/UtilityCost"
|
329
|
-
}
|
330
|
-
},
|
331
337
|
"comfort_result": {
|
332
338
|
"$ref": "#/definitions/ComfortResult"
|
333
339
|
}
|
@@ -436,6 +442,12 @@
|
|
436
442
|
"time_setpoint_not_met_during_occupied_hours": {
|
437
443
|
"description": "(hrs)",
|
438
444
|
"type": "number"
|
445
|
+
},
|
446
|
+
"hours_out_of_comfort_bounds_PMV": {
|
447
|
+
"type": "number"
|
448
|
+
},
|
449
|
+
"hours_out_of_comfort_bounds_PPD": {
|
450
|
+
"type": "number"
|
439
451
|
}
|
440
452
|
},
|
441
453
|
"additionalProperties": false
|
@@ -709,6 +721,10 @@
|
|
709
721
|
"aspect_ratio": {
|
710
722
|
"description": "Ratio of longest to shortest axis",
|
711
723
|
"type": "number"
|
724
|
+
},
|
725
|
+
"total_construction_cost": {
|
726
|
+
"description": "total construction cost calculated from the defined cost per floor area ($)",
|
727
|
+
"type": "number"
|
712
728
|
}
|
713
729
|
},
|
714
730
|
"required": [
|
@@ -825,6 +841,17 @@
|
|
825
841
|
"column_names"
|
826
842
|
],
|
827
843
|
"additionalProperties": false
|
844
|
+
},
|
845
|
+
"PowerDistribution": {
|
846
|
+
"type": "object",
|
847
|
+
"properties": {
|
848
|
+
"over_voltage_hours": {
|
849
|
+
"type": "number"
|
850
|
+
},
|
851
|
+
"under_voltage_hours": {
|
852
|
+
"type": "number"
|
853
|
+
}
|
854
|
+
}
|
828
855
|
}
|
829
856
|
}
|
830
857
|
}
|