openstudio-calibration 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/Gemfile +6 -0
  4. data/LICENSE.md +1 -1
  5. data/Rakefile +1 -1
  6. data/doc_templates/LICENSE.md +1 -1
  7. data/doc_templates/copyright_erb.txt +1 -1
  8. data/doc_templates/copyright_js.txt +1 -1
  9. data/doc_templates/copyright_ruby.txt +1 -1
  10. data/lib/measures/AddMonthlyJSONUtilityData/LICENSE.md +1 -1
  11. data/lib/measures/AddMonthlyJSONUtilityData/measure.rb +1 -1
  12. data/lib/measures/AddMonthlyJSONUtilityData/measure.xml +12 -11
  13. data/lib/measures/AddMonthlyUtilityData/LICENSE.md +1 -1
  14. data/lib/measures/AddMonthlyUtilityData/measure.rb +1 -1
  15. data/lib/measures/AddMonthlyUtilityData/measure.xml +13 -12
  16. data/lib/measures/CalibrationReports/LICENSE.md +1 -1
  17. data/lib/measures/CalibrationReports/README.md +2 -2
  18. data/lib/measures/CalibrationReports/measure.rb +1 -1
  19. data/lib/measures/CalibrationReports/measure.xml +12 -11
  20. data/lib/measures/CalibrationReportsEnhanced/LICENSE.md +1 -1
  21. data/lib/measures/CalibrationReportsEnhanced/measure.rb +2 -2
  22. data/lib/measures/CalibrationReportsEnhanced/measure.xml +18 -17
  23. data/lib/measures/CoilCoolingDXSingleSpeedMultiplier/LICENSE.md +1 -1
  24. data/lib/measures/CoilCoolingDXSingleSpeedMultiplier/measure.rb +1 -1
  25. data/lib/measures/CoilCoolingDXSingleSpeedMultiplier/measure.xml +14 -13
  26. data/lib/measures/CoilCoolingDXSingleSpeedPercentChange/LICENSE.md +1 -1
  27. data/lib/measures/CoilCoolingDXSingleSpeedPercentChange/measure.rb +1 -1
  28. data/lib/measures/CoilCoolingDXSingleSpeedPercentChange/measure.xml +14 -13
  29. data/lib/measures/CoilCoolingDXTwoSpeedMultiplier/LICENSE.md +1 -1
  30. data/lib/measures/CoilCoolingDXTwoSpeedMultiplier/measure.rb +1 -1
  31. data/lib/measures/CoilCoolingDXTwoSpeedMultiplier/measure.xml +14 -13
  32. data/lib/measures/CoilCoolingDXTwoSpeedPercentChange/LICENSE.md +1 -1
  33. data/lib/measures/CoilCoolingDXTwoSpeedPercentChange/measure.rb +1 -1
  34. data/lib/measures/CoilCoolingDXTwoSpeedPercentChange/measure.xml +14 -13
  35. data/lib/measures/CoilCoolingWaterMultiplier/LICENSE.md +1 -1
  36. data/lib/measures/CoilCoolingWaterMultiplier/measure.rb +1 -1
  37. data/lib/measures/CoilCoolingWaterMultiplier/measure.xml +14 -13
  38. data/lib/measures/CoilCoolingWaterPercentChange/LICENSE.md +1 -1
  39. data/lib/measures/CoilCoolingWaterPercentChange/measure.rb +1 -1
  40. data/lib/measures/CoilCoolingWaterPercentChange/measure.xml +14 -13
  41. data/lib/measures/CoilHeatingElectricMultiplier/LICENSE.md +1 -1
  42. data/lib/measures/CoilHeatingElectricMultiplier/measure.rb +1 -1
  43. data/lib/measures/CoilHeatingElectricMultiplier/measure.xml +14 -13
  44. data/lib/measures/CoilHeatingElectricPercentChange/LICENSE.md +1 -1
  45. data/lib/measures/CoilHeatingElectricPercentChange/measure.rb +1 -1
  46. data/lib/measures/CoilHeatingElectricPercentChange/measure.xml +14 -13
  47. data/lib/measures/CoilHeatingGasMultiplier/LICENSE.md +1 -1
  48. data/lib/measures/CoilHeatingGasMultiplier/measure.rb +1 -1
  49. data/lib/measures/CoilHeatingGasMultiplier/measure.xml +14 -13
  50. data/lib/measures/CoilHeatingGasPercentChange/LICENSE.md +1 -1
  51. data/lib/measures/CoilHeatingGasPercentChange/measure.rb +1 -1
  52. data/lib/measures/CoilHeatingGasPercentChange/measure.xml +14 -13
  53. data/lib/measures/CoilHeatingWaterMultiplier/LICENSE.md +1 -1
  54. data/lib/measures/CoilHeatingWaterMultiplier/measure.rb +1 -1
  55. data/lib/measures/CoilHeatingWaterMultiplier/measure.xml +14 -13
  56. data/lib/measures/CoilHeatingWaterPercentChange/LICENSE.md +1 -1
  57. data/lib/measures/CoilHeatingWaterPercentChange/measure.rb +1 -1
  58. data/lib/measures/CoilHeatingWaterPercentChange/measure.xml +14 -13
  59. data/lib/measures/ConstructionLayerZeroMaterialProperties/LICENSE.md +1 -1
  60. data/lib/measures/ConstructionLayerZeroMaterialProperties/measure.rb +1 -1
  61. data/lib/measures/ConstructionLayerZeroMaterialProperties/measure.xml +12 -11
  62. data/lib/measures/ElectricBaseboardEfficiencyAndCapacity/LICENSE.md +1 -1
  63. data/lib/measures/ElectricBaseboardEfficiencyAndCapacity/measure.rb +1 -1
  64. data/lib/measures/ElectricBaseboardEfficiencyAndCapacity/measure.xml +12 -11
  65. data/lib/measures/ExteriorWallThermalPropertiesMultiplier/LICENSE.md +1 -1
  66. data/lib/measures/ExteriorWallThermalPropertiesMultiplier/measure.rb +3 -3
  67. data/lib/measures/ExteriorWallThermalPropertiesMultiplier/measure.xml +24 -11
  68. data/lib/measures/ExteriorWallThermalPropertiesPercentChange/LICENSE.md +1 -1
  69. data/lib/measures/ExteriorWallThermalPropertiesPercentChange/measure.rb +3 -3
  70. data/lib/measures/ExteriorWallThermalPropertiesPercentChange/measure.xml +24 -11
  71. data/lib/measures/FansMultiplier/LICENSE.md +1 -1
  72. data/lib/measures/FansMultiplier/measure.rb +1 -1
  73. data/lib/measures/FansMultiplier/measure.xml +14 -13
  74. data/lib/measures/FansPercentChange/LICENSE.md +1 -1
  75. data/lib/measures/FansPercentChange/measure.rb +1 -1
  76. data/lib/measures/FansPercentChange/measure.xml +14 -13
  77. data/lib/measures/GeneralCalibrationMeasureMultiplier/LICENSE.md +1 -1
  78. data/lib/measures/GeneralCalibrationMeasureMultiplier/measure.rb +1 -1
  79. data/lib/measures/GeneralCalibrationMeasureMultiplier/measure.xml +16 -15
  80. data/lib/measures/GeneralCalibrationMeasurePercentChange/LICENSE.md +1 -1
  81. data/lib/measures/GeneralCalibrationMeasurePercentChange/measure.rb +1 -1
  82. data/lib/measures/GeneralCalibrationMeasurePercentChange/measure.xml +16 -15
  83. data/lib/measures/HardSizeHvac/LICENSE.md +1 -1
  84. data/lib/measures/HardSizeHvac/measure.rb +1 -1
  85. data/lib/measures/HardSizeHvac/measure.xml +13 -12
  86. data/lib/measures/RValueOfInsulationForConstructionMultiplier/LICENSE.md +1 -1
  87. data/lib/measures/RValueOfInsulationForConstructionMultiplier/measure.rb +1 -1
  88. data/lib/measures/RValueOfInsulationForConstructionMultiplier/measure.xml +12 -11
  89. data/lib/measures/RValueOfInsulationForConstructionPercentageChange/LICENSE.md +1 -1
  90. data/lib/measures/RValueOfInsulationForConstructionPercentageChange/measure.rb +1 -1
  91. data/lib/measures/RValueOfInsulationForConstructionPercentageChange/measure.xml +12 -11
  92. data/lib/measures/RoofThermalPropertiesMultiplier/LICENSE.md +1 -1
  93. data/lib/measures/RoofThermalPropertiesMultiplier/measure.rb +3 -3
  94. data/lib/measures/RoofThermalPropertiesMultiplier/measure.xml +24 -11
  95. data/lib/measures/RoofThermalPropertiesPercentChange/LICENSE.md +1 -1
  96. data/lib/measures/RoofThermalPropertiesPercentChange/measure.rb +3 -3
  97. data/lib/measures/RoofThermalPropertiesPercentChange/measure.xml +24 -11
  98. data/lib/measures/TimeseriesObjectiveFunction/LICENSE.md +1 -1
  99. data/lib/measures/TimeseriesObjectiveFunction/measure.rb +1 -1
  100. data/lib/measures/TimeseriesObjectiveFunction/measure.xml +12 -12
  101. data/lib/measures/TimeseriesObjectiveFunction/resources/report.html.erb +4 -1
  102. data/lib/measures/TimeseriesPlot/LICENSE.md +1 -1
  103. data/lib/measures/TimeseriesPlot/measure.rb +1 -1
  104. data/lib/measures/TimeseriesPlot/measure.xml +17 -17
  105. data/lib/measures/TimeseriesPlot/resources/report.html.erb +4 -1
  106. data/lib/measures/WaterHeaterMixedMultiplier/LICENSE.md +1 -1
  107. data/lib/measures/WaterHeaterMixedMultiplier/measure.rb +1 -1
  108. data/lib/measures/WaterHeaterMixedMultiplier/measure.xml +14 -13
  109. data/lib/measures/WaterHeaterMixedPercentChange/LICENSE.md +1 -1
  110. data/lib/measures/WaterHeaterMixedPercentChange/measure.rb +1 -1
  111. data/lib/measures/WaterHeaterMixedPercentChange/measure.xml +14 -13
  112. data/lib/measures/{zone_report → inspect_and_edit_parametric_schedules}/LICENSE.md +1 -1
  113. data/lib/measures/inspect_and_edit_parametric_schedules/README.md +41 -0
  114. data/lib/measures/inspect_and_edit_parametric_schedules/README.md.erb +53 -0
  115. data/lib/measures/inspect_and_edit_parametric_schedules/docs/.gitkeep +0 -0
  116. data/lib/measures/inspect_and_edit_parametric_schedules/docs/apply_measures_now.png +0 -0
  117. data/lib/measures/inspect_and_edit_parametric_schedules/measure.rb +224 -0
  118. data/lib/measures/inspect_and_edit_parametric_schedules/measure.xml +131 -0
  119. data/lib/measures/shift_hours_of_operation/LICENSE.md +27 -0
  120. data/lib/measures/shift_hours_of_operation/README.md +134 -0
  121. data/lib/measures/{zone_report → shift_hours_of_operation}/README.md.erb +5 -0
  122. data/lib/measures/shift_hours_of_operation/docs/.gitkeep +0 -0
  123. data/lib/measures/shift_hours_of_operation/measure.rb +513 -0
  124. data/lib/measures/shift_hours_of_operation/measure.xml +261 -0
  125. data/lib/openstudio-calibration.rb +1 -1
  126. data/lib/openstudio/calibration.rb +1 -1
  127. data/lib/openstudio/calibration/extension.rb +1 -1
  128. data/lib/openstudio/calibration/version.rb +2 -2
  129. data/openstudio-calibration.gemspec +3 -3
  130. metadata +21 -14
  131. data/lib/measures/zone_report/README.md +0 -26
  132. data/lib/measures/zone_report/measure.rb +0 -706
  133. data/lib/measures/zone_report/measure.xml +0 -69
  134. data/lib/measures/zone_report/resources/report.html.in +0 -342
@@ -0,0 +1,261 @@
1
+ <?xml version="1.0"?>
2
+ <measure>
3
+ <schema_version>3.0</schema_version>
4
+ <name>shift_hours_of_operation</name>
5
+ <uid>e8ae02a4-4be2-45c3-b85b-2a1d94662653</uid>
6
+ <version_id>e49fc9ef-be88-4958-aa01-5c25c5ac37a2</version_id>
7
+ <version_modified>20210423T201850Z</version_modified>
8
+ <xml_checksum>4098406A</xml_checksum>
9
+ <class_name>ShiftHoursOfOperation</class_name>
10
+ <display_name>Shift Hours of Operation</display_name>
11
+ <description>This measure will infer the hours of operation for the building and then will shift the start of the hours of operation and change the duration of the hours of operation. In an alternate workflow you can directly pass in target start and duration rather than a shift and delta. Inputs can vary for weekday, Saturday, and Sunday. if a day does not have any hours of operation to start with increasing hours of operation may not have any impact as the auto generated data may not know what to do during operating hours. Future version may be able to borrow a profile formula but would probably require additional user arguments.</description>
12
+ <modeler_description>This will only impact schedule rulesets. It will use methods in openstudio-standards to infer hours of operation, develop a parametric formula for all of the ruleset schedules, alter the hours of operation inputs to that formula and then re-apply the schedules. Input is expose to set ramp frequency of the resulting schedules. If inputs are such that no changes are requested, bypass the measure with NA so that it will not be parameterized. An advanced option for this measure would be bool to use hours of operation from OSM schedule ruleset hours of operation instead of inferring from standards. This should allow different parts of the building to have different hours of operation in the seed model.</modeler_description>
13
+ <arguments>
14
+ <argument>
15
+ <name>hoo_start_weekday</name>
16
+ <display_name>Shift the weekday start of hours of operation.</display_name>
17
+ <description>Use decimal hours so an 1 hour and 15 minute shift would be 1.25. Positive value moves the hour of operation later</description>
18
+ <type>Double</type>
19
+ <units>Hours</units>
20
+ <required>true</required>
21
+ <model_dependent>false</model_dependent>
22
+ <default_value>0</default_value>
23
+ </argument>
24
+ <argument>
25
+ <name>hoo_dur_weekday</name>
26
+ <display_name>Extend the weekday of hours of operation.</display_name>
27
+ <description>Use decimal hours so an 1 hour and 15 minute would be 1.25. Positive value makes the hour of operation longer.</description>
28
+ <type>Double</type>
29
+ <units>Hours</units>
30
+ <required>true</required>
31
+ <model_dependent>false</model_dependent>
32
+ <default_value>0</default_value>
33
+ </argument>
34
+ <argument>
35
+ <name>hoo_start_saturday</name>
36
+ <display_name>Shift the saturday start of hours of operation.</display_name>
37
+ <description>Use decimal hours so an 1 hour and 15 minute shift would be 1.25. Positive value moves the hour of operation later</description>
38
+ <type>Double</type>
39
+ <units>Hours</units>
40
+ <required>true</required>
41
+ <model_dependent>false</model_dependent>
42
+ <default_value>0</default_value>
43
+ </argument>
44
+ <argument>
45
+ <name>hoo_dur_saturday</name>
46
+ <display_name>Extend the saturday of hours of operation.</display_name>
47
+ <description>Use decimal hours so an 1 hour and 15 minute would be 1.25. Positive value makes the hour of operation longer.</description>
48
+ <type>Double</type>
49
+ <units>Hours</units>
50
+ <required>true</required>
51
+ <model_dependent>false</model_dependent>
52
+ <default_value>0</default_value>
53
+ </argument>
54
+ <argument>
55
+ <name>hoo_start_sunday</name>
56
+ <display_name>Shift the sunday start of hours of operation.</display_name>
57
+ <description>Use decimal hours so an 1 hour and 15 minute shift would be 1.25. Positive value moves the hour of operation later</description>
58
+ <type>Double</type>
59
+ <units>Hours</units>
60
+ <required>true</required>
61
+ <model_dependent>false</model_dependent>
62
+ <default_value>0</default_value>
63
+ </argument>
64
+ <argument>
65
+ <name>hoo_dur_sunday</name>
66
+ <display_name>Extend the sunday of hours of operation.</display_name>
67
+ <description>Use decimal hours so an 1 hour and 15 minute would be 1.25. Positive value makes the hour of operation longer.</description>
68
+ <type>Double</type>
69
+ <units>Hours</units>
70
+ <required>true</required>
71
+ <model_dependent>false</model_dependent>
72
+ <default_value>0</default_value>
73
+ </argument>
74
+ <argument>
75
+ <name>delta_values</name>
76
+ <display_name>Hours of operation values treated as deltas</display_name>
77
+ <description>When this is true the hours of operation start and duration represent a delta from the original model values. When switched to false they represent absolute values.</description>
78
+ <type>Boolean</type>
79
+ <required>true</required>
80
+ <model_dependent>false</model_dependent>
81
+ <default_value>true</default_value>
82
+ <choices>
83
+ <choice>
84
+ <value>true</value>
85
+ <display_name>true</display_name>
86
+ </choice>
87
+ <choice>
88
+ <value>false</value>
89
+ <display_name>false</display_name>
90
+ </choice>
91
+ </choices>
92
+ </argument>
93
+ <argument>
94
+ <name>infer_parametric_schedules</name>
95
+ <display_name>Dynamically generate parametric schedules from current ruleset schedules.</display_name>
96
+ <description>When this is true the parametric schedule formulas and hours of operation will be generated from the existing model schedules. When false it expects the model already has parametric formulas stored.</description>
97
+ <type>Boolean</type>
98
+ <required>true</required>
99
+ <model_dependent>false</model_dependent>
100
+ <default_value>true</default_value>
101
+ <choices>
102
+ <choice>
103
+ <value>true</value>
104
+ <display_name>true</display_name>
105
+ </choice>
106
+ <choice>
107
+ <value>false</value>
108
+ <display_name>false</display_name>
109
+ </choice>
110
+ </choices>
111
+ </argument>
112
+ <argument>
113
+ <name>fraction_of_daily_occ_range</name>
114
+ <display_name>Fraction of Daily Occupancy Range.</display_name>
115
+ <description>This determine what fraction of occupancy be considered operating conditions. This fraction is normalized to expanded to range seen over the full year and does not necessary equal fraction of design occupancy. This value should be between 0 and 1.0 and is only used if dynamically generated parametric schedules are used.</description>
116
+ <type>Double</type>
117
+ <units>Hours</units>
118
+ <required>true</required>
119
+ <model_dependent>false</model_dependent>
120
+ <default_value>0.25</default_value>
121
+ </argument>
122
+ <argument>
123
+ <name>target_hoo_from_model</name>
124
+ <display_name>Use model hours of operation as target</display_name>
125
+ <description>The default behavior is for this to be false. This can not be used unless Dynamically generate parametric schedules from current ruleset schedules is set to false and if the schedules in the model already have parametric profiles. When changed to true all of the hours of operation start and duration values will be ignored as the bool to treat those values as relative or absolute. Instead the hours of operation schedules for the model will be used.</description>
126
+ <type>Boolean</type>
127
+ <required>true</required>
128
+ <model_dependent>false</model_dependent>
129
+ <default_value>false</default_value>
130
+ <choices>
131
+ <choice>
132
+ <value>true</value>
133
+ <display_name>true</display_name>
134
+ </choice>
135
+ <choice>
136
+ <value>false</value>
137
+ <display_name>false</display_name>
138
+ </choice>
139
+ </choices>
140
+ </argument>
141
+ </arguments>
142
+ <outputs />
143
+ <provenances />
144
+ <tags>
145
+ <tag>Whole Building.Whole Building Schedules</tag>
146
+ </tags>
147
+ <attributes>
148
+ <attribute>
149
+ <name>Measure Type</name>
150
+ <value>ModelMeasure</value>
151
+ <datatype>string</datatype>
152
+ </attribute>
153
+ <attribute>
154
+ <name>Intended Software Tool</name>
155
+ <value>Apply Measure Now</value>
156
+ <datatype>string</datatype>
157
+ </attribute>
158
+ <attribute>
159
+ <name>Intended Software Tool</name>
160
+ <value>OpenStudio Application</value>
161
+ <datatype>string</datatype>
162
+ </attribute>
163
+ <attribute>
164
+ <name>Intended Software Tool</name>
165
+ <value>Parametric Analysis Tool</value>
166
+ <datatype>string</datatype>
167
+ </attribute>
168
+ <attribute>
169
+ <name>Intended Use Case</name>
170
+ <value>Model Articulation</value>
171
+ <datatype>string</datatype>
172
+ </attribute>
173
+ <attribute>
174
+ <name>Intended Use Case</name>
175
+ <value>Calibration</value>
176
+ <datatype>string</datatype>
177
+ </attribute>
178
+ <attribute>
179
+ <name>Intended Use Case</name>
180
+ <value>Sensitivity Analysis</value>
181
+ <datatype>string</datatype>
182
+ </attribute>
183
+ <attribute>
184
+ <name>Intended Use Case</name>
185
+ <value>New Construction EE</value>
186
+ <datatype>string</datatype>
187
+ </attribute>
188
+ <attribute>
189
+ <name>Intended Use Case</name>
190
+ <value>Retrofit EE</value>
191
+ <datatype>string</datatype>
192
+ </attribute>
193
+ </attributes>
194
+ <files>
195
+ <file>
196
+ <filename>.gitkeep</filename>
197
+ <filetype>gitkeep</filetype>
198
+ <usage_type>doc</usage_type>
199
+ <checksum>00000000</checksum>
200
+ </file>
201
+ <file>
202
+ <filename>example_model.osm</filename>
203
+ <filetype>osm</filetype>
204
+ <usage_type>test</usage_type>
205
+ <checksum>BE467EF8</checksum>
206
+ </file>
207
+ <file>
208
+ <filename>README.md.erb</filename>
209
+ <filetype>erb</filetype>
210
+ <usage_type>readmeerb</usage_type>
211
+ <checksum>232D0477</checksum>
212
+ </file>
213
+ <file>
214
+ <filename>delta_values_false.osm</filename>
215
+ <filetype>osm</filetype>
216
+ <usage_type>test</usage_type>
217
+ <checksum>21CE90F0</checksum>
218
+ </file>
219
+ <file>
220
+ <filename>target_hoo_from_model.osm</filename>
221
+ <filetype>osm</filetype>
222
+ <usage_type>test</usage_type>
223
+ <checksum>3F74E693</checksum>
224
+ </file>
225
+ <file>
226
+ <filename>SimpleModel.osm</filename>
227
+ <filetype>osm</filetype>
228
+ <usage_type>test</usage_type>
229
+ <checksum>F2778476</checksum>
230
+ </file>
231
+ <file>
232
+ <filename>README.md</filename>
233
+ <filetype>md</filetype>
234
+ <usage_type>readme</usage_type>
235
+ <checksum>88FAD40B</checksum>
236
+ </file>
237
+ <file>
238
+ <filename>LICENSE.md</filename>
239
+ <filetype>md</filetype>
240
+ <usage_type>license</usage_type>
241
+ <checksum>A21A3ED2</checksum>
242
+ </file>
243
+ <file>
244
+ <filename>shift_hours_of_operation_test.rb</filename>
245
+ <filetype>rb</filetype>
246
+ <usage_type>test</usage_type>
247
+ <checksum>F983E36E</checksum>
248
+ </file>
249
+ <file>
250
+ <version>
251
+ <software_program>OpenStudio</software_program>
252
+ <identifier>3.1.0</identifier>
253
+ <min_compatible>3.1.0</min_compatible>
254
+ </version>
255
+ <filename>measure.rb</filename>
256
+ <filetype>rb</filetype>
257
+ <usage_type>script</usage_type>
258
+ <checksum>FAF9D893</checksum>
259
+ </file>
260
+ </files>
261
+ </measure>
@@ -1,5 +1,5 @@
1
1
  # *******************************************************************************
2
- # OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC.
2
+ # OpenStudio(R), Copyright (c) 2008-2021, Alliance for Sustainable Energy, LLC.
3
3
  # All rights reserved.
4
4
  # Redistribution and use in source and binary forms, with or without
5
5
  # modification, are permitted provided that the following conditions are met:
@@ -1,5 +1,5 @@
1
1
  # *******************************************************************************
2
- # OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC.
2
+ # OpenStudio(R), Copyright (c) 2008-2021, Alliance for Sustainable Energy, LLC.
3
3
  # All rights reserved.
4
4
  # Redistribution and use in source and binary forms, with or without
5
5
  # modification, are permitted provided that the following conditions are met:
@@ -1,5 +1,5 @@
1
1
  # *******************************************************************************
2
- # OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC.
2
+ # OpenStudio(R), Copyright (c) 2008-2021, Alliance for Sustainable Energy, LLC.
3
3
  # All rights reserved.
4
4
  # Redistribution and use in source and binary forms, with or without
5
5
  # modification, are permitted provided that the following conditions are met:
@@ -1,5 +1,5 @@
1
1
  # *******************************************************************************
2
- # OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC.
2
+ # OpenStudio(R), Copyright (c) 2008-2021, Alliance for Sustainable Energy, LLC.
3
3
  # All rights reserved.
4
4
  # Redistribution and use in source and binary forms, with or without
5
5
  # modification, are permitted provided that the following conditions are met:
@@ -35,6 +35,6 @@
35
35
 
36
36
  module OpenStudio
37
37
  module Calibration
38
- VERSION = '0.3.1'.freeze
38
+ VERSION = '0.4.0'.freeze
39
39
  end
40
40
  end
@@ -27,11 +27,11 @@ Gem::Specification.new do |spec|
27
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = ['lib']
29
29
 
30
- spec.required_ruby_version = '~> 2.5.0'
30
+ spec.required_ruby_version = '~> 2.7.0'
31
31
 
32
32
  spec.add_dependency 'bundler', '~> 2.1'
33
- spec.add_dependency 'openstudio-extension', '~> 0.3.2'
34
- spec.add_dependency 'openstudio-standards', '~> 0.2.12'
33
+ spec.add_dependency 'openstudio-extension', '~> 0.4.2'
34
+ spec.add_dependency 'openstudio-standards', '~> 0.2.13'
35
35
 
36
36
  spec.add_development_dependency 'rake', '~> 13.0'
37
37
  spec.add_development_dependency 'rspec', '~> 3.9'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openstudio-calibration
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Ball
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2020-12-09 00:00:00.000000000 Z
12
+ date: 2021-04-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -31,28 +31,28 @@ dependencies:
31
31
  requirements:
32
32
  - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: 0.3.2
34
+ version: 0.4.2
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: 0.3.2
41
+ version: 0.4.2
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: openstudio-standards
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
46
  - - "~>"
47
47
  - !ruby/object:Gem::Version
48
- version: 0.2.12
48
+ version: 0.2.13
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
- version: 0.2.12
55
+ version: 0.2.13
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: rake
58
58
  requirement: !ruby/object:Gem::Requirement
@@ -273,12 +273,19 @@ files:
273
273
  - lib/measures/WaterHeaterMixedPercentChange/README.md.erb
274
274
  - lib/measures/WaterHeaterMixedPercentChange/measure.rb
275
275
  - lib/measures/WaterHeaterMixedPercentChange/measure.xml
276
- - lib/measures/zone_report/LICENSE.md
277
- - lib/measures/zone_report/README.md
278
- - lib/measures/zone_report/README.md.erb
279
- - lib/measures/zone_report/measure.rb
280
- - lib/measures/zone_report/measure.xml
281
- - lib/measures/zone_report/resources/report.html.in
276
+ - lib/measures/inspect_and_edit_parametric_schedules/LICENSE.md
277
+ - lib/measures/inspect_and_edit_parametric_schedules/README.md
278
+ - lib/measures/inspect_and_edit_parametric_schedules/README.md.erb
279
+ - lib/measures/inspect_and_edit_parametric_schedules/docs/.gitkeep
280
+ - lib/measures/inspect_and_edit_parametric_schedules/docs/apply_measures_now.png
281
+ - lib/measures/inspect_and_edit_parametric_schedules/measure.rb
282
+ - lib/measures/inspect_and_edit_parametric_schedules/measure.xml
283
+ - lib/measures/shift_hours_of_operation/LICENSE.md
284
+ - lib/measures/shift_hours_of_operation/README.md
285
+ - lib/measures/shift_hours_of_operation/README.md.erb
286
+ - lib/measures/shift_hours_of_operation/docs/.gitkeep
287
+ - lib/measures/shift_hours_of_operation/measure.rb
288
+ - lib/measures/shift_hours_of_operation/measure.xml
282
289
  - lib/openstudio-calibration.rb
283
290
  - lib/openstudio/calibration.rb
284
291
  - lib/openstudio/calibration/extension.rb
@@ -289,7 +296,7 @@ licenses: []
289
296
  metadata:
290
297
  bug_tracker_uri: https://github.com/NREL/openstudio-calibration-gem/issues
291
298
  changelog_uri: https://github.com/NREL/openstudio-calibration-gem/blob/develop/CHANGELOG.md
292
- source_code_uri: https://github.com/NREL/openstudio-calibration-gem/tree/v0.3.1
299
+ source_code_uri: https://github.com/NREL/openstudio-calibration-gem/tree/v0.4.0
293
300
  post_install_message:
294
301
  rdoc_options: []
295
302
  require_paths:
@@ -298,7 +305,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
298
305
  requirements:
299
306
  - - "~>"
300
307
  - !ruby/object:Gem::Version
301
- version: 2.5.0
308
+ version: 2.7.0
302
309
  required_rubygems_version: !ruby/object:Gem::Requirement
303
310
  requirements:
304
311
  - - ">="
@@ -1,26 +0,0 @@
1
-
2
-
3
- ###### (Automatically generated documentation)
4
-
5
- #
6
-
7
- ## Description
8
-
9
-
10
- ## Modeler Description
11
-
12
-
13
- ## Measure Type
14
- ModelMeasure
15
-
16
- ## Taxonomy
17
-
18
-
19
- ## Arguments
20
-
21
-
22
-
23
-
24
- This measure does not have any user arguments
25
-
26
-
@@ -1,706 +0,0 @@
1
- # *******************************************************************************
2
- # OpenStudio(R), Copyright (c) 2008-2020, 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
- require 'erb'
37
- # require 'pry'
38
-
39
- # start the measure
40
- class ZoneReport < OpenStudio::Measure::ReportingMeasure
41
- # define the name that a user will see, this method may be deprecated as
42
- # the display name in PAT comes from the name field in measure.xml
43
- def name
44
- 'Zone Report'
45
- end
46
-
47
- # define the arguments that the user will input
48
- def arguments
49
- args = OpenStudio::Measure::OSArgumentVector.new
50
- args
51
- end # end the arguments method
52
-
53
- # return a vector of IdfObject's to request EnergyPlus objects needed by the run method
54
- def energyPlusOutputRequests(runner, user_arguments)
55
- super(runner, user_arguments)
56
-
57
- result = OpenStudio::IdfObjectVector.new
58
-
59
- # use the built-in error checking
60
- return result unless runner.validateUserArguments(arguments, user_arguments)
61
-
62
- request = OpenStudio::IdfObject.load('Output:Table:SummaryReports,AllSummaryAndSizingPeriod;').get
63
- result << request
64
-
65
- result
66
- end
67
-
68
- # Method to make class names nicer (remove OS and _)
69
- def niceClassName(class_name)
70
- class_name = class_name.gsub('OS_', '')
71
- class_name = class_name.tr('_', ' ')
72
- class_name
73
- end
74
-
75
- # Convert a value from the view TabularDataWithStrings from the unit represented there to the given unit.
76
- # We make a bunch of special cases for unit aliases used by EnergyPlus which are not in the default
77
- # list of OpenStudio conversions
78
- # We also special case a few conversions for unitless 'units' so that our final display makes more sense to the user.
79
- # When the property is not present (for instance, cooled beams don't have properties in the sql file under 1.5)
80
- # this method will return "-" as a placeholder.
81
- def eplus_to_openstudio(unitstr)
82
- unitstr.gsub('m3', 'm^3').gsub('pa', 'Pa').gsub('m2', 'm^2').gsub(' per ', '/')
83
- end
84
-
85
- def convert_prop(property, final_units)
86
- return ['-', '-'] unless property
87
-
88
- return [property[0].to_f.round(2), ''] if final_units.empty?
89
- return [(property[0].to_f * 100).round(2), '%'] if final_units == '%'
90
- return [property[0].to_f.round(2), 'COP'] if final_units == 'COP'
91
-
92
- initial_units = eplus_to_openstudio(property[1])
93
- converted = OpenStudio.convert(property[0].to_f, initial_units, final_units)
94
- if converted.empty?
95
- "Could not convert from #{initial_units} to #{final_units}"
96
- else
97
- final_units = final_units.gsub('inH_{2}O', 'in. w.c.')
98
- [converted.get.round(2), final_units]
99
- end
100
- end
101
-
102
- def properties_for_cooling_coil(e, props, parent)
103
- autosized = case e.iddObjectType
104
- when OpenStudio::Model::CoilCoolingDXSingleSpeed.iddObjectType
105
- coil = e.to_CoilCoolingDXSingleSpeed.get
106
- coil.isRatedTotalCoolingCapacityAutosized && coil.isRatedSensibleHeatRatioAutosized && coil.isRatedAirFlowRateAutosized ? 'Yes' : 'No'
107
- when OpenStudio::Model::CoilCoolingWater.iddObjectType
108
- coil = e.to_CoilCoolingWater.get
109
- coil.isDesignWaterFlowRateAutosized && coil.isDesignAirFlowRateAutosized && coil.isDesignInletWaterTemperatureAutosized ? 'Yes' : 'No'
110
- when OpenStudio::Model::CoilCoolingWaterToAirHeatPumpEquationFit.iddObjectType
111
- coil = e.to_CoilCoolingWaterToAirHeatPumpEquationFit.get
112
- coil.isRatedTotalCoolingCapacityAutosized && coil.isRatedSensibleHeatRatioAutosized && coil.isRatedAirFlowRateAutosized ? 'Yes' : 'No'
113
- else
114
- '?'
115
- end
116
-
117
- coolingcap = convert_prop(props['Nominal Total Capacity'], 'kBtu/hr')
118
- coolingeff = convert_prop(props['Nominal Efficiency'], 'COP')
119
- sensibleheatratio = convert_prop(props['Nominal Sensible Heat Ratio'], '')
120
- parent_name = parent.name.get
121
- name = e.name.get
122
- coiltype = niceClassName(e.iddObjectType.valueName)
123
-
124
- { 'Terminal/Zone Equip Name' => parent_name, 'Coil Type' => coiltype, 'Name' => name, 'Autosized' => autosized, 'Nominal Capacity' => coolingcap, 'Nominal Efficiency' => coolingeff, 'Nominal SHR' => sensibleheatratio }
125
- end
126
-
127
- def properties_for_heating_coil(e, props, parent)
128
- autosized = '-'
129
- eff_units = 'COP'
130
- heatingcap = ['-', '-']
131
- heatingeff = ['-', '-']
132
- case e.iddObjectType
133
- when OpenStudio::Model::CoilHeatingElectric.iddObjectType
134
- coil = e.to_CoilHeatingElectric.get
135
- autosized = coil.isNominalCapacityAutosized ? 'Yes' : 'No'
136
- heatingcap = convert_prop(props['Nominal Total Capacity'], 'kW')
137
- heatingeff = convert_prop(props['Nominal Efficiency'], '%')
138
- when OpenStudio::Model::CoilHeatingGas.iddObjectType
139
- coil = e.to_CoilHeatingGas.get
140
- autosized = coil.isNominalCapacityAutosized ? 'Yes' : 'No'
141
- heatingcap = convert_prop(props['Nominal Total Capacity'], 'kBtu/hr')
142
- heatingeff = convert_prop(props['Nominal Efficiency'], 'COP')
143
- when OpenStudio::Model::CoilHeatingDXSingleSpeed.iddObjectType
144
- coil = e.to_CoilHeatingDXSingleSpeed.get
145
- autosized = coil.isRatedTotalHeatingCapacityAutosized && coil.isRatedAirFlowRateAutosized ? 'Yes' : 'No'
146
- heatingcap = convert_prop(props['Nominal Total Capacity'], 'kBtu/hr')
147
- heatingeff = convert_prop(props['Nominal Efficiency'], 'COP')
148
- when OpenStudio::Model::CoilHeatingWater.iddObjectType
149
- coil = e.to_CoilHeatingWater.get
150
- autosized = coil.isMaximumWaterFlowRateAutosized && coil.isRatedCapacityAutosized && coil.isUFactorTimesAreaValueAutosized ? 'Yes' : 'No'
151
- heatingcap = convert_prop(props['Nominal Total Capacity'], 'kBtu/hr')
152
- heatingeff = ['-', '-']
153
- when OpenStudio::Model::CoilHeatingWaterBaseboard.iddObjectType
154
- coil = e.to_CoilHeatingWaterBaseboard.get
155
- autosized = coil.isMaximumWaterFlowRateAutosized && coil.isUFactorTimesAreaValueAutosized ? 'Yes' : 'No'
156
- heatingcap = convert_prop(props['Nominal Total Capacity'], 'kBtu/hr')
157
- heatingeff = ['-', '-']
158
- when OpenStudio::Model::CoilHeatingWaterToAirHeatPumpEquationFit.iddObjectType
159
- coil = e.to_CoilHeatingWaterToAirHeatPumpEquationFit.get
160
- autosized = coil.isRatedHeatingCapacityAutosized && coil.isRatedAirFlowRateAutosized && coil.isRatedWaterFlowRateAutosized ? 'Yes' : 'No'
161
- heatingcap = convert_prop(props['Nominal Total Capacity'], 'kBtu/hr')
162
- heatingeff = convert_prop(props['Nominal Efficiency'], 'COP')
163
- else
164
- autosized = '?'
165
- end
166
-
167
- parent_name = parent.name.get
168
- name = e.name.get
169
- coiltype = niceClassName(e.iddObjectType.valueName)
170
-
171
- { 'Terminal/Zone Equip Name' => parent_name, 'Coil Type' => coiltype, 'Name' => name, 'Autosized' => autosized, 'Nominal Capacity' => heatingcap, 'Nominal Efficiency' => heatingeff }
172
- end
173
-
174
- def properties_for_fan(equipment, properties, parent)
175
- autosized = case equipment.iddObjectType
176
- when OpenStudio::Model::FanConstantVolume.iddObjectType
177
- fan = equipment.to_FanConstantVolume.get
178
- fan.isMaximumFlowRateAutosized ? 'Yes' : 'No'
179
- when OpenStudio::Model::FanVariableVolume.iddObjectType
180
- fan = equipment.to_FanVariableVolume.get
181
- fan.isMaximumFlowRateAutosized ? 'Yes' : 'No'
182
- when OpenStudio::Model::FanOnOff.iddObjectType
183
- fan = equipment.to_FanOnOff.get
184
- fan.isMaximumFlowRateAutosized ? 'Yes' : 'No'
185
- when OpenStudio::Model::FanZoneExhaust.iddObjectType
186
- 'N/A'
187
- else
188
- '?'
189
- end
190
-
191
- name = equipment.name.get
192
- parent_name = parent.name.get
193
- maxflowrate = convert_prop(properties['Max Air Flow Rate'], 'cfm')
194
- fanpressure = convert_prop(properties['Delta Pressure'], 'inH_{2}O')
195
- totalefficiency = convert_prop(properties['Total Efficiency'], '%')
196
- ratedfanpower = convert_prop(properties['Rated Electric Power'], 'W')
197
- { 'Terminal/Zone Equip Name' => parent_name, 'Fan Type' => niceClassName(equipment.iddObjectType.valueName), 'Name' => name, 'Autosized' => autosized, 'Max Flow' => maxflowrate, 'Efficiency' => totalefficiency, 'Pressure' => fanpressure, 'Power' => ratedfanpower }
198
- end
199
-
200
- # Each equipment is grouped into Heating, Cooling or Fans and has properties extracted appropriate for that group.
201
- # This method returns a tuple [equipment group, properties] where properties is a hash of name, value or name, [value, units] pairs
202
- def properties_for_zone_equipment(equipment, equipment_properties, parent)
203
- # Make properties an empty hash if it was nil
204
- equipment_properties ||= {}
205
- if /^OS_Coil_Cooling/ =~ equipment.iddObjectType.valueName
206
- return 'Cooling', properties_for_cooling_coil(equipment, equipment_properties, parent)
207
- elsif /^OS_Coil_Heating/ =~ equipment.iddObjectType.valueName
208
- return 'Heating', properties_for_heating_coil(equipment, equipment_properties, parent)
209
- elsif /^OS_Fan/ =~ equipment.iddObjectType.valueName
210
- return 'Fans', properties_for_fan(equipment, equipment_properties, parent)
211
- elsif OpenStudio::Model::ZoneHVACBaseboardConvectiveElectric.iddObjectType == equipment.iddObjectType
212
- baseboard = equipment.to_ZoneHVACBaseboardConvectiveElectric.get
213
- autosized = baseboard.isNominalCapacityAutosized ? 'Yes' : 'No'
214
- heatingcap = convert_prop(equipment_properties['Design Size Nominal Capacity'], 'kW')
215
- name = baseboard.name.get
216
- coiltype = niceClassName(baseboard.iddObjectType.valueName)
217
- return 'Heating', { 'Terminal/Zone Equip Name' => name, 'Coil Type' => coiltype, 'Name' => name, 'Autosized' => autosized, 'Nominal Capacity' => heatingcap, 'Nominal Efficiency' => [100, '%'] }
218
- else
219
- return nil, nil
220
- end
221
- end
222
-
223
- # define what happens when the measure is run
224
- def run(runner, user_arguments)
225
- super(runner, user_arguments)
226
-
227
- # use the built-in error checking
228
- return false unless runner.validateUserArguments(arguments, user_arguments)
229
-
230
- @runner = runner
231
-
232
- # get the last model and sql file
233
-
234
- model = runner.lastOpenStudioModel
235
- if model.empty?
236
- runner.registerError('Cannot find last model.')
237
- return false
238
- end
239
- model = model.get
240
-
241
- @sqlFile = runner.lastEnergyPlusSqlFile
242
- if @sqlFile.empty?
243
- runner.registerError('Cannot find last sql file.')
244
- return false
245
- end
246
- @sqlFile = @sqlFile.get
247
- model.setSqlFile(@sqlFile)
248
-
249
- @graph_data = []
250
-
251
- # Collect and collate information about the hvac equipment
252
- # When we are done we will have a hash of equipment keyed by equipment name
253
- # who's values are hashes keyed by the property name. The values of the
254
- # property hashes are [value, unit] pairs
255
- # Some types of equipment (for instance CoilCoolingCooledBeams) are not present
256
- # in the database as of OS 1.5
257
-
258
- # find table names, etc. in the SupportZoneHVACEquipFields
259
- tableNames = getDataByColumn('TableName')
260
- columnNames = getDataByColumn('ColumnName')
261
- rowNames = getDataByColumn('RowName')
262
- units = getDataByColumn('Units')
263
- values = getDataByColumn('Value')
264
- equipment_rows = tableNames.zip(columnNames, rowNames, units, values)
265
- equipment = {}
266
- equipment_rows.each do |r|
267
- _, field, name, units, value = r
268
- next unless name != 'None'
269
- eh = equipment[name] || {}
270
- eh[field] = [value, units]
271
- equipment[name] = eh
272
- end
273
-
274
- @zone_collection = []
275
-
276
- @testData = {}
277
-
278
- # Go through each zone in the model and collect all the zone equipment
279
- model.getThermalZones.sort.each do |thermalZone|
280
- # Skip unconditioned zones
281
- if thermalZone.thermostatSetpointDualSetpoint.empty?
282
- @runner.registerInfo("Skipping #{thermalZone.name} because it is unconditioned.")
283
- next
284
- end
285
-
286
- # Skip plenums
287
- if thermalZone.isPlenum == true
288
- @runner.registerInfo("Skipping #{thermalZone.name} because it is a plenum.")
289
- next
290
- end
291
-
292
- zone_equipment = {}
293
-
294
- thermalZone.equipment.each do |e|
295
- childquipment = e.to_ParentObject.get.children
296
- # Look for data on the top level equipment and each of that equipment's children
297
- found_primary_heat = false
298
- ([e] + childquipment).each do |ce|
299
- ename = ce.name.get.upcase
300
- reporting_type, equipment_properties = properties_for_zone_equipment(ce, equipment[ename], e)
301
- next unless equipment_properties
302
- # The first heating coil in a zone equipment chain will be primary heating; all
303
- # following heating coils will be marked as Backup Heating.
304
- if reporting_type == 'Heating'
305
- reporting_type = 'Backup Heating' if found_primary_heat
306
- found_primary_heat = true
307
- end
308
- # Find the priority for heating or cooling equipment - the priority is based on the 'parent' zone equipment priority
309
- if reporting_type == 'Heating'
310
- equipment_properties['Priority'] = (thermalZone.equipmentInHeatingOrder.index { |ze| ze.name.get == e.name.get && ze.iddObjectType == e.iddObjectType }) + 1
311
- end
312
- if reporting_type == 'Cooling'
313
- equipment_properties['Priority'] = (thermalZone.equipmentInCoolingOrder.index { |ze| ze.name.get == e.name.get && ze.iddObjectType == e.iddObjectType }) + 1
314
- end
315
- # If we don't yet have equipment of this type, make a new array. Then add
316
- # our equipment information to the array and update our zone equipment hash.
317
- equip_of_type = zone_equipment[reporting_type] || []
318
- equip_of_type << equipment_properties
319
- zone_equipment[reporting_type] = equip_of_type
320
- end
321
- end
322
-
323
- zoneMetrics = {}
324
- zoneMetrics[:name] = !thermalZone.name.empty? ? thermalZone.name.get : ''
325
- zoneMetrics[:equipment] = zone_equipment
326
- zoneMetrics[:area] = OpenStudio.convert(thermalZone.floorArea, 'm^2', 'ft^2').get.round(2)
327
-
328
- @currentZoneName = zoneMetrics[:name]
329
-
330
- vals = {}
331
-
332
- vals[:va] = getDetailsData('LightingSummary', 'Entire Facility', 'Interior Lighting', "#{zoneMetrics[:name]}%", 'Lighting Power Density', 'W/m2', 'W/ft^2').round(2)
333
- vals[:vb] = getDetailsData('LightingSummary', 'Entire Facility', 'Interior Lighting', "#{zoneMetrics[:name]}%", 'Full Load Hours/Week', 'hr', 'hr').round(2)
334
-
335
- vals[:vc] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Electricity', "InteriorLights:Electricity:Zone:#{zoneMetrics[:name]}", 'Electricity Annual Value', 'GJ', 'kWh').round(2)
336
-
337
- vals[:vd] = getDetailsData('InputVerificationandResultsSummary', 'Entire Facility', 'Zone Summary', zoneMetrics[:name], 'Plug and Process', 'W/m2', 'W/ft^2').round(2)
338
-
339
- vals[:ve] = getDetailsData('InputVerificationandResultsSummary', 'Entire Facility', 'Zone Summary', zoneMetrics[:name], 'Area', 'm2', 'ft^2').round(2)
340
-
341
- vals[:vf] = getDetailsData('InputVerificationandResultsSummary', 'Entire Facility', 'Zone Summary', zoneMetrics[:name], 'Conditioned (Y/N)', '', 's')
342
- vals[:vf] = 'No' if vals[:vf] == ''
343
-
344
- vals[:vg] = getDetailsData('HVACSizingSummary', 'Entire Facility', 'Zone Heating', zoneMetrics[:name], 'User Design Load', 'W', 'kBtu/hr').round(2)
345
- vals[:vh] = getDetailsData('HVACSizingSummary', 'Entire Facility', 'Zone Heating', zoneMetrics[:name], 'User Design Air Flow', 'm3/s', 'ft^3/s').round(2)
346
- vals[:vi] = getDetailsData('HVACSizingSummary', 'Entire Facility', 'Zone Cooling', zoneMetrics[:name], 'User Design Load', 'W', 'kBtu/hr').round(2)
347
- vals[:vj] = getDetailsData('HVACSizingSummary', 'Entire Facility', 'Zone Cooling', zoneMetrics[:name], 'User Design Air Flow', 'm3/s', 'ft^3/s').round(2)
348
-
349
- vals[:vk] = getDetailsData('OutdoorAirSummary', 'Entire Facility', 'Average Outdoor Air During Occupied Hours', zoneMetrics[:name], 'Mechanical Ventilation', 'ach', 'ach').round(2)
350
- vals[:vl] = getDetailsData('OutdoorAirSummary', 'Entire Facility', 'Average Outdoor Air During Occupied Hours', zoneMetrics[:name], 'Infiltration', 'ach', 'ach').round(2)
351
-
352
- vals[:vm] = getDetailsData('InputVerificationandResultsSummary', 'Entire Facility', 'Zone Summary', zoneMetrics[:name], 'People', 'm2 per person', 'ft^2/person').round(2)
353
-
354
- vals[:vn] = getDetailsData('HVACSizingSummary', 'Entire Facility', 'Zone Cooling', zoneMetrics[:name], 'Date/Time Of Peak', '', 's')
355
- vals[:vo] = getDetailsData('HVACSizingSummary', 'Entire Facility', 'Zone Heating', zoneMetrics[:name], 'Date/Time Of Peak', '', 's')
356
-
357
- vals[:vp] = getDetailsData('SystemSummary', 'Entire Facility', 'Time Setpoint Not Met', zoneMetrics[:name], 'During Heating', 'hr', 'hr')
358
- vals[:vq] = getDetailsData('SystemSummary', 'Entire Facility', 'Time Setpoint Not Met', zoneMetrics[:name], 'During Cooling', 'hr', 'hr')
359
-
360
- vals[:vr] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Gas', "InteriorEquipment:Gas:Zone:#{zoneMetrics[:name]}", 'Electricity Annual Value', 'GJ', 'Therm').round(2)
361
- vals[:vs] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Electricity', "InteriorEquipment:Electricity:Zone:#{zoneMetrics[:name]}", 'Electricity Annual Value', 'GJ', 'kWh').round(2)
362
-
363
- vals[:vt] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Gas', "InteriorEquipment:Gas:Zone:#{zoneMetrics[:name]}", 'Gas Maximum Value', 'W', 'kBtu/hr').round(2)
364
- vals[:vu] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Gas', "InteriorEquipment:Gas:Zone:#{zoneMetrics[:name]}", 'Timestamp of Maximum', '', 's')
365
-
366
- vals[:vv] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Electricity', "InteriorLights:Electricity:Zone:#{zoneMetrics[:name]}", 'Electricity Maximum Value', 'W', 'kW').round(2)
367
- vals[:vw] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Electricity', "InteriorLights:Electricity:Zone:#{zoneMetrics[:name]}", 'Timestamp of Maximum', '', 's')
368
-
369
- # X unused
370
-
371
- vals[:vy] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Electricity', "InteriorEquipment:Electricity:Zone:#{zoneMetrics[:name]}", 'Electricity Maximum Value', 'W', 'kW').round(2)
372
- vals[:vz] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Electricity', "InteriorEquipment:Electricity:Zone:#{zoneMetrics[:name]}", 'Timestamp of Maximum', '', 's')
373
-
374
- vals[:vaa] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Other', "InteriorEquipment:DistrictHeating:Zone:#{zoneMetrics[:name]}", 'Annual Value', 'GJ', 'kBtu').round(2)
375
- vals[:vab] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Other', "InteriorEquipment:DistrictHeating:Zone:#{zoneMetrics[:name]}", 'Maximum Value', 'W', 'kBtu/hr').round(2)
376
- vals[:vac] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Other', "InteriorEquipment:DistrictHeating:Zone:#{zoneMetrics[:name]}", 'Timestamp of Maximum', '', 's')
377
-
378
- vals[:vad] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Other', "Heating:EnergyTransfer:Zone:#{zoneMetrics[:name]}", 'Annual Value', 'GJ', 'kBtu').round(2)
379
- vals[:vae] = (getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Other', "Heating:EnergyTransfer:Zone:#{zoneMetrics[:name]}", 'Maximum Value', 'W', 'kBtu/hr') / zoneMetrics[:area]).round(2)
380
- vals[:vaf] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Other', "Heating:EnergyTransfer:Zone:#{zoneMetrics[:name]}", 'Timestamp of Maximum', '', 's')
381
-
382
- vals[:vag] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Other', "Cooling:EnergyTransfer:Zone:#{zoneMetrics[:name]}", 'Annual Value', 'GJ', 'kBtu').round(2)
383
- vals[:vah] = (getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Other', "Cooling:EnergyTransfer:Zone:#{zoneMetrics[:name]}", 'Maximum Value', 'W', 'kBtu/hr') / zoneMetrics[:area]).round(2)
384
- vals[:vai] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Other', "Cooling:EnergyTransfer:Zone:#{zoneMetrics[:name]}", 'Timestamp of Maximum', '', 's')
385
-
386
- vals[:vaj] = zoneHeatComponentCalc('People', zoneMetrics)
387
- vals[:vak] = zoneHeatComponentCalc('Lights', zoneMetrics)
388
- vals[:val] = zoneHeatComponentCalc('Equipment', zoneMetrics)
389
- vals[:vam] = zoneHeatComponentCalc('Refrigeration', zoneMetrics)
390
- vals[:van] = zoneHeatComponentCalc('Water Use Equipment', zoneMetrics)
391
- vals[:vao] = zoneHeatComponentCalc('HVAC Equipment Losses', zoneMetrics)
392
- vals[:vap] = zoneHeatComponentCalc('Power Generation Equipment', zoneMetrics)
393
- vals[:vaq] = zoneHeatComponentCalc('Infiltration', zoneMetrics)
394
- vals[:var] = zoneHeatComponentCalc('Zone Ventilation', zoneMetrics)
395
- vals[:vas] = zoneHeatComponentCalc('Interzone Mixing', zoneMetrics)
396
- vals[:vat] = zoneHeatComponentCalc('Exterior Wall', zoneMetrics)
397
- vals[:vau] = zoneHeatComponentCalc('Interzone Wall', zoneMetrics)
398
- vals[:vav] = zoneHeatComponentCalc('Ground Contact Wall', zoneMetrics)
399
- vals[:vaw] = zoneHeatComponentCalc('Other Wall', zoneMetrics)
400
- vals[:vax] = zoneHeatComponentCalc('Opaque Door', zoneMetrics)
401
- vals[:vay] = zoneHeatComponentCalc('Roof', zoneMetrics)
402
- vals[:vaz] = zoneHeatComponentCalc('Interzone Ceiling', zoneMetrics)
403
- vals[:vba] = zoneHeatComponentCalc('Other Roof', zoneMetrics)
404
- vals[:vbb] = zoneHeatComponentCalc('Exterior Floor', zoneMetrics)
405
- vals[:vbc] = zoneHeatComponentCalc('Interzone Floor', zoneMetrics)
406
- vals[:vbd] = zoneHeatComponentCalc('Ground Contact Floor', zoneMetrics)
407
- vals[:vbe] = zoneHeatComponentCalc('Other Floor', zoneMetrics)
408
- vals[:vbf] = zoneHeatComponentCalc('Fenestration Conduction', zoneMetrics)
409
- vals[:vbg] = zoneHeatComponentCalc('Fenestration Solar', zoneMetrics)
410
-
411
- vals[:vbh] = getDetailsData('ZoneComponentLoadSummary', (zoneMetrics[:name]).to_s, 'Heating Peak Conditions', 'Time of Peak Load', 'Value', '', 's')
412
-
413
- vals[:vbi] = zoneCoolComponentCalc('People', zoneMetrics)
414
- vals[:vbj] = zoneCoolComponentCalc('Lights', zoneMetrics)
415
- vals[:vbk] = zoneCoolComponentCalc('Equipment', zoneMetrics)
416
- vals[:vbl] = zoneCoolComponentCalc('Refrigeration', zoneMetrics)
417
- vals[:vbm] = zoneCoolComponentCalc('Water Use Equipment', zoneMetrics)
418
- vals[:vbn] = zoneCoolComponentCalc('HVAC Equipment Losses', zoneMetrics)
419
- vals[:vbo] = zoneCoolComponentCalc('Power Generation Equipment', zoneMetrics)
420
- vals[:vbp] = zoneCoolComponentCalc('Infiltration', zoneMetrics)
421
- vals[:vbq] = zoneCoolComponentCalc('Zone Ventilation', zoneMetrics)
422
- vals[:vbr] = zoneCoolComponentCalc('Interzone Mixing', zoneMetrics)
423
- vals[:vbs] = zoneCoolComponentCalc('Exterior Wall', zoneMetrics)
424
- vals[:vbt] = zoneCoolComponentCalc('Interzone Wall', zoneMetrics)
425
- vals[:vbu] = zoneCoolComponentCalc('Ground Contact Wall', zoneMetrics)
426
- vals[:vbv] = zoneCoolComponentCalc('Other Wall', zoneMetrics)
427
- vals[:vbw] = zoneCoolComponentCalc('Opaque Door', zoneMetrics)
428
- vals[:vbx] = zoneCoolComponentCalc('Roof', zoneMetrics)
429
- vals[:vby] = zoneCoolComponentCalc('Interzone Ceiling', zoneMetrics)
430
- vals[:vbz] = zoneCoolComponentCalc('Other Roof', zoneMetrics)
431
- vals[:vca] = zoneCoolComponentCalc('Exterior Floor', zoneMetrics)
432
- vals[:vcb] = zoneCoolComponentCalc('Interzone Floor', zoneMetrics)
433
- vals[:vcc] = zoneCoolComponentCalc('Ground Contact Floor', zoneMetrics)
434
- vals[:vcd] = zoneCoolComponentCalc('Other Floor', zoneMetrics)
435
- vals[:vce] = zoneCoolComponentCalc('Fenestration Conduction', zoneMetrics)
436
- vals[:vcf] = zoneCoolComponentCalc('Fenestration Solar', zoneMetrics)
437
-
438
- vals[:vcg] = getDetailsData('ZoneComponentLoadSummary', (zoneMetrics[:name]).to_s, 'Cooling Peak Conditions', 'Time of Peak Load', 'Value', '', 's')
439
-
440
- # vals = loadTestVals( vals )
441
-
442
- vals[:sumBasicHeating] = (vals[:vaj] + vals[:vak] + vals[:val] + vals[:vam] + vals[:vaq] + vals[:var] + vals[:vas]).round(2)
443
- vals[:sumBasicCooling] = (vals[:vbi] + vals[:vbj] + vals[:vbk] + vals[:vbl] + vals[:vbp] + vals[:vbq] + vals[:vbr]).round(2)
444
-
445
- vals[:sumOtherHeating] = (vals[:van] + vals[:vao] + vals[:vap]).round(2)
446
- vals[:sumOtherCooling] = (vals[:vbm] + vals[:vbn] + vals[:vbo]).round(2)
447
-
448
- vals[:sumWallDoorHeating] = (vals[:vat] + vals[:vau] + vals[:vav] + vals[:vaw] + vals[:vax]).round(2)
449
- vals[:sumWallDoorCooling] = (vals[:vbs] + vals[:vbt] + vals[:vbu] + vals[:vbv] + vals[:vbw]).round(2)
450
-
451
- vals[:sumRoofCeilingHeating] = (vals[:vay] + vals[:vaz] + vals[:vba]).round(2)
452
- vals[:sumRoofCeilingCooling] = (vals[:vbx] + vals[:vby] + vals[:vbz]).round(2)
453
-
454
- vals[:sumFloorHeating] = (vals[:vbb] + vals[:vbc] + vals[:vbd] + vals[:vbe]).round(2)
455
- vals[:sumFloorCooling] = (vals[:vca] + vals[:vcb] + vals[:vcc] + vals[:vcd]).round(2)
456
-
457
- vals[:sumWindowsHeating] = (vals[:vbf] + vals[:vbg]).round(2)
458
- vals[:sumWindowsCooling] = (vals[:vce] + vals[:vcf]).round(2)
459
-
460
- vals[:sumHeatingTotal] = (vals[:sumBasicHeating] + vals[:sumOtherHeating] + vals[:sumWallDoorHeating] + vals[:sumRoofCeilingHeating] + vals[:sumFloorHeating] + vals[:sumWindowsHeating]).round(2)
461
- vals[:sumCoolingTotal] = (vals[:sumBasicCooling] + vals[:sumOtherCooling] + vals[:sumWallDoorCooling] + vals[:sumRoofCeilingCooling] + vals[:sumFloorCooling] + vals[:sumWindowsCooling]).round(2)
462
-
463
- zoneMetrics[:vals] = vals
464
-
465
- @zone_collection.push(zoneMetrics)
466
-
467
- stacked_bars(zoneMetrics)
468
- end
469
-
470
- @zone_collection = @zone_collection.sort_by { |z| z[:name] }
471
-
472
- equipment_lengths = @zone_collection.map { |z| z[:equipment].values.map(&:length) }
473
- max_zone_equipments = equipment_lengths.flatten.max
474
-
475
- # Convert the graph data to JSON
476
- # This measure requires ruby 2.0.0 to create the JSON for the report graph
477
- if RUBY_VERSION >= '2.0.0'
478
- require 'json'
479
- @graph_data = @graph_data.to_json
480
- else
481
- runner.registerInfo("This Measure needs Ruby 2.0.0 to generate timeseries graphs on the report. You have Ruby #{RUBY_VERSION}. OpenStudio 1.4.2 and higher user Ruby 2.0.0.")
482
- end
483
-
484
- web_asset_path = OpenStudio.getSharedResourcesPath / OpenStudio::Path.new('web_assets')
485
-
486
- html_in = getResourceFileData('report.html.in')
487
-
488
- # configure template with variable values
489
- renderer = ERB.new(html_in)
490
- html_out = renderer.result(binding)
491
-
492
- writeResourceFileData('report.html', html_out)
493
- # copyResourceFile( "graph_resource.js" )
494
- # copyResourceFile( "style_resource.css" )
495
-
496
- # closing the sql file
497
- @sqlFile.close
498
-
499
- # reporting final condition
500
- runner.registerFinalCondition("Successfully finished writing 'Zone Report'.")
501
-
502
- true
503
- end # end the run method
504
-
505
- def zoneHeatComponentCalc(component, zoneMetrics)
506
- (getDetailsData('ZoneComponentLoadSummary', (zoneMetrics[:name]).to_s, 'Estimated Heating Peak Load Components', component, 'Total', 'W', 'Btu/hr') / zoneMetrics[:area]).round(2)
507
- end
508
-
509
- def zoneCoolComponentCalc(component, zoneMetrics)
510
- (getDetailsData('ZoneComponentLoadSummary', (zoneMetrics[:name]).to_s, 'Estimated Cooling Peak Load Components', component, 'Total', 'W', 'Btu/hr') / zoneMetrics[:area]).round(2)
511
- end
512
-
513
- def stacked_bars(zoneMetrics)
514
- # people, lights, equipment, refrigeration, other, infiltration, zone ventilation,
515
- # interzone mixing, walls/doors, roof/ceiling, floor, windows
516
-
517
- vals = zoneMetrics[:vals]
518
-
519
- heatingVals = [vals[:vaj],
520
- vals[:vak],
521
- vals[:val],
522
- vals[:vam],
523
- vals[:sumOtherHeating],
524
- vals[:vaq],
525
- vals[:var],
526
- vals[:vas],
527
- vals[:sumWallDoorHeating],
528
- vals[:sumRoofCeilingHeating],
529
- vals[:sumFloorHeating],
530
- vals[:sumWindowsHeating]]
531
-
532
- coolingVals = [vals[:vbi],
533
- vals[:vbj],
534
- vals[:vbk],
535
- vals[:vbl],
536
- vals[:sumOtherCooling],
537
- vals[:vbp],
538
- vals[:vbq],
539
- vals[:vbr],
540
- vals[:sumWallDoorCooling],
541
- vals[:sumRoofCeilingCooling],
542
- vals[:sumFloorCooling],
543
- vals[:sumWindowsCooling]]
544
-
545
- positiveHeating = heatingVals.select { |v| v >= 0 }.inject { |sum, x| sum + x } || 0
546
- negativeHeating = heatingVals.select { |v| v < 0 }.inject { |sum, x| sum + x } || 0
547
-
548
- positiveCooling = coolingVals.select { |v| v >= 0 }.inject { |sum, x| sum + x } || 0
549
- negativeCooling = coolingVals.select { |v| v < 0 }.inject { |sum, x| sum + x } || 0
550
-
551
- maxPositive = positiveHeating > positiveCooling ? positiveHeating : positiveCooling
552
- maxNegative = negativeHeating < negativeCooling ? negativeHeating : negativeCooling
553
-
554
- maxPositive = maxPositive == 0 ? maxNegative * -0.20 : maxPositive
555
- maxNegative = maxNegative == 0 ? maxPositive * -0.10 : maxNegative
556
-
557
- maxPositive += (maxPositive * 0.20).round(2)
558
- maxNegative += (maxNegative * 0.10).round(2)
559
-
560
- stacked_vals = [[0, maxPositive, maxNegative, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
561
- [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, vals[:sumHeatingTotal], 0],
562
- [2,
563
- vals[:vaj],
564
- vals[:vak],
565
- vals[:val],
566
- vals[:vam],
567
- vals[:sumOtherHeating],
568
- vals[:vaq],
569
- vals[:var],
570
- vals[:vas],
571
- vals[:sumWallDoorHeating],
572
- vals[:sumRoofCeilingHeating],
573
- vals[:sumFloorHeating],
574
- vals[:sumWindowsHeating],
575
- 0,
576
- 0],
577
- [3,
578
- vals[:vbi],
579
- vals[:vbj],
580
- vals[:vbk],
581
- vals[:vbl],
582
- vals[:sumOtherCooling],
583
- vals[:vbp],
584
- vals[:vbq],
585
- vals[:vbr],
586
- vals[:sumWallDoorCooling],
587
- vals[:sumRoofCeilingCooling],
588
- vals[:sumFloorCooling],
589
- vals[:sumWindowsCooling],
590
- 0,
591
- 0],
592
- [4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, vals[:sumCoolingTotal]],
593
- [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
594
-
595
- # Add the hourly load data to JSON for the report.html
596
- graph = {}
597
- graph['title'] = ''
598
- graph['xaxislabel'] = ''
599
- graph['yaxislabel'] = 'Contribution Btu/hr/ft2'
600
- graph['labels'] = ['index', 'people', 'lights', 'equipment', 'refrigeration', 'other', 'infiltration', 'zone_ventilation', 'interzone_mixing', 'walls/doors', 'roof/ceiling', 'floor', 'windows', 'net/heating', 'net/cooling']
601
- graph['colors'] = ['#888855', '#AAAA55', '#3333AA', '#8888FF', '#888888', '#9999FF', '#AAAAFF', '#AA6666', '#777733', '#888833', '#999933', '#9999FF', '#FF9999', '#9999FF']
602
- graph['data'] = stacked_vals
603
-
604
- @graph_data << graph
605
- end
606
-
607
- def getPctLoad(val, total)
608
- if val != '' && total != 0
609
- (val * 100 / total).round(2)
610
- else
611
- 0
612
- end
613
- end
614
-
615
- def getResourceFileData(fileName)
616
- data_in_path = "#{File.dirname(__FILE__)}/resources/#{fileName}"
617
- unless File.exist?(data_in_path)
618
- data_in_path = "#{File.dirname(__FILE__)}/#{fileName}"
619
- end
620
-
621
- html_in = ''
622
- File.open(data_in_path, 'r') do |file|
623
- html_in = file.read
624
- end
625
-
626
- html_in
627
- end
628
-
629
- def writeResourceFileData(fileName, data)
630
- File.open("./#{fileName}", 'w') do |file|
631
- file << data
632
- # make sure data is written to the disk one way or the other
633
- begin
634
- file.fsync
635
- rescue StandardError
636
- file.flush
637
- end
638
- end
639
- end
640
-
641
- # Fetch a value from the tabulardatawithstrings database view
642
- # If final_units is "s" the value is returned unchanged as a string
643
- # Otherwise the value is converted from units to final_units - units is specified in energy plus style (m2, m3, etc)
644
- # and final_units should be open studio style (m^2, m^3, ...)
645
- # If the data is not found or cannot be converted a warning is registered and "" or 0.0 is returned.
646
- def getDetailsData(report, forstring, table, row, column, units, final_units)
647
- forstring.upcase! if report == 'ZoneComponentLoadSummary'
648
-
649
- str_HVACEquipment_query = 'SELECT Value FROM tabulardatawithstrings WHERE '
650
- str_HVACEquipment_query << "ReportName='#{report}' AND "
651
- str_HVACEquipment_query << "ReportForString='#{forstring}' AND "
652
- str_HVACEquipment_query << "TableName='#{table}' AND "
653
- str_HVACEquipment_query << "RowName LIKE '#{row}' AND "
654
- str_HVACEquipment_query << "ColumnName='#{column}' AND "
655
- str_HVACEquipment_query << "Units='#{units}'"
656
-
657
- query_results = @sqlFile.execAndReturnFirstString(str_HVACEquipment_query)
658
-
659
- if query_results.empty?
660
-
661
- @runner.registerWarning("Could not get data for #{report} #{forstring} #{table} #{row} #{column}.")
662
- return final_units == 's' ? '' : 0.0
663
-
664
- else
665
- r = query_results.get
666
- if report == 'ZoneComponentLoadSummary'
667
- @testData["#{@currentZoneName}_#{table}_#{row}"] = r
668
- end
669
-
670
- if final_units == 's'
671
- return r
672
- else
673
- converted = OpenStudio.convert(r.to_f, eplus_to_openstudio(units), final_units)
674
- if converted.empty?
675
- @runner.registerError("Could not convert #{r} from #{units} to #{final_units}")
676
- return 0.0
677
- else
678
- return converted.get.round(2)
679
- end
680
- end
681
-
682
- end
683
- end
684
-
685
- def getDataByColumn(colName)
686
- strvec_HVACEquipment_query = "SELECT #{colName} FROM tabulardatawithstrings WHERE "
687
- strvec_HVACEquipment_query << "ReportName='EquipmentSummary' and "
688
- strvec_HVACEquipment_query << "ReportForString='Entire Facility'"
689
- strvec_HVACEquipment_query << 'ORDER BY TableName, ColumnName, RowName, Units, Value'
690
-
691
- query_results = @sqlFile.execAndReturnVectorOfString(strvec_HVACEquipment_query).get
692
-
693
- if query_results.empty?
694
- @runner.registerError("Could not get data for requested Column #{colName}.")
695
- return []
696
- else
697
- return query_results
698
- end
699
- end
700
-
701
- # Accessor to support unit tests
702
- attr_reader :zone_collection
703
- end # end the measure
704
-
705
- # this allows the measure to be use by the application
706
- ZoneReport.new.registerWithApplication