openstudio-extension 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +29 -26
  3. data/.rspec +3 -3
  4. data/.rubocop.yml +10 -9
  5. data/CHANGELOG.md +16 -0
  6. data/Gemfile +6 -6
  7. data/Jenkinsfile +10 -10
  8. data/README.md +251 -250
  9. data/Rakefile +119 -119
  10. data/bin/console +14 -14
  11. data/bin/setup +8 -8
  12. data/doc_templates/LICENSE.md +26 -26
  13. data/doc_templates/README.md.erb +41 -41
  14. data/doc_templates/copyright_erb.txt +35 -35
  15. data/doc_templates/copyright_js.txt +3 -3
  16. data/doc_templates/copyright_ruby.txt +33 -33
  17. data/init_templates/README.md +37 -37
  18. data/init_templates/gemspec.txt +32 -32
  19. data/init_templates/openstudio_module.rb +50 -50
  20. data/init_templates/spec.rb +47 -47
  21. data/init_templates/spec_helper.rb +49 -49
  22. data/init_templates/template_gemfile.txt +17 -17
  23. data/init_templates/template_rakefile.txt +15 -15
  24. data/init_templates/version.rb +40 -40
  25. data/lib/files/openstudio-extension-gem-test.ddy +536 -536
  26. data/lib/files/openstudio-extension-gem-test.epw +8768 -8768
  27. data/lib/files/openstudio-extension-gem-test.stat +554 -554
  28. data/lib/measures/openstudio_extension_test_measure/LICENSE.md +26 -26
  29. data/lib/measures/openstudio_extension_test_measure/README.md +26 -26
  30. data/lib/measures/openstudio_extension_test_measure/README.md.erb +41 -41
  31. data/lib/measures/openstudio_extension_test_measure/measure.rb +72 -72
  32. data/lib/measures/openstudio_extension_test_measure/measure.xml +83 -83
  33. data/lib/measures/openstudio_extension_test_measure/resources/os_lib_helper_methods.rb +399 -399
  34. data/lib/measures/openstudio_extension_test_measure/tests/{OpenStudioExtensionTestMeasure_Test.rb → openstudio_extension_test_measure_test.rb} +74 -75
  35. data/lib/openstudio-extension.rb +1 -1
  36. data/lib/openstudio/extension.rb +234 -229
  37. data/lib/openstudio/extension/core/CreateResults.rb +886 -886
  38. data/lib/openstudio/extension/core/check_air_sys_temps.rb +190 -190
  39. data/lib/openstudio/extension/core/check_calibration.rb +155 -155
  40. data/lib/openstudio/extension/core/check_cond_zns.rb +84 -84
  41. data/lib/openstudio/extension/core/check_domestic_hot_water.rb +334 -334
  42. data/lib/openstudio/extension/core/check_envelope_conductance.rb +453 -453
  43. data/lib/openstudio/extension/core/check_eui_by_end_use.rb +162 -162
  44. data/lib/openstudio/extension/core/check_eui_reasonableness.rb +135 -135
  45. data/lib/openstudio/extension/core/check_fan_pwr.rb +98 -98
  46. data/lib/openstudio/extension/core/check_internal_loads.rb +393 -393
  47. data/lib/openstudio/extension/core/check_mech_sys_capacity.rb +226 -226
  48. data/lib/openstudio/extension/core/check_mech_sys_efficiency.rb +326 -326
  49. data/lib/openstudio/extension/core/check_mech_sys_part_load_eff.rb +464 -464
  50. data/lib/openstudio/extension/core/check_mech_sys_type.rb +139 -139
  51. data/lib/openstudio/extension/core/check_part_loads.rb +451 -451
  52. data/lib/openstudio/extension/core/check_placeholder.rb +75 -75
  53. data/lib/openstudio/extension/core/check_plant_cap.rb +123 -123
  54. data/lib/openstudio/extension/core/check_plant_temps.rb +159 -159
  55. data/lib/openstudio/extension/core/check_plenum_loads.rb +87 -87
  56. data/lib/openstudio/extension/core/check_pump_pwr.rb +108 -108
  57. data/lib/openstudio/extension/core/check_sch_coord.rb +241 -241
  58. data/lib/openstudio/extension/core/check_schedules.rb +311 -311
  59. data/lib/openstudio/extension/core/check_simultaneous_heating_and_cooling.rb +158 -158
  60. data/lib/openstudio/extension/core/check_supply_air_and_thermostat_temp_difference.rb +148 -148
  61. data/lib/openstudio/extension/core/check_weather_files.rb +132 -132
  62. data/lib/openstudio/extension/core/deer_vintages.rb +311 -311
  63. data/lib/openstudio/extension/core/os_lib_aedg_measures.rb +491 -491
  64. data/lib/openstudio/extension/core/os_lib_cofee.rb +258 -258
  65. data/lib/openstudio/extension/core/os_lib_constructions.rb +378 -378
  66. data/lib/openstudio/extension/core/os_lib_geometry.rb +1022 -1022
  67. data/lib/openstudio/extension/core/os_lib_helper_methods.rb +399 -399
  68. data/lib/openstudio/extension/core/os_lib_hvac.rb +2171 -2171
  69. data/lib/openstudio/extension/core/os_lib_lighting_and_equipment.rb +214 -214
  70. data/lib/openstudio/extension/core/os_lib_model_generation.rb +817 -817
  71. data/lib/openstudio/extension/core/os_lib_model_simplification.rb +1049 -1049
  72. data/lib/openstudio/extension/core/os_lib_outdoorair_and_infiltration.rb +165 -165
  73. data/lib/openstudio/extension/core/os_lib_reporting.rb +4651 -4651
  74. data/lib/openstudio/extension/core/os_lib_reporting_qaqc.rb +200 -200
  75. data/lib/openstudio/extension/core/os_lib_schedules.rb +963 -963
  76. data/lib/openstudio/extension/rake_task.rb +159 -149
  77. data/lib/openstudio/extension/runner.rb +667 -644
  78. data/lib/openstudio/extension/runner_config.rb +114 -0
  79. data/lib/openstudio/extension/version.rb +40 -40
  80. data/openstudio-extension.gemspec +34 -33
  81. metadata +39 -37
@@ -1,158 +1,158 @@
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_simultaneous_heating_and_cooling(category, max_pass, name_only = false)
41
- # summary of the check
42
- check_elems = OpenStudio::AttributeVector.new
43
- check_elems << OpenStudio::Attribute.new('name', 'Simultaneous Heating and Cooling')
44
- check_elems << OpenStudio::Attribute.new('category', category)
45
- check_elems << OpenStudio::Attribute.new('description', 'Check for simultaneous heating and cooling by looping through all Single Duct VAV Reheat Air Terminals and analyzing hourly data when there is a cooling load. ')
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
- # get the weather file run period (as opposed to design day run period)
58
- ann_env_pd = nil
59
- @sql.availableEnvPeriods.each do |env_pd|
60
- env_type = @sql.environmentType(env_pd)
61
- if env_type.is_initialized
62
- if env_type.get == OpenStudio::EnvironmentType.new('WeatherRunPeriod')
63
- ann_env_pd = env_pd
64
- break
65
- end
66
- end
67
- end
68
-
69
- # only try to get the annual timeseries if an annual simulation was run
70
- if ann_env_pd.nil?
71
- check_elems << OpenStudio::Attribute.new('flag', 'Cannot find the annual simulation run period, cannot determine simultaneous heating and cooling.')
72
- return check_elem
73
- end
74
-
75
- # For each VAV reheat terminal, calculate
76
- # the annual total % reheat hours.
77
- @model.getAirTerminalSingleDuctVAVReheats.each do |term|
78
- # Reheat coil heating rate
79
- rht_coil = term.reheatCoil
80
- key_value = rht_coil.name.get.to_s.upcase # must be in all caps.
81
- time_step = 'Hourly' # "Zone Timestep", "Hourly", "HVAC System Timestep"
82
- variable_name = 'Heating Coil Heating Rate'
83
- variable_name_alt = 'Heating Coil Air Heating Rate'
84
- rht_rate_ts = @sql.timeSeries(ann_env_pd, time_step, variable_name, key_value) # key value would go at the end if we used it.
85
-
86
- # try and alternate variable name
87
- if rht_rate_ts.empty?
88
- rht_rate_ts = @sql.timeSeries(ann_env_pd, time_step, variable_name_alt, key_value) # key value would go at the end if we used it.
89
- end
90
-
91
- if rht_rate_ts.empty?
92
- check_elems << OpenStudio::Attribute.new('flag', "Heating Coil (Air) Heating Rate Timeseries not found for #{key_value}.")
93
- else
94
-
95
- rht_rate_ts = rht_rate_ts.get.values
96
- # Put timeseries into array
97
- rht_rate_vals = []
98
- for i in 0..(rht_rate_ts.size - 1)
99
- rht_rate_vals << rht_rate_ts[i]
100
- end
101
-
102
- # Zone Air Terminal Sensible Heating Rate
103
- key_value = "ADU #{term.name.get.to_s.upcase}" # must be in all caps.
104
- time_step = 'Hourly' # "Zone Timestep", "Hourly", "HVAC System Timestep"
105
- variable_name = 'Zone Air Terminal Sensible Cooling Rate'
106
- clg_rate_ts = @sql.timeSeries(ann_env_pd, time_step, variable_name, key_value) # key value would go at the end if we used it.
107
- if clg_rate_ts.empty?
108
- check_elems << OpenStudio::Attribute.new('flag', "Zone Air Terminal Sensible Cooling Rate Timeseries not found for #{key_value}.")
109
- else
110
-
111
- clg_rate_ts = clg_rate_ts.get.values
112
- # Put timeseries into array
113
- clg_rate_vals = []
114
- for i in 0..(clg_rate_ts.size - 1)
115
- clg_rate_vals << clg_rate_ts[i]
116
- end
117
-
118
- # Loop through each timestep and calculate the hourly
119
- # % reheat value.
120
- ann_rht_hrs = 0
121
- ann_clg_hrs = 0
122
- ann_pcts = []
123
- rht_rate_vals.zip(clg_rate_vals).each do |rht_w, clg_w|
124
- # Skip hours with no cooling (in heating mode)
125
- next if clg_w == 0
126
- pct_overcool_rht = rht_w / (rht_w + clg_w)
127
- ann_rht_hrs += pct_overcool_rht # implied * 1hr b/c hrly results
128
- ann_clg_hrs += 1
129
- ann_pcts << pct_overcool_rht.round(3)
130
- end
131
-
132
- # Calculate annual % reheat hours
133
- ann_pct_reheat = ((ann_rht_hrs / ann_clg_hrs) * 100).round(1)
134
-
135
- # Compare to limit
136
- if ann_pct_reheat > max_pass * 100.0
137
- check_elems << OpenStudio::Attribute.new('flag', "#{term.name} has #{ann_pct_reheat}% overcool-reheat, which is greater than the limit of #{max_pass * 100.0}%. This terminal is in cooling mode for #{ann_clg_hrs} hours of the year.")
138
- end
139
-
140
- end
141
-
142
- end
143
- end
144
- rescue StandardError => e
145
- # brief description of ruby error
146
- check_elems << OpenStudio::Attribute.new('flag', "Error prevented QAQC check from running (#{e}).")
147
-
148
- # backtrace of ruby error for diagnostic use
149
- if @error_backtrace then check_elems << OpenStudio::Attribute.new('flag', e.backtrace.join("\n").to_s) end
150
- end
151
-
152
- # add check_elms to new attribute
153
- check_elem = OpenStudio::Attribute.new('check', check_elems)
154
-
155
- return check_elem
156
- # note: registerWarning and registerValue will be added for checks downstream using os_lib_reporting_qaqc.rb
157
- end
158
- end
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_simultaneous_heating_and_cooling(category, max_pass, name_only = false)
41
+ # summary of the check
42
+ check_elems = OpenStudio::AttributeVector.new
43
+ check_elems << OpenStudio::Attribute.new('name', 'Simultaneous Heating and Cooling')
44
+ check_elems << OpenStudio::Attribute.new('category', category)
45
+ check_elems << OpenStudio::Attribute.new('description', 'Check for simultaneous heating and cooling by looping through all Single Duct VAV Reheat Air Terminals and analyzing hourly data when there is a cooling load. ')
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
+ # get the weather file run period (as opposed to design day run period)
58
+ ann_env_pd = nil
59
+ @sql.availableEnvPeriods.each do |env_pd|
60
+ env_type = @sql.environmentType(env_pd)
61
+ if env_type.is_initialized
62
+ if env_type.get == OpenStudio::EnvironmentType.new('WeatherRunPeriod')
63
+ ann_env_pd = env_pd
64
+ break
65
+ end
66
+ end
67
+ end
68
+
69
+ # only try to get the annual timeseries if an annual simulation was run
70
+ if ann_env_pd.nil?
71
+ check_elems << OpenStudio::Attribute.new('flag', 'Cannot find the annual simulation run period, cannot determine simultaneous heating and cooling.')
72
+ return check_elem
73
+ end
74
+
75
+ # For each VAV reheat terminal, calculate
76
+ # the annual total % reheat hours.
77
+ @model.getAirTerminalSingleDuctVAVReheats.each do |term|
78
+ # Reheat coil heating rate
79
+ rht_coil = term.reheatCoil
80
+ key_value = rht_coil.name.get.to_s.upcase # must be in all caps.
81
+ time_step = 'Hourly' # "Zone Timestep", "Hourly", "HVAC System Timestep"
82
+ variable_name = 'Heating Coil Heating Rate'
83
+ variable_name_alt = 'Heating Coil Air Heating Rate'
84
+ rht_rate_ts = @sql.timeSeries(ann_env_pd, time_step, variable_name, key_value) # key value would go at the end if we used it.
85
+
86
+ # try and alternate variable name
87
+ if rht_rate_ts.empty?
88
+ rht_rate_ts = @sql.timeSeries(ann_env_pd, time_step, variable_name_alt, key_value) # key value would go at the end if we used it.
89
+ end
90
+
91
+ if rht_rate_ts.empty?
92
+ check_elems << OpenStudio::Attribute.new('flag', "Heating Coil (Air) Heating Rate Timeseries not found for #{key_value}.")
93
+ else
94
+
95
+ rht_rate_ts = rht_rate_ts.get.values
96
+ # Put timeseries into array
97
+ rht_rate_vals = []
98
+ for i in 0..(rht_rate_ts.size - 1)
99
+ rht_rate_vals << rht_rate_ts[i]
100
+ end
101
+
102
+ # Zone Air Terminal Sensible Heating Rate
103
+ key_value = "ADU #{term.name.get.to_s.upcase}" # must be in all caps.
104
+ time_step = 'Hourly' # "Zone Timestep", "Hourly", "HVAC System Timestep"
105
+ variable_name = 'Zone Air Terminal Sensible Cooling Rate'
106
+ clg_rate_ts = @sql.timeSeries(ann_env_pd, time_step, variable_name, key_value) # key value would go at the end if we used it.
107
+ if clg_rate_ts.empty?
108
+ check_elems << OpenStudio::Attribute.new('flag', "Zone Air Terminal Sensible Cooling Rate Timeseries not found for #{key_value}.")
109
+ else
110
+
111
+ clg_rate_ts = clg_rate_ts.get.values
112
+ # Put timeseries into array
113
+ clg_rate_vals = []
114
+ for i in 0..(clg_rate_ts.size - 1)
115
+ clg_rate_vals << clg_rate_ts[i]
116
+ end
117
+
118
+ # Loop through each timestep and calculate the hourly
119
+ # % reheat value.
120
+ ann_rht_hrs = 0
121
+ ann_clg_hrs = 0
122
+ ann_pcts = []
123
+ rht_rate_vals.zip(clg_rate_vals).each do |rht_w, clg_w|
124
+ # Skip hours with no cooling (in heating mode)
125
+ next if clg_w == 0
126
+ pct_overcool_rht = rht_w / (rht_w + clg_w)
127
+ ann_rht_hrs += pct_overcool_rht # implied * 1hr b/c hrly results
128
+ ann_clg_hrs += 1
129
+ ann_pcts << pct_overcool_rht.round(3)
130
+ end
131
+
132
+ # Calculate annual % reheat hours
133
+ ann_pct_reheat = ((ann_rht_hrs / ann_clg_hrs) * 100).round(1)
134
+
135
+ # Compare to limit
136
+ if ann_pct_reheat > max_pass * 100.0
137
+ check_elems << OpenStudio::Attribute.new('flag', "#{term.name} has #{ann_pct_reheat}% overcool-reheat, which is greater than the limit of #{max_pass * 100.0}%. This terminal is in cooling mode for #{ann_clg_hrs} hours of the year.")
138
+ end
139
+
140
+ end
141
+
142
+ end
143
+ end
144
+ rescue StandardError => e
145
+ # brief description of ruby error
146
+ check_elems << OpenStudio::Attribute.new('flag', "Error prevented QAQC check from running (#{e}).")
147
+
148
+ # backtrace of ruby error for diagnostic use
149
+ if @error_backtrace then check_elems << OpenStudio::Attribute.new('flag', e.backtrace.join("\n").to_s) end
150
+ end
151
+
152
+ # add check_elms to new attribute
153
+ check_elem = OpenStudio::Attribute.new('check', check_elems)
154
+
155
+ return check_elem
156
+ # note: registerWarning and registerValue will be added for checks downstream using os_lib_reporting_qaqc.rb
157
+ end
158
+ end
@@ -1,148 +1,148 @@
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_supply_air_and_thermostat_temp_difference(category, target_standard, max_delta, name_only = false)
41
- # G3.1.2.9 requires a 20 degree F delta between supply air temperature and zone temperature.
42
- target_clg_delta = 20.0
43
-
44
- # summary of the check
45
- check_elems = OpenStudio::AttributeVector.new
46
- check_elems << OpenStudio::Attribute.new('name', 'Supply and Zone Air Temperature')
47
- check_elems << OpenStudio::Attribute.new('category', category)
48
- if @utility_name.nil?
49
- check_elems << OpenStudio::Attribute.new('description', "Check if fans modeled to ASHRAE 90.1 2013 Section G3.1.2.9 requirements. Compare the supply air temperature for each thermal zone against the thermostat setpoints. Throw flag if temperature difference excedes threshold of #{target_clg_delta}F plus the selected tolerance.")
50
- else
51
- check_elems << OpenStudio::Attribute.new('description', "Check if fans modeled to ASHRAE 90.1 2013 Section G3.1.2.9 requirements. Compare the supply air temperature for each thermal zone against the thermostat setpoints. Throw flag if temperature difference excedes threshold set by #{@utility_name}.")
52
- end
53
-
54
- # stop here if only name is requested this is used to populate display name for arguments
55
- if name_only == true
56
- results = []
57
- check_elems.each do |elem|
58
- results << elem.valueAsString
59
- end
60
- return results
61
- end
62
-
63
- # Versions of OpenStudio greater than 2.4.0 use a modified version of
64
- # openstudio-standards with different method calls. These methods
65
- # require a "Standard" object instead of the standard being passed into method calls.
66
- # This Standard object is used throughout the QAQC check.
67
- if OpenStudio::VersionString.new(OpenStudio.openStudioVersion) < OpenStudio::VersionString.new('2.4.3')
68
- use_old_gem_code = true
69
- else
70
- use_old_gem_code = false
71
- std = Standard.build(target_standard)
72
- end
73
-
74
- begin
75
- # loop through thermal zones
76
- @model.getThermalZones.sort.each do |thermal_zone|
77
- model_clg_min = nil
78
-
79
- # populate thermostat ranges
80
- if thermal_zone.thermostatSetpointDualSetpoint.is_initialized
81
-
82
- thermostat = thermal_zone.thermostatSetpointDualSetpoint.get
83
- if thermostat.coolingSetpointTemperatureSchedule.is_initialized
84
-
85
- clg_sch = thermostat.coolingSetpointTemperatureSchedule.get
86
- schedule_values = nil
87
- if clg_sch.to_ScheduleRuleset.is_initialized
88
- if use_old_gem_code
89
- schedule_values = clg_sch.to_ScheduleRuleset.get.annual_min_max_value
90
- else
91
- schedule_values = std.schedule_ruleset_annual_min_max_value(clg_sch.to_ScheduleRuleset.get)
92
- end
93
- elsif clg_sch.to_ScheduleConstant.is_initialized
94
- if use_old_gem_code
95
- schedule_values = clg_sch.to_ScheduleConstant.get.annual_min_max_value
96
- else
97
- schedule_values = std.schedule_constant_annual_min_max_value(clg_sch.to_ScheduleConstant.get)
98
- end
99
- end
100
-
101
- unless schedule_values.nil?
102
- model_clg_min = schedule_values['min']
103
- end
104
- end
105
-
106
- else
107
- # go to next zone if not conditioned
108
- next
109
-
110
- end
111
-
112
- # flag if there is setpoint schedule can't be inspected (isn't ruleset)
113
- if model_clg_min.nil?
114
- check_elems << OpenStudio::Attribute.new('flag', "Can't inspect thermostat schedules for #{thermal_zone.name}")
115
- else
116
-
117
- # get supply air temps from thermal zone sizing
118
- sizing_zone = thermal_zone.sizingZone
119
- clg_supply_air_temp = sizing_zone.zoneCoolingDesignSupplyAirTemperature
120
-
121
- # convert model values to IP
122
- model_clg_min_ip = OpenStudio.convert(model_clg_min, 'C', 'F').get
123
- clg_supply_air_temp_ip = OpenStudio.convert(clg_supply_air_temp, 'C', 'F').get
124
-
125
- # check supply air against zone temperature (only check against min setpoint, assume max is night setback)
126
- if model_clg_min_ip - clg_supply_air_temp_ip > target_clg_delta + max_delta
127
- check_elems << OpenStudio::Attribute.new('flag', "For #{thermal_zone.name} the delta temp between the cooling supply air temp of #{clg_supply_air_temp_ip.round(2)} (F) and the minimum thermostat cooling temp of #{model_clg_min_ip.round(2)} (F) is more than #{max_delta} (F) larger than the expected delta of #{target_clg_delta} (F)")
128
- elsif model_clg_min_ip - clg_supply_air_temp_ip < target_clg_delta - max_delta
129
- check_elems << OpenStudio::Attribute.new('flag', "For #{thermal_zone.name} the delta temp between the cooling supply air temp of #{clg_supply_air_temp_ip.round(2)} (F) and the minimum thermostat cooling temp of #{model_clg_min_ip.round(2)} (F) is more than #{max_delta} (F) smaller than the expected delta of #{target_clg_delta} (F)")
130
- end
131
-
132
- end
133
- end
134
- rescue StandardError => e
135
- # brief description of ruby error
136
- check_elems << OpenStudio::Attribute.new('flag', "Error prevented QAQC check from running (#{e}).")
137
-
138
- # backtrace of ruby error for diagnostic use
139
- if @error_backtrace then check_elems << OpenStudio::Attribute.new('flag', e.backtrace.join("\n").to_s) end
140
- end
141
-
142
- # add check_elms to new attribute
143
- check_elem = OpenStudio::Attribute.new('check', check_elems)
144
-
145
- return check_elem
146
- # note: registerWarning and registerValue will be added for checks downstream using os_lib_reporting_qaqc.rb
147
- end
148
- end
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_supply_air_and_thermostat_temp_difference(category, target_standard, max_delta, name_only = false)
41
+ # G3.1.2.9 requires a 20 degree F delta between supply air temperature and zone temperature.
42
+ target_clg_delta = 20.0
43
+
44
+ # summary of the check
45
+ check_elems = OpenStudio::AttributeVector.new
46
+ check_elems << OpenStudio::Attribute.new('name', 'Supply and Zone Air Temperature')
47
+ check_elems << OpenStudio::Attribute.new('category', category)
48
+ if @utility_name.nil?
49
+ check_elems << OpenStudio::Attribute.new('description', "Check if fans modeled to ASHRAE 90.1 2013 Section G3.1.2.9 requirements. Compare the supply air temperature for each thermal zone against the thermostat setpoints. Throw flag if temperature difference excedes threshold of #{target_clg_delta}F plus the selected tolerance.")
50
+ else
51
+ check_elems << OpenStudio::Attribute.new('description', "Check if fans modeled to ASHRAE 90.1 2013 Section G3.1.2.9 requirements. Compare the supply air temperature for each thermal zone against the thermostat setpoints. Throw flag if temperature difference excedes threshold set by #{@utility_name}.")
52
+ end
53
+
54
+ # stop here if only name is requested this is used to populate display name for arguments
55
+ if name_only == true
56
+ results = []
57
+ check_elems.each do |elem|
58
+ results << elem.valueAsString
59
+ end
60
+ return results
61
+ end
62
+
63
+ # Versions of OpenStudio greater than 2.4.0 use a modified version of
64
+ # openstudio-standards with different method calls. These methods
65
+ # require a "Standard" object instead of the standard being passed into method calls.
66
+ # This Standard object is used throughout the QAQC check.
67
+ if OpenStudio::VersionString.new(OpenStudio.openStudioVersion) < OpenStudio::VersionString.new('2.4.3')
68
+ use_old_gem_code = true
69
+ else
70
+ use_old_gem_code = false
71
+ std = Standard.build(target_standard)
72
+ end
73
+
74
+ begin
75
+ # loop through thermal zones
76
+ @model.getThermalZones.sort.each do |thermal_zone|
77
+ model_clg_min = nil
78
+
79
+ # populate thermostat ranges
80
+ if thermal_zone.thermostatSetpointDualSetpoint.is_initialized
81
+
82
+ thermostat = thermal_zone.thermostatSetpointDualSetpoint.get
83
+ if thermostat.coolingSetpointTemperatureSchedule.is_initialized
84
+
85
+ clg_sch = thermostat.coolingSetpointTemperatureSchedule.get
86
+ schedule_values = nil
87
+ if clg_sch.to_ScheduleRuleset.is_initialized
88
+ if use_old_gem_code
89
+ schedule_values = clg_sch.to_ScheduleRuleset.get.annual_min_max_value
90
+ else
91
+ schedule_values = std.schedule_ruleset_annual_min_max_value(clg_sch.to_ScheduleRuleset.get)
92
+ end
93
+ elsif clg_sch.to_ScheduleConstant.is_initialized
94
+ if use_old_gem_code
95
+ schedule_values = clg_sch.to_ScheduleConstant.get.annual_min_max_value
96
+ else
97
+ schedule_values = std.schedule_constant_annual_min_max_value(clg_sch.to_ScheduleConstant.get)
98
+ end
99
+ end
100
+
101
+ unless schedule_values.nil?
102
+ model_clg_min = schedule_values['min']
103
+ end
104
+ end
105
+
106
+ else
107
+ # go to next zone if not conditioned
108
+ next
109
+
110
+ end
111
+
112
+ # flag if there is setpoint schedule can't be inspected (isn't ruleset)
113
+ if model_clg_min.nil?
114
+ check_elems << OpenStudio::Attribute.new('flag', "Can't inspect thermostat schedules for #{thermal_zone.name}")
115
+ else
116
+
117
+ # get supply air temps from thermal zone sizing
118
+ sizing_zone = thermal_zone.sizingZone
119
+ clg_supply_air_temp = sizing_zone.zoneCoolingDesignSupplyAirTemperature
120
+
121
+ # convert model values to IP
122
+ model_clg_min_ip = OpenStudio.convert(model_clg_min, 'C', 'F').get
123
+ clg_supply_air_temp_ip = OpenStudio.convert(clg_supply_air_temp, 'C', 'F').get
124
+
125
+ # check supply air against zone temperature (only check against min setpoint, assume max is night setback)
126
+ if model_clg_min_ip - clg_supply_air_temp_ip > target_clg_delta + max_delta
127
+ check_elems << OpenStudio::Attribute.new('flag', "For #{thermal_zone.name} the delta temp between the cooling supply air temp of #{clg_supply_air_temp_ip.round(2)} (F) and the minimum thermostat cooling temp of #{model_clg_min_ip.round(2)} (F) is more than #{max_delta} (F) larger than the expected delta of #{target_clg_delta} (F)")
128
+ elsif model_clg_min_ip - clg_supply_air_temp_ip < target_clg_delta - max_delta
129
+ check_elems << OpenStudio::Attribute.new('flag', "For #{thermal_zone.name} the delta temp between the cooling supply air temp of #{clg_supply_air_temp_ip.round(2)} (F) and the minimum thermostat cooling temp of #{model_clg_min_ip.round(2)} (F) is more than #{max_delta} (F) smaller than the expected delta of #{target_clg_delta} (F)")
130
+ end
131
+
132
+ end
133
+ end
134
+ rescue StandardError => e
135
+ # brief description of ruby error
136
+ check_elems << OpenStudio::Attribute.new('flag', "Error prevented QAQC check from running (#{e}).")
137
+
138
+ # backtrace of ruby error for diagnostic use
139
+ if @error_backtrace then check_elems << OpenStudio::Attribute.new('flag', e.backtrace.join("\n").to_s) end
140
+ end
141
+
142
+ # add check_elms to new attribute
143
+ check_elem = OpenStudio::Attribute.new('check', check_elems)
144
+
145
+ return check_elem
146
+ # note: registerWarning and registerValue will be added for checks downstream using os_lib_reporting_qaqc.rb
147
+ end
148
+ end