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,162 +1,162 @@
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_eui_by_end_use(category, target_standard, min_pass, max_pass, name_only = false)
41
- # summary of the check
42
- check_elems = OpenStudio::AttributeVector.new
43
- check_elems << OpenStudio::Attribute.new('name', 'End Use by Category')
44
- check_elems << OpenStudio::Attribute.new('category', category)
45
- check_elems << OpenStudio::Attribute.new('description', "Check end use by category against #{target_standard} DOE prototype buildings.")
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
- # Versions of OpenStudio greater than 2.4.0 use a modified version of
57
- # openstudio-standards with different method calls. These methods
58
- # require a "Standard" object instead of the standard being passed into method calls.
59
- # This Standard object is used throughout the QAQC check.
60
- if OpenStudio::VersionString.new(OpenStudio.openStudioVersion) < OpenStudio::VersionString.new('2.4.3')
61
- use_old_gem_code = true
62
- else
63
- use_old_gem_code = false
64
- std = Standard.build(target_standard)
65
- end
66
-
67
- begin
68
- # total building area
69
- query = 'SELECT Value FROM tabulardatawithstrings WHERE '
70
- query << "ReportName='AnnualBuildingUtilityPerformanceSummary' and "
71
- query << "ReportForString='Entire Facility' and "
72
- query << "TableName='Building Area' and "
73
- query << "RowName='Total Building Area' and "
74
- query << "ColumnName='Area' and "
75
- query << "Units='m2';"
76
- query_results = @sql.execAndReturnFirstDouble(query)
77
- if query_results.empty?
78
- check_elems << OpenStudio::Attribute.new('flag', "Can't calculate EUI, SQL query for building area failed.")
79
- return OpenStudio::Attribute.new('check', check_elems)
80
- else
81
- energy_plus_area = query_results.get
82
- end
83
-
84
- # temp code to check OS vs. E+ area
85
- open_studio_area = @model.getBuilding.floorArea
86
- if (energy_plus_area - open_studio_area).abs >= 0.1
87
- check_elems << OpenStudio::Attribute.new('flag', "EnergyPlus reported area is #{energy_plus_area} (m^2). OpenStudio reported area is #{@model.getBuilding.floorArea} (m^2).")
88
- end
89
-
90
- # loop through end uses and gather consumption, normalized by floor area
91
- actual_eui_by_end_use = {}
92
- OpenStudio::EndUseCategoryType.getValues.each do |end_use|
93
- # get end uses
94
- end_use = OpenStudio::EndUseCategoryType.new(end_use).valueDescription
95
- query_elec = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='AnnualBuildingUtilityPerformanceSummary' and TableName='End Uses' and RowName= '#{end_use}' and ColumnName= 'Electricity'"
96
- query_gas = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='AnnualBuildingUtilityPerformanceSummary' and TableName='End Uses' and RowName= '#{end_use}' and ColumnName= 'Natural Gas'"
97
- query_add = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='AnnualBuildingUtilityPerformanceSummary' and TableName='End Uses' and RowName= '#{end_use}' and ColumnName= 'Additional Fuel'"
98
- query_dc = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='AnnualBuildingUtilityPerformanceSummary' and TableName='End Uses' and RowName= '#{end_use}' and ColumnName= 'District Cooling'"
99
- query_dh = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='AnnualBuildingUtilityPerformanceSummary' and TableName='End Uses' and RowName= '#{end_use}' and ColumnName= 'District Heating'"
100
- results_elec = @sql.execAndReturnFirstDouble(query_elec).get
101
- results_gas = @sql.execAndReturnFirstDouble(query_gas).get
102
- results_add = @sql.execAndReturnFirstDouble(query_add).get
103
- results_dc = @sql.execAndReturnFirstDouble(query_dc).get
104
- results_dh = @sql.execAndReturnFirstDouble(query_dh).get
105
- total_end_use = results_elec + results_gas + results_add + results_dc + results_dh
106
-
107
- # populate hash for actual end use normalized by area
108
- actual_eui_by_end_use[end_use] = total_end_use / energy_plus_area
109
- end
110
-
111
- # gather target end uses for given standard as hash
112
- if use_old_gem_code
113
- target_eui_by_end_use = @model.find_target_eui_by_end_use(target_standard)
114
- else
115
- std = Standard.build(target_standard)
116
- target_eui_by_end_use = std.model_find_target_eui_by_end_use(@model)
117
- end
118
-
119
- # units for flag display text and unit conversion
120
- source_units = 'GJ/m^2'
121
- target_units = 'kBtu/ft^2'
122
-
123
- # check acutal vs. target against tolerance
124
- if !target_eui_by_end_use.nil?
125
- actual_eui_by_end_use.each do |end_use, value|
126
- # this should have value of 0 in model. This page change in the future. It doesn't exist in target lookup
127
- next if end_use == 'Exterior Equipment'
128
-
129
- # perform check and issue flags as needed
130
- target_value = target_eui_by_end_use[end_use]
131
- eui_ip_neat = OpenStudio.toNeatString(OpenStudio.convert(value, source_units, target_units).get, 5, true)
132
- target_eui_ip_neat = OpenStudio.toNeatString(OpenStudio.convert(target_value, source_units, target_units).get, 1, true)
133
-
134
- # add in use case specific logic to skip checks when near 0 actual and target
135
- skip = false
136
- if (end_use == 'Heat Recovery') && (value < 0.05) && (target_value < 0.05) then skip = true end
137
- if (end_use == 'Pumps') && (value < 0.05) && (target_value < 0.05) then skip = true end
138
-
139
- if (value < target_value * (1.0 - min_pass)) && !skip
140
- check_elems << OpenStudio::Attribute.new('flag', "#{end_use} EUI of #{eui_ip_neat} (#{target_units}) is less than #{min_pass * 100} % below the expected #{end_use} EUI of #{target_eui_ip_neat} (#{target_units}) for #{target_standard}.")
141
- elsif (value > target_value * (1.0 + max_pass)) && !skip
142
- check_elems << OpenStudio::Attribute.new('flag', "#{end_use} EUI of #{eui_ip_neat} (#{target_units}) is more than #{max_pass * 100} % above the expected #{end_use} EUI of #{target_eui_ip_neat} (#{target_units}) for #{target_standard}.")
143
- end
144
- end
145
- else
146
- check_elems << OpenStudio::Attribute.new('flag', "Can't calculate target end use EUIs. Make sure model has expected climate zone and building type.")
147
- end
148
- rescue StandardError => e
149
- # brief description of ruby error
150
- check_elems << OpenStudio::Attribute.new('flag', "Error prevented QAQC check from running (#{e}).")
151
-
152
- # backtrace of ruby error for diagnostic use
153
- if @error_backtrace then check_elems << OpenStudio::Attribute.new('flag', e.backtrace.join("\n").to_s) end
154
- end
155
-
156
- # add check_elms to new attribute
157
- check_elem = OpenStudio::Attribute.new('check', check_elems)
158
-
159
- return check_elem
160
- # note: registerWarning and registerValue will be added for checks downstream using os_lib_reporting_qaqc.rb
161
- end
162
- 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_eui_by_end_use(category, target_standard, min_pass, max_pass, name_only = false)
41
+ # summary of the check
42
+ check_elems = OpenStudio::AttributeVector.new
43
+ check_elems << OpenStudio::Attribute.new('name', 'End Use by Category')
44
+ check_elems << OpenStudio::Attribute.new('category', category)
45
+ check_elems << OpenStudio::Attribute.new('description', "Check end use by category against #{target_standard} DOE prototype buildings.")
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
+ # Versions of OpenStudio greater than 2.4.0 use a modified version of
57
+ # openstudio-standards with different method calls. These methods
58
+ # require a "Standard" object instead of the standard being passed into method calls.
59
+ # This Standard object is used throughout the QAQC check.
60
+ if OpenStudio::VersionString.new(OpenStudio.openStudioVersion) < OpenStudio::VersionString.new('2.4.3')
61
+ use_old_gem_code = true
62
+ else
63
+ use_old_gem_code = false
64
+ std = Standard.build(target_standard)
65
+ end
66
+
67
+ begin
68
+ # total building area
69
+ query = 'SELECT Value FROM tabulardatawithstrings WHERE '
70
+ query << "ReportName='AnnualBuildingUtilityPerformanceSummary' and "
71
+ query << "ReportForString='Entire Facility' and "
72
+ query << "TableName='Building Area' and "
73
+ query << "RowName='Total Building Area' and "
74
+ query << "ColumnName='Area' and "
75
+ query << "Units='m2';"
76
+ query_results = @sql.execAndReturnFirstDouble(query)
77
+ if query_results.empty?
78
+ check_elems << OpenStudio::Attribute.new('flag', "Can't calculate EUI, SQL query for building area failed.")
79
+ return OpenStudio::Attribute.new('check', check_elems)
80
+ else
81
+ energy_plus_area = query_results.get
82
+ end
83
+
84
+ # temp code to check OS vs. E+ area
85
+ open_studio_area = @model.getBuilding.floorArea
86
+ if (energy_plus_area - open_studio_area).abs >= 0.1
87
+ check_elems << OpenStudio::Attribute.new('flag', "EnergyPlus reported area is #{energy_plus_area} (m^2). OpenStudio reported area is #{@model.getBuilding.floorArea} (m^2).")
88
+ end
89
+
90
+ # loop through end uses and gather consumption, normalized by floor area
91
+ actual_eui_by_end_use = {}
92
+ OpenStudio::EndUseCategoryType.getValues.each do |end_use|
93
+ # get end uses
94
+ end_use = OpenStudio::EndUseCategoryType.new(end_use).valueDescription
95
+ query_elec = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='AnnualBuildingUtilityPerformanceSummary' and TableName='End Uses' and RowName= '#{end_use}' and ColumnName= 'Electricity'"
96
+ query_gas = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='AnnualBuildingUtilityPerformanceSummary' and TableName='End Uses' and RowName= '#{end_use}' and ColumnName= 'Natural Gas'"
97
+ query_add = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='AnnualBuildingUtilityPerformanceSummary' and TableName='End Uses' and RowName= '#{end_use}' and ColumnName= 'Additional Fuel'"
98
+ query_dc = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='AnnualBuildingUtilityPerformanceSummary' and TableName='End Uses' and RowName= '#{end_use}' and ColumnName= 'District Cooling'"
99
+ query_dh = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='AnnualBuildingUtilityPerformanceSummary' and TableName='End Uses' and RowName= '#{end_use}' and ColumnName= 'District Heating'"
100
+ results_elec = @sql.execAndReturnFirstDouble(query_elec).get
101
+ results_gas = @sql.execAndReturnFirstDouble(query_gas).get
102
+ results_add = @sql.execAndReturnFirstDouble(query_add).get
103
+ results_dc = @sql.execAndReturnFirstDouble(query_dc).get
104
+ results_dh = @sql.execAndReturnFirstDouble(query_dh).get
105
+ total_end_use = results_elec + results_gas + results_add + results_dc + results_dh
106
+
107
+ # populate hash for actual end use normalized by area
108
+ actual_eui_by_end_use[end_use] = total_end_use / energy_plus_area
109
+ end
110
+
111
+ # gather target end uses for given standard as hash
112
+ if use_old_gem_code
113
+ target_eui_by_end_use = @model.find_target_eui_by_end_use(target_standard)
114
+ else
115
+ std = Standard.build(target_standard)
116
+ target_eui_by_end_use = std.model_find_target_eui_by_end_use(@model)
117
+ end
118
+
119
+ # units for flag display text and unit conversion
120
+ source_units = 'GJ/m^2'
121
+ target_units = 'kBtu/ft^2'
122
+
123
+ # check acutal vs. target against tolerance
124
+ if !target_eui_by_end_use.nil?
125
+ actual_eui_by_end_use.each do |end_use, value|
126
+ # this should have value of 0 in model. This page change in the future. It doesn't exist in target lookup
127
+ next if end_use == 'Exterior Equipment'
128
+
129
+ # perform check and issue flags as needed
130
+ target_value = target_eui_by_end_use[end_use]
131
+ eui_ip_neat = OpenStudio.toNeatString(OpenStudio.convert(value, source_units, target_units).get, 5, true)
132
+ target_eui_ip_neat = OpenStudio.toNeatString(OpenStudio.convert(target_value, source_units, target_units).get, 1, true)
133
+
134
+ # add in use case specific logic to skip checks when near 0 actual and target
135
+ skip = false
136
+ if (end_use == 'Heat Recovery') && (value < 0.05) && (target_value < 0.05) then skip = true end
137
+ if (end_use == 'Pumps') && (value < 0.05) && (target_value < 0.05) then skip = true end
138
+
139
+ if (value < target_value * (1.0 - min_pass)) && !skip
140
+ check_elems << OpenStudio::Attribute.new('flag', "#{end_use} EUI of #{eui_ip_neat} (#{target_units}) is less than #{min_pass * 100} % below the expected #{end_use} EUI of #{target_eui_ip_neat} (#{target_units}) for #{target_standard}.")
141
+ elsif (value > target_value * (1.0 + max_pass)) && !skip
142
+ check_elems << OpenStudio::Attribute.new('flag', "#{end_use} EUI of #{eui_ip_neat} (#{target_units}) is more than #{max_pass * 100} % above the expected #{end_use} EUI of #{target_eui_ip_neat} (#{target_units}) for #{target_standard}.")
143
+ end
144
+ end
145
+ else
146
+ check_elems << OpenStudio::Attribute.new('flag', "Can't calculate target end use EUIs. Make sure model has expected climate zone and building type.")
147
+ end
148
+ rescue StandardError => e
149
+ # brief description of ruby error
150
+ check_elems << OpenStudio::Attribute.new('flag', "Error prevented QAQC check from running (#{e}).")
151
+
152
+ # backtrace of ruby error for diagnostic use
153
+ if @error_backtrace then check_elems << OpenStudio::Attribute.new('flag', e.backtrace.join("\n").to_s) end
154
+ end
155
+
156
+ # add check_elms to new attribute
157
+ check_elem = OpenStudio::Attribute.new('check', check_elems)
158
+
159
+ return check_elem
160
+ # note: registerWarning and registerValue will be added for checks downstream using os_lib_reporting_qaqc.rb
161
+ end
162
+ end
@@ -1,135 +1,135 @@
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_eui_reasonableness(category, target_standard, min_pass, max_pass, name_only = false)
41
- # summary of the check
42
- check_elems = OpenStudio::AttributeVector.new
43
- check_elems << OpenStudio::Attribute.new('name', 'EUI Reasonableness')
44
- check_elems << OpenStudio::Attribute.new('category', category)
45
- check_elems << OpenStudio::Attribute.new('description', "Check EUI for model against #{target_standard} DOE prototype buildings.")
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
- # Versions of OpenStudio greater than 2.4.0 use a modified version of
57
- # openstudio-standards with different method calls. These methods
58
- # require a "Standard" object instead of the standard being passed into method calls.
59
- # This Standard object is used throughout the QAQC check.
60
- if OpenStudio::VersionString.new(OpenStudio.openStudioVersion) < OpenStudio::VersionString.new('2.4.3')
61
- use_old_gem_code = true
62
- else
63
- use_old_gem_code = false
64
- std = Standard.build(target_standard)
65
- end
66
-
67
- begin
68
- # total building area
69
- query = 'SELECT Value FROM tabulardatawithstrings WHERE '
70
- query << "ReportName='AnnualBuildingUtilityPerformanceSummary' and "
71
- query << "ReportForString='Entire Facility' and "
72
- query << "TableName='Building Area' and "
73
- query << "RowName='Total Building Area' and "
74
- query << "ColumnName='Area' and "
75
- query << "Units='m2';"
76
- query_results = @sql.execAndReturnFirstDouble(query)
77
- if query_results.empty?
78
- check_elems << OpenStudio::Attribute.new('flag', "Can't calculate EUI, SQL query for building area failed.")
79
- return OpenStudio::Attribute.new('check', check_elems)
80
- else
81
- energy_plus_area = query_results.get
82
- end
83
-
84
- # temp code to check OS vs. E+ area
85
- open_studio_area = @model.getBuilding.floorArea
86
- if (energy_plus_area - open_studio_area).abs >= 0.1
87
- check_elems << OpenStudio::Attribute.new('flag', "EnergyPlus reported area is #{energy_plus_area} (m^2). OpenStudio reported area is #{@model.getBuilding.floorArea} (m^2).")
88
- end
89
-
90
- # EUI
91
- source_units = 'GJ/m^2'
92
- target_units = 'kBtu/ft^2'
93
- if energy_plus_area > 0.0 # don't calculate EUI if building doesn't have any area
94
- # todo - netSiteEnergy deducts for renewable. May want to update this to show gross consumption vs. net consumption
95
- eui = @sql.netSiteEnergy.get / energy_plus_area
96
- else
97
- check_elems << OpenStudio::Attribute.new('flag', "Can't calculate model EUI, building doesn't have any floor area.")
98
- return OpenStudio::Attribute.new('check', check_elems)
99
- end
100
-
101
- # test using new method
102
- if use_old_gem_code
103
- target_eui = @model.find_target_eui(target_standard)
104
- else
105
- std = Standard.build(target_standard)
106
- target_eui = std.model_find_target_eui(@model)
107
- end
108
-
109
- # check model vs. target for user specified tolerance.
110
- if !target_eui.nil?
111
- eui_ip_neat = OpenStudio.toNeatString(OpenStudio.convert(eui, source_units, target_units).get, 1, true)
112
- target_eui_ip_neat = OpenStudio.toNeatString(OpenStudio.convert(target_eui, source_units, target_units).get, 1, true)
113
- if eui < target_eui * (1.0 - min_pass)
114
- check_elems << OpenStudio::Attribute.new('flag', "Model EUI of #{eui_ip_neat} (#{target_units}) is less than #{min_pass * 100} % below the expected EUI of #{target_eui_ip_neat} (#{target_units}) for #{target_standard}.")
115
- elsif eui > target_eui * (1.0 + max_pass)
116
- check_elems << OpenStudio::Attribute.new('flag', "Model EUI of #{eui_ip_neat} (#{target_units}) is more than #{max_pass * 100} % above the expected EUI of #{target_eui_ip_neat} (#{target_units}) for #{target_standard}.")
117
- end
118
- else
119
- check_elems << OpenStudio::Attribute.new('flag', "Can't calculate target EUI. Make sure model has expected climate zone and building type.")
120
- end
121
- rescue StandardError => e
122
- # brief description of ruby error
123
- check_elems << OpenStudio::Attribute.new('flag', "Error prevented QAQC check from running (#{e}).")
124
-
125
- # backtrace of ruby error for diagnostic use
126
- if @error_backtrace then check_elems << OpenStudio::Attribute.new('flag', e.backtrace.join("\n").to_s) end
127
- end
128
-
129
- # add check_elms to new attribute
130
- check_elem = OpenStudio::Attribute.new('check', check_elems)
131
-
132
- return check_elem
133
- # note: registerWarning and registerValue will be added for checks downstream using os_lib_reporting_qaqc.rb
134
- end
135
- 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_eui_reasonableness(category, target_standard, min_pass, max_pass, name_only = false)
41
+ # summary of the check
42
+ check_elems = OpenStudio::AttributeVector.new
43
+ check_elems << OpenStudio::Attribute.new('name', 'EUI Reasonableness')
44
+ check_elems << OpenStudio::Attribute.new('category', category)
45
+ check_elems << OpenStudio::Attribute.new('description', "Check EUI for model against #{target_standard} DOE prototype buildings.")
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
+ # Versions of OpenStudio greater than 2.4.0 use a modified version of
57
+ # openstudio-standards with different method calls. These methods
58
+ # require a "Standard" object instead of the standard being passed into method calls.
59
+ # This Standard object is used throughout the QAQC check.
60
+ if OpenStudio::VersionString.new(OpenStudio.openStudioVersion) < OpenStudio::VersionString.new('2.4.3')
61
+ use_old_gem_code = true
62
+ else
63
+ use_old_gem_code = false
64
+ std = Standard.build(target_standard)
65
+ end
66
+
67
+ begin
68
+ # total building area
69
+ query = 'SELECT Value FROM tabulardatawithstrings WHERE '
70
+ query << "ReportName='AnnualBuildingUtilityPerformanceSummary' and "
71
+ query << "ReportForString='Entire Facility' and "
72
+ query << "TableName='Building Area' and "
73
+ query << "RowName='Total Building Area' and "
74
+ query << "ColumnName='Area' and "
75
+ query << "Units='m2';"
76
+ query_results = @sql.execAndReturnFirstDouble(query)
77
+ if query_results.empty?
78
+ check_elems << OpenStudio::Attribute.new('flag', "Can't calculate EUI, SQL query for building area failed.")
79
+ return OpenStudio::Attribute.new('check', check_elems)
80
+ else
81
+ energy_plus_area = query_results.get
82
+ end
83
+
84
+ # temp code to check OS vs. E+ area
85
+ open_studio_area = @model.getBuilding.floorArea
86
+ if (energy_plus_area - open_studio_area).abs >= 0.1
87
+ check_elems << OpenStudio::Attribute.new('flag', "EnergyPlus reported area is #{energy_plus_area} (m^2). OpenStudio reported area is #{@model.getBuilding.floorArea} (m^2).")
88
+ end
89
+
90
+ # EUI
91
+ source_units = 'GJ/m^2'
92
+ target_units = 'kBtu/ft^2'
93
+ if energy_plus_area > 0.0 # don't calculate EUI if building doesn't have any area
94
+ # todo - netSiteEnergy deducts for renewable. May want to update this to show gross consumption vs. net consumption
95
+ eui = @sql.netSiteEnergy.get / energy_plus_area
96
+ else
97
+ check_elems << OpenStudio::Attribute.new('flag', "Can't calculate model EUI, building doesn't have any floor area.")
98
+ return OpenStudio::Attribute.new('check', check_elems)
99
+ end
100
+
101
+ # test using new method
102
+ if use_old_gem_code
103
+ target_eui = @model.find_target_eui(target_standard)
104
+ else
105
+ std = Standard.build(target_standard)
106
+ target_eui = std.model_find_target_eui(@model)
107
+ end
108
+
109
+ # check model vs. target for user specified tolerance.
110
+ if !target_eui.nil?
111
+ eui_ip_neat = OpenStudio.toNeatString(OpenStudio.convert(eui, source_units, target_units).get, 1, true)
112
+ target_eui_ip_neat = OpenStudio.toNeatString(OpenStudio.convert(target_eui, source_units, target_units).get, 1, true)
113
+ if eui < target_eui * (1.0 - min_pass)
114
+ check_elems << OpenStudio::Attribute.new('flag', "Model EUI of #{eui_ip_neat} (#{target_units}) is less than #{min_pass * 100} % below the expected EUI of #{target_eui_ip_neat} (#{target_units}) for #{target_standard}.")
115
+ elsif eui > target_eui * (1.0 + max_pass)
116
+ check_elems << OpenStudio::Attribute.new('flag', "Model EUI of #{eui_ip_neat} (#{target_units}) is more than #{max_pass * 100} % above the expected EUI of #{target_eui_ip_neat} (#{target_units}) for #{target_standard}.")
117
+ end
118
+ else
119
+ check_elems << OpenStudio::Attribute.new('flag', "Can't calculate target EUI. Make sure model has expected climate zone and building type.")
120
+ end
121
+ rescue StandardError => e
122
+ # brief description of ruby error
123
+ check_elems << OpenStudio::Attribute.new('flag', "Error prevented QAQC check from running (#{e}).")
124
+
125
+ # backtrace of ruby error for diagnostic use
126
+ if @error_backtrace then check_elems << OpenStudio::Attribute.new('flag', e.backtrace.join("\n").to_s) end
127
+ end
128
+
129
+ # add check_elms to new attribute
130
+ check_elem = OpenStudio::Attribute.new('check', check_elems)
131
+
132
+ return check_elem
133
+ # note: registerWarning and registerValue will be added for checks downstream using os_lib_reporting_qaqc.rb
134
+ end
135
+ end