openstudio-standards 0.4.0 → 0.5.0.rc1

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 (376) hide show
  1. checksums.yaml +4 -4
  2. data/data/inventory/thermal_bridging.csv +90 -0
  3. data/data/standards/OpenStudio_Standards-deer-comstock.xlsx +0 -0
  4. data/data/standards/manage_OpenStudio_Standards.rb +1 -1
  5. data/data/standards/test_performance_expected_dd_results.csv +2014 -1891
  6. data/lib/openstudio-standards/btap/analysis.rb +8 -8
  7. data/lib/openstudio-standards/btap/bridging.rb +664 -645
  8. data/lib/openstudio-standards/btap/btap.model.rb +14 -14
  9. data/lib/openstudio-standards/btap/btap.rb +7 -7
  10. data/lib/openstudio-standards/btap/btap_result.rb +1 -1
  11. data/lib/openstudio-standards/btap/economics.rb +23 -23
  12. data/lib/openstudio-standards/btap/envelope.rb +8 -8
  13. data/lib/openstudio-standards/btap/equest.rb +1 -1
  14. data/lib/openstudio-standards/btap/geometry.rb +2 -2
  15. data/lib/openstudio-standards/btap/mpc.rb +7 -7
  16. data/lib/openstudio-standards/btap/schedules.rb +1 -1
  17. data/lib/openstudio-standards/btap/simmanager.rb +4 -4
  18. data/lib/openstudio-standards/btap/spaceloads.rb +26 -26
  19. data/lib/openstudio-standards/btap/utilities.rb +6 -6
  20. data/lib/openstudio-standards/btap/vintagizer.rb +1 -1
  21. data/lib/openstudio-standards/constructions/information.rb +83 -0
  22. data/lib/openstudio-standards/constructions/materials/modify.rb +72 -0
  23. data/lib/openstudio-standards/constructions/modify.rb +80 -0
  24. data/lib/openstudio-standards/create_typical/create_typical.rb +983 -0
  25. data/lib/openstudio-standards/create_typical/enumerations.rb +484 -0
  26. data/lib/openstudio-standards/create_typical/space_type_blend.rb +791 -0
  27. data/lib/openstudio-standards/create_typical/space_type_ratios.rb +494 -0
  28. data/lib/openstudio-standards/daylighting/space.rb +47 -0
  29. data/lib/openstudio-standards/geometry/create.rb +801 -0
  30. data/lib/openstudio-standards/geometry/create_bar.rb +2171 -0
  31. data/lib/openstudio-standards/geometry/information.rb +462 -0
  32. data/lib/openstudio-standards/geometry/modify.rb +48 -0
  33. data/lib/openstudio-standards/hvac/air_loop/information.rb +79 -0
  34. data/lib/openstudio-standards/hvac/cbecs_hvac.rb +616 -0
  35. data/lib/openstudio-standards/hvac/setpoint_managers/information.rb +91 -0
  36. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.AirTerminalSingleDuctVAVReheat.rb +1 -1
  37. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.AirTerminalSingleDuctVAVReheat.rb +1 -1
  38. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.AirTerminalSingleDuctVAVReheat.rb +1 -1
  39. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.Model.rb +1 -1
  40. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.AirTerminalSingleDuctVAVReheat.rb +1 -1
  41. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.Model.rb +2 -2
  42. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.hvac_systems.rb +1 -1
  43. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirTerminalSingleDuctVAVReheat.rb +1 -1
  44. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Model.rb +4 -36
  45. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.hvac_systems.rb +1 -1
  46. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirTerminalSingleDuctVAVReheat.rb +1 -1
  47. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Model.rb +4 -36
  48. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Space.rb +3 -3
  49. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.hvac_systems.rb +1 -1
  50. data/lib/openstudio-standards/prototypes/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.AirTerminalSingleDuctVAVReheat.rb +1 -1
  51. data/lib/openstudio-standards/prototypes/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.Model.elevators.rb +1 -1
  52. data/lib/openstudio-standards/prototypes/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.AirTerminalSingleDuctVAVReheat.rb +1 -1
  53. data/lib/openstudio-standards/prototypes/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.CoilHeatingGas.rb +1 -1
  54. data/lib/openstudio-standards/prototypes/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.Model.elevators.rb +1 -1
  55. data/lib/openstudio-standards/prototypes/ashrae_90_1/nrel_nze_ready_2017/nrel_zne_ready_2017.AirTerminalSingleDuctVAVReheat.rb +1 -1
  56. data/lib/openstudio-standards/prototypes/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.AirTerminalSingleDuctVAVReheat.rb +1 -1
  57. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.College.rb +7 -7
  58. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Courthouse.rb +8 -8
  59. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.FullServiceRestaurant.rb +14 -14
  60. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.HighRiseApartment.rb +9 -9
  61. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Hospital.rb +16 -16
  62. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Laboratory.rb +7 -7
  63. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeDataCenterHighITE.rb +8 -8
  64. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeDataCenterLowITE.rb +8 -8
  65. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeHotel.rb +11 -11
  66. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeOffice.rb +7 -7
  67. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeOfficeDetailed.rb +9 -9
  68. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.MediumOffice.rb +8 -8
  69. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.MediumOfficeDetailed.rb +11 -11
  70. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.MidriseApartment.rb +9 -9
  71. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Outpatient.rb +19 -19
  72. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.PrimarySchool.rb +10 -10
  73. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.QuickServiceRestaurant.rb +13 -13
  74. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.RetailStandalone.rb +6 -6
  75. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.RetailStripmall.rb +6 -6
  76. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SecondarySchool.rb +9 -9
  77. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallDataCenterHighITE.rb +8 -8
  78. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallDataCenterLowITE.rb +8 -8
  79. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallHotel.rb +8 -8
  80. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallOffice.rb +8 -8
  81. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallOfficeDetailed.rb +11 -11
  82. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SuperMarket.rb +10 -10
  83. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SuperTallBuilding.rb +19 -19
  84. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.TallBuilding.rb +18 -18
  85. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Warehouse.rb +6 -6
  86. data/lib/openstudio-standards/prototypes/common/do_not_edit_metaclasses.rb +957 -957
  87. data/lib/openstudio-standards/prototypes/common/objects/Prototype.AirConditionerVariableRefrigerantFlow.rb +1 -1
  88. data/lib/openstudio-standards/prototypes/common/objects/Prototype.AirTerminalSingleDuctVAVReheat.rb +1 -1
  89. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingWaterToAirHeatPumpEquationFit.rb +84 -16
  90. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingDXSingleSpeed.rb +1 -1
  91. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingGas.rb +1 -1
  92. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingWaterToAirHeatPumpEquationFit.rb +61 -10
  93. data/lib/openstudio-standards/prototypes/common/objects/Prototype.ControllerWaterCoil.rb +1 -1
  94. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoolingTower.rb +1 -1
  95. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Fan.rb +1 -1
  96. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanConstantVolume.rb +1 -1
  97. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanOnOff.rb +1 -1
  98. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanVariableVolume.rb +1 -1
  99. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanZoneExhaust.rb +1 -1
  100. data/lib/openstudio-standards/prototypes/common/objects/Prototype.HeatExchangerAirToAirSensibleAndLatent.rb +2 -2
  101. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.exterior_lights.rb +4 -4
  102. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.hvac.rb +4 -4
  103. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.rb +43 -30
  104. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.swh.rb +1 -1
  105. data/lib/openstudio-standards/prototypes/common/objects/Prototype.ServiceWaterHeating.rb +18 -11
  106. data/lib/openstudio-standards/prototypes/common/objects/Prototype.SizingSystem.rb +1 -1
  107. data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +774 -117
  108. data/lib/openstudio-standards/prototypes/common/objects/Prototype.radiant_system_controls.rb +340 -481
  109. data/lib/openstudio-standards/prototypes/common/objects/Prototype.refrigeration.rb +3 -3
  110. data/lib/openstudio-standards/prototypes/common/objects/Prototype.utilities.rb +3 -3
  111. data/lib/openstudio-standards/prototypes/common/prototype_metaprogramming.rb +22 -22
  112. data/lib/openstudio-standards/prototypes/deer/deer.Model.rb +1 -1
  113. data/lib/openstudio-standards/qaqc/calibration.rb +131 -0
  114. data/lib/openstudio-standards/qaqc/create_results.rb +983 -0
  115. data/lib/openstudio-standards/qaqc/envelope.rb +399 -0
  116. data/lib/openstudio-standards/qaqc/eui.rb +213 -0
  117. data/lib/openstudio-standards/qaqc/hvac.rb +1943 -0
  118. data/lib/openstudio-standards/qaqc/internal_loads.rb +568 -0
  119. data/lib/openstudio-standards/qaqc/reporting.rb +141 -0
  120. data/lib/openstudio-standards/qaqc/schedules.rb +129 -0
  121. data/lib/openstudio-standards/qaqc/service_water_heating.rb +273 -0
  122. data/lib/openstudio-standards/qaqc/weather_files.rb +497 -0
  123. data/lib/openstudio-standards/qaqc/zone_conditions.rb +278 -0
  124. data/lib/openstudio-standards/schedules/create.rb +364 -0
  125. data/lib/openstudio-standards/schedules/information.rb +169 -0
  126. data/lib/openstudio-standards/schedules/modify.rb +445 -0
  127. data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +110 -71
  128. data/lib/openstudio-standards/standards/Standards.AirTerminalSingleDuctParallelPIUReheat.rb +3 -3
  129. data/lib/openstudio-standards/standards/Standards.AirTerminalSingleDuctVAVReheat.rb +4 -4
  130. data/lib/openstudio-standards/standards/Standards.BoilerHotWater.rb +2 -1
  131. data/lib/openstudio-standards/standards/Standards.ChillerElectricEIR.rb +16 -10
  132. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXSingleSpeed.rb +4 -4
  133. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXTwoSpeed.rb +1 -1
  134. data/lib/openstudio-standards/standards/Standards.CoilCoolingWaterToAirHeatPumpEquationFit.rb +1 -1
  135. data/lib/openstudio-standards/standards/Standards.CoilDX.rb +4 -4
  136. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXMultiSpeed.rb +1 -1
  137. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXSingleSpeed.rb +5 -5
  138. data/lib/openstudio-standards/standards/Standards.CoilHeatingGas.rb +1 -1
  139. data/lib/openstudio-standards/standards/Standards.CoilHeatingGasMultiStage.rb +1 -1
  140. data/lib/openstudio-standards/standards/Standards.CoilHeatingWaterToAirHeatPumpEquationFit.rb +1 -1
  141. data/lib/openstudio-standards/standards/Standards.Construction.rb +17 -18
  142. data/lib/openstudio-standards/standards/Standards.CoolingTower.rb +6 -6
  143. data/lib/openstudio-standards/standards/Standards.CoolingTowerSingleSpeed.rb +1 -1
  144. data/lib/openstudio-standards/standards/Standards.CoolingTowerTwoSpeed.rb +1 -1
  145. data/lib/openstudio-standards/standards/Standards.CoolingTowerVariableSpeed.rb +1 -1
  146. data/lib/openstudio-standards/standards/Standards.Fan.rb +6 -12
  147. data/lib/openstudio-standards/standards/Standards.FanVariableVolume.rb +2 -2
  148. data/lib/openstudio-standards/standards/Standards.FluidCooler.rb +1 -1
  149. data/lib/openstudio-standards/standards/Standards.HeaderedPumpsVariableSpeed.rb +1 -1
  150. data/lib/openstudio-standards/standards/Standards.HeatExchangerSensLat.rb +3 -3
  151. data/lib/openstudio-standards/standards/Standards.Model.rb +411 -261
  152. data/lib/openstudio-standards/standards/Standards.PlanarSurface.rb +2 -2
  153. data/lib/openstudio-standards/standards/Standards.PlantLoop.rb +94 -29
  154. data/lib/openstudio-standards/standards/Standards.Pump.rb +2 -2
  155. data/lib/openstudio-standards/standards/Standards.ScheduleConstant.rb +2 -2
  156. data/lib/openstudio-standards/standards/Standards.ScheduleRuleset.rb +14 -14
  157. data/lib/openstudio-standards/standards/Standards.Space.rb +37 -30
  158. data/lib/openstudio-standards/standards/Standards.SpaceType.rb +38 -29
  159. data/lib/openstudio-standards/standards/Standards.SubSurface.rb +7 -7
  160. data/lib/openstudio-standards/standards/Standards.Surface.rb +13 -13
  161. data/lib/openstudio-standards/standards/Standards.ThermalZone.rb +109 -66
  162. data/lib/openstudio-standards/standards/Standards.WaterHeaterMixed.rb +11 -4
  163. data/lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb +6 -6
  164. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.AirLoopHVAC.rb +1 -1
  165. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.PlantLoop.rb +1 -1
  166. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.Space.rb +1 -1
  167. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.Space.rb +1 -1
  168. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.AirLoopHVAC.rb +4 -4
  169. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.AirTerminalSingleDuctVAVReheat.rb +1 -1
  170. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.Space.rb +4 -4
  171. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.AirLoopHVAC.rb +4 -4
  172. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.AirTerminalSingleDuctVAVReheat.rb +1 -1
  173. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.CoolingTowerVariableSpeed.rb +1 -1
  174. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.Model.rb +5 -21
  175. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.Space.rb +4 -4
  176. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.WaterHeaterMixed.rb +1 -1
  177. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.ZoneHVACComponent.rb +1 -1
  178. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirLoopHVAC.rb +36 -4
  179. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirTerminalSingleDuctVAVReheat.rb +1 -1
  180. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.CoolingTowerVariableSpeed.rb +1 -1
  181. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Space.rb +4 -4
  182. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.ZoneHVACComponent.rb +1 -1
  183. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/comstock_ashrae_90_1_2016/comstock_ashrae_90_1_2016.AirLoopHVAC.rb +26 -0
  184. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +53 -10
  185. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirTerminalSingleDuctVAVReheat.rb +1 -1
  186. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.CoolingTowerVariableSpeed.rb +1 -1
  187. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Space.rb +6 -6
  188. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.ZoneHVACComponent.rb +2 -2
  189. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/comstock_ashrae_90_1_2019/comstock_ashrae_90_1_2019.AirLoopHVAC.rb +26 -0
  190. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.curves.json +211 -211
  191. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.economizers.json +14 -14
  192. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.AirLoopHVAC.rb +4 -4
  193. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.Model.rb +1 -1
  194. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.PlantLoop.rb +1 -1
  195. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.economizers.json +14 -14
  196. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.AirLoopHVAC.rb +4 -4
  197. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.Model.rb +1 -1
  198. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.PlantLoop.rb +1 -1
  199. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.AirLoopHVAC.rb +6 -6
  200. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.AirTerminalSingleDuctVAVReheat.rb +1 -1
  201. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.CoolingTowerVariableSpeed.rb +1 -1
  202. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.PlantLoop.rb +1 -1
  203. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.Space.rb +4 -4
  204. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.AirLoopHVAC.rb +6 -6
  205. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.AirTerminalSingleDuctVAVReheat.rb +1 -1
  206. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.CoolingTowerVariableSpeed.rb +1 -1
  207. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.PlantLoop.rb +1 -1
  208. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.Space.rb +4 -4
  209. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirLoopHVAC.rb +22 -28
  210. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirTerminalSingleDuctParallelPIUReheat.rb +1 -1
  211. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirTerminalSingleDuctVAVReheat.rb +2 -2
  212. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.BoilerHotWater.rb +1 -74
  213. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ChillerElectricEIR.rb +7 -59
  214. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilCoolingDXSingleSpeed.rb +1 -1
  215. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilCoolingDXTwoSpeed.rb +1 -1
  216. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilDX.rb +1 -1
  217. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingDXSingleSpeed.rb +1 -1
  218. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingGas.rb +1 -21
  219. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.DesignSpecificationOutdoorAir.rb +101 -0
  220. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanConstantVolume.rb +1 -1
  221. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanOnOff.rb +1 -1
  222. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanVariableVolume.rb +1 -1
  223. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.HeatExchangerSensLat.rb +1 -1
  224. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Model.rb +643 -526
  225. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlanarSurface.rb +8 -2
  226. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlantLoop.rb +17 -77
  227. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Space.rb +74 -16
  228. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.SpaceType.rb +96 -44
  229. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Surface.rb +6 -6
  230. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ThermalZone.rb +18 -6
  231. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ZoneHVACComponent.rb +1 -1
  232. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.rb +328 -74
  233. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019.Model.rb +0 -118
  234. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019.rb +2 -1
  235. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.heat_rejection.json +1 -1
  236. data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/baseline_outdoor_air.md +35 -0
  237. data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/set_plug_load_measures.md +1 -1
  238. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/ashrae_90_1_prm.UserData.rb +228 -0
  239. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_enums.rb +131 -0
  240. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_space.csv +1 -1
  241. data/lib/openstudio-standards/standards/cbes/cbes.AirLoopHVAC.rb +5 -5
  242. data/lib/openstudio-standards/standards/cbes/cbes.Model.rb +1 -1
  243. data/lib/openstudio-standards/standards/cbes/cbes.PlantLoop.rb +1 -1
  244. data/lib/openstudio-standards/standards/cbes/cbes.Space.rb +1 -1
  245. data/lib/openstudio-standards/standards/cbes/cbes_t24_2005/cbes_t24_2005.Space.rb +1 -1
  246. data/lib/openstudio-standards/standards/cbes/cbes_t24_2008/cbes_t24_2008.Space.rb +1 -1
  247. data/lib/openstudio-standards/standards/deer/deer.AirLoopHVAC.rb +109 -27
  248. data/lib/openstudio-standards/standards/deer/deer.Space.rb +1 -1
  249. data/lib/openstudio-standards/standards/deer/deer_1985/data/deer_1985.economizers.json +246 -4
  250. data/lib/openstudio-standards/standards/deer/deer_1996/data/deer_1996.economizers.json +246 -4
  251. data/lib/openstudio-standards/standards/deer/deer_2003/data/deer_2003.economizers.json +246 -4
  252. data/lib/openstudio-standards/standards/deer/deer_2003/deer_2003.ThermalZone.rb +18 -18
  253. data/lib/openstudio-standards/standards/deer/deer_2007/data/deer_2007.economizers.json +246 -4
  254. data/lib/openstudio-standards/standards/deer/deer_2007/deer_2007.ThermalZone.rb +18 -18
  255. data/lib/openstudio-standards/standards/deer/deer_2011/data/deer_2011.economizers.json +246 -4
  256. data/lib/openstudio-standards/standards/deer/deer_2011/deer_2011.ThermalZone.rb +18 -18
  257. data/lib/openstudio-standards/standards/deer/deer_2014/data/deer_2014.economizers.json +248 -6
  258. data/lib/openstudio-standards/standards/deer/deer_2014/deer_2014.Space.rb +3 -3
  259. data/lib/openstudio-standards/standards/deer/deer_2014/deer_2014.ThermalZone.rb +18 -18
  260. data/lib/openstudio-standards/standards/deer/deer_2015/data/deer_2015.economizers.json +248 -6
  261. data/lib/openstudio-standards/standards/deer/deer_2015/deer_2015.Space.rb +3 -3
  262. data/lib/openstudio-standards/standards/deer/deer_2015/deer_2015.ThermalZone.rb +18 -18
  263. data/lib/openstudio-standards/standards/deer/deer_2017/data/deer_2017.economizers.json +248 -6
  264. data/lib/openstudio-standards/standards/deer/deer_2017/deer_2017.Space.rb +3 -3
  265. data/lib/openstudio-standards/standards/deer/deer_2017/deer_2017.ThermalZone.rb +18 -18
  266. data/lib/openstudio-standards/standards/deer/deer_2020/data/deer_2020.economizers.json +248 -6
  267. data/lib/openstudio-standards/standards/deer/deer_2020/deer_2020.AirLoopHVAC.rb +18 -5
  268. data/lib/openstudio-standards/standards/deer/deer_2020/deer_2020.FanVariableVolume.rb +1 -1
  269. data/lib/openstudio-standards/standards/deer/deer_2020/deer_2020.Space.rb +3 -3
  270. data/lib/openstudio-standards/standards/deer/deer_2020/deer_2020.ThermalZone.rb +18 -18
  271. data/lib/openstudio-standards/standards/deer/deer_2025/data/deer_2025.economizers.json +248 -6
  272. data/lib/openstudio-standards/standards/deer/deer_2025/deer_2025.AirLoopHVAC.rb +3 -3
  273. data/lib/openstudio-standards/standards/deer/deer_2025/deer_2025.FanVariableVolume.rb +1 -1
  274. data/lib/openstudio-standards/standards/deer/deer_2025/deer_2025.Space.rb +3 -3
  275. data/lib/openstudio-standards/standards/deer/deer_2030/data/deer_2030.economizers.json +248 -6
  276. data/lib/openstudio-standards/standards/deer/deer_2030/data/deer_2030.heat_pumps.json +2 -2
  277. data/lib/openstudio-standards/standards/deer/deer_2030/deer_2030.AirLoopHVAC.rb +3 -3
  278. data/lib/openstudio-standards/standards/deer/deer_2030/deer_2030.FanVariableVolume.rb +1 -1
  279. data/lib/openstudio-standards/standards/deer/deer_2030/deer_2030.Space.rb +3 -3
  280. data/lib/openstudio-standards/standards/deer/deer_2035/data/deer_2035.economizers.json +248 -6
  281. data/lib/openstudio-standards/standards/deer/deer_2035/deer_2035.AirLoopHVAC.rb +3 -3
  282. data/lib/openstudio-standards/standards/deer/deer_2035/deer_2035.FanVariableVolume.rb +1 -1
  283. data/lib/openstudio-standards/standards/deer/deer_2035/deer_2035.Space.rb +3 -3
  284. data/lib/openstudio-standards/standards/deer/deer_2040/data/deer_2040.economizers.json +248 -6
  285. data/lib/openstudio-standards/standards/deer/deer_2040/deer_2040.AirLoopHVAC.rb +3 -3
  286. data/lib/openstudio-standards/standards/deer/deer_2040/deer_2040.FanVariableVolume.rb +1 -1
  287. data/lib/openstudio-standards/standards/deer/deer_2040/deer_2040.Space.rb +3 -3
  288. data/lib/openstudio-standards/standards/deer/deer_2045/data/deer_2045.economizers.json +260 -0
  289. data/lib/openstudio-standards/standards/deer/deer_2045/deer_2045.AirLoopHVAC.rb +3 -3
  290. data/lib/openstudio-standards/standards/deer/deer_2045/deer_2045.FanVariableVolume.rb +1 -1
  291. data/lib/openstudio-standards/standards/deer/deer_2045/deer_2045.Space.rb +3 -3
  292. data/lib/openstudio-standards/standards/deer/deer_2050/data/deer_2050.economizers.json +248 -6
  293. data/lib/openstudio-standards/standards/deer/deer_2050/deer_2050.AirLoopHVAC.rb +3 -3
  294. data/lib/openstudio-standards/standards/deer/deer_2050/deer_2050.FanVariableVolume.rb +1 -1
  295. data/lib/openstudio-standards/standards/deer/deer_2050/deer_2050.Space.rb +3 -3
  296. data/lib/openstudio-standards/standards/deer/deer_2055/data/deer_2055.economizers.json +248 -6
  297. data/lib/openstudio-standards/standards/deer/deer_2055/deer_2055.AirLoopHVAC.rb +3 -3
  298. data/lib/openstudio-standards/standards/deer/deer_2055/deer_2055.FanVariableVolume.rb +1 -1
  299. data/lib/openstudio-standards/standards/deer/deer_2055/deer_2055.Space.rb +3 -3
  300. data/lib/openstudio-standards/standards/deer/deer_2060/data/deer_2060.economizers.json +248 -6
  301. data/lib/openstudio-standards/standards/deer/deer_2060/deer_2060.AirLoopHVAC.rb +3 -3
  302. data/lib/openstudio-standards/standards/deer/deer_2060/deer_2060.FanVariableVolume.rb +1 -1
  303. data/lib/openstudio-standards/standards/deer/deer_2060/deer_2060.Space.rb +3 -3
  304. data/lib/openstudio-standards/standards/deer/deer_2065/data/deer_2065.economizers.json +248 -6
  305. data/lib/openstudio-standards/standards/deer/deer_2065/deer_2065.AirLoopHVAC.rb +3 -3
  306. data/lib/openstudio-standards/standards/deer/deer_2065/deer_2065.FanVariableVolume.rb +1 -1
  307. data/lib/openstudio-standards/standards/deer/deer_2065/deer_2065.Space.rb +3 -3
  308. data/lib/openstudio-standards/standards/deer/deer_2070/data/deer_2070.economizers.json +248 -6
  309. data/lib/openstudio-standards/standards/deer/deer_2070/deer_2070.AirLoopHVAC.rb +3 -3
  310. data/lib/openstudio-standards/standards/deer/deer_2070/deer_2070.FanVariableVolume.rb +1 -1
  311. data/lib/openstudio-standards/standards/deer/deer_2070/deer_2070.Space.rb +3 -3
  312. data/lib/openstudio-standards/standards/deer/deer_2075/data/deer_2075.economizers.json +248 -6
  313. data/lib/openstudio-standards/standards/deer/deer_2075/deer_2075.AirLoopHVAC.rb +3 -3
  314. data/lib/openstudio-standards/standards/deer/deer_2075/deer_2075.FanVariableVolume.rb +1 -1
  315. data/lib/openstudio-standards/standards/deer/deer_2075/deer_2075.Space.rb +3 -3
  316. data/lib/openstudio-standards/standards/deer/deer_pre_1975/data/deer_pre_1975.economizers.json +246 -4
  317. data/lib/openstudio-standards/standards/necb/BTAP1980TO2010/data/space_types.json +447 -223
  318. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/building_envelope.rb +1 -1
  319. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/data/space_types.json +447 -223
  320. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_systems.rb +5 -2
  321. data/lib/openstudio-standards/standards/necb/ECMS/data/chiller_types.json +25 -0
  322. data/lib/openstudio-standards/standards/necb/ECMS/data/chillers.json +44 -0
  323. data/lib/openstudio-standards/standards/necb/ECMS/data/curves.json +225 -0
  324. data/lib/openstudio-standards/standards/necb/ECMS/ecms.rb +2 -2
  325. data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +193 -73
  326. data/lib/openstudio-standards/standards/necb/ECMS/pv_ground.rb +1 -1
  327. data/lib/openstudio-standards/standards/necb/NECB2011/autozone.rb +10 -4
  328. data/lib/openstudio-standards/standards/necb/NECB2011/beps_compliance_path.rb +7 -7
  329. data/lib/openstudio-standards/standards/necb/NECB2011/building_envelope.rb +4 -5
  330. data/lib/openstudio-standards/standards/necb/NECB2011/data/chiller_types.json +32 -0
  331. data/lib/openstudio-standards/standards/necb/NECB2011/data/chillers.json +1 -1
  332. data/lib/openstudio-standards/standards/necb/NECB2011/data/constants.json +36 -0
  333. data/lib/openstudio-standards/standards/necb/NECB2011/data/fuel_type_sets.json +7 -7
  334. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/NorthernEducation.osm +47587 -0
  335. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/NorthernHealthCare.osm +49764 -0
  336. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/Warehouse.osm +283 -297
  337. data/lib/openstudio-standards/standards/necb/NECB2011/data/space_type_unit_definitions.txt +2 -1
  338. data/lib/openstudio-standards/standards/necb/NECB2011/data/space_types.json +447 -223
  339. data/lib/openstudio-standards/standards/necb/NECB2011/data/standards_data.rb +3 -3
  340. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_1_multi_speed.rb +1 -1
  341. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +49 -27
  342. data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +400 -202
  343. data/lib/openstudio-standards/standards/necb/NECB2011/service_water_heating.rb +4 -4
  344. data/lib/openstudio-standards/standards/necb/NECB2015/data/space_types.json +637 -318
  345. data/lib/openstudio-standards/standards/necb/NECB2015/hvac_systems.rb +18 -1
  346. data/lib/openstudio-standards/standards/necb/NECB2015/necb_2015.rb +3 -3
  347. data/lib/openstudio-standards/standards/necb/NECB2017/data/space_types.json +637 -318
  348. data/lib/openstudio-standards/standards/necb/NECB2017/hvac_systems.rb +1 -1
  349. data/lib/openstudio-standards/standards/necb/NECB2017/necb_2017.rb +3 -3
  350. data/lib/openstudio-standards/standards/necb/NECB2020/building_envelope.rb +1 -1
  351. data/lib/openstudio-standards/standards/necb/NECB2020/data/space_types.json +615 -307
  352. data/lib/openstudio-standards/standards/necb/NECB2020/service_water_heating.rb +4 -4
  353. data/lib/openstudio-standards/standards/necb/common/btap_data.rb +10 -5
  354. data/lib/openstudio-standards/standards/necb/common/btap_datapoint.rb +1 -1
  355. data/lib/openstudio-standards/utilities/assertion.rb +128 -0
  356. data/lib/openstudio-standards/utilities/logging.rb +2 -3
  357. data/lib/openstudio-standards/utilities/object_info.rb +39 -18
  358. data/lib/openstudio-standards/utilities/schedule_translator.rb +8 -6
  359. data/lib/openstudio-standards/utilities/simulation.rb +24 -11
  360. data/lib/openstudio-standards/utilities/sqlfile.rb +10 -5
  361. data/lib/openstudio-standards/version.rb +1 -1
  362. data/lib/openstudio-standards/weather/Weather.Model.rb +8 -9
  363. data/lib/openstudio-standards/weather/Weather.stat_file.rb +3 -3
  364. data/lib/openstudio-standards/weather/information.rb +35 -0
  365. data/lib/openstudio-standards.rb +69 -5
  366. metadata +52 -16
  367. data/data/standards/OpenStudio_Standards-deer-ALL-comstock(space_types).xlsx +0 -0
  368. data/lib/openstudio-standards/hvac_sizing/Siz.AirLoopHVAC.rb +0 -59
  369. data/lib/openstudio-standards/hvac_sizing/Siz.CoilCoolingWater.rb +0 -13
  370. data/lib/openstudio-standards/hvac_sizing/Siz.HVACComponent.rb +0 -36
  371. data/lib/openstudio-standards/hvac_sizing/Siz.HeatingCoolingFuels.rb +0 -898
  372. data/lib/openstudio-standards/hvac_sizing/Siz.Model.rb +0 -126
  373. data/lib/openstudio-standards/hvac_sizing/Siz.ThermalZone.rb +0 -356
  374. data/lib/openstudio-standards/prototypes/ashrae_90_1/nrel_nze_ready_2017/nrel_zne_ready_2017.Model.rb +0 -35
  375. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoolingTower.rb +0 -110
  376. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoolingTowerVariableSpeed.rb +0 -5
@@ -0,0 +1,399 @@
1
+ # Module to apply QAQC checks to a model
2
+ module OpenstudioStandards
3
+ module QAQC
4
+ # @!group Envelope
5
+
6
+ # Check the envelope conductance against a standard
7
+ #
8
+ # @param category [String] category to bin this check into
9
+ # @param target_standard [String] standard template, e.g. '90.1-2013'
10
+ # @param min_pass_pct [Double] threshold for throwing an error for percent difference
11
+ # @param max_pass_pct [Double] threshold for throwing an error for percent difference
12
+ # @param name_only [Boolean] If true, only return the name of this check
13
+ # @return [OpenStudio::Attribute] OpenStudio Attribute object containing check results
14
+ # @todo unique tolerance ranges for conductance, reflectance, and shgc
15
+ def self.check_envelope_conductance(category, target_standard, min_pass_pct: 0.2, max_pass_pct: 0.2, name_only: false)
16
+ # summary of the check
17
+ check_elems = OpenStudio::AttributeVector.new
18
+ check_elems << OpenStudio::Attribute.new('name', 'Envelope R-Value')
19
+ check_elems << OpenStudio::Attribute.new('category', category)
20
+ if target_standard == 'ICC IECC 2015'
21
+ dislay_standard = target_standard
22
+ check_elems << OpenStudio::Attribute.new('description', "Check envelope against Table R402.1.2 and R402.1.4 in #{dislay_standard} Residential Provisions.")
23
+ elsif target_standard.include?('90.1-2013')
24
+ display_standard = "ASHRAE #{target_standard}"
25
+ check_elems << OpenStudio::Attribute.new('description', "Check envelope against #{display_standard} Table 5.5.2, Table G2.1.5 b,c,d,e, Section 5.5.3.1.1a. Roof reflectance of 55%, wall reflectance of 30%.")
26
+ else
27
+ # @todo could add more elsifs if want to dsiplay tables and sections for additional 90.1 standards
28
+ if target_standard.include?('90.1')
29
+ display_standard = "ASHRAE #{target_standard}"
30
+ else
31
+ display_standard = target_standard
32
+ end
33
+ check_elems << OpenStudio::Attribute.new('description', "Check envelope against #{display_standard}. Roof reflectance of 55%, wall reflectance of 30%.")
34
+ end
35
+
36
+ # stop here if only name is requested this is used to populate display name for arguments
37
+ if name_only == true
38
+ results = []
39
+ check_elems.each do |elem|
40
+ results << elem.valueAsString
41
+ end
42
+ return results
43
+ end
44
+
45
+ std = Standard.build(target_standard)
46
+
47
+ # list of surface types to identify for each space type for surfaces and sub-surfaces
48
+ construction_type_array = []
49
+ construction_type_array << ['ExteriorWall', 'SteelFramed']
50
+ construction_type_array << ['ExteriorRoof', 'IEAD']
51
+ construction_type_array << ['ExteriorFloor', 'Mass']
52
+ construction_type_array << ['ExteriorDoor', 'Swinging']
53
+ construction_type_array << ['ExteriorWindow', 'Metal framing (all other)']
54
+ construction_type_array << ['Skylight', 'Glass with Curb']
55
+ # overhead door doesn't show in list, or glass door
56
+
57
+ begin
58
+ # loop through all space types used in the model
59
+ @model.getSpaceTypes.sort.each do |space_type|
60
+ next if space_type.floorArea <= 0
61
+
62
+ space_type_const_properties = {}
63
+ construction_type_array.each do |const_type|
64
+ # gather data for exterior wall
65
+ intended_surface_type = const_type[0]
66
+ standards_construction_type = const_type[1]
67
+ space_type_const_properties[intended_surface_type] = {}
68
+ data = std.space_type_get_construction_properties(space_type, intended_surface_type, standards_construction_type)
69
+ if data.nil?
70
+ puts "lookup for #{target_standard},#{intended_surface_type},#{standards_construction_type}"
71
+ check_elems << OpenStudio::Attribute.new('flag', "Didn't find construction for #{standards_construction_type} #{intended_surface_type} for #{space_type.name}.")
72
+ elsif intended_surface_type.include? 'ExteriorWall' || 'ExteriorFloor' || 'ExteriorDoor'
73
+ space_type_const_properties[intended_surface_type]['u_value'] = data['assembly_maximum_u_value']
74
+ space_type_const_properties[intended_surface_type]['reflectance'] = 0.30 # hard coded value
75
+ elsif intended_surface_type.include? 'ExteriorRoof'
76
+ space_type_const_properties[intended_surface_type]['u_value'] = data['assembly_maximum_u_value']
77
+ space_type_const_properties[intended_surface_type]['reflectance'] = 0.55 # hard coded value
78
+ else
79
+ space_type_const_properties[intended_surface_type]['u_value'] = data['assembly_maximum_u_value']
80
+ space_type_const_properties[intended_surface_type]['shgc'] = data['assembly_maximum_solar_heat_gain_coefficient']
81
+ end
82
+ end
83
+
84
+ # make array of construction details for surfaces
85
+ surface_details = []
86
+ missing_surface_constructions = []
87
+ sub_surface_details = []
88
+ missing_sub_surface_constructions = []
89
+
90
+ # loop through spaces
91
+ space_type.spaces.each do |space|
92
+ space.surfaces.each do |surface|
93
+ next if surface.outsideBoundaryCondition != 'Outdoors'
94
+
95
+ if surface.construction.is_initialized
96
+ surface_details << { boundary_condition: surface.outsideBoundaryCondition, surface_type: surface.surfaceType, construction: surface.construction.get }
97
+ else
98
+ missing_surface_constructions << surface.name.get
99
+ end
100
+
101
+ # make array of construction details for sub_surfaces
102
+ surface.subSurfaces.each do |sub_surface|
103
+ if sub_surface.construction.is_initialized
104
+ sub_surface_details << { boundary_condition: sub_surface.outsideBoundaryCondition, surface_type: sub_surface.subSurfaceType, construction: sub_surface.construction.get }
105
+ else
106
+ missing_sub_surface_constructions << sub_surface.name.get
107
+ end
108
+ end
109
+ end
110
+ end
111
+
112
+ if !missing_surface_constructions.empty?
113
+ check_elems << OpenStudio::Attribute.new('flag', "#{missing_surface_constructions.size} surfaces are missing constructions in #{space_type.name}. Spaces and can't be checked.")
114
+ end
115
+
116
+ if !missing_sub_surface_constructions.empty?
117
+ check_elems << OpenStudio::Attribute.new('flag', "#{missing_sub_surface_constructions.size} sub surfaces are missing constructions in #{space_type.name}. Spaces and can't be checked.")
118
+ end
119
+
120
+ # gather target values for this space type
121
+ # @todo address support for other surface types e.g. overhead door glass door
122
+ target_r_value_ip = {}
123
+ target_reflectance = {}
124
+ target_u_value_ip = {}
125
+ target_shgc = {}
126
+ target_r_value_ip['Wall'] = 1.0 / space_type_const_properties['ExteriorWall']['u_value'].to_f
127
+ target_reflectance['Wall'] = space_type_const_properties['ExteriorWall']['reflectance'].to_f
128
+ target_r_value_ip['RoofCeiling'] = 1.0 / space_type_const_properties['ExteriorRoof']['u_value'].to_f
129
+ target_reflectance['RoofCeiling'] = space_type_const_properties['ExteriorRoof']['reflectance'].to_f
130
+ target_r_value_ip['Floor'] = 1.0 / space_type_const_properties['ExteriorFloor']['u_value'].to_f
131
+ target_reflectance['Floor'] = space_type_const_properties['ExteriorFloor']['reflectance'].to_f
132
+ target_r_value_ip['Door'] = 1.0 / space_type_const_properties['ExteriorDoor']['u_value'].to_f
133
+ target_reflectance['Door'] = space_type_const_properties['ExteriorDoor']['reflectance'].to_f
134
+ target_u_value_ip['FixedWindow'] = space_type_const_properties['ExteriorWindow']['u_value'].to_f
135
+ target_shgc['FixedWindow'] = space_type_const_properties['ExteriorWindow']['shgc'].to_f
136
+ target_u_value_ip['OperableWindow'] = space_type_const_properties['ExteriorWindow']['u_value'].to_f
137
+ target_shgc['OperableWindow'] = space_type_const_properties['ExteriorWindow']['shgc'].to_f
138
+ target_u_value_ip['Skylight'] = space_type_const_properties['Skylight']['u_value'].to_f
139
+ target_shgc['Skylight'] = space_type_const_properties['Skylight']['shgc'].to_f
140
+
141
+ # loop through unique construction array combinations
142
+ surface_details.uniq.each do |surface_detail|
143
+ if surface_detail[:construction].thermalConductance.is_initialized
144
+
145
+ # don't use intended surface type of construction, look map based on surface type and boundary condition
146
+ boundary_condition = surface_detail[:boundary_condition]
147
+ surface_type = surface_detail[:surface_type]
148
+ intended_surface_type = ''
149
+ if boundary_condition.to_s == 'Outdoors'
150
+ case surface_type.to_s
151
+ when 'Wall'
152
+ intended_surface_type = 'ExteriorWall'
153
+ when 'RoofCeiling'
154
+ intended_surface_type = 'ExteriorRoof'
155
+ when 'Floor'
156
+ intended_surface_type = 'ExteriorFloor'
157
+ end
158
+ else
159
+ # currently only used for surfaces with outdoor boundary condition
160
+ end
161
+ film_coefficients_r_value = std.film_coefficients_r_value(intended_surface_type, includes_int_film = true, includes_ext_film = true)
162
+ thermal_conductance = surface_detail[:construction].thermalConductance.get
163
+ r_value_with_film = 1 / thermal_conductance + film_coefficients_r_value
164
+ source_units = 'm^2*K/W'
165
+ target_units = 'ft^2*h*R/Btu'
166
+ r_value_ip = OpenStudio.convert(r_value_with_film, source_units, target_units).get
167
+ solar_reflectance = surface_detail[:construction].to_LayeredConstruction.get.layers[0].to_OpaqueMaterial.get.solarReflectance.get
168
+ # @todo check with exterior air wall
169
+
170
+ # stop if didn't find values (0 or infinity)
171
+ next if target_r_value_ip[surface_detail[:surface_type]] == 0.0
172
+ next if target_r_value_ip[surface_detail[:surface_type]] == Float::INFINITY
173
+
174
+ # check r avlues
175
+ if r_value_ip < target_r_value_ip[surface_detail[:surface_type]] * (1.0 - min_pass_pct)
176
+ check_elems << OpenStudio::Attribute.new('flag', "R value of #{r_value_ip.round(2)} (#{target_units}) for #{surface_detail[:construction].name} in #{space_type.name} is more than #{min_pass_pct * 100} % below the expected value of #{target_r_value_ip[surface_detail[:surface_type]].round(2)} (#{target_units}) for #{display_standard}.")
177
+ elsif r_value_ip > target_r_value_ip[surface_detail[:surface_type]] * (1.0 + max_pass_pct)
178
+ check_elems << OpenStudio::Attribute.new('flag', "R value of #{r_value_ip.round(2)} (#{target_units}) for #{surface_detail[:construction].name} in #{space_type.name} is more than #{max_pass_pct * 100} % above the expected value of #{target_r_value_ip[surface_detail[:surface_type]].round(2)} (#{target_units}) for #{display_standard}.")
179
+ end
180
+
181
+ # check solar reflectance
182
+ if (solar_reflectance < target_reflectance[surface_detail[:surface_type]] * (1.0 - min_pass_pct)) && (target_standard != 'ICC IECC 2015')
183
+ check_elems << OpenStudio::Attribute.new('flag', "Solar Reflectance of #{(solar_reflectance * 100).round} % for #{surface_detail[:construction].name} in #{space_type.name} is more than #{min_pass_pct * 100} % below the expected value of #{(target_reflectance[surface_detail[:surface_type]] * 100).round} %.")
184
+ elsif (solar_reflectance > target_reflectance[surface_detail[:surface_type]] * (1.0 + max_pass_pct)) && (target_standard != 'ICC IECC 2015')
185
+ check_elems << OpenStudio::Attribute.new('flag', "Solar Reflectance of #{(solar_reflectance * 100).round} % for #{surface_detail[:construction].name} in #{space_type.name} is more than #{max_pass_pct * 100} % above the expected value of #{(target_reflectance[surface_detail[:surface_type]] * 100).round} %.")
186
+ end
187
+
188
+ else
189
+ check_elems << OpenStudio::Attribute.new('flag', "Can't calculate R value for #{surface_detail[:construction].name}.")
190
+ end
191
+ end
192
+
193
+ # loop through unique construction array combinations
194
+ sub_surface_details.uniq.each do |sub_surface_detail|
195
+ if sub_surface_detail[:surface_type] == 'FixedWindow' || sub_surface_detail[:surface_type] == 'OperableWindow' || sub_surface_detail[:surface_type] == 'Skylight'
196
+ # check for non opaque sub surfaces
197
+ source_units = 'W/m^2*K'
198
+ target_units = 'Btu/ft^2*h*R'
199
+ u_factor_si = std.construction_calculated_u_factor(sub_surface_detail[:construction].to_LayeredConstruction.get.to_Construction.get)
200
+ u_factor_ip = OpenStudio.convert(u_factor_si, source_units, target_units).get
201
+ shgc = std.construction_calculated_solar_heat_gain_coefficient(sub_surface_detail[:construction].to_LayeredConstruction.get.to_Construction.get)
202
+
203
+ # stop if didn't find values (0 or infinity)
204
+ next if target_u_value_ip[sub_surface_detail[:surface_type]] == 0.0
205
+ next if target_u_value_ip[sub_surface_detail[:surface_type]] == Float::INFINITY
206
+
207
+ # check u avlues
208
+ if u_factor_ip < target_u_value_ip[sub_surface_detail[:surface_type]] * (1.0 - min_pass_pct)
209
+ check_elems << OpenStudio::Attribute.new('flag', "U value of #{u_factor_ip.round(2)} (#{target_units}) for #{sub_surface_detail[:construction].name} in #{space_type.name} is more than #{min_pass_pct * 100} % below the expected value of #{target_u_value_ip[sub_surface_detail[:surface_type]].round(2)} (#{target_units}) for #{display_standard}.")
210
+ elsif u_factor_ip > target_u_value_ip[sub_surface_detail[:surface_type]] * (1.0 + max_pass_pct)
211
+ check_elems << OpenStudio::Attribute.new('flag', "U value of #{u_factor_ip.round(2)} (#{target_units}) for #{sub_surface_detail[:construction].name} in #{space_type.name} is more than #{max_pass_pct * 100} % above the expected value of #{target_u_value_ip[sub_surface_detail[:surface_type]].round(2)} (#{target_units}) for #{display_standard}.")
212
+ end
213
+
214
+ # check shgc
215
+ if shgc < target_shgc[sub_surface_detail[:surface_type]] * (1.0 - min_pass_pct)
216
+ check_elems << OpenStudio::Attribute.new('flag', "SHGC of #{shgc.round(2)} % for #{sub_surface_detail[:construction].name} in #{space_type.name} is more than #{min_pass_pct * 100} % below the expected value of #{target_shgc[sub_surface_detail[:surface_type]].round(2)} %.")
217
+ elsif shgc > target_shgc[sub_surface_detail[:surface_type]] * (1.0 + max_pass_pct)
218
+ check_elems << OpenStudio::Attribute.new('flag', "SHGC of #{shgc.round(2)} % for #{sub_surface_detail[:construction].name} in #{space_type.name} is more than #{max_pass_pct * 100} % above the expected value of #{target_shgc[sub_surface_detail[:surface_type]].round(2)} %.")
219
+ end
220
+
221
+ else
222
+ # check for opaque sub surfaces
223
+ if sub_surface_detail[:construction].thermalConductance.is_initialized
224
+
225
+ # don't use intended surface type of construction, look map based on surface type and boundary condition
226
+ boundary_condition = sub_surface_detail[:boundary_condition]
227
+ surface_type = sub_surface_detail[:surface_type]
228
+ intended_surface_type = ''
229
+ if boundary_condition.to_s == 'Outdoors'
230
+ # @todo add additional intended surface types
231
+ if surface_type.to_s == 'Door' then intended_surface_type = 'ExteriorDoor' end
232
+ else
233
+ # currently only used for surfaces with outdoor boundary condition
234
+ end
235
+ film_coefficients_r_value = std.film_coefficients_r_value(intended_surface_type, includes_int_film = true, includes_ext_film = true)
236
+
237
+ thermal_conductance = sub_surface_detail[:construction].thermalConductance.get
238
+ r_value_with_film = 1 / thermal_conductance + film_coefficients_r_value
239
+ source_units = 'm^2*K/W'
240
+ target_units = 'ft^2*h*R/Btu'
241
+ r_value_ip = OpenStudio.convert(r_value_with_film, source_units, target_units).get
242
+ solar_reflectance = sub_surface_detail[:construction].to_LayeredConstruction.get.layers[0].to_OpaqueMaterial.get.solarReflectance.get
243
+ # @todo check what happens with exterior air wall
244
+
245
+ # stop if didn't find values (0 or infinity)
246
+ next if target_r_value_ip[sub_surface_detail[:surface_type]] == 0.0
247
+ next if target_r_value_ip[sub_surface_detail[:surface_type]] == Float::INFINITY
248
+
249
+ # check r avlues
250
+ if r_value_ip < target_r_value_ip[sub_surface_detail[:surface_type]] * (1.0 - min_pass_pct)
251
+ check_elems << OpenStudio::Attribute.new('flag', "R value of #{r_value_ip.round(2)} (#{target_units}) for #{sub_surface_detail[:construction].name} in #{space_type.name} is more than #{min_pass_pct * 100} % below the expected value of #{target_r_value_ip[sub_surface_detail[:surface_type]].round(2)} (#{target_units}) for #{display_standard}.")
252
+ elsif r_value_ip > target_r_value_ip[sub_surface_detail[:surface_type]] * (1.0 + max_pass_pct)
253
+ check_elems << OpenStudio::Attribute.new('flag', "R value of #{r_value_ip.round(2)} (#{target_units}) for #{sub_surface_detail[:construction].name} in #{space_type.name} is more than #{max_pass_pct * 100} % above the expected value of #{target_r_value_ip[sub_surface_detail[:surface_type]].round(2)} (#{target_units}) for #{display_standard}.")
254
+ end
255
+
256
+ # check solar reflectance
257
+ if (solar_reflectance < target_reflectance[sub_surface_detail[:surface_type]] * (1.0 - min_pass_pct)) && (target_standard != 'ICC IECC 2015')
258
+ check_elems << OpenStudio::Attribute.new('flag', "Solar Reflectance of #{(solar_reflectance * 100).round} % for #{sub_surface_detail[:construction].name} in #{space_type.name} is more than #{min_pass_pct * 100} % below the expected value of #{(target_reflectance[sub_surface_detail[:surface_type]] * 100).round} %.")
259
+ elsif (solar_reflectance > target_reflectance[sub_surface_detail[:surface_type]] * (1.0 + max_pass_pct)) && (target_standard != 'ICC IECC 2015')
260
+ check_elems << OpenStudio::Attribute.new('flag', "Solar Reflectance of #{(solar_reflectance * 100).round} % for #{sub_surface_detail[:construction].name} in #{space_type.name} is more than #{max_pass_pct * 100} % above the expected value of #{(target_reflectance[sub_surface_detail[:surface_type]] * 100).round} %.")
261
+ end
262
+
263
+ else
264
+ check_elems << OpenStudio::Attribute.new('flag', "Can't calculate R value for #{sub_surface_detail[:construction].name}.")
265
+ end
266
+
267
+ end
268
+ end
269
+ end
270
+
271
+ # check spaces without space types against Nonresidential for this climate zone
272
+ @model.getSpaces.sort.each do |space|
273
+ unless space.spaceType.is_initialized
274
+
275
+ # make array of construction details for surfaces
276
+ surface_details = []
277
+ missing_surface_constructions = []
278
+ sub_surface_details = []
279
+ missing_sub_surface_constructions = []
280
+
281
+ space.surfaces.each do |surface|
282
+ next if surface.outsideBoundaryCondition != 'Outdoors'
283
+
284
+ if surface.construction.is_initialized
285
+ surface_details << { boundary_condition: surface.outsideBoundaryCondition, surface_type: surface.surfaceType, construction: surface.construction.get }
286
+ else
287
+ missing_surface_constructions << surface.name.get
288
+ end
289
+
290
+ # make array of construction details for sub_surfaces
291
+ surface.subSurfaces.each do |sub_surface|
292
+ if sub_surface.construction.is_initialized
293
+ sub_surface_details << { boundary_condition: sub_surface.outsideBoundaryCondition, surface_type: sub_surface.subSurfaceType, construction: sub_surface.construction.get }
294
+ else
295
+ missing_sub_surface_constructions << sub_surface.name.get
296
+ end
297
+ end
298
+ end
299
+
300
+ unless missing_surface_constructions.empty?
301
+ check_elems << OpenStudio::Attribute.new('flag', "#{missing_surface_constructions.size} surfaces are missing constructions in #{space_type.name}. Spaces and can't be checked.")
302
+ end
303
+
304
+ unless missing_sub_surface_constructions.empty?
305
+ check_elems << OpenStudio::Attribute.new('flag', "#{missing_sub_surface_constructions.size} sub surfaces are missing constructions in #{space_type.name}. Spaces and can't be checked.")
306
+ end
307
+
308
+ surface_details.uniq.each do |surface_detail|
309
+ if surface_detail[:construction].thermalConductance.is_initialized
310
+ # don't use intended surface type of construction, look map based on surface type and boundary condition
311
+ boundary_condition = surface_detail[:boundary_condition]
312
+ surface_type = surface_detail[:surface_type]
313
+ intended_surface_type = ''
314
+ if boundary_condition.to_s == 'Outdoors'
315
+ case surface_type.to_s
316
+ when 'Wall'
317
+ intended_surface_type = 'ExteriorWall'
318
+ standards_construction_type = 'SteelFramed'
319
+ when 'RoofCeiling'
320
+ intended_surface_type = 'ExteriorRoof'
321
+ standards_construction_type = 'IEAD'
322
+ when 'Floor'
323
+ intended_surface_type = 'ExteriorFloor'
324
+ standards_construction_type = 'Mass'
325
+ end
326
+ # currently only used for surfaces with outdoor boundary condition
327
+ end
328
+ film_coefficients_r_value = std.film_coefficients_r_value(intended_surface_type, includes_int_film = true, includes_ext_film = true)
329
+ thermal_conductance = surface_detail[:construction].thermalConductance.get
330
+ r_value_with_film = 1 / thermal_conductance + film_coefficients_r_value
331
+ source_units = 'm^2*K/W'
332
+ target_units = 'ft^2*h*R/Btu'
333
+ r_value_ip = OpenStudio.convert(r_value_with_film, source_units, target_units).get
334
+ solar_reflectance = surface_detail[:construction].to_LayeredConstruction.get.layers[0].to_OpaqueMaterial.get.solarReflectance.get
335
+ # @todo check what happens with exterior air wall
336
+
337
+ # calculate target_r_value_ip
338
+ target_reflectance = nil
339
+ data = std.model_get_construction_properties(@model, intended_surface_type, standards_construction_type)
340
+
341
+ if data.nil?
342
+ check_elems << OpenStudio::Attribute.new('flag', "Didn't find construction for #{standards_construction_type} #{intended_surface_type} for #{space.name}.")
343
+ next
344
+ elsif intended_surface_type.include? 'ExteriorWall' || 'ExteriorFloor' || 'ExteriorDoor'
345
+ assembly_maximum_u_value = data['assembly_maximum_u_value']
346
+ target_reflectance = 0.30
347
+ elsif intended_surface_type.include? 'ExteriorRoof'
348
+ assembly_maximum_u_value = data['assembly_maximum_u_value']
349
+ target_reflectance = 0.55
350
+ else
351
+ assembly_maximum_u_value = data['assembly_maximum_u_value']
352
+ assembly_maximum_solar_heat_gain_coefficient = data['assembly_maximum_solar_heat_gain_coefficient']
353
+ end
354
+ assembly_maximum_r_value_ip = 1 / assembly_maximum_u_value
355
+
356
+ # stop if didn't find values (0 or infinity)
357
+ next if assembly_maximum_r_value_ip == 0.0
358
+ next if assembly_maximum_r_value_ip == Float::INFINITY
359
+
360
+ # check r avlues
361
+ if r_value_ip < assembly_maximum_r_value_ip * (1.0 - min_pass_pct)
362
+ check_elems << OpenStudio::Attribute.new('flag', "R value of #{r_value_ip.round(2)} (#{target_units}) for #{surface_detail[:construction].name} in #{space.name} is more than #{min_pass_pct * 100} % below the expected value of #{assembly_maximum_r_value_ip.round(2)} (#{target_units}) for #{display_standard}.")
363
+ elsif r_value_ip > assembly_maximum_r_value_ip * (1.0 + max_pass_pct)
364
+ check_elems << OpenStudio::Attribute.new('flag', "R value of #{r_value_ip.round(2)} (#{target_units}) for #{surface_detail[:construction].name} in #{space.name} is more than #{max_pass_pct * 100} % above the expected value of #{assembly_maximum_r_value_ip.round(2)} (#{target_units}) for #{display_standard}.")
365
+ end
366
+
367
+ # check solar reflectance
368
+ if (solar_reflectance < target_reflectance * (1.0 - min_pass_pct)) && (target_standard != 'ICC IECC 2015')
369
+ check_elems << OpenStudio::Attribute.new('flag', "Solar Reflectance of #{(solar_reflectance * 100).round} % for #{surface_detail[:construction].name} in #{space.name} is more than #{min_pass_pct * 100} % below the expected value of #{(target_reflectance * 100).round} %.")
370
+ elsif (solar_reflectance > target_reflectance * (1.0 + max_pass_pct)) && (target_standard != 'ICC IECC 2015')
371
+ check_elems << OpenStudio::Attribute.new('flag', "Solar Reflectance of #{(solar_reflectance * 100).round} % for #{surface_detail[:construction].name} in #{space.name} is more than #{max_pass_pct * 100} % above the expected value of #{(target_reflectance * 100).round} %.")
372
+ end
373
+ else
374
+ check_elems << OpenStudio::Attribute.new('flag', "Can't calculate R value for #{surface_detail[:construction].name}.")
375
+ end
376
+ end
377
+
378
+ sub_surface_details.uniq.each do |sub_surface_detail|
379
+ # @todo update this so it works for doors and windows
380
+ check_elems << OpenStudio::Attribute.new('flag', "Not setup to check sub-surfaces of spaces without space types. Can't check properties for #{sub_surface_detail[:construction].name}.")
381
+ end
382
+
383
+ end
384
+ end
385
+ rescue StandardError => e
386
+ # brief description of ruby error
387
+ check_elems << OpenStudio::Attribute.new('flag', "Error prevented QAQC check from running (#{e}).")
388
+
389
+ # backtrace of ruby error for diagnostic use
390
+ if @error_backtrace then check_elems << OpenStudio::Attribute.new('flag', e.backtrace.join("\n").to_s) end
391
+ end
392
+
393
+ # add check_elms to new attribute
394
+ check_elem = OpenStudio::Attribute.new('check', check_elems)
395
+
396
+ return check_elem
397
+ end
398
+ end
399
+ end
@@ -0,0 +1,213 @@
1
+ # Module to apply QAQC checks to a model
2
+ module OpenstudioStandards
3
+ module QAQC
4
+ # @!group Energy Use Intensity (EUI)
5
+
6
+ # Checks EUI for reasonableness
7
+ #
8
+ # @param category [String] category to bin this check into
9
+ # @param target_standard [String] standard template, e.g. '90.1-2013'
10
+ # @param min_pass_pct [Double] threshold for throwing an error for percent difference
11
+ # @param max_pass_pct [Double] threshold for throwing an error for percent difference
12
+ # @param name_only [Boolean] If true, only return the name of this check
13
+ # @return [OpenStudio::Attribute] OpenStudio Attribute object containing check results
14
+ def self.check_eui(category, target_standard, min_pass_pct: 0.1, max_pass_pct: 0.1, name_only: false)
15
+ # summary of the check
16
+ check_elems = OpenStudio::AttributeVector.new
17
+ check_elems << OpenStudio::Attribute.new('name', 'EUI Reasonableness')
18
+ check_elems << OpenStudio::Attribute.new('category', category)
19
+ check_elems << OpenStudio::Attribute.new('description', "Check EUI for model against #{target_standard} DOE prototype buildings.")
20
+
21
+ # stop here if only name is requested this is used to populate display name for arguments
22
+ if name_only == true
23
+ results = []
24
+ check_elems.each do |elem|
25
+ results << elem.valueAsString
26
+ end
27
+ return results
28
+ end
29
+
30
+ std = Standard.build(target_standard)
31
+
32
+ begin
33
+ # total building area
34
+ query = 'SELECT Value FROM tabulardatawithstrings WHERE '
35
+ query << "ReportName='AnnualBuildingUtilityPerformanceSummary' and "
36
+ query << "ReportForString='Entire Facility' and "
37
+ query << "TableName='Building Area' and "
38
+ query << "RowName='Total Building Area' and "
39
+ query << "ColumnName='Area' and "
40
+ query << "Units='m2';"
41
+ query_results = @sql.execAndReturnFirstDouble(query)
42
+ if query_results.empty?
43
+ check_elems << OpenStudio::Attribute.new('flag', "Can't calculate EUI, SQL query for building area failed.")
44
+ return OpenStudio::Attribute.new('check', check_elems)
45
+ else
46
+ energy_plus_area = query_results.get
47
+ end
48
+
49
+ # temp code to check OS vs. E+ area
50
+ open_studio_area = @model.getBuilding.floorArea
51
+ if (energy_plus_area - open_studio_area).abs >= 0.1
52
+ check_elems << OpenStudio::Attribute.new('flag', "EnergyPlus reported area is #{energy_plus_area} (m^2). OpenStudio reported area is #{@model.getBuilding.floorArea} (m^2).")
53
+ end
54
+
55
+ # EUI
56
+ source_units = 'GJ/m^2'
57
+ target_units = 'kBtu/ft^2'
58
+ if energy_plus_area > 0.0 # don't calculate EUI if building doesn't have any area
59
+ # todo - netSiteEnergy deducts for renewable. May want to update this to show gross consumption vs. net consumption
60
+ eui = @sql.netSiteEnergy.get / energy_plus_area
61
+ else
62
+ check_elems << OpenStudio::Attribute.new('flag', "Can't calculate model EUI, building doesn't have any floor area.")
63
+ return OpenStudio::Attribute.new('check', check_elems)
64
+ end
65
+
66
+ # test using new method
67
+ std = Standard.build(target_standard)
68
+ target_eui = std.model_find_target_eui(@model)
69
+
70
+ # check model vs. target for user specified tolerance.
71
+ if !target_eui.nil?
72
+ eui_ip_neat = OpenStudio.toNeatString(OpenStudio.convert(eui, source_units, target_units).get, 1, true)
73
+ target_eui_ip_neat = OpenStudio.toNeatString(OpenStudio.convert(target_eui, source_units, target_units).get, 1, true)
74
+ if eui < target_eui * (1.0 - min_pass_pct)
75
+ check_elems << OpenStudio::Attribute.new('flag', "Model EUI of #{eui_ip_neat} (#{target_units}) is less than #{min_pass_pct * 100} % below the expected EUI of #{target_eui_ip_neat} (#{target_units}) for #{target_standard}.")
76
+ elsif eui > target_eui * (1.0 + max_pass_pct)
77
+ check_elems << OpenStudio::Attribute.new('flag', "Model EUI of #{eui_ip_neat} (#{target_units}) is more than #{max_pass_pct * 100} % above the expected EUI of #{target_eui_ip_neat} (#{target_units}) for #{target_standard}.")
78
+ end
79
+ else
80
+ check_elems << OpenStudio::Attribute.new('flag', "Can't calculate target EUI. Make sure model has expected climate zone and building type.")
81
+ end
82
+ rescue StandardError => e
83
+ # brief description of ruby error
84
+ check_elems << OpenStudio::Attribute.new('flag', "Error prevented QAQC check from running (#{e}).")
85
+
86
+ # backtrace of ruby error for diagnostic use
87
+ if @error_backtrace then check_elems << OpenStudio::Attribute.new('flag', e.backtrace.join("\n").to_s) end
88
+ end
89
+
90
+ # add check_elms to new attribute
91
+ check_elem = OpenStudio::Attribute.new('check', check_elems)
92
+
93
+ return check_elem
94
+ end
95
+
96
+ # Checks end use EUIs for reasonableness
97
+ #
98
+ # @param category [String] category to bin this check into
99
+ # @param target_standard [String] standard template, e.g. '90.1-2013'
100
+ # @param min_pass_pct [Double] threshold for throwing an error for percent difference
101
+ # @param max_pass_pct [Double] threshold for throwing an error for percent difference
102
+ # @param name_only [Boolean] If true, only return the name of this check
103
+ # @return [OpenStudio::Attribute] OpenStudio Attribute object containing check results
104
+ def self.check_eui_by_end_use(category, target_standard, min_pass_pct: 0.2, max_pass_pct: 0.2, name_only: false)
105
+ # summary of the check
106
+ check_elems = OpenStudio::AttributeVector.new
107
+ check_elems << OpenStudio::Attribute.new('name', 'End Use by Category')
108
+ check_elems << OpenStudio::Attribute.new('category', category)
109
+ check_elems << OpenStudio::Attribute.new('description', "Check end use by category against #{target_standard} DOE prototype buildings.")
110
+
111
+ # stop here if only name is requested this is used to populate display name for arguments
112
+ if name_only == true
113
+ results = []
114
+ check_elems.each do |elem|
115
+ results << elem.valueAsString
116
+ end
117
+ return results
118
+ end
119
+
120
+ std = Standard.build(target_standard)
121
+
122
+ begin
123
+ # total building area
124
+ query = 'SELECT Value FROM tabulardatawithstrings WHERE '
125
+ query << "ReportName='AnnualBuildingUtilityPerformanceSummary' and "
126
+ query << "ReportForString='Entire Facility' and "
127
+ query << "TableName='Building Area' and "
128
+ query << "RowName='Total Building Area' and "
129
+ query << "ColumnName='Area' and "
130
+ query << "Units='m2';"
131
+ query_results = @sql.execAndReturnFirstDouble(query)
132
+ if query_results.empty?
133
+ check_elems << OpenStudio::Attribute.new('flag', "Can't calculate EUI, SQL query for building area failed.")
134
+ return OpenStudio::Attribute.new('check', check_elems)
135
+ else
136
+ energy_plus_area = query_results.get
137
+ end
138
+
139
+ # temp code to check OS vs. E+ area
140
+ open_studio_area = @model.getBuilding.floorArea
141
+ if (energy_plus_area - open_studio_area).abs >= 0.1
142
+ check_elems << OpenStudio::Attribute.new('flag', "EnergyPlus reported area is #{energy_plus_area} (m^2). OpenStudio reported area is #{@model.getBuilding.floorArea} (m^2).")
143
+ end
144
+
145
+ # loop through end uses and gather consumption, normalized by floor area
146
+ actual_eui_by_end_use = {}
147
+ OpenStudio::EndUseCategoryType.getValues.each do |end_use|
148
+ # get end uses
149
+ end_use = OpenStudio::EndUseCategoryType.new(end_use).valueDescription
150
+ query_elec = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='AnnualBuildingUtilityPerformanceSummary' and TableName='End Uses' and RowName= '#{end_use}' and ColumnName= 'Electricity'"
151
+ query_gas = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='AnnualBuildingUtilityPerformanceSummary' and TableName='End Uses' and RowName= '#{end_use}' and ColumnName= 'Natural Gas'"
152
+ query_add = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='AnnualBuildingUtilityPerformanceSummary' and TableName='End Uses' and RowName= '#{end_use}' and ColumnName= 'Additional Fuel'"
153
+ query_dc = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='AnnualBuildingUtilityPerformanceSummary' and TableName='End Uses' and RowName= '#{end_use}' and ColumnName= 'District Cooling'"
154
+ query_dh = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='AnnualBuildingUtilityPerformanceSummary' and TableName='End Uses' and RowName= '#{end_use}' and ColumnName= 'District Heating'"
155
+ results_elec = @sql.execAndReturnFirstDouble(query_elec).get
156
+ results_gas = @sql.execAndReturnFirstDouble(query_gas).get
157
+ results_add = @sql.execAndReturnFirstDouble(query_add).get
158
+ results_dc = @sql.execAndReturnFirstDouble(query_dc).get
159
+ results_dh = @sql.execAndReturnFirstDouble(query_dh).get
160
+ total_end_use = results_elec + results_gas + results_add + results_dc + results_dh
161
+
162
+ # populate hash for actual end use normalized by area
163
+ actual_eui_by_end_use[end_use] = total_end_use / energy_plus_area
164
+ end
165
+
166
+ # gather target end uses for given standard as hash
167
+ std = Standard.build(target_standard)
168
+ target_eui_by_end_use = std.model_find_target_eui_by_end_use(@model)
169
+
170
+ # units for flag display text and unit conversion
171
+ source_units = 'GJ/m^2'
172
+ target_units = 'kBtu/ft^2'
173
+
174
+ # check acutal vs. target against tolerance
175
+ if !target_eui_by_end_use.nil?
176
+ actual_eui_by_end_use.each do |end_use, value|
177
+ # this should have value of 0 in model. This page change in the future. It doesn't exist in target lookup
178
+ next if end_use == 'Exterior Equipment'
179
+
180
+ # perform check and issue flags as needed
181
+ target_value = target_eui_by_end_use[end_use]
182
+ eui_ip_neat = OpenStudio.toNeatString(OpenStudio.convert(value, source_units, target_units).get, 5, true)
183
+ target_eui_ip_neat = OpenStudio.toNeatString(OpenStudio.convert(target_value, source_units, target_units).get, 1, true)
184
+
185
+ # add in use case specific logic to skip checks when near 0 actual and target
186
+ skip = false
187
+ if (end_use == 'Heat Recovery') && (value < 0.05) && (target_value < 0.05) then skip = true end
188
+ if (end_use == 'Pumps') && (value < 0.05) && (target_value < 0.05) then skip = true end
189
+
190
+ if (value < target_value * (1.0 - min_pass_pct)) && !skip
191
+ check_elems << OpenStudio::Attribute.new('flag', "#{end_use} EUI of #{eui_ip_neat} (#{target_units}) is less than #{min_pass_pct * 100} % below the expected #{end_use} EUI of #{target_eui_ip_neat} (#{target_units}) for #{target_standard}.")
192
+ elsif (value > target_value * (1.0 + max_pass_pct)) && !skip
193
+ check_elems << OpenStudio::Attribute.new('flag', "#{end_use} EUI of #{eui_ip_neat} (#{target_units}) is more than #{max_pass_pct * 100} % above the expected #{end_use} EUI of #{target_eui_ip_neat} (#{target_units}) for #{target_standard}.")
194
+ end
195
+ end
196
+ else
197
+ check_elems << OpenStudio::Attribute.new('flag', "Can't calculate target end use EUIs. Make sure model has expected climate zone and building type.")
198
+ end
199
+ rescue StandardError => e
200
+ # brief description of ruby error
201
+ check_elems << OpenStudio::Attribute.new('flag', "Error prevented QAQC check from running (#{e}).")
202
+
203
+ # backtrace of ruby error for diagnostic use
204
+ if @error_backtrace then check_elems << OpenStudio::Attribute.new('flag', e.backtrace.join("\n").to_s) end
205
+ end
206
+
207
+ # add check_elms to new attribute
208
+ check_elem = OpenStudio::Attribute.new('check', check_elems)
209
+
210
+ return check_elem
211
+ end
212
+ end
213
+ end