openstudio-extension 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +14 -0
  4. data/LICENSE.md +1 -1
  5. data/README.md +2 -0
  6. data/lib/openstudio/extension/runner.rb +12 -8
  7. data/lib/openstudio/extension/runner_config.rb +33 -6
  8. data/lib/openstudio/extension/version.rb +1 -1
  9. data/openstudio-extension.gemspec +6 -6
  10. metadata +18 -75
  11. data/lib/openstudio/extension/core/CreateResults.rb +0 -1033
  12. data/lib/openstudio/extension/core/check_air_sys_temps.rb +0 -160
  13. data/lib/openstudio/extension/core/check_calibration.rb +0 -125
  14. data/lib/openstudio/extension/core/check_cond_zns.rb +0 -54
  15. data/lib/openstudio/extension/core/check_domestic_hot_water.rb +0 -304
  16. data/lib/openstudio/extension/core/check_envelope_conductance.rb +0 -423
  17. data/lib/openstudio/extension/core/check_eui_by_end_use.rb +0 -132
  18. data/lib/openstudio/extension/core/check_eui_reasonableness.rb +0 -105
  19. data/lib/openstudio/extension/core/check_fan_pwr.rb +0 -68
  20. data/lib/openstudio/extension/core/check_internal_loads.rb +0 -363
  21. data/lib/openstudio/extension/core/check_mech_sys_capacity.rb +0 -196
  22. data/lib/openstudio/extension/core/check_mech_sys_efficiency.rb +0 -296
  23. data/lib/openstudio/extension/core/check_mech_sys_part_load_eff.rb +0 -434
  24. data/lib/openstudio/extension/core/check_mech_sys_type.rb +0 -109
  25. data/lib/openstudio/extension/core/check_part_loads.rb +0 -421
  26. data/lib/openstudio/extension/core/check_placeholder.rb +0 -45
  27. data/lib/openstudio/extension/core/check_plant_cap.rb +0 -93
  28. data/lib/openstudio/extension/core/check_plant_temps.rb +0 -129
  29. data/lib/openstudio/extension/core/check_plenum_loads.rb +0 -57
  30. data/lib/openstudio/extension/core/check_pump_pwr.rb +0 -78
  31. data/lib/openstudio/extension/core/check_sch_coord.rb +0 -211
  32. data/lib/openstudio/extension/core/check_schedules.rb +0 -281
  33. data/lib/openstudio/extension/core/check_simultaneous_heating_and_cooling.rb +0 -128
  34. data/lib/openstudio/extension/core/check_supply_air_and_thermostat_temp_difference.rb +0 -118
  35. data/lib/openstudio/extension/core/check_weather_files.rb +0 -102
  36. data/lib/openstudio/extension/core/deer_vintages.rb +0 -281
  37. data/lib/openstudio/extension/core/os_lib_aedg_measures.rb +0 -461
  38. data/lib/openstudio/extension/core/os_lib_constructions.rb +0 -353
  39. data/lib/openstudio/extension/core/os_lib_geometry.rb +0 -1169
  40. data/lib/openstudio/extension/core/os_lib_helper_methods.rb +0 -383
  41. data/lib/openstudio/extension/core/os_lib_hvac.rb +0 -2163
  42. data/lib/openstudio/extension/core/os_lib_lighting_and_equipment.rb +0 -184
  43. data/lib/openstudio/extension/core/os_lib_model_generation.rb +0 -3584
  44. data/lib/openstudio/extension/core/os_lib_model_simplification.rb +0 -1019
  45. data/lib/openstudio/extension/core/os_lib_outdoorair_and_infiltration.rb +0 -135
  46. data/lib/openstudio/extension/core/os_lib_reporting_qaqc.rb +0 -170
  47. data/lib/openstudio/extension/core/os_lib_schedules.rb +0 -933
@@ -1,434 +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_QAQC
7
- # include any general notes about QAQC method here
8
- # 'standard performance curves' based on what is in OpenStudio standards for prototype building
9
- # initially the tollerance will be hard coded vs. passed in as a method argument
10
-
11
- # checks the number of unmet hours in the model
12
- def check_mech_sys_part_load_eff(category, target_standard, min_pass, max_pass, name_only = false)
13
- if target_standard.include?('90.1')
14
- display_standard = "ASHRAE #{target_standard}"
15
- else
16
- display_standard = target_standard
17
- end
18
-
19
- component_type_array = ['ChillerElectricEIR', 'CoilCoolingDXSingleSpeed', 'CoilCoolingDXTwoSpeed', 'CoilHeatingDXSingleSpeed']
20
-
21
- # summary of the check
22
- check_elems = OpenStudio::AttributeVector.new
23
- check_elems << OpenStudio::Attribute.new('name', 'Mechanical System Part Load Efficiency')
24
- check_elems << OpenStudio::Attribute.new('category', category)
25
- check_elems << OpenStudio::Attribute.new('description', "Check 40% and 80% part load efficency against #{display_standard} for the following compenent types: #{component_type_array.join(', ')}. Checking EIR Function of Part Load Ratio curve for chiller and EIR Function of Flow Fraction for DX coils.")
26
- # TODO: - add in check for VAV fan
27
-
28
- # stop here if only name is requested this is used to populate display name for arguments
29
- if name_only == true
30
- results = []
31
- check_elems.each do |elem|
32
- results << elem.valueAsString
33
- end
34
- return results
35
- end
36
-
37
- # Versions of OpenStudio greater than 2.4.0 use a modified version of
38
- # openstudio-standards with different method calls. These methods
39
- # require a "Standard" object instead of the standard being passed into method calls.
40
- # This Standard object is used throughout the QAQC check.
41
- if OpenStudio::VersionString.new(OpenStudio.openStudioVersion) < OpenStudio::VersionString.new('2.4.3')
42
- use_old_gem_code = true
43
- else
44
- use_old_gem_code = false
45
- std = Standard.build(target_standard)
46
- end
47
-
48
- begin
49
- # TODO: - in future would be nice to dynamically genrate list of possible options from standards json
50
- chiller_air_cooled_condenser_types = ['WithCondenser', 'WithoutCondenser']
51
- chiller_water_cooled_compressor_types = ['Reciprocating', 'Scroll', 'Rotary Screw', 'Centrifugal']
52
- absorption_types = ['Single Effect', 'Double Effect Indirect Fired', 'Double Effect Direct Fired']
53
-
54
- # check getChillerElectricEIRs objects (will also have curve check in different script)
55
- @model.getChillerElectricEIRs.each do |component|
56
- # get curve and evaluate
57
- electric_input_to_cooling_output_ratio_function_of_PLR = component.electricInputToCoolingOutputRatioFunctionOfPLR
58
- curve_40_pct = electric_input_to_cooling_output_ratio_function_of_PLR.evaluate(0.4)
59
- curve_80_pct = electric_input_to_cooling_output_ratio_function_of_PLR.evaluate(0.8)
60
-
61
- # find ac properties
62
- if use_old_gem_code
63
- search_criteria = component.find_search_criteria(target_standard)
64
- else
65
- search_criteria = std.chiller_electric_eir_find_search_criteria(component)
66
- end
67
-
68
- # extend search_criteria for absorption_type
69
- absorption_types.each do |absorption_type|
70
- if component.name.to_s.include?(absorption_type)
71
- search_criteria['absorption_type'] = absorption_type
72
- next
73
- end
74
- end
75
- # extend search_criteria for condenser type or compressor type
76
- if search_criteria['cooling_type'] == 'AirCooled'
77
- chiller_air_cooled_condenser_types.each do |condenser_type|
78
- if component.name.to_s.include?(condenser_type)
79
- search_criteria['condenser_type'] = condenser_type
80
- next
81
- end
82
- end
83
- # if no match and also no absorption_type then issue warning
84
- if !search_criteria.key?('condenser_type') || search_criteria['condenser_type'].nil?
85
- if !search_criteria.key?('absorption_type') || search_criteria['absorption_type'].nil?
86
- check_elems << OpenStudio::Attribute.new('flag', "Can't find unique search criteria for #{component.name}. #{search_criteria}")
87
- next # don't go past here
88
- end
89
- end
90
- elsif search_criteria['cooling_type'] == 'WaterCooled'
91
- chiller_air_cooled_condenser_types.each do |compressor_type|
92
- if component.name.to_s.include?(compressor_type)
93
- search_criteria['compressor_type'] = compressor_type
94
- next
95
- end
96
- end
97
- # if no match and also no absorption_type then issue warning
98
- if !search_criteria.key?('compressor_type') || search_criteria['compressor_type'].nil?
99
- if !search_criteria.key?('absorption_type') || search_criteria['absorption_type'].nil?
100
- check_elems << OpenStudio::Attribute.new('flag', "Can't find unique search criteria for #{component.name}. #{search_criteria}")
101
- next # don't go past here
102
- end
103
- end
104
- end
105
-
106
- # lookup chiller
107
- if use_old_gem_code
108
- capacity_w = component.find_capacity
109
- else
110
- capacity_w = std.chiller_electric_eir_find_capacity(component)
111
- end
112
- capacity_tons = OpenStudio.convert(capacity_w, 'W', 'ton').get
113
-
114
- if use_old_gem_code
115
- chlr_props = component.model.find_object($os_standards['chillers'], search_criteria, capacity_tons, Date.today)
116
- chlr_props
117
- chlr_props = std.model_find_object(std.standards_data['chillers'], search_criteria, capacity_tons, Date.today)
118
- end
119
- if chlr_props.nil?
120
- check_elems << OpenStudio::Attribute.new('flag', "Didn't find chiller for #{component.name}. #{search_criteria}")
121
- next # don't go past here in loop if can't find curve
122
- end
123
-
124
- # temp model to hold temp curve
125
- model_temp = OpenStudio::Model::Model.new
126
-
127
- # create temp curve
128
- target_curve_name = chlr_props['eirfplr']
129
- if target_curve_name.nil?
130
- check_elems << OpenStudio::Attribute.new('flag', "Can't find target eirfplr curve for #{component.name}")
131
- next # don't go past here in loop if can't find curve
132
- end
133
- if use_old_gem_code
134
- temp_curve = model_temp.add_curve(target_curve_name)
135
- else
136
- temp_curve = std.model_add_curve(model_temp, target_curve_name)
137
- end
138
-
139
- target_curve_40_pct = temp_curve.evaluate(0.4)
140
- target_curve_80_pct = temp_curve.evaluate(0.8)
141
-
142
- # check curve at two points
143
- if curve_40_pct < target_curve_40_pct * (1.0 - min_pass)
144
- check_elems << OpenStudio::Attribute.new('flag', "The curve value at 40% of #{curve_40_pct.round(2)} for #{component.name} is more than #{min_pass * 100} % below the typical value of #{target_curve_40_pct.round(2)} for #{display_standard}.")
145
- elsif curve_40_pct > target_curve_40_pct * (1.0 + max_pass)
146
- check_elems << OpenStudio::Attribute.new('flag', "The curve value at 40% of #{curve_40_pct.round(2)} for #{component.name} is more than #{max_pass * 100} % above the typical value of #{target_curve_40_pct.round(2)} for #{display_standard}.")
147
- end
148
- if curve_80_pct < target_curve_80_pct * (1.0 - min_pass)
149
- check_elems << OpenStudio::Attribute.new('flag', "The curve value at 80% of #{curve_80_pct.round(2)} for #{component.name} is more than #{min_pass * 100} % below the typical value of #{target_curve_80_pct.round(2)} for #{display_standard}.")
150
- elsif curve_80_pct > target_curve_80_pct * (1.0 + max_pass)
151
- check_elems << OpenStudio::Attribute.new('flag', "The curve value at 80% of #{curve_80_pct.round(2)} for #{component.name} is more than #{max_pass * 100} % above the typical value of #{target_curve_80_pct.round(2)} for #{display_standard}.")
152
- end
153
- end
154
-
155
- # check getCoilCoolingDXSingleSpeeds objects (will also have curve check in different script)
156
- @model.getCoilCoolingDXSingleSpeeds.each do |component|
157
- # get curve and evaluate
158
- eir_function_of_flow_fraction_curve = component.energyInputRatioFunctionOfFlowFractionCurve
159
- curve_40_pct = eir_function_of_flow_fraction_curve.evaluate(0.4)
160
- curve_80_pct = eir_function_of_flow_fraction_curve.evaluate(0.8)
161
-
162
- # find ac properties
163
- if use_old_gem_code
164
- search_criteria = component.find_search_criteria(target_standard)
165
- else
166
- search_criteria = std.coil_dx_find_search_criteria(component)
167
- end
168
-
169
- if use_old_gem_code
170
- capacity_w = component.find_capacity
171
- else
172
- capacity_w = std.coil_cooling_dx_single_speed_find_capacity(component)
173
- end
174
- capacity_btu_per_hr = OpenStudio.convert(capacity_w, 'W', 'Btu/hr').get
175
-
176
- if use_old_gem_code
177
- if component.heat_pump?
178
- ac_props = component.model.find_object($os_standards['heat_pumps'], search_criteria, capacity_btu_per_hr, Date.today)
179
- else
180
- ac_props = component.model.find_object($os_standards['unitary_acs'], search_criteria, capacity_btu_per_hr, Date.today)
181
- end
182
- else
183
- if std.coil_dx_heat_pump?(component)
184
- ac_props = std.model_find_object(std.standards_data['heat_pumps'], search_criteria, capacity_btu_per_hr, Date.today)
185
- else
186
- ac_props = std.model_find_object(std.standards_data['unitary_acs'], search_criteria, capacity_btu_per_hr, Date.today)
187
- end
188
- end
189
-
190
- # temp model to hold temp curve
191
- model_temp = OpenStudio::Model::Model.new
192
-
193
- # create temp curve
194
- target_curve_name = ac_props['cool_eir_fflow']
195
- if target_curve_name.nil?
196
- check_elems << OpenStudio::Attribute.new('flag', "Can't find target cool_eir_fflow curve for #{component.name}")
197
- next # don't go past here in loop if can't find curve
198
- end
199
- if use_old_gem_code
200
- temp_curve = model_temp.add_curve(target_curve_name)
201
- else
202
- temp_curve = std.model_add_curve(model_temp, target_curve_name)
203
- end
204
- target_curve_40_pct = temp_curve.evaluate(0.4)
205
- target_curve_80_pct = temp_curve.evaluate(0.8)
206
-
207
- # check curve at two points
208
- if curve_40_pct < target_curve_40_pct * (1.0 - min_pass)
209
- check_elems << OpenStudio::Attribute.new('flag', "The curve value at 40% of #{curve_40_pct.round(2)} for #{component.name} is more than #{min_pass * 100} % below the typical value of #{target_curve_40_pct.round(2)} for #{display_standard}.")
210
- elsif curve_40_pct > target_curve_40_pct * (1.0 + max_pass)
211
- check_elems << OpenStudio::Attribute.new('flag', "The curve value at 40% of #{curve_40_pct.round(2)} for #{component.name} is more than #{max_pass * 100} % above the typical value of #{target_curve_40_pct.round(2)} for #{display_standard}.")
212
- end
213
- if curve_80_pct < target_curve_80_pct * (1.0 - min_pass)
214
- check_elems << OpenStudio::Attribute.new('flag', "The curve value at 80% of #{curve_80_pct.round(2)} for #{component.name} is more than #{min_pass * 100} % below the typical value of #{target_curve_80_pct.round(2)} for #{display_standard}.")
215
- elsif curve_80_pct > target_curve_80_pct * (1.0 + max_pass)
216
- check_elems << OpenStudio::Attribute.new('flag', "The curve value at 80% of #{curve_80_pct.round(2)} for #{component.name} is more than #{max_pass * 100} % above the typical value of #{target_curve_80_pct.round(2)} for #{display_standard}.")
217
- end
218
- end
219
-
220
- # check CoilCoolingDXTwoSpeed objects (will also have curve check in different script)
221
- @model.getCoilCoolingDXTwoSpeeds.each do |component|
222
- # get curve and evaluate
223
- eir_function_of_flow_fraction_curve = component.energyInputRatioFunctionOfFlowFractionCurve
224
- curve_40_pct = eir_function_of_flow_fraction_curve.evaluate(0.4)
225
- curve_80_pct = eir_function_of_flow_fraction_curve.evaluate(0.8)
226
-
227
- # find ac properties
228
- if use_old_gem_code
229
- search_criteria = component.find_search_criteria(target_standard)
230
- else
231
- search_criteria = std.coil_dx_find_search_criteria(component)
232
- end
233
-
234
- if use_old_gem_code
235
- capacity_w = component.find_capacity
236
- else
237
- capacity_w = std.coil_cooling_dx_two_speed_find_capacity(component)
238
- end
239
- capacity_btu_per_hr = OpenStudio.convert(capacity_w, 'W', 'Btu/hr').get
240
-
241
- if use_old_gem_code
242
- ac_props = component.model.find_object($os_standards['unitary_acs'], search_criteria, capacity_btu_per_hr, Date.today)
243
- else
244
- ac_props = std.model_find_object(std.standards_data['unitary_acs'], search_criteria, capacity_btu_per_hr, Date.today)
245
- end
246
-
247
- # temp model to hold temp curve
248
- model_temp = OpenStudio::Model::Model.new
249
-
250
- # create temp curve
251
- target_curve_name = ac_props['cool_eir_fflow']
252
- if target_curve_name.nil?
253
- check_elems << OpenStudio::Attribute.new('flag', "Can't find target cool_eir_flow curve for #{component.name}")
254
- next # don't go past here in loop if can't find curve
255
- end
256
- if use_old_gem_code
257
- temp_curve = model_temp.add_curve(target_curve_name)
258
- else
259
- temp_curve = std.model_add_curve(model_temp, target_curve_name)
260
- end
261
- target_curve_40_pct = temp_curve.evaluate(0.4)
262
- target_curve_80_pct = temp_curve.evaluate(0.8)
263
-
264
- # check curve at two points
265
- if curve_40_pct < target_curve_40_pct * (1.0 - min_pass)
266
- check_elems << OpenStudio::Attribute.new('flag', "The curve value at 40% of #{curve_40_pct.round(2)} for #{component.name} is more than #{min_pass * 100} % below the typical value of #{target_curve_40_pct.round(2)} for #{display_standard}.")
267
- elsif curve_40_pct > target_curve_40_pct * (1.0 + max_pass)
268
- check_elems << OpenStudio::Attribute.new('flag', "The curve value at 40% of #{curve_40_pct.round(2)} for #{component.name} is more than #{max_pass * 100} % above the typical value of #{target_curve_40_pct.round(2)} for #{display_standard}.")
269
- end
270
- if curve_80_pct < target_curve_80_pct * (1.0 - min_pass)
271
- check_elems << OpenStudio::Attribute.new('flag', "The curve value at 80% of #{curve_80_pct.round(2)} for #{component.name} is more than #{min_pass * 100} % below the typical value of #{target_curve_80_pct.round(2)} for #{display_standard}.")
272
- elsif curve_80_pct > target_curve_80_pct * (1.0 + max_pass)
273
- check_elems << OpenStudio::Attribute.new('flag', "The curve value at 80% of #{curve_80_pct.round(2)} for #{component.name} is more than #{max_pass * 100} % above the typical value of #{target_curve_80_pct.round(2)} for #{display_standard}.")
274
- end
275
- end
276
-
277
- # check CoilCoolingDXTwoSpeed objects (will also have curve check in different script)
278
- @model.getCoilHeatingDXSingleSpeeds.each do |component|
279
- # get curve and evaluate
280
- eir_function_of_flow_fraction_curve = component.energyInputRatioFunctionofFlowFractionCurve # why lowercase of here but not in CoilCoolingDX objects
281
- curve_40_pct = eir_function_of_flow_fraction_curve.evaluate(0.4)
282
- curve_80_pct = eir_function_of_flow_fraction_curve.evaluate(0.8)
283
-
284
- # find ac properties
285
- if use_old_gem_code
286
- search_criteria = component.find_search_criteria(target_standard)
287
- else
288
- search_criteria = std.coil_dx_find_search_criteria(component)
289
- end
290
-
291
- if use_old_gem_code
292
- capacity_w = component.find_capacity
293
- else
294
- capacity_w = std.coil_heating_dx_single_speed_find_capacity(component)
295
- end
296
- capacity_btu_per_hr = OpenStudio.convert(capacity_w, 'W', 'Btu/hr').get
297
-
298
- if use_old_gem_code
299
- ac_props = component.model.find_object($os_standards['heat_pumps_heating'], search_criteria, capacity_btu_per_hr, Date.today)
300
- else
301
- ac_props = std.model_find_object(std.standards_data['heat_pumps_heating'], search_criteria, capacity_btu_per_hr, Date.today)
302
- end
303
- if ac_props.nil?
304
- target_curve_name = nil
305
- else
306
- target_curve_name = ac_props['heat_eir_fflow']
307
- end
308
-
309
- # temp model to hold temp curve
310
- model_temp = OpenStudio::Model::Model.new
311
-
312
- # create temp curve
313
- if target_curve_name.nil?
314
- check_elems << OpenStudio::Attribute.new('flag', "Can't find target curve for #{component.name}")
315
- next # don't go past here in loop if can't find curve
316
- end
317
- if use_old_gem_code
318
- temp_curve = model_temp.add_curve(target_curve_name)
319
- else
320
- temp_curve = std.model_add_curve(model_temp, target_curve_name)
321
- end
322
-
323
- # Ensure that the curve was found in standards before attempting to evaluate
324
- if temp_curve.nil?
325
- check_elems << OpenStudio::Attribute.new('flag', "Can't find coefficients of curve called #{target_curve_name} for #{component.name}, cannot check part-load performance.")
326
- next
327
- end
328
-
329
- target_curve_40_pct = temp_curve.evaluate(0.4)
330
- target_curve_80_pct = temp_curve.evaluate(0.8)
331
-
332
- # check curve at two points
333
- if curve_40_pct < target_curve_40_pct * (1.0 - min_pass)
334
- check_elems << OpenStudio::Attribute.new('flag', "The curve value at 40% of #{curve_40_pct.round(2)} for #{component.name} is more than #{min_pass * 100} % below the typical value of #{target_curve_40_pct.round(2)} for #{display_standard}.")
335
- elsif curve_40_pct > target_curve_40_pct * (1.0 + max_pass)
336
- check_elems << OpenStudio::Attribute.new('flag', "The curve value at 40% of #{curve_40_pct.round(2)} for #{component.name} is more than #{max_pass * 100} % above the typical value of #{target_curve_40_pct.round(2)} for #{display_standard}.")
337
- end
338
- if curve_80_pct < target_curve_80_pct * (1.0 - min_pass)
339
- check_elems << OpenStudio::Attribute.new('flag', "The curve value at 80% of #{curve_80_pct.round(2)} for #{component.name} is more than #{min_pass * 100} % below the typical value of #{target_curve_80_pct.round(2)} for #{display_standard}.")
340
- elsif curve_80_pct > target_curve_80_pct * (1.0 + max_pass)
341
- check_elems << OpenStudio::Attribute.new('flag', "The curve value at 80% of #{curve_80_pct.round(2)} for #{component.name} is more than #{max_pass * 100} % above the typical value of #{target_curve_80_pct.round(2)} for #{display_standard}.")
342
- end
343
- end
344
-
345
- # check
346
- @model.getFanVariableVolumes.each do |component|
347
- # skip if not on multi-zone system.
348
- if component.airLoopHVAC.is_initialized
349
- airloop = component.airLoopHVAC.get
350
-
351
- next unless airloop.thermalZones.size > 1.0
352
- end
353
-
354
- # skip of brake horsepower is 0
355
- if use_old_gem_code
356
- next if component.brake_horsepower == 0.0
357
- else
358
- next if std.fan_brake_horsepower(component) == 0.0
359
- end
360
-
361
- # temp model for use by temp model and target curve
362
- model_temp = OpenStudio::Model::Model.new
363
-
364
- # get coeficents for fan
365
- model_fan_coefs = []
366
- model_fan_coefs << component.fanPowerCoefficient1.get
367
- model_fan_coefs << component.fanPowerCoefficient2.get
368
- model_fan_coefs << component.fanPowerCoefficient3.get
369
- model_fan_coefs << component.fanPowerCoefficient4.get
370
- model_fan_coefs << component.fanPowerCoefficient5.get
371
-
372
- # make model curve
373
- model_curve = OpenStudio::Model::CurveQuartic.new(model_temp)
374
- model_curve.setCoefficient1Constant(model_fan_coefs[0])
375
- model_curve.setCoefficient2x(model_fan_coefs[1])
376
- model_curve.setCoefficient3xPOW2(model_fan_coefs[2])
377
- model_curve.setCoefficient4xPOW3(model_fan_coefs[3])
378
- model_curve.setCoefficient5xPOW4(model_fan_coefs[4])
379
- curve_40_pct = model_curve.evaluate(0.4)
380
- curve_80_pct = model_curve.evaluate(0.8)
381
-
382
- # get target coefs
383
- target_fan = OpenStudio::Model::FanVariableVolume.new(model_temp)
384
- if use_old_gem_code
385
- target_fan.set_control_type('Multi Zone VAV with Static Pressure Reset')
386
- else
387
- std.fan_variable_volume_set_control_type(target_fan, 'Multi Zone VAV with VSD and Static Pressure Reset')
388
- end
389
-
390
- # get coeficents for fan
391
- target_fan_coefs = []
392
- target_fan_coefs << target_fan.fanPowerCoefficient1.get
393
- target_fan_coefs << target_fan.fanPowerCoefficient2.get
394
- target_fan_coefs << target_fan.fanPowerCoefficient3.get
395
- target_fan_coefs << target_fan.fanPowerCoefficient4.get
396
- target_fan_coefs << target_fan.fanPowerCoefficient5.get
397
-
398
- # make model curve
399
- target_curve = OpenStudio::Model::CurveQuartic.new(model_temp)
400
- target_curve.setCoefficient1Constant(target_fan_coefs[0])
401
- target_curve.setCoefficient2x(target_fan_coefs[1])
402
- target_curve.setCoefficient3xPOW2(target_fan_coefs[2])
403
- target_curve.setCoefficient4xPOW3(target_fan_coefs[3])
404
- target_curve.setCoefficient5xPOW4(target_fan_coefs[4])
405
- target_curve_40_pct = target_curve.evaluate(0.4)
406
- target_curve_80_pct = target_curve.evaluate(0.8)
407
-
408
- # check curve at two points
409
- if curve_40_pct < target_curve_40_pct * (1.0 - min_pass)
410
- check_elems << OpenStudio::Attribute.new('flag', "The curve value at 40% of #{curve_40_pct.round(2)} for #{component.name} is more than #{min_pass * 100} % below the typical value of #{target_curve_40_pct.round(2)} for #{display_standard}.")
411
- elsif curve_40_pct > target_curve_40_pct * (1.0 + max_pass)
412
- check_elems << OpenStudio::Attribute.new('flag', "The curve value at 40% of #{curve_40_pct.round(2)} for #{component.name} is more than #{max_pass * 100} % above the typical value of #{target_curve_40_pct.round(2)} for #{display_standard}.")
413
- end
414
- if curve_80_pct < target_curve_80_pct * (1.0 - min_pass)
415
- check_elems << OpenStudio::Attribute.new('flag', "The curve value at 80% of #{curve_80_pct.round(2)} for #{component.name} is more than #{min_pass * 100} % below the typical value of #{target_curve_80_pct.round(2)} for #{display_standard}.")
416
- elsif curve_80_pct > target_curve_80_pct * (1.0 + max_pass)
417
- check_elems << OpenStudio::Attribute.new('flag', "The curve value at 80% of #{curve_80_pct.round(2)} for #{component.name} is more than #{max_pass * 100} % above the typical value of #{target_curve_80_pct.round(2)} for #{display_standard}.")
418
- end
419
- end
420
- rescue StandardError => e
421
- # brief description of ruby error
422
- check_elems << OpenStudio::Attribute.new('flag', "Error prevented QAQC check from running (#{e}).")
423
-
424
- # backtrace of ruby error for diagnostic use
425
- if @error_backtrace then check_elems << OpenStudio::Attribute.new('flag', e.backtrace.join("\n").to_s) end
426
- end
427
-
428
- # add check_elms to new attribute
429
- check_elem = OpenStudio::Attribute.new('check', check_elems)
430
-
431
- return check_elem
432
- # note: registerWarning and registerValue will be added for checks downstream using os_lib_reporting_qaqc.rb
433
- end
434
- end
@@ -1,109 +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_QAQC
7
- # include any general notes about QAQC method here
8
-
9
- # checks the number of unmet hours in the model
10
- def check_mech_sys_type(category, target_standard, name_only = false)
11
- # summary of the check
12
- check_elems = OpenStudio::AttributeVector.new
13
- check_elems << OpenStudio::Attribute.new('name', 'Mechanical System Type')
14
- check_elems << OpenStudio::Attribute.new('category', category)
15
-
16
- # add ASHRAE to display of target standard if includes with 90.1
17
- if target_standard.include?('90.1 2013')
18
- check_elems << OpenStudio::Attribute.new('description', 'Check against ASHRAE 90.1 2013 Tables G3.1.1 A-B. Infers the baseline system type based on the equipment serving the zone and their heating/cooling fuels. Only does a high-level inference; does not look for the presence/absence of required controls, etc.')
19
- else
20
- check_elems << OpenStudio::Attribute.new('description', 'Check against ASHRAE 90.1. Infers the baseline system type based on the equipment serving the zone and their heating/cooling fuels. Only does a high-level inference; does not look for the presence/absence of required controls, etc.')
21
- end
22
-
23
- # stop here if only name is requested this is used to populate display name for arguments
24
- if name_only == true
25
- results = []
26
- check_elems.each do |elem|
27
- results << elem.valueAsString
28
- end
29
- return results
30
- end
31
-
32
- # Versions of OpenStudio greater than 2.4.0 use a modified version of
33
- # openstudio-standards with different method calls. These methods
34
- # require a "Standard" object instead of the standard being passed into method calls.
35
- # This Standard object is used throughout the QAQC check.
36
- if OpenStudio::VersionString.new(OpenStudio.openStudioVersion) < OpenStudio::VersionString.new('2.4.3')
37
- use_old_gem_code = true
38
- else
39
- use_old_gem_code = false
40
- std = Standard.build(target_standard)
41
- end
42
-
43
- begin
44
- # Get the actual system type for all zones in the model
45
- act_zone_to_sys_type = {}
46
- @model.getThermalZones.each do |zone|
47
- if use_old_gem_code
48
- act_zone_to_sys_type[zone] = zone.infer_system_type
49
- else
50
- act_zone_to_sys_type[zone] = std.thermal_zone_infer_system_type(zone)
51
- end
52
- end
53
-
54
- # Get the baseline system type for all zones in the model
55
- if use_old_gem_code
56
- climate_zone = @model.get_building_climate_zone_and_building_type['climate_zone']
57
- else
58
- climate_zone = std.model_get_building_properties(@model)['climate_zone']
59
- end
60
-
61
- if use_old_gem_code
62
- req_zone_to_sys_type = @model.get_baseline_system_type_by_zone(target_standard, climate_zone)
63
- else
64
- req_zone_to_sys_type = std.model_get_baseline_system_type_by_zone(@model, climate_zone)
65
- end
66
-
67
- # Compare the actual to the correct
68
- @model.getThermalZones.each do |zone|
69
- # TODO: - skip if plenum
70
- is_plenum = false
71
- zone.spaces.each do |space|
72
- if use_old_gem_code
73
- if space.plenum?
74
- is_plenum = true
75
- end
76
- else
77
- if std.space_plenum?(space)
78
- is_plenum = true
79
- end
80
- end
81
- end
82
- next if is_plenum
83
-
84
- req_sys_type = req_zone_to_sys_type[zone]
85
- act_sys_type = act_zone_to_sys_type[zone]
86
-
87
- if act_sys_type == req_sys_type
88
- puts "#{zone.name} system type = #{act_sys_type}"
89
- else
90
- if req_sys_type == '' then req_sys_type = 'Unknown' end
91
- puts "#{zone.name} baseline system type is incorrect. Supposed to be #{req_sys_type}, but was #{act_sys_type} instead."
92
- check_elems << OpenStudio::Attribute.new('flag', "#{zone.name} baseline system type is incorrect. Supposed to be #{req_sys_type}, but was #{act_sys_type} instead.")
93
- end
94
- end
95
- rescue StandardError => e
96
- # brief description of ruby error
97
- check_elems << OpenStudio::Attribute.new('flag', "Error prevented QAQC check from running (#{e}).")
98
-
99
- # backtrace of ruby error for diagnostic use
100
- if @error_backtrace then check_elems << OpenStudio::Attribute.new('flag', e.backtrace.join("\n").to_s) end
101
- end
102
-
103
- # add check_elms to new attribute
104
- check_elem = OpenStudio::Attribute.new('check', check_elems)
105
-
106
- return check_elem
107
- # note: registerWarning and registerValue will be added for checks downstream using os_lib_reporting_qaqc.rb
108
- end
109
- end