openstudio-calibration 0.1.3 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +7 -0
  4. data/CHANGELOG.md +40 -8
  5. data/Gemfile +6 -3
  6. data/Jenkinsfile +7 -2
  7. data/LICENSE.md +1 -1
  8. data/README.md +15 -4
  9. data/Rakefile +6 -6
  10. data/doc_templates/LICENSE.md +1 -1
  11. data/doc_templates/copyright_erb.txt +1 -1
  12. data/doc_templates/copyright_js.txt +1 -1
  13. data/doc_templates/copyright_ruby.txt +1 -1
  14. data/lib/measures/AddMonthlyJSONUtilityData/LICENSE.md +1 -1
  15. data/lib/measures/AddMonthlyJSONUtilityData/measure.rb +1 -1
  16. data/lib/measures/AddMonthlyJSONUtilityData/measure.xml +12 -11
  17. data/lib/measures/AddMonthlyUtilityData/LICENSE.md +1 -1
  18. data/lib/measures/AddMonthlyUtilityData/measure.rb +1 -1
  19. data/lib/measures/AddMonthlyUtilityData/measure.xml +13 -12
  20. data/lib/measures/CalibrationReports/LICENSE.md +1 -1
  21. data/lib/measures/CalibrationReports/README.md +2 -2
  22. data/lib/measures/CalibrationReports/measure.rb +1 -1
  23. data/lib/measures/CalibrationReports/measure.xml +11 -11
  24. data/lib/measures/CalibrationReportsEnhanced/LICENSE.md +1 -1
  25. data/lib/measures/CalibrationReportsEnhanced/measure.rb +2 -2
  26. data/lib/measures/CalibrationReportsEnhanced/measure.xml +18 -17
  27. data/lib/measures/CoilCoolingDXSingleSpeedMultiplier/LICENSE.md +1 -1
  28. data/lib/measures/CoilCoolingDXSingleSpeedMultiplier/measure.rb +1 -1
  29. data/lib/measures/CoilCoolingDXSingleSpeedMultiplier/measure.xml +14 -13
  30. data/lib/measures/CoilCoolingDXSingleSpeedPercentChange/LICENSE.md +1 -1
  31. data/lib/measures/CoilCoolingDXSingleSpeedPercentChange/measure.rb +1 -1
  32. data/lib/measures/CoilCoolingDXSingleSpeedPercentChange/measure.xml +14 -13
  33. data/lib/measures/CoilCoolingDXTwoSpeedMultiplier/LICENSE.md +1 -1
  34. data/lib/measures/CoilCoolingDXTwoSpeedMultiplier/measure.rb +1 -1
  35. data/lib/measures/CoilCoolingDXTwoSpeedMultiplier/measure.xml +14 -13
  36. data/lib/measures/CoilCoolingDXTwoSpeedPercentChange/LICENSE.md +1 -1
  37. data/lib/measures/CoilCoolingDXTwoSpeedPercentChange/measure.rb +1 -1
  38. data/lib/measures/CoilCoolingDXTwoSpeedPercentChange/measure.xml +14 -13
  39. data/lib/measures/CoilCoolingWaterMultiplier/LICENSE.md +1 -1
  40. data/lib/measures/CoilCoolingWaterMultiplier/measure.rb +1 -1
  41. data/lib/measures/CoilCoolingWaterMultiplier/measure.xml +14 -13
  42. data/lib/measures/CoilCoolingWaterPercentChange/LICENSE.md +1 -1
  43. data/lib/measures/CoilCoolingWaterPercentChange/measure.rb +1 -1
  44. data/lib/measures/CoilCoolingWaterPercentChange/measure.xml +14 -13
  45. data/lib/measures/CoilHeatingElectricMultiplier/LICENSE.md +1 -1
  46. data/lib/measures/CoilHeatingElectricMultiplier/measure.rb +1 -1
  47. data/lib/measures/CoilHeatingElectricMultiplier/measure.xml +14 -13
  48. data/lib/measures/CoilHeatingElectricPercentChange/LICENSE.md +1 -1
  49. data/lib/measures/CoilHeatingElectricPercentChange/measure.rb +1 -1
  50. data/lib/measures/CoilHeatingElectricPercentChange/measure.xml +14 -13
  51. data/lib/measures/CoilHeatingGasMultiplier/LICENSE.md +1 -1
  52. data/lib/measures/CoilHeatingGasMultiplier/measure.rb +1 -1
  53. data/lib/measures/CoilHeatingGasMultiplier/measure.xml +14 -13
  54. data/lib/measures/CoilHeatingGasPercentChange/LICENSE.md +1 -1
  55. data/lib/measures/CoilHeatingGasPercentChange/measure.rb +1 -1
  56. data/lib/measures/CoilHeatingGasPercentChange/measure.xml +14 -13
  57. data/lib/measures/CoilHeatingWaterMultiplier/LICENSE.md +1 -1
  58. data/lib/measures/CoilHeatingWaterMultiplier/measure.rb +1 -1
  59. data/lib/measures/CoilHeatingWaterMultiplier/measure.xml +14 -13
  60. data/lib/measures/CoilHeatingWaterPercentChange/LICENSE.md +1 -1
  61. data/lib/measures/CoilHeatingWaterPercentChange/measure.rb +1 -1
  62. data/lib/measures/CoilHeatingWaterPercentChange/measure.xml +14 -13
  63. data/lib/measures/ConstructionLayerZeroMaterialProperties/LICENSE.md +1 -1
  64. data/lib/measures/ConstructionLayerZeroMaterialProperties/measure.rb +1 -1
  65. data/lib/measures/ConstructionLayerZeroMaterialProperties/measure.xml +12 -11
  66. data/lib/measures/ElectricBaseboardEfficiencyAndCapacity/LICENSE.md +1 -1
  67. data/lib/measures/ElectricBaseboardEfficiencyAndCapacity/measure.rb +1 -1
  68. data/lib/measures/ElectricBaseboardEfficiencyAndCapacity/measure.xml +12 -11
  69. data/lib/measures/ExteriorWallThermalPropertiesMultiplier/LICENSE.md +1 -1
  70. data/lib/measures/ExteriorWallThermalPropertiesMultiplier/measure.rb +3 -3
  71. data/lib/measures/ExteriorWallThermalPropertiesMultiplier/measure.xml +24 -11
  72. data/lib/measures/ExteriorWallThermalPropertiesPercentChange/LICENSE.md +1 -1
  73. data/lib/measures/ExteriorWallThermalPropertiesPercentChange/measure.rb +3 -3
  74. data/lib/measures/ExteriorWallThermalPropertiesPercentChange/measure.xml +24 -11
  75. data/lib/measures/FansMultiplier/LICENSE.md +1 -1
  76. data/lib/measures/FansMultiplier/measure.rb +1 -1
  77. data/lib/measures/FansMultiplier/measure.xml +14 -13
  78. data/lib/measures/FansPercentChange/LICENSE.md +1 -1
  79. data/lib/measures/FansPercentChange/measure.rb +1 -1
  80. data/lib/measures/FansPercentChange/measure.xml +14 -13
  81. data/lib/measures/GeneralCalibrationMeasureMultiplier/LICENSE.md +1 -1
  82. data/lib/measures/GeneralCalibrationMeasureMultiplier/measure.rb +1 -1
  83. data/lib/measures/GeneralCalibrationMeasureMultiplier/measure.xml +16 -15
  84. data/lib/measures/GeneralCalibrationMeasurePercentChange/LICENSE.md +1 -1
  85. data/lib/measures/GeneralCalibrationMeasurePercentChange/measure.rb +1 -1
  86. data/lib/measures/GeneralCalibrationMeasurePercentChange/measure.xml +16 -15
  87. data/lib/measures/HardSizeHvac/LICENSE.md +1 -1
  88. data/lib/measures/HardSizeHvac/measure.rb +1 -1
  89. data/lib/measures/HardSizeHvac/measure.xml +13 -12
  90. data/lib/measures/RValueOfInsulationForConstructionMultiplier/LICENSE.md +1 -1
  91. data/lib/measures/RValueOfInsulationForConstructionMultiplier/measure.rb +1 -1
  92. data/lib/measures/RValueOfInsulationForConstructionMultiplier/measure.xml +12 -11
  93. data/lib/measures/RValueOfInsulationForConstructionPercentageChange/LICENSE.md +1 -1
  94. data/lib/measures/RValueOfInsulationForConstructionPercentageChange/measure.rb +1 -1
  95. data/lib/measures/RValueOfInsulationForConstructionPercentageChange/measure.xml +12 -11
  96. data/lib/measures/RoofThermalPropertiesMultiplier/LICENSE.md +1 -1
  97. data/lib/measures/RoofThermalPropertiesMultiplier/measure.rb +3 -3
  98. data/lib/measures/RoofThermalPropertiesMultiplier/measure.xml +24 -11
  99. data/lib/measures/RoofThermalPropertiesPercentChange/LICENSE.md +1 -1
  100. data/lib/measures/RoofThermalPropertiesPercentChange/measure.rb +3 -3
  101. data/lib/measures/RoofThermalPropertiesPercentChange/measure.xml +24 -11
  102. data/lib/measures/TimeseriesObjectiveFunction/LICENSE.md +1 -1
  103. data/lib/measures/TimeseriesObjectiveFunction/README.md +5 -171
  104. data/lib/measures/TimeseriesObjectiveFunction/measure.rb +3 -7
  105. data/lib/measures/TimeseriesObjectiveFunction/measure.xml +84 -9
  106. data/lib/measures/TimeseriesObjectiveFunction/resources/report.html.erb +6 -1
  107. data/lib/measures/TimeseriesPlot/LICENSE.md +1 -1
  108. data/lib/measures/TimeseriesPlot/README.md +5 -35
  109. data/lib/measures/TimeseriesPlot/measure.rb +1 -1
  110. data/lib/measures/TimeseriesPlot/measure.xml +28 -13
  111. data/lib/measures/TimeseriesPlot/resources/report.html.erb +6 -1
  112. data/lib/measures/WaterHeaterMixedMultiplier/LICENSE.md +1 -1
  113. data/lib/measures/WaterHeaterMixedMultiplier/measure.rb +1 -1
  114. data/lib/measures/WaterHeaterMixedMultiplier/measure.xml +14 -13
  115. data/lib/measures/WaterHeaterMixedPercentChange/LICENSE.md +1 -1
  116. data/lib/measures/WaterHeaterMixedPercentChange/measure.rb +1 -1
  117. data/lib/measures/WaterHeaterMixedPercentChange/measure.xml +14 -13
  118. data/lib/measures/{CalibrationReportsEnhanced21 → inspect_and_edit_parametric_schedules}/LICENSE.md +1 -1
  119. data/lib/measures/inspect_and_edit_parametric_schedules/README.md +41 -0
  120. data/lib/measures/{zone_report → inspect_and_edit_parametric_schedules}/README.md.erb +12 -1
  121. data/lib/measures/inspect_and_edit_parametric_schedules/docs/.gitkeep +0 -0
  122. data/lib/measures/inspect_and_edit_parametric_schedules/docs/apply_measures_now.png +0 -0
  123. data/lib/measures/inspect_and_edit_parametric_schedules/measure.rb +224 -0
  124. data/lib/measures/inspect_and_edit_parametric_schedules/measure.xml +125 -0
  125. data/lib/measures/{zone_report → shift_hours_of_operation}/LICENSE.md +1 -1
  126. data/lib/measures/shift_hours_of_operation/README.md +147 -0
  127. data/lib/measures/{MaalkaMonthlyJSONUtilityData → shift_hours_of_operation}/README.md.erb +5 -0
  128. data/lib/measures/shift_hours_of_operation/docs/.gitkeep +0 -0
  129. data/lib/measures/shift_hours_of_operation/measure.rb +525 -0
  130. data/lib/measures/shift_hours_of_operation/measure.xml +280 -0
  131. data/lib/openstudio/{calibration_measures → calibration}/extension.rb +2 -2
  132. data/lib/openstudio/{calibration_measures → calibration}/version.rb +3 -3
  133. data/lib/openstudio/{calibration_measures.rb → calibration.rb} +3 -3
  134. data/lib/{openstudio-calibration-measures.rb → openstudio-calibration.rb} +2 -2
  135. data/openstudio-calibration.gemspec +38 -0
  136. metadata +50 -61
  137. data/lib/measures/AddMonthlyUtilityData/tests/AddMonthlyUtilityData_Test.rb +0 -88
  138. data/lib/measures/AddMonthlyUtilityData/tests/electric_billed_usages.json +0 -198
  139. data/lib/measures/AddMonthlyUtilityData/tests/gas_billed_usages.json +0 -198
  140. data/lib/measures/CalibrationReports/tests/CalibrationReports_Test.rb +0 -523
  141. data/lib/measures/CalibrationReports/tests/ExampleModel.osm +0 -10497
  142. data/lib/measures/CalibrationReports/tests/ExampleModelNoDemandInput.osm +0 -10560
  143. data/lib/measures/CalibrationReports/tests/ExampleModelNoGasInput.osm +0 -10456
  144. data/lib/measures/CalibrationReports/tests/USA_CO_Golden-NREL.724666_TMY3.epw +0 -8768
  145. data/lib/measures/CalibrationReportsEnhanced/tests/CalibrationReportsEnhanced_Test.rb +0 -734
  146. data/lib/measures/CalibrationReportsEnhanced/tests/ExampleModel.osm +0 -10497
  147. data/lib/measures/CalibrationReportsEnhanced/tests/ExampleModel_FuelOil.osm +0 -12740
  148. data/lib/measures/CalibrationReportsEnhanced/tests/USA_CO_Golden-NREL.724666_TMY3.epw +0 -8768
  149. data/lib/measures/CalibrationReportsEnhanced21/README.md +0 -109
  150. data/lib/measures/CalibrationReportsEnhanced21/README.md.erb +0 -42
  151. data/lib/measures/CalibrationReportsEnhanced21/measure.rb +0 -690
  152. data/lib/measures/CalibrationReportsEnhanced21/measure.xml +0 -269
  153. data/lib/measures/CalibrationReportsEnhanced21/resources/report.html.in +0 -380
  154. data/lib/measures/MaalkaMonthlyJSONUtilityData/LICENSE.md +0 -27
  155. data/lib/measures/MaalkaMonthlyJSONUtilityData/README.md +0 -104
  156. data/lib/measures/MaalkaMonthlyJSONUtilityData/measure.rb +0 -304
  157. data/lib/measures/MaalkaMonthlyJSONUtilityData/measure.xml +0 -216
  158. data/lib/measures/zone_report/README.md +0 -26
  159. data/lib/measures/zone_report/measure.rb +0 -706
  160. data/lib/measures/zone_report/measure.xml +0 -67
  161. data/lib/measures/zone_report/resources/report.html.in +0 -342
  162. data/openstudio-calibration-measures.gemspec +0 -30
@@ -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'] = %w[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