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
@@ -1,6 +1,9 @@
1
1
  # This class holds methods that apply NECB2011 rules.
2
2
  # @ref [References::NECB2011]
3
3
  class NECB2011 < Standard
4
+ require 'zip'
5
+ require 'open-uri'
6
+
4
7
  @template = new.class.name
5
8
  register_standard(@template)
6
9
  attr_reader :tbd
@@ -231,17 +234,19 @@ class NECB2011 < Standard
231
234
  output_meters: nil,
232
235
  airloop_economizer_type: nil,
233
236
  baseline_system_zones_map_option: nil,
234
- tbd_option: nil)
237
+ tbd_option: nil,
238
+ tbd_interpolate: false)
235
239
  model = load_building_type_from_library(building_type: building_type)
236
240
  return model_apply_standard(model: model,
237
241
  tbd_option: tbd_option,
242
+ tbd_interpolate: tbd_interpolate,
238
243
  epw_file: epw_file,
239
244
  sizing_run_dir: sizing_run_dir,
240
245
  primary_heating_fuel: primary_heating_fuel,
241
246
  dcv_type: dcv_type, # Four options: (1) 'NECB_Default', (2) 'No_DCV', (3) 'Occupancy_based_DCV' , (4) 'CO2_based_DCV'
242
247
  lights_type: lights_type, # Two options: (1) 'NECB_Default', (2) 'LED'
243
248
  lights_scale: lights_scale,
244
- daylighting_type: daylighting_type, # Two options: (1) 'NECB_Default', (2) 'add_daylighting_controls'
249
+ daylighting_type: daylighting_type, # Two options: (1) nil/none/false/'NECB_Default' (Option #1 puts daylighting sensors in the spaces as per NECB requirements; so some spaces may not have sensors), (2) 'add_daylighting_controls' (Option #2 puts daylighting sensors in all spaces regardless of NECB requirements)
245
250
  ecm_system_name: ecm_system_name,
246
251
  ecm_system_zones_map_option: ecm_system_zones_map_option, # (1) 'NECB_Default' (2) 'one_sys_per_floor' (3) 'one_sys_per_bldg'
247
252
  erv_package: erv_package,
@@ -306,6 +311,7 @@ class NECB2011 < Standard
306
311
  # code versions without modifying the build_protoype_model method or copying it wholesale for a few changes.
307
312
  def model_apply_standard(model:,
308
313
  tbd_option: nil,
314
+ tbd_interpolate: nil,
309
315
  epw_file:,
310
316
  sizing_run_dir: Dir.pwd,
311
317
  necb_reference_hp: false,
@@ -367,6 +373,11 @@ class NECB2011 < Standard
367
373
  fdwr_set = convert_arg_to_f(variable: fdwr_set, default: -1)
368
374
  srr_set = convert_arg_to_f(variable: srr_set, default: -1)
369
375
 
376
+ # Ensure the volume calculation in all spaces is done automatically
377
+ model.getSpaces.sort.each do |space|
378
+ space.autocalculateVolume
379
+ end
380
+
370
381
  apply_weather_data(model: model, epw_file: epw_file)
371
382
  apply_loads(model: model,
372
383
  lights_type: lights_type,
@@ -393,7 +404,12 @@ class NECB2011 < Standard
393
404
  apply_fdwr_srr_daylighting(model: model,
394
405
  fdwr_set: fdwr_set,
395
406
  srr_set: srr_set)
396
- apply_thermal_bridging(model: model, tbd_option: tbd_option)
407
+ apply_thermal_bridging(model: model,
408
+ tbd_option: tbd_option,
409
+ tbd_interpolate: tbd_interpolate,
410
+ wall_U: ext_wall_cond,
411
+ floor_U: ext_floor_cond,
412
+ roof_U: ext_roof_cond)
397
413
  apply_auto_zoning(model: model,
398
414
  sizing_run_dir: sizing_run_dir,
399
415
  lights_type: lights_type,
@@ -518,12 +534,12 @@ class NECB2011 < Standard
518
534
 
519
535
  # -------- Performace, Efficiencies, Controls and Sensors ------------
520
536
  #
521
- # Set code standard equipment charecteristics.
537
+ # Set code standard equipment characteristics.
522
538
  sql_db_vars_map = apply_standard_efficiencies(model: model,
523
539
  sizing_run_dir: sizing_run_dir,
524
540
  necb_reference_hp: self.fuel_type_set.necb_reference_hp)
525
541
  # Apply System
526
- ecm.apply_system_efficiencies_ecm(model: model, ecm_system_name: ecm_system_name)
542
+ ecm.apply_system_efficiencies_ecm(model: model, ecm_system_name: ecm_system_name, template_standard: self)
527
543
  # Apply ECM ERV charecteristics as required. Part 2 of above ECM.
528
544
  ecm.apply_erv_ecm_efficiency(model: model, erv_package: erv_package)
529
545
  # Apply DCV as required
@@ -537,7 +553,7 @@ class NECB2011 < Standard
537
553
  # Apply SHW Efficiency
538
554
  ecm.modify_shw_efficiency(model: model, shw_eff: shw_eff)
539
555
  # Apply daylight controls.
540
- model_add_daylighting_controls(model) if daylighting_type == 'add_daylighting_controls'
556
+ model_add_daylighting_controls(model: model, daylighting_type: daylighting_type)
541
557
  # Apply Chiller efficiency
542
558
  ecm.modify_chiller_efficiency(model: model, chiller_type: chiller_type)
543
559
  # Apply airloop economizer
@@ -551,7 +567,13 @@ class NECB2011 < Standard
551
567
  # apply unitary cop
552
568
  ecm.modify_unitary_cop(model: model, unitary_cop: unitary_cop, sizing_done: true, sql_db_vars_map: sql_db_vars_map)
553
569
  # set capacities of district heating and cooling equipment for ground-source heat pump ecm
554
- ecm.set_ghx_loop_district_cap(model) if (!model.getDistrictHeatings.empty? && !model.getDistrictCoolings.empty?)
570
+ district_heat = false
571
+ if model.version < OpenStudio::VersionString.new('3.7.0')
572
+ district_heat = !model.getDistrictHeatings.empty?
573
+ else
574
+ district_heat = !model.getDistrictHeatingWaters.empty?
575
+ end
576
+ ecm.set_ghx_loop_district_cap(model) if (district_heat && !model.getDistrictCoolings.empty?)
555
577
 
556
578
  # -------Pump sizing required by some vintages----------------
557
579
  # Apply Pump power as required.
@@ -578,6 +600,10 @@ class NECB2011 < Standard
578
600
  pv_ground_module_description: pv_ground_module_description)
579
601
  end
580
602
 
603
+ # Rename air loop and plant loop nodes to accommodate coming OpenStudio version
604
+ rename_air_loop_nodes(model)
605
+ rename_plant_loop_nodes(model)
606
+
581
607
  end
582
608
 
583
609
  def apply_loads(model:,
@@ -604,6 +630,14 @@ class NECB2011 < Standard
604
630
  end
605
631
 
606
632
  def apply_weather_data(model:, epw_file:)
633
+ # Create full path to weather file
634
+ weather_files = File.absolute_path(File.join(__FILE__, '..', '..', '..', '..', '..' , '..', "data/weather"))
635
+ weather_file = File.join(weather_files, epw_file)
636
+ # Check if the weather file exists. If it does continue as normal, otherwise try to dowload it from the
637
+ # canmet-energy/btap_weather repository
638
+ unless File.exist?(weather_file)
639
+ get_weather_file_from_repo(epw_file: epw_file)
640
+ end
607
641
  climate_zone = 'NECB HDD Method'
608
642
  # Fix EMS references. Temporary workaround for OS issue #2598
609
643
  model_temp_fix_ems_references(model)
@@ -901,43 +935,64 @@ class NECB2011 < Standard
901
935
  # @param model [OpenStudio::Model::Model] an OpenStudio model
902
936
  # @param tbd_option [String] BTAP/TBD option
903
937
  #
904
- # @return [Bool] true if successful, e.g. no errors, compliant if uprated
905
- def apply_thermal_bridging(model: nil, tbd_option: nil)
938
+ # @return [Boolean] true if successful, e.g. no errors, compliant if uprated
939
+
940
+ ##
941
+ # (Optionally) uprates, then derates, envelope surface constructions due to
942
+ # MAJOR thermal bridges (e.g. roof parapets, corners, fenestration
943
+ # perimeters). See lib/openstudio-standards/btap/bridging.rb, which relies on
944
+ # the Thermal Bridging & Derating (TBD) gem.
945
+ #
946
+ # @param model [OpenStudio::Model::Model] an OpenStudio model
947
+ # @param tbd_option [String] BTAP/TBD option
948
+ # @param tbd_interpolate [Boolean] true if TBD interpolates between costed Uo
949
+ # @param wall_U [Double] wall conductance in W/m2.K (nil by default)
950
+ # @param floor_U [Double] floor conductance in W/m2.K (nil by default)
951
+ # @param roof_U [Double] roof conductance in W/m2.K (nil by default)
952
+ #
953
+ # @return [Boolean] true if successful, e.g. no errors, compliant if uprated
954
+ def apply_thermal_bridging(model: nil,
955
+ tbd_option: 'none',
956
+ tbd_interpolate: false,
957
+ wall_U: nil,
958
+ floor_U: nil,
959
+ roof_U: nil)
906
960
  return false unless model.is_a?(OpenStudio::Model::Model)
907
961
  return false unless tbd_option.respond_to?(:to_s)
908
962
 
909
963
  tbd_option = tbd_option.to_s
910
964
  # 4x options:
911
- # - nil or 'none'(TBD is ignored)
965
+ # - 'none' (TBD is ignored)
912
966
  # - derate using 'bad' PSI factors (BTAP-costed)
913
967
  # - derate using 'good' PSI factors (BTAP-costed)
914
968
  # - 'uprate' (then derate), i.e. iterative process (BTAP-costed)
969
+ ok = tbd_option == 'bad' || tbd_option == 'good' || tbd_option == 'uprate'
970
+ return true if tbd_option == 'none'
971
+ return false unless ok
915
972
 
916
- # Do nothing if nil or none or NECB_Default.
917
- return true if tbd_option.nil? || tbd_option == 'none' || tbd_option =='NECB_Default'
918
- unless tbd_option == 'bad' || tbd_option == 'good' || tbd_option == 'uprate'
919
- puts("invalid input for thermal bridging. Must be good, bad, uprate or nil")
920
- return false
921
- end
973
+ argh = {} # BTAP/TBD arguments
974
+ ok = tbd_interpolate == true || tbd_interpolate == false
975
+ argh[:interpolate] = tbd_interpolate if ok
976
+ argh[:interpolate] = false unless ok
922
977
 
923
- argh = {} # BTAP/TBD arguments
924
- argh[:walls ] = { uo: nil }
925
- argh[:floors] = { uo: nil }
926
- argh[:roofs ] = { uo: nil }
978
+ argh[:walls ] = { uo: wall_U }
979
+ argh[:floors] = { uo: floor_U }
980
+ argh[:roofs ] = { uo: roof_U }
927
981
 
928
982
  if tbd_option == 'uprate'
929
- argh[:walls ][:ut] = nil
930
- argh[:floors ][:ut] = nil
931
- argh[:roofs ][:ut] = nil
983
+ argh[:walls ][:ut] = wall_U
984
+ argh[:floors ][:ut] = floor_U
985
+ argh[:roofs ][:ut] = roof_U
932
986
  elsif tbd_option == 'good'
933
987
  argh[:quality] = :good
934
988
  end # default == :bad
935
989
 
936
990
  @tbd = BTAP::Bridging.new(model, argh)
991
+
937
992
  true
938
993
  end
939
994
 
940
- # @param necb_ref_hp [Bool] if true, NECB reference model rules for heat pumps will be used.
995
+ # @param necb_reference_hp [Boolean] if true, NECB reference model rules for heat pumps will be used.
941
996
  def apply_standard_efficiencies(model:, sizing_run_dir:, dcv_type: 'NECB_Default', necb_reference_hp: false)
942
997
  raise('validation of model failed.') unless validate_initial_model(model)
943
998
 
@@ -972,7 +1027,7 @@ class NECB2011 < Standard
972
1027
  #
973
1028
  # @param min_occ_pct [Double] the fractional value below which
974
1029
  # the system will be considered unoccupied.
975
- # @return [Bool] true if successful, false if not
1030
+ # @return [Boolean] true if successful, false if not
976
1031
  def air_loop_hvac_enable_unoccupied_fan_shutoff(air_loop_hvac, min_occ_pct = 0.05)
977
1032
  # Set the system to night cycle
978
1033
  air_loop_hvac.setNightCycleControlType('CycleOnAny')
@@ -1154,7 +1209,7 @@ class NECB2011 < Standard
1154
1209
  return true
1155
1210
  end
1156
1211
 
1157
- # @return [Bool] returns true if successful, false if not
1212
+ # @return [Boolean] returns true if successful, false if not
1158
1213
  def set_occ_sensor_spacetypes(model, space_type_map)
1159
1214
  building_type = 'Space Function'
1160
1215
  space_type_map.each do |space_type_name, space_names|
@@ -1255,24 +1310,37 @@ class NECB2011 < Standard
1255
1310
  end
1256
1311
  end
1257
1312
 
1258
- ##### Ask user's inputs for daylighting controls illuminance setpoint and number of stepped control steps.
1259
- ##### Note that the minimum number of stepped control steps is two steps as per NECB2011.
1260
- def daylighting_controls_settings(illuminance_setpoint: 500.0,
1261
- number_of_stepped_control_steps: 2)
1262
- return illuminance_setpoint, number_of_stepped_control_steps
1263
- end
1313
+ def model_add_daylighting_controls(model:, daylighting_type:)
1264
1314
 
1265
- def model_add_daylighting_controls(model)
1315
+ return if daylighting_type == 'none'
1266
1316
  ##### Find spaces with exterior fenestration including fixed window, operable window, and skylight.
1267
1317
  daylight_spaces = []
1318
+ daylight_spaces_target_illuminance_setpoint_hash = {}
1268
1319
  model.getSpaces.sort.each do |space|
1269
1320
  space.surfaces.sort.each do |surface|
1270
1321
  surface.subSurfaces.sort.each do |subsurface|
1271
1322
  if subsurface.outsideBoundaryCondition == 'Outdoors' &&
1272
- (subsurface.subSurfaceType == 'FixedWindow' ||
1273
- subsurface.subSurfaceType == 'OperableWindow' ||
1274
- subsurface.subSurfaceType == 'Skylight')
1323
+ (subsurface.subSurfaceType == 'FixedWindow' ||
1324
+ subsurface.subSurfaceType == 'OperableWindow' ||
1325
+ subsurface.subSurfaceType == 'Skylight')
1275
1326
  daylight_spaces << space
1327
+ space_type = space.spaceType.get
1328
+ space_type_name = space.spaceType.get.name.to_s
1329
+ space_type_name = space_type_name.gsub('Space Function', '')
1330
+ # puts "space_type_name is #{space_type_name}"
1331
+
1332
+ # Gather minimum illuminance level as per NECB
1333
+ lux_spacetype_data = @standards_data['tables']['space_types']['table']
1334
+ standards_building_type = space_type.standardsBuildingType.is_initialized ? space_type.standardsBuildingType.get : nil
1335
+ standards_space_type = space_type.standardsSpaceType.is_initialized ? space_type.standardsSpaceType.get : nil
1336
+ lux_space_type_properties = lux_spacetype_data.detect { |s| (s['building_type'] == standards_building_type) && (s['space_type'] == standards_space_type) }
1337
+ if lux_space_type_properties.nil?
1338
+ raise("#{standards_building_type} for #{standards_space_type} was not found please verify the target_illuminance_setpoint database names match the space type names.")
1339
+ end
1340
+
1341
+ target_illuminance_setpoint = lux_space_type_properties['target_illuminance_setpoint'].to_f
1342
+ daylight_spaces_target_illuminance_setpoint_hash[space.name.to_s] = target_illuminance_setpoint
1343
+
1276
1344
  # subsurface.outsideBoundaryCondition == "Outdoors" && (subsurface.subSurfaceType == "FixedWindow" || "OperableWindow")
1277
1345
  end
1278
1346
  # surface.subSurfaces.each do |subsurface|
@@ -1284,188 +1352,193 @@ class NECB2011 < Standard
1284
1352
 
1285
1353
  ##### Remove duplicate spaces from the "daylight_spaces" array, as a daylighted space may have various fenestration types.
1286
1354
  daylight_spaces = daylight_spaces.uniq
1287
- # puts daylight_spaces
1288
-
1289
- ##### Create hashes for "Primary Sidelighted Areas", "Sidelighting Effective Aperture", "Daylighted Area Under Skylights",
1290
- ##### and "Skylight Effective Aperture" for the whole model.
1291
- ##### Each of these hashes will be used later in this function (i.e. model_add_daylighting_controls)
1292
- ##### to provide a dictionary of daylighted space names and the associated value (i.e. daylighted area or effective aperture).
1293
- primary_sidelighted_area_hash = {}
1294
- sidelighting_effective_aperture_hash = {}
1295
- daylighted_area_under_skylights_hash = {}
1296
- skylight_effective_aperture_hash = {}
1297
-
1298
- ##### Calculate "Primary Sidelighted Areas" AND "Sidelighting Effective Aperture" as per NECB2011. #TODO: consider removing overlapped sidelighted area
1299
- daylight_spaces.sort.each do |daylight_space|
1300
- # puts daylight_space.name.to_s
1301
- primary_sidelighted_area = 0.0
1302
- area_weighted_vt_handle = 0.0
1303
- area_weighted_vt = 0.0
1304
- window_area_sum = 0.0
1305
-
1306
- ##### Calculate floor area of the daylight_space and get floor vertices of the daylight_space (to be used for the calculation of daylight_space depth)
1307
- floor_surface = nil
1308
- floor_area = 0.0
1309
- floor_vertices = []
1310
- daylight_space.surfaces.sort.each do |surface|
1311
- if surface.surfaceType == 'Floor'
1312
- floor_surface = surface
1313
- floor_area += surface.netArea
1314
- floor_vertices << surface.vertices
1315
- end
1316
- end
1355
+ # puts "daylight_spaces are #{daylight_spaces}"
1317
1356
 
1318
- ##### Loop through the surfaces of each daylight_space to calculate primary_sidelighted_area and
1319
- ##### area-weighted visible transmittance and window_area_sum which are used to calculate sidelighting_effective_aperture
1320
- primary_sidelighted_area, area_weighted_vt_handle, window_area_sum =
1321
- get_parameters_sidelighting(daylight_space: daylight_space,
1322
- floor_surface: floor_surface,
1323
- floor_vertices: floor_vertices,
1324
- floor_area: floor_area,
1325
- primary_sidelighted_area: primary_sidelighted_area,
1326
- area_weighted_vt_handle: area_weighted_vt_handle,
1327
- window_area_sum: window_area_sum)
1328
-
1329
- primary_sidelighted_area_hash[daylight_space.name.to_s] = primary_sidelighted_area
1330
-
1331
- ##### Calculate area-weighted VT of glazing (this is used to calculate sidelighting effective aperture; see NECB2011: 4.2.2.10.).
1332
- area_weighted_vt = area_weighted_vt_handle / window_area_sum
1333
- sidelighting_effective_aperture_hash[daylight_space.name.to_s] = window_area_sum * area_weighted_vt / primary_sidelighted_area
1334
- # daylight_spaces.each do |daylight_space|
1335
- end
1357
+ if daylighting_type.nil? || daylighting_type == false || daylighting_type == 'none' || daylighting_type == 'NECB_Default' # puts daylighting sensors in the spaces as per NECB requirements; so some spaces may not have sensors
1336
1358
 
1337
- ##### Calculate "Daylighted Area Under Skylights" AND "Skylight Effective Aperture"
1338
- daylight_spaces.sort.each do |daylight_space|
1339
- # puts daylight_space.name.to_s
1340
- skylight_area = 0.0
1341
- skylight_area_weighted_vt_handle = 0.0
1342
- skylight_area_weighted_vt = 0.0
1343
- skylight_area_sum = 0.0
1344
- daylighted_under_skylight_area = 0.0
1345
-
1346
- ##### Loop through the surfaces of each daylight_space to calculate daylighted_area_under_skylights and skylight_effective_aperture for each daylight_space
1347
- daylighted_under_skylight_area, skylight_area_weighted_vt_handle, skylight_area_sum =
1348
- get_parameters_skylight(daylight_space: daylight_space,
1349
- skylight_area_weighted_vt_handle: skylight_area_weighted_vt_handle,
1350
- skylight_area_sum: skylight_area_sum,
1351
- daylighted_under_skylight_area: daylighted_under_skylight_area)
1352
-
1353
- daylighted_area_under_skylights_hash[daylight_space.name.to_s] = daylighted_under_skylight_area
1354
-
1355
- ##### Calculate skylight_effective_aperture as per NECB2011: 4.2.2.7.
1356
- ##### Note that it was assumed that the skylight is flush with the ceiling. Therefore, area-weighted average well factor (WF) was set to 0.9 in the below Equation.
1357
- skylight_area_weighted_vt = skylight_area_weighted_vt_handle / skylight_area_sum
1358
- skylight_effective_aperture_hash[daylight_space.name.to_s] = 0.85 * skylight_area_sum * skylight_area_weighted_vt * 0.9 / daylighted_under_skylight_area
1359
- # daylight_spaces.each do |daylight_space|
1360
- end
1361
- # puts primary_sidelighted_area_hash
1362
- # puts sidelighting_effective_aperture_hash
1363
- # puts daylighted_area_under_skylights_hash
1364
- # puts skylight_effective_aperture_hash
1359
+ ##### Create hashes for "Primary Sidelighted Areas", "Sidelighting Effective Aperture", "Daylighted Area Under Skylights",
1360
+ ##### and "Skylight Effective Aperture" for the whole model.
1361
+ ##### Each of these hashes will be used later in this function (i.e. model_add_daylighting_controls)
1362
+ ##### to provide a dictionary of daylighted space names and the associated value (i.e. daylighted area or effective aperture).
1363
+ primary_sidelighted_area_hash = {}
1364
+ sidelighting_effective_aperture_hash = {}
1365
+ daylighted_area_under_skylights_hash = {}
1366
+ skylight_effective_aperture_hash = {}
1365
1367
 
1366
- ##### Find office spaces >= 25m2 among daylight_spaces
1367
- offices_larger_25m2 = []
1368
- daylight_spaces.sort.each do |daylight_space|
1369
- ## The following steps are for in case an office has multiple floors at various heights
1370
- ## 1. Calculate number of floors of each daylight_space
1371
- ## 2. Find the lowest z among all floors of each daylight_space
1372
- ## 3. Find lowest floors of each daylight_space (these floors are at the same level)
1373
- ## 4. Calculate 'daylight_space_area' as sum of area of all the lowest floors of each daylight_space, and gather the vertices of all the lowest floors of each daylight_space
1374
-
1375
- ## 1. Calculate number of floors of daylight_space
1376
- floor_vertices = []
1377
- number_floor = 0
1378
- daylight_space.surfaces.sort.each do |surface|
1379
- if surface.surfaceType == 'Floor'
1380
- floor_vertices << surface.vertices
1381
- number_floor += 1
1368
+ ##### Calculate "Primary Sidelighted Areas" AND "Sidelighting Effective Aperture" as per NECB2011. # @todo consider removing overlapped sidelighted area
1369
+ daylight_spaces.sort.each do |daylight_space|
1370
+ primary_sidelighted_area = 0.0
1371
+ area_weighted_vt_handle = 0.0
1372
+ area_weighted_vt = 0.0
1373
+ window_area_sum = 0.0
1374
+
1375
+ ##### Calculate floor area of the daylight_space and get floor vertices of the daylight_space (to be used for the calculation of daylight_space depth)
1376
+ floor_surface = nil
1377
+ floor_area = 0.0
1378
+ floor_vertices = []
1379
+ daylight_space.surfaces.sort.each do |surface|
1380
+ if surface.surfaceType == 'Floor'
1381
+ floor_surface = surface
1382
+ floor_area += surface.netArea
1383
+ floor_vertices << surface.vertices
1384
+ end
1382
1385
  end
1386
+
1387
+ ##### Loop through the surfaces of each daylight_space to calculate primary_sidelighted_area and
1388
+ ##### area-weighted visible transmittance and window_area_sum which are used to calculate sidelighting_effective_aperture
1389
+ primary_sidelighted_area, area_weighted_vt_handle, window_area_sum =
1390
+ get_parameters_sidelighting(daylight_space: daylight_space,
1391
+ floor_surface: floor_surface,
1392
+ floor_vertices: floor_vertices,
1393
+ floor_area: floor_area,
1394
+ primary_sidelighted_area: primary_sidelighted_area,
1395
+ area_weighted_vt_handle: area_weighted_vt_handle,
1396
+ window_area_sum: window_area_sum)
1397
+
1398
+ primary_sidelighted_area_hash[daylight_space.name.to_s] = primary_sidelighted_area
1399
+
1400
+ ##### Calculate area-weighted VT of glazing (this is used to calculate sidelighting effective aperture; see NECB2011: 4.2.2.10.).
1401
+ area_weighted_vt = area_weighted_vt_handle / window_area_sum
1402
+ sidelighting_effective_aperture_hash[daylight_space.name.to_s] = window_area_sum * area_weighted_vt / primary_sidelighted_area
1403
+ # daylight_spaces.each do |daylight_space|
1383
1404
  end
1384
1405
 
1385
- ## 2. Loop through all floors of daylight_space, and find the lowest z among all floors of daylight_space
1386
- lowest_floor_z = []
1387
- highest_floor_z = []
1388
- for i in 0..number_floor - 1
1389
- if i == 0
1390
- lowest_floor_z = floor_vertices[i][0].z
1391
- highest_floor_z = floor_vertices[i][0].z
1392
- else
1393
- if lowest_floor_z > floor_vertices[i][0].z
1394
- lowest_floor_z = floor_vertices[i][0].z
1395
- else
1396
- lowest_floor_z = lowest_floor_z
1406
+ ##### Calculate "Daylighted Area Under Skylights" AND "Skylight Effective Aperture"
1407
+ daylight_spaces.sort.each do |daylight_space|
1408
+ # puts daylight_space.name.to_s
1409
+ skylight_area = 0.0
1410
+ skylight_area_weighted_vt_handle = 0.0
1411
+ skylight_area_weighted_vt = 0.0
1412
+ skylight_area_sum = 0.0
1413
+ daylighted_under_skylight_area = 0.0
1414
+
1415
+ ##### Loop through the surfaces of each daylight_space to calculate daylighted_area_under_skylights and skylight_effective_aperture for each daylight_space
1416
+ daylighted_under_skylight_area, skylight_area_weighted_vt_handle, skylight_area_sum =
1417
+ get_parameters_skylight(daylight_space: daylight_space,
1418
+ skylight_area_weighted_vt_handle: skylight_area_weighted_vt_handle,
1419
+ skylight_area_sum: skylight_area_sum,
1420
+ daylighted_under_skylight_area: daylighted_under_skylight_area)
1421
+
1422
+ daylighted_area_under_skylights_hash[daylight_space.name.to_s] = daylighted_under_skylight_area
1423
+
1424
+ ##### Calculate skylight_effective_aperture as per NECB2011: 4.2.2.7.
1425
+ ##### Note that it was assumed that the skylight is flush with the ceiling. Therefore, area-weighted average well factor (WF) was set to 0.9 in the below Equation.
1426
+ skylight_area_weighted_vt = skylight_area_weighted_vt_handle / skylight_area_sum
1427
+ skylight_effective_aperture_hash[daylight_space.name.to_s] = 0.85 * skylight_area_sum * skylight_area_weighted_vt * 0.9 / daylighted_under_skylight_area
1428
+ # daylight_spaces.each do |daylight_space|
1429
+ end
1430
+ # puts "primary_sidelighted_area_hash is #{primary_sidelighted_area_hash}"
1431
+ # puts sidelighting_effective_aperture_hash
1432
+ # puts daylighted_area_under_skylights_hash
1433
+ # puts skylight_effective_aperture_hash
1434
+
1435
+ ##### Find office spaces >= 25m2 among daylight_spaces
1436
+ offices_larger_25m2 = []
1437
+ daylight_spaces.sort.each do |daylight_space|
1438
+ ## The following steps are for in case an office has multiple floors at various heights
1439
+ ## 1. Calculate number of floors of each daylight_space
1440
+ ## 2. Find the lowest z among all floors of each daylight_space
1441
+ ## 3. Find lowest floors of each daylight_space (these floors are at the same level)
1442
+ ## 4. Calculate 'daylight_space_area' as sum of area of all the lowest floors of each daylight_space, and gather the vertices of all the lowest floors of each daylight_space
1443
+
1444
+ ## 1. Calculate number of floors of daylight_space
1445
+ floor_vertices = []
1446
+ number_floor = 0
1447
+ daylight_space.surfaces.sort.each do |surface|
1448
+ if surface.surfaceType == 'Floor'
1449
+ floor_vertices << surface.vertices
1450
+ number_floor += 1
1397
1451
  end
1398
- if highest_floor_z < floor_vertices[i][0].z
1452
+ end
1453
+
1454
+ ## 2. Loop through all floors of daylight_space, and find the lowest z among all floors of daylight_space
1455
+ lowest_floor_z = []
1456
+ highest_floor_z = []
1457
+ for i in 0..number_floor - 1
1458
+ if i == 0
1459
+ lowest_floor_z = floor_vertices[i][0].z
1399
1460
  highest_floor_z = floor_vertices[i][0].z
1400
1461
  else
1401
- highest_floor_z = highest_floor_z
1462
+ if lowest_floor_z > floor_vertices[i][0].z
1463
+ lowest_floor_z = floor_vertices[i][0].z
1464
+ else
1465
+ lowest_floor_z = lowest_floor_z
1466
+ end
1467
+ if highest_floor_z < floor_vertices[i][0].z
1468
+ highest_floor_z = floor_vertices[i][0].z
1469
+ else
1470
+ highest_floor_z = highest_floor_z
1471
+ end
1402
1472
  end
1403
1473
  end
1404
- end
1405
1474
 
1406
- ## 3 and 4. Loop through all floors of daylight_space, and calculate the sum of area of all the lowest floors of daylight_space,
1407
- ## and gather the vertices of all the lowest floors of daylight_space
1408
- daylight_space_area = 0
1409
- lowest_floors_vertices = []
1410
- floor_vertices = []
1411
- daylight_space.surfaces.sort.each do |surface|
1412
- if surface.surfaceType == 'Floor'
1413
- floor_vertices = surface.vertices
1414
- if floor_vertices[0].z == lowest_floor_z
1415
- lowest_floors_vertices << floor_vertices
1416
- daylight_space_area += surface.netArea
1475
+ ## 3 and 4. Loop through all floors of daylight_space, and calculate the sum of area of all the lowest floors of daylight_space,
1476
+ ## and gather the vertices of all the lowest floors of daylight_space
1477
+ daylight_space_area = 0
1478
+ lowest_floors_vertices = []
1479
+ floor_vertices = []
1480
+ daylight_space.surfaces.sort.each do |surface|
1481
+ if surface.surfaceType == 'Floor'
1482
+ floor_vertices = surface.vertices
1483
+ if floor_vertices[0].z == lowest_floor_z
1484
+ lowest_floors_vertices << floor_vertices
1485
+ daylight_space_area += surface.netArea
1486
+ end
1417
1487
  end
1418
1488
  end
1419
- end
1420
1489
 
1421
- if daylight_space.spaceType.get.standardsSpaceType.get.to_s == 'Office - enclosed' && daylight_space_area >= 25.0
1422
- offices_larger_25m2 << daylight_space.name.to_s
1490
+ if daylight_space.spaceType.get.standardsSpaceType.get.to_s == 'Office - enclosed' && daylight_space_area >= 25.0
1491
+ offices_larger_25m2 << daylight_space.name.to_s
1492
+ end
1423
1493
  end
1424
- end
1425
1494
 
1426
- ##### find daylight_spaces which do not need daylight sensor controls based on the primary_sidelighted_area as per NECB2011: 4.2.2.8.
1427
- ##### Note: Office spaces >= 25m2 are excluded (i.e. they should have daylighting controls even if their primary_sidelighted_area <= 100m2), as per NECB2011: 4.2.2.2.
1428
- daylight_spaces_exception = []
1429
- primary_sidelighted_area_hash.sort.each do |key_daylight_space_name, value_primary_sidelighted_area|
1430
- if value_primary_sidelighted_area <= 100.0 && [key_daylight_space_name].any? { |word| offices_larger_25m2.include?(word) } == false
1431
- daylight_spaces_exception << key_daylight_space_name
1495
+ ##### find daylight_spaces which do not need daylight sensor controls based on the primary_sidelighted_area as per NECB2011: 4.2.2.8.
1496
+ ##### Note: Office spaces >= 25m2 are excluded (i.e. they should have daylighting controls even if their primary_sidelighted_area <= 100m2), as per NECB2011: 4.2.2.2.
1497
+ daylight_spaces_exception = []
1498
+ primary_sidelighted_area_hash.sort.each do |key_daylight_space_name, value_primary_sidelighted_area|
1499
+ if value_primary_sidelighted_area <= 100.0 && [key_daylight_space_name].any? { |word| offices_larger_25m2.include?(word) } == false
1500
+ daylight_spaces_exception << key_daylight_space_name
1501
+ end
1432
1502
  end
1433
- end
1434
1503
 
1435
- ##### find daylight_spaces which do not need daylight sensor controls based on the sidelighting_effective_aperture as per NECB2011: 4.2.2.8.
1436
- ##### Note: Office spaces >= 25m2 are excluded (i.e. they should have daylighting controls even if their sidelighting_effective_aperture <= 10%), as per NECB2011: 4.2.2.2.
1437
- sidelighting_effective_aperture_hash.sort.each do |key_daylight_space_name, value_sidelighting_effective_aperture|
1438
- if value_sidelighting_effective_aperture <= 0.1 && [key_daylight_space_name].any? { |word| offices_larger_25m2.include?(word) } == false
1439
- daylight_spaces_exception << key_daylight_space_name
1504
+ ##### find daylight_spaces which do not need daylight sensor controls based on the sidelighting_effective_aperture as per NECB2011: 4.2.2.8.
1505
+ ##### Note: Office spaces >= 25m2 are excluded (i.e. they should have daylighting controls even if their sidelighting_effective_aperture <= 10%), as per NECB2011: 4.2.2.2.
1506
+ sidelighting_effective_aperture_hash.sort.each do |key_daylight_space_name, value_sidelighting_effective_aperture|
1507
+ if value_sidelighting_effective_aperture <= 0.1 && [key_daylight_space_name].any? { |word| offices_larger_25m2.include?(word) } == false
1508
+ daylight_spaces_exception << key_daylight_space_name
1509
+ end
1440
1510
  end
1441
- end
1442
1511
 
1443
- ##### find daylight_spaces which do not need daylight sensor controls based on the daylighted_area_under_skylights as per NECB2011: 4.2.2.4.
1444
- ##### Note: Office spaces >= 25m2 are excluded (i.e. they should have daylighting controls even if their daylighted_area_under_skylights <= 400m2), as per NECB2011: 4.2.2.2.
1445
- daylighted_area_under_skylights_hash.sort.each do |key_daylight_space_name, value_daylighted_area_under_skylights|
1446
- if value_daylighted_area_under_skylights <= 400.0 && [key_daylight_space_name].any? { |word| offices_larger_25m2.include?(word) } == false
1447
- daylight_spaces_exception << key_daylight_space_name
1512
+ ##### find daylight_spaces which do not need daylight sensor controls based on the daylighted_area_under_skylights as per NECB2011: 4.2.2.4.
1513
+ ##### Note: Office spaces >= 25m2 are excluded (i.e. they should have daylighting controls even if their daylighted_area_under_skylights <= 400m2), as per NECB2011: 4.2.2.2.
1514
+ daylighted_area_under_skylights_hash.sort.each do |key_daylight_space_name, value_daylighted_area_under_skylights|
1515
+ if value_daylighted_area_under_skylights <= 400.0 && [key_daylight_space_name].any? { |word| offices_larger_25m2.include?(word) } == false
1516
+ daylight_spaces_exception << key_daylight_space_name
1517
+ end
1448
1518
  end
1449
- end
1450
1519
 
1451
- ##### find daylight_spaces which do not need daylight sensor controls based on the skylight_effective_aperture criterion as per NECB2011: 4.2.2.4.
1452
- ##### Note: Office spaces >= 25m2 are excluded (i.e. they should have daylighting controls even if their skylight_effective_aperture <= 0.6%), as per NECB2011: 4.2.2.2.
1453
- skylight_effective_aperture_hash.sort.each do |key_daylight_space_name, value_skylight_effective_aperture|
1454
- if value_skylight_effective_aperture <= 0.006 && [key_daylight_space_name].any? { |word| offices_larger_25m2.include?(word) } == false
1455
- daylight_spaces_exception << key_daylight_space_name
1520
+ ##### find daylight_spaces which do not need daylight sensor controls based on the skylight_effective_aperture criterion as per NECB2011: 4.2.2.4.
1521
+ ##### Note: Office spaces >= 25m2 are excluded (i.e. they should have daylighting controls even if their skylight_effective_aperture <= 0.6%), as per NECB2011: 4.2.2.2.
1522
+ skylight_effective_aperture_hash.sort.each do |key_daylight_space_name, value_skylight_effective_aperture|
1523
+ if value_skylight_effective_aperture <= 0.006 && [key_daylight_space_name].any? { |word| offices_larger_25m2.include?(word) } == false
1524
+ daylight_spaces_exception << key_daylight_space_name
1525
+ end
1456
1526
  end
1457
- end
1458
- # puts daylight_spaces_exception
1527
+ # puts daylight_spaces_exception
1459
1528
 
1460
- ##### Loop through the daylight_spaces and exclude the daylight_spaces that do not meet the criteria (see above) as per NECB2011: 4.2.2.4. and 4.2.2.8.
1461
- daylight_spaces_exception.sort.each do |daylight_space_exception|
1462
- daylight_spaces.sort.each do |daylight_space|
1463
- if daylight_space.name.to_s == daylight_space_exception
1464
- daylight_spaces.delete(daylight_space)
1529
+ ##### Loop through the daylight_spaces and exclude the daylight_spaces that do not meet the criteria (see above) as per NECB2011: 4.2.2.4. and 4.2.2.8.
1530
+ daylight_spaces_exception.sort.each do |daylight_space_exception|
1531
+ daylight_spaces.sort.each do |daylight_space|
1532
+ if daylight_space.name.to_s == daylight_space_exception
1533
+ daylight_spaces.delete(daylight_space)
1534
+ end
1465
1535
  end
1466
1536
  end
1467
- end
1468
- # puts daylight_spaces
1537
+ # puts daylight_spaces
1538
+
1539
+ # elsif daylighting_type == 'add_daylighting_controls' # puts daylighting sensors in all spaces regardless of NECB requirements
1540
+
1541
+ end #if daylighting_type.nil? || daylighting_type == false || daylighting_type == 'none' || daylighting_type == 'NECB_Default'
1469
1542
 
1470
1543
  ##### Create one daylighting sensor and put it at the center of each daylight_space if the space area < 250m2;
1471
1544
  ##### otherwise, create two daylight sensors, divide the space into two parts and put each of the daylight sensors at the center of each part of the space.
@@ -1559,6 +1632,7 @@ class NECB2011 < Standard
1559
1632
 
1560
1633
  ##### Get the thermal zone of daylight_space (this is used later to assign daylighting sensor)
1561
1634
  zone = daylight_space.thermalZone
1635
+ # puts "zone name is #{zone}"
1562
1636
  if !zone.empty?
1563
1637
  zone = daylight_space.thermalZone.get
1564
1638
  ##### Get the floor of the daylight_space
@@ -1569,8 +1643,10 @@ class NECB2011 < Standard
1569
1643
  end
1570
1644
  end
1571
1645
 
1572
- ##### Get user's input for daylighting controls illuminance setpoint and number of stepped control steps
1573
- illuminance_setpoint, number_of_stepped_control_steps = daylighting_controls_settings(illuminance_setpoint: 500.0, number_of_stepped_control_steps: 2)
1646
+ ##### Set daylighting controls illuminance setpoint and number of stepped control steps
1647
+ number_of_stepped_control_steps = 2 ##### Note that the minimum number of stepped control steps is two steps as per NECB2011.
1648
+ illuminance_setpoint = daylight_spaces_target_illuminance_setpoint_hash.select {|key| key == daylight_space.name.to_s }
1649
+ illuminance_setpoint = illuminance_setpoint[daylight_space.name.to_s]
1574
1650
 
1575
1651
  ##### Create daylighting sensor control
1576
1652
  ##### NOTE: NECB2011 has some requirements on the number of sensors in spaces based on the area of the spaces.
@@ -1597,11 +1673,12 @@ class NECB2011 < Standard
1597
1673
  # if !zone.empty?
1598
1674
  end
1599
1675
  # daylight_spaces.each do |daylight_space|
1600
- end
1601
- end
1676
+ end # END if daylighting_controls_type.nil? || daylighting_controls_type == false || daylighting_controls_type == 'none' || daylighting_controls_type == 'NECB_Default'
1677
+
1678
+ end # END model_add_daylighting_controls(model:, daylighting_type:)
1602
1679
 
1603
1680
  ##### Define ScheduleTypeLimits for Any_Number_ppm
1604
- ##### TODO: (upon other BTAP tasks) This function can be added to btap/schedules.rb > module StandardScheduleTypeLimits
1681
+ ##### @todo (upon other BTAP tasks) This function can be added to btap/schedules.rb > module StandardScheduleTypeLimits
1605
1682
  def get_any_number_ppm(model)
1606
1683
  name = 'Any_Number_ppm'
1607
1684
  any_number_ppm_schedule_type_limits = model.getScheduleTypeLimitsByName(name)
@@ -1621,7 +1698,7 @@ class NECB2011 < Standard
1621
1698
  return if dcv_type == 'NECB_Defualt'
1622
1699
 
1623
1700
  if dcv_type == 'Occupancy_based_DCV' || dcv_type == 'CO2_based_DCV'
1624
- # TODO: IMPORTANT: (upon other BTAP tasks) Set a value for the "Outdoor Air Flow per Person" field of the "OS:DesignSpecification:OutdoorAir" object
1701
+ # @todo IMPORTANT: (upon other BTAP tasks) Set a value for the "Outdoor Air Flow per Person" field of the "OS:DesignSpecification:OutdoorAir" object
1625
1702
  # Note: The "Outdoor Air Flow per Person" field is required for occupancy-based DCV.
1626
1703
  # Note: The "Outdoor Air Flow per Person" values should be based on ASHRAE 62.1: Article 6.2.2.1.
1627
1704
  # Note: The "Outdoor Air Flow per Person" should be entered for "ventilation_per_person" in "lib/openstudio-standards/standards/necb/NECB2011/data/space_types.json"
@@ -1758,17 +1835,17 @@ class NECB2011 < Standard
1758
1835
 
1759
1836
  # ##### Since Atrium's LPD for LED lighting depends on atrium's height, the height of the atrium (if applicable) should be found.
1760
1837
  standards_space_type = space_type.standardsSpaceType.is_initialized ? space_type.standardsSpaceType.get : nil
1761
- if standards_space_type.include? 'Atrium' # TODO: Note that since none of the archetypes has Atrium, this was tested for 'Dining'. #Atrium
1838
+ if standards_space_type.include? 'Atrium' # @todo Note that since none of the archetypes has Atrium, this was tested for 'Dining'. #Atrium
1762
1839
  puts "#{standards_space_type} - has atrium" # space_type.name.to_s
1763
1840
  # Get the max height for the spacetype.
1764
1841
  max_space_height_for_spacetype = get_max_space_height_for_space_type(space_type: space_type)
1765
- if max_space_height_for_spacetype < 12.0 # TODO: Note that since none of the archetypes has Atrium, this was tested for 'Dining' with the threshold of 5.0 m for space_height.
1766
- # TODO: Regarding the below equations, identify which version of ASHRAE 90.1 was used in NECB2015.
1842
+ if max_space_height_for_spacetype < 12.0 # @todo Note that since none of the archetypes has Atrium, this was tested for 'Dining' with the threshold of 5.0 m for space_height.
1843
+ # @todo Regarding the below equations, identify which version of ASHRAE 90.1 was used in NECB2015.
1767
1844
  atrium_lpd_eq_smaller_12_intercept = 0
1768
1845
  atrium_lpd_eq_smaller_12_slope = 1.06
1769
1846
  atrium_lpd_eq_larger_12_intercept = 4.3
1770
1847
  atrium_lpd_eq_larger_12_slope = 1.06
1771
- lighting_per_area_led_lighting_atrium = (atrium_lpd_eq_smaller_12_intercept + atrium_lpd_eq_smaller_12_slope * 12.0) * 0.092903 # W/ft2 TODO: Note that for NECB2011, a constant LPD is used for atrium based on NECB2015's equations. NECB2011's threshold for height is 13.0 m.
1848
+ lighting_per_area_led_lighting_atrium = (atrium_lpd_eq_smaller_12_intercept + atrium_lpd_eq_smaller_12_slope * 12.0) * 0.092903 # W/ft2 @todo Note that for NECB2011, a constant LPD is used for atrium based on NECB2015's equations. NECB2011's threshold for height is 13.0 m.
1772
1849
  elsif max_space_height_for_spacetype >= 12.0 && max_space_height_for_spacetype < 13.0
1773
1850
  lighting_per_area_led_lighting_atrium = (atrium_lpd_eq_larger_12_intercept + atrium_lpd_eq_larger_12_slope * 12.5) * 0.092903 # W/ft2
1774
1851
  else # i.e. space_height >= 13.0
@@ -1790,7 +1867,7 @@ class NECB2011 < Standard
1790
1867
  # Some loads are governed by the standard, others are typical values
1791
1868
  # pulled from sources such as the DOE Reference and DOE Prototype Buildings.
1792
1869
  #
1793
- # @return [Bool] returns true if successful, false if not
1870
+ # @return [Boolean] returns true if successful, false if not
1794
1871
  def model_add_loads(model, lights_type, lights_scale)
1795
1872
  OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started applying space types (loads)')
1796
1873
 
@@ -2128,4 +2205,125 @@ class NECB2011 < Standard
2128
2205
  return model
2129
2206
  end
2130
2207
 
2208
+ # This method handles looking for the epw_file in the https://github.com/canmet-energy/btap_weather repository. It
2209
+ # checks for the epw_file in the historical data first. If it is not there then it looks in the future weather data.
2210
+ # If it is not there either, it throws an error.
2211
+ # epw_file (String): The name of the epw file. The different weather files all share the same name as the epw file,
2212
+ # only the extension changes.
2213
+ def get_weather_file_from_repo(epw_file:)
2214
+ # Get just the weather file name without the extension
2215
+ weather_loc = epw_file[0..-5]
2216
+ # Get the url of the file containing the historical weather data file names in the repository and the repository
2217
+ # folder containing the files
2218
+ historic_weather_files_loc = @standards_data['constants']['historic_weather_file_list']['value'].to_s
2219
+ historic_git_folder = @standards_data['constants']['historic_weather_folder_url']['value'].to_s
2220
+ # Get the files from the repository
2221
+ success_flag = download_and_save_file(weather_list_url: historic_weather_files_loc, weather_loc: weather_loc, git_folder: historic_git_folder)
2222
+ return if success_flag == true
2223
+ # If the file could not be found in the historical data look for it with the future weather data.
2224
+ puts "Could not find #{epw_file} in historical weather data files, looking in future weather data files."
2225
+ future_weather_files_loc = @standards_data['constants']['future_weather_file_list']['value'].to_s
2226
+ future_git_folder = @standards_data['constants']['future_weather_folder_url']['value'].to_s
2227
+ success_flag = download_and_save_file(weather_list_url: future_weather_files_loc, weather_loc: weather_loc, git_folder: future_git_folder)
2228
+ if success_flag == true
2229
+ # Rename the non-ASHRAE.ddy as '_non_ASHRAE.ddy' and save the '_ASHRAE.ddy' as the regular '.ddy' file. This is
2230
+ # because the ASHRAE .ddy file includes sizing information not included in the regular .ddy file for future
2231
+ # weather data files. Unfortunately, openstudio-standards just looks for the regular .ddy file for sizing
2232
+ # information which is why the switch is done.
2233
+ puts "Renaming #{weather_loc}.ddy as #{weather_loc}_orig.ddy and #{weather_loc}_ASHRAE.ddy as #{weather_loc}.ddy."
2234
+ puts "This is so that the design weather information in the #{weather_loc}_ASHRAE.ddy file is used."
2235
+ weather_dir = File.absolute_path(File.join(__FILE__, '..', '..', '..', '..', '..' , '..', "data/weather"))
2236
+ orig_ddy_name = File.join(weather_dir, (weather_loc + ".ddy"))
2237
+ ashrae_ddy_name = File.join(weather_dir, (weather_loc + "_ASHRAE.ddy"))
2238
+ rev_ddy_name = File.join(weather_dir, (weather_loc + "_orig.ddy"))
2239
+ FileUtils.cp(orig_ddy_name, rev_ddy_name)
2240
+ FileUtils.cp(ashrae_ddy_name, orig_ddy_name)
2241
+ return
2242
+ end
2243
+ raise("Could not locate the following file in the canmet/btap_weather repository: #{epw_file}. Please check the spelling of the file or visit https://github.com/canmet-energy/btap_weather to see if the file exists.")
2244
+ end
2245
+
2246
+ # This method actually looks for and downloads the zip file from the https://github.com/canmet-energy/btap_weather
2247
+ # repository. The repository contains json files containing the names of all of the weather data zip files of a given
2248
+ # type (either historic weather files or future weather files). This json is checked first to make sure that the file
2249
+ # is in the repository. If it is, the method downloads the zip file and extracts the data all to the
2250
+ # openstudio-standards weather file folder.
2251
+
2252
+ # Arguments:
2253
+ # weather_list_url (string): the web address of the json file containing the list of weather files on the repository
2254
+ # weather_loc (string): the name of the epw file we are looking for without the .epw extension
2255
+ # git_folder (string): the url of the folder containing the weather files. As of 2023-07-07 this this is either the
2256
+ # url of the historical weather data folder or the future weather data folder.
2257
+ def download_and_save_file(weather_list_url:, weather_loc:, git_folder:)
2258
+ status = false
2259
+ attempt = 1
2260
+ # Try to download the list of weather files 5 times, waiting 5 seconds between each attempt.
2261
+ until attempt > 5
2262
+ begin
2263
+ puts "Beginning attempt #{attempt} to download #{weather_list_url}"
2264
+ # Download the list of weather files on the repository
2265
+ URI.open(weather_list_url) do |web_data|
2266
+ # Convert the weather file list to an array
2267
+ if web_data.size <= 100
2268
+ raise("Could not read #{weather_list_url}!")
2269
+ end
2270
+ weather_files = (JSON.parse(web_data.read)).to_a
2271
+ # Check to see if the requested weather file is on the list
2272
+ zip_name = weather_files.find{ |weather_file| weather_file.match(weather_loc) }
2273
+ # If the weather file is on the list proceed, otherwise report that it could not be found
2274
+ unless zip_name.nil?
2275
+ # Found the weather file on the list
2276
+ status = true
2277
+ # Define the full url of the weather zip file we want to download
2278
+ save_file_url = git_folder + zip_name
2279
+ # Define the local location of where the weather zip file will be saved
2280
+ weather_dir = File.absolute_path(File.join(__FILE__, '..', '..', '..', '..', '..' , '..', "data/weather"))
2281
+ save_file = File.join(weather_dir, zip_name)
2282
+ attemptb = 1
2283
+ # Try to download the weather file up to 5 times, waiting 5 seconds between each attempt.
2284
+ until attemptb > 5
2285
+ begin
2286
+ puts "Beginning attempt #{attemptb} to download #{save_file_url}"
2287
+ # Download the weather zip file from the repository
2288
+ URI.open(save_file_url) do |file_url|
2289
+ if file_url.size <= 100
2290
+ raise("Could not read #{save_file_url}!")
2291
+ end
2292
+ # Save the zip file in the /data/weather folder
2293
+ File.open(save_file, 'wb') { |f| f.write(file_url.read) }
2294
+ puts "Downloaded #{save_file_url} to #{save_file}"
2295
+ # Extract the individual weother files from the zip file
2296
+ Zip::File.open(save_file) do |zip_file|
2297
+ puts "Expanding #{save_file}"
2298
+ # Cycle through each file in the zip file
2299
+ zip_file.each do |entry|
2300
+ # Define the location of where the file will be saved locally
2301
+ curr_save_file = File.join(weather_dir, entry.name.to_s)
2302
+ puts "Extracting #{entry.name} to #{curr_save_file}"
2303
+ # entry.extract # This was required before but now it isn't. I'm confused so am saving this comment to
2304
+ # remind me if there are ploblems later
2305
+ # Read the data from the file
2306
+ content = entry.get_input_stream.read
2307
+ # Save the data locally
2308
+ File.open(curr_save_file, 'wb') { |save_f| save_f.write(content) }
2309
+ end
2310
+ end
2311
+ end
2312
+ attemptb = 10
2313
+ rescue
2314
+ sleep(30)
2315
+ attemptb += 1
2316
+ end
2317
+ end
2318
+ end
2319
+ end
2320
+ attempt = 10
2321
+ rescue
2322
+ sleep(30)
2323
+ attempt += 1
2324
+ end
2325
+ end
2326
+ return status
2327
+ end
2328
+
2131
2329
  end