openstudio-standards 0.2.12.rc4 → 0.2.13.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (541) hide show
  1. checksums.yaml +4 -4
  2. data/data/geometry/ASHRAE90120162019HighriseApartment.json +1042 -0
  3. data/data/geometry/ASHRAE90120162019Hospital.json +199 -0
  4. data/data/geometry/ASHRAE90120162019LargeHotel.json +73 -0
  5. data/data/geometry/ASHRAE90120162019LargeOffice.json +109 -0
  6. data/data/geometry/ASHRAE90120162019SecondarySchool.json +205 -0
  7. data/data/geometry/ASHRAECourthouse.json +112 -0
  8. data/data/geometry/ASHRAECourthouse.osm +26470 -0
  9. data/data/geometry/ASHRAELargeHotel.osm +11 -1
  10. data/data/geometry/ASHRAELargeOffice.json +4 -0
  11. data/data/geometry/ASHRAESmallDataCenter.json +1 -1
  12. data/data/standards/OpenStudio_Standards-ashrae_90_1(space_types).xlsx +0 -0
  13. data/data/standards/OpenStudio_Standards-ashrae_90_1-ALL-comstock(space_types).xlsx +0 -0
  14. data/data/standards/OpenStudio_Standards-ashrae_90_1.xlsx +0 -0
  15. data/data/standards/exclude_list.csv +19 -0
  16. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.boilers.json +49 -0
  17. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.chillers.json +293 -0
  18. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.construction_properties.json +25426 -0
  19. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.construction_sets.json +1600 -0
  20. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.economizers.json +564 -0
  21. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.elevators.json +349 -0
  22. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.ext_ltg.json +164 -0
  23. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.ground_temperatures.json +10663 -0
  24. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.heat_pumps.json +508 -0
  25. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.heat_pumps_heating.json +156 -0
  26. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.heat_rejection.json +44 -0
  27. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.motors.json +184 -0
  28. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.prototype_inputs.json +3094 -0
  29. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.ref_cases.json +829 -0
  30. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.ref_lnup.json +562 -0
  31. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.refrigeration_compressors.json +52 -0
  32. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.refrigeration_condenser.json +220 -0
  33. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.refrigeration_system.json +156 -0
  34. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.refrigeration_walkins.json +1316 -0
  35. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.spc_typ.json +21446 -0
  36. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.unitary_acs.json +554 -0
  37. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.water_heaters.json +68 -0
  38. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.water_source_heat_pumps.json +28 -0
  39. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.water_source_heat_pumps_heating.json +12 -0
  40. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.boilers.json +49 -0
  41. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.chillers.json +293 -0
  42. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.construction_properties.json +12487 -0
  43. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.construction_sets.json +1600 -0
  44. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.economizers.json +564 -0
  45. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.elevators.json +349 -0
  46. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.ext_ltg.json +164 -0
  47. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.ground_temperatures.json +10663 -0
  48. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.heat_pumps.json +466 -0
  49. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.heat_pumps_heating.json +137 -0
  50. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.heat_rejection.json +44 -0
  51. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.motors.json +184 -0
  52. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.prototype_inputs.json +3094 -0
  53. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.ref_cases.json +829 -0
  54. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.ref_lnup.json +562 -0
  55. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.refrigeration_compressors.json +52 -0
  56. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.refrigeration_condenser.json +220 -0
  57. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.refrigeration_system.json +156 -0
  58. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.refrigeration_walkins.json +1316 -0
  59. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.spc_typ.json +21380 -0
  60. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.unitary_acs.json +554 -0
  61. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.water_heaters.json +68 -0
  62. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.water_source_heat_pumps.json +28 -0
  63. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.water_source_heat_pumps_heating.json +12 -0
  64. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.boilers.json +49 -0
  65. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.chillers.json +395 -0
  66. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.construction_properties.json +12487 -0
  67. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.construction_sets.json +1600 -0
  68. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.economizers.json +592 -0
  69. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.elevators.json +349 -0
  70. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.energy_recovery.json +550 -0
  71. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.ext_ltg.json +164 -0
  72. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.ground_temperatures.json +10663 -0
  73. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.heat_pumps.json +466 -0
  74. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.heat_pumps_heating.json +137 -0
  75. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.heat_rejection.json +44 -0
  76. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.motors.json +238 -0
  77. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.prototype_inputs.json +3094 -0
  78. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.ref_cases.json +829 -0
  79. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.ref_lnup.json +562 -0
  80. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.refrigeration_compressors.json +52 -0
  81. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.refrigeration_condenser.json +220 -0
  82. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.refrigeration_system.json +156 -0
  83. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.refrigeration_walkins.json +1316 -0
  84. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.spc_typ.json +21548 -0
  85. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.unitary_acs.json +554 -0
  86. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.water_heaters.json +68 -0
  87. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.water_source_heat_pumps.json +28 -0
  88. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.water_source_heat_pumps_heating.json +12 -0
  89. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.boilers.json +64 -0
  90. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.chillers.json +871 -0
  91. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.construction_properties.json +12487 -0
  92. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.construction_sets.json +1600 -0
  93. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.economizers.json +592 -0
  94. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.elevators.json +349 -0
  95. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.energy_recovery.json +1096 -0
  96. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.ext_ltg.json +164 -0
  97. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.ground_temperatures.json +10663 -0
  98. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.heat_pumps.json +886 -0
  99. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.heat_pumps_heating.json +194 -0
  100. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.heat_rejection.json +44 -0
  101. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.motors.json +247 -0
  102. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.prototype_inputs.json +3094 -0
  103. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.ref_cases.json +829 -0
  104. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.ref_lnup.json +562 -0
  105. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.refrigeration_compressors.json +52 -0
  106. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.refrigeration_condenser.json +220 -0
  107. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.refrigeration_system.json +156 -0
  108. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.refrigeration_walkins.json +1316 -0
  109. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.spc_typ.json +22079 -0
  110. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.unitary_acs.json +994 -0
  111. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.water_heaters.json +68 -0
  112. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.water_source_heat_pumps.json +28 -0
  113. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.water_source_heat_pumps_heating.json +12 -0
  114. data/data/standards/manage_OpenStudio_Standards.rb +87 -37
  115. data/data/standards/metadata_units_OpenStudio_Standards-ashrae_90_1-ALL-comstockspace_types.csv +236 -0
  116. data/data/standards/metadata_units_OpenStudio_Standards-ashrae_90_1.csv +622 -0
  117. data/data/standards/metadata_units_OpenStudio_Standards-ashrae_90_1space_types.csv +191 -0
  118. data/data/standards/openstudio_standards_duplicates_log.csv +17 -0
  119. data/data/standards/test_performance_expected_dd_results.csv +1971 -1171
  120. data/lib/openstudio-standards.rb +76 -18
  121. data/lib/openstudio-standards/btap/btap.model.rb +1 -1
  122. data/lib/openstudio-standards/btap/economics.rb +14 -11
  123. data/lib/openstudio-standards/btap/envelope.rb +185 -257
  124. data/lib/openstudio-standards/btap/fileio.rb +1 -0
  125. data/lib/openstudio-standards/btap/geometry.rb +21 -1
  126. data/lib/openstudio-standards/btap/measures.rb +12 -11
  127. data/lib/openstudio-standards/btap/schedules.rb +3 -12
  128. data/lib/openstudio-standards/hvac_sizing/Siz.AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed.rb +178 -0
  129. data/lib/openstudio-standards/hvac_sizing/Siz.CoilCoolingDXMultiSpeed.rb +8 -8
  130. data/lib/openstudio-standards/hvac_sizing/Siz.Model.rb +3 -0
  131. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.PumpVariableSpeed.rb +28 -0
  132. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.FanVariableVolume.rb +0 -1
  133. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.PumpVariableSpeed.rb +28 -0
  134. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.Model.rb +53 -2
  135. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.PumpVariableSpeed.rb +29 -0
  136. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.Model.rb +157 -2
  137. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.PumpVariableSpeed.rb +29 -0
  138. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirTerminalSingleDuctVAVReheat.rb +24 -0
  139. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.FanConstantVolume.rb +32 -0
  140. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.FanOnOff.rb +33 -0
  141. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.FanVariableVolume.rb +32 -0
  142. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Model.elevators.rb +25 -0
  143. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Model.rb +366 -0
  144. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.PumpVariableSpeed.rb +144 -0
  145. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.hvac_systems.rb +11 -0
  146. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirTerminalSingleDuctVAVReheat.rb +24 -0
  147. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.FanConstantVolume.rb +32 -0
  148. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.FanOnOff.rb +33 -0
  149. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.FanVariableVolume.rb +32 -0
  150. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Model.elevators.rb +25 -0
  151. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Model.rb +367 -0
  152. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.PumpVariableSpeed.rb +144 -0
  153. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.hvac_systems.rb +11 -0
  154. data/lib/openstudio-standards/prototypes/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.AirTerminalSingleDuctVAVReheat.rb +0 -1
  155. data/lib/openstudio-standards/prototypes/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.AirTerminalSingleDuctVAVReheat.rb +0 -1
  156. data/lib/openstudio-standards/prototypes/ashrae_90_1/nrel_nze_ready_2017/nrel_zne_ready_2017.HeatExchangerAirToAirSensibleAndLatent.rb +1 -1
  157. data/lib/openstudio-standards/prototypes/ashrae_90_1/nrel_nze_ready_2017/nrel_zne_ready_2017.Model.rb +1 -1
  158. data/lib/openstudio-standards/prototypes/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.HeatExchangerAirToAirSensibleAndLatent.rb +1 -1
  159. data/lib/openstudio-standards/prototypes/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.Model.rb +1 -1
  160. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.College.rb +3 -3
  161. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Courthouse.rb +74 -0
  162. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.FullServiceRestaurant.rb +46 -30
  163. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.HighRiseApartment.rb +23 -8
  164. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Hospital.rb +26 -15
  165. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Laboratory.rb +8 -11
  166. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeDataCenterHighITE.rb +54 -60
  167. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeDataCenterLowITE.rb +56 -60
  168. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeHotel.rb +38 -12
  169. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeOffice.rb +218 -134
  170. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeOfficeDetailed.rb +6 -2
  171. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.MediumOffice.rb +230 -134
  172. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.MediumOfficeDetailed.rb +60 -62
  173. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.MidriseApartment.rb +25 -15
  174. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Outpatient.rb +34 -22
  175. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.PrimarySchool.rb +31 -7
  176. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.QuickServiceRestaurant.rb +43 -28
  177. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.RetailStandalone.rb +48 -38
  178. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.RetailStripmall.rb +9 -5
  179. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SecondarySchool.rb +575 -345
  180. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallDataCenterHighITE.rb +13 -19
  181. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallDataCenterLowITE.rb +13 -17
  182. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallHotel.rb +9 -5
  183. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallOffice.rb +79 -51
  184. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallOfficeDetailed.rb +60 -60
  185. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SuperMarket.rb +2 -4
  186. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SuperTallBuilding.rb +133 -120
  187. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.TallBuilding.rb +124 -112
  188. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Warehouse.rb +138 -66
  189. data/lib/openstudio-standards/prototypes/common/do_not_edit_metaclasses.rb +7275 -199
  190. data/lib/openstudio-standards/prototypes/common/objects/Prototype.AirConditionerVariableRefrigerantFlow.rb +35 -35
  191. data/lib/openstudio-standards/prototypes/common/objects/Prototype.BoilerHotWater.rb +2 -2
  192. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CentralAirSourceHeatPump.rb +2 -2
  193. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingDXSingleSpeed.rb +3 -3
  194. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingDXTwoSpeed.rb +1 -1
  195. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingWater.rb +2 -2
  196. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingWaterToAirHeatPumpEquationFit.rb +2 -2
  197. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingDXSingleSpeed.rb +1 -1
  198. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingElectric.rb +2 -2
  199. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingWater.rb +2 -2
  200. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingWaterToAirHeatPumpEquationFit.rb +2 -2
  201. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoolingTower.rb +1 -1
  202. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Fan.rb +4 -3
  203. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanConstantVolume.rb +7 -8
  204. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanOnOff.rb +7 -8
  205. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanVariableVolume.rb +13 -14
  206. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanZoneExhaust.rb +7 -5
  207. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.elevators.rb +4 -1
  208. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.exterior_lights.rb +0 -1
  209. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.hvac.rb +25 -14
  210. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.rb +474 -89
  211. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.swh.rb +35 -33
  212. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Pump.rb +3 -0
  213. data/lib/openstudio-standards/prototypes/common/objects/Prototype.PumpVariableSpeed.rb +72 -0
  214. data/lib/openstudio-standards/prototypes/common/objects/Prototype.ServiceWaterHeating.rb +120 -120
  215. data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +142 -154
  216. data/lib/openstudio-standards/prototypes/common/objects/Prototype.radiant_system_controls.rb +9 -3
  217. data/lib/openstudio-standards/prototypes/common/objects/Prototype.refrigeration.rb +11 -5
  218. data/lib/openstudio-standards/prototypes/common/objects/Prototype.utilities.rb +26 -14
  219. data/lib/openstudio-standards/prototypes/common/prototype_metaprogramming.rb +270 -247
  220. data/lib/openstudio-standards/prototypes/deer/deer.Model.rb +1 -1
  221. data/lib/openstudio-standards/refs/references.rb +5 -2
  222. data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +70 -51
  223. data/lib/openstudio-standards/standards/Standards.AirTerminalSingleDuctVAVReheat.rb +0 -1
  224. data/lib/openstudio-standards/standards/Standards.BoilerHotWater.rb +0 -1
  225. data/lib/openstudio-standards/standards/Standards.BuildingStory.rb +1 -0
  226. data/lib/openstudio-standards/standards/Standards.ChillerElectricEIR.rb +2 -4
  227. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXMultiSpeed.rb +91 -2
  228. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXSingleSpeed.rb +4 -5
  229. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXTwoSpeed.rb +0 -1
  230. data/lib/openstudio-standards/standards/Standards.CoilCoolingWaterToAirHeatPumpEquationFit.rb +1 -1
  231. data/lib/openstudio-standards/standards/Standards.CoilDX.rb +30 -9
  232. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXMultiSpeed.rb +2 -1
  233. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXSingleSpeed.rb +3 -1
  234. data/lib/openstudio-standards/standards/Standards.CoilHeatingGas.rb +0 -3
  235. data/lib/openstudio-standards/standards/Standards.CoilHeatingGasMultiStage.rb +37 -1
  236. data/lib/openstudio-standards/standards/Standards.CoilHeatingWaterToAirHeatPumpEquationFit.rb +1 -3
  237. data/lib/openstudio-standards/standards/Standards.Construction.rb +124 -118
  238. data/lib/openstudio-standards/standards/Standards.CoolingTower.rb +0 -1
  239. data/lib/openstudio-standards/standards/Standards.CoolingTowerSingleSpeed.rb +0 -1
  240. data/lib/openstudio-standards/standards/Standards.CoolingTowerTwoSpeed.rb +0 -1
  241. data/lib/openstudio-standards/standards/Standards.CoolingTowerVariableSpeed.rb +0 -1
  242. data/lib/openstudio-standards/standards/Standards.Fan.rb +0 -1
  243. data/lib/openstudio-standards/standards/Standards.FanConstantVolume.rb +0 -1
  244. data/lib/openstudio-standards/standards/Standards.FanOnOff.rb +0 -1
  245. data/lib/openstudio-standards/standards/Standards.FanVariableVolume.rb +2 -4
  246. data/lib/openstudio-standards/standards/Standards.FanZoneExhaust.rb +0 -1
  247. data/lib/openstudio-standards/standards/Standards.FluidCooler.rb +10 -3
  248. data/lib/openstudio-standards/standards/Standards.HeaderedPumpsConstantSpeed.rb +0 -1
  249. data/lib/openstudio-standards/standards/Standards.HeaderedPumpsVariableSpeed.rb +0 -1
  250. data/lib/openstudio-standards/standards/Standards.Model.rb +305 -247
  251. data/lib/openstudio-standards/standards/Standards.PlanarSurface.rb +2 -0
  252. data/lib/openstudio-standards/standards/Standards.PlantLoop.rb +11 -9
  253. data/lib/openstudio-standards/standards/Standards.Pump.rb +0 -1
  254. data/lib/openstudio-standards/standards/Standards.PumpConstantSpeed.rb +0 -1
  255. data/lib/openstudio-standards/standards/Standards.PumpVariableSpeed.rb +0 -1
  256. data/lib/openstudio-standards/standards/Standards.ScheduleCompact.rb +0 -1
  257. data/lib/openstudio-standards/standards/Standards.ScheduleConstant.rb +0 -1
  258. data/lib/openstudio-standards/standards/Standards.ScheduleRuleset.rb +103 -121
  259. data/lib/openstudio-standards/standards/Standards.Space.rb +42 -35
  260. data/lib/openstudio-standards/standards/Standards.SpaceType.rb +9 -17
  261. data/lib/openstudio-standards/standards/Standards.SubSurface.rb +25 -27
  262. data/lib/openstudio-standards/standards/Standards.Surface.rb +97 -52
  263. data/lib/openstudio-standards/standards/Standards.ThermalZone.rb +76 -25
  264. data/lib/openstudio-standards/standards/Standards.WaterHeaterMixed.rb +6 -7
  265. data/lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb +85 -7
  266. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1.Standards.FanVariableVolume.rb +0 -1
  267. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.AirLoopHVAC.rb +10 -2
  268. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.Model.rb +2 -2
  269. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/comstock_ashrae_90_1_2004/data/ashrae_90_1.schedules.json +63 -99
  270. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/comstock_ashrae_90_1_2004/data/comstock_ashrae_90_1_2004.ext_ltg.json +7 -7
  271. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.construction_properties.json +2420 -0
  272. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.economizers.json +32 -0
  273. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.heat_rejection.json +9 -0
  274. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.prototype_inputs.json +70 -40
  275. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.spc_typ.json +105 -40
  276. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.unitary_acs.json +15 -15
  277. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.AirLoopHVAC.rb +5 -1
  278. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/comstock_ashrae_90_1_2007/data/ashrae_90_1.schedules.json +63 -99
  279. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/comstock_ashrae_90_1_2007/data/comstock_ashrae_90_1_2007.ext_ltg.json +7 -7
  280. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.construction_properties.json +1460 -0
  281. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.economizers.json +32 -0
  282. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.heat_rejection.json +9 -0
  283. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.prototype_inputs.json +123 -39
  284. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.spc_typ.json +104 -17
  285. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.unitary_acs.json +15 -15
  286. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.AirLoopHVAC.rb +32 -15
  287. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.Space.rb +1 -1
  288. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/comstock_ashrae_90_1_2010/data/ashrae_90_1.schedules.json +63 -99
  289. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/comstock_ashrae_90_1_2010/data/comstock_ashrae_90_1_2010.ext_ltg.json +7 -7
  290. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.construction_properties.json +1460 -0
  291. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.economizers.json +64 -0
  292. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.energy_recovery.json +52 -0
  293. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.heat_rejection.json +9 -0
  294. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.prototype_inputs.json +123 -39
  295. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.spc_typ.json +112 -25
  296. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.unitary_acs.json +5 -5
  297. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.AirLoopHVAC.rb +37 -14
  298. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.WaterHeaterMixed.rb +1 -1
  299. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/comstock_ashrae_90_1_2013/data/ashrae_90_1.schedules.json +63 -99
  300. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/comstock_ashrae_90_1_2013/data/comstock_ashrae_90_1_2013.ext_ltg.json +7 -7
  301. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.boilers.json +1 -1
  302. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.chillers.json +2 -2
  303. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.construction_properties.json +1460 -0
  304. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.economizers.json +64 -0
  305. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.energy_recovery.json +104 -0
  306. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.heat_rejection.json +9 -0
  307. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.prototype_inputs.json +125 -41
  308. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.spc_typ.json +172 -55
  309. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.unitary_acs.json +15 -15
  310. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.water_heaters.json +4 -4
  311. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.water_source_heat_pumps_heating.json +1 -1
  312. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirLoopHVAC.rb +456 -0
  313. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirTerminalSingleDuctVAVReheat.rb +24 -0
  314. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.CoolingTower.rb +19 -0
  315. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.CoolingTowerSingleSpeed.rb +5 -0
  316. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.CoolingTowerTwoSpeed.rb +5 -0
  317. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.CoolingTowerVariableSpeed.rb +16 -0
  318. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.FanVariableVolume.rb +37 -0
  319. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Space.rb +189 -0
  320. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.ThermalZone.rb +57 -0
  321. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.ZoneHVACComponent.rb +22 -0
  322. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.rb +16 -0
  323. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.boilers.json +68 -0
  324. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.chillers.json +490 -0
  325. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.construction_properties.json +21244 -0
  326. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.construction_sets.json +2111 -0
  327. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.economizers.json +676 -0
  328. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.elevators.json +372 -0
  329. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.energy_recovery.json +1096 -0
  330. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.ext_ltg.json +169 -0
  331. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.heat_pumps.json +532 -0
  332. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.heat_pumps_heating.json +164 -0
  333. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.heat_rejection.json +49 -0
  334. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.motors.json +274 -0
  335. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.prototype_inputs.json +3094 -0
  336. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.ref_cases.json +854 -0
  337. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.ref_lnup.json +562 -0
  338. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.refrigeration_compressors.json +58 -0
  339. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.refrigeration_condenser.json +238 -0
  340. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.refrigeration_system.json +12 -0
  341. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.refrigeration_walkins.json +1316 -0
  342. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.spc_typ.json +23067 -0
  343. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.unitary_acs.json +648 -0
  344. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.water_heaters.json +72 -0
  345. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.water_source_heat_pumps.json +31 -0
  346. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.water_source_heat_pumps_heating.json +13 -0
  347. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +456 -0
  348. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirTerminalSingleDuctVAVReheat.rb +24 -0
  349. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.CoolingTower.rb +19 -0
  350. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.CoolingTowerSingleSpeed.rb +5 -0
  351. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.CoolingTowerTwoSpeed.rb +5 -0
  352. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.CoolingTowerVariableSpeed.rb +16 -0
  353. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.FanVariableVolume.rb +37 -0
  354. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Space.rb +189 -0
  355. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.ThermalZone.rb +57 -0
  356. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.ZoneHVACComponent.rb +22 -0
  357. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.rb +16 -0
  358. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.boilers.json +68 -0
  359. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.chillers.json +490 -0
  360. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.construction_properties.json +21244 -0
  361. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.construction_sets.json +2111 -0
  362. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.economizers.json +676 -0
  363. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.elevators.json +372 -0
  364. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.energy_recovery.json +1096 -0
  365. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.ext_ltg.json +169 -0
  366. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.heat_pumps.json +664 -0
  367. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.heat_pumps_heating.json +204 -0
  368. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.heat_rejection.json +49 -0
  369. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.motors.json +274 -0
  370. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.prototype_inputs.json +3094 -0
  371. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.ref_cases.json +854 -0
  372. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.ref_lnup.json +562 -0
  373. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.refrigeration_compressors.json +58 -0
  374. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.refrigeration_condenser.json +238 -0
  375. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.refrigeration_system.json +12 -0
  376. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.refrigeration_walkins.json +1316 -0
  377. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.spc_typ.json +23067 -0
  378. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.unitary_acs.json +671 -0
  379. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.water_heaters.json +72 -0
  380. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.water_source_heat_pumps.json +31 -0
  381. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.water_source_heat_pumps_heating.json +13 -0
  382. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.constructions.json +1662 -332
  383. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.fans.json +1 -1
  384. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.materials.json +4994 -234
  385. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.schedules.json +1743 -161
  386. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/comstock_doe_ref_1980_2004/data/ashrae_90_1.schedules.json +63 -99
  387. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/comstock_doe_ref_1980_2004/data/comstock_doe_ref_1980_2004.ext_ltg.json +11 -11
  388. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.heat_rejection.json +9 -0
  389. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.prototype_inputs.json +8 -8
  390. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.spc_typ.json +5967 -2727
  391. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.Model.rb +4 -4
  392. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/comstock_doe_ref_pre_1980/data/ashrae_90_1.schedules.json +63 -99
  393. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/comstock_doe_ref_pre_1980/data/comstock_doe_ref_pre_1980.ext_ltg.json +10 -10
  394. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.heat_rejection.json +9 -0
  395. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.prototype_inputs.json +7 -7
  396. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.spc_typ.json +5920 -2700
  397. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.Model.rb +4 -4
  398. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.heat_rejection.json +9 -0
  399. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.spc_typ.json +2011 -1112
  400. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.AirLoopHVAC.rb +0 -1
  401. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.Model.rb +4 -4
  402. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.PlantLoop.rb +1 -1
  403. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.ZoneHVACComponent.rb +1 -1
  404. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/data/ze_aedg_multifamily.heat_rejection.json +9 -0
  405. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/data/ze_aedg_multifamily.spc_typ.json +1946 -1106
  406. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/data/ze_aedg_multifamily.water_heaters.json +2 -2
  407. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.AirLoopHVAC.rb +3 -6
  408. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.Model.rb +4 -4
  409. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.PlantLoop.rb +1 -1
  410. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.ZoneHVACComponent.rb +1 -1
  411. data/lib/openstudio-standards/standards/cbes/cbes.Model.rb +1 -3
  412. data/lib/openstudio-standards/standards/cbes/cbes.rb +1 -1
  413. data/lib/openstudio-standards/standards/deer/deer.AirLoopHVAC.rb +8 -13
  414. data/lib/openstudio-standards/standards/deer/deer.Model.rb +2 -2
  415. data/lib/openstudio-standards/standards/deer/deer.PlanarSurface.rb +2 -0
  416. data/lib/openstudio-standards/standards/deer/deer.Space.rb +1 -1
  417. data/lib/openstudio-standards/standards/deer/deer_2011/deer_2011.rb +0 -1
  418. data/lib/openstudio-standards/standards/deer/deer_2014/deer_2014.Space.rb +0 -1
  419. data/lib/openstudio-standards/standards/deer/deer_2014/deer_2014.rb +0 -1
  420. data/lib/openstudio-standards/standards/deer/deer_2015/deer_2015.Space.rb +0 -1
  421. data/lib/openstudio-standards/standards/deer/deer_2017/deer_2017.Space.rb +0 -1
  422. data/lib/openstudio-standards/standards/deer/deer_2020/deer_2020.AirLoopHVAC.rb +1 -1
  423. data/lib/openstudio-standards/standards/deer/deer_2020/deer_2020.FanVariableVolume.rb +1 -1
  424. data/lib/openstudio-standards/standards/deer/deer_2020/deer_2020.Space.rb +0 -1
  425. data/lib/openstudio-standards/standards/deer/deer_2025/deer_2025.AirLoopHVAC.rb +1 -1
  426. data/lib/openstudio-standards/standards/deer/deer_2025/deer_2025.FanVariableVolume.rb +1 -1
  427. data/lib/openstudio-standards/standards/deer/deer_2025/deer_2025.Space.rb +0 -1
  428. data/lib/openstudio-standards/standards/deer/deer_2030/deer_2030.AirLoopHVAC.rb +1 -1
  429. data/lib/openstudio-standards/standards/deer/deer_2030/deer_2030.FanVariableVolume.rb +1 -1
  430. data/lib/openstudio-standards/standards/deer/deer_2030/deer_2030.Space.rb +0 -1
  431. data/lib/openstudio-standards/standards/deer/deer_2035/deer_2035.AirLoopHVAC.rb +1 -1
  432. data/lib/openstudio-standards/standards/deer/deer_2035/deer_2035.FanVariableVolume.rb +1 -1
  433. data/lib/openstudio-standards/standards/deer/deer_2035/deer_2035.Space.rb +0 -1
  434. data/lib/openstudio-standards/standards/deer/deer_2040/deer_2040.AirLoopHVAC.rb +1 -1
  435. data/lib/openstudio-standards/standards/deer/deer_2040/deer_2040.FanVariableVolume.rb +1 -1
  436. data/lib/openstudio-standards/standards/deer/deer_2040/deer_2040.Space.rb +0 -1
  437. data/lib/openstudio-standards/standards/deer/deer_2045/deer_2045.AirLoopHVAC.rb +1 -1
  438. data/lib/openstudio-standards/standards/deer/deer_2045/deer_2045.FanVariableVolume.rb +1 -1
  439. data/lib/openstudio-standards/standards/deer/deer_2045/deer_2045.Space.rb +0 -1
  440. data/lib/openstudio-standards/standards/deer/deer_2050/deer_2050.AirLoopHVAC.rb +1 -1
  441. data/lib/openstudio-standards/standards/deer/deer_2050/deer_2050.FanVariableVolume.rb +1 -1
  442. data/lib/openstudio-standards/standards/deer/deer_2050/deer_2050.Space.rb +0 -1
  443. data/lib/openstudio-standards/standards/deer/deer_2055/deer_2055.AirLoopHVAC.rb +1 -1
  444. data/lib/openstudio-standards/standards/deer/deer_2055/deer_2055.FanVariableVolume.rb +1 -1
  445. data/lib/openstudio-standards/standards/deer/deer_2055/deer_2055.Space.rb +0 -1
  446. data/lib/openstudio-standards/standards/deer/deer_2060/deer_2060.AirLoopHVAC.rb +1 -1
  447. data/lib/openstudio-standards/standards/deer/deer_2060/deer_2060.FanVariableVolume.rb +1 -1
  448. data/lib/openstudio-standards/standards/deer/deer_2060/deer_2060.Space.rb +0 -1
  449. data/lib/openstudio-standards/standards/deer/deer_2065/deer_2065.AirLoopHVAC.rb +1 -1
  450. data/lib/openstudio-standards/standards/deer/deer_2065/deer_2065.FanVariableVolume.rb +1 -1
  451. data/lib/openstudio-standards/standards/deer/deer_2065/deer_2065.Space.rb +0 -1
  452. data/lib/openstudio-standards/standards/deer/deer_2070/deer_2070.AirLoopHVAC.rb +1 -1
  453. data/lib/openstudio-standards/standards/deer/deer_2070/deer_2070.FanVariableVolume.rb +1 -1
  454. data/lib/openstudio-standards/standards/deer/deer_2070/deer_2070.Space.rb +0 -1
  455. data/lib/openstudio-standards/standards/deer/deer_2075/deer_2075.AirLoopHVAC.rb +1 -1
  456. data/lib/openstudio-standards/standards/deer/deer_2075/deer_2075.FanVariableVolume.rb +1 -1
  457. data/lib/openstudio-standards/standards/deer/deer_2075/deer_2075.Space.rb +0 -1
  458. data/lib/openstudio-standards/standards/icc_iecc/icc_iecc_2015/icc_iecc_2015.rb +0 -1
  459. data/lib/openstudio-standards/standards/necb/BTAP1980TO2010/btap_1980to2010.rb +2 -18
  460. data/lib/openstudio-standards/standards/necb/BTAP1980TO2010/data/space_types.json +1677 -1005
  461. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/btap_pre1980.rb +87 -15
  462. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/building_envelope.rb +31 -19
  463. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/data/curves.json +75 -0
  464. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/data/heat_pumps.json +16 -16
  465. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/data/space_types.json +1677 -1005
  466. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_3_and_8_single_speed.rb +16 -2
  467. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_4.rb +15 -0
  468. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_6.rb +14 -0
  469. data/lib/openstudio-standards/standards/necb/ECMS/data/boiler_set.json +29 -0
  470. data/lib/openstudio-standards/standards/necb/ECMS/data/curves.json +913 -0
  471. data/lib/openstudio-standards/standards/necb/ECMS/data/equip_eff_lim.json +52 -0
  472. data/lib/openstudio-standards/standards/necb/ECMS/data/erv.json +109 -0
  473. data/lib/openstudio-standards/standards/necb/ECMS/data/furnace_set.json +23 -0
  474. data/lib/openstudio-standards/standards/necb/ECMS/data/heat_pumps.json +803 -0
  475. data/lib/openstudio-standards/standards/necb/ECMS/data/heat_pumps_heating.json +787 -0
  476. data/lib/openstudio-standards/standards/necb/ECMS/data/pv.json +112 -0
  477. data/lib/openstudio-standards/standards/necb/ECMS/data/shw_set.json +29 -0
  478. data/lib/openstudio-standards/standards/necb/ECMS/data/unitary_acs.json +50 -0
  479. data/lib/openstudio-standards/standards/necb/ECMS/ecms.rb +100 -0
  480. data/lib/openstudio-standards/standards/necb/ECMS/erv.rb +33 -0
  481. data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +1729 -0
  482. data/lib/openstudio-standards/standards/necb/ECMS/nv.rb +189 -0
  483. data/lib/openstudio-standards/standards/necb/ECMS/pv_ground.rb +104 -0
  484. data/lib/openstudio-standards/standards/necb/NECB2011/autozone.rb +68 -33
  485. data/lib/openstudio-standards/standards/necb/NECB2011/beps_compliance_path.rb +24 -13
  486. data/lib/openstudio-standards/standards/necb/NECB2011/building_envelope.rb +110 -99
  487. data/lib/openstudio-standards/standards/necb/NECB2011/data/constants.json +24 -24
  488. data/lib/openstudio-standards/standards/necb/NECB2011/data/curves.json +50 -0
  489. data/lib/openstudio-standards/standards/necb/NECB2011/data/erv.json +31 -0
  490. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LowriseApartment.osm +39278 -0
  491. data/lib/openstudio-standards/standards/necb/NECB2011/data/led_lighting_data.json +2028 -0
  492. data/lib/openstudio-standards/standards/necb/NECB2011/data/space_types.json +1745 -1297
  493. data/lib/openstudio-standards/standards/necb/NECB2011/daylighting_control.md +70 -0
  494. data/lib/openstudio-standards/standards/necb/NECB2011/demand_controlled_ventilation.md +46 -0
  495. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_1_multi_speed.rb +69 -107
  496. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_1_single_speed.rb +41 -2
  497. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_2_and_5.rb +15 -0
  498. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_multi_speed.rb +139 -141
  499. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_single_speed.rb +38 -2
  500. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_4.rb +13 -0
  501. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_6.rb +12 -0
  502. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +492 -240
  503. data/lib/openstudio-standards/standards/necb/NECB2011/led_lighting.md +51 -0
  504. data/lib/openstudio-standards/standards/necb/NECB2011/lighting.rb +75 -9
  505. data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +1229 -37
  506. data/lib/openstudio-standards/standards/necb/NECB2011/nv.md +74 -0
  507. data/lib/openstudio-standards/standards/necb/NECB2011/pv_ground.md +44 -0
  508. data/lib/openstudio-standards/standards/necb/NECB2011/qaqc/necb_qaqc.rb +11 -3
  509. data/lib/openstudio-standards/standards/necb/NECB2011/qaqc/qaqc_resources/neb_end_use_prices.csv +39 -84
  510. data/lib/openstudio-standards/standards/necb/NECB2011/service_water_heating.rb +1 -1
  511. data/lib/openstudio-standards/standards/necb/NECB2015/data/led_lighting_data.json +2883 -0
  512. data/lib/openstudio-standards/standards/necb/NECB2015/data/space_types.json +2554 -1916
  513. data/lib/openstudio-standards/standards/necb/NECB2015/necb_2015.rb +32 -1
  514. data/lib/openstudio-standards/standards/necb/NECB2017/data/led_lighting_data.json +2883 -0
  515. data/lib/openstudio-standards/standards/necb/NECB2017/data/space_types.json +2554 -1916
  516. data/lib/openstudio-standards/standards/necb/NECB2017/necb_2017.rb +29 -0
  517. data/lib/openstudio-standards/standards/oeesc/oeesc_2014/oeesc_2014.rb +0 -1
  518. data/lib/openstudio-standards/standards/standard.rb +6 -5
  519. data/lib/openstudio-standards/utilities/Add_template_field_to_json.rb +3 -3
  520. data/lib/openstudio-standards/utilities/convert_surfaces_to_adiabatic_necb_8426.rb +54 -54
  521. data/lib/openstudio-standards/utilities/generate_prototype_database.rb +2 -2
  522. data/lib/openstudio-standards/utilities/generate_space_types.rb +3 -3
  523. data/lib/openstudio-standards/utilities/logging.rb +7 -7
  524. data/lib/openstudio-standards/utilities/necb_to_epw_map.rb +14 -14
  525. data/lib/openstudio-standards/utilities/os_sim_extract.rb +25 -25
  526. data/lib/openstudio-standards/utilities/rename_surfaces.rb +10 -13
  527. data/lib/openstudio-standards/utilities/round_surf_coords.rb +18 -20
  528. data/lib/openstudio-standards/utilities/sched_create.rb +39 -41
  529. data/lib/openstudio-standards/utilities/set_mult_to_adiabatic.rb +31 -31
  530. data/lib/openstudio-standards/utilities/simulation.rb +13 -21
  531. data/lib/openstudio-standards/utilities/speacetype_map_converter.rb +10 -11
  532. data/lib/openstudio-standards/utilities/sqlfile.rb +6 -8
  533. data/lib/openstudio-standards/utilities/template_measure/measure.rb +108 -0
  534. data/lib/openstudio-standards/utilities/template_measure/measure.xml +162 -0
  535. data/lib/openstudio-standards/utilities/template_measure/resources/BTAPMeasureHelper.rb +448 -0
  536. data/lib/openstudio-standards/utilities/template_measure/tests/test.rb +160 -0
  537. data/lib/openstudio-standards/utilities/weatherData1_xlsx_to_json.rb +23 -26
  538. data/lib/openstudio-standards/version.rb +1 -1
  539. data/lib/openstudio-standards/weather/Weather.Model.rb +112 -87
  540. data/lib/openstudio-standards/weather/Weather.stat_file.rb +17 -17
  541. metadata +236 -2
@@ -1,4 +1,3 @@
1
-
2
1
  # A variety of cooling tower methods that are the same regardless of type.
3
2
  # These methods are available to CoolingTowerSingleSpeed, CoolingTowerTwoSpeed, and CoolingTowerVariableSpeed
4
3
  module CoolingTower
@@ -1,4 +1,3 @@
1
-
2
1
  class Standard
3
2
  # @!group CoolingTowerSingleSpeed
4
3
 
@@ -1,4 +1,3 @@
1
-
2
1
  class Standard
3
2
  # @!group CoolingTowerTwoSpeed
4
3
 
@@ -1,4 +1,3 @@
1
-
2
1
  class Standard
3
2
  # @!group CoolingTowerVariableSpeed
4
3
 
@@ -1,4 +1,3 @@
1
-
2
1
  # A variety of fan calculation methods that are the same regardless of fan type.
3
2
  # These methods are available to FanConstantVolume, FanOnOff, FanVariableVolume, and FanZoneExhaust
4
3
  module Fan
@@ -1,4 +1,3 @@
1
-
2
1
  class Standard
3
2
  # @!group FanConstantVolume
4
3
 
@@ -1,4 +1,3 @@
1
-
2
1
  class Standard
3
2
  # @!group FanOnOff
4
3
 
@@ -1,4 +1,3 @@
1
-
2
1
  class Standard
3
2
  # @!group FanVariableVolume
4
3
 
@@ -184,9 +183,8 @@ class Standard
184
183
 
185
184
  # Get the air loop this fan is connected to
186
185
  air_loop = fan_variable_volume.airLoopHVAC
187
- unless air_loop.is_initialized
188
- return clg_sys_type
189
- end
186
+ return clg_sys_type unless air_loop.is_initialized
187
+
190
188
  air_loop = air_loop.get
191
189
 
192
190
  # Check the types of coils on the AirLoopHVAC
@@ -1,4 +1,3 @@
1
-
2
1
  class Standard
3
2
  # @!group FanZoneExhaust
4
3
 
@@ -14,8 +14,15 @@ class Standard
14
14
  # rate will not (and should not)
15
15
  # exactly equal the minimum tower performance.
16
16
  #
17
+ # @param fluid_cooler [OpenStudio::Model::FluidCoolerSingleSpeed,
18
+ # OpenStudio::Model::FluidCoolerTwoSpeed,
19
+ # OpenStudio::Model::EvaporativeFluidCoolerSingleSpeed,
20
+ # OpenStudio::Model::EvaporativeFluidCoolerTwoSpeed] the fluid cooler
21
+ # @param equipment_type [String] heat rejection equipment type enumeration used for lookup query,
22
+ # options are 'Closed Cooling Tower', modeled as an EvaporativeFluidCooler,
23
+ # or 'Dry Cooler', modeled as a FluidCooler
17
24
  # @return [Bool] true if successful, false if not
18
- def fluid_cooler_apply_minimum_power_per_flow(fluid_cooler)
25
+ def fluid_cooler_apply_minimum_power_per_flow(fluid_cooler, equipment_type: 'Closed Cooling Tower')
19
26
  # Get the design water flow rate
20
27
  if fluid_cooler.designWaterFlowRate.is_initialized
21
28
  design_water_flow_m3_per_s = fluid_cooler.designWaterFlowRate.get
@@ -36,7 +43,7 @@ class Standard
36
43
  search_criteria['template'] = template
37
44
 
38
45
  # Closed cooling towers are fluidcooler objects.
39
- search_criteria['equipment_type'] = 'Closed Cooling Tower'
46
+ search_criteria['equipment_type'] = equipment_type
40
47
 
41
48
  # TODO: Standards replace this with a mechanism to store this
42
49
  # data in the fluid cooler object itself.
@@ -121,4 +128,4 @@ class Standard
121
128
 
122
129
  return true
123
130
  end
124
- end
131
+ end
@@ -1,4 +1,3 @@
1
-
2
1
  class Standard
3
2
  # @!group HeaderedPumpsConstantSpeed
4
3
 
@@ -1,4 +1,3 @@
1
-
2
1
  class Standard
3
2
  # @!group HeaderedPumpsVariableSpeed
4
3
 
@@ -150,6 +150,7 @@ class Standard
150
150
  model.getPlantLoops.sort.each do |plant_loop|
151
151
  # Skip the SWH loops
152
152
  next if plant_loop_swh_loop?(plant_loop)
153
+
153
154
  plant_loop_apply_prm_baseline_temperatures(plant_loop)
154
155
  end
155
156
 
@@ -179,6 +180,7 @@ class Standard
179
180
  model.getPlantLoops.sort.each do |plant_loop|
180
181
  # Skip the SWH loops
181
182
  next if plant_loop_swh_loop?(plant_loop)
183
+
182
184
  plant_loop_apply_prm_number_of_boilers(plant_loop)
183
185
  plant_loop_apply_prm_number_of_chillers(plant_loop)
184
186
  end
@@ -188,6 +190,7 @@ class Standard
188
190
  model.getPlantLoops.sort.each do |plant_loop|
189
191
  # Skip the SWH loops
190
192
  next if plant_loop_swh_loop?(plant_loop)
193
+
191
194
  plant_loop_apply_prm_number_of_cooling_towers(plant_loop)
192
195
  end
193
196
 
@@ -201,6 +204,7 @@ class Standard
201
204
  model.getPlantLoops.sort.each do |plant_loop|
202
205
  # Skip the SWH loops
203
206
  next if plant_loop_swh_loop?(plant_loop)
207
+
204
208
  plant_loop_apply_prm_baseline_pump_power(plant_loop)
205
209
  plant_loop_apply_prm_baseline_pumping_type(plant_loop)
206
210
  end
@@ -272,6 +276,7 @@ class Standard
272
276
  zone.spaces.each do |space|
273
277
  story = space.buildingStory
274
278
  next if story.empty?
279
+
275
280
  stories << story.get
276
281
  end
277
282
  end
@@ -738,10 +743,10 @@ class Standard
738
743
  # Add a hot water PTAC to each zone
739
744
  model_add_ptac(model,
740
745
  zones,
741
- cooling_type: "Single Speed DX AC",
742
- heating_type: "Water",
746
+ cooling_type: 'Single Speed DX AC',
747
+ heating_type: 'Water',
743
748
  hot_water_loop: hot_water_loop,
744
- fan_type: "ConstantVolume")
749
+ fan_type: 'ConstantVolume')
745
750
  end
746
751
 
747
752
  when 'PTHP' # System 2
@@ -786,7 +791,7 @@ class Standard
786
791
  cooling_type: cooling_type,
787
792
  chilled_water_loop: chilled_water_loop,
788
793
  heating_type: heating_type,
789
- supplemental_heating_type: "Gas",
794
+ supplemental_heating_type: 'Gas',
790
795
  hot_water_loop: hot_water_loop,
791
796
  fan_location: 'DrawThrough',
792
797
  fan_type: 'ConstantVolume')
@@ -850,7 +855,7 @@ class Standard
850
855
  story_group[0].spaces.each do |space|
851
856
  stories << [space.buildingStory.get.name.get, building_story_minimum_z_value(space.buildingStory.get)]
852
857
  end
853
- story_name = stories.sort_by { |nm, z| z }[0][0]
858
+ story_name = stories.min_by { |nm, z| z }[0]
854
859
  system_name = "#{story_name} PVAV_Reheat (Sys5)"
855
860
 
856
861
  # If and only if there are primary zones to attach to the loop
@@ -901,7 +906,7 @@ class Standard
901
906
  story_group[0].spaces.each do |space|
902
907
  stories << [space.buildingStory.get.name.get, building_story_minimum_z_value(space.buildingStory.get)]
903
908
  end
904
- story_name = stories.sort_by { |nm, z| z }[0][0]
909
+ story_name = stories.min_by { |nm, z| z }[0]
905
910
  system_name = "#{story_name} PVAV_PFP_Boxes (Sys6)"
906
911
  # If and only if there are primary zones to attach to the loop
907
912
  unless pri_zones.empty?
@@ -979,7 +984,7 @@ class Standard
979
984
  story_group[0].spaces.each do |space|
980
985
  stories << [space.buildingStory.get.name.get, building_story_minimum_z_value(space.buildingStory.get)]
981
986
  end
982
- story_name = stories.sort_by { |nm, z| z }[0][0]
987
+ story_name = stories.min_by { |nm, z| z }[0]
983
988
  system_name = "#{story_name} VAV_Reheat (Sys7)"
984
989
 
985
990
  # If and only if there are primary zones to attach to the loop
@@ -1046,7 +1051,7 @@ class Standard
1046
1051
  story_group[0].spaces.each do |space|
1047
1052
  stories << [space.buildingStory.get.name.get, building_story_minimum_z_value(space.buildingStory.get)]
1048
1053
  end
1049
- story_name = stories.sort_by { |nm, z| z }[0][0]
1054
+ story_name = stories.min_by { |nm, z| z }[0]
1050
1055
  system_name = "#{story_name} VAV_PFP_Boxes (Sys8)"
1051
1056
  # If and only if there are primary zones to attach to the loop
1052
1057
  unless pri_zones.empty?
@@ -1054,7 +1059,7 @@ class Standard
1054
1059
  pri_zones,
1055
1060
  system_name: system_name,
1056
1061
  chilled_water_loop: chilled_water_loop,
1057
- fan_efficiency:0.62,
1062
+ fan_efficiency: 0.62,
1058
1063
  fan_motor_efficiency: 0.9,
1059
1064
  fan_pressure_rise: 4.0)
1060
1065
  end
@@ -1294,6 +1299,7 @@ class Standard
1294
1299
  full_load_hrs = 0.0
1295
1300
  # Skip lights with no schedule
1296
1301
  next if lights_sch.empty?
1302
+
1297
1303
  lights_sch = lights_sch.get
1298
1304
  if lights_sch.to_ScheduleRuleset.is_initialized
1299
1305
  lights_sch = lights_sch.to_ScheduleRuleset.get
@@ -1404,6 +1410,7 @@ class Standard
1404
1410
  # This can happen if a zone has multiple spaces on multiple stories.
1405
1411
  # Stairwells and atriums are typical scenarios.
1406
1412
  next if zones_already_assigned.include?(zone)
1413
+
1407
1414
  zones_on_story << zone
1408
1415
  zones_already_assigned << zone
1409
1416
  end
@@ -1465,14 +1472,14 @@ class Standard
1465
1472
  OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started applying multizone vav OA sizing.')
1466
1473
 
1467
1474
  # Multi-zone VAV outdoor air sizing
1468
- model.getAirLoopHVACs.sort.each {|obj| air_loop_hvac_apply_multizone_vav_outdoor_air_sizing(obj)}
1475
+ model.getAirLoopHVACs.sort.each { |obj| air_loop_hvac_apply_multizone_vav_outdoor_air_sizing(obj) }
1469
1476
 
1470
1477
  OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished applying multizone vav OA sizing.')
1471
1478
  end
1472
1479
 
1473
1480
  # Applies the HVAC parts of the template to all objects in the model using the the template specified in the model.
1474
- def model_apply_hvac_efficiency_standard(model, climate_zone, apply_controls: true)
1475
- sql_db_vars_map = {}
1481
+ def model_apply_hvac_efficiency_standard(model, climate_zone, apply_controls: true, sql_db_vars_map: nil)
1482
+ sql_db_vars_map = {} if sql_db_vars_map.nil?
1476
1483
 
1477
1484
  OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "Started applying HVAC efficiency standards for #{template} template.")
1478
1485
 
@@ -1512,6 +1519,7 @@ class Standard
1512
1519
  # Unitary ACs
1513
1520
  model.getCoilCoolingDXTwoSpeeds.sort.each { |obj| sql_db_vars_map = coil_cooling_dx_two_speed_apply_efficiency_and_curves(obj, sql_db_vars_map) }
1514
1521
  model.getCoilCoolingDXSingleSpeeds.sort.each { |obj| sql_db_vars_map = coil_cooling_dx_single_speed_apply_efficiency_and_curves(obj, sql_db_vars_map) }
1522
+ model.getCoilCoolingDXMultiSpeeds.sort.each { |obj| sql_db_vars_map = coil_cooling_dx_multi_speed_apply_efficiency_and_curves(obj, sql_db_vars_map) }
1515
1523
 
1516
1524
  # WSHPs
1517
1525
  # set WSHP heating coils before cooling coils to get cooling coil capacities before they are renamed
@@ -1534,19 +1542,20 @@ class Standard
1534
1542
  model.getCoolingTowerVariableSpeeds.sort.each { |obj| cooling_tower_variable_speed_apply_efficiency_and_curves(obj) }
1535
1543
 
1536
1544
  # Fluid Coolers
1537
- # TODO: enable when evaportive fluid cooler methods and data are available
1538
- # model.getFluidCoolerSingleSpeeds.sort.each { |obj| fluid_cooler_apply_minimum_power_per_flow(obj) }
1539
- # model.getFluidCoolerTwoSpeeds.sort.each { |obj| fluid_cooler_apply_minimum_power_per_flow(obj) }
1540
- # model.getEvaporativeFluidCoolerSingleSpeeds.sort.each { |obj| fluid_cooler_apply_minimum_power_per_flow(obj) }
1541
- # model.getEvaporativeFluidCoolerTwoSpeeds.sort.each { |obj| fluid_cooler_apply_minimum_power_per_flow(obj) }
1545
+ model.getFluidCoolerSingleSpeeds.sort.each { |obj| fluid_cooler_apply_minimum_power_per_flow(obj, equipment_type: 'Dry Cooler') }
1546
+ model.getFluidCoolerTwoSpeeds.sort.each { |obj| fluid_cooler_apply_minimum_power_per_flow(obj, equipment_type: 'Dry Cooler') }
1547
+ model.getEvaporativeFluidCoolerSingleSpeeds.sort.each { |obj| fluid_cooler_apply_minimum_power_per_flow(obj, equipment_type: 'Closed Cooling Tower') }
1548
+ model.getEvaporativeFluidCoolerTwoSpeeds.sort.each { |obj| fluid_cooler_apply_minimum_power_per_flow(obj, equipment_type: 'Closed Cooling Tower') }
1542
1549
 
1543
1550
  # ERVs
1544
1551
  model.getHeatExchangerAirToAirSensibleAndLatents.each { |obj| heat_exchanger_air_to_air_sensible_and_latent_apply_efficiency(obj) }
1545
1552
 
1546
1553
  # Gas Heaters
1547
1554
  model.getCoilHeatingGass.sort.each { |obj| coil_heating_gas_apply_efficiency_and_curves(obj) }
1555
+ model.getCoilHeatingGasMultiStages.each { |obj| coil_heating_gas_multi_stage_apply_efficiency_and_curves(obj) }
1548
1556
 
1549
1557
  OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "Finished applying HVAC efficiency standards for #{template} template.")
1558
+ return true
1550
1559
  end
1551
1560
 
1552
1561
  # Applies daylighting controls to each space in the model per the standard.
@@ -1584,7 +1593,6 @@ class Standard
1584
1593
  return true
1585
1594
  end
1586
1595
 
1587
-
1588
1596
  # Method to search through a hash for the objects that meets the desired search criteria, as passed via a hash.
1589
1597
  # Returns an Array (empty if nothing found) of matching objects.
1590
1598
  #
@@ -1606,7 +1614,6 @@ class Standard
1606
1614
  # return false
1607
1615
  # end
1608
1616
  def model_find_objects(hash_of_objects, search_criteria, capacity = nil, date = nil, area = nil, num_floors = nil)
1609
-
1610
1617
  matching_objects = []
1611
1618
  if hash_of_objects.is_a?(Hash) && hash_of_objects.key?('table')
1612
1619
  hash_of_objects = hash_of_objects['table']
@@ -1614,11 +1621,13 @@ class Standard
1614
1621
 
1615
1622
  # Compare each of the objects against the search criteria
1616
1623
  raise("This is not a table #{hash_of_objects}") unless hash_of_objects.respond_to?(:each)
1624
+
1617
1625
  hash_of_objects.each do |object|
1618
1626
  meets_all_search_criteria = true
1619
1627
  search_criteria.each do |key, value|
1620
1628
  # Don't check non-existent search criteria
1621
1629
  next unless object.key?(key)
1630
+
1622
1631
  # Stop as soon as one of the search criteria is not met
1623
1632
  # 'Any' is a special key that matches anything
1624
1633
  unless object[key] == value || object[key] == 'Any'
@@ -1628,6 +1637,7 @@ class Standard
1628
1637
  end
1629
1638
  # Skip objects that don't meet all search criteria
1630
1639
  next unless meets_all_search_criteria
1640
+
1631
1641
  # If made it here, object matches all search criteria
1632
1642
  matching_objects << object
1633
1643
  end
@@ -1723,7 +1733,6 @@ class Standard
1723
1733
  # }
1724
1734
  # motor_properties = self.model.find_object(motors, search_criteria, capacity: 2.5)
1725
1735
  def model_find_object(hash_of_objects, search_criteria, capacity = nil, date = nil, area = nil, num_floors = nil)
1726
-
1727
1736
  matching_objects = model_find_objects(hash_of_objects, search_criteria, capacity, date, area, num_floors)
1728
1737
 
1729
1738
  # Check the number of matching objects found
@@ -1740,10 +1749,6 @@ class Standard
1740
1749
  return desired_object
1741
1750
  end
1742
1751
 
1743
-
1744
-
1745
-
1746
-
1747
1752
  # Method to search through a hash for the objects that meets the desired search criteria, as passed via a hash.
1748
1753
  # Returns an Array (empty if nothing found) of matching objects.
1749
1754
  #
@@ -1764,13 +1769,13 @@ class Standard
1764
1769
  # OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Model', "Cannot find data for schedule: #{schedule_name}, will not be created.")
1765
1770
  # return false
1766
1771
  # end
1767
- def standards_lookup_table_many(table_name: , search_criteria: {} , capacity: nil, date: nil, area: nil, num_floors: nil)
1772
+ def standards_lookup_table_many(table_name:, search_criteria: {}, capacity: nil, date: nil, area: nil, num_floors: nil)
1768
1773
  desired_object = nil
1769
1774
  search_criteria_matching_objects = []
1770
1775
  matching_objects = []
1771
- hash_of_objects= @standards_data[table_name]
1772
-
1773
- #needed for NRCan data structure compatibility. We keep all tables in a 'tables' hash in @standards_data and the table
1776
+ hash_of_objects = @standards_data[table_name]
1777
+
1778
+ # needed for NRCan data structure compatibility. We keep all tables in a 'tables' hash in @standards_data and the table
1774
1779
  # itself is in the 'table' hash index.
1775
1780
  if hash_of_objects.nil?
1776
1781
  if @standards_data['tables'].nil?
@@ -1788,6 +1793,7 @@ class Standard
1788
1793
  search_criteria.each do |key, value|
1789
1794
  # Don't check non-existent search criteria
1790
1795
  next unless object.key?(key)
1796
+
1791
1797
  # Stop as soon as one of the search criteria is not met
1792
1798
  # 'Any' is a special key that matches anything
1793
1799
  unless object[key] == value || object[key] == 'Any'
@@ -1797,6 +1803,7 @@ class Standard
1797
1803
  end
1798
1804
  # Skip objects that don't meet all search criteria
1799
1805
  next unless meets_all_search_criteria
1806
+
1800
1807
  # If made it here, object matches all search criteria
1801
1808
  matching_objects << object
1802
1809
  end
@@ -1828,6 +1835,7 @@ class Standard
1828
1835
  next if capacity <= object['minimum_capacity'].to_f
1829
1836
  # Skip objects whose max
1830
1837
  next if capacity > object['maximum_capacity'].to_f
1838
+
1831
1839
  # Found a matching object
1832
1840
  matching_objects << object
1833
1841
  end
@@ -1842,6 +1850,7 @@ class Standard
1842
1850
  next if date <= Date.parse(object['start_date'])
1843
1851
  # Skip objects whose end date is beyond the specified date
1844
1852
  next if date > Date.parse(object['end_date'])
1853
+
1845
1854
  # Found a matching object
1846
1855
  date_matching_objects << object
1847
1856
  end
@@ -1903,11 +1912,11 @@ class Standard
1903
1912
  # }
1904
1913
  # motor_properties = self.model.find_object(motors, search_criteria, 2.5)
1905
1914
  def standards_lookup_table_first(table_name:, search_criteria: {}, capacity: nil, date: nil)
1906
- #run the many version of the look up code...DRY.
1915
+ # run the many version of the look up code...DRY.
1907
1916
  matching_objects = standards_lookup_table_many(table_name: table_name,
1908
- search_criteria: search_criteria,
1909
- capacity: capacity,
1910
- date: date)
1917
+ search_criteria: search_criteria,
1918
+ capacity: capacity,
1919
+ date: date)
1911
1920
 
1912
1921
  # Check the number of matching objects found
1913
1922
  if matching_objects.size.zero?
@@ -1981,7 +1990,7 @@ class Standard
1981
1990
 
1982
1991
  if standard_sch_type_limit.nil?
1983
1992
  if lower_limit_value.nil? || upper_limit_value.nil? || numeric_type.nil? || unit_type.nil?
1984
- OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Model', "If calling model_add_schedule_type_limits without a standard_sch_type_limit, you must specify all properties of ScheduleTypeLimits.")
1993
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Model', 'If calling model_add_schedule_type_limits without a standard_sch_type_limit, you must specify all properties of ScheduleTypeLimits.')
1985
1994
  return false
1986
1995
  end
1987
1996
  schedule_type_limits = OpenStudio::Model::ScheduleTypeLimits.new(model)
@@ -2041,8 +2050,8 @@ class Standard
2041
2050
  schedule_type_limits.setUpperLimitValue(1000.0)
2042
2051
  schedule_type_limits.setNumericType('Continuous')
2043
2052
  schedule_type_limits.setUnitType('ActivityLevel')
2044
- else
2045
- OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Model', "Invalid standard_sch_type_limit for method model_add_schedule_type_limits.")
2053
+ else
2054
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Model', 'Invalid standard_sch_type_limit for method model_add_schedule_type_limits.')
2046
2055
  end
2047
2056
  end
2048
2057
  end
@@ -2057,6 +2066,7 @@ class Standard
2057
2066
  # @todo make return an OptionalScheduleRuleset
2058
2067
  def model_add_schedule(model, schedule_name)
2059
2068
  return nil if schedule_name.nil? || schedule_name == ''
2069
+
2060
2070
  # First check model and return schedule if it already exists
2061
2071
  model.getSchedules.sort.each do |schedule|
2062
2072
  if schedule.name.get.to_s == schedule_name
@@ -2328,7 +2338,7 @@ class Standard
2328
2338
  else # if !data['intended_surface_type'] == 'ExteriorWindow' && !data['intended_surface_type'] == 'Skylight'
2329
2339
  # Set the U-Value
2330
2340
  construction_set_u_value(construction, target_u_value_ip.to_f, data['insulation_layer'], data['intended_surface_type'], u_includes_int_film, u_includes_ext_film)
2331
- # else
2341
+ # else
2332
2342
  # OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "Not modifying U-value for #{data['intended_surface_type']} u_val #{target_u_value_ip} f_fac #{target_f_factor_ip} c_fac #{target_c_factor_ip}")
2333
2343
  end
2334
2344
 
@@ -2371,7 +2381,7 @@ class Standard
2371
2381
  frame_with_m = OpenStudio.convert(frame_width_in, 'in', 'm').get
2372
2382
  frame_resistance_ip = frame_data['resistance'].to_f
2373
2383
  frame_resistance_si = OpenStudio.convert(frame_resistance_ip, 'hr*ft^2*R/Btu', 'm^2*K/W').get
2374
- frame_conductance_si = 1.0/frame_resistance_si
2384
+ frame_conductance_si = 1.0 / frame_resistance_si
2375
2385
  frame = OpenStudio::Model::WindowPropertyFrameAndDivider.new(model)
2376
2386
  frame.setName("Skylight frame R-#{frame_resistance_ip.round(2)} #{frame_width_in.round(1)} in. wide")
2377
2387
  frame.setFrameWidth(frame_with_m)
@@ -2379,7 +2389,8 @@ class Standard
2379
2389
  skylights_frame_added = 0
2380
2390
  model.getSubSurfaces.each do |sub_surface|
2381
2391
  next unless sub_surface.outsideBoundaryCondition == 'Outdoors' && sub_surface.subSurfaceType == 'Skylight'
2382
- # todo enable proper window frame setting after https://github.com/NREL/OpenStudio/issues/2895 is fixed
2392
+
2393
+ # TODO: enable proper window frame setting after https://github.com/NREL/OpenStudio/issues/2895 is fixed
2383
2394
  sub_surface.setString(8, frame.name.get.to_s)
2384
2395
  skylights_frame_added += 1
2385
2396
  # if sub_surface.allowWindowPropertyFrameAndDivider
@@ -2615,7 +2626,7 @@ class Standard
2615
2626
  if data['exterior_glass_door_standards_construction_type'] && data['exterior_glass_door_building_category']
2616
2627
  exterior_subsurfaces.setGlassDoorConstruction(model_find_and_add_construction(model,
2617
2628
  climate_zone_set,
2618
- 'GlassDoor',
2629
+ 'GlassDoor',
2619
2630
  data['exterior_glass_door_standards_construction_type'],
2620
2631
  data['exterior_glass_door_building_category']))
2621
2632
  end
@@ -2696,7 +2707,7 @@ class Standard
2696
2707
  # Find curve data
2697
2708
  data = model_find_object(standards_data['curves'], 'name' => curve_name)
2698
2709
  if data.nil?
2699
- OpenStudio::logFree(OpenStudio::Warn, "openstudio.Model.Model", "Could not find a curve called '#{curve_name}' in the standards.")
2710
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.Model.Model', "Could not find a curve called '#{curve_name}' in the standards.")
2700
2711
  return nil
2701
2712
  end
2702
2713
 
@@ -2784,8 +2795,35 @@ class Standard
2784
2795
  curve.setMinimumCurveOutput(data['minimum_dependent_variable_output']) if data['minimum_dependent_variable_output']
2785
2796
  curve.setMaximumCurveOutput(data['maximum_dependent_variable_output']) if data['maximum_dependent_variable_output']
2786
2797
  return curve
2798
+ when 'MultiVariableLookupTable'
2799
+ num_ind_var = data['number_independent_variables'].to_i
2800
+ table = OpenStudio::Model::TableMultiVariableLookup.new(model, num_ind_var)
2801
+ table.setName(data['name'])
2802
+ table.setInterpolationMethod(data['interpolation_method'])
2803
+ table.setNumberofInterpolationPoints(data['number_of_interpolation_points'])
2804
+ table.setCurveType(data['curve_type'])
2805
+ table.setTableDataFormat('SingleLineIndependentVariableWithMatrix')
2806
+ table.setNormalizationReference(data['normalization_reference'].to_f)
2807
+ table.setOutputUnitType(data['output_unit_type'])
2808
+ table.setMinimumValueofX1(data['minimum_independent_variable_1'].to_f)
2809
+ table.setMaximumValueofX1(data['maximum_independent_variable_1'].to_f)
2810
+ table.setInputUnitTypeforX1(data['input_unit_type_x1'])
2811
+ if num_ind_var == 2
2812
+ table.setMinimumValueofX2(data['minimum_independent_variable_2'].to_f)
2813
+ table.setMaximumValueofX2(data['maximum_independent_variable_2'].to_f)
2814
+ table.setInputUnitTypeforX2(data['input_unit_type_x2'])
2815
+ end
2816
+ data_points = data.each.select { |key, value| key.include? 'data_point' }
2817
+ data_points.each do |key, value|
2818
+ if num_ind_var == 1
2819
+ table.addPoint(value.split(',')[0].to_f, value.split(',')[1].to_f)
2820
+ elsif num_ind_var == 2
2821
+ table.addPoint(value.split(',')[0].to_f, value.split(',')[1].to_f, value.split(',')[2].to_f)
2822
+ end
2823
+ end
2824
+ return table
2787
2825
  else
2788
- OpenStudio::logFree(OpenStudio::Error, "openstudio.Model.Model", "#{curve_name}' has an invalid form: #{data['form']}', cannot create this curve.")
2826
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.Model.Model', "#{curve_name}' has an invalid form: #{data['form']}', cannot create this curve.")
2789
2827
  return nil
2790
2828
  end
2791
2829
  end
@@ -2847,14 +2885,14 @@ class Standard
2847
2885
  temp = File.read("#{standards_data_dir}/legacy_idf_results.csv")
2848
2886
  end
2849
2887
  end
2850
- legacy_idf_csv = CSV.new(temp, :headers => true, :converters => :all)
2851
- legacy_idf_results = legacy_idf_csv.to_a.map {|row| row.to_hash }
2888
+ legacy_idf_csv = CSV.new(temp, headers: true, converters: :all)
2889
+ legacy_idf_results = legacy_idf_csv.to_a.map(&:to_hash)
2852
2890
 
2853
2891
  # Get the results for this building
2854
2892
  search_criteria = {
2855
- 'Building Type' => building_type,
2856
- 'Template' => template,
2857
- 'Climate Zone' => climate_zone
2893
+ 'Building Type' => building_type,
2894
+ 'Template' => template,
2895
+ 'Climate Zone' => climate_zone
2858
2896
  }
2859
2897
  energy_values = model_find_object(legacy_idf_results, search_criteria)
2860
2898
  if energy_values.nil?
@@ -2889,12 +2927,13 @@ class Standard
2889
2927
  fuel_types = ['Electricity', 'Natural Gas', 'Additional Fuel', 'District Cooling', 'District Heating', 'Water']
2890
2928
 
2891
2929
  # List of all end uses
2892
- end_uses = ['Heating', 'Cooling', 'Interior Lighting', 'Exterior Lighting', 'Interior Equipment', 'Exterior Equipment', 'Fans', 'Pumps', 'Heat Rejection','Humidification', 'Heat Recovery', 'Water Systems', 'Refrigeration', 'Generators']
2930
+ end_uses = ['Heating', 'Cooling', 'Interior Lighting', 'Exterior Lighting', 'Interior Equipment', 'Exterior Equipment', 'Fans', 'Pumps', 'Heat Rejection', 'Humidification', 'Heat Recovery', 'Water Systems', 'Refrigeration', 'Generators']
2893
2931
 
2894
2932
  # Sum the legacy results up by fuel and by end use
2895
2933
  fuel_types.each do |fuel_type|
2896
2934
  end_uses.each do |end_use|
2897
2935
  next if end_use == 'Exterior Equipment'
2936
+
2898
2937
  legacy_val = legacy_values["#{end_use}|#{fuel_type}"]
2899
2938
 
2900
2939
  # Combine the exterior lighting and exterior equipment
@@ -2929,10 +2968,9 @@ class Standard
2929
2968
  else
2930
2969
  legacy_results_hash['total_energy_by_end_use'][end_use] = legacy_val # start new counter
2931
2970
  end
2932
-
2933
2971
  end
2934
- end # Next end use
2935
- end # Next fuel type
2972
+ end
2973
+ end
2936
2974
 
2937
2975
  return legacy_results_hash
2938
2976
  end
@@ -2954,14 +2992,15 @@ class Standard
2954
2992
  result = 46_320
2955
2993
  elsif building_type == 'MediumOffice' # 53,600 ft^2
2956
2994
  result = 4982
2957
- elsif building_type == 'LargeOfficeDetailed' # 498,600 ft^2
2995
+ elsif building_type == 'LargeOfficeDetailed' # 498,600 ft^2
2958
2996
  result = 46_320
2959
2997
  elsif building_type == 'MediumOfficeDetailed' # 53,600 ft^2
2960
2998
  result = 4982
2961
2999
  elsif building_type == 'MidriseApartment' # 33,700 ft^2
2962
3000
  result = 3135
2963
3001
  elsif building_type == 'Office'
2964
- result = nil # TODO: - there shouldn't be a prototype building for this
3002
+ result = nil
3003
+ # TODO: there shouldn't be a prototype building for this
2965
3004
  OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Model', 'Measures calling this should choose between SmallOffice, MediumOffice, and LargeOffice')
2966
3005
  elsif building_type == 'Outpatient' # 40.950 ft^2
2967
3006
  result = 3804
@@ -2985,9 +3024,9 @@ class Standard
2985
3024
  result = 4181
2986
3025
  elsif building_type == 'Warehouse' # 49,495 ft^2 (legacy ref shows 52,045, but I wil calc using 49,495)
2987
3026
  result = 4595
2988
- elsif building_type == 'SmallDataCenterLowITE' or building_type == 'SmallDataCenterHighITE' # 600 ft^2
3027
+ elsif building_type == 'SmallDataCenterLowITE' || building_type == 'SmallDataCenterHighITE' # 600 ft^2
2989
3028
  result = 56
2990
- elsif building_type == 'LargeDataCenterLowITE' or building_type == 'LargeDataCenterHighITE' # 6000 ft^2
3029
+ elsif building_type == 'LargeDataCenterLowITE' || building_type == 'LargeDataCenterHighITE' # 6000 ft^2
2991
3030
  result = 557
2992
3031
  elsif building_type == 'Laboratory' # 90000 ft^2
2993
3032
  result = 8361
@@ -3224,6 +3263,7 @@ class Standard
3224
3263
  # Hard-assigned surfaces
3225
3264
  model.getSurfaces.sort.each do |surf|
3226
3265
  next unless surf.outsideBoundaryCondition == boundary_condition
3266
+
3227
3267
  surf_type = surf.surfaceType
3228
3268
  if surf_type == 'Floor' || surf_type == 'Wall'
3229
3269
  next unless type.include?(surf_type)
@@ -3236,6 +3276,7 @@ class Standard
3236
3276
  # Hard-assigned subsurfaces
3237
3277
  model.getSubSurfaces.sort.each do |surf|
3238
3278
  next unless surf.outsideBoundaryCondition == boundary_condition
3279
+
3239
3280
  surf_type = surf.subSurfaceType
3240
3281
  if surf_type == 'FixedWindow' || surf_type == 'OperableWindow'
3241
3282
  next unless type == 'ExteriorWindow'
@@ -3251,6 +3292,7 @@ class Standard
3251
3292
  all_constructions = []
3252
3293
  constructions.uniq.each do |const|
3253
3294
  next if const.empty?
3295
+
3254
3296
  all_constructions << const.get
3255
3297
  end
3256
3298
 
@@ -3395,6 +3437,7 @@ class Standard
3395
3437
  model.getSurfaces.sort.each do |surf|
3396
3438
  next unless surf.outsideBoundaryCondition == boundary_condition
3397
3439
  next unless surf.surfaceType == surface_type
3440
+
3398
3441
  surfaces_to_modify << surf
3399
3442
  end
3400
3443
 
@@ -3402,6 +3445,7 @@ class Standard
3402
3445
  model.getSubSurfaces.sort.each do |surf|
3403
3446
  next unless surf.outsideBoundaryCondition == boundary_condition
3404
3447
  next unless surf.subSurfaceType == surface_type
3448
+
3405
3449
  surfaces_to_modify << surf
3406
3450
  end
3407
3451
  end
@@ -3431,8 +3475,7 @@ class Standard
3431
3475
  # @param building_category [string] the type of building
3432
3476
  # @param climate_zone [string] the building's climate zone
3433
3477
  # @return [hash] hash of construction properties
3434
- def model_get_construction_properties(model, intended_surface_type, standards_construction_type, building_category, climate_zone=nil)
3435
-
3478
+ def model_get_construction_properties(model, intended_surface_type, standards_construction_type, building_category, climate_zone = nil)
3436
3479
  # get climate_zone_set
3437
3480
  climate_zone = model_get_building_climate_zone_and_building_type(model)['climate_zone'] if climate_zone.nil?
3438
3481
  climate_zone_set = model_find_climate_zone_set(model, climate_zone)
@@ -3458,14 +3501,14 @@ class Standard
3458
3501
  # @param space_type [string] space type within the building type. Typically nil.
3459
3502
  # @return [hash] hash of construction set data
3460
3503
  def model_get_construction_set(building_type, space_type = nil)
3461
- #populate search hash
3504
+ # populate search hash
3462
3505
  search_criteria = {
3463
- 'template' => template,
3464
- 'building_type' => building_type,
3465
- 'space_type' => space_type
3506
+ 'template' => template,
3507
+ 'building_type' => building_type,
3508
+ 'space_type' => space_type
3466
3509
  }
3467
3510
 
3468
- #Search construction sets table for the exterior wall building category and construction type
3511
+ # Search construction sets table for the exterior wall building category and construction type
3469
3512
  construction_set_data = model_find_object(standards_data['construction_sets'], search_criteria)
3470
3513
 
3471
3514
  return construction_set_data
@@ -3504,11 +3547,13 @@ class Standard
3504
3547
  next unless surface.outsideBoundaryCondition == 'Outdoors'
3505
3548
  # Skip non-walls
3506
3549
  next unless surface.surfaceType.casecmp('wall').zero?
3550
+
3507
3551
  # This wall's gross area (including window area)
3508
3552
  wall_area_m2 += surface.grossArea * space.multiplier
3509
3553
  # Subsurfaces in this surface
3510
3554
  surface.subSurfaces.sort.each do |ss|
3511
3555
  next unless ss.subSurfaceType == 'FixedWindow' || ss.subSurfaceType == 'OperableWindow'
3556
+
3512
3557
  wind_area_m2 += ss.netArea * space.multiplier
3513
3558
  end
3514
3559
  end
@@ -3603,12 +3648,15 @@ class Standard
3603
3648
  next # Skip unconditioned spaces
3604
3649
  when 'NonResConditioned'
3605
3650
  next unless red_nr
3651
+
3606
3652
  mult = mult_nr_red
3607
3653
  when 'ResConditioned'
3608
3654
  next unless red_res
3655
+
3609
3656
  mult = mult_res_red
3610
3657
  when 'Semiheated'
3611
3658
  next unless red_sh
3659
+
3612
3660
  mult = mult_sh_red
3613
3661
  end
3614
3662
 
@@ -3618,9 +3666,11 @@ class Standard
3618
3666
  next unless surface.outsideBoundaryCondition == 'Outdoors'
3619
3667
  # Skip non-walls
3620
3668
  next unless surface.surfaceType.casecmp('wall').zero?
3669
+
3621
3670
  # Subsurfaces in this surface
3622
3671
  surface.subSurfaces.sort.each do |ss|
3623
3672
  next unless ss.subSurfaceType == 'FixedWindow' || ss.subSurfaceType == 'OperableWindow'
3673
+
3624
3674
  # Reduce the size of the window
3625
3675
  # If a vertical rectangle, raise sill height to avoid
3626
3676
  # impacting daylighting areas, otherwise
@@ -3664,11 +3714,13 @@ class Standard
3664
3714
  next unless surface.outsideBoundaryCondition == 'Outdoors'
3665
3715
  # Skip non-walls
3666
3716
  next unless surface.surfaceType == 'RoofCeiling'
3717
+
3667
3718
  # This wall's gross area (including skylight area)
3668
3719
  wall_area_m2 += surface.grossArea * space.multiplier
3669
3720
  # Subsurfaces in this surface
3670
3721
  surface.subSurfaces.sort.each do |ss|
3671
3722
  next unless ss.subSurfaceType == 'Skylight'
3723
+
3672
3724
  sky_area_m2 += ss.netArea * space.multiplier
3673
3725
  end
3674
3726
  end
@@ -3738,9 +3790,11 @@ class Standard
3738
3790
  case cat
3739
3791
  when 'NonRes'
3740
3792
  next unless red_nr
3793
+
3741
3794
  mult = mult_nr_red
3742
3795
  when 'Res'
3743
3796
  next unless red_res
3797
+
3744
3798
  mult = mult_res_red
3745
3799
  when 'Semiheated'
3746
3800
  next unless red_sh
@@ -3753,9 +3807,11 @@ class Standard
3753
3807
  next unless surface.outsideBoundaryCondition == 'Outdoors'
3754
3808
  # Skip non-walls
3755
3809
  next unless surface.surfaceType == 'RoofCeiling'
3810
+
3756
3811
  # Subsurfaces in this surface
3757
3812
  surface.subSurfaces.sort.each do |ss|
3758
3813
  next unless ss.subSurfaceType == 'Skylight'
3814
+
3759
3815
  # Reduce the size of the skylight
3760
3816
  red = 1.0 - mult
3761
3817
  sub_surface_reduce_area_by_percent_by_shrinking_toward_centroid(ss, red)
@@ -3783,6 +3839,7 @@ class Standard
3783
3839
  model.getPlantLoops.sort.each do |loop|
3784
3840
  # Don't remove service water heating loops
3785
3841
  next if plant_loop_swh_loop?(loop)
3842
+
3786
3843
  loop.remove
3787
3844
  end
3788
3845
 
@@ -3793,6 +3850,7 @@ class Standard
3793
3850
  model.getThermalZones.sort.each do |zone|
3794
3851
  zone.equipment.each do |zone_equipment|
3795
3852
  next if zone_equipment.to_FanZoneExhaust.is_initialized
3853
+
3796
3854
  zone_equipment.remove
3797
3855
  end
3798
3856
  end
@@ -3807,18 +3865,18 @@ class Standard
3807
3865
  #
3808
3866
  # @return [Bool] true if successful, false if not
3809
3867
  def model_remove_prm_ems_objects(model)
3810
- model.getEnergyManagementSystemActuators.each { |x| x.remove }
3811
- model.getEnergyManagementSystemConstructionIndexVariables.each { |x| x.remove }
3812
- model.getEnergyManagementSystemCurveOrTableIndexVariables.each { |x| x.remove }
3813
- model.getEnergyManagementSystemGlobalVariables.each { |x| x.remove }
3814
- model.getEnergyManagementSystemInternalVariables.each { |x| x.remove }
3815
- model.getEnergyManagementSystemMeteredOutputVariables.each { |x| x.remove }
3816
- model.getEnergyManagementSystemOutputVariables.each { |x| x.remove }
3817
- model.getEnergyManagementSystemPrograms.each { |x| x.remove }
3818
- model.getEnergyManagementSystemProgramCallingManagers.each { |x| x.remove }
3819
- model.getEnergyManagementSystemSensors.each { |x| x.remove }
3820
- model.getEnergyManagementSystemSubroutines.each { |x| x.remove }
3821
- model.getEnergyManagementSystemTrendVariables.each { |x| x.remove }
3868
+ model.getEnergyManagementSystemActuators.each(&:remove)
3869
+ model.getEnergyManagementSystemConstructionIndexVariables.each(&:remove)
3870
+ model.getEnergyManagementSystemCurveOrTableIndexVariables.each(&:remove)
3871
+ model.getEnergyManagementSystemGlobalVariables.each(&:remove)
3872
+ model.getEnergyManagementSystemInternalVariables.each(&:remove)
3873
+ model.getEnergyManagementSystemMeteredOutputVariables.each(&:remove)
3874
+ model.getEnergyManagementSystemOutputVariables.each(&:remove)
3875
+ model.getEnergyManagementSystemPrograms.each(&:remove)
3876
+ model.getEnergyManagementSystemProgramCallingManagers.each(&:remove)
3877
+ model.getEnergyManagementSystemSensors.each(&:remove)
3878
+ model.getEnergyManagementSystemSubroutines.each(&:remove)
3879
+ model.getEnergyManagementSystemTrendVariables.each(&:remove)
3822
3880
 
3823
3881
  return true
3824
3882
  end
@@ -3830,6 +3888,7 @@ class Standard
3830
3888
  model.getShadingSurfaceGroups.sort.each do |shade_group|
3831
3889
  # Skip Site shading
3832
3890
  next if shade_group.shadingSurfaceType == 'Site'
3891
+
3833
3892
  # Space shading surfaces should be removed
3834
3893
  shading_surfaces_removed += shade_group.shadingSurfaces.size
3835
3894
  shade_group.remove
@@ -3907,7 +3966,7 @@ class Standard
3907
3966
  result << { units: 'unit', block: 75, max_hourly: 8.5, max_daily: 66.0, avg_day_unit: 38.0 }
3908
3967
  result << { units: 'unit', block: 100, max_hourly: 7.0, max_daily: 60.0, avg_day_unit: 37.0 }
3909
3968
  result << { units: 'unit', block: 200, max_hourly: 5.0, max_daily: 50.0, avg_day_unit: 35.0 }
3910
- elsif ['Office', 'LargeOffice', 'MediumOffice', 'SmallOffice','LargeOfficeDetailed', 'MediumOfficeDetailed', 'SmallOfficeDetailed'].include? building_type
3969
+ elsif ['Office', 'LargeOffice', 'MediumOffice', 'SmallOffice', 'LargeOfficeDetailed', 'MediumOfficeDetailed', 'SmallOfficeDetailed'].include? building_type
3911
3970
  result << { units: 'person', block: nil, max_hourly: 0.4, max_daily: 2.0, avg_day_unit: 1.0 }
3912
3971
  elsif building_type == 'Outpatient'
3913
3972
  OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Model', "No SWH rules of thumbs for #{building_type}.")
@@ -4086,7 +4145,7 @@ class Standard
4086
4145
  # Defaults to the least specific climate zone set.
4087
4146
  # For example, 2A and 2 both contain 2A, so use 2.
4088
4147
  def model_get_climate_zone_set_from_list(model, possible_climate_zone_sets)
4089
- climate_zone_set = possible_climate_zone_sets.sort.first
4148
+ climate_zone_set = possible_climate_zone_sets.min
4090
4149
  return climate_zone_set
4091
4150
  end
4092
4151
 
@@ -4171,6 +4230,7 @@ class Standard
4171
4230
  # update count of ground wall areas
4172
4231
  next if surface.surfaceType != 'Wall'
4173
4232
  next if surface.outsideBoundaryCondition != 'Ground' # TODO: - make more flexible for slab/basement model.modeling
4233
+
4174
4234
  story_ground_wall_area += surface.grossArea
4175
4235
  end
4176
4236
 
@@ -4269,6 +4329,7 @@ class Standard
4269
4329
  # loop through spaces to get mis values
4270
4330
  space_type.spaces.sort.each do |space|
4271
4331
  next unless space.partofTotalFloorArea
4332
+
4272
4333
  effective_num_spaces += space.multiplier
4273
4334
  floor_area += space.floorArea * space.multiplier
4274
4335
  num_people += space.numberOfPeople * space.multiplier
@@ -4344,7 +4405,6 @@ class Standard
4344
4405
  return space_type_hash.sort.to_h
4345
4406
  end
4346
4407
 
4347
-
4348
4408
  # This method will apply the a FDWR to a model. It will remove any existing windows and doors and use the
4349
4409
  # Default contruction to set to apply the window construction. Sill height is in meters
4350
4410
  def apply_max_fdwr(model, runner, sillHeight_si, wwr)
@@ -4354,10 +4414,12 @@ class Standard
4354
4414
  zone = surface.space.get.thermalZone
4355
4415
  zone_multiplier = nil
4356
4416
  next if zone.empty?
4357
- if surface.outsideBoundaryCondition == 'Outdoors' and surface.surfaceType == "Wall"
4358
- surface.subSurfaces.each {|ss| ss.remove}
4417
+
4418
+ if (surface.outsideBoundaryCondition == 'Outdoors') && (surface.surfaceType == 'Wall')
4419
+ surface.subSurfaces.each(&:remove)
4359
4420
  new_window = surface.setWindowToWallRatio(wwr, sillHeight_si, true)
4360
4421
  raise "#{surface.name.get} did not get set to #{wwr}. The size of the surface is #{surface.grossArea}" unless surface.windowToWallRatio.round(3) == wwr.round(3)
4422
+
4361
4423
  if new_window.empty?
4362
4424
  runner.registerWarning("The requested window to wall ratio for surface '#{surface.name}' was too large. Fenestration was not altered for this surface.")
4363
4425
  else
@@ -4377,10 +4439,10 @@ class Standard
4377
4439
  # Default contruction to set to apply the skylight construction. A default skylight square area of 0.25^2 is used.
4378
4440
  def apply_max_srr(model, runner, srr, skylight_area = 0.25 * 0.25)
4379
4441
  spaces = []
4380
- surface_type = "RoofCeiling"
4442
+ surface_type = 'RoofCeiling'
4381
4443
  model.getSpaces.sort.each do |space|
4382
4444
  space.surfaces.sort.each do |surface|
4383
- if surface.outsideBoundaryCondition == 'Outdoors' and surface.surfaceType == surface_type
4445
+ if (surface.outsideBoundaryCondition == 'Outdoors') && (surface.surfaceType == surface_type)
4384
4446
  spaces << space
4385
4447
  break
4386
4448
  end
@@ -4389,13 +4451,13 @@ class Standard
4389
4451
  pattern = OpenStudio::Model.generateSkylightPattern(spaces, spaces[0].directionofRelativeNorth, srr, Math.sqrt(skylight_area), Math.sqrt(skylight_area)) # ratio, x value, y value
4390
4452
  # applying skylight pattern
4391
4453
  skylights = OpenStudio::Model.applySkylightPattern(pattern, spaces, OpenStudio::Model::OptionalConstructionBase.new)
4392
- spacenames = spaces.map {|space| space.name.get}
4454
+ spacenames = spaces.map { |space| space.name.get }
4393
4455
  runner.registerInfo("Adding #{skylights.size} skylights to #{spacenames}")
4394
4456
  end
4395
4457
 
4396
4458
  # This method will limit the subsurface of a given surface_type ("Wall" or "RoofCeiling") to the ratio for the building.
4397
4459
  # This method only reduces subsurface sizes at most.
4398
- def apply_limit_to_subsurface_ratio(model, ratio, surface_type = "Wall")
4460
+ def apply_limit_to_subsurface_ratio(model, ratio, surface_type = 'Wall')
4399
4461
  fdwr = get_outdoor_subsurface_ratio(model, surface_type)
4400
4462
  if fdwr <= ratio
4401
4463
  OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "Building FDWR of #{fdwr} is already lower than limit of #{ratio.round}%.")
@@ -4412,6 +4474,7 @@ class Standard
4412
4474
  next unless surface.outsideBoundaryCondition == 'Outdoors'
4413
4475
  # Skip non-walls
4414
4476
  next unless surface.surfaceType == surface_type
4477
+
4415
4478
  # Subsurfaces in this surface
4416
4479
  surface.subSurfaces.sort.each do |ss|
4417
4480
  # Reduce the size of the window
@@ -4436,6 +4499,7 @@ class Standard
4436
4499
  model.getClimateZones.climateZones.each do |cz|
4437
4500
  if cz.institution == 'ASHRAE'
4438
4501
  next if cz.value == '' # Skip blank ASHRAE climate zones put in by OpenStudio Application
4502
+
4439
4503
  climate_zone = if cz.value == '7' || cz.value == '8'
4440
4504
  "ASHRAE 169-2013-#{cz.value}A"
4441
4505
  else
@@ -4443,6 +4507,7 @@ class Standard
4443
4507
  end
4444
4508
  elsif cz.institution == 'CEC'
4445
4509
  next if cz.value == '' # Skip blank ASHRAE climate zones put in by OpenStudio Application
4510
+
4446
4511
  climate_zone = "CEC T24-CEC#{cz.value}"
4447
4512
  end
4448
4513
  end
@@ -4473,9 +4538,8 @@ class Standard
4473
4538
  return true
4474
4539
  end
4475
4540
 
4476
-
4477
4541
  # This method return the building ratio of subsurface_area / surface_type_area where surface_type can be "Wall" or "RoofCeiling"
4478
- def get_outdoor_subsurface_ratio(model, surface_type = "Wall")
4542
+ def get_outdoor_subsurface_ratio(model, surface_type = 'Wall')
4479
4543
  surface_area = 0.0
4480
4544
  sub_surface_area = 0
4481
4545
  all_surfaces = []
@@ -4484,9 +4548,10 @@ class Standard
4484
4548
  zone = space.thermalZone
4485
4549
  zone_multiplier = nil
4486
4550
  next if zone.empty?
4551
+
4487
4552
  zone_multiplier = zone.get.multiplier
4488
4553
  space.surfaces.sort.each do |surface|
4489
- if surface.outsideBoundaryCondition == 'Outdoors' and surface.surfaceType == surface_type
4554
+ if (surface.outsideBoundaryCondition == 'Outdoors') && (surface.surfaceType == surface_type)
4490
4555
  surface_area += surface.grossArea * zone_multiplier
4491
4556
  surface.subSurfaces.sort.each do |sub_surface|
4492
4557
  sub_surface_area += sub_surface.grossArea * sub_surface.multiplier * zone_multiplier
@@ -4505,6 +4570,7 @@ class Standard
4505
4570
  unless File.exist?(osm_file)
4506
4571
  raise("The initial osm path: #{osm_file} does not exist.")
4507
4572
  end
4573
+
4508
4574
  osm_model_path = OpenStudio::Path.new(osm_file.to_s)
4509
4575
  # Upgrade version if required.
4510
4576
  version_translator = OpenStudio::OSVersion::VersionTranslator.new
@@ -4516,19 +4582,19 @@ class Standard
4516
4582
  def validate_initial_model(model)
4517
4583
  is_valid = true
4518
4584
  if model.getBuildingStorys.empty?
4519
- OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', "Please assign Spaces to BuildingStorys the geometry model.")
4585
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', 'Please assign Spaces to BuildingStorys the geometry model.')
4520
4586
  is_valid = false
4521
4587
  end
4522
4588
  if model.getThermalZones.empty?
4523
- OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', "Please assign Spaces to ThermalZones the geometry model.")
4589
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', 'Please assign Spaces to ThermalZones the geometry model.')
4524
4590
  is_valid = false
4525
4591
  end
4526
4592
  if model.getBuilding.standardsNumberOfStories.empty?
4527
- OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', "Please define Building.standardsNumberOfStories the geometry model.")
4593
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', 'Please define Building.standardsNumberOfStories the geometry model.')
4528
4594
  is_valid = false
4529
4595
  end
4530
4596
  if model.getBuilding.standardsNumberOfAboveGroundStories.empty?
4531
- OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', "Please define Building.standardsNumberOfAboveStories in the geometry model.")
4597
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', 'Please define Building.standardsNumberOfAboveStories in the geometry model.')
4532
4598
  is_valid = false
4533
4599
  end
4534
4600
 
@@ -4539,12 +4605,12 @@ class Standard
4539
4605
  is_valid = false
4540
4606
  else
4541
4607
  @space_type_map = @space_type_map.sort.to_h
4542
- OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', "Loaded space type map from model")
4608
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Loaded space type map from model')
4543
4609
  end
4544
4610
  end
4545
4611
 
4546
4612
  # ensure that model is intersected correctly.
4547
- model.getSpaces.each {|space1| model.getSpaces.each {|space2| space1.intersectSurfaces(space2)}}
4613
+ model.getSpaces.each { |space1| model.getSpaces.each { |space2| space1.intersectSurfaces(space2) } }
4548
4614
  # Get multipliers from TZ in model. Need this for HVAC contruction.
4549
4615
  @space_multiplier_map = {}
4550
4616
  model.getSpaces.sort.each do |space|
@@ -4566,7 +4632,7 @@ class Standard
4566
4632
  def model_ventilation_method(model)
4567
4633
  building_data = model_get_building_climate_zone_and_building_type(model)
4568
4634
  building_type = building_data['building_type']
4569
- if building_type != 'Laboratory' # Laboratory has multiple criteria on ventilation, pick the greatest
4635
+ if building_type != 'Laboratory' # Laboratory has multiple criteria on ventilation, pick the greatest
4570
4636
  ventilation_method = 'Sum'
4571
4637
  else
4572
4638
  ventilation_method = 'Maximum'
@@ -4583,12 +4649,12 @@ class Standard
4583
4649
  start_size = model.objects.size
4584
4650
  model.getResourceObjects.sort.each do |obj|
4585
4651
  if obj.directUseCount.zero?
4586
- OpenStudio::logFree(OpenStudio::Debug, 'openstudio.standards.Model', "#{obj.name} is unused; it will be removed.")
4652
+ OpenStudio.logFree(OpenStudio::Debug, 'openstudio.standards.Model', "#{obj.name} is unused; it will be removed.")
4587
4653
  model.removeObject(obj.handle)
4588
4654
  end
4589
4655
  end
4590
4656
  end_size = model.objects.size
4591
- OpenStudio::logFree(OpenStudio::Info, 'openstudio.standards.Model', "The model started with #{start_size} objects and finished with #{end_size} objects after removing unused resource objects.")
4657
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "The model started with #{start_size} objects and finished with #{end_size} objects after removing unused resource objects.")
4592
4658
  return true
4593
4659
  end
4594
4660
 
@@ -4608,13 +4674,12 @@ class Standard
4608
4674
  # @param gen_occ_profile [Bool] if true creates a merged occupancy schedule for diagnostic purposes. This schedule is added to the model but no specifically returned by this method
4609
4675
  # @return [ScheduleRuleset] schedule that is assigned to the building as default hours of operation
4610
4676
  def model_infer_hours_of_operation_building(model, fraction_of_daily_occ_range: 0.25, invert_res: true, gen_occ_profile: false)
4611
-
4612
4677
  # create an array of non-residential and residential spaces
4613
4678
  res_spaces = []
4614
4679
  non_res_spaces = []
4615
4680
  res_people_design = 0
4616
4681
  non_res_people_design = 0
4617
- model.getSpaces.each do |space|
4682
+ model.getSpaces.sort.each do |space|
4618
4683
  if space_residential?(space)
4619
4684
  res_spaces << space
4620
4685
  res_people_design += space.numberOfPeople * space.multiplier
@@ -4623,31 +4688,31 @@ class Standard
4623
4688
  non_res_people_design += space.numberOfPeople * space.multiplier
4624
4689
  end
4625
4690
  end
4626
- OpenStudio::logFree(OpenStudio::Info, "openstudio.Standards.Model", "Model has design level of #{non_res_people_design} people in non residential spaces and #{res_people_design} people in residential spaces.")
4691
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.Standards.Model', "Model has design level of #{non_res_people_design} people in non residential spaces and #{res_people_design} people in residential spaces.")
4627
4692
 
4628
4693
  # create merged schedule for prevalent type (not used but can be generated for diagnostics)
4629
4694
  if gen_occ_profile
4630
4695
  res_prevalent = false
4631
4696
  if res_people_design > non_res_people_design
4632
- occ_merged = spaces_get_occupancy_schedule(res_spaces, sch_name: "Calculated Occupancy Fraction Residential Merged")
4697
+ occ_merged = spaces_get_occupancy_schedule(res_spaces, sch_name: 'Calculated Occupancy Fraction Residential Merged')
4633
4698
  res_prevalent = true
4634
4699
  else
4635
- occ_merged = spaces_get_occupancy_schedule(non_res_spaces, sch_name: "Calculated Occupancy Fraction NonResidential Merged")
4700
+ occ_merged = spaces_get_occupancy_schedule(non_res_spaces, sch_name: 'Calculated Occupancy Fraction NonResidential Merged')
4636
4701
  end
4637
4702
  end
4638
4703
 
4639
4704
  # re-run spaces_get_occupancy_schedule with x above min occupancy to create on/off schedule
4640
4705
  if res_people_design > non_res_people_design
4641
4706
  hours_of_operation = spaces_get_occupancy_schedule(res_spaces,
4642
- sch_name: "Building Hours of Operation Residential",
4643
- occupied_percentage_threshold: fraction_of_daily_occ_range,
4644
- threshold_calc_method: "normalized_daily_range")
4707
+ sch_name: 'Building Hours of Operation Residential',
4708
+ occupied_percentage_threshold: fraction_of_daily_occ_range,
4709
+ threshold_calc_method: 'normalized_daily_range')
4645
4710
  res_prevalent = true
4646
4711
  else
4647
4712
  hours_of_operation = spaces_get_occupancy_schedule(non_res_spaces,
4648
- sch_name: "Building Hours of Operation NonResidential",
4649
- occupied_percentage_threshold: fraction_of_daily_occ_range,
4650
- threshold_calc_method: "normalized_daily_range")
4713
+ sch_name: 'Building Hours of Operation NonResidential',
4714
+ occupied_percentage_threshold: fraction_of_daily_occ_range,
4715
+ threshold_calc_method: 'normalized_daily_range')
4651
4716
  end
4652
4717
 
4653
4718
  # remove gaps resulting in multiple on off cycles for each rule in schedule so it will be valid hours of operation
@@ -4656,10 +4721,11 @@ class Standard
4656
4721
  hours_of_operation.scheduleRules.each do |rule|
4657
4722
  profiles << rule.daySchedule
4658
4723
  end
4659
- profiles.each do |profile|
4724
+ profiles.sort.each do |profile|
4660
4725
  times = profile.times
4661
4726
  values = profile.values
4662
4727
  next if times.size <= 3 # length of 1-3 should produce valid hours_of_operation profiles
4728
+
4663
4729
  # Find the latest time where the value == 1
4664
4730
  latest_time = nil
4665
4731
  times.zip(values).each do |time, value|
@@ -4669,6 +4735,7 @@ class Standard
4669
4735
  end
4670
4736
  # Skip profiles that are zero all the time
4671
4737
  next if latest_time.nil?
4738
+
4672
4739
  # Calculate the duration from this point to midnight
4673
4740
  wrap_dur_left_hr = 0
4674
4741
  if values.first == 0 && values.last == 0
@@ -4677,9 +4744,10 @@ class Standard
4677
4744
  occ_gap_hash = {}
4678
4745
  prev_time = 0
4679
4746
  prev_val = nil
4680
- times.each_with_index do |time,i|
4747
+ times.each_with_index do |time, i|
4681
4748
  next if time.totalHours == 0.0 # should not see this
4682
4749
  next if values[i] == prev_val # check if two 0 until time next to each other
4750
+
4683
4751
  if values[i] == 0 # only store vacant segments
4684
4752
  if time.totalHours == 24
4685
4753
  occ_gap_hash[prev_time] = time.totalHours - prev_time + wrap_dur_left_hr
@@ -4705,44 +4773,42 @@ class Standard
4705
4773
  target_end_min = ((max_occ_gap_end_hr - target_end_hr) * 60.0).truncate
4706
4774
  max_occ_gap_end = OpenStudio::Time.new(0, target_end_hr, target_end_min, 0)
4707
4775
 
4708
- profile.addValue(max_occ_gap_start,1)
4709
- profile.addValue(max_occ_gap_end,0)
4776
+ profile.addValue(max_occ_gap_start, 1)
4777
+ profile.addValue(max_occ_gap_end, 0)
4710
4778
  os_time_24 = OpenStudio::Time.new(0, 24, 0, 0)
4711
4779
  if max_occ_gap_start > max_occ_gap_end
4712
- profile.addValue(os_time_24,0)
4780
+ profile.addValue(os_time_24, 0)
4713
4781
  else
4714
- profile.addValue(os_time_24,1)
4782
+ profile.addValue(os_time_24, 1)
4715
4783
  end
4716
4784
  end
4717
4785
 
4718
4786
  # reverse 1 and 0 values for res_prevalent building
4719
4787
  # currently spaces_get_occupancy_schedule doesn't use defaultDayProflie, so only inspecting rules for now.
4720
4788
  if invert_res && res_prevalent
4721
- OpenStudio::logFree(OpenStudio::Info, "openstudio.Standards.Model", "Per argument passed in hours of operation are being inverted for buildings with more people in residential versus non-residential spaces.")
4789
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.Standards.Model', 'Per argument passed in hours of operation are being inverted for buildings with more people in residential versus non-residential spaces.')
4722
4790
  hours_of_operation.scheduleRules.each do |rule|
4723
4791
  profile = rule.daySchedule
4724
4792
  times = profile.times
4725
4793
  values = profile.values
4726
4794
  profile.clearValues
4727
- times.each_with_index do |time,i|
4795
+ times.each_with_index do |time, i|
4728
4796
  orig_val = values[i]
4729
4797
  new_value = nil
4730
4798
  if orig_val == 0 then new_value = 1 end
4731
4799
  if orig_val == 1 then new_value = 0 end
4732
- profile.addValue(time,new_value)
4800
+ profile.addValue(time, new_value)
4733
4801
  end
4734
4802
  end
4735
4803
  end
4736
4804
 
4737
4805
  # set hours of operation for building level hours of operation
4738
- model.getDefaultScheduleSets.each do |sch_set|
4739
- sch_set.resetHoursofOperationSchedule
4740
- end
4806
+ model.getDefaultScheduleSets.each(&:resetHoursofOperationSchedule)
4741
4807
  if model.getBuilding.defaultScheduleSet.is_initialized
4742
4808
  default_sch_set = model.getBuilding.defaultScheduleSet.get
4743
4809
  else
4744
4810
  default_sch_set = OpenStudio::Model::DefaultScheduleSet.new(model)
4745
- default_sch_set.setName("Building Default Schedule Set")
4811
+ default_sch_set.setName('Building Default Schedule Set')
4746
4812
  model.getBuilding.setDefaultScheduleSet(default_sch_set)
4747
4813
  end
4748
4814
  default_sch_set.setHoursofOperationSchedule(hours_of_operation)
@@ -4759,9 +4825,10 @@ class Standard
4759
4825
  # @param model [Model]
4760
4826
  # @param step_ramp_logic [String]
4761
4827
  # @param infer_hoo_for_non_assigned_objects [Bool] # attempt to get hoo for objects like swh with and exterior lighting
4828
+ # @param gather_data_only: false (stops method before changes made if true)
4829
+ # @param [hoo_var_method] accepts hours and fractional. Any other value value will result in hoo variables not being applied
4762
4830
  # @return [Hash] schedule is key, value is hash of number of objects
4763
- def model_setup_parametric_schedules(model, step_ramp_logic: nil, infer_hoo_for_non_assigned_objects: true,gather_data_only: false)
4764
-
4831
+ def model_setup_parametric_schedules(model, step_ramp_logic: nil, infer_hoo_for_non_assigned_objects: true, gather_data_only: false, hoo_var_method: 'hours')
4765
4832
  parametric_inputs = {}
4766
4833
  default_sch_type = OpenStudio::Model::DefaultScheduleType.new('HoursofOperationSchedule')
4767
4834
  # thermal zones, air loops, plant loops will require some logic if they refer to more than one hours of operaiton schedule.
@@ -4771,14 +4838,14 @@ class Standard
4771
4838
  # whatever approach is used for gathering parametric inputs for existing ruleset schedules should also be used for model_apply_parametric_schedules
4772
4839
 
4773
4840
  # loop through spaces (trace hours of operation back to space)
4774
- gather_inputs_parametric_space_space_type_schedules(model.getSpaces,parametric_inputs,gather_data_only)
4841
+ gather_inputs_parametric_space_space_type_schedules(model.getSpaces, parametric_inputs, gather_data_only)
4775
4842
 
4776
4843
  # loop through space types (trace hours of operation back to space type).
4777
- gather_inputs_parametric_space_space_type_schedules(model.getSpaceTypes,parametric_inputs,gather_data_only)
4844
+ gather_inputs_parametric_space_space_type_schedules(model.getSpaceTypes, parametric_inputs, gather_data_only)
4778
4845
 
4779
4846
  # loop through thermal zones (trace hours of operation back to spaces in thermal zone)
4780
4847
  thermal_zone_hash = {} # key is zone and hash is hours of operation
4781
- model.getThermalZones.each do |zone|
4848
+ model.getThermalZones.sort.each do |zone|
4782
4849
  # identify hours of operation
4783
4850
  hours_of_operation = spaces_hours_of_operation(zone.spaces)
4784
4851
  thermal_zone_hash[zone] = hours_of_operation
@@ -4787,39 +4854,39 @@ class Standard
4787
4854
  thermostat = zone.thermostatSetpointDualSetpoint.get
4788
4855
  if thermostat.heatingSetpointTemperatureSchedule.is_initialized && thermostat.heatingSetpointTemperatureSchedule.get.to_ScheduleRuleset.is_initialized
4789
4856
  schedule = thermostat.heatingSetpointTemperatureSchedule.get.to_ScheduleRuleset.get
4790
- gather_inputs_parametric_schedules(schedule,thermostat,parametric_inputs,hours_of_operation,gather_data_only: gather_data_only)
4857
+ gather_inputs_parametric_schedules(schedule, thermostat, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: hoo_var_method)
4791
4858
  end
4792
- if thermostat.coolingSetpointTemperatureSchedule.is_initialized&& thermostat.coolingSetpointTemperatureSchedule.get.to_ScheduleRuleset.is_initialized
4859
+ if thermostat.coolingSetpointTemperatureSchedule.is_initialized && thermostat.coolingSetpointTemperatureSchedule.get.to_ScheduleRuleset.is_initialized
4793
4860
  schedule = thermostat.coolingSetpointTemperatureSchedule.get.to_ScheduleRuleset.get
4794
- gather_inputs_parametric_schedules(schedule,thermostat,parametric_inputs,hours_of_operation,gather_data_only: gather_data_only)
4861
+ gather_inputs_parametric_schedules(schedule, thermostat, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: hoo_var_method)
4795
4862
  end
4796
4863
  end
4797
4864
  end
4798
4865
 
4799
4866
  # loop through air loops (trace hours of operation back through spaces served by air loops)
4800
4867
  air_loop_hash = {} # key is zone and hash is hours of operation
4801
- model.getAirLoopHVACs.each do |air_loop|
4868
+ model.getAirLoopHVACs.sort.each do |air_loop|
4802
4869
  # identify hours of operation
4803
4870
  air_loop_spaces = []
4804
- air_loop.thermalZones.each do |zone|
4805
- air_loop_spaces = air_loop_spaces + zone.spaces
4806
- air_loop_spaces = air_loop_spaces + zone.spaces
4871
+ air_loop.thermalZones.sort.each do |zone|
4872
+ air_loop_spaces += zone.spaces
4873
+ air_loop_spaces += zone.spaces
4807
4874
  end
4808
4875
  hours_of_operation = spaces_hours_of_operation(air_loop_spaces)
4809
4876
  air_loop_hash[air_loop] = hours_of_operation
4810
4877
  if air_loop.availabilitySchedule.to_ScheduleRuleset.is_initialized
4811
4878
  schedule = air_loop.availabilitySchedule.to_ScheduleRuleset.get
4812
- gather_inputs_parametric_schedules(schedule,air_loop,parametric_inputs,hours_of_operation,gather_data_only: gather_data_only)
4879
+ gather_inputs_parametric_schedules(schedule, air_loop, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: hoo_var_method)
4813
4880
  end
4814
4881
  avail_mgrs = air_loop.availabilityManagers
4815
- avail_mgrs.each do |avail_mgr|
4816
- # todo - I'm finding availability mangers, but not any resources for them, even if I use OpenStudio::Model.getRecursiveChildren(avail_mgr)
4882
+ avail_mgrs.sort.each do |avail_mgr|
4883
+ # TODO: - I'm finding availability mangers, but not any resources for them, even if I use OpenStudio::Model.getRecursiveChildren(avail_mgr)
4817
4884
  resources = avail_mgr.resources
4818
4885
  resources = OpenStudio::Model.getRecursiveResources(avail_mgr)
4819
- resources.each do |resource|
4886
+ resources.sort.each do |resource|
4820
4887
  if resource.to_ScheduleRuleset.is_initialized
4821
4888
  schedule = resource.to_ScheduleRuleset.get
4822
- gather_inputs_parametric_schedules(schedule,avail_mgr,parametric_inputs,hours_of_operation,gather_data_only: gather_data_only)
4889
+ gather_inputs_parametric_schedules(schedule, avail_mgr, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: hoo_var_method)
4823
4890
  end
4824
4891
  end
4825
4892
  end
@@ -4827,7 +4894,7 @@ class Standard
4827
4894
 
4828
4895
  # look through all model HVAC components find scheduleRuleset objects, resources, that use them and zone or air loop for hours of operation
4829
4896
  hvac_components = model.getHVACComponents
4830
- hvac_components.each do |component|
4897
+ hvac_components.sort.each do |component|
4831
4898
  # identify zone, or air loop it refers to, some may refer to plant loop, OA or other component
4832
4899
  thermal_zone = nil
4833
4900
  air_loop = nil
@@ -4838,12 +4905,11 @@ class Standard
4838
4905
  end
4839
4906
  if component.airLoopHVAC.is_initialized
4840
4907
  air_loop = component.airLoopHVAC.get
4841
- else
4842
4908
  end
4843
4909
  if component.plantLoop.is_initialized
4844
4910
  plant_loop = component.plantLoop.get
4845
4911
  end
4846
- component.resources.each do |resource|
4912
+ component.resources.sort.each do |resource|
4847
4913
  if resource.to_ThermalZone.is_initialized
4848
4914
  thermal_zone = resource.to_ThermalZone.get
4849
4915
  elsif resource.to_ScheduleRuleset.is_initialized
@@ -4854,9 +4920,10 @@ class Standard
4854
4920
  # inspect resources for children of objects found in thermal zone or plant loop
4855
4921
  # get objects like OA controllers and unitary object components
4856
4922
  next if thermal_zone.nil? && air_loop.nil?
4923
+
4857
4924
  children = OpenStudio::Model.getRecursiveChildren(component)
4858
- children.each do |child|
4859
- child.resources.each do |sub_resource|
4925
+ children.sort.each do |child|
4926
+ child.resources.sort.each do |sub_resource|
4860
4927
  if sub_resource.to_ScheduleRuleset.is_initialized
4861
4928
  schedules << sub_resource.to_ScheduleRuleset.get
4862
4929
  end
@@ -4864,7 +4931,7 @@ class Standard
4864
4931
  end
4865
4932
 
4866
4933
  # process schedules found for this component
4867
- schedules.each do |schedule|
4934
+ schedules.sort.each do |schedule|
4868
4935
  hours_of_operation = nil
4869
4936
  if !thermal_zone.nil?
4870
4937
  hours_of_operation = thermal_zone_hash[thermal_zone]
@@ -4877,37 +4944,35 @@ class Standard
4877
4944
  OpenStudio.logFree(OpenStudio::Warn, 'openstudio.model.Model', "Cannot identify where #{component.name.get} is in system. Will not gather parametric inputs for #{schedule.name.get}")
4878
4945
  next
4879
4946
  end
4880
- gather_inputs_parametric_schedules(schedule,component,parametric_inputs,hours_of_operation,gather_data_only: gather_data_only)
4947
+ gather_inputs_parametric_schedules(schedule, component, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: hoo_var_method)
4881
4948
  end
4882
-
4883
4949
  end
4884
4950
 
4885
- # todo - Service Water Heating supply side (may or may not be associated with a space)
4951
+ # TODO: - Service Water Heating supply side (may or may not be associated with a space)
4886
4952
  # todo - water use equipment definitions (temperature, sensible, latent) may be in multiple spaces, need to identify hoo, but typically constant schedules
4887
4953
 
4888
4954
  # water use equipment (flow rate fraction)
4889
4955
  # todo - address common schedules used across multiple instances
4890
- model.getWaterUseEquipments.each do |water_use_equipment|
4891
-
4956
+ model.getWaterUseEquipments.sort.each do |water_use_equipment|
4892
4957
  if water_use_equipment.flowRateFractionSchedule.is_initialized && water_use_equipment.flowRateFractionSchedule.get.to_ScheduleRuleset.is_initialized
4893
4958
  schedule = water_use_equipment.flowRateFractionSchedule.get.to_ScheduleRuleset.get
4894
- next if parametric_inputs.has_key?(schedule)
4959
+ next if parametric_inputs.key?(schedule)
4895
4960
 
4896
4961
  opt_space = water_use_equipment.space
4897
4962
  if opt_space.is_initialized
4898
4963
  space = space.get
4899
4964
  hours_of_operation = space_hours_of_operation(space)
4900
- gather_inputs_parametric_schedules(schedule,water_use_equipment,parametric_inputs,hours_of_operation,gather_data_only: gather_data_only)
4965
+ gather_inputs_parametric_schedules(schedule, water_use_equipment, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: hoo_var_method)
4901
4966
  else
4902
4967
  hours_of_operation = spaces_hours_of_operation(model.getSpaces)
4903
4968
  if !hours_of_operation.nil?
4904
- gather_inputs_parametric_schedules(schedule,water_use_equipment,parametric_inputs,hours_of_operation,gather_data_only: gather_data_only)
4969
+ gather_inputs_parametric_schedules(schedule, water_use_equipment, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: hoo_var_method)
4905
4970
  end
4906
4971
  end
4907
4972
 
4908
4973
  end
4909
4974
  end
4910
- # todo - Refrigeration (will be associated with thermal zone)
4975
+ # TODO: - Refrigeration (will be associated with thermal zone)
4911
4976
  # todo - exterior lights (will be astronomical, but like AEDG's may have reduction later at night)
4912
4977
 
4913
4978
  return parametric_inputs
@@ -4926,7 +4991,6 @@ class Standard
4926
4991
  # @param error_on_out_of_order [Bool] true will error if applying formula creates out of order values
4927
4992
  # @return [Array] of modified ScheduleRuleset objects
4928
4993
  def model_apply_parametric_schedules(model, ramp_frequency: nil, infer_hoo_for_non_assigned_objects: true, error_on_out_of_order: true)
4929
-
4930
4994
  # get ramp frequency (fractional hour) from timestep
4931
4995
  if ramp_frequency.nil?
4932
4996
  steps_per_hour = if model.getSimulationControl.timestep.is_initialized
@@ -4934,32 +4998,31 @@ class Standard
4934
4998
  else
4935
4999
  6 # default OpenStudio timestep if none specified
4936
5000
  end
4937
- ramp_frequency = 1.0/steps_per_hour.to_f
5001
+ ramp_frequency = 1.0 / steps_per_hour.to_f
4938
5002
  end
4939
5003
 
4940
5004
  # Go through model and create parametric formulas for all schedules
4941
- parametric_inputs = model_setup_parametric_schedules(model,gather_data_only: true)
5005
+ parametric_inputs = model_setup_parametric_schedules(model, gather_data_only: true)
4942
5006
 
4943
5007
  parametric_schedules = []
4944
5008
  model.getScheduleRulesets.sort.each do |sch|
4945
- if !sch.hasAdditionalProperties or !sch.additionalProperties.hasFeature("param_sch_ver")
5009
+ if !sch.hasAdditionalProperties || !sch.additionalProperties.hasFeature('param_sch_ver')
4946
5010
  # for now don't look at schedules without targets, in future can alter these by looking at building level hours of operation
4947
- next if not sch.directUseCount > 0 # won't catch if used for space type load instance, but that space type isn't used
4948
- # todo - address schedules that fall into this category, if they are used in the model
5011
+ next if sch.directUseCount <= 0 # won't catch if used for space type load instance, but that space type isn't used
5012
+
5013
+ # TODO: - address schedules that fall into this category, if they are used in the model
4949
5014
  OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Model', "For #{sch.sources.first.name}, #{sch.name} is not setup as parametric schedule. It has #{sch.sources.size} sources.")
4950
5015
  next
4951
5016
  end
4952
5017
 
4953
5018
  # apply parametric inputs
4954
- schedule_apply_parametric_inputs(sch,ramp_frequency,infer_hoo_for_non_assigned_objects,error_on_out_of_order,parametric_inputs)
5019
+ schedule_apply_parametric_inputs(sch, ramp_frequency, infer_hoo_for_non_assigned_objects, error_on_out_of_order, parametric_inputs)
4955
5020
 
4956
5021
  # add schedule to array
4957
5022
  parametric_schedules << sch
4958
-
4959
5023
  end
4960
5024
 
4961
5025
  return parametric_schedules
4962
-
4963
5026
  end
4964
5027
 
4965
5028
  private
@@ -4971,6 +5034,7 @@ class Standard
4971
5034
  elsif sch_type == 'Hourly'
4972
5035
  (0..23).each do |i|
4973
5036
  next if values[i] == values[i + 1]
5037
+
4974
5038
  day_sch.addValue(OpenStudio::Time.new(0, i + 1, 0, 0), values[i])
4975
5039
  end
4976
5040
  else
@@ -5042,6 +5106,7 @@ class Standard
5042
5106
  if electric
5043
5107
  plant_loop.supplyComponents.each do |component|
5044
5108
  next unless component.to_WaterHeaterMixed.is_initialized
5109
+
5045
5110
  water_heater = component.to_WaterHeaterMixed.get
5046
5111
  # G3.1.11.b: If electric, WaterHeater:Mixed with electric resistance
5047
5112
  water_heater.setHeaterFuelType('Electricity')
@@ -5082,8 +5147,6 @@ class Standard
5082
5147
  return true
5083
5148
  end
5084
5149
 
5085
-
5086
-
5087
5150
  def load_user_geometry_osm(osm_model_path:)
5088
5151
  version_translator = OpenStudio::OSVersion::VersionTranslator.new
5089
5152
  model = version_translator.loadModel(osm_model_path)
@@ -5121,11 +5184,6 @@ class Standard
5121
5184
  return model
5122
5185
  end
5123
5186
 
5124
-
5125
-
5126
-
5127
-
5128
-
5129
5187
  # Loads a osm as a starting point.
5130
5188
  #
5131
5189
  # @param osm_file [String] path to the .osm file, relative to the /data folder
@@ -5178,7 +5236,6 @@ class Standard
5178
5236
  end
5179
5237
  end
5180
5238
  return model
5181
-
5182
5239
  end
5183
5240
 
5184
5241
  # pass array of space types or spaces
@@ -5186,51 +5243,51 @@ class Standard
5186
5243
  # @author David Goldwasser
5187
5244
  # @param array of spaces or space types
5188
5245
  # @return hash
5189
- def gather_inputs_parametric_space_space_type_schedules(space_space_types,parametric_inputs,gather_data_only)
5190
-
5246
+ def gather_inputs_parametric_space_space_type_schedules(space_space_types, parametric_inputs, gather_data_only)
5191
5247
  space_space_types.each do |space_type|
5192
5248
  # get hours of operation for space type once
5193
- next if space_type.class == "OpenStudio::Model::SpaceTypes" && space_type.floorArea == 0
5249
+ next if space_type.class == 'OpenStudio::Model::SpaceTypes' && space_type.floorArea == 0
5250
+
5194
5251
  hours_of_operation = space_hours_of_operation(space_type)
5195
5252
  if hours_of_operation.nil?
5196
- OpenStudio::logFree(OpenStudio::Warn, "openstudio.Standards.Model", "Can't evaluate schedules for #{space_type.name}, doesn't have hours of operation.")
5253
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.Standards.Model', "Can't evaluate schedules for #{space_type.name}, doesn't have hours of operation.")
5197
5254
  next
5198
5255
  end
5199
5256
  # loop through internal load instances
5200
5257
  space_type.lights.each do |load_inst|
5201
- gather_inputs_parametric_load_inst_schedules(load_inst,parametric_inputs,hours_of_operation,gather_data_only)
5258
+ gather_inputs_parametric_load_inst_schedules(load_inst, parametric_inputs, hours_of_operation, gather_data_only)
5202
5259
  end
5203
5260
  space_type.luminaires.each do |load_inst|
5204
- gather_inputs_parametric_load_inst_schedules(load_inst,parametric_inputs,hours_of_operation,gather_data_only)
5261
+ gather_inputs_parametric_load_inst_schedules(load_inst, parametric_inputs, hours_of_operation, gather_data_only)
5205
5262
  end
5206
5263
  space_type.electricEquipment.each do |load_inst|
5207
- gather_inputs_parametric_load_inst_schedules(load_inst,parametric_inputs,hours_of_operation,gather_data_only)
5264
+ gather_inputs_parametric_load_inst_schedules(load_inst, parametric_inputs, hours_of_operation, gather_data_only)
5208
5265
  end
5209
5266
  space_type.gasEquipment.each do |load_inst|
5210
- gather_inputs_parametric_load_inst_schedules(load_inst,parametric_inputs,hours_of_operation,gather_data_only)
5267
+ gather_inputs_parametric_load_inst_schedules(load_inst, parametric_inputs, hours_of_operation, gather_data_only)
5211
5268
  end
5212
5269
  space_type.steamEquipment.each do |load_inst|
5213
- gather_inputs_parametric_load_inst_schedules(load_inst,parametric_inputs,hours_of_operation,gather_data_only)
5270
+ gather_inputs_parametric_load_inst_schedules(load_inst, parametric_inputs, hours_of_operation, gather_data_only)
5214
5271
  end
5215
5272
  space_type.otherEquipment.each do |load_inst|
5216
- gather_inputs_parametric_load_inst_schedules(load_inst,parametric_inputs,hours_of_operation,gather_data_only)
5273
+ gather_inputs_parametric_load_inst_schedules(load_inst, parametric_inputs, hours_of_operation, gather_data_only)
5217
5274
  end
5218
5275
  space_type.people.each do |load_inst|
5219
- gather_inputs_parametric_load_inst_schedules(load_inst,parametric_inputs,hours_of_operation,gather_data_only)
5276
+ gather_inputs_parametric_load_inst_schedules(load_inst, parametric_inputs, hours_of_operation, gather_data_only)
5220
5277
  if load_inst.activityLevelSchedule.is_initialized && load_inst.activityLevelSchedule.get.to_ScheduleRuleset.is_initialized
5221
5278
  act_sch = load_inst.activityLevelSchedule.get.to_ScheduleRuleset.get
5222
- gather_inputs_parametric_schedules(act_sch,load_inst,parametric_inputs,hours_of_operation,gather_data_only: gather_data_only)
5279
+ gather_inputs_parametric_schedules(act_sch, load_inst, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: 'hours')
5223
5280
  end
5224
5281
  end
5225
5282
  space_type.spaceInfiltrationDesignFlowRates.each do |load_inst|
5226
- gather_inputs_parametric_load_inst_schedules(load_inst,parametric_inputs,hours_of_operation,gather_data_only)
5283
+ gather_inputs_parametric_load_inst_schedules(load_inst, parametric_inputs, hours_of_operation, gather_data_only)
5227
5284
  end
5228
5285
  space_type.spaceInfiltrationEffectiveLeakageAreas.each do |load_inst|
5229
- gather_inputs_parametric_load_inst_schedules(load_inst,parametric_inputs,hours_of_operation,gather_data_only)
5286
+ gather_inputs_parametric_load_inst_schedules(load_inst, parametric_inputs, hours_of_operation, gather_data_only)
5230
5287
  end
5231
5288
  dsgn_spec_oa = space_type.designSpecificationOutdoorAir
5232
5289
  if dsgn_spec_oa.is_initialized
5233
- gather_inputs_parametric_load_inst_schedules(dsgn_spec_oa.get,parametric_inputs,hours_of_operation,gather_data_only)
5290
+ gather_inputs_parametric_load_inst_schedules(dsgn_spec_oa.get, parametric_inputs, hours_of_operation, gather_data_only)
5234
5291
  end
5235
5292
  end
5236
5293
 
@@ -5242,10 +5299,10 @@ class Standard
5242
5299
  # @author David Goldwasser
5243
5300
  # @param opt_sch
5244
5301
  # @return hash
5245
- def gather_inputs_parametric_load_inst_schedules(load_inst,parametric_inputs,hours_of_operation,gather_data_only)
5246
- if load_inst.class.to_s == "OpenStudio::Model::People"
5302
+ def gather_inputs_parametric_load_inst_schedules(load_inst, parametric_inputs, hours_of_operation, gather_data_only)
5303
+ if load_inst.class.to_s == 'OpenStudio::Model::People'
5247
5304
  opt_sch = load_inst.numberofPeopleSchedule
5248
- elsif load_inst.class.to_s == "OpenStudio::Model::DesignSpecificationOutdoorAir"
5305
+ elsif load_inst.class.to_s == 'OpenStudio::Model::DesignSpecificationOutdoorAir'
5249
5306
  opt_sch = load_inst.outdoorAirFlowRateFractionSchedule
5250
5307
  else
5251
5308
  opt_sch = load_inst.schedule
@@ -5253,7 +5310,8 @@ class Standard
5253
5310
  if !opt_sch.is_initialized || !opt_sch.get.to_ScheduleRuleset.is_initialized
5254
5311
  return nil
5255
5312
  end
5256
- gather_inputs_parametric_schedules(opt_sch.get.to_ScheduleRuleset.get,load_inst,parametric_inputs,hours_of_operation,gather_data_only: gather_data_only)
5313
+
5314
+ gather_inputs_parametric_schedules(opt_sch.get.to_ScheduleRuleset.get, load_inst, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: 'hours')
5257
5315
 
5258
5316
  return parametric_inputs
5259
5317
  end
@@ -5264,18 +5322,17 @@ class Standard
5264
5322
  # @param [sch]
5265
5323
  # @param [hoo_var_Method] accepts hours and fractional. Any other value value will result in hoo variables not being applied
5266
5324
  # @return [hash]
5267
- def gather_inputs_parametric_schedules(sch,load_inst,parametric_inputs,hours_of_operation,ramp: true,min_ramp_dur_hr: 2.0,gather_data_only: false,hoo_var_method: "hours")
5268
-
5269
- if parametric_inputs.has_key?(sch)
5325
+ def gather_inputs_parametric_schedules(sch, load_inst, parametric_inputs, hours_of_operation, ramp: true, min_ramp_dur_hr: 2.0, gather_data_only: false, hoo_var_method: 'hours')
5326
+ if parametric_inputs.key?(sch)
5270
5327
  if hours_of_operation != parametric_inputs[sch][:hoo_inputs] # don't warn if the hours of operation between old and new schedule are equivalent
5271
- OpenStudio::logFree(OpenStudio::Warn, "openstudio.Standards.Model", "#{load_inst.name} uses #{sch.name} but parametric inputs have already been setup based on hours of operation for #{parametric_inputs[sch][:target].name.to_s}.")
5328
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.Standards.Model', "#{load_inst.name} uses #{sch.name} but parametric inputs have already been setup based on hours of operation for #{parametric_inputs[sch][:target].name}.")
5272
5329
  return nil
5273
5330
  end
5274
5331
  end
5275
5332
 
5276
5333
  # gather and store data for scheduleRuleset
5277
5334
  min_max = schedule_ruleset_annual_min_max_value(sch)
5278
- ruleset_hash = {floor: min_max['min'], ceiling: min_max['max'], target: load_inst, hoo_inputs: hours_of_operation}
5335
+ ruleset_hash = { floor: min_max['min'], ceiling: min_max['max'], target: load_inst, hoo_inputs: hours_of_operation }
5279
5336
  parametric_inputs[sch] = ruleset_hash
5280
5337
 
5281
5338
  # stop here if only gathering information otherwise will continue and generate additional parametric properties for schedules and rules
@@ -5283,9 +5340,9 @@ class Standard
5283
5340
 
5284
5341
  # set scheduleRuleset properties
5285
5342
  props = sch.additionalProperties
5286
- props.setFeature("param_sch_ver","0.0.1") # this is needed to see if formulas are in sync with version of standards that processes them also used to flag schedule as parametric
5287
- props.setFeature("param_sch_floor",min_max['min'])
5288
- props.setFeature("param_sch_ceiling",min_max['max'])
5343
+ props.setFeature('param_sch_ver', '0.0.1') # this is needed to see if formulas are in sync with version of standards that processes them also used to flag schedule as parametric
5344
+ props.setFeature('param_sch_floor', min_max['min'])
5345
+ props.setFeature('param_sch_ceiling', min_max['max'])
5289
5346
 
5290
5347
  # cleanup existing profiles
5291
5348
  schedule_ruleset_cleanup_profiles(sch)
@@ -5308,18 +5365,17 @@ class Standard
5308
5365
  indices_vector = sch.getActiveRuleIndices(year_start_date, year_end_date)
5309
5366
 
5310
5367
  # step through profiles and add additional properties to describe profiles
5311
- schedule_days.each_with_index do |(schedule_day,current_rule_index),i|
5312
-
5368
+ schedule_days.each_with_index do |(schedule_day, current_rule_index), i|
5313
5369
  # loop through indices looking of rule in hoo that contains days in the rule
5314
5370
  hoo_target_index = nil
5315
5371
  days_used = []
5316
- indices_vector.each_with_index do |profile_index,i|
5317
- if profile_index == current_rule_index then days_used << i+1 end
5372
+ indices_vector.each_with_index do |profile_index, i|
5373
+ if profile_index == current_rule_index then days_used << i + 1 end
5318
5374
  end
5319
5375
  # find days_used in hoo profiles that contains all days used from this profile
5320
5376
  hoo_profile_match_hash = {}
5321
5377
  best_fit_check = {}
5322
- hours_of_operation.each do |profile_index,value|
5378
+ hours_of_operation.each do |profile_index, value|
5323
5379
  days_for_rule_not_in_hoo_profile = days_used - value[:days_used]
5324
5380
  hoo_profile_match_hash[profile_index] = days_for_rule_not_in_hoo_profile
5325
5381
  best_fit_check[profile_index] = days_for_rule_not_in_hoo_profile.size
@@ -5333,7 +5389,7 @@ class Standard
5333
5389
  hoo_end = nil
5334
5390
  occ = nil
5335
5391
  vac = nil
5336
- # todo - issue warning when this happens on any profile that isn't a constant value
5392
+ # TODO: - issue warning when this happens on any profile that isn't a constant value
5337
5393
  else
5338
5394
  # get hours of operation for this specific profile
5339
5395
  hoo_start = hours_of_operation[hoo_target_index][:hoo_start]
@@ -5346,8 +5402,7 @@ class Standard
5346
5402
  par_val_time_hash = {} # time is key, value is value in and optional value out as a one or two object array
5347
5403
  times = schedule_day.times
5348
5404
  values = schedule_day.values
5349
- values.each_with_index do |value,j|
5350
-
5405
+ values.each_with_index do |value, j|
5351
5406
  # don't add value until 24 if it is the same as first value for non constant profiles
5352
5407
  if values.size > 1 && j == values.size - 1 && value == values.first
5353
5408
  next
@@ -5355,18 +5410,18 @@ class Standard
5355
5410
 
5356
5411
  current_time = times[j].totalHours
5357
5412
  # if step height goes floor to ceiling then do not ramp.
5358
- if !ramp or values.uniq.size < 3
5413
+ if !ramp || (values.uniq.size < 3)
5359
5414
  # this will result in steps like old profiles, update to ramp in most cases
5360
5415
  if j == values.size - 1
5361
- par_val_time_hash[current_time] = [value,values.first]
5416
+ par_val_time_hash[current_time] = [value, values.first]
5362
5417
  else
5363
- par_val_time_hash[current_time] = [value,values[j+1]]
5418
+ par_val_time_hash[current_time] = [value, values[j + 1]]
5364
5419
  end
5365
5420
  else
5366
5421
  if j == 0
5367
5422
  prev_time = times.last.totalHours - 24 # e.g. 24 would show as until 0
5368
5423
  else
5369
- prev_time = times[j-1].totalHours
5424
+ prev_time = times[j - 1].totalHours
5370
5425
  end
5371
5426
  if j == values.size - 1
5372
5427
  next_time = times.first.totalHours + 24 # e.g. 6 would show as until 30
@@ -5378,15 +5433,15 @@ class Standard
5378
5433
  end
5379
5434
 
5380
5435
  else
5381
- next_time = times[j+1].totalHours
5382
- next_value = values[j+1]
5436
+ next_time = times[j + 1].totalHours
5437
+ next_value = values[j + 1]
5383
5438
  end
5384
5439
  # delta time is min min_ramp_dur_hr, half of previous dur, half of next dur
5385
5440
  # todo - would be nice to change to 0.25 for vally less than 2 hours
5386
5441
  multiplier = 0.5
5387
- delta = [min_ramp_dur_hr,(current_time - prev_time)*multiplier,(next_time - current_time)*multiplier].min
5442
+ delta = [min_ramp_dur_hr, (current_time - prev_time) * multiplier, (next_time - current_time) * multiplier].min
5388
5443
  # add value to left if not already added
5389
- if !par_val_time_hash.has_key?(current_time - delta)
5444
+ if !par_val_time_hash.key?(current_time - delta)
5390
5445
  time_left = current_time - delta
5391
5446
  if time_left < 0.0 then time_left += 24.0 end
5392
5447
  par_val_time_hash[time_left] = [value]
@@ -5403,11 +5458,11 @@ class Standard
5403
5458
 
5404
5459
  # calculate estimated value (not including any secondary logic)
5405
5460
  est_daily_flh = 0.0
5406
- prev_time = par_val_time_hash.keys.sort.last - 24.0
5461
+ prev_time = par_val_time_hash.keys.max - 24.0
5407
5462
  prev_value = par_val_time_hash.values.last.last # last value in last optional pair of values
5408
- par_val_time_hash.sort.each do |time,value_array|
5463
+ par_val_time_hash.sort.each do |time, value_array|
5409
5464
  segment_length = time - prev_time
5410
- avg_value = (value_array.first + prev_value)*0.5
5465
+ avg_value = (value_array.first + prev_value) * 0.5
5411
5466
  est_daily_flh += segment_length * avg_value
5412
5467
  prev_time = time
5413
5468
  prev_value = value_array.last
@@ -5415,16 +5470,15 @@ class Standard
5415
5470
 
5416
5471
  # test expected value against estimated value
5417
5472
  daily_flh = day_schedule_equivalent_full_load_hrs(schedule_day)
5418
- percent_change = ((daily_flh - est_daily_flh)/daily_flh) * 100.0
5473
+ percent_change = ((daily_flh - est_daily_flh) / daily_flh) * 100.0
5419
5474
  if percent_change.abs > 0.05
5420
- # todo - this estimation can have flaws. Fix or remove it, make sure to update for secondary logic (if we implement that here)
5475
+ # TODO: - this estimation can have flaws. Fix or remove it, make sure to update for secondary logic (if we implement that here)
5421
5476
  # post application checks compares against actual instead of estimated values
5422
5477
  OpenStudio.logFree(OpenStudio::Debug, 'openstudio.standards.Model', "For day schedule #{schedule_day.name} in #{sch.name} there was a #{percent_change.round(4)}% change. Expected full load hours is #{daily_flh.round(4)}, but estimated value is #{est_daily_flh.round(4)}")
5423
5478
  end
5424
5479
 
5425
5480
  raw_string = []
5426
- par_val_time_hash.sort.each do |time,value_array|
5427
-
5481
+ par_val_time_hash.sort.each do |time, value_array|
5428
5482
  # add in value variables
5429
5483
  # not currently using range, only using min max for constant schedules or schedules with just two values
5430
5484
  value_array_var = []
@@ -5447,20 +5501,20 @@ class Standard
5447
5501
  start_delta_array = [hoo_start - time, hoo_start - time + 24, hoo_start - time - 24]
5448
5502
  start_delta_array_abs = [(hoo_start - time).abs, (hoo_start - time + 24).abs, (hoo_start - time - 24).abs]
5449
5503
  start_delta_h = start_delta_array[start_delta_array_abs.index(start_delta_array_abs.min)]
5450
- formula_identifier["start"] = start_delta_h
5504
+ formula_identifier['start'] = start_delta_h
5451
5505
  mid_calc = hoo_start + occ * 0.5
5452
5506
  mid_delta_array = [mid_calc - time, mid_calc - time + 24, mid_calc - time - 24]
5453
5507
  mid_delta_array_abs = [(mid_calc - time).abs, (mid_calc - time + 24).abs, (mid_calc - time - 24).abs]
5454
5508
  mid_delta_h = mid_delta_array[mid_delta_array_abs.index(mid_delta_array_abs.min)]
5455
- formula_identifier["mid"] = mid_delta_h
5509
+ formula_identifier['mid'] = mid_delta_h
5456
5510
  end_delta_array = [hoo_end - time, hoo_end - time + 24, hoo_end - time - 24]
5457
5511
  end_delta_array_abs = [(hoo_end - time).abs, (hoo_end - time + 24).abs, (hoo_end - time - 24).abs]
5458
5512
  end_delta_h = end_delta_array[end_delta_array_abs.index(end_delta_array_abs.min)]
5459
- formula_identifier["end"] = end_delta_h
5513
+ formula_identifier['end'] = end_delta_h
5460
5514
 
5461
5515
  # need to store min absolute value to pick the best fit
5462
5516
  formula_identifier_min_abs = {}
5463
- formula_identifier.each do |k,v|
5517
+ formula_identifier.each do |k, v|
5464
5518
  formula_identifier_min_abs[k] = v.abs
5465
5519
  end
5466
5520
 
@@ -5468,20 +5522,20 @@ class Standard
5468
5522
  min_key = formula_identifier_min_abs.key(formula_identifier_min_abs.values.min)
5469
5523
  min_value = formula_identifier[min_key]
5470
5524
 
5471
- if hoo_var_method == "hours"
5525
+ if hoo_var_method == 'hours'
5472
5526
  # minimize x, which should be no greater than 12, see if rounding to 2 decimal places works
5473
5527
  min_value = min_value.round(2)
5474
- if min_key == "start"
5528
+ if min_key == 'start'
5475
5529
  if min_value == 0
5476
- time = "hoo_start"
5530
+ time = 'hoo_start'
5477
5531
  elsif min_value < 0
5478
5532
  time = "hoo_start + #{min_value.abs}"
5479
5533
  else # greater than 0
5480
5534
  time = "hoo_start - #{min_value}"
5481
5535
  end
5482
- elsif min_key == "mid"
5536
+ elsif min_key == 'mid'
5483
5537
  if min_value == 0
5484
- time = "mid"
5538
+ time = 'mid'
5485
5539
  # converted to variable for simplicity but could also be described like this
5486
5540
  # time = "hoo_start + occ * 0.5"
5487
5541
  elsif min_value < 0
@@ -5491,7 +5545,7 @@ class Standard
5491
5545
  end
5492
5546
  else # min_key == "end"
5493
5547
  if min_value == 0
5494
- time = "hoo_end"
5548
+ time = 'hoo_end'
5495
5549
  elsif min_value < 0
5496
5550
  time = "hoo_end + #{min_value.abs}"
5497
5551
  else # greater than 0
@@ -5499,31 +5553,31 @@ class Standard
5499
5553
  end
5500
5554
  end
5501
5555
 
5502
- elsif hoo_var_method == "fractional"
5556
+ elsif hoo_var_method == 'fractional'
5503
5557
 
5504
5558
  # minimize x(hour before converted to fraction), which should be no greater than 0.5 as fraction, see if rounding to 3 decimal places works
5505
5559
  if occ > 0
5506
- min_value_occ_fract = min_value.abs/occ
5560
+ min_value_occ_fract = min_value.abs / occ
5507
5561
  else
5508
5562
  min_value_occ_fract = 0.0
5509
5563
  end
5510
5564
  if vac > 0
5511
- min_value_vac_fract = min_value.abs/vac
5565
+ min_value_vac_fract = min_value.abs / vac
5512
5566
  else
5513
5567
  min_value_vac_fract = 0.0
5514
5568
  end
5515
- if min_key == "start"
5569
+ if min_key == 'start'
5516
5570
  if min_value == 0
5517
- time = "hoo_start"
5571
+ time = 'hoo_start'
5518
5572
  elsif min_value < 0
5519
5573
  time = "hoo_start + occ * #{min_value_occ_fract.round(3)}"
5520
5574
  else # greater than 0
5521
5575
  time = "hoo_start - vac * #{min_value_vac_fract.round(3)}"
5522
5576
  end
5523
- elsif min_key == "mid"
5524
- # todo - see what is going wrong with after mid in formula
5577
+ elsif min_key == 'mid'
5578
+ # TODO: - see what is going wrong with after mid in formula
5525
5579
  if min_value == 0
5526
- time = "mid"
5580
+ time = 'mid'
5527
5581
  # converted to variable for simplicity but could also be described like this
5528
5582
  # time = "hoo_start + occ * 0.5"
5529
5583
  elsif min_value < 0
@@ -5533,7 +5587,7 @@ class Standard
5533
5587
  end
5534
5588
  else # min_key == "end"
5535
5589
  if min_value == 0
5536
- time = "hoo_end"
5590
+ time = 'hoo_end'
5537
5591
  elsif min_value < 0
5538
5592
  time = "hoo_end + vac * #{min_value_vac_fract.round(3)}"
5539
5593
  else # greater than 0
@@ -5541,8 +5595,6 @@ class Standard
5541
5595
  end
5542
5596
  end
5543
5597
 
5544
- else # "none"
5545
- # do not add in hoo variables
5546
5598
  end
5547
5599
 
5548
5600
  end
@@ -5556,14 +5608,14 @@ class Standard
5556
5608
  end
5557
5609
 
5558
5610
  # store profile formula with hoo and value variables
5559
- props.setFeature("param_day_profile",raw_string.join(" | "))
5611
+ props.setFeature('param_day_profile', raw_string.join(' | '))
5560
5612
 
5561
- # todo - not used yet, but will add methods described below and others
5613
+ # TODO: - not used yet, but will add methods described below and others
5562
5614
  # todo - lower infiltration based on air loop hours of operation if air loop has outdoor air object
5563
5615
  # todo - lower lighting or plug loads based on occupancy at given time steps in a space
5564
5616
  # todo - set elevator fraction based multiple factors such as trips, occupants per trip, and elevator type to determine floor consumption when not in use.
5565
- props.setFeature("param_day_secondary_logic","") # secondary logic method such as occupancy impacting schedule values
5566
- props.setFeature("param_day_secondary_logic_arg_val","") # optional argument used for some secondary logic applied to values
5617
+ props.setFeature('param_day_secondary_logic', '') # secondary logic method such as occupancy impacting schedule values
5618
+ props.setFeature('param_day_secondary_logic_arg_val', '') # optional argument used for some secondary logic applied to values
5567
5619
 
5568
5620
  # tag profile type
5569
5621
  # may be useful for parametric changes to tag typical, medium, minimal, or same ones with off_peak prefix
@@ -5572,18 +5624,24 @@ class Standard
5572
5624
  # todo - I think these tags should come from occpancy schedule for space(s) schedule. That way all schedules in a space will refer to same profile from hours of operation
5573
5625
  # todo - add school specific logic hear or in post processing, currently default profile for school may not be most prevalent one
5574
5626
  if current_rule_index == -1
5575
- props.setFeature("param_day_tag","typical_operation")
5627
+ props.setFeature('param_day_tag', 'typical_operation')
5576
5628
  elsif daily_flh == daily_flhs.min
5577
- props.setFeature("param_day_tag","minimal_operation")
5629
+ props.setFeature('param_day_tag', 'minimal_operation')
5578
5630
  elsif daily_flh == daily_flhs.max
5579
- props.setFeature("param_day_tag","maximum_operation") # normally this should not be used as typical should be the most active day
5631
+ props.setFeature('param_day_tag', 'maximum_operation') # normally this should not be used as typical should be the most active day
5580
5632
  else
5581
- props.setFeature("param_day_tag","medium_operation") # not min max or typical
5633
+ props.setFeature('param_day_tag', 'medium_operation') # not min max or typical
5582
5634
  end
5583
-
5584
5635
  end
5585
5636
 
5586
5637
  return parametric_inputs
5587
5638
  end
5588
5639
 
5640
+ # Default SAT reset type
5641
+ #
5642
+ # @param air_loop_hvac [OpenStudio::model::AirLoopHVAC] Airloop
5643
+ # @return [String] Returns type of SAT reset
5644
+ def air_loop_hvac_supply_air_temperature_reset_type(air_loop_hvac)
5645
+ return 'warmest_zone'
5646
+ end
5589
5647
  end