openstudio-extension 0.1.0 → 0.1.1

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.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +9 -0
  3. data/.rubocop.yml +9 -0
  4. data/Gemfile +3 -1
  5. data/Jenkinsfile +10 -0
  6. data/README.md +230 -12
  7. data/Rakefile +88 -3
  8. data/bin/console +3 -3
  9. data/doc_templates/LICENSE.md +27 -0
  10. data/doc_templates/README.md.erb +42 -0
  11. data/doc_templates/copyright_erb.txt +36 -0
  12. data/doc_templates/copyright_js.txt +4 -0
  13. data/doc_templates/copyright_ruby.txt +34 -0
  14. data/init_templates/README.md +37 -0
  15. data/init_templates/gemspec.txt +32 -0
  16. data/init_templates/openstudio_module.rb +50 -0
  17. data/init_templates/spec.rb +47 -0
  18. data/init_templates/spec_helper.rb +49 -0
  19. data/init_templates/template_gemfile.txt +17 -0
  20. data/init_templates/template_rakefile.txt +15 -0
  21. data/init_templates/version.rb +40 -0
  22. data/lib/files/openstudio-extension-gem-test.ddy +536 -0
  23. data/lib/files/openstudio-extension-gem-test.epw +8768 -0
  24. data/lib/files/openstudio-extension-gem-test.stat +554 -0
  25. data/lib/measures/openstudio_extension_test_measure/LICENSE.md +27 -0
  26. data/lib/measures/openstudio_extension_test_measure/README.md +26 -0
  27. data/lib/measures/openstudio_extension_test_measure/README.md.erb +42 -0
  28. data/lib/measures/openstudio_extension_test_measure/measure.rb +72 -0
  29. data/lib/measures/openstudio_extension_test_measure/measure.xml +83 -0
  30. data/lib/measures/openstudio_extension_test_measure/resources/os_lib_helper_methods.rb +399 -0
  31. data/lib/measures/openstudio_extension_test_measure/tests/OpenStudioExtensionTestMeasure_Test.rb +75 -0
  32. data/lib/openstudio/extension.rb +220 -0
  33. data/lib/openstudio/extension/core/CreateResults.rb +879 -0
  34. data/lib/openstudio/extension/core/check_air_sys_temps.rb +190 -0
  35. data/lib/openstudio/extension/core/check_calibration.rb +155 -0
  36. data/lib/openstudio/extension/core/check_cond_zns.rb +84 -0
  37. data/lib/openstudio/extension/core/check_domestic_hot_water.rb +334 -0
  38. data/lib/openstudio/extension/core/check_envelope_conductance.rb +453 -0
  39. data/lib/openstudio/extension/core/check_eui_by_end_use.rb +162 -0
  40. data/lib/openstudio/extension/core/check_eui_reasonableness.rb +135 -0
  41. data/lib/openstudio/extension/core/check_fan_pwr.rb +98 -0
  42. data/lib/openstudio/extension/core/check_internal_loads.rb +393 -0
  43. data/lib/openstudio/extension/core/check_mech_sys_capacity.rb +226 -0
  44. data/lib/openstudio/extension/core/check_mech_sys_efficiency.rb +326 -0
  45. data/lib/openstudio/extension/core/check_mech_sys_part_load_eff.rb +464 -0
  46. data/lib/openstudio/extension/core/check_mech_sys_type.rb +139 -0
  47. data/lib/openstudio/extension/core/check_part_loads.rb +451 -0
  48. data/lib/openstudio/extension/core/check_placeholder.rb +75 -0
  49. data/lib/openstudio/extension/core/check_plant_cap.rb +123 -0
  50. data/lib/openstudio/extension/core/check_plant_temps.rb +159 -0
  51. data/lib/openstudio/extension/core/check_plenum_loads.rb +87 -0
  52. data/lib/openstudio/extension/core/check_pump_pwr.rb +108 -0
  53. data/lib/openstudio/extension/core/check_sch_coord.rb +241 -0
  54. data/lib/openstudio/extension/core/check_schedules.rb +311 -0
  55. data/lib/openstudio/extension/core/check_simultaneous_heating_and_cooling.rb +158 -0
  56. data/lib/openstudio/extension/core/check_supply_air_and_thermostat_temp_difference.rb +148 -0
  57. data/lib/openstudio/extension/core/check_weather_files.rb +132 -0
  58. data/lib/openstudio/extension/core/deer_vintages.rb +311 -0
  59. data/lib/openstudio/extension/core/os_lib_aedg_measures.rb +491 -0
  60. data/lib/openstudio/extension/core/os_lib_cofee.rb +259 -0
  61. data/lib/openstudio/extension/core/os_lib_constructions.rb +378 -0
  62. data/lib/openstudio/extension/core/os_lib_geometry.rb +1022 -0
  63. data/lib/openstudio/extension/core/os_lib_helper_methods.rb +399 -0
  64. data/lib/openstudio/extension/core/os_lib_hvac.rb +2171 -0
  65. data/lib/openstudio/extension/core/os_lib_lighting_and_equipment.rb +214 -0
  66. data/lib/openstudio/extension/core/os_lib_model_generation.rb +817 -0
  67. data/lib/openstudio/extension/core/os_lib_model_simplification.rb +1049 -0
  68. data/lib/openstudio/extension/core/os_lib_outdoorair_and_infiltration.rb +165 -0
  69. data/lib/openstudio/extension/core/os_lib_reporting.rb +4652 -0
  70. data/lib/openstudio/extension/core/os_lib_reporting_qaqc.rb +200 -0
  71. data/lib/openstudio/extension/core/os_lib_schedules.rb +963 -0
  72. data/lib/openstudio/extension/rake_task.rb +149 -0
  73. data/lib/openstudio/extension/runner.rb +644 -0
  74. data/lib/openstudio/extension/version.rb +40 -0
  75. data/openstudio-extension.gemspec +20 -15
  76. metadata +150 -14
  77. data/.travis.yml +0 -7
  78. data/lib/OpenStudio/Extension/rake_task.rb +0 -84
  79. data/lib/OpenStudio/Extension/version.rb +0 -33
  80. data/lib/OpenStudio/extension.rb +0 -65
@@ -0,0 +1,75 @@
1
+ # *******************************************************************************
2
+ # OpenStudio(R), Copyright (c) 2008-2019, Alliance for Sustainable Energy, LLC.
3
+ # All rights reserved.
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are met:
6
+ #
7
+ # (1) Redistributions of source code must retain the above copyright notice,
8
+ # this list of conditions and the following disclaimer.
9
+ #
10
+ # (2) Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ #
14
+ # (3) Neither the name of the copyright holder nor the names of any contributors
15
+ # may be used to endorse or promote products derived from this software without
16
+ # specific prior written permission from the respective party.
17
+ #
18
+ # (4) Other than as required in clauses (1) and (2), distributions in any form
19
+ # of modifications or other derivative works may not use the "OpenStudio"
20
+ # trademark, "OS", "os", or any other confusingly similar designation without
21
+ # specific prior written permission from Alliance for Sustainable Energy, LLC.
22
+ #
23
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS
24
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE
27
+ # UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF
28
+ # THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
30
+ # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
32
+ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33
+ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
+ # *******************************************************************************
35
+
36
+ module OsLib_QAQC
37
+ # include any general notes about QAQC method here
38
+
39
+ # checks the number of unmet hours in the model
40
+ def check_placeholder(category, name_only = false)
41
+ # summary of the check
42
+ check_elems = OpenStudio::AttributeVector.new
43
+ check_elems << OpenStudio::Attribute.new('name', 'Place Holder Check')
44
+ check_elems << OpenStudio::Attribute.new('category', category)
45
+ check_elems << OpenStudio::Attribute.new('description', 'This does nothing, it will just throw a flag until I add real check code to the method.')
46
+
47
+ # stop here if only name is requested this is used to populate display name for arguments
48
+ if name_only == true
49
+ results = []
50
+ check_elems.each do |elem|
51
+ results << elem.valueAsString
52
+ end
53
+ return results
54
+ end
55
+
56
+ begin
57
+ # TODO: - implement QAQC check code here
58
+
59
+ # remove this once code is written to do real checks
60
+ check_elems << OpenStudio::Attribute.new('flag', 'Code has not been implemented yet for this QAQC check')
61
+ rescue StandardError => e
62
+ # brief description of ruby error
63
+ check_elems << OpenStudio::Attribute.new('flag', "Error prevented QAQC check from running (#{e}).")
64
+
65
+ # backtrace of ruby error for diagnostic use
66
+ if @error_backtrace then check_elems << OpenStudio::Attribute.new('flag', e.backtrace.join("\n").to_s) end
67
+ end
68
+
69
+ # add check_elms to new attribute
70
+ check_elem = OpenStudio::Attribute.new('check', check_elems)
71
+
72
+ return check_elem
73
+ # note: registerWarning and registerValue will be added for checks downstream using os_lib_reporting_qaqc.rb
74
+ end
75
+ end
@@ -0,0 +1,123 @@
1
+ # *******************************************************************************
2
+ # OpenStudio(R), Copyright (c) 2008-2019, Alliance for Sustainable Energy, LLC.
3
+ # All rights reserved.
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are met:
6
+ #
7
+ # (1) Redistributions of source code must retain the above copyright notice,
8
+ # this list of conditions and the following disclaimer.
9
+ #
10
+ # (2) Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ #
14
+ # (3) Neither the name of the copyright holder nor the names of any contributors
15
+ # may be used to endorse or promote products derived from this software without
16
+ # specific prior written permission from the respective party.
17
+ #
18
+ # (4) Other than as required in clauses (1) and (2), distributions in any form
19
+ # of modifications or other derivative works may not use the "OpenStudio"
20
+ # trademark, "OS", "os", or any other confusingly similar designation without
21
+ # specific prior written permission from Alliance for Sustainable Energy, LLC.
22
+ #
23
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS
24
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE
27
+ # UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF
28
+ # THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
30
+ # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
32
+ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33
+ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
+ # *******************************************************************************
35
+
36
+ module OsLib_QAQC
37
+ # Check primary plant loop heating and cooling equipment capacity against
38
+ # coil loads to find equipment that is significantly oversized or undersized.
39
+ def check_plant_cap(category, target_standard, max_pct_delta = 0.1, name_only = false)
40
+ # summary of the check
41
+ check_elems = OpenStudio::AttributeVector.new
42
+ check_elems << OpenStudio::Attribute.new('name', 'Plant Capacity')
43
+ check_elems << OpenStudio::Attribute.new('category', category)
44
+ check_elems << OpenStudio::Attribute.new('description', 'Check that plant equipment capacity matches loads.')
45
+
46
+ # stop here if only name is requested this is used to populate display name for arguments
47
+ if name_only == true
48
+ results = []
49
+ check_elems.each do |elem|
50
+ results << elem.valueAsString
51
+ end
52
+ return results
53
+ end
54
+
55
+ std = Standard.build(target_standard)
56
+
57
+ begin
58
+ # Check the heating and cooling capacity of the plant loops against their coil loads
59
+ @model.getPlantLoops.each do |plant_loop|
60
+ # Heating capacity
61
+ htg_cap_w = std.plant_loop_total_heating_capacity(plant_loop)
62
+
63
+ # Cooling capacity
64
+ clg_cap_w = std.plant_loop_total_cooling_capacity(plant_loop)
65
+
66
+ # Heating and cooling loads
67
+ plant_loop.demandComponents.each do |dc|
68
+ # Get the load for each coil
69
+ htg_load_w = 0.0
70
+ clg_load_w = 0.0
71
+ obj_type = sc.iddObjectType.valueName.to_s
72
+ case obj_type
73
+ when 'OS_Coil_Heating_Water'
74
+ coil = sc.to_CoilHeatingWater.get
75
+ if coil.ratedCapacity.is_initialized
76
+ clg_load_w += coil.ratedCapacity.get
77
+ elsif coil.autosizedRatedCapacity.is_initialized
78
+ clg_load_w += coil.autosizedRatedCapacity.get
79
+ end
80
+ when 'OS_Coil_Cooling_Water'
81
+ coil = sc.to_CoilCoolingWater.get
82
+ if coil.autosizedDesignCoilLoad.is_initialized
83
+ clg_load_w += coil.autosizedDesignCoilLoad.get
84
+ end
85
+ end
86
+ end
87
+
88
+ # Don't check loops with no loads. These are probably
89
+ # SWH or non-typical loops that can't be checked by simple methods.
90
+
91
+ # Heating
92
+ if htg_load_w > 0
93
+ htg_cap_kbtu_per_hr = OpenStudio.convert(htg_cap_w, 'W', 'kBtu/hr').get.round(1)
94
+ htg_load_kbtu_per_hr = OpenStudio.convert(htg_load_w, 'W', 'kBtu/hr').get.round(1)
95
+ if ((htg_cap_w - htg_load_w) / htg_cap_w).abs > max_pct_delta
96
+ check_elems << OpenStudio::Attribute.new('flag', "For #{plant_loop.name}, the total heating capacity of #{htg_cap_kbtu_per_hr} kBtu/hr is more than #{(max_pct_delta * 100.0).round(2)}% different from the combined coil load of #{htg_load_kbtu_per_hr} kBtu/hr. This could indicate significantly oversized or undersized equipment.")
97
+ end
98
+ end
99
+
100
+ # Cooling
101
+ if clg_load_w > 0
102
+ clg_cap_tons = OpenStudio.convert(clg_cap_w, 'W', 'ton').get.round(1)
103
+ clg_load_tons = OpenStudio.convert(clg_load_w, 'W', 'ton').get.round(1)
104
+ if ((clg_cap_w - clg_load_w) / clg_cap_w).abs > max_pct_delta
105
+ check_elems << OpenStudio::Attribute.new('flag', "For #{plant_loop.name}, the total cooling capacity of #{clg_cap_kbtu_per_hr} tons is more than #{(max_pct_delta * 100.0).round(2)}% different from the combined coil load of #{clg_load_kbtu_per_hr} tons. This could indicate significantly oversized or undersized equipment.")
106
+ end
107
+ end
108
+ end
109
+ rescue StandardError => e
110
+ # brief description of ruby error
111
+ check_elems << OpenStudio::Attribute.new('flag', "Error prevented QAQC check from running (#{e}).")
112
+
113
+ # backtrace of ruby error for diagnostic use
114
+ if @error_backtrace then check_elems << OpenStudio::Attribute.new('flag', e.backtrace.join("\n").to_s) end
115
+ end
116
+
117
+ # add check_elms to new attribute
118
+ check_elem = OpenStudio::Attribute.new('check', check_elems)
119
+
120
+ return check_elem
121
+ # note: registerWarning and registerValue will be added for checks downstream using os_lib_reporting_qaqc.rb
122
+ end
123
+ end
@@ -0,0 +1,159 @@
1
+ # *******************************************************************************
2
+ # OpenStudio(R), Copyright (c) 2008-2019, Alliance for Sustainable Energy, LLC.
3
+ # All rights reserved.
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are met:
6
+ #
7
+ # (1) Redistributions of source code must retain the above copyright notice,
8
+ # this list of conditions and the following disclaimer.
9
+ #
10
+ # (2) Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ #
14
+ # (3) Neither the name of the copyright holder nor the names of any contributors
15
+ # may be used to endorse or promote products derived from this software without
16
+ # specific prior written permission from the respective party.
17
+ #
18
+ # (4) Other than as required in clauses (1) and (2), distributions in any form
19
+ # of modifications or other derivative works may not use the "OpenStudio"
20
+ # trademark, "OS", "os", or any other confusingly similar designation without
21
+ # specific prior written permission from Alliance for Sustainable Energy, LLC.
22
+ #
23
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS
24
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE
27
+ # UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF
28
+ # THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
30
+ # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
32
+ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33
+ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
+ # *******************************************************************************
35
+
36
+ module OsLib_QAQC
37
+ # Check the plant loop operational vs. sizing temperatures
38
+ # and make sure everything is coordinated. This identifies problems
39
+ # caused by sizing to one set of conditions and operating at a different set.
40
+ def check_plant_temps(category, target_standard, max_sizing_temp_delta = 0.1, name_only = false)
41
+ # summary of the check
42
+ check_elems = OpenStudio::AttributeVector.new
43
+ check_elems << OpenStudio::Attribute.new('name', 'Plant Loop Temperatures')
44
+ check_elems << OpenStudio::Attribute.new('category', category)
45
+ check_elems << OpenStudio::Attribute.new('description', 'Check that plant loop sizing and operation temperatures are coordinated.')
46
+
47
+ # stop here if only name is requested this is used to populate display name for arguments
48
+ if name_only == true
49
+ results = []
50
+ check_elems.each do |elem|
51
+ results << elem.valueAsString
52
+ end
53
+ return results
54
+ end
55
+
56
+ std = Standard.build(target_standard)
57
+
58
+ begin
59
+ # Check each plant loop in the model
60
+ @model.getPlantLoops.sort.each do |plant_loop|
61
+ loop_name = plant_loop.name.to_s
62
+
63
+ # Get the central heating and cooling SAT for sizing
64
+ sizing_plant = plant_loop.sizingPlant
65
+ loop_siz_f = OpenStudio.convert(sizing_plant.designLoopExitTemperature, 'C', 'F').get
66
+
67
+ # Determine the min and max operational temperatures
68
+ loop_op_min_f = nil
69
+ loop_op_max_f = nil
70
+ plant_loop.supplyOutletNode.setpointManagers.each do |spm|
71
+ obj_type = spm.iddObjectType.valueName.to_s
72
+ case obj_type
73
+ when 'OS_SetpointManager_Scheduled'
74
+ sch = spm.to_SetpointManagerScheduled.get.schedule
75
+ if sch.to_ScheduleRuleset.is_initialized
76
+ min_c = std.schedule_ruleset_annual_min_max_value(sch.to_ScheduleRuleset.get)['min']
77
+ max_c = std.schedule_ruleset_annual_min_max_value(sch.to_ScheduleRuleset.get)['max']
78
+ elsif sch.to_ScheduleConstant.is_initialized
79
+ min_c = std.schedule_constant_annual_min_max_value(sch.to_ScheduleConstant.get)['min']
80
+ max_c = std.schedule_constant_annual_min_max_value(sch.to_ScheduleConstant.get)['max']
81
+ else
82
+ next
83
+ end
84
+ loop_op_min_f = OpenStudio.convert(min_c, 'C', 'F').get
85
+ loop_op_max_f = OpenStudio.convert(max_c, 'C', 'F').get
86
+ when 'OS_SetpointManager_Scheduled_DualSetpoint'
87
+ spm = spm.to_SetpointManagerSingleZoneReheat.get
88
+ # Lowest setpoint is minimum of low schedule
89
+ low_sch = spm.to_SetpointManagerScheduled.get.lowSetpointSchedule
90
+ next if low_sch.empty?
91
+ low_sch = low_sch.get
92
+ if low_sch.to_ScheduleRuleset.is_initialized
93
+ min_c = std.schedule_ruleset_annual_min_max_value(low_sch.to_ScheduleRuleset.get)['min']
94
+ max_c = std.schedule_ruleset_annual_min_max_value(low_sch.to_ScheduleRuleset.get)['max']
95
+ elsif low_sch.to_ScheduleConstant.is_initialized
96
+ min_c = std.schedule_constant_annual_min_max_value(low_sch.to_ScheduleConstant.get)['min']
97
+ max_c = std.schedule_constant_annual_min_max_value(low_sch.to_ScheduleConstant.get)['max']
98
+ else
99
+ next
100
+ end
101
+ loop_op_min_f = OpenStudio.convert(min_c, 'C', 'F').get
102
+ # Highest setpoint it maximum of high schedule
103
+ high_sch = spm.to_SetpointManagerScheduled.get.highSetpointSchedule
104
+ next if high_sch.empty?
105
+ high_sch = high_sch.get
106
+ if high_sch.to_ScheduleRuleset.is_initialized
107
+ min_c = std.schedule_ruleset_annual_min_max_value(high_sch.to_ScheduleRuleset.get)['min']
108
+ max_c = std.schedule_ruleset_annual_min_max_value(high_sch.to_ScheduleRuleset.get)['max']
109
+ elsif high_sch.to_ScheduleConstant.is_initialized
110
+ min_c = std.schedule_constant_annual_min_max_value(high_sch.to_ScheduleConstant.get)['min']
111
+ max_c = std.schedule_constant_annual_min_max_value(high_sch.to_ScheduleConstant.get)['max']
112
+ else
113
+ next
114
+ end
115
+ loop_op_max_f = OpenStudio.convert(max_c, 'C', 'F').get
116
+ when 'OS_SetpointManager_OutdoorAirReset'
117
+ spm = spm.to_SetpointManagerOutdoorAirReset.get
118
+ temp_1_f = OpenStudio.convert(spm.setpointatOutdoorHighTemperature, 'C', 'F').get
119
+ temp_2_f = OpenStudio.convert(spm.setpointatOutdoorLowTemperature, 'C', 'F').get
120
+ loop_op_min_f = [temp_1_f, temp_2_f].min
121
+ loop_op_max_f = [temp_1_f, temp_2_f].max
122
+ else
123
+ next # Only check the commonly used setpoint managers
124
+ end
125
+ end
126
+
127
+ # Compare plant loop sizing temperatures to operational temperatures
128
+ case sizing_plant.loopType
129
+ when 'Heating'
130
+ if loop_op_max_f
131
+ if ((loop_op_max_f - loop_siz_f) / loop_op_max_f).abs > max_sizing_temp_delta
132
+ check_elems << OpenStudio::Attribute.new('flag', "For #{plant_loop.name}, the sizing is done with a supply water temp of #{loop_siz_f.round(2)}F, but the setpoint manager controlling the loop operates up to #{loop_op_max_f.round(2)}F. These are farther apart than the acceptable #{(max_sizing_temp_delta * 100.0).round(2)}% difference.")
133
+ end
134
+ end
135
+ when 'Cooling'
136
+ if loop_op_min_f
137
+ if ((loop_op_min_f - loop_siz_f) / loop_op_min_f).abs > max_sizing_temp_delta
138
+ check_elems << OpenStudio::Attribute.new('flag', "For #{plant_loop.name}, the sizing is done with a supply water temp of #{loop_siz_f.round(2)}F, but the setpoint manager controlling the loop operates down to #{loop_op_min_f.round(2)}F. These are farther apart than the acceptable #{(max_sizing_temp_delta * 100.0).round(2)}% difference.")
139
+ end
140
+ end
141
+ when 'Condenser'
142
+ # Not checking sizing of condenser loops
143
+ end
144
+ end
145
+ rescue StandardError => e
146
+ # brief description of ruby error
147
+ check_elems << OpenStudio::Attribute.new('flag', "Error prevented QAQC check from running (#{e}).")
148
+
149
+ # backtrace of ruby error for diagnostic use
150
+ if @error_backtrace then check_elems << OpenStudio::Attribute.new('flag', e.backtrace.join("\n").to_s) end
151
+ end
152
+
153
+ # add check_elms to new attribute
154
+ check_elem = OpenStudio::Attribute.new('check', check_elems)
155
+
156
+ return check_elem
157
+ # note: registerWarning and registerValue will be added for checks downstream using os_lib_reporting_qaqc.rb
158
+ end
159
+ end
@@ -0,0 +1,87 @@
1
+ # *******************************************************************************
2
+ # OpenStudio(R), Copyright (c) 2008-2019, Alliance for Sustainable Energy, LLC.
3
+ # All rights reserved.
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are met:
6
+ #
7
+ # (1) Redistributions of source code must retain the above copyright notice,
8
+ # this list of conditions and the following disclaimer.
9
+ #
10
+ # (2) Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ #
14
+ # (3) Neither the name of the copyright holder nor the names of any contributors
15
+ # may be used to endorse or promote products derived from this software without
16
+ # specific prior written permission from the respective party.
17
+ #
18
+ # (4) Other than as required in clauses (1) and (2), distributions in any form
19
+ # of modifications or other derivative works may not use the "OpenStudio"
20
+ # trademark, "OS", "os", or any other confusingly similar designation without
21
+ # specific prior written permission from Alliance for Sustainable Energy, LLC.
22
+ #
23
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS
24
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE
27
+ # UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF
28
+ # THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
30
+ # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
32
+ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33
+ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
+ # *******************************************************************************
35
+
36
+ module OsLib_QAQC
37
+ # Check that there are no people or lights in plenums.
38
+ def check_plenum_loads(category, target_standard, name_only = false)
39
+ # summary of the check
40
+ check_elems = OpenStudio::AttributeVector.new
41
+ check_elems << OpenStudio::Attribute.new('name', 'Plenum Loads')
42
+ check_elems << OpenStudio::Attribute.new('category', category)
43
+ check_elems << OpenStudio::Attribute.new('description', 'Check that the plenums do not have people or lights.')
44
+
45
+ # stop here if only name is requested this is used to populate display name for arguments
46
+ if name_only == true
47
+ results = []
48
+ check_elems.each do |elem|
49
+ results << elem.valueAsString
50
+ end
51
+ return results
52
+ end
53
+
54
+ std = Standard.build(target_standard)
55
+
56
+ begin
57
+ @model.getThermalZones.each do |zone|
58
+ # Only check plenums
59
+ next unless std.thermal_zone_plenum?(zone)
60
+
61
+ # People
62
+ num_people = zone.numberOfPeople
63
+ if num_people > 0
64
+ check_elems << OpenStudio::Attribute.new('flag', "#{zone.name} is a plenum, but has #{num_people.round(1)} people. Plenums should not contain people.")
65
+ end
66
+
67
+ # Lights
68
+ lights_w = zone.lightingPower
69
+ if lights_w > 0
70
+ check_elems << OpenStudio::Attribute.new('flag', "#{zone.name} is a plenum, but has #{lights_w.round(1)} W of lights. Plenums should not contain lights.")
71
+ end
72
+ end
73
+ rescue StandardError => e
74
+ # brief description of ruby error
75
+ check_elems << OpenStudio::Attribute.new('flag', "Error prevented QAQC check from running (#{e}).")
76
+
77
+ # backtrace of ruby error for diagnostic use
78
+ if @error_backtrace then check_elems << OpenStudio::Attribute.new('flag', e.backtrace.join("\n").to_s) end
79
+ end
80
+
81
+ # add check_elms to new attribute
82
+ check_elem = OpenStudio::Attribute.new('check', check_elems)
83
+
84
+ return check_elem
85
+ # note: registerWarning and registerValue will be added for checks downstream using os_lib_reporting_qaqc.rb
86
+ end
87
+ end
@@ -0,0 +1,108 @@
1
+ # *******************************************************************************
2
+ # OpenStudio(R), Copyright (c) 2008-2019, Alliance for Sustainable Energy, LLC.
3
+ # All rights reserved.
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are met:
6
+ #
7
+ # (1) Redistributions of source code must retain the above copyright notice,
8
+ # this list of conditions and the following disclaimer.
9
+ #
10
+ # (2) Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ #
14
+ # (3) Neither the name of the copyright holder nor the names of any contributors
15
+ # may be used to endorse or promote products derived from this software without
16
+ # specific prior written permission from the respective party.
17
+ #
18
+ # (4) Other than as required in clauses (1) and (2), distributions in any form
19
+ # of modifications or other derivative works may not use the "OpenStudio"
20
+ # trademark, "OS", "os", or any other confusingly similar designation without
21
+ # specific prior written permission from Alliance for Sustainable Energy, LLC.
22
+ #
23
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS
24
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE
27
+ # UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF
28
+ # THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
30
+ # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
32
+ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33
+ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
+ # *******************************************************************************
35
+
36
+ module OsLib_QAQC
37
+ # Check the pumping power (W/gpm) for each pump in the model to identify
38
+ # unrealistically sized pumps.
39
+ def check_pump_pwr(category, target_standard, max_pwr_delta = 0.1, name_only = false)
40
+ # summary of the check
41
+ check_elems = OpenStudio::AttributeVector.new
42
+ check_elems << OpenStudio::Attribute.new('name', 'Pump Power')
43
+ check_elems << OpenStudio::Attribute.new('category', category)
44
+ check_elems << OpenStudio::Attribute.new('description', 'Check that pump power vs flow makes sense.')
45
+
46
+ # stop here if only name is requested this is used to populate display name for arguments
47
+ if name_only == true
48
+ results = []
49
+ check_elems.each do |elem|
50
+ results << elem.valueAsString
51
+ end
52
+ return results
53
+ end
54
+
55
+ std = Standard.build(target_standard)
56
+
57
+ begin
58
+ # Check each plant loop
59
+ @model.getPlantLoops.each do |plant_loop|
60
+ # Set the expected/typical W/gpm
61
+ loop_type = plant_loop.sizingPlant.loopType
62
+ case loop_type
63
+ when 'Heating'
64
+ expected_w_per_gpm = 19.0
65
+ when 'Cooling'
66
+ expected_w_per_gpm = 22.0
67
+ when 'Condenser'
68
+ expected_w_per_gpm = 19.0
69
+ end
70
+
71
+ # Check the W/gpm for each pump on each plant loop
72
+ plant_loop.supplyComponents.each do |sc|
73
+ # Get the W/gpm for the pump
74
+ obj_type = sc.iddObjectType.valueName.to_s
75
+ case obj_type
76
+ when 'OS_Pump_ConstantSpeed'
77
+ actual_w_per_gpm = std.pump_rated_w_per_gpm(sc.to_PumpConstantSpeed.get)
78
+ when 'OS_Pump_VariableSpeed'
79
+ actual_w_per_gpm = std.pump_rated_w_per_gpm(sc.to_PumpVariableSpeed.get)
80
+ when 'OS_HeaderedPumps_ConstantSpeed'
81
+ actual_w_per_gpm = std.pump_rated_w_per_gpm(sc.to_HeaderedPumpsConstantSpeed.get)
82
+ when 'OS_HeaderedPumps_VariableSpeed'
83
+ actual_w_per_gpm = std.pump_rated_w_per_gpm(sc.to_HeaderedPumpsVariableSpeed.get)
84
+ else
85
+ next # Skip non-pump objects
86
+ end
87
+
88
+ # Compare W/gpm to expected/typical values
89
+ if ((expected_w_per_gpm - actual_w_per_gpm) / actual_w_per_gpm).abs > max_pwr_delta
90
+ check_elems << OpenStudio::Attribute.new('flag', "For #{sc.name} on #{plant_loop.name}, the actual pumping power of #{actual_w_per_gpm.round(1)} W/gpm is more than #{(max_pwr_delta * 100.0).round(2)}% different from the expected #{expected_w_per_gpm} W/gpm for a #{loop_type} plant loop.")
91
+ end
92
+ end
93
+ end
94
+ rescue StandardError => e
95
+ # brief description of ruby error
96
+ check_elems << OpenStudio::Attribute.new('flag', "Error prevented QAQC check from running (#{e}).")
97
+
98
+ # backtrace of ruby error for diagnostic use
99
+ if @error_backtrace then check_elems << OpenStudio::Attribute.new('flag', e.backtrace.join("\n").to_s) end
100
+ end
101
+
102
+ # add check_elms to new attribute
103
+ check_elem = OpenStudio::Attribute.new('check', check_elems)
104
+
105
+ return check_elem
106
+ # note: registerWarning and registerValue will be added for checks downstream using os_lib_reporting_qaqc.rb
107
+ end
108
+ end