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,568 @@
1
+ # Module to apply QAQC checks to a model
2
+ module OpenstudioStandards
3
+ module QAQC
4
+ # @!group Internal Loads
5
+
6
+ # Check the internal loads 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
+ def self.check_internal_loads(category, target_standard, min_pass_pct: 0.2, max_pass_pct: 0.2, name_only: false)
15
+ # summary of the check
16
+ check_elems = OpenStudio::AttributeVector.new
17
+ check_elems << OpenStudio::Attribute.new('name', 'Internal Loads')
18
+ check_elems << OpenStudio::Attribute.new('category', category)
19
+ if target_standard == 'ICC IECC 2015'
20
+ check_elems << OpenStudio::Attribute.new('description', 'Check internal loads against Table R405.5.2(1) in ICC IECC 2015 Residential Provisions.')
21
+ else
22
+ if target_standard.include?('90.1')
23
+ display_standard = "ASHRAE #{target_standard}"
24
+ else
25
+ display_standard = target_standard
26
+ end
27
+ check_elems << OpenStudio::Attribute.new('description', "Check LPD, ventilation rates, occupant density, plug loads, and equipment loads against #{display_standard} and DOE Prototype buildings.")
28
+ end
29
+
30
+ # stop here if only name is requested this is used to populate display name for arguments
31
+ if name_only == true
32
+ results = []
33
+ check_elems.each do |elem|
34
+ results << elem.valueAsString
35
+ end
36
+ return results
37
+ end
38
+
39
+ std = Standard.build(target_standard)
40
+
41
+ begin
42
+ if target_standard == 'ICC IECC 2015'
43
+
44
+ num_people = 0.0
45
+ @model.getSpaceTypes.each do |space_type|
46
+ next if !space_type.standardsSpaceType.is_initialized
47
+ next if space_type.standardsSpaceType.get != 'Apartment' # currently only supports midrise apt space type
48
+
49
+ space_type_floor_area = space_type.floorArea
50
+ space_type_num_people = space_type.getNumberOfPeople(space_type_floor_area)
51
+ num_people += space_type_num_people
52
+ end
53
+
54
+ # lookup iecc internal loads for the building
55
+ bedrooms_per_unit = 2.0 # assumption
56
+ num_units = num_people / 2.5 # Avg 2.5 units per person.
57
+ target_loads_hash = std.model_find_icc_iecc_2015_internal_loads(@model, num_units, bedrooms_per_unit)
58
+
59
+ # get model internal gains for lights, elec equipment, and gas equipment
60
+ model_internal_gains_si = 0.0
61
+ query_eleint_lights = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='AnnualBuildingUtilityPerformanceSummary' and TableName='End Uses' and RowName= 'Interior Lighting' and ColumnName= 'Electricity'"
62
+ query_elec_equip = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='AnnualBuildingUtilityPerformanceSummary' and TableName='End Uses' and RowName= 'Interior Equipment' and ColumnName= 'Electricity'"
63
+ query_gas_equip = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='AnnualBuildingUtilityPerformanceSummary' and TableName='End Uses' and RowName= 'Interior Equipment' and ColumnName= 'Natural Gas'"
64
+ model_internal_gains_si += results_elec = @sql.execAndReturnFirstDouble(query_eleint_lights).get
65
+ model_internal_gains_si += results_elec = @sql.execAndReturnFirstDouble(query_elec_equip).get
66
+ model_internal_gains_si += results_elec = @sql.execAndReturnFirstDouble(query_gas_equip).get
67
+ model_internal_gains_si_kbtu_per_day = OpenStudio.convert(model_internal_gains_si, 'GJ', 'kBtu').get / 365.0 # assumes annual run
68
+
69
+ # get target internal loads
70
+ target_igain_btu_per_day = target_loads_hash['igain_btu_per_day']
71
+ target_igain_kbtu_per_day = OpenStudio.convert(target_igain_btu_per_day, 'Btu', 'kBtu').get
72
+
73
+ # check internal loads
74
+ if model_internal_gains_si_kbtu_per_day < target_igain_kbtu_per_day * (1.0 - min_pass_pct)
75
+ check_elems << OpenStudio::Attribute.new('flag', "The model average of #{OpenStudio.toNeatString(model_internal_gains_si_kbtu_per_day, 2, true)} (kBtu/day) is more than #{min_pass_pct * 100} % below the expected value of #{OpenStudio.toNeatString(target_igain_kbtu_per_day, 2, true)} (kBtu/day) for #{target_standard}.")
76
+ elsif model_internal_gains_si_kbtu_per_day > target_igain_kbtu_per_day * (1.0 + max_pass_pct)
77
+ check_elems << OpenStudio::Attribute.new('flag', "The model average of #{OpenStudio.toNeatString(model_internal_gains_si_kbtu_per_day, 2, true)} (kBtu/day) is more than #{max_pass_pct * 100} % above the expected value of #{OpenStudio.toNeatString(target_igain_kbtu_per_day, 2, true)} k(Btu/day) for #{target_standard}.")
78
+ end
79
+
80
+ # get target mech vent
81
+ target_mech_vent_cfm = target_loads_hash['mech_vent_cfm']
82
+
83
+ # get model mech vent
84
+ model_mech_vent_si = 0
85
+ @model.getSpaceTypes.each do |space_type|
86
+ next if space_type.floorArea <= 0
87
+
88
+ # get necessary space type information
89
+ floor_area = space_type.floorArea
90
+ num_people = space_type.getNumberOfPeople(floor_area)
91
+
92
+ # get volume for space type for use with ventilation and infiltration
93
+ space_type_volume = 0.0
94
+ space_type_exterior_area = 0.0
95
+ space_type_exterior_wall_area = 0.0
96
+ space_type.spaces.each do |space|
97
+ space_type_volume += space.volume * space.multiplier
98
+ space_type_exterior_area = space.exteriorArea * space.multiplier
99
+ space_type_exterior_wall_area = space.exteriorWallArea * space.multiplier
100
+ end
101
+
102
+ # get design spec OA object
103
+ if space_type.designSpecificationOutdoorAir.is_initialized
104
+ oa = space_type.designSpecificationOutdoorAir.get
105
+ oa_method = oa.outdoorAirMethod
106
+ oa_per_person = oa.outdoorAirFlowperPerson * num_people
107
+ oa_ach = oa.outdoorAirFlowAirChangesperHour * space_type_volume
108
+ oa_per_area = oa.outdoorAirFlowperFloorArea * floor_area
109
+ oa_flow_rate = oa.outdoorAirFlowRate
110
+ oa_space_type_total = oa_per_person + oa_ach + oa_per_area + oa_flow_rate
111
+
112
+ value_count = 0
113
+ if oa_per_person > 0 then value_count += 1 end
114
+ if oa_ach > 0 then value_count += 1 end
115
+ if oa_per_area > 0 then value_count += 1 end
116
+ if oa_flow_rate > 0 then value_count += 1 end
117
+ if (oa_method != 'Sum') && (value_count > 1)
118
+ check_elems << OpenStudio::Attribute.new('flag', "Outdoor Air Method for #{space_type.name} was #{oa_method}. Expected value was Sum.")
119
+ end
120
+ else
121
+ oa_space_type_total = 0.0
122
+ end
123
+ # add to building total oa
124
+ model_mech_vent_si += oa_space_type_total
125
+ end
126
+
127
+ # check oa
128
+ model_mech_vent_cfm = OpenStudio.convert(model_mech_vent_si, 'm^3/s', 'cfm').get
129
+ if model_mech_vent_cfm < target_mech_vent_cfm * (1.0 - min_pass_pct)
130
+ check_elems << OpenStudio::Attribute.new('flag', "The model mechanical ventilation of #{OpenStudio.toNeatString(model_mech_vent_cfm, 2, true)} cfm is more than #{min_pass_pct * 100} % below the expected value of #{OpenStudio.toNeatString(target_mech_vent_cfm, 2, true)} cfm for #{target_standard}.")
131
+ elsif model_mech_vent_cfm > target_mech_vent_cfm * (1.0 + max_pass_pct)
132
+ check_elems << OpenStudio::Attribute.new('flag', "The model mechanical ventilation of #{OpenStudio.toNeatString(model_mech_vent_cfm, 2, true)} cfm is more than #{max_pass_pct * 100} % above the expected value of #{OpenStudio.toNeatString(target_mech_vent_cfm, 2, true)} cfm for #{target_standard}.")
133
+ end
134
+
135
+ else
136
+
137
+ # loop through all space types used in the model
138
+ @model.getSpaceTypes.sort.each do |space_type|
139
+ next if space_type.floorArea <= 0
140
+ next if space_type.name.to_s == 'Plenum'
141
+
142
+ # get necessary space type information
143
+ floor_area = space_type.floorArea
144
+ num_people = space_type.getNumberOfPeople(floor_area)
145
+
146
+ # load in standard info for this space type
147
+ data = std.space_type_get_standards_data(space_type)
148
+
149
+ if data.nil? || data.empty?
150
+
151
+ # skip if all spaces using this space type are plenums
152
+ all_spaces_plenums = true
153
+ space_type.spaces.each do |space|
154
+ unless std.space_plenum?(space)
155
+ all_spaces_plenums = false
156
+ next
157
+ end
158
+ end
159
+
160
+ unless all_spaces_plenums
161
+ check_elems << OpenStudio::Attribute.new('flag', "Unexpected standards type for #{space_type.name}, can't validate internal loads.")
162
+ end
163
+
164
+ next
165
+ end
166
+
167
+ # check lpd for space type
168
+ model_lights_si = space_type.getLightingPowerPerFloorArea(floor_area, num_people)
169
+ data['lighting_per_area'].nil? ? (target_lights_ip = 0.0) : (target_lights_ip = data['lighting_per_area'])
170
+ source_units = 'W/m^2'
171
+ target_units = 'W/ft^2'
172
+ load_type = 'Lighting Power Density'
173
+ model_ip = OpenStudio.convert(model_lights_si, source_units, target_units).get
174
+ target_ip = target_lights_ip.to_f
175
+ model_ip_neat = OpenStudio.toNeatString(model_ip, 2, true)
176
+ target_ip_neat = OpenStudio.toNeatString(target_ip, 2, true)
177
+ if model_ip < target_ip * (1.0 - min_pass_pct)
178
+ check_elems << OpenStudio::Attribute.new('flag', "#{load_type} of #{model_ip_neat} (#{target_units}) for #{space_type.name} is more than #{min_pass_pct * 100} % below the expected value of #{target_ip_neat} (#{target_units}) for #{display_standard}.")
179
+ elsif model_ip > target_ip * (1.0 + max_pass_pct)
180
+ check_elems << OpenStudio::Attribute.new('flag', "#{load_type} of #{model_ip_neat} (#{target_units}) for #{space_type.name} is more than #{max_pass_pct * 100} % above the expected value of #{target_ip_neat} (#{target_units}) for #{display_standard}.")
181
+ end
182
+
183
+ # check electric equipment
184
+ model_elec_si = space_type.getElectricEquipmentPowerPerFloorArea(floor_area, num_people)
185
+ data['electric_equipment_per_area'].nil? ? (target_elec_ip = 0.0) : (target_elec_ip = data['electric_equipment_per_area'])
186
+ source_units = 'W/m^2'
187
+ target_units = 'W/ft^2'
188
+ load_type = 'Electric Power Density'
189
+ model_ip = OpenStudio.convert(model_elec_si, source_units, target_units).get
190
+ target_ip = target_elec_ip.to_f
191
+ model_ip_neat = OpenStudio.toNeatString(model_ip, 2, true)
192
+ target_ip_neat = OpenStudio.toNeatString(target_ip, 2, true)
193
+ if model_ip < target_ip * (1.0 - min_pass_pct)
194
+ check_elems << OpenStudio::Attribute.new('flag', "#{load_type} of #{model_ip_neat} (#{target_units}) for #{space_type.name} is more than #{min_pass_pct * 100} % below the expected value of #{target_ip_neat} (#{target_units}) for #{display_standard}.")
195
+ elsif model_ip > target_ip * (1.0 + max_pass_pct)
196
+ check_elems << OpenStudio::Attribute.new('flag', "#{load_type} of #{model_ip_neat} (#{target_units}) for #{space_type.name} is more than #{max_pass_pct * 100} % above the expected value of #{target_ip_neat} (#{target_units}) for #{display_standard}.")
197
+ end
198
+
199
+ # check gas equipment
200
+ model_gas_si = space_type.getGasEquipmentPowerPerFloorArea(floor_area, num_people)
201
+ data['gas_equipment_per_area'].nil? ? (target_gas_ip = 0.0) : (target_gas_ip = data['gas_equipment_per_area'])
202
+ source_units = 'W/m^2'
203
+ target_units = 'Btu/hr*ft^2'
204
+ load_type = 'Gas Power Density'
205
+ model_ip = OpenStudio.convert(model_gas_si, source_units, target_units).get
206
+ target_ip = target_gas_ip.to_f
207
+ model_ip_neat = OpenStudio.toNeatString(model_ip, 2, true)
208
+ target_ip_neat = OpenStudio.toNeatString(target_ip, 2, true)
209
+ if model_ip < target_ip * (1.0 - min_pass_pct)
210
+ check_elems << OpenStudio::Attribute.new('flag', "#{load_type} of #{model_ip_neat} (#{target_units}) for #{space_type.name} is more than #{min_pass_pct * 100} % below the expected value of #{target_ip_neat} (#{target_units}) for #{display_standard}.")
211
+ elsif model_ip > target_ip * (1.0 + max_pass_pct)
212
+ check_elems << OpenStudio::Attribute.new('flag', "#{load_type} of #{model_ip_neat} (#{target_units}) for #{space_type.name} is more than #{max_pass_pct * 100} % above the expected value of #{target_ip_neat} (#{target_units}) for #{display_standard}.")
213
+ end
214
+
215
+ # check people
216
+ model_occ_si = space_type.getPeoplePerFloorArea(floor_area)
217
+ data['occupancy_per_area'].nil? ? (target_occ_ip = 0.0) : (target_occ_ip = data['occupancy_per_area'])
218
+ source_units = '1/m^2' # people/m^2
219
+ target_units = '1/ft^2' # people per ft^2 (can't add *1000) to the bottom, need to do later
220
+ load_type = 'Occupancy per Area'
221
+ model_ip = OpenStudio.convert(model_occ_si, source_units, target_units).get * 1000.0
222
+ target_ip = target_occ_ip.to_f
223
+ model_ip_neat = OpenStudio.toNeatString(model_ip, 2, true)
224
+ target_ip_neat = OpenStudio.toNeatString(target_ip, 2, true)
225
+ # for people need to update target units just for display. Can't be used for converstion.
226
+ target_units = 'People/1000 ft^2'
227
+ if model_ip < target_ip * (1.0 - min_pass_pct)
228
+ check_elems << OpenStudio::Attribute.new('flag', "#{load_type} of #{model_ip_neat} (#{target_units}) for #{space_type.name} is more than #{min_pass_pct * 100} % below the expected value of #{target_ip_neat} (#{target_units}) for #{display_standard}.")
229
+ elsif model_ip > target_ip * (1.0 + max_pass_pct)
230
+ check_elems << OpenStudio::Attribute.new('flag', "#{load_type} of #{model_ip_neat} (#{target_units}) for #{space_type.name} is more than #{max_pass_pct * 100} % above the expected value of #{target_ip_neat} (#{target_units}) for #{display_standard}.")
231
+ end
232
+
233
+ # get volume for space type for use with ventilation and infiltration
234
+ space_type_volume = 0.0
235
+ space_type_exterior_area = 0.0
236
+ space_type_exterior_wall_area = 0.0
237
+ space_type.spaces.each do |space|
238
+ space_type_volume += space.volume * space.multiplier
239
+ space_type_exterior_area = space.exteriorArea * space.multiplier
240
+ space_type_exterior_wall_area = space.exteriorWallArea * space.multiplier
241
+ end
242
+
243
+ # get design spec OA object
244
+ if space_type.designSpecificationOutdoorAir.is_initialized
245
+ oa = space_type.designSpecificationOutdoorAir.get
246
+ oa_method = oa.outdoorAirMethod
247
+ oa_per_person = oa.outdoorAirFlowperPerson
248
+ oa_ach = oa.outdoorAirFlowAirChangesperHour * space_type_volume
249
+ oa_per_area = oa.outdoorAirFlowperFloorArea * floor_area
250
+ oa_flow_rate = oa.outdoorAirFlowRate
251
+ oa_total = oa_ach + oa_per_area + oa_flow_rate
252
+
253
+ value_count = 0
254
+ if oa_per_person > 0 then value_count += 1 end
255
+ if oa_ach > 0 then value_count += 1 end
256
+ if oa_per_area > 0 then value_count += 1 end
257
+ if oa_flow_rate > 0 then value_count += 1 end
258
+ if (oa_method != 'Sum') && (value_count > 1)
259
+ check_elems << OpenStudio::Attribute.new('flag', "Outdoor Air Method for #{space_type.name} was #{oa_method}. Expected value was Sum.")
260
+ end
261
+ else
262
+ oa_per_person = 0.0
263
+ end
264
+
265
+ # get target values for OA
266
+ target_oa_per_person_ip = data['ventilation_per_person'].to_f # ft^3/min*person
267
+ target_oa_ach_ip = data['ventilation_air_changes'].to_f # ach
268
+ target_oa_per_area_ip = data['ventilation_per_area'].to_f # ft^3/min*ft^2
269
+ if target_oa_per_person_ip.nil?
270
+ target_oa_per_person_si = 0.0
271
+ else
272
+ target_oa_per_person_si = OpenStudio.convert(target_oa_per_person_ip, 'cfm', 'm^3/s').get
273
+ end
274
+ if target_oa_ach_ip.nil?
275
+ target_oa_ach_si = 0.0
276
+ else
277
+ target_oa_ach_si = target_oa_ach_ip * space_type_volume
278
+ end
279
+ if target_oa_per_area_ip.nil?
280
+ target_oa_per_area_si = 0.0
281
+ else
282
+ target_oa_per_area_si = OpenStudio.convert(target_oa_per_area_ip, 'cfm/ft^2', 'm^3/s*m^2').get * floor_area
283
+ end
284
+ target_oa_total = target_oa_ach_si + target_oa_per_area_si
285
+
286
+ # check oa per person
287
+ source_units = 'm^3/s'
288
+ target_units = 'cfm'
289
+ load_type = 'Outdoor Air Per Person'
290
+ model_ip_neat = OpenStudio.toNeatString(OpenStudio.convert(oa_per_person, source_units, target_units).get, 2, true)
291
+ target_ip_neat = OpenStudio.toNeatString(target_oa_per_person_ip, 2, true)
292
+ if oa_per_person < target_oa_per_person_si * (1.0 - min_pass_pct)
293
+ check_elems << OpenStudio::Attribute.new('flag', "#{load_type} of #{model_ip_neat} (#{target_units}) for #{space_type.name} is more than #{min_pass_pct * 100} % below the expected value of #{target_ip_neat} (#{target_units}) for #{display_standard}.")
294
+ elsif oa_per_person > target_oa_per_person_si * (1.0 + max_pass_pct)
295
+ check_elems << OpenStudio::Attribute.new('flag', "#{load_type} of #{model_ip_neat} (#{target_units}) for #{space_type.name} is more than #{max_pass_pct * 100} % above the expected value of #{target_ip_neat} (#{target_units}) for #{display_standard}.")
296
+ end
297
+
298
+ # check other oa
299
+ source_units = 'm^3/s'
300
+ target_units = 'cfm'
301
+ load_type = 'Outdoor Air (Excluding per Person Value)'
302
+ model_ip_neat = OpenStudio.toNeatString(OpenStudio.convert(oa_total, source_units, target_units).get, 2, true)
303
+ target_ip_neat = OpenStudio.toNeatString(OpenStudio.convert(target_oa_total, source_units, target_units).get, 2, true)
304
+ if oa_total < target_oa_total * (1.0 - min_pass_pct)
305
+ check_elems << OpenStudio::Attribute.new('flag', "#{load_type} of #{model_ip_neat} (#{target_units}) for #{space_type.name} is more than #{min_pass_pct * 100} % below the expected value of #{target_ip_neat} (#{target_units}) for #{display_standard}.")
306
+ elsif oa_total > target_oa_total * (1.0 + max_pass_pct)
307
+ check_elems << OpenStudio::Attribute.new('flag', "#{load_type} of #{model_ip_neat} (#{target_units}) for #{space_type.name} is more than #{max_pass_pct * 100} % above the expected value of #{target_ip_neat} (#{target_units}) for #{display_standard}.")
308
+ end
309
+ end
310
+
311
+ # warn if there are spaces in model that don't use space type unless they appear to be plenums
312
+ @model.getSpaces.sort.each do |space|
313
+ next if std.space_plenum?(space)
314
+
315
+ if !space.spaceType.is_initialized
316
+ check_elems << OpenStudio::Attribute.new('flag', "#{space.name} doesn't have a space type assigned, can't validate internal loads.")
317
+ end
318
+ end
319
+
320
+ # @todo need to address internal loads where fuel is variable like cooking and laundry
321
+ # @todo For now we are not going to loop through spaces looking for loads beyond what comes from space type
322
+ # @todo space infiltration
323
+
324
+ end
325
+ rescue StandardError => e
326
+ # brief description of ruby error
327
+ check_elems << OpenStudio::Attribute.new('flag', "Error prevented QAQC check from running (#{e}).")
328
+
329
+ # backtrace of ruby error for diagnostic use
330
+ if @error_backtrace then check_elems << OpenStudio::Attribute.new('flag', e.backtrace.join("\n").to_s) end
331
+ end
332
+
333
+ # add check_elms to new attribute
334
+ check_elem = OpenStudio::Attribute.new('check', check_elems)
335
+
336
+ return check_elem
337
+ end
338
+
339
+ # Check the internal load schedules against template prototypes
340
+ #
341
+ # @param category [String] category to bin this check into
342
+ # @param target_standard [String] standard template, e.g. '90.1-2013'
343
+ # @param min_pass_pct [Double] threshold for throwing an error for percent difference
344
+ # @param max_pass_pct [Double] threshold for throwing an error for percent difference
345
+ # @param name_only [Boolean] If true, only return the name of this check
346
+ # @return [OpenStudio::Attribute] OpenStudio Attribute object containing check results
347
+ def self.check_internal_loads_schedules(category, target_standard, min_pass_pct: 0.2, max_pass_pct: 0.2, name_only: false)
348
+ # summary of the check
349
+ check_elems = OpenStudio::AttributeVector.new
350
+ check_elems << OpenStudio::Attribute.new('name', 'Schedules')
351
+ check_elems << OpenStudio::Attribute.new('category', category)
352
+ check_elems << OpenStudio::Attribute.new('description', 'Check schedules for lighting, ventilation, occupant density, plug loads, and equipment based on DOE reference building schedules in terms of full load hours per year.')
353
+
354
+ # stop here if only name is requested this is used to populate display name for arguments
355
+ if name_only == true
356
+ results = []
357
+ check_elems.each do |elem|
358
+ results << elem.valueAsString
359
+ end
360
+ return results
361
+ end
362
+
363
+ std = Standard.build(target_standard)
364
+
365
+ begin
366
+ # loop through all space types used in the model
367
+ @model.getSpaceTypes.each do |space_type|
368
+ next if space_type.floorArea <= 0
369
+
370
+ # load in standard info for this space type
371
+ data = std.space_type_get_standards_data(space_type)
372
+
373
+ if data.nil? || data.empty?
374
+
375
+ # skip if all spaces using this space type are plenums
376
+ all_spaces_plenums = true
377
+ space_type.spaces.each do |space|
378
+ unless std.space_plenum?(space)
379
+ all_spaces_plenums = false
380
+ break
381
+ end
382
+ end
383
+
384
+ unless all_spaces_plenums
385
+ check_elems << OpenStudio::Attribute.new('flag', "Unexpected standards type for #{space_type.name}, can't validate schedules.")
386
+ end
387
+
388
+ next
389
+ end
390
+
391
+ # temp model to hold schedules to check
392
+ model_temp = OpenStudio::Model::Model.new
393
+
394
+ # check lighting schedules
395
+ data['lighting_per_area'].nil? ? (target_ip = 0.0) : (target_ip = data['lighting_per_area'])
396
+ if target_ip.to_f > 0
397
+ schedule_target = std.model_add_schedule(model_temp, data['lighting_schedule'])
398
+ if !schedule_target
399
+ check_elems << OpenStudio::Attribute.new('flag', "Didn't find schedule named #{data['lighting_schedule']} in standards json.")
400
+ elsif !schedule_target.to_ScheduleRuleset.is_initialized
401
+ check_elems << OpenStudio::Attribute.new('flag', "Schedule named #{schedule_target.name} is a #{schedule_target.class}, not a ScheduleRuleset schedule.")
402
+ else
403
+ schedule_target = schedule_target.to_ScheduleRuleset.get
404
+ # loop through and test individual load instances
405
+ expected_hours = std.schedule_ruleset_annual_equivalent_full_load_hrs(schedule_target)
406
+ space_type.lights.each do |space_load_instance|
407
+ inst_sch_check = OpenstudioStandards::QAQC.space_load_instance_schedule_check(space_load_instance, expected_hours, std: std, min_pass_pct: min_pass_pct, max_pass_pct: max_pass_pct)
408
+ if inst_sch_check then check_elems << inst_sch_check end
409
+ end
410
+
411
+ end
412
+ end
413
+
414
+ # check electric equipment schedules
415
+ data['electric_equipment_per_area'].nil? ? (target_ip = 0.0) : (target_ip = data['electric_equipment_per_area'])
416
+ if target_ip.to_f > 0
417
+ schedule_target = std.model_add_schedule(model_temp, data['electric_equipment_schedule'])
418
+ if !schedule_target
419
+ check_elems << OpenStudio::Attribute.new('flag', "Didn't find schedule named #{data['electric_equipment_schedule']} in standards json.")
420
+ elsif !schedule_target.to_ScheduleRuleset.is_initialized
421
+ check_elems << OpenStudio::Attribute.new('flag', "Schedule named #{schedule_target.name} is a #{schedule_target.class}, not a ScheduleRuleset schedule.")
422
+ else
423
+ schedule_target = schedule_target.to_ScheduleRuleset.get
424
+ # loop through and test individual load instances
425
+ expected_hours = std.schedule_ruleset_annual_equivalent_full_load_hrs(schedule_target)
426
+
427
+ space_type.electricEquipment.each do |space_load_instance|
428
+ inst_sch_check = OpenstudioStandards::QAQC.space_load_instance_schedule_check(space_load_instance, expected_hours, std: std, min_pass_pct: min_pass_pct, max_pass_pct: max_pass_pct)
429
+ if inst_sch_check then check_elems << inst_sch_check end
430
+ end
431
+ end
432
+ end
433
+
434
+ # check gas equipment schedules
435
+ # @todo - update measure test to with space type to check this
436
+ data['gas_equipment_per_area'].nil? ? (target_ip = 0.0) : (target_ip = data['gas_equipment_per_area'])
437
+ if target_ip.to_f > 0
438
+ schedule_target = std.model_add_schedule(model_temp, data['gas_equipment_schedule'])
439
+ if !schedule_target
440
+ check_elems << OpenStudio::Attribute.new('flag', "Didn't find schedule named #{data['gas_equipment_schedule']} in standards json.")
441
+ elsif !schedule_target.to_ScheduleRuleset.is_initialized
442
+ check_elems << OpenStudio::Attribute.new('flag', "Schedule named #{schedule_target.name} is a #{schedule_target.class}, not a ScheduleRuleset schedule.")
443
+ else
444
+ schedule_target = schedule_target.to_ScheduleRuleset.get
445
+ # loop through and test individual load instances
446
+ expected_hours = std.schedule_ruleset_annual_equivalent_full_load_hrs(schedule_target)
447
+ space_type.gasEquipment.each do |space_load_instance|
448
+ inst_sch_check = OpenstudioStandards::QAQC.space_load_instance_schedule_check(space_load_instance, expected_hours, std: std, min_pass_pct: min_pass_pct, max_pass_pct: max_pass_pct)
449
+ if inst_sch_check then check_elems << inst_sch_check end
450
+ end
451
+ end
452
+ end
453
+
454
+ # check occupancy schedules
455
+ data['occupancy_per_area'].nil? ? (target_ip = 0.0) : (target_ip = data['occupancy_per_area'])
456
+ if target_ip.to_f > 0
457
+ schedule_target = std.model_add_schedule(model_temp, data['occupancy_schedule'])
458
+ if !schedule_target
459
+ check_elems << OpenStudio::Attribute.new('flag', "Didn't find schedule named #{data['occupancy_schedule']} in standards json.")
460
+ elsif !schedule_target.to_ScheduleRuleset.is_initialized
461
+ check_elems << OpenStudio::Attribute.new('flag', "Schedule named #{schedule_target.name} is a #{schedule_target.class}, not a ScheduleRuleset schedule.")
462
+ else
463
+ schedule_target = schedule_target.to_ScheduleRuleset.get
464
+ # loop through and test individual load instances
465
+ expected_hours = std.schedule_ruleset_annual_equivalent_full_load_hrs(schedule_target)
466
+ space_type.people.each do |space_load_instance|
467
+ inst_sch_check = OpenstudioStandards::QAQC.space_load_instance_schedule_check(space_load_instance, expected_hours, std: std, min_pass_pct: min_pass_pct, max_pass_pct: max_pass_pct)
468
+ if inst_sch_check then check_elems << inst_sch_check end
469
+ end
470
+
471
+ end
472
+ end
473
+
474
+ # @todo: check ventilation schedules
475
+ # if objects are in the model should they just be always on schedule, or have a 8760 annual equivalent value
476
+ # oa_schedule should not exist, or if it does shoudl be always on or have 8760 annual equivalent value
477
+ if space_type.designSpecificationOutdoorAir.is_initialized
478
+ oa = space_type.designSpecificationOutdoorAir.get
479
+ if oa.outdoorAirFlowRateFractionSchedule.is_initialized
480
+ # @todo: update measure test to check this
481
+ expected_hours = 8760
482
+ inst_sch_check = OpenstudioStandards::QAQC.space_load_instance_schedule_check(oa, expected_hours, std: std, min_pass_pct: min_pass_pct, max_pass_pct: max_pass_pct)
483
+ if inst_sch_check then check_elems << inst_sch_check end
484
+ end
485
+ end
486
+
487
+ # notes
488
+ # current logic only looks at 8760 values and not design days
489
+ # when multiple instances of a type currently check every schedule by itself. In future could do weighted avgerage merge
490
+ # not looking at infiltration schedules
491
+ # not looking at luminaires
492
+ # not looking at space loads, only loads at space type
493
+ # only checking schedules where standard shows non zero load value
494
+ # model load for space type where standards doesn't have one wont throw flag about mis-matched schedules
495
+ end
496
+
497
+ # warn if there are spaces in model that don't use space type unless they appear to be plenums
498
+ @model.getSpaces.sort.each do |space|
499
+ next if std.space_plenum?(space)
500
+
501
+ if !space.spaceType.is_initialized
502
+ check_elems << OpenStudio::Attribute.new('flag', "#{space.name} doesn't have a space type assigned, can't validate schedules.")
503
+ end
504
+ end
505
+ rescue StandardError => e
506
+ # brief description of ruby error
507
+ check_elems << OpenStudio::Attribute.new('flag', "Error prevented QAQC check from running (#{e}).")
508
+
509
+ # backtrace of ruby error for diagnostic use
510
+ if @error_backtrace then check_elems << OpenStudio::Attribute.new('flag', e.backtrace.join("\n").to_s) end
511
+ end
512
+
513
+ # add check_elms to new attribute
514
+ check_elem = OpenStudio::Attribute.new('check', check_elems)
515
+
516
+ return check_elem
517
+ end
518
+
519
+ # Check the schedule for a space load instance
520
+ # will return false or a single attribute
521
+ #
522
+ # @param space_load_instance [OpenStudio::Model::SpaceLoadInstance] Openstudio SpaceLoadInstance object
523
+ # @param expected_hours [Double] expected number of equivalent full load hours
524
+ # @param std [String] openstudio-standards Standard Class
525
+ # @param min_pass_pct [Double] threshold for throwing an error for percent difference
526
+ # @param max_pass_pct [Double] threshold for throwing an error for percent difference
527
+ # @return [OpenStudio::Attribute, false] OpenStudio Attribute object containing check results, or false if no error
528
+ def self.space_load_instance_schedule_check(space_load_instance, expected_hours, std: nil, min_pass_pct: 0.2, max_pass_pct: 0.2)
529
+ if std.nil?
530
+ std = Standard.build('90.1-2013')
531
+ end
532
+
533
+ if space_load_instance.spaceType.is_initialized
534
+ space_type = space_load_instance
535
+ end
536
+
537
+ # get schedule
538
+ if (space_load_instance.class.to_s == 'OpenStudio::Model::People') && space_load_instance.numberofPeopleSchedule.is_initialized
539
+ schedule_inst = space_load_instance.numberofPeopleSchedule.get
540
+ elsif (space_load_instance.class.to_s == 'OpenStudio::Model::DesignSpecificationOutdoorAir') && space_load_instance.outdoorAirFlowRateFractionSchedule.is_initialized
541
+ schedule_inst = space_load_instance.outdoorAirFlowRateFractionSchedule .get
542
+ elsif space_load_instance.schedule.is_initialized
543
+ schedule_inst = space_load_instance.schedule.get
544
+ else
545
+ return OpenStudio::Attribute.new('flag', "#{space_load_instance.name} in #{space_type.name} doesn't have a schedule assigned.")
546
+ end
547
+
548
+ # get annual equiv for model schedule
549
+ if schedule_inst.to_ScheduleRuleset.is_initialized
550
+ inst_hrs = std.schedule_ruleset_annual_equivalent_full_load_hrs(schedule_inst.to_ScheduleRuleset.get)
551
+ elsif schedule_inst.to_ScheduleConstant.is_initialized
552
+ inst_hrs = std.schedule_constant_annual_equivalent_full_load_hrs(schedule_inst.to_ScheduleConstant.get)
553
+ else
554
+ return OpenStudio::Attribute.new('flag', "#{schedule_inst.name} isn't a Ruleset or Constant schedule. Can't calculate annual equivalent full load hours.")
555
+ end
556
+
557
+ # check instance against target
558
+ if inst_hrs < expected_hours * (1.0 - min_pass_pct)
559
+ return OpenStudio::Attribute.new('flag', "#{inst_hrs.round} annual equivalent full load hours for #{schedule_inst.name} in #{space_type.name} is more than #{min_pass_pct * 100} (%) below the typical value of #{expected_hours.round} hours from the DOE Prototype building.")
560
+ elsif inst_hrs > expected_hours * (1.0 + max_pass_pct)
561
+ return OpenStudio::Attribute.new('flag', "#{inst_hrs.round} annual equivalent full load hours for #{schedule_inst.name} in #{space_type.name} is more than #{max_pass_pct * 100} (%) above the typical value of #{expected_hours.round} hours DOE Prototype building.")
562
+ end
563
+
564
+ # will get to this if no flag was thrown
565
+ return false
566
+ end
567
+ end
568
+ end