openstudio-extension 0.7.1 → 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/.gitignore +1 -0
- data/CHANGELOG.md +14 -0
- data/LICENSE.md +1 -1
- data/README.md +2 -0
- data/lib/openstudio/extension/runner.rb +12 -8
- data/lib/openstudio/extension/runner_config.rb +33 -6
- data/lib/openstudio/extension/version.rb +1 -1
- data/openstudio-extension.gemspec +6 -6
- metadata +15 -66
- data/lib/openstudio/extension/core/CreateResults.rb +0 -1033
- data/lib/openstudio/extension/core/check_air_sys_temps.rb +0 -160
- data/lib/openstudio/extension/core/check_calibration.rb +0 -125
- data/lib/openstudio/extension/core/check_cond_zns.rb +0 -54
- data/lib/openstudio/extension/core/check_domestic_hot_water.rb +0 -304
- data/lib/openstudio/extension/core/check_envelope_conductance.rb +0 -423
- data/lib/openstudio/extension/core/check_eui_by_end_use.rb +0 -132
- data/lib/openstudio/extension/core/check_eui_reasonableness.rb +0 -105
- data/lib/openstudio/extension/core/check_fan_pwr.rb +0 -68
- data/lib/openstudio/extension/core/check_internal_loads.rb +0 -363
- data/lib/openstudio/extension/core/check_mech_sys_capacity.rb +0 -196
- data/lib/openstudio/extension/core/check_mech_sys_efficiency.rb +0 -296
- data/lib/openstudio/extension/core/check_mech_sys_part_load_eff.rb +0 -434
- data/lib/openstudio/extension/core/check_mech_sys_type.rb +0 -109
- data/lib/openstudio/extension/core/check_part_loads.rb +0 -421
- data/lib/openstudio/extension/core/check_placeholder.rb +0 -45
- data/lib/openstudio/extension/core/check_plant_cap.rb +0 -93
- data/lib/openstudio/extension/core/check_plant_temps.rb +0 -129
- data/lib/openstudio/extension/core/check_plenum_loads.rb +0 -57
- data/lib/openstudio/extension/core/check_pump_pwr.rb +0 -78
- data/lib/openstudio/extension/core/check_sch_coord.rb +0 -211
- data/lib/openstudio/extension/core/check_schedules.rb +0 -281
- data/lib/openstudio/extension/core/check_simultaneous_heating_and_cooling.rb +0 -128
- data/lib/openstudio/extension/core/check_supply_air_and_thermostat_temp_difference.rb +0 -118
- data/lib/openstudio/extension/core/check_weather_files.rb +0 -102
- data/lib/openstudio/extension/core/deer_vintages.rb +0 -281
- data/lib/openstudio/extension/core/os_lib_aedg_measures.rb +0 -461
- data/lib/openstudio/extension/core/os_lib_constructions.rb +0 -353
- data/lib/openstudio/extension/core/os_lib_geometry.rb +0 -1169
- data/lib/openstudio/extension/core/os_lib_helper_methods.rb +0 -383
- data/lib/openstudio/extension/core/os_lib_hvac.rb +0 -2163
- data/lib/openstudio/extension/core/os_lib_lighting_and_equipment.rb +0 -184
- data/lib/openstudio/extension/core/os_lib_model_generation.rb +0 -3584
- data/lib/openstudio/extension/core/os_lib_model_simplification.rb +0 -1019
- data/lib/openstudio/extension/core/os_lib_outdoorair_and_infiltration.rb +0 -135
- data/lib/openstudio/extension/core/os_lib_reporting_qaqc.rb +0 -170
- data/lib/openstudio/extension/core/os_lib_schedules.rb +0 -933
@@ -1,1033 +0,0 @@
|
|
1
|
-
# *******************************************************************************
|
2
|
-
# OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC.
|
3
|
-
# See also https://openstudio.net/license
|
4
|
-
# *******************************************************************************
|
5
|
-
|
6
|
-
module OsLib_CreateResults
|
7
|
-
# Reports out the detailed simulation results needed by EDAPT.
|
8
|
-
# Results are output as both OpenStudio::Attributes (for OpenStudio 1.X)
|
9
|
-
# and runner.registerValue (for OpenStudio 2.X).
|
10
|
-
# @param skip_weekends [Bool] if true, weekends will not be included in the peak demand window
|
11
|
-
# @param skip_holidays [Bool] if true, holidays will not be included in the peak demand window
|
12
|
-
# @param start_mo [String] the start month for the peak demand window
|
13
|
-
# @param start_day [Integer] the start day for the peak demand window
|
14
|
-
# @param start_hr [Integer] the start hour for the peak demand window, using 24-hr clock
|
15
|
-
# @param end_mo [String] the end month for the peak demand window
|
16
|
-
# @param end_day [Integer] the end day for the peak demand window
|
17
|
-
# @param end_hr [Integer] the end hour for the peak demand window, using 24-hr clock
|
18
|
-
# @param electricity_consumption_tou_periods [Array<Hash>] optional array of hashes to add
|
19
|
-
# time-of-use electricity consumption values to the annual consumption information.
|
20
|
-
# Periods may overlap, but should be listed in the order in which they must be checked,
|
21
|
-
# where the value will be assigned to the first encountered period it falls into.
|
22
|
-
# An example hash looks like this:
|
23
|
-
# {
|
24
|
-
# 'tou_name' => 'system_peak',
|
25
|
-
# 'tou_id' => 1,
|
26
|
-
# 'skip_weekends' => true,
|
27
|
-
# 'skip_holidays' => true,
|
28
|
-
# 'start_mo' => 'July',
|
29
|
-
# 'start_day' => 1,
|
30
|
-
# 'start_hr' => 14,
|
31
|
-
# 'end_mo' => 'August',
|
32
|
-
# 'end_day' => 31,
|
33
|
-
# 'end_hr' => 18
|
34
|
-
# }
|
35
|
-
# @return [OpenStudio::AttributeVector] a vector of results needed by EDAPT
|
36
|
-
def create_results(skip_weekends = true,
|
37
|
-
skip_holidays = true,
|
38
|
-
start_mo = 'June',
|
39
|
-
start_day = 1,
|
40
|
-
start_hr = 14,
|
41
|
-
end_mo = 'September',
|
42
|
-
end_day = 30,
|
43
|
-
end_hr = 18,
|
44
|
-
electricity_consumption_tou_periods = [])
|
45
|
-
|
46
|
-
# get the current version of OS being used to determine if sql query
|
47
|
-
# changes are needed (for when E+ changes).
|
48
|
-
os_version = OpenStudio::VersionString.new(OpenStudio.openStudioVersion)
|
49
|
-
|
50
|
-
# create an attribute vector to hold results
|
51
|
-
result_elems = OpenStudio::AttributeVector.new
|
52
|
-
|
53
|
-
# floor_area
|
54
|
-
floor_area_query = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='AnnualBuildingUtilityPerformanceSummary' AND ReportForString='Entire Facility' AND TableName='Building Area' AND RowName='Net Conditioned Building Area' AND ColumnName='Area' AND Units='m2'"
|
55
|
-
floor_area = @sql.execAndReturnFirstDouble(floor_area_query)
|
56
|
-
if floor_area.is_initialized
|
57
|
-
result_elems << OpenStudio::Attribute.new('floor_area', floor_area.get, 'm^2')
|
58
|
-
@runner.registerValue('charsfloor_area', floor_area.get, 'm^2')
|
59
|
-
else
|
60
|
-
@runner.registerWarning('Building floor area not found')
|
61
|
-
return false
|
62
|
-
end
|
63
|
-
|
64
|
-
# inflation approach
|
65
|
-
inf_appr_query = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='Life-Cycle Cost Report' AND ReportForString='Entire Facility' AND TableName='Life-Cycle Cost Parameters' AND RowName='Inflation Approach' AND ColumnName='Value'"
|
66
|
-
inf_appr = @sql.execAndReturnFirstString(inf_appr_query)
|
67
|
-
if inf_appr.is_initialized
|
68
|
-
if inf_appr.get == 'ConstantDollar'
|
69
|
-
inf_appr = 'Constant Dollar'
|
70
|
-
elsif inf_appr.get == 'CurrentDollar'
|
71
|
-
inf_appr = 'Current Dollar'
|
72
|
-
else
|
73
|
-
@runner.registerError("Inflation approach: #{inf_appr.get} not recognized")
|
74
|
-
return OpenStudio::Attribute.new('report', result_elems)
|
75
|
-
end
|
76
|
-
@runner.registerInfo("Inflation approach = #{inf_appr}")
|
77
|
-
else
|
78
|
-
@runner.registerError('Could not determine inflation approach used')
|
79
|
-
return OpenStudio::Attribute.new('report', result_elems)
|
80
|
-
end
|
81
|
-
|
82
|
-
# base year
|
83
|
-
base_yr_query = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='Life-Cycle Cost Report' AND ReportForString='Entire Facility' AND TableName='Life-Cycle Cost Parameters' AND RowName='Base Date' AND ColumnName='Value'"
|
84
|
-
base_yr = @sql.execAndReturnFirstString(base_yr_query)
|
85
|
-
if base_yr.is_initialized
|
86
|
-
if base_yr.get =~ /\d\d\d\d/
|
87
|
-
base_yr = base_yr.get.match(/\d\d\d\d/)[0].to_f
|
88
|
-
else
|
89
|
-
@runner.registerError("Could not determine the analysis start year from #{base_yr.get}")
|
90
|
-
return OpenStudio::Attribute.new('report', result_elems)
|
91
|
-
end
|
92
|
-
else
|
93
|
-
@runner.registerError('Could not determine analysis start year')
|
94
|
-
return OpenStudio::Attribute.new('report', result_elems)
|
95
|
-
end
|
96
|
-
|
97
|
-
# analysis length
|
98
|
-
length_yrs_query = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='Life-Cycle Cost Report' AND ReportForString='Entire Facility' AND TableName='Life-Cycle Cost Parameters' AND RowName='Length of Study Period in Years' AND ColumnName='Value'"
|
99
|
-
length_yrs = @sql.execAndReturnFirstInt(length_yrs_query)
|
100
|
-
if length_yrs.is_initialized
|
101
|
-
@runner.registerInfo "Analysis length = #{length_yrs.get} yrs"
|
102
|
-
length_yrs = length_yrs.get
|
103
|
-
else
|
104
|
-
@runner.registerError('Could not determine analysis length')
|
105
|
-
return OpenStudio::Attribute.new('report', result_elems)
|
106
|
-
end
|
107
|
-
|
108
|
-
# cash flows
|
109
|
-
cash_flow_elems = OpenStudio::AttributeVector.new
|
110
|
-
|
111
|
-
# setup a vector for each type of cash flow
|
112
|
-
cap_cash_flow_elems = OpenStudio::AttributeVector.new
|
113
|
-
om_cash_flow_elems = OpenStudio::AttributeVector.new
|
114
|
-
energy_cash_flow_elems = OpenStudio::AttributeVector.new
|
115
|
-
water_cash_flow_elems = OpenStudio::AttributeVector.new
|
116
|
-
tot_cash_flow_elems = OpenStudio::AttributeVector.new
|
117
|
-
|
118
|
-
# add the type to the element
|
119
|
-
cap_cash_flow_elems << OpenStudio::Attribute.new('type', "#{inf_appr} Capital Costs")
|
120
|
-
om_cash_flow_elems << OpenStudio::Attribute.new('type', "#{inf_appr} Operating Costs")
|
121
|
-
energy_cash_flow_elems << OpenStudio::Attribute.new('type', "#{inf_appr} Energy Costs")
|
122
|
-
water_cash_flow_elems << OpenStudio::Attribute.new('type', "#{inf_appr} Water Costs")
|
123
|
-
tot_cash_flow_elems << OpenStudio::Attribute.new('type', "#{inf_appr} Total Costs")
|
124
|
-
|
125
|
-
@runner.registerValue('cash_flows_capital_type', "#{inf_appr} Capital Costs")
|
126
|
-
@runner.registerValue('cash_flows_operating_type', "#{inf_appr} Operating Costs")
|
127
|
-
@runner.registerValue('cash_flows_energy_type', "#{inf_appr} Energy Costs")
|
128
|
-
@runner.registerValue('cash_flows_water_type', "#{inf_appr} Water Costs")
|
129
|
-
@runner.registerValue('cash_flows_total_type', "#{inf_appr} Total Costs")
|
130
|
-
|
131
|
-
# record the cash flow in these hashes
|
132
|
-
cap_cash_flow = {}
|
133
|
-
om_cash_flow = {}
|
134
|
-
energy_cash_flow = {}
|
135
|
-
water_cash_flow = {}
|
136
|
-
tot_cash_flow = {}
|
137
|
-
|
138
|
-
# loop through each year and record the cash flow
|
139
|
-
for i in 0..(length_yrs - 1) do
|
140
|
-
new_yr = base_yr + i
|
141
|
-
|
142
|
-
yr = nil
|
143
|
-
if os_version > OpenStudio::VersionString.new('1.5.3')
|
144
|
-
yr = "January #{new_yr.round}"
|
145
|
-
else
|
146
|
-
yr = "January #{new_yr.round}"
|
147
|
-
end
|
148
|
-
|
149
|
-
ann_cap_cash = 0.0
|
150
|
-
ann_om_cash = 0.0
|
151
|
-
ann_energy_cash = 0.0
|
152
|
-
ann_water_cash = 0.0
|
153
|
-
ann_tot_cash = 0.0
|
154
|
-
|
155
|
-
# capital cash flow
|
156
|
-
cap_cash_query = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='Life-Cycle Cost Report' AND ReportForString='Entire Facility' AND TableName='Capital Cash Flow by Category (Without Escalation)' AND RowName='#{yr}' AND ColumnName='Total'"
|
157
|
-
cap_cash = @sql.execAndReturnFirstDouble(cap_cash_query)
|
158
|
-
if cap_cash.is_initialized
|
159
|
-
ann_cap_cash += cap_cash.get
|
160
|
-
ann_tot_cash += cap_cash.get
|
161
|
-
end
|
162
|
-
|
163
|
-
# o&m cash flow (excluding utility costs)
|
164
|
-
om_types = ['Maintenance', 'Repair', 'Operation', 'Replacement', 'MinorOverhaul', 'MajorOverhaul', 'OtherOperational']
|
165
|
-
om_types.each do |om_type|
|
166
|
-
om_cash_query = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='Life-Cycle Cost Report' AND ReportForString='Entire Facility' AND TableName='Operating Cash Flow by Category (Without Escalation)' AND RowName='#{yr}' AND ColumnName='#{om_type}'"
|
167
|
-
om_cash = @sql.execAndReturnFirstDouble(om_cash_query)
|
168
|
-
if om_cash.is_initialized
|
169
|
-
ann_om_cash += om_cash.get
|
170
|
-
ann_tot_cash += om_cash.get
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
# energy cash flow
|
175
|
-
energy_cash_query = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='Life-Cycle Cost Report' AND ReportForString='Entire Facility' AND TableName='Operating Cash Flow by Category (Without Escalation)' AND RowName='#{yr}' AND ColumnName='Energy'"
|
176
|
-
energy_cash = @sql.execAndReturnFirstDouble(energy_cash_query)
|
177
|
-
if energy_cash.is_initialized
|
178
|
-
ann_energy_cash += energy_cash.get
|
179
|
-
ann_tot_cash += energy_cash.get
|
180
|
-
end
|
181
|
-
|
182
|
-
# water cash flow
|
183
|
-
water_cash_query = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='Life-Cycle Cost Report' AND ReportForString='Entire Facility' AND TableName='Operating Cash Flow by Category (Without Escalation)' AND RowName='#{yr}' AND ColumnName='Water'"
|
184
|
-
water_cash = @sql.execAndReturnFirstDouble(water_cash_query)
|
185
|
-
if water_cash.is_initialized
|
186
|
-
ann_water_cash += water_cash.get
|
187
|
-
ann_tot_cash += water_cash.get
|
188
|
-
end
|
189
|
-
|
190
|
-
# log the values for this year
|
191
|
-
cap_cash_flow[yr] = ann_cap_cash
|
192
|
-
om_cash_flow[yr] = ann_om_cash
|
193
|
-
energy_cash_flow[yr] = ann_energy_cash
|
194
|
-
water_cash_flow[yr] = ann_water_cash
|
195
|
-
tot_cash_flow[yr] = ann_tot_cash
|
196
|
-
|
197
|
-
cap_cash_flow_elems << OpenStudio::Attribute.new('year', ann_cap_cash, 'dollars')
|
198
|
-
om_cash_flow_elems << OpenStudio::Attribute.new('year', ann_om_cash, 'dollars')
|
199
|
-
energy_cash_flow_elems << OpenStudio::Attribute.new('year', ann_energy_cash, 'dollars')
|
200
|
-
water_cash_flow_elems << OpenStudio::Attribute.new('year', ann_water_cash, 'dollars')
|
201
|
-
tot_cash_flow_elems << OpenStudio::Attribute.new('year', ann_tot_cash, 'dollars')
|
202
|
-
|
203
|
-
@runner.registerValue("cash_flows_capital_year_#{i + 1}", ann_cap_cash, 'dollars')
|
204
|
-
@runner.registerValue("cash_flows_operating_year_#{i + 1}", ann_om_cash, 'dollars')
|
205
|
-
@runner.registerValue("cash_flows_energy_year_#{i + 1}", ann_energy_cash, 'dollars')
|
206
|
-
@runner.registerValue("cash_flows_water_year_#{i + 1}", ann_water_cash, 'dollars')
|
207
|
-
@runner.registerValue("cash_flows_total_year_#{i + 1}", ann_tot_cash, 'dollars')
|
208
|
-
|
209
|
-
end # next year
|
210
|
-
|
211
|
-
# end cash flows
|
212
|
-
cash_flow_elems << OpenStudio::Attribute.new('cash_flow', cap_cash_flow_elems)
|
213
|
-
cash_flow_elems << OpenStudio::Attribute.new('cash_flow', om_cash_flow_elems)
|
214
|
-
cash_flow_elems << OpenStudio::Attribute.new('cash_flow', energy_cash_flow_elems)
|
215
|
-
cash_flow_elems << OpenStudio::Attribute.new('cash_flow', water_cash_flow_elems)
|
216
|
-
cash_flow_elems << OpenStudio::Attribute.new('cash_flow', tot_cash_flow_elems)
|
217
|
-
result_elems << OpenStudio::Attribute.new('cash_flows', cash_flow_elems)
|
218
|
-
|
219
|
-
# list of all end uses in OpenStudio
|
220
|
-
end_use_cat_types = []
|
221
|
-
OpenStudio::EndUseCategoryType.getValues.each do |end_use_val|
|
222
|
-
end_use_cat_types << OpenStudio::EndUseCategoryType.new(end_use_val)
|
223
|
-
end
|
224
|
-
|
225
|
-
# list of all end use fule types in OpenStudio
|
226
|
-
end_use_fuel_types = []
|
227
|
-
OpenStudio::EndUseFuelType.getValues.each do |end_use_fuel_type_val|
|
228
|
-
end_use_fuel_types << OpenStudio::EndUseFuelType.new(end_use_fuel_type_val)
|
229
|
-
end
|
230
|
-
|
231
|
-
# list of the 12 months of the year in OpenStudio
|
232
|
-
months = []
|
233
|
-
OpenStudio::MonthOfYear.getValues.each do |month_of_year_val|
|
234
|
-
if (month_of_year_val >= 1) && (month_of_year_val <= 12)
|
235
|
-
months << OpenStudio::MonthOfYear.new(month_of_year_val)
|
236
|
-
end
|
237
|
-
end
|
238
|
-
|
239
|
-
# map each end use category type to the name that will be used in the xml
|
240
|
-
end_use_map = {
|
241
|
-
OpenStudio::EndUseCategoryType.new('Heating').value => 'heating',
|
242
|
-
OpenStudio::EndUseCategoryType.new('Cooling').value => 'cooling',
|
243
|
-
OpenStudio::EndUseCategoryType.new('InteriorLights').value => 'lighting_interior',
|
244
|
-
OpenStudio::EndUseCategoryType.new('ExteriorLights').value => 'lighting_exterior',
|
245
|
-
OpenStudio::EndUseCategoryType.new('InteriorEquipment').value => 'equipment_interior',
|
246
|
-
OpenStudio::EndUseCategoryType.new('ExteriorEquipment').value => 'equipment_exterior',
|
247
|
-
OpenStudio::EndUseCategoryType.new('Fans').value => 'fans',
|
248
|
-
OpenStudio::EndUseCategoryType.new('Pumps').value => 'pumps',
|
249
|
-
OpenStudio::EndUseCategoryType.new('HeatRejection').value => 'heat_rejection',
|
250
|
-
OpenStudio::EndUseCategoryType.new('Humidifier').value => 'humidification',
|
251
|
-
OpenStudio::EndUseCategoryType.new('HeatRecovery').value => 'heat_recovery',
|
252
|
-
OpenStudio::EndUseCategoryType.new('WaterSystems').value => 'water_systems',
|
253
|
-
OpenStudio::EndUseCategoryType.new('Refrigeration').value => 'refrigeration',
|
254
|
-
OpenStudio::EndUseCategoryType.new('Generators').value => 'generators'
|
255
|
-
}
|
256
|
-
|
257
|
-
# map each fuel type in EndUseFuelTypes to a specific FuelTypes
|
258
|
-
fuel_type_map = {
|
259
|
-
OpenStudio::EndUseFuelType.new('Electricity').value => OpenStudio::FuelType.new('Electricity'),
|
260
|
-
OpenStudio::EndUseFuelType.new('Gas').value => OpenStudio::FuelType.new('Gas'),
|
261
|
-
OpenStudio::EndUseFuelType.new('AdditionalFuel').value => OpenStudio::FuelType.new('Diesel'), # TODO: add other fuel types
|
262
|
-
OpenStudio::EndUseFuelType.new('DistrictCooling').value => OpenStudio::FuelType.new('DistrictCooling'),
|
263
|
-
OpenStudio::EndUseFuelType.new('DistrictHeating').value => OpenStudio::FuelType.new('DistrictHeating'),
|
264
|
-
OpenStudio::EndUseFuelType.new('Water').value => OpenStudio::FuelType.new('Water')
|
265
|
-
}
|
266
|
-
|
267
|
-
# map each fuel type in EndUseFuelTypes to a specific FuelTypes
|
268
|
-
fuel_type_alias_map = {
|
269
|
-
OpenStudio::EndUseFuelType.new('Electricity').value => 'electricity',
|
270
|
-
OpenStudio::EndUseFuelType.new('Gas').value => 'gas',
|
271
|
-
OpenStudio::EndUseFuelType.new('AdditionalFuel').value => 'other_energy',
|
272
|
-
OpenStudio::EndUseFuelType.new('DistrictCooling').value => 'district_cooling',
|
273
|
-
OpenStudio::EndUseFuelType.new('DistrictHeating').value => 'district_heating',
|
274
|
-
OpenStudio::EndUseFuelType.new('Water').value => 'water'
|
275
|
-
}
|
276
|
-
|
277
|
-
# annual "annual"
|
278
|
-
annual_elems = OpenStudio::AttributeVector.new
|
279
|
-
|
280
|
-
# consumption "consumption"
|
281
|
-
cons_elems = OpenStudio::AttributeVector.new
|
282
|
-
|
283
|
-
# electricity
|
284
|
-
electricity = @sql.electricityTotalEndUses
|
285
|
-
if electricity.is_initialized
|
286
|
-
cons_elems << OpenStudio::Attribute.new('electricity', electricity.get, 'GJ')
|
287
|
-
@runner.registerValue('annual_consumption_electricity', electricity.get, 'GJ')
|
288
|
-
else
|
289
|
-
cons_elems << OpenStudio::Attribute.new('electricity', 0.0, 'GJ')
|
290
|
-
@runner.registerValue('annual_consumption_electricity', 0.0, 'GJ')
|
291
|
-
end
|
292
|
-
|
293
|
-
# gas
|
294
|
-
gas = @sql.naturalGasTotalEndUses
|
295
|
-
if gas.is_initialized
|
296
|
-
cons_elems << OpenStudio::Attribute.new('gas', gas.get, 'GJ')
|
297
|
-
@runner.registerValue('annual_consumption_gas', gas.get, 'GJ')
|
298
|
-
else
|
299
|
-
cons_elems << OpenStudio::Attribute.new('gas', 0.0, 'GJ')
|
300
|
-
@runner.registerValue('annual_consumption_gas', 0.0, 'GJ')
|
301
|
-
end
|
302
|
-
|
303
|
-
# other_energy
|
304
|
-
other_energy = @sql.otherFuelTotalEndUses
|
305
|
-
if other_energy.is_initialized
|
306
|
-
cons_elems << OpenStudio::Attribute.new('other_energy', other_energy.get, 'GJ')
|
307
|
-
@runner.registerValue('annual_consumption_other_energy', other_energy.get, 'GJ')
|
308
|
-
else
|
309
|
-
cons_elems << OpenStudio::Attribute.new('other_energy', 0.0, 'GJ')
|
310
|
-
@runner.registerValue('annual_consumption_other_energy', 0.0, 'GJ')
|
311
|
-
end
|
312
|
-
|
313
|
-
# district_cooling
|
314
|
-
district_cooling = @sql.districtCoolingTotalEndUses
|
315
|
-
if district_cooling.is_initialized
|
316
|
-
cons_elems << OpenStudio::Attribute.new('district_cooling', district_cooling.get, 'GJ')
|
317
|
-
@runner.registerValue('annual_consumption_district_cooling', district_cooling.get, 'GJ')
|
318
|
-
else
|
319
|
-
cons_elems << OpenStudio::Attribute.new('district_cooling', 0.0, 'GJ')
|
320
|
-
@runner.registerValue('annual_consumption_district_cooling', 0.0, 'GJ')
|
321
|
-
end
|
322
|
-
|
323
|
-
# district_heating
|
324
|
-
district_heating = @sql.districtHeatingTotalEndUses
|
325
|
-
if district_heating.is_initialized
|
326
|
-
cons_elems << OpenStudio::Attribute.new('district_heating', district_heating.get, 'GJ')
|
327
|
-
@runner.registerValue('annual_consumption_district_heating', district_heating.get, 'GJ')
|
328
|
-
else
|
329
|
-
cons_elems << OpenStudio::Attribute.new('district_heating', 0.0, 'GJ')
|
330
|
-
@runner.registerValue('annual_consumption_district_heating', 0.0, 'GJ')
|
331
|
-
end
|
332
|
-
|
333
|
-
# water
|
334
|
-
water = @sql.waterTotalEndUses
|
335
|
-
if water.is_initialized
|
336
|
-
cons_elems << OpenStudio::Attribute.new('water', water.get, 'm^3')
|
337
|
-
@runner.registerValue('annual_consumption_water', water.get, 'm^3')
|
338
|
-
else
|
339
|
-
cons_elems << OpenStudio::Attribute.new('water', 0.0, 'm^3')
|
340
|
-
@runner.registerValue('annual_consumption_water', 0.0, 'm^3')
|
341
|
-
end
|
342
|
-
|
343
|
-
# end consumption
|
344
|
-
annual_elems << OpenStudio::Attribute.new('consumption', cons_elems)
|
345
|
-
|
346
|
-
# demand "demand"
|
347
|
-
demand_elems = OpenStudio::AttributeVector.new
|
348
|
-
|
349
|
-
# get the weather file run period (as opposed to design day run period)
|
350
|
-
ann_env_pd = nil
|
351
|
-
@sql.availableEnvPeriods.each do |env_pd|
|
352
|
-
env_type = @sql.environmentType(env_pd)
|
353
|
-
if env_type.is_initialized
|
354
|
-
if env_type.get == OpenStudio::EnvironmentType.new('WeatherRunPeriod')
|
355
|
-
ann_env_pd = env_pd
|
356
|
-
end
|
357
|
-
end
|
358
|
-
end
|
359
|
-
|
360
|
-
# only try to get the annual peak demand if an annual simulation was run
|
361
|
-
if ann_env_pd
|
362
|
-
|
363
|
-
# create some units to use
|
364
|
-
joule_unit = OpenStudio.createUnit('J').get
|
365
|
-
gigajoule_unit = OpenStudio.createUnit('GJ').get
|
366
|
-
hrs_unit = OpenStudio.createUnit('h').get
|
367
|
-
kilowatt_unit = OpenStudio.createUnit('kW').get
|
368
|
-
|
369
|
-
# get the annual hours simulated
|
370
|
-
hrs_sim = '(0 - no partial annual simulation)'
|
371
|
-
if @sql.hoursSimulated.is_initialized
|
372
|
-
hrs_sim = @sql.hoursSimulated.get
|
373
|
-
if hrs_sim != 8760
|
374
|
-
@runner.registerError("Simulation was only #{hrs_sim} hrs; EDA requires an annual simulation (8760 hrs)")
|
375
|
-
return OpenStudio::Attribute.new('report', result_elems)
|
376
|
-
end
|
377
|
-
end
|
378
|
-
|
379
|
-
# Get the electricity timeseries to determine the year used
|
380
|
-
elec = @sql.timeSeries(ann_env_pd, 'Zone Timestep', 'Electricity:Facility', '')
|
381
|
-
timeseries_yr = nil
|
382
|
-
if elec.is_initialized
|
383
|
-
timeseries_yr = elec.get.dateTimes[0].date.year
|
384
|
-
else
|
385
|
-
@runner.registerError('Peak Demand timeseries (Electricity:Facility at zone timestep) could not be found, cannot determine the informatino needed to calculate savings or incentives.')
|
386
|
-
end
|
387
|
-
# Setup the peak demand time window based on input arguments.
|
388
|
-
# Note that holidays and weekends are not excluded because
|
389
|
-
# of a bug in EnergyPlus dates.
|
390
|
-
# This will only impact corner-case buildings that have
|
391
|
-
# peak demand on weekends or holidays, which is unusual.
|
392
|
-
@runner.registerInfo("Peak Demand window is #{start_mo} #{start_day} to #{end_mo} #{end_day} from #{start_hr}:00 to #{end_hr}:00.")
|
393
|
-
start_date = OpenStudio::DateTime.new(OpenStudio::Date.new(OpenStudio::MonthOfYear.new(start_mo), start_day, timeseries_yr), OpenStudio::Time.new(0, 0, 0, 0))
|
394
|
-
end_date = OpenStudio::DateTime.new(OpenStudio::Date.new(OpenStudio::MonthOfYear.new(end_mo), end_day, timeseries_yr), OpenStudio::Time.new(0, 24, 0, 0))
|
395
|
-
start_time = OpenStudio::Time.new(0, start_hr, 0, 0)
|
396
|
-
end_time = OpenStudio::Time.new(0, end_hr, 0, 0)
|
397
|
-
|
398
|
-
# Get the day type timeseries.
|
399
|
-
day_types = nil
|
400
|
-
day_type_indices = @sql.timeSeries(ann_env_pd, 'Zone Timestep', 'Site Day Type Index', 'Environment')
|
401
|
-
if day_type_indices.is_initialized
|
402
|
-
# Put values into array
|
403
|
-
day_types = []
|
404
|
-
day_type_vals = day_type_indices.get.values
|
405
|
-
for i in 0..(day_type_vals.size - 1)
|
406
|
-
day_types << day_type_vals[i]
|
407
|
-
end
|
408
|
-
else
|
409
|
-
@runner.registerError('Day Type timeseries (Site Day Type Index at zone timestep) could not be found, cannot accurately determine the peak demand.')
|
410
|
-
end
|
411
|
-
|
412
|
-
# electricity_peak_demand
|
413
|
-
electricity_peak_demand = -1.0
|
414
|
-
electricity_peak_demand_time = nil
|
415
|
-
# deduce the timestep based on the hours simulated and the number of datapoints in the timeseries
|
416
|
-
if elec.is_initialized && day_types
|
417
|
-
elec = elec.get
|
418
|
-
num_int = elec.values.size
|
419
|
-
int_len_hrs = OpenStudio::Quantity.new(hrs_sim / num_int, hrs_unit)
|
420
|
-
|
421
|
-
# Put timeseries into array
|
422
|
-
elec_vals = []
|
423
|
-
ann_elec_vals = elec.values
|
424
|
-
for i in 0..(ann_elec_vals.size - 1)
|
425
|
-
elec_vals << ann_elec_vals[i]
|
426
|
-
end
|
427
|
-
|
428
|
-
# Put values into array
|
429
|
-
elec_times = []
|
430
|
-
ann_elec_times = elec.dateTimes
|
431
|
-
for i in 0..(ann_elec_times.size - 1)
|
432
|
-
elec_times << ann_elec_times[i]
|
433
|
-
end
|
434
|
-
|
435
|
-
# Loop through the time/value pairs and find the peak
|
436
|
-
# excluding the times outside of the Xcel peak demand window
|
437
|
-
elec_times.zip(elec_vals).each_with_index do |vs, ind|
|
438
|
-
date_time = vs[0]
|
439
|
-
val = vs[1]
|
440
|
-
day_type = day_types[ind]
|
441
|
-
time = date_time.time
|
442
|
-
date = date_time.date
|
443
|
-
day_of_week = date.dayOfWeek
|
444
|
-
# Convert the peak demand to kW
|
445
|
-
val_J_per_hr = val / int_len_hrs.value
|
446
|
-
val_kW = OpenStudio.convert(val_J_per_hr, 'J/h', 'kW').get
|
447
|
-
|
448
|
-
# puts("#{val_kW}kW; #{date}; #{time}; #{day_of_week.valueName}")
|
449
|
-
|
450
|
-
# Skip times outside of the correct months
|
451
|
-
next if date_time < start_date || date_time > end_date
|
452
|
-
# Skip times before 2pm and after 6pm
|
453
|
-
next if time < start_time || time > end_time
|
454
|
-
# Skip weekends if asked
|
455
|
-
if skip_weekends
|
456
|
-
# Sunday = 1, Saturday = 7
|
457
|
-
next if day_type == 1 || day_type == 7
|
458
|
-
end
|
459
|
-
# Skip holidays if asked
|
460
|
-
if skip_holidays
|
461
|
-
# Holiday = 8
|
462
|
-
next if day_type == 8
|
463
|
-
end
|
464
|
-
|
465
|
-
# puts("VALID #{val_kW}kW; #{date}; #{time}; #{day_of_week.valueName}")
|
466
|
-
|
467
|
-
# Check peak demand against this timestep
|
468
|
-
# and update if this timestep is higher.
|
469
|
-
if val > electricity_peak_demand
|
470
|
-
electricity_peak_demand = val
|
471
|
-
electricity_peak_demand_time = date_time
|
472
|
-
end
|
473
|
-
end
|
474
|
-
elec_peak_demand_timestep_J = OpenStudio::Quantity.new(electricity_peak_demand, joule_unit)
|
475
|
-
num_int = elec.values.size
|
476
|
-
int_len_hrs = OpenStudio::Quantity.new(hrs_sim / num_int, hrs_unit)
|
477
|
-
elec_peak_demand_hourly_J_per_hr = elec_peak_demand_timestep_J / int_len_hrs
|
478
|
-
electricity_peak_demand = OpenStudio.convert(elec_peak_demand_hourly_J_per_hr, kilowatt_unit).get.value
|
479
|
-
demand_elems << OpenStudio::Attribute.new('electricity_peak_demand', electricity_peak_demand, 'kW')
|
480
|
-
@runner.registerValue('annual_demand_electricity_peak_demand', electricity_peak_demand, 'kW')
|
481
|
-
@runner.registerInfo("Peak Demand = #{electricity_peak_demand.round(2)}kW on #{electricity_peak_demand_time}")
|
482
|
-
else
|
483
|
-
@runner.registerError('Peak Demand timeseries (Electricity:Facility at zone timestep) could not be found, cannot determine the informatino needed to calculate savings or incentives.')
|
484
|
-
demand_elems << OpenStudio::Attribute.new('electricity_peak_demand', 0.0, 'kW')
|
485
|
-
@runner.registerValue('annual_demand_electricity_peak_demand', 0.0, 'kW')
|
486
|
-
end
|
487
|
-
|
488
|
-
# Describe the TOU periods
|
489
|
-
electricity_consumption_tou_periods.each do |tou_pd|
|
490
|
-
@runner.registerInfo("TOU period #{tou_pd['tou_id']} represents #{tou_pd['tou_name']} and covers #{tou_pd['start_mo']}-#{tou_pd['start_day']} to #{tou_pd['end_mo']}-#{tou_pd['end_day']} from #{tou_pd['start_hr']} to #{tou_pd['end_hr']}, skip weekends = #{tou_pd['skip_weekends']}, skip holidays = #{tou_pd['skip_holidays']}")
|
491
|
-
end
|
492
|
-
|
493
|
-
# electricity time-of-use periods
|
494
|
-
elec = @sql.timeSeries(ann_env_pd, 'Zone Timestep', 'Electricity:Facility', '')
|
495
|
-
if elec.is_initialized && day_types
|
496
|
-
elec = elec.get
|
497
|
-
# Put timeseries into array
|
498
|
-
elec_vals = []
|
499
|
-
ann_elec_vals = elec.values
|
500
|
-
for i in 0..(ann_elec_vals.size - 1)
|
501
|
-
elec_vals << ann_elec_vals[i]
|
502
|
-
end
|
503
|
-
|
504
|
-
# Put values into array
|
505
|
-
elec_times = []
|
506
|
-
ann_elec_times = elec.dateTimes
|
507
|
-
for i in 0..(ann_elec_times.size - 1)
|
508
|
-
elec_times << ann_elec_times[i]
|
509
|
-
end
|
510
|
-
|
511
|
-
# Loop through the time/value pairs and find the peak
|
512
|
-
# excluding the times outside of the Xcel peak demand window
|
513
|
-
electricity_tou_vals = Hash.new(0)
|
514
|
-
elec_times.zip(elec_vals).each_with_index do |vs, ind|
|
515
|
-
date_time = vs[0]
|
516
|
-
joules = vs[1]
|
517
|
-
day_type = day_types[ind]
|
518
|
-
time = date_time.time
|
519
|
-
date = date_time.date
|
520
|
-
|
521
|
-
# puts("#{val_kW}kW; #{date}; #{time}; #{day_of_week.valueName}")
|
522
|
-
|
523
|
-
# Determine which TOU period this hour falls into
|
524
|
-
tou_period_assigned = false
|
525
|
-
electricity_consumption_tou_periods.each do |tou_pd|
|
526
|
-
pd_start_date = OpenStudio::DateTime.new(OpenStudio::Date.new(OpenStudio::MonthOfYear.new(tou_pd['start_mo']), tou_pd['start_day'], timeseries_yr), OpenStudio::Time.new(0, 0, 0, 0))
|
527
|
-
pd_end_date = OpenStudio::DateTime.new(OpenStudio::Date.new(OpenStudio::MonthOfYear.new(tou_pd['end_mo']), tou_pd['end_day'], timeseries_yr), OpenStudio::Time.new(0, 24, 0, 0))
|
528
|
-
pd_start_time = OpenStudio::Time.new(0, tou_pd['start_hr'], 0, 0)
|
529
|
-
pd_end_time = OpenStudio::Time.new(0, tou_pd['end_hr'], 0, 0)
|
530
|
-
# Skip times outside of the correct months
|
531
|
-
next if date_time < pd_start_date || date_time > pd_end_date
|
532
|
-
# Skip times before some time and after another time
|
533
|
-
next if time < pd_start_time || time > pd_end_time
|
534
|
-
# Skip weekends if asked
|
535
|
-
if tou_pd['skip_weekends']
|
536
|
-
# Sunday = 1, Saturday = 7
|
537
|
-
next if day_type == 1 || day_type == 7
|
538
|
-
end
|
539
|
-
# Skip holidays if asked
|
540
|
-
if tou_pd['skip_holidays']
|
541
|
-
# Holiday = 8
|
542
|
-
next if day_type == 8
|
543
|
-
end
|
544
|
-
# If here, this hour falls into the specified period
|
545
|
-
tou_period_assigned = true
|
546
|
-
electricity_tou_vals[tou_pd['tou_id']] += joules
|
547
|
-
break
|
548
|
-
end
|
549
|
-
# Ensure that the value fell into a period
|
550
|
-
unless tou_period_assigned
|
551
|
-
@runner.registerError("Did not find a TOU period covering #{time} on #{date}, kWh will not be included in any TOU period.")
|
552
|
-
end
|
553
|
-
end
|
554
|
-
# Register values for any time-of-use period with kWh
|
555
|
-
electricity_tou_vals.each do |tou_pd_id, joules_in_pd|
|
556
|
-
gj_in_pd = OpenStudio.convert(joules_in_pd, 'J', 'GJ').get
|
557
|
-
kwh_in_pd = OpenStudio.convert(joules_in_pd, 'J', 'kWh').get
|
558
|
-
@runner.registerValue("annual_consumption_electricity_tou_#{tou_pd_id}", gj_in_pd, 'GJ')
|
559
|
-
@runner.registerInfo("TOU period #{tou_pd_id} annual electricity consumption = #{kwh_in_pd} kWh.")
|
560
|
-
end
|
561
|
-
else
|
562
|
-
@runner.registerError('Electricity timeseries (Electricity:Facility at zone timestep) could not be found, cannot determine the information needed to calculate savings or incentives.')
|
563
|
-
end
|
564
|
-
|
565
|
-
# electricity_annual_avg_peak_demand
|
566
|
-
val = @sql.electricityTotalEndUses
|
567
|
-
if val.is_initialized
|
568
|
-
ann_elec_gj = OpenStudio::Quantity.new(val.get, gigajoule_unit)
|
569
|
-
ann_hrs = OpenStudio::Quantity.new(hrs_sim, hrs_unit)
|
570
|
-
elec_ann_avg_peak_demand_hourly_GJ_per_hr = ann_elec_gj / ann_hrs
|
571
|
-
electricity_annual_avg_peak_demand = OpenStudio.convert(elec_ann_avg_peak_demand_hourly_GJ_per_hr, kilowatt_unit).get.value
|
572
|
-
demand_elems << OpenStudio::Attribute.new('electricity_annual_avg_peak_demand', electricity_annual_avg_peak_demand, 'kW')
|
573
|
-
@runner.registerValue('annual_demand_electricity_annual_avg_peak_demand', electricity_annual_avg_peak_demand, 'kW')
|
574
|
-
else
|
575
|
-
demand_elems << OpenStudio::Attribute.new('electricity_annual_avg_peak_demand', 0.0, 'kW')
|
576
|
-
@runner.registerValue('annual_demand_electricity_annual_avg_peak_demand', 0.0, 'kW')
|
577
|
-
end
|
578
|
-
|
579
|
-
# district_cooling_peak_demand
|
580
|
-
district_cooling_peak_demand = -1.0
|
581
|
-
ann_dist_clg_peak_demand_time = nil
|
582
|
-
dist_clg = @sql.timeSeries(ann_env_pd, 'Zone Timestep', 'DistrictCooling:Facility', '')
|
583
|
-
# deduce the timestep based on the hours simulated and the number of datapoints in the timeseries
|
584
|
-
if dist_clg.is_initialized && day_types
|
585
|
-
dist_clg = dist_clg.get
|
586
|
-
num_int = dist_clg.values.size
|
587
|
-
int_len_hrs = OpenStudio::Quantity.new(hrs_sim / num_int, hrs_unit)
|
588
|
-
|
589
|
-
# Put timeseries into array
|
590
|
-
dist_clg_vals = []
|
591
|
-
ann_dist_clg_vals = dist_clg.values
|
592
|
-
for i in 0..(ann_dist_clg_vals.size - 1)
|
593
|
-
dist_clg_vals << ann_dist_clg_vals[i]
|
594
|
-
end
|
595
|
-
|
596
|
-
# Put values into array
|
597
|
-
dist_clg_times = []
|
598
|
-
ann_dist_clg_times = dist_clg.dateTimes
|
599
|
-
for i in 0..(ann_dist_clg_times.size - 1)
|
600
|
-
dist_clg_times << ann_dist_clg_times[i]
|
601
|
-
end
|
602
|
-
|
603
|
-
# Loop through the time/value pairs and find the peak
|
604
|
-
# excluding the times outside of the Xcel peak demand window
|
605
|
-
dist_clg_times.zip(dist_clg_vals).each_with_index do |vs, ind|
|
606
|
-
date_time = vs[0]
|
607
|
-
val = vs[1]
|
608
|
-
day_type = day_types[ind]
|
609
|
-
time = date_time.time
|
610
|
-
date = date_time.date
|
611
|
-
day_of_week = date.dayOfWeek
|
612
|
-
# Convert the peak demand to kW
|
613
|
-
val_J_per_hr = val / int_len_hrs.value
|
614
|
-
val_kW = OpenStudio.convert(val_J_per_hr, 'J/h', 'kW').get
|
615
|
-
|
616
|
-
# puts("#{val_kW}kW; #{date}; #{time}; #{day_of_week.valueName}")
|
617
|
-
|
618
|
-
# Skip times outside of the correct months
|
619
|
-
next if date_time < start_date || date_time > end_date
|
620
|
-
# Skip times before 2pm and after 6pm
|
621
|
-
next if time < start_time || time > end_time
|
622
|
-
# Skip weekends if asked
|
623
|
-
if skip_weekends
|
624
|
-
# Sunday = 1, Saturday = 7
|
625
|
-
next if day_type == 1 || day_type == 7
|
626
|
-
end
|
627
|
-
# Skip holidays if asked
|
628
|
-
if skip_holidays
|
629
|
-
# Holiday = 8
|
630
|
-
next if day_type == 8
|
631
|
-
end
|
632
|
-
|
633
|
-
# puts("VALID #{val_kW}kW; #{date}; #{time}; #{day_of_week.valueName}")
|
634
|
-
|
635
|
-
# Check peak demand against this timestep
|
636
|
-
# and update if this timestep is higher.
|
637
|
-
if val > district_cooling_peak_demand
|
638
|
-
district_cooling_peak_demand = val
|
639
|
-
ann_dist_clg_peak_demand_time = date_time
|
640
|
-
end
|
641
|
-
end
|
642
|
-
dist_clg_peak_demand_timestep_J = OpenStudio::Quantity.new(district_cooling_peak_demand, joule_unit)
|
643
|
-
num_int = dist_clg.values.size
|
644
|
-
int_len_hrs = OpenStudio::Quantity.new(hrs_sim / num_int, hrs_unit)
|
645
|
-
dist_clg_peak_demand_hourly_J_per_hr = dist_clg_peak_demand_timestep_J / int_len_hrs
|
646
|
-
district_cooling_peak_demand = OpenStudio.convert(dist_clg_peak_demand_hourly_J_per_hr, kilowatt_unit).get.value
|
647
|
-
demand_elems << OpenStudio::Attribute.new('district_cooling_peak_demand', district_cooling_peak_demand, 'kW')
|
648
|
-
@runner.registerValue('annual_demand_district_cooling_peak_demand', district_cooling_peak_demand, 'kW')
|
649
|
-
@runner.registerInfo("District Cooling Peak Demand = #{district_cooling_peak_demand.round(2)}kW on #{ann_dist_clg_peak_demand_time}")
|
650
|
-
else
|
651
|
-
demand_elems << OpenStudio::Attribute.new('district_cooling_peak_demand', 0.0, 'kW')
|
652
|
-
@runner.registerValue('annual_demand_district_cooling_peak_demand', 0.0, 'kW')
|
653
|
-
end
|
654
|
-
|
655
|
-
# district cooling time-of-use periods
|
656
|
-
dist_clg = @sql.timeSeries(ann_env_pd, 'Zone Timestep', 'DistrictCooling:Facility', '')
|
657
|
-
if dist_clg.is_initialized && day_types
|
658
|
-
dist_clg = dist_clg.get
|
659
|
-
# Put timeseries into array
|
660
|
-
dist_clg_vals = []
|
661
|
-
ann_dist_clg_vals = dist_clg.values
|
662
|
-
for i in 0..(ann_dist_clg_vals.size - 1)
|
663
|
-
dist_clg_vals << ann_dist_clg_vals[i]
|
664
|
-
end
|
665
|
-
|
666
|
-
# Put values into array
|
667
|
-
dist_clg_times = []
|
668
|
-
ann_dist_clg_times = dist_clg.dateTimes
|
669
|
-
for i in 0..(ann_dist_clg_times.size - 1)
|
670
|
-
dist_clg_times << ann_dist_clg_times[i]
|
671
|
-
end
|
672
|
-
|
673
|
-
# Loop through the time/value pairs and find the peak
|
674
|
-
# excluding the times outside of the Xcel peak demand window
|
675
|
-
dist_clg_tou_vals = Hash.new(0)
|
676
|
-
dist_clg_times.zip(dist_clg_vals).each_with_index do |vs, ind|
|
677
|
-
date_time = vs[0]
|
678
|
-
joules = vs[1]
|
679
|
-
day_type = day_types[ind]
|
680
|
-
time = date_time.time
|
681
|
-
date = date_time.date
|
682
|
-
|
683
|
-
# puts("#{val_kW}kW; #{date}; #{time}; #{day_of_week.valueName}")
|
684
|
-
|
685
|
-
# Determine which TOU period this hour falls into
|
686
|
-
tou_period_assigned = false
|
687
|
-
electricity_consumption_tou_periods.each do |tou_pd|
|
688
|
-
pd_start_date = OpenStudio::DateTime.new(OpenStudio::Date.new(OpenStudio::MonthOfYear.new(tou_pd['start_mo']), tou_pd['start_day'], timeseries_yr), OpenStudio::Time.new(0, 0, 0, 0))
|
689
|
-
pd_end_date = OpenStudio::DateTime.new(OpenStudio::Date.new(OpenStudio::MonthOfYear.new(tou_pd['end_mo']), tou_pd['end_day'], timeseries_yr), OpenStudio::Time.new(0, 24, 0, 0))
|
690
|
-
pd_start_time = OpenStudio::Time.new(0, tou_pd['start_hr'], 0, 0)
|
691
|
-
pd_end_time = OpenStudio::Time.new(0, tou_pd['end_hr'], 0, 0)
|
692
|
-
# Skip times outside of the correct months
|
693
|
-
next if date_time < pd_start_date || date_time > pd_end_date
|
694
|
-
# Skip times before some time and after another time
|
695
|
-
next if time < pd_start_time || time > pd_end_time
|
696
|
-
# Skip weekends if asked
|
697
|
-
if tou_pd['skip_weekends']
|
698
|
-
# Sunday = 1, Saturday = 7
|
699
|
-
next if day_type == 1 || day_type == 7
|
700
|
-
end
|
701
|
-
# Skip holidays if asked
|
702
|
-
if tou_pd['skip_holidays']
|
703
|
-
# Holiday = 8
|
704
|
-
next if day_type == 8
|
705
|
-
end
|
706
|
-
# If here, this hour falls into the specified period
|
707
|
-
tou_period_assigned = true
|
708
|
-
dist_clg_tou_vals[tou_pd['tou_id']] += joules
|
709
|
-
break
|
710
|
-
end
|
711
|
-
# Ensure that the value fell into a period
|
712
|
-
unless tou_period_assigned
|
713
|
-
@runner.registerError("Did not find a TOU period covering #{time} on #{date}, kWh will not be included in any TOU period.")
|
714
|
-
end
|
715
|
-
end
|
716
|
-
# Register values for any time-of-use period with kWh
|
717
|
-
dist_clg_tou_vals.each do |tou_pd_id, joules_in_pd|
|
718
|
-
gj_in_pd = OpenStudio.convert(joules_in_pd, 'J', 'GJ').get
|
719
|
-
kwh_in_pd = OpenStudio.convert(joules_in_pd, 'J', 'kWh').get
|
720
|
-
@runner.registerValue("annual_consumption_district_cooling_tou_#{tou_pd_id}", gj_in_pd, 'GJ')
|
721
|
-
@runner.registerInfo("TOU period #{tou_pd_id} annual district cooling consumption = #{kwh_in_pd} kWh.")
|
722
|
-
end
|
723
|
-
else
|
724
|
-
# If TOU periods were specified but this model has no district cooling, report zeroes
|
725
|
-
if electricity_consumption_tou_periods.size > 0
|
726
|
-
# Get the TOU ids
|
727
|
-
tou_ids = []
|
728
|
-
electricity_consumption_tou_periods.each do |tou_pd|
|
729
|
-
tou_ids << tou_pd['tou_id']
|
730
|
-
end
|
731
|
-
tou_ids.uniq.each do |tou_id|
|
732
|
-
@runner.registerValue("annual_consumption_district_cooling_tou_#{tou_id}", 0.0, 'GJ')
|
733
|
-
end
|
734
|
-
end
|
735
|
-
end
|
736
|
-
|
737
|
-
else
|
738
|
-
@runner.registerError('Could not find an annual run period')
|
739
|
-
return OpenStudio::Attribute.new('report', result_elems)
|
740
|
-
end
|
741
|
-
|
742
|
-
# end demand
|
743
|
-
annual_elems << OpenStudio::Attribute.new('demand', demand_elems)
|
744
|
-
|
745
|
-
# utility_cost
|
746
|
-
utility_cost_elems = OpenStudio::AttributeVector.new
|
747
|
-
annual_utility_cost_map = {}
|
748
|
-
|
749
|
-
# electricity
|
750
|
-
electricity = @sql.annualTotalCost(OpenStudio::FuelType.new('Electricity'))
|
751
|
-
if electricity.is_initialized
|
752
|
-
utility_cost_elems << OpenStudio::Attribute.new('electricity', electricity.get, 'dollars')
|
753
|
-
@runner.registerValue('annual_utility_cost_electricity', electricity.get, 'dollars')
|
754
|
-
annual_utility_cost_map[OpenStudio::EndUseFuelType.new('Electricity').valueName] = electricity.get
|
755
|
-
else
|
756
|
-
utility_cost_elems << OpenStudio::Attribute.new('electricity', 0.0, 'dollars')
|
757
|
-
@runner.registerValue('annual_utility_cost_electricity', 0.0, 'dollars')
|
758
|
-
annual_utility_cost_map[OpenStudio::EndUseFuelType.new('Electricity').valueName] = 0.0
|
759
|
-
end
|
760
|
-
|
761
|
-
# electricity_consumption_charge and electricity_demand_charge
|
762
|
-
electric_consumption_charge = 0.0
|
763
|
-
electric_demand_charge = 0.0
|
764
|
-
|
765
|
-
electric_rate_query = "SELECT value FROM tabulardatawithstrings WHERE ReportName='LEEDsummary' AND ReportForString='Entire Facility' AND TableName='EAp2-3. Energy Type Summary' AND RowName='Electricity' AND ColumnName='Utility Rate'"
|
766
|
-
electric_rate_name = @sql.execAndReturnFirstString(electric_rate_query)
|
767
|
-
if electric_rate_name.is_initialized
|
768
|
-
electric_rate_name = electric_rate_name.get.strip
|
769
|
-
|
770
|
-
# electricity_consumption_charge
|
771
|
-
electric_consumption_charge_query = "SELECT value FROM tabulardatawithstrings WHERE ReportName='Tariff Report' AND ReportForString='#{electric_rate_name}' AND TableName='Categories' AND RowName='EnergyCharges (~~$~~)' AND ColumnName='Sum'"
|
772
|
-
val = @sql.execAndReturnFirstDouble(electric_consumption_charge_query)
|
773
|
-
if val.is_initialized
|
774
|
-
electric_consumption_charge = val.get
|
775
|
-
end
|
776
|
-
|
777
|
-
# electricity_demand_charge
|
778
|
-
electric_demand_charge_query = "SELECT value FROM tabulardatawithstrings WHERE ReportName='Tariff Report' AND ReportForString='#{electric_rate_name}' AND TableName='Categories' AND RowName='DemandCharges (~~$~~)' AND ColumnName='Sum'"
|
779
|
-
val = @sql.execAndReturnFirstDouble(electric_demand_charge_query)
|
780
|
-
if val.is_initialized
|
781
|
-
electric_demand_charge = val.get
|
782
|
-
end
|
783
|
-
|
784
|
-
end
|
785
|
-
utility_cost_elems << OpenStudio::Attribute.new('electricity_consumption_charge', electric_consumption_charge, 'dollars')
|
786
|
-
@runner.registerValue('annual_utility_cost_electricity_consumption_charge', electric_consumption_charge, 'dollars')
|
787
|
-
utility_cost_elems << OpenStudio::Attribute.new('electricity_demand_charge', electric_demand_charge, 'dollars')
|
788
|
-
@runner.registerValue('annual_utility_cost_electricity_demand_charge', electric_demand_charge, 'dollars')
|
789
|
-
|
790
|
-
# gas
|
791
|
-
gas = @sql.annualTotalCost(OpenStudio::FuelType.new('Gas'))
|
792
|
-
if gas.is_initialized
|
793
|
-
annual_utility_cost_map[OpenStudio::EndUseFuelType.new('Gas').valueName] = gas.get
|
794
|
-
else
|
795
|
-
annual_utility_cost_map[OpenStudio::EndUseFuelType.new('Gas').valueName] = 0.0
|
796
|
-
end
|
797
|
-
|
798
|
-
# district_cooling
|
799
|
-
district_cooling_charge = 0.0
|
800
|
-
|
801
|
-
district_cooling_rate_query = "SELECT value FROM tabulardatawithstrings WHERE ReportName='LEEDsummary' AND ReportForString='Entire Facility' AND TableName='EAp2-3. Energy Type Summary' AND RowName='District Cooling' AND ColumnName='Utility Rate'"
|
802
|
-
district_cooling_rate_name = @sql.execAndReturnFirstString(district_cooling_rate_query)
|
803
|
-
if district_cooling_rate_name.is_initialized
|
804
|
-
district_cooling_rate_name = district_cooling_rate_name.get.strip
|
805
|
-
|
806
|
-
# district_cooling_charge
|
807
|
-
district_cooling_charge_query = "SELECT value FROM tabulardatawithstrings WHERE ReportName='Tariff Report' AND ReportForString='#{district_cooling_rate_name}' AND TableName='Categories' AND RowName='Basis (~~$~~)' AND ColumnName='Sum'"
|
808
|
-
val = @sql.execAndReturnFirstDouble(district_cooling_charge_query)
|
809
|
-
if val.is_initialized
|
810
|
-
district_cooling_charge = val.get
|
811
|
-
end
|
812
|
-
|
813
|
-
end
|
814
|
-
annual_utility_cost_map[OpenStudio::EndUseFuelType.new('DistrictCooling').valueName] = district_cooling_charge
|
815
|
-
|
816
|
-
# district_heating
|
817
|
-
district_heating_charge = 0.0
|
818
|
-
|
819
|
-
district_heating_rate_query = "SELECT value FROM tabulardatawithstrings WHERE ReportName='LEEDsummary' AND ReportForString='Entire Facility' AND TableName='EAp2-3. Energy Type Summary' AND RowName='District Heating' AND ColumnName='Utility Rate'"
|
820
|
-
district_heating_rate_name = @sql.execAndReturnFirstString(district_heating_rate_query)
|
821
|
-
if district_heating_rate_name.is_initialized
|
822
|
-
district_heating_rate_name = district_heating_rate_name.get.strip
|
823
|
-
|
824
|
-
# district_heating_charge
|
825
|
-
district_heating_charge_query = "SELECT value FROM tabulardatawithstrings WHERE ReportName='Tariff Report' AND ReportForString='#{district_heating_rate_name}' AND TableName='Categories' AND RowName='Basis (~~$~~)' AND ColumnName='Sum'"
|
826
|
-
val = @sql.execAndReturnFirstDouble(district_heating_charge_query)
|
827
|
-
if val.is_initialized
|
828
|
-
district_heating_charge = val.get
|
829
|
-
end
|
830
|
-
|
831
|
-
end
|
832
|
-
annual_utility_cost_map[OpenStudio::EndUseFuelType.new('DistrictHeating').valueName] = district_heating_charge
|
833
|
-
|
834
|
-
# water
|
835
|
-
water = @sql.annualTotalCost(OpenStudio::FuelType.new('Water'))
|
836
|
-
if water.is_initialized
|
837
|
-
annual_utility_cost_map[OpenStudio::EndUseFuelType.new('Water').valueName] = water.get
|
838
|
-
else
|
839
|
-
annual_utility_cost_map[OpenStudio::EndUseFuelType.new('Water').valueName] = 0.0
|
840
|
-
end
|
841
|
-
|
842
|
-
# total
|
843
|
-
total_query = "SELECT Value from tabulardatawithstrings where (reportname = 'Economics Results Summary Report') and (ReportForString = 'Entire Facility') and (TableName = 'Annual Cost') and (ColumnName ='Total') and (((RowName = 'Cost') and (Units = '~~$~~')) or (RowName = 'Cost (~~$~~)'))"
|
844
|
-
total = @sql.execAndReturnFirstDouble(total_query)
|
845
|
-
|
846
|
-
# other_energy
|
847
|
-
# Subtract off the already accounted for fuel types from the total
|
848
|
-
# to account for fuels on custom meters where the fuel type is not known.
|
849
|
-
prev_tot = 0.0
|
850
|
-
annual_utility_cost_map.each do |fuel, val|
|
851
|
-
prev_tot += val
|
852
|
-
end
|
853
|
-
if total.is_initialized
|
854
|
-
other_val = total.get - prev_tot
|
855
|
-
annual_utility_cost_map[OpenStudio::EndUseFuelType.new('AdditionalFuel').valueName] = other_val
|
856
|
-
else
|
857
|
-
annual_utility_cost_map[OpenStudio::EndUseFuelType.new('AdditionalFuel').valueName] = 0.0
|
858
|
-
end
|
859
|
-
|
860
|
-
# export remaining costs in the correct order
|
861
|
-
# gas
|
862
|
-
utility_cost_elems << OpenStudio::Attribute.new('gas', annual_utility_cost_map[OpenStudio::EndUseFuelType.new('Gas').valueName], 'dollars')
|
863
|
-
@runner.registerValue('annual_utility_cost_gas', annual_utility_cost_map[OpenStudio::EndUseFuelType.new('Gas').valueName], 'dollars')
|
864
|
-
# other_energy
|
865
|
-
utility_cost_elems << OpenStudio::Attribute.new('other_energy', annual_utility_cost_map[OpenStudio::EndUseFuelType.new('AdditionalFuel').valueName], 'dollars')
|
866
|
-
@runner.registerValue('annual_utility_cost_other_energy', annual_utility_cost_map[OpenStudio::EndUseFuelType.new('AdditionalFuel').valueName], 'dollars')
|
867
|
-
# district_cooling
|
868
|
-
utility_cost_elems << OpenStudio::Attribute.new('district_cooling', annual_utility_cost_map[OpenStudio::EndUseFuelType.new('DistrictCooling').valueName], 'dollars')
|
869
|
-
@runner.registerValue('annual_utility_cost_district_cooling', annual_utility_cost_map[OpenStudio::EndUseFuelType.new('DistrictCooling').valueName], 'dollars')
|
870
|
-
# district_heating
|
871
|
-
utility_cost_elems << OpenStudio::Attribute.new('district_heating', annual_utility_cost_map[OpenStudio::EndUseFuelType.new('DistrictHeating').valueName], 'dollars')
|
872
|
-
@runner.registerValue('annual_utility_cost_district_heating', annual_utility_cost_map[OpenStudio::EndUseFuelType.new('DistrictHeating').valueName], 'dollars')
|
873
|
-
# water
|
874
|
-
utility_cost_elems << OpenStudio::Attribute.new('water', annual_utility_cost_map[OpenStudio::EndUseFuelType.new('Water').valueName], 'dollars')
|
875
|
-
@runner.registerValue('annual_utility_cost_water', annual_utility_cost_map[OpenStudio::EndUseFuelType.new('Water').valueName], 'dollars')
|
876
|
-
# total
|
877
|
-
if total.is_initialized
|
878
|
-
utility_cost_elems << OpenStudio::Attribute.new('total', total.get, 'dollars')
|
879
|
-
@runner.registerValue('annual_utility_cost_total', total.get, 'dollars')
|
880
|
-
else
|
881
|
-
utility_cost_elems << OpenStudio::Attribute.new('total', 0.0, 'dollars')
|
882
|
-
@runner.registerValue('annual_utility_cost_total', 0.0, 'dollars')
|
883
|
-
end
|
884
|
-
|
885
|
-
# end_uses - utility costs by end use using average blended cost
|
886
|
-
end_uses_elems = OpenStudio::AttributeVector.new
|
887
|
-
# map to store the costs by end use
|
888
|
-
cost_by_end_use = {}
|
889
|
-
|
890
|
-
# fill the map with 0.0's to start
|
891
|
-
end_use_cat_types.each do |end_use_cat_type|
|
892
|
-
cost_by_end_use[end_use_cat_type] = 0.0
|
893
|
-
end
|
894
|
-
|
895
|
-
# only attempt to get monthly data if enduses table is available
|
896
|
-
if @sql.endUses.is_initialized
|
897
|
-
end_uses_table = @sql.endUses.get
|
898
|
-
# loop through all the fuel types
|
899
|
-
end_use_fuel_types.each do |end_use_fuel_type|
|
900
|
-
# get the annual total cost for this fuel type
|
901
|
-
ann_cost = annual_utility_cost_map[end_use_fuel_type.valueName]
|
902
|
-
# get the total annual usage for this fuel type in all end use categories
|
903
|
-
# loop through all end uses, adding the annual usage value to the aggregator
|
904
|
-
ann_usg = 0.0
|
905
|
-
end_use_cat_types.each do |end_use_cat_type|
|
906
|
-
ann_usg += end_uses_table.getEndUse(end_use_fuel_type, end_use_cat_type)
|
907
|
-
end
|
908
|
-
# figure out the annual blended rate for this fuel type
|
909
|
-
avg_ann_rate = 0.0
|
910
|
-
if ann_cost > 0 && ann_usg > 0
|
911
|
-
avg_ann_rate = ann_cost / ann_usg
|
912
|
-
end
|
913
|
-
# for each end use category, figure out the cost if using
|
914
|
-
# the avg ann rate; add this cost to the map
|
915
|
-
end_use_cat_types.each do |end_use_cat_type|
|
916
|
-
cost_by_end_use[end_use_cat_type] += end_uses_table.getEndUse(end_use_fuel_type, end_use_cat_type) * avg_ann_rate
|
917
|
-
end
|
918
|
-
end
|
919
|
-
# loop through the end uses and record the annual total cost based on the avg annual rate
|
920
|
-
end_use_cat_types.each do |end_use_cat_type|
|
921
|
-
# record the value
|
922
|
-
end_uses_elems << OpenStudio::Attribute.new(end_use_map[end_use_cat_type.value], cost_by_end_use[end_use_cat_type], 'dollars')
|
923
|
-
@runner.registerValue("annual_utility_cost_end_uses_#{end_use_map[end_use_cat_type.value]}", cost_by_end_use[end_use_cat_type], 'dollars')
|
924
|
-
end
|
925
|
-
else
|
926
|
-
@runner.registerError('End-Use table not available in results; could not retrieve monthly costs by end use')
|
927
|
-
return OpenStudio::Attribute.new('report', result_elems)
|
928
|
-
end
|
929
|
-
|
930
|
-
# end end_uses
|
931
|
-
utility_cost_elems << OpenStudio::Attribute.new('end_uses', end_uses_elems)
|
932
|
-
|
933
|
-
# end utility_costs
|
934
|
-
annual_elems << OpenStudio::Attribute.new('utility_cost', utility_cost_elems)
|
935
|
-
|
936
|
-
# end annual
|
937
|
-
result_elems << OpenStudio::Attribute.new('annual', annual_elems)
|
938
|
-
|
939
|
-
# monthly
|
940
|
-
monthly_elems = OpenStudio::AttributeVector.new
|
941
|
-
|
942
|
-
# consumption
|
943
|
-
cons_elems = OpenStudio::AttributeVector.new
|
944
|
-
# loop through all end uses
|
945
|
-
end_use_cat_types.each do |end_use_cat|
|
946
|
-
end_use_elems = OpenStudio::AttributeVector.new
|
947
|
-
end_use_name = end_use_map[end_use_cat.value]
|
948
|
-
# in each end use, loop through all fuel types
|
949
|
-
end_use_fuel_types.each do |end_use_fuel_type|
|
950
|
-
fuel_type_elems = OpenStudio::AttributeVector.new
|
951
|
-
fuel_type_name = fuel_type_alias_map[end_use_fuel_type.value]
|
952
|
-
ann_energy_cons = 0.0
|
953
|
-
# in each end use, loop through months and get monthly enedy consumption
|
954
|
-
months.each_with_index do |month, i|
|
955
|
-
mon_energy_cons = 0.0
|
956
|
-
val = @sql.energyConsumptionByMonth(end_use_fuel_type, end_use_cat, month)
|
957
|
-
if val.is_initialized
|
958
|
-
monthly_consumption_J = OpenStudio::Quantity.new(val.get, joule_unit)
|
959
|
-
monthly_consumption_GJ = OpenStudio.convert(monthly_consumption_J, gigajoule_unit).get.value
|
960
|
-
mon_energy_cons = monthly_consumption_GJ
|
961
|
-
ann_energy_cons += monthly_consumption_GJ
|
962
|
-
end
|
963
|
-
# record the monthly value
|
964
|
-
if end_use_fuel_type == OpenStudio::EndUseFuelType.new('Water')
|
965
|
-
fuel_type_elems << OpenStudio::Attribute.new('month', mon_energy_cons, 'm^3')
|
966
|
-
@runner.registerValue("monthly_consumption_#{end_use_name}_#{fuel_type_name}_month_#{i + 1}", mon_energy_cons, 'm^3')
|
967
|
-
else
|
968
|
-
fuel_type_elems << OpenStudio::Attribute.new('month', mon_energy_cons, 'GJ')
|
969
|
-
@runner.registerValue("monthly_consumption_#{end_use_name}_#{fuel_type_name}_month_#{i + 1}", mon_energy_cons, 'GJ')
|
970
|
-
end
|
971
|
-
end
|
972
|
-
# record the annual total
|
973
|
-
fuel_type_elems << OpenStudio::Attribute.new('year', ann_energy_cons, 'GJ')
|
974
|
-
@runner.registerValue("monthly_consumption_#{end_use_name}_#{fuel_type_name}_year", ann_energy_cons, 'GJ')
|
975
|
-
# add this fuel type
|
976
|
-
end_use_elems << OpenStudio::Attribute.new(fuel_type_alias_map[end_use_fuel_type.value], fuel_type_elems)
|
977
|
-
end
|
978
|
-
# add this end use
|
979
|
-
cons_elems << OpenStudio::Attribute.new(end_use_map[end_use_cat.value], end_use_elems)
|
980
|
-
end
|
981
|
-
# end consumption
|
982
|
-
monthly_elems << OpenStudio::Attribute.new('consumption', cons_elems)
|
983
|
-
|
984
|
-
# create a unit to use
|
985
|
-
watt_unit = OpenStudio.createUnit('W').get
|
986
|
-
kilowatt_unit = OpenStudio.createUnit('kW').get
|
987
|
-
|
988
|
-
# demand
|
989
|
-
demand_elems = OpenStudio::AttributeVector.new
|
990
|
-
# loop through all end uses
|
991
|
-
end_use_cat_types.each do |end_use_cat|
|
992
|
-
end_use_elems = OpenStudio::AttributeVector.new
|
993
|
-
end_use_name = end_use_map[end_use_cat.value]
|
994
|
-
# in each end use, loop through all fuel types
|
995
|
-
end_use_fuel_types.each do |end_use_fuel_type|
|
996
|
-
fuel_type_elems = OpenStudio::AttributeVector.new
|
997
|
-
fuel_type_name = fuel_type_alias_map[end_use_fuel_type.value]
|
998
|
-
ann_peak_demand = 0.0
|
999
|
-
# in each end use, loop through months and get monthly enedy consumption
|
1000
|
-
months.each_with_index do |month, i|
|
1001
|
-
mon_peak_demand = 0.0
|
1002
|
-
val = @sql.peakEnergyDemandByMonth(end_use_fuel_type, end_use_cat, month)
|
1003
|
-
if val.is_initialized
|
1004
|
-
mon_peak_demand_W = OpenStudio::Quantity.new(val.get, watt_unit)
|
1005
|
-
mon_peak_demand = OpenStudio.convert(mon_peak_demand_W, kilowatt_unit).get.value
|
1006
|
-
end
|
1007
|
-
# record the monthly value
|
1008
|
-
fuel_type_elems << OpenStudio::Attribute.new('month', mon_peak_demand, 'kW')
|
1009
|
-
@runner.registerValue("monthly_demand_#{end_use_name}_#{fuel_type_name}_month_#{i + 1}", mon_peak_demand, 'kW')
|
1010
|
-
# if month peak demand > ann peak demand make this new ann peak demand
|
1011
|
-
if mon_peak_demand > ann_peak_demand
|
1012
|
-
ann_peak_demand = mon_peak_demand
|
1013
|
-
end
|
1014
|
-
end
|
1015
|
-
# record the annual peak demand
|
1016
|
-
fuel_type_elems << OpenStudio::Attribute.new('year', ann_peak_demand, 'kW')
|
1017
|
-
@runner.registerValue("monthly_demand_#{end_use_name}_#{fuel_type_name}_year", ann_peak_demand, 'kW')
|
1018
|
-
# add this fuel type
|
1019
|
-
end_use_elems << OpenStudio::Attribute.new(fuel_type_alias_map[end_use_fuel_type.value], fuel_type_elems)
|
1020
|
-
end
|
1021
|
-
# add this end use
|
1022
|
-
demand_elems << OpenStudio::Attribute.new(end_use_map[end_use_cat.value], end_use_elems)
|
1023
|
-
end
|
1024
|
-
# end demand
|
1025
|
-
monthly_elems << OpenStudio::Attribute.new('demand', demand_elems)
|
1026
|
-
|
1027
|
-
# end monthly
|
1028
|
-
result_elems << OpenStudio::Attribute.new('monthly', monthly_elems)
|
1029
|
-
|
1030
|
-
result_elem = OpenStudio::Attribute.new('results', result_elems)
|
1031
|
-
return result_elem
|
1032
|
-
end # end create_results
|
1033
|
-
end
|