openstudio-standards 0.8.3 → 0.8.5.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (330) hide show
  1. checksums.yaml +4 -4
  2. data/data/geometry/ASHRAECollege.osm +30 -30
  3. data/data/geometry/ASHRAECourthouse.osm +22 -22
  4. data/data/geometry/ASHRAESmallOfficeDetailed.osm +2 -2
  5. data/data/geometry/DEER_Asm.osm +1 -1
  6. data/data/geometry/DEER_ECC.osm +1 -1
  7. data/data/geometry/DEER_EPr.osm +1 -1
  8. data/data/geometry/DEER_ERC.osm +1 -1
  9. data/data/geometry/DEER_ESe.osm +1 -1
  10. data/data/geometry/DEER_EUn.osm +1 -1
  11. data/data/geometry/DEER_Hsp.osm +1 -1
  12. data/data/geometry/DEER_Htl.osm +1 -1
  13. data/data/geometry/DEER_MBT.osm +1 -1
  14. data/data/geometry/DEER_MFm.osm +1 -1
  15. data/data/geometry/DEER_Nrs.osm +1 -1
  16. data/data/geometry/DEER_OfL.osm +1 -1
  17. data/data/geometry/DEER_OfS.osm +1 -1
  18. data/data/geometry/DEER_RFF.osm +1 -1
  19. data/data/geometry/DEER_RSD.osm +1 -1
  20. data/data/geometry/DEER_Rt3.osm +1 -1
  21. data/data/geometry/DEER_RtS.osm +1 -1
  22. data/data/standards/export_OpenStudio_libraries.rb +2 -3
  23. data/data/standards/test_performance_expected_dd_results.csv +42 -42
  24. data/lib/openstudio-standards/btap/NECB_building_types.csv +35 -0
  25. data/lib/openstudio-standards/btap/NECB_space_types.csv +109 -0
  26. data/lib/openstudio-standards/btap/activity.rb +480 -0
  27. data/lib/openstudio-standards/btap/attributes.rb +166 -0
  28. data/lib/openstudio-standards/btap/bridging.rb +561 -1402
  29. data/lib/openstudio-standards/btap/btap.rb +4 -2
  30. data/lib/openstudio-standards/btap/btap_test_helper.rb +86 -0
  31. data/lib/openstudio-standards/btap/carbon/btap_carbon.rb +177 -0
  32. data/lib/openstudio-standards/btap/common_paths.rb +81 -0
  33. data/lib/openstudio-standards/btap/common_resources/ConstructionProperties.csv +52 -0
  34. data/lib/openstudio-standards/btap/common_resources/Constructions.csv +37 -0
  35. data/lib/openstudio-standards/btap/common_resources/carbon_frame.csv +35 -0
  36. data/lib/openstudio-standards/btap/common_resources/carbon_glazing.csv +35 -0
  37. data/lib/openstudio-standards/btap/common_resources/carbon_opaque.csv +164 -0
  38. data/lib/openstudio-standards/btap/common_resources/construction_sets.csv +1270 -0
  39. data/lib/openstudio-standards/btap/common_resources/constructions_glazing.csv +121 -0
  40. data/lib/openstudio-standards/btap/common_resources/constructions_opaque.csv +2256 -0
  41. data/lib/openstudio-standards/btap/common_resources/costs.csv +1897 -0
  42. data/lib/openstudio-standards/btap/common_resources/costs_local_factors.csv +2315 -0
  43. data/lib/openstudio-standards/btap/common_resources/hvac_vent_ahu.csv +925 -0
  44. data/lib/openstudio-standards/btap/common_resources/lighting.csv +364 -0
  45. data/lib/openstudio-standards/btap/common_resources/lighting_sets.csv +2667 -0
  46. data/lib/openstudio-standards/btap/common_resources/locations.csv +75 -0
  47. data/lib/openstudio-standards/btap/common_resources/materials_glazing.csv +35 -0
  48. data/lib/openstudio-standards/btap/common_resources/materials_hvac.csv +1686 -0
  49. data/lib/openstudio-standards/btap/common_resources/materials_lighting.csv +267 -0
  50. data/lib/openstudio-standards/btap/common_resources/materials_opaque.csv +164 -0
  51. data/lib/openstudio-standards/btap/costing/README.md +502 -0
  52. data/lib/openstudio-standards/btap/costing/btap_costing.rb +469 -0
  53. data/lib/openstudio-standards/btap/costing/btap_measure_helper.rb +359 -0
  54. data/lib/openstudio-standards/btap/costing/btap_workflow.rb +117 -0
  55. data/lib/openstudio-standards/btap/costing/copy_test_results_files_to_expected_results.rb +11 -0
  56. data/lib/openstudio-standards/btap/costing/cost_building_from_file.rb +136 -0
  57. data/lib/openstudio-standards/btap/costing/costing_database_wrapper.rb +173 -0
  58. data/lib/openstudio-standards/btap/costing/daylighting_sensor_control_costing.rb +354 -0
  59. data/lib/openstudio-standards/btap/costing/dcv_costing.rb +314 -0
  60. data/lib/openstudio-standards/btap/costing/dummy.epw +8768 -0
  61. data/lib/openstudio-standards/btap/costing/dummy.osm +5320 -0
  62. data/lib/openstudio-standards/btap/costing/envelope_costing.rb +215 -0
  63. data/lib/openstudio-standards/btap/costing/heating_cooling_costing.rb +2584 -0
  64. data/lib/openstudio-standards/btap/costing/led_lighting_costing.rb +156 -0
  65. data/lib/openstudio-standards/btap/costing/lighting_costing.rb +209 -0
  66. data/lib/openstudio-standards/btap/costing/mech_sizing.json +502 -0
  67. data/lib/openstudio-standards/btap/costing/neb_end_use_prices.csv +42 -0
  68. data/lib/openstudio-standards/btap/costing/necb_2011_spacetype_info.csv +225 -0
  69. data/lib/openstudio-standards/btap/costing/necb_reference_runs.csv +28705 -0
  70. data/lib/openstudio-standards/btap/costing/nv_costing.rb +547 -0
  71. data/lib/openstudio-standards/btap/costing/parallel_tests.rb +92 -0
  72. data/lib/openstudio-standards/btap/costing/pv_ground_costing.rb +687 -0
  73. data/lib/openstudio-standards/btap/costing/shw_costing.rb +705 -0
  74. data/lib/openstudio-standards/btap/costing/test_list.txt +15 -0
  75. data/lib/openstudio-standards/btap/costing/test_run_all_test_locally.rb +27 -0
  76. data/lib/openstudio-standards/btap/costing/test_run_costing_tests.rb +80 -0
  77. data/lib/openstudio-standards/btap/costing/ventilation_costing.rb +2616 -0
  78. data/lib/openstudio-standards/btap/geometry.rb +86 -6
  79. data/lib/openstudio-standards/btap/structure.rb +657 -0
  80. data/lib/openstudio-standards/constructions/modify.rb +2 -1
  81. data/lib/openstudio-standards/create_typical/create_typical.rb +17 -33
  82. data/lib/openstudio-standards/create_typical/space_type_ratios.rb +36 -36
  83. data/lib/openstudio-standards/equipment/create_transformer.rb +104 -0
  84. data/lib/openstudio-standards/equipment/create_typical_equipment.rb +117 -0
  85. data/lib/openstudio-standards/equipment/data/electric_equipment_space_types.json +1514 -0
  86. data/lib/openstudio-standards/equipment/data/gas_equipment_space_types.json +227 -0
  87. data/lib/openstudio-standards/exterior_lighting/create.rb +22 -22
  88. data/lib/openstudio-standards/exterior_lighting/information.rb +3 -2
  89. data/lib/openstudio-standards/hvac/components/air_conditioner_vrf.rb +482 -0
  90. data/lib/openstudio-standards/hvac/components/air_terminal.rb +31 -0
  91. data/lib/openstudio-standards/hvac/components/boiler_hot_water.rb +163 -0
  92. data/lib/openstudio-standards/hvac/components/central_air_source_heat_pump.rb +220 -0
  93. data/lib/openstudio-standards/hvac/components/chiller.rb +25 -0
  94. data/lib/openstudio-standards/hvac/components/coil.rb +276 -0
  95. data/lib/openstudio-standards/hvac/components/coil_cooling_dx_multi_speed.rb +40 -0
  96. data/lib/openstudio-standards/hvac/components/coil_cooling_dx_single_speed.rb +300 -0
  97. data/lib/openstudio-standards/hvac/components/coil_cooling_dx_two_speed.rb +187 -0
  98. data/lib/openstudio-standards/hvac/components/coil_cooling_water.rb +80 -0
  99. data/lib/openstudio-standards/hvac/components/coil_cooling_water_to_air_heat_pump_equation_fit.rb +182 -0
  100. data/lib/openstudio-standards/hvac/components/coil_heating_dx_single_speed.rb +220 -0
  101. data/lib/openstudio-standards/hvac/components/coil_heating_electric.rb +56 -0
  102. data/lib/openstudio-standards/hvac/components/coil_heating_gas.rb +90 -0
  103. data/lib/openstudio-standards/hvac/components/coil_heating_gas_multi_stage.rb +33 -0
  104. data/lib/openstudio-standards/hvac/components/coil_heating_water.rb +98 -0
  105. data/lib/openstudio-standards/hvac/components/coil_heating_water_to_air_heat_pump_equation_fit.rb +147 -0
  106. data/lib/openstudio-standards/hvac/components/component.rb +39 -0
  107. data/lib/openstudio-standards/{standards/ashrae_90_1/data/ashrae_90_1.fans.json → hvac/components/data/fans.json} +6 -6
  108. data/lib/openstudio-standards/hvac/components/fan.rb +363 -0
  109. data/lib/openstudio-standards/hvac/components/heat_exchanger_air_to_air.rb +203 -0
  110. data/lib/openstudio-standards/hvac/components/pump.rb +181 -0
  111. data/lib/openstudio-standards/hvac/controls/radiant_system_controls.rb +594 -0
  112. data/lib/openstudio-standards/hvac/conversions.rb +222 -0
  113. data/lib/openstudio-standards/hvac/curves.rb +192 -0
  114. data/lib/openstudio-standards/hvac/helpers.rb +357 -0
  115. data/lib/openstudio-standards/hvac/setpoint_managers/information.rb +4 -4
  116. data/lib/openstudio-standards/interior_lighting/create_lights.rb +52 -0
  117. data/lib/openstudio-standards/interior_lighting/create_typical_interior_lighting.rb +254 -0
  118. data/lib/openstudio-standards/interior_lighting/data/convert_lighting_data.rb +249 -0
  119. data/lib/openstudio-standards/interior_lighting/data/lighting_space_types.csv +96 -0
  120. data/lib/openstudio-standards/interior_lighting/data/lighting_space_types.json +1429 -0
  121. data/lib/openstudio-standards/interior_lighting/data/lighting_technology.csv +46 -0
  122. data/lib/openstudio-standards/interior_lighting/data/lighting_technology.json +859 -0
  123. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.AirTerminalSingleDuctVAVReheat.rb +1 -1
  124. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.AirTerminalSingleDuctVAVReheat.rb +1 -1
  125. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirTerminalSingleDuctVAVReheat.rb +1 -1
  126. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Model.rb +4 -4
  127. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirTerminalSingleDuctVAVReheat.rb +1 -1
  128. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Model.rb +4 -4
  129. data/lib/openstudio-standards/prototypes/ashrae_90_1/nrel_nze_ready_2017/nrel_zne_ready_2017.AirTerminalSingleDuctVAVReheat.rb +1 -1
  130. data/lib/openstudio-standards/prototypes/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.AirTerminalSingleDuctVAVReheat.rb +1 -1
  131. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.HighRiseApartment.rb +6 -7
  132. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Hospital.rb +15 -15
  133. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeHotel.rb +4 -4
  134. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeOffice.rb +5 -5
  135. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.MediumOffice.rb +6 -6
  136. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Outpatient.rb +7 -7
  137. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.PrimarySchool.rb +4 -4
  138. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SecondarySchool.rb +6 -6
  139. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallOfficeDetailed.rb +5 -1
  140. data/lib/openstudio-standards/prototypes/common/data/prototype_space_type_map.json +2594 -0
  141. data/lib/openstudio-standards/prototypes/common/data/thermostat_schedule_lookup.json +2108 -0
  142. data/lib/openstudio-standards/prototypes/common/objects/Prototype.AirTerminalSingleDuctVAVReheat.rb +33 -0
  143. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Fan.rb +0 -140
  144. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanConstantVolume.rb +1 -73
  145. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanOnOff.rb +1 -69
  146. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanVariableVolume.rb +0 -116
  147. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanZoneExhaust.rb +0 -61
  148. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.hvac.rb +2 -2
  149. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.rb +128 -13
  150. data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +606 -607
  151. data/lib/openstudio-standards/prototypes/common/prototype_space_type_map.rb +41 -0
  152. data/lib/openstudio-standards/prototypes/common/space_type_equipment_map.rb +184 -0
  153. data/lib/openstudio-standards/prototypes/common/space_type_thermostat_schedule_map.rb +116 -0
  154. data/lib/openstudio-standards/qaqc/hvac.rb +12 -12
  155. data/lib/openstudio-standards/refrigeration/create_compressor.rb +2 -5
  156. data/lib/openstudio-standards/refrigeration/data/refrigeration_compressors.csv +4 -4
  157. data/lib/openstudio-standards/service_water_heating/create_water_heater.rb +1 -2
  158. data/lib/openstudio-standards/service_water_heating/create_water_use.rb +5 -5
  159. data/lib/openstudio-standards/space_type/data/level_1_space_types.json +612 -0
  160. data/lib/openstudio-standards/space_type/standards_space_type.rb +53 -0
  161. data/lib/openstudio-standards/standards/Standards.AirConditionerVariableRefrigerantFlow.rb +8 -26
  162. data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +13 -13
  163. data/lib/openstudio-standards/standards/Standards.AirTerminalSingleDuctVAVReheat.rb +0 -24
  164. data/lib/openstudio-standards/standards/Standards.BoilerHotWater.rb +6 -43
  165. data/lib/openstudio-standards/standards/Standards.ChillerElectricEIR.rb +7 -24
  166. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXMultiSpeed.rb +19 -44
  167. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXSingleSpeed.rb +25 -50
  168. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXTwoSpeed.rb +25 -33
  169. data/lib/openstudio-standards/standards/Standards.CoilCoolingWaterToAirHeatPumpEquationFit.rb +9 -22
  170. data/lib/openstudio-standards/standards/Standards.CoilDX.rb +15 -157
  171. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXMultiSpeed.rb +2 -2
  172. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXSingleSpeed.rb +18 -105
  173. data/lib/openstudio-standards/standards/Standards.CoilHeatingGas.rb +3 -23
  174. data/lib/openstudio-standards/standards/Standards.CoilHeatingGasMultiStage.rb +0 -24
  175. data/lib/openstudio-standards/standards/Standards.CoilHeatingWaterToAirHeatPumpEquationFit.rb +2 -86
  176. data/lib/openstudio-standards/standards/Standards.FanVariableVolume.rb +0 -107
  177. data/lib/openstudio-standards/standards/Standards.Model.rb +45 -20
  178. data/lib/openstudio-standards/standards/Standards.People.rb +113 -0
  179. data/lib/openstudio-standards/standards/Standards.PlantLoop.rb +11 -11
  180. data/lib/openstudio-standards/standards/Standards.Pump.rb +2 -147
  181. data/lib/openstudio-standards/standards/Standards.PumpVariableSpeed.rb +57 -41
  182. data/lib/openstudio-standards/standards/Standards.SpaceType.rb +30 -153
  183. data/lib/openstudio-standards/standards/Standards.Ventilation.rb +74 -0
  184. data/lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb +1 -1
  185. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.PlantLoop.rb +4 -4
  186. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.heat_pumps_heating.json +3 -3
  187. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.spc_typ.json +37 -112
  188. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/comstock_ashrae_90_1_2007/data/comstock_ashrae_90_1_2007.spc_typ.json +37 -102
  189. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.heat_pumps_heating.json +3 -3
  190. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.spc_typ.json +37 -112
  191. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.AirTerminalSingleDuctVAVReheat.rb +1 -1
  192. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/comstock_ashrae_90_1_2010/data/comstock_ashrae_90_1_2010.spc_typ.json +37 -37
  193. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.heat_pumps_heating.json +6 -6
  194. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.spc_typ.json +37 -37
  195. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.AirTerminalSingleDuctVAVReheat.rb +1 -1
  196. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.BoilerHotWater.rb +1 -1
  197. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/comstock_ashrae_90_1_2013/data/comstock_ashrae_90_1_2013.spc_typ.json +37 -102
  198. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.heat_pumps_heating.json +6 -6
  199. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.spc_typ.json +37 -37
  200. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirTerminalSingleDuctVAVReheat.rb +1 -1
  201. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.BoilerHotWater.rb +1 -1
  202. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/comstock_ashrae_90_1_2016/data/comstock_ashrae_90_1_2016.spc_typ.json +45 -109
  203. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.heat_pumps_heating.json +6 -6
  204. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.spc_typ.json +37 -37
  205. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +1 -1
  206. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirTerminalSingleDuctVAVReheat.rb +1 -1
  207. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.BoilerHotWater.rb +1 -1
  208. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.CoilHeatingGas.rb +1 -1
  209. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/comstock_ashrae_90_1_2019/data/comstock_ashrae_90_1_2019.spc_typ.json +45 -109
  210. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.heat_pumps_heating.json +6 -6
  211. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.spc_typ.json +37 -37
  212. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.curves.json +0 -200
  213. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/comstock_doe_ref_1980_2004/data/comstock_doe_ref_1980_2004.spc_typ.json +37 -37
  214. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.spc_typ.json +37 -37
  215. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/comstock_doe_ref_pre_1980/data/comstock_doe_ref_pre_1980.spc_typ.json +37 -37
  216. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.spc_typ.json +37 -37
  217. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.AirTerminalSingleDuctVAVReheat.rb +1 -1
  218. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.PlantLoop.rb +5 -5
  219. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.AirTerminalSingleDuctVAVReheat.rb +1 -1
  220. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.PlantLoop.rb +5 -5
  221. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirLoopHVAC.rb +1 -1
  222. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ChillerElectricEIR.rb +2 -2
  223. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilCoolingDXSingleSpeed.rb +2 -68
  224. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilCoolingDXTwoSpeed.rb +2 -35
  225. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilDX.rb +42 -0
  226. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingDXSingleSpeed.rb +5 -2
  227. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingGas.rb +2 -2
  228. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Model.rb +2 -2
  229. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlantLoop.rb +3 -3
  230. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.SpaceType.rb +1 -1
  231. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019.Model.rb +1 -0
  232. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019_WaterHeaterMixed.rb +2 -4
  233. data/lib/openstudio-standards/standards/ashrae_90_1_prm/data/ashrae_90_1_prm.curves.json +0 -200
  234. data/lib/openstudio-standards/standards/ashrae_90_1_prm/data/ashrae_90_1_prm.fans.json +5 -5
  235. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/ashrae_90_1_prm.UserData.rb +7 -1
  236. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_enums.rb +0 -1
  237. data/lib/openstudio-standards/standards/cbes/data/cbes.curves.json +0 -200
  238. data/lib/openstudio-standards/standards/deer/data/deer.curves.json +0 -200
  239. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/btap_pre1980.rb +21 -37
  240. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/building_envelope.rb +12 -11
  241. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_3_and_8_single_speed.rb +68 -27
  242. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_4.rb +64 -25
  243. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_6.rb +9 -14
  244. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_systems.rb +4 -4
  245. data/lib/openstudio-standards/standards/necb/ECMS/ecms.rb +1 -1
  246. data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +115 -112
  247. data/lib/openstudio-standards/standards/necb/NECB2011/autozone.rb +637 -249
  248. data/lib/openstudio-standards/standards/necb/NECB2011/beps_compliance_path.rb +16 -12
  249. data/lib/openstudio-standards/standards/necb/NECB2011/building_envelope.rb +799 -46
  250. data/lib/openstudio-standards/standards/necb/NECB2011/data/chillers.json +33 -51
  251. data/lib/openstudio-standards/standards/necb/NECB2011/data/constants.json +75 -7
  252. data/lib/openstudio-standards/standards/necb/NECB2011/data/fuel_type_sets.json +25 -1
  253. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/HighriseApartmentMult.osm +14272 -0
  254. data/lib/openstudio-standards/standards/necb/NECB2011/data/heat_pumps_heating.json +21 -15
  255. data/lib/openstudio-standards/standards/necb/NECB2011/data/necb_2015_table_c1.json +1 -1
  256. data/lib/openstudio-standards/standards/necb/NECB2011/data/space_types.json +437 -437
  257. data/lib/openstudio-standards/standards/necb/NECB2011/data/systems.json +516 -0
  258. data/lib/openstudio-standards/standards/necb/NECB2011/data/systems_including_sys5.json +588 -0
  259. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_namer.rb +489 -0
  260. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_1_single_speed.rb +18 -6
  261. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_2_and_5.rb +48 -5
  262. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_multi_speed.rb +2 -2
  263. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_single_speed.rb +35 -27
  264. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_4.rb +34 -23
  265. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_6.rb +8 -6
  266. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +68 -150
  267. data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +444 -134
  268. data/lib/openstudio-standards/standards/necb/NECB2011/system_fuels.rb +61 -1
  269. data/lib/openstudio-standards/standards/necb/NECB2015/data/heat_pumps_heating.json +10 -2
  270. data/lib/openstudio-standards/standards/necb/NECB2015/data/space_types.json +636 -636
  271. data/lib/openstudio-standards/standards/necb/NECB2015/data/unitary_acs.json +38 -38
  272. data/lib/openstudio-standards/standards/necb/NECB2015/hvac_systems.rb +17 -8
  273. data/lib/openstudio-standards/standards/necb/NECB2017/data/space_types.json +636 -636
  274. data/lib/openstudio-standards/standards/necb/NECB2020/data/chillers.json +71 -71
  275. data/lib/openstudio-standards/standards/necb/NECB2020/data/heat_pumps_heating.json +16 -6
  276. data/lib/openstudio-standards/standards/necb/NECB2020/data/unitary_acs.json +60 -61
  277. data/lib/openstudio-standards/standards/necb/NECB2020/service_water_heating.rb +30 -30
  278. data/lib/openstudio-standards/standards/necb/README.md +343 -0
  279. data/lib/openstudio-standards/standards/necb/common/btap_analysis.rb +79 -0
  280. data/lib/openstudio-standards/standards/necb/common/btap_data.rb +206 -32
  281. data/lib/openstudio-standards/standards/necb/common/btap_datapoint.rb +75 -43
  282. data/lib/openstudio-standards/standards/necb/common/eccc_electric_grid_intensity_20250311.csv +14 -0
  283. data/lib/openstudio-standards/standards/necb/common/nir_gas_grid_intensity_20250311.csv +14 -0
  284. data/lib/openstudio-standards/standards/necb/common/system_types.yaml +0 -0
  285. data/lib/openstudio-standards/thermal_zone/{thermal_zone.rb → information.rb} +12 -45
  286. data/lib/openstudio-standards/thermal_zone/thermostat_schedules.rb +152 -0
  287. data/lib/openstudio-standards/utilities/logging.rb +18 -14
  288. data/lib/openstudio-standards/version.rb +1 -1
  289. data/lib/openstudio-standards/weather/modify.rb +2 -2
  290. data/lib/openstudio-standards/weather/stat_file.rb +2 -2
  291. data/lib/openstudio-standards.rb +67 -38
  292. metadata +141 -50
  293. data/lib/openstudio-standards/hvac/components/create.rb +0 -169
  294. data/lib/openstudio-standards/hvac/components/modify.rb +0 -42
  295. data/lib/openstudio-standards/prototypes/common/objects/Prototype.AirConditionerVariableRefrigerantFlow.rb +0 -438
  296. data/lib/openstudio-standards/prototypes/common/objects/Prototype.BoilerHotWater.rb +0 -123
  297. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CentralAirSourceHeatPump.rb +0 -216
  298. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingDXSingleSpeed.rb +0 -273
  299. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingDXTwoSpeed.rb +0 -159
  300. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingWater.rb +0 -77
  301. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingWaterToAirHeatPumpEquationFit.rb +0 -154
  302. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingDXSingleSpeed.rb +0 -214
  303. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingElectric.rb +0 -53
  304. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingGas.rb +0 -72
  305. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingWater.rb +0 -95
  306. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingWaterToAirHeatPumpEquationFit.rb +0 -125
  307. data/lib/openstudio-standards/prototypes/common/objects/Prototype.ControllerWaterCoil.rb +0 -17
  308. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.transformers.rb +0 -90
  309. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Pump.rb +0 -4
  310. data/lib/openstudio-standards/prototypes/common/objects/Prototype.PumpVariableSpeed.rb +0 -70
  311. data/lib/openstudio-standards/prototypes/common/objects/Prototype.radiant_system_controls.rb +0 -590
  312. data/lib/openstudio-standards/prototypes/common/objects/Prototype.utilities.rb +0 -901
  313. data/lib/openstudio-standards/standards/Standards.FanConstantVolume.rb +0 -5
  314. data/lib/openstudio-standards/standards/Standards.FanOnOff.rb +0 -5
  315. data/lib/openstudio-standards/standards/Standards.FanZoneExhaust.rb +0 -5
  316. data/lib/openstudio-standards/standards/Standards.HeaderedPumpsConstantSpeed.rb +0 -5
  317. data/lib/openstudio-standards/standards/Standards.HeaderedPumpsVariableSpeed.rb +0 -55
  318. data/lib/openstudio-standards/standards/Standards.PumpConstantSpeed.rb +0 -5
  319. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanConstantVolume.rb +0 -5
  320. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanOnOff.rb +0 -5
  321. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanZoneExhaust.rb +0 -5
  322. data/lib/openstudio-standards/standards/cbes/data/cbes.fans.json +0 -328
  323. data/lib/openstudio-standards/standards/deer/data/deer.fans.json +0 -328
  324. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.PumpVariableSpeed.rb +0 -0
  325. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.PumpVariableSpeed.rb +0 -0
  326. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.PumpVariableSpeed.rb +0 -0
  327. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.PumpVariableSpeed.rb +0 -0
  328. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.PumpVariableSpeed.rb +0 -0
  329. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Pump.rb +0 -0
  330. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.PumpVariableSpeed.rb +0 -0
@@ -0,0 +1,594 @@
1
+ module OpenstudioStandards
2
+ # The HVAC module provides methods create, modify, and get information about HVAC systems in the model
3
+ module HVAC
4
+ # @!group Radiant Controls
5
+ # Methods to add radiant system controls
6
+
7
+ # These EnergyPlus objects implement a proportional control for a single thermal zone with a radiant system.
8
+ # @ref [References::CBERadiantSystems]
9
+ # @param zone [OpenStudio::Model::ThermalZone>] zone to add radiant controls
10
+ # @param radiant_loop [OpenStudio::Model::ZoneHVACLowTempRadiantVarFlow>] radiant loop in thermal zone
11
+ # @param radiant_temperature_control_type [String] determines the controlled temperature for the radiant system
12
+ # options are 'SurfaceFaceTemperature', 'SurfaceInteriorTemperature'
13
+ # @param use_zone_occupancy_for_control [Boolean] Set to true if radiant system is to use specific zone occupancy objects
14
+ # for CBE control strategy. If false, then it will use values in model_occ_hr_start and model_occ_hr_end
15
+ # for all radiant zones. default to true.
16
+ # @param occupied_percentage_threshold [Double] the minimum fraction (0 to 1) that counts as occupied
17
+ # if this parameter is set, the returned ScheduleRuleset will be 0 = unoccupied, 1 = occupied
18
+ # otherwise the ScheduleRuleset will be the weighted fractional occupancy schedule
19
+ # @param model_occ_hr_start [Double] Starting decimal hour of whole building occupancy
20
+ # @param model_occ_hr_end [Double] Ending decimal hour of whole building occupancy
21
+ # @todo model_occ_hr_start and model_occ_hr_end from zone occupancy schedules
22
+ # @param proportional_gain [Double] Proportional gain constant (recommended 0.3 or less).
23
+ # @param switch_over_time [Double] Time limitation for when the system can switch between heating and cooling
24
+ def self.model_add_radiant_proportional_controls(model, zone, radiant_loop,
25
+ radiant_temperature_control_type: 'SurfaceFaceTemperature',
26
+ use_zone_occupancy_for_control: true,
27
+ occupied_percentage_threshold: 0.10,
28
+ model_occ_hr_start: 6.0,
29
+ model_occ_hr_end: 18.0,
30
+ proportional_gain: 0.3,
31
+ switch_over_time: 24.0)
32
+ zone_name = OpenstudioStandards::HVAC.ems_friendly_name(zone.name)
33
+ zone_timestep = model.getTimestep.numberOfTimestepsPerHour
34
+
35
+ if model.version < OpenStudio::VersionString.new('3.1.1')
36
+ coil_cooling_radiant = radiant_loop.coolingCoil.to_CoilCoolingLowTempRadiantVarFlow.get
37
+ coil_heating_radiant = radiant_loop.heatingCoil.to_CoilHeatingLowTempRadiantVarFlow.get
38
+ else
39
+ coil_cooling_radiant = radiant_loop.coolingCoil.get.to_CoilCoolingLowTempRadiantVarFlow.get
40
+ coil_heating_radiant = radiant_loop.heatingCoil.get.to_CoilHeatingLowTempRadiantVarFlow.get
41
+ end
42
+
43
+ #####
44
+ # Define radiant system parameters
45
+ ####
46
+ # set radiant system temperature and setpoint control type
47
+ unless ['surfacefacetemperature', 'surfaceinteriortemperature'].include? radiant_temperature_control_type.downcase
48
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.Model.Model',
49
+ "Control sequences not compatible with '#{radiant_temperature_control_type}' radiant system control. Defaulting to 'SurfaceFaceTemperature'.")
50
+ radiant_temperature_control_type = 'SurfaceFaceTemperature'
51
+ end
52
+
53
+ radiant_loop.setTemperatureControlType(radiant_temperature_control_type)
54
+
55
+ #####
56
+ # List of schedule objects used to hold calculation results
57
+ ####
58
+
59
+ # get existing switchover time schedule or create one if needed
60
+ sch_radiant_switchover = model.getScheduleRulesetByName('Radiant System Switchover')
61
+ if sch_radiant_switchover.is_initialized
62
+ sch_radiant_switchover = sch_radiant_switchover.get
63
+ else
64
+ sch_radiant_switchover = OpenstudioStandards::Schedules.create_constant_schedule_ruleset(model,
65
+ switch_over_time,
66
+ name: 'Radiant System Switchover',
67
+ schedule_type_limit: 'Dimensionless')
68
+ end
69
+
70
+ # set radiant system switchover schedule
71
+ radiant_loop.setChangeoverDelayTimePeriodSchedule(sch_radiant_switchover.to_Schedule.get)
72
+
73
+ # Calculated active slab heating and cooling temperature setpoint.
74
+ # radiant system cooling control actuator
75
+ sch_radiant_clgsetp = OpenstudioStandards::Schedules.create_constant_schedule_ruleset(model,
76
+ 26.0,
77
+ name: "#{zone_name}_Sch_Radiant_ClgSetP",
78
+ schedule_type_limit: 'Temperature')
79
+ coil_cooling_radiant.setCoolingControlTemperatureSchedule(sch_radiant_clgsetp)
80
+ cmd_cold_water_ctrl = OpenStudio::Model::EnergyManagementSystemActuator.new(sch_radiant_clgsetp,
81
+ 'Schedule:Year',
82
+ 'Schedule Value')
83
+ cmd_cold_water_ctrl.setName("#{zone_name}_cmd_cold_water_ctrl")
84
+
85
+ # radiant system heating control actuator
86
+ sch_radiant_htgsetp = OpenstudioStandards::Schedules.create_constant_schedule_ruleset(model,
87
+ 20.0,
88
+ name: "#{zone_name}_Sch_Radiant_HtgSetP",
89
+ schedule_type_limit: 'Temperature')
90
+ coil_heating_radiant.setHeatingControlTemperatureSchedule(sch_radiant_htgsetp)
91
+ cmd_hot_water_ctrl = OpenStudio::Model::EnergyManagementSystemActuator.new(sch_radiant_htgsetp,
92
+ 'Schedule:Year',
93
+ 'Schedule Value')
94
+ cmd_hot_water_ctrl.setName("#{zone_name}_cmd_hot_water_ctrl")
95
+
96
+ # Calculated cooling setpoint error. Calculated from upper comfort limit minus setpoint offset and 'measured' controlled zone temperature.
97
+ sch_csp_error = OpenstudioStandards::Schedules.create_constant_schedule_ruleset(model,
98
+ 0.0,
99
+ name: "#{zone_name}_Sch_CSP_Error",
100
+ schedule_type_limit: 'Temperature')
101
+ cmd_csp_error = OpenStudio::Model::EnergyManagementSystemActuator.new(sch_csp_error,
102
+ 'Schedule:Year',
103
+ 'Schedule Value')
104
+ cmd_csp_error.setName("#{zone_name}_cmd_csp_error")
105
+
106
+ # Calculated heating setpoint error. Calculated from lower comfort limit plus setpoint offset and 'measured' controlled zone temperature.
107
+ sch_hsp_error = OpenstudioStandards::Schedules.create_constant_schedule_ruleset(model,
108
+ 0.0,
109
+ name: "#{zone_name}_Sch_HSP_Error",
110
+ schedule_type_limit: 'Temperature')
111
+ cmd_hsp_error = OpenStudio::Model::EnergyManagementSystemActuator.new(sch_hsp_error,
112
+ 'Schedule:Year',
113
+ 'Schedule Value')
114
+ cmd_hsp_error.setName("#{zone_name}_cmd_hsp_error")
115
+
116
+ #####
117
+ # List of global variables used in EMS scripts
118
+ ####
119
+
120
+ # Proportional gain constant (recommended 0.3 or less).
121
+ prp_k = model.getEnergyManagementSystemGlobalVariableByName('prp_k')
122
+ if prp_k.is_initialized
123
+ prp_k = prp_k.get
124
+ else
125
+ prp_k = OpenStudio::Model::EnergyManagementSystemGlobalVariable.new(model, 'prp_k')
126
+ end
127
+
128
+ # Upper slab temperature setpoint limit (recommended no higher than 29C (84F))
129
+ upper_slab_sp_lim = model.getEnergyManagementSystemGlobalVariableByName('upper_slab_sp_lim')
130
+ if upper_slab_sp_lim.is_initialized
131
+ upper_slab_sp_lim = upper_slab_sp_lim.get
132
+ else
133
+ upper_slab_sp_lim = OpenStudio::Model::EnergyManagementSystemGlobalVariable.new(model, 'upper_slab_sp_lim')
134
+ end
135
+
136
+ # Lower slab temperature setpoint limit (recommended no lower than 19C (66F))
137
+ lower_slab_sp_lim = model.getEnergyManagementSystemGlobalVariableByName('lower_slab_sp_lim')
138
+ if lower_slab_sp_lim.is_initialized
139
+ lower_slab_sp_lim = lower_slab_sp_lim.get
140
+ else
141
+ lower_slab_sp_lim = OpenStudio::Model::EnergyManagementSystemGlobalVariable.new(model, 'lower_slab_sp_lim')
142
+ end
143
+
144
+ # Temperature offset used as a safety factor for thermal control (recommend 0.5C (1F)).
145
+ ctrl_temp_offset = model.getEnergyManagementSystemGlobalVariableByName('ctrl_temp_offset')
146
+ if ctrl_temp_offset.is_initialized
147
+ ctrl_temp_offset = ctrl_temp_offset.get
148
+ else
149
+ ctrl_temp_offset = OpenStudio::Model::EnergyManagementSystemGlobalVariable.new(model, 'ctrl_temp_offset')
150
+ end
151
+
152
+ # Hour where slab setpoint is to be changed
153
+ hour_of_slab_sp_change = model.getEnergyManagementSystemGlobalVariableByName('hour_of_slab_sp_change')
154
+ if hour_of_slab_sp_change.is_initialized
155
+ hour_of_slab_sp_change = hour_of_slab_sp_change.get
156
+ else
157
+ hour_of_slab_sp_change = OpenStudio::Model::EnergyManagementSystemGlobalVariable.new(model, 'hour_of_slab_sp_change')
158
+ end
159
+
160
+ #####
161
+ # List of zone specific variables used in EMS scripts
162
+ ####
163
+
164
+ # Maximum 'measured' temperature in zone during occupied times. Default setup uses mean air temperature.
165
+ # Other possible choices are operative and mean radiant temperature.
166
+ zone_max_ctrl_temp = OpenStudio::Model::EnergyManagementSystemGlobalVariable.new(model, "#{zone_name}_max_ctrl_temp")
167
+
168
+ # Minimum 'measured' temperature in zone during occupied times. Default setup uses mean air temperature.
169
+ # Other possible choices are operative and mean radiant temperature.
170
+ zone_min_ctrl_temp = OpenStudio::Model::EnergyManagementSystemGlobalVariable.new(model, "#{zone_name}_min_ctrl_temp")
171
+
172
+ #####
173
+ # List of 'sensors' used in the EMS programs
174
+ ####
175
+
176
+ # Controlled zone temperature for the zone.
177
+ zone_ctrl_temperature = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Zone Air Temperature')
178
+ zone_ctrl_temperature.setName("#{zone_name}_ctrl_temperature")
179
+ zone_ctrl_temperature.setKeyName(zone.name.get)
180
+
181
+ # check for zone thermostat and replace heat/cool schedules for radiant system control
182
+ # if there is no zone thermostat, then create one
183
+ zone_thermostat = zone.thermostatSetpointDualSetpoint
184
+
185
+ if zone_thermostat.is_initialized
186
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.Model.Model', "Replacing thermostat schedules in zone #{zone.name} for radiant system control.")
187
+ zone_thermostat = zone.thermostatSetpointDualSetpoint.get
188
+ else
189
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.Model.Model', "Zone #{zone.name} does not have a thermostat. Creating a thermostat for radiant system control.")
190
+ zone_thermostat = OpenStudio::Model::ThermostatSetpointDualSetpoint.new(model)
191
+ zone_thermostat.setName("#{zone_name}_Thermostat_DualSetpoint")
192
+ end
193
+
194
+ # create new heating and cooling schedules to be used with all radiant systems
195
+ zone_htg_thermostat = model.getScheduleRulesetByName('Radiant System Heating Setpoint')
196
+ if zone_htg_thermostat.is_initialized
197
+ zone_htg_thermostat = zone_htg_thermostat.get
198
+ else
199
+ zone_htg_thermostat = OpenstudioStandards::Schedules.create_constant_schedule_ruleset(model,
200
+ 20.0,
201
+ name: 'Radiant System Heating Setpoint',
202
+ schedule_type_limit: 'Temperature')
203
+ end
204
+
205
+ zone_clg_thermostat = model.getScheduleRulesetByName('Radiant System Cooling Setpoint')
206
+ if zone_clg_thermostat.is_initialized
207
+ zone_clg_thermostat = zone_clg_thermostat.get
208
+ else
209
+ zone_clg_thermostat = OpenstudioStandards::Schedules.create_constant_schedule_ruleset(model,
210
+ 26.0,
211
+ name: 'Radiant System Cooling Setpoint',
212
+ schedule_type_limit: 'Temperature')
213
+ end
214
+
215
+ # implement new heating and cooling schedules
216
+ zone_thermostat.setHeatingSetpointTemperatureSchedule(zone_htg_thermostat)
217
+ zone_thermostat.setCoolingSetpointTemperatureSchedule(zone_clg_thermostat)
218
+
219
+ # Upper comfort limit for the zone. Taken from existing thermostat schedules in the zone.
220
+ zone_upper_comfort_limit = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Schedule Value')
221
+ zone_upper_comfort_limit.setName("#{zone_name}_upper_comfort_limit")
222
+ zone_upper_comfort_limit.setKeyName(zone_clg_thermostat.name.get)
223
+
224
+ # Lower comfort limit for the zone. Taken from existing thermostat schedules in the zone.
225
+ zone_lower_comfort_limit = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Schedule Value')
226
+ zone_lower_comfort_limit.setName("#{zone_name}_lower_comfort_limit")
227
+ zone_lower_comfort_limit.setKeyName(zone_htg_thermostat.name.get)
228
+
229
+ # Radiant system water flow rate used to determine if there is active hydronic cooling in the radiant system.
230
+ zone_rad_cool_operation = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'System Node Mass Flow Rate')
231
+ zone_rad_cool_operation.setName("#{zone_name}_rad_cool_operation")
232
+ zone_rad_cool_operation.setKeyName(coil_cooling_radiant.to_StraightComponent.get.inletModelObject.get.name.get)
233
+
234
+ # Radiant system water flow rate used to determine if there is active hydronic heating in the radiant system.
235
+ zone_rad_heat_operation = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'System Node Mass Flow Rate')
236
+ zone_rad_heat_operation.setName("#{zone_name}_rad_heat_operation")
237
+ zone_rad_heat_operation.setKeyName(coil_heating_radiant.to_StraightComponent.get.inletModelObject.get.name.get)
238
+
239
+ # Radiant system switchover delay time period schedule
240
+ # used to determine if there is active hydronic cooling/heating in the radiant system.
241
+ zone_rad_switch_over = model.getEnergyManagementSystemSensorByName('radiant_switch_over_time')
242
+
243
+ unless zone_rad_switch_over.is_initialized
244
+ zone_rad_switch_over = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Schedule Value')
245
+ zone_rad_switch_over.setName('radiant_switch_over_time')
246
+ zone_rad_switch_over.setKeyName(sch_radiant_switchover.name.get)
247
+ end
248
+
249
+ # Last 24 hours trend for radiant system in cooling mode.
250
+ zone_rad_cool_operation_trend = OpenStudio::Model::EnergyManagementSystemTrendVariable.new(model, zone_rad_cool_operation)
251
+ zone_rad_cool_operation_trend.setName("#{zone_name}_rad_cool_operation_trend")
252
+ zone_rad_cool_operation_trend.setNumberOfTimestepsToBeLogged(zone_timestep * 48)
253
+
254
+ # Last 24 hours trend for radiant system in heating mode.
255
+ zone_rad_heat_operation_trend = OpenStudio::Model::EnergyManagementSystemTrendVariable.new(model, zone_rad_heat_operation)
256
+ zone_rad_heat_operation_trend.setName("#{zone_name}_rad_heat_operation_trend")
257
+ zone_rad_heat_operation_trend.setNumberOfTimestepsToBeLogged(zone_timestep * 48)
258
+
259
+ # use zone occupancy objects for radiant system control if selected
260
+ if use_zone_occupancy_for_control
261
+
262
+ # get annual occupancy schedule for zone
263
+ occ_schedule_ruleset = OpenstudioStandards::ThermalZone.thermal_zone_get_occupancy_schedule(zone,
264
+ sch_name: "#{zone.name} Radiant System Occupied Schedule",
265
+ occupied_percentage_threshold: occupied_percentage_threshold)
266
+ else
267
+
268
+ occ_schedule_ruleset = model.getScheduleRulesetByName('Whole Building Radiant System Occupied Schedule')
269
+ if occ_schedule_ruleset.is_initialized
270
+ occ_schedule_ruleset = occ_schedule_ruleset.get
271
+ else
272
+ # create occupancy schedules
273
+ occ_schedule_ruleset = OpenStudio::Model::ScheduleRuleset.new(model)
274
+ occ_schedule_ruleset.setName('Whole Building Radiant System Occupied Schedule')
275
+
276
+ start_hour = model_occ_hr_end.to_i
277
+ start_minute = ((model_occ_hr_end % 1) * 60).to_i
278
+ end_hour = model_occ_hr_start.to_i
279
+ end_minute = ((model_occ_hr_start % 1) * 60).to_i
280
+
281
+ if end_hour > start_hour
282
+ occ_schedule_ruleset.defaultDaySchedule.addValue(OpenStudio::Time.new(0, start_hour, start_minute, 0), 1.0)
283
+ occ_schedule_ruleset.defaultDaySchedule.addValue(OpenStudio::Time.new(0, end_hour, end_minute, 0), 0.0)
284
+ occ_schedule_ruleset.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), 1.0) if end_hour < 24
285
+ elsif start_hour > end_hour
286
+ occ_schedule_ruleset.defaultDaySchedule.addValue(OpenStudio::Time.new(0, end_hour, end_minute, 0), 0.0)
287
+ occ_schedule_ruleset.defaultDaySchedule.addValue(OpenStudio::Time.new(0, start_hour, start_minute, 0), 1.0)
288
+ occ_schedule_ruleset.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), 0.0) if start_hour < 24
289
+ else
290
+ occ_schedule_ruleset.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), 1.0)
291
+ end
292
+ end
293
+ end
294
+
295
+ # create ems sensor for zone occupied status
296
+ zone_occupied_status = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Schedule Value')
297
+ zone_occupied_status.setName("#{zone_name}_occupied_status")
298
+ zone_occupied_status.setKeyName(occ_schedule_ruleset.name.get)
299
+
300
+ # Last 24 hours trend for zone occupied status
301
+ zone_occupied_status_trend = OpenStudio::Model::EnergyManagementSystemTrendVariable.new(model, zone_occupied_status)
302
+ zone_occupied_status_trend.setName("#{zone_name}_occupied_status_trend")
303
+ zone_occupied_status_trend.setNumberOfTimestepsToBeLogged(zone_timestep * 48)
304
+
305
+ #####
306
+ # List of EMS programs to implement the proportional control for the radiant system.
307
+ ####
308
+
309
+ # Initialize global constant values used in EMS programs.
310
+ set_constant_values_prg_body = <<-EMS
311
+ SET prp_k = #{proportional_gain},
312
+ SET ctrl_temp_offset = 0.5,
313
+ SET upper_slab_sp_lim = 29,
314
+ SET lower_slab_sp_lim = 19,
315
+ SET hour_of_slab_sp_change = 18
316
+ EMS
317
+
318
+ set_constant_values_prg = model.getEnergyManagementSystemProgramByName('Set_Constant_Values')
319
+ if set_constant_values_prg.is_initialized
320
+ set_constant_values_prg = set_constant_values_prg.get
321
+ else
322
+ set_constant_values_prg = OpenStudio::Model::EnergyManagementSystemProgram.new(model)
323
+ set_constant_values_prg.setName('Set_Constant_Values')
324
+ set_constant_values_prg.setBody(set_constant_values_prg_body)
325
+ end
326
+
327
+ # Initialize zone specific constant values used in EMS programs.
328
+ set_constant_zone_values_prg_body = <<-EMS
329
+ SET #{zone_name}_max_ctrl_temp = #{zone_name}_lower_comfort_limit,
330
+ SET #{zone_name}_min_ctrl_temp = #{zone_name}_upper_comfort_limit,
331
+ SET #{zone_name}_cmd_csp_error = 0,
332
+ SET #{zone_name}_cmd_hsp_error = 0,
333
+ SET #{zone_name}_cmd_cold_water_ctrl = #{zone_name}_upper_comfort_limit,
334
+ SET #{zone_name}_cmd_hot_water_ctrl = #{zone_name}_lower_comfort_limit
335
+ EMS
336
+
337
+ set_constant_zone_values_prg = OpenStudio::Model::EnergyManagementSystemProgram.new(model)
338
+ set_constant_zone_values_prg.setName("#{zone_name}_Set_Constant_Values")
339
+ set_constant_zone_values_prg.setBody(set_constant_zone_values_prg_body)
340
+
341
+ # Calculate maximum and minimum 'measured' controlled temperature in the zone
342
+ calculate_minmax_ctrl_temp_prg = OpenStudio::Model::EnergyManagementSystemProgram.new(model)
343
+ calculate_minmax_ctrl_temp_prg.setName("#{zone_name}_Calculate_Extremes_In_Zone")
344
+ calculate_minmax_ctrl_temp_prg_body = <<-EMS
345
+ IF (#{zone_name}_occupied_status == 1),
346
+ IF #{zone_name}_ctrl_temperature > #{zone_name}_max_ctrl_temp,
347
+ SET #{zone_name}_max_ctrl_temp = #{zone_name}_ctrl_temperature,
348
+ ENDIF,
349
+ IF #{zone_name}_ctrl_temperature < #{zone_name}_min_ctrl_temp,
350
+ SET #{zone_name}_min_ctrl_temp = #{zone_name}_ctrl_temperature,
351
+ ENDIF,
352
+ ELSE,
353
+ SET #{zone_name}_max_ctrl_temp = #{zone_name}_lower_comfort_limit,
354
+ SET #{zone_name}_min_ctrl_temp = #{zone_name}_upper_comfort_limit,
355
+ ENDIF
356
+ EMS
357
+ calculate_minmax_ctrl_temp_prg.setBody(calculate_minmax_ctrl_temp_prg_body)
358
+
359
+ # Calculate errors from comfort zone limits and 'measured' controlled temperature in the zone.
360
+ calculate_errors_from_comfort_prg = OpenStudio::Model::EnergyManagementSystemProgram.new(model)
361
+ calculate_errors_from_comfort_prg.setName("#{zone_name}_Calculate_Errors_From_Comfort")
362
+ calculate_errors_from_comfort_prg_body = <<-EMS
363
+ IF (CurrentTime == (hour_of_slab_sp_change - ZoneTimeStep)),
364
+ SET #{zone_name}_cmd_csp_error = (#{zone_name}_upper_comfort_limit - ctrl_temp_offset) - #{zone_name}_max_ctrl_temp,
365
+ SET #{zone_name}_cmd_hsp_error = (#{zone_name}_lower_comfort_limit + ctrl_temp_offset) - #{zone_name}_min_ctrl_temp,
366
+ ENDIF
367
+ EMS
368
+ calculate_errors_from_comfort_prg.setBody(calculate_errors_from_comfort_prg_body)
369
+
370
+ # Calculate the new active slab temperature setpoint for heating and cooling
371
+ calculate_slab_ctrl_setpoint_prg = OpenStudio::Model::EnergyManagementSystemProgram.new(model)
372
+ calculate_slab_ctrl_setpoint_prg.setName("#{zone_name}_Calculate_Slab_Ctrl_Setpoint")
373
+ calculate_slab_ctrl_setpoint_prg_body = <<-EMS
374
+ SET #{zone_name}_cont_cool_oper = @TrendSum #{zone_name}_rad_cool_operation_trend radiant_switch_over_time/ZoneTimeStep,
375
+ SET #{zone_name}_cont_heat_oper = @TrendSum #{zone_name}_rad_heat_operation_trend radiant_switch_over_time/ZoneTimeStep,
376
+ SET #{zone_name}_occupied_hours = @TrendSum #{zone_name}_occupied_status_trend 24/ZoneTimeStep,
377
+ IF (#{zone_name}_cont_cool_oper > 0) && (#{zone_name}_occupied_hours > 0) && (CurrentTime == hour_of_slab_sp_change),
378
+ SET #{zone_name}_cmd_hot_water_ctrl = #{zone_name}_cmd_hot_water_ctrl + (#{zone_name}_cmd_csp_error*prp_k),
379
+ ELSEIF (#{zone_name}_cont_heat_oper > 0) && (#{zone_name}_occupied_hours > 0) && (CurrentTime == hour_of_slab_sp_change),
380
+ SET #{zone_name}_cmd_hot_water_ctrl = #{zone_name}_cmd_hot_water_ctrl + (#{zone_name}_cmd_hsp_error*prp_k),
381
+ ELSE,
382
+ SET #{zone_name}_cmd_hot_water_ctrl = #{zone_name}_cmd_hot_water_ctrl,
383
+ ENDIF,
384
+ IF (#{zone_name}_cmd_hot_water_ctrl < lower_slab_sp_lim),
385
+ SET #{zone_name}_cmd_hot_water_ctrl = lower_slab_sp_lim,
386
+ ELSEIF (#{zone_name}_cmd_hot_water_ctrl > upper_slab_sp_lim),
387
+ SET #{zone_name}_cmd_hot_water_ctrl = upper_slab_sp_lim,
388
+ ENDIF,
389
+ SET #{zone_name}_cmd_cold_water_ctrl = #{zone_name}_cmd_hot_water_ctrl + 0.01
390
+ EMS
391
+ calculate_slab_ctrl_setpoint_prg.setBody(calculate_slab_ctrl_setpoint_prg_body)
392
+
393
+ #####
394
+ # List of EMS program manager objects
395
+ ####
396
+
397
+ initialize_constant_parameters = model.getEnergyManagementSystemProgramCallingManagerByName('Initialize_Constant_Parameters')
398
+ if initialize_constant_parameters.is_initialized
399
+ initialize_constant_parameters = initialize_constant_parameters.get
400
+ # add program if it does not exist in manager
401
+ existing_program_names = initialize_constant_parameters.programs.collect { |prg| prg.name.get.downcase }
402
+ unless existing_program_names.include? set_constant_values_prg.name.get.downcase
403
+ initialize_constant_parameters.addProgram(set_constant_values_prg)
404
+ end
405
+ else
406
+ initialize_constant_parameters = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(model)
407
+ initialize_constant_parameters.setName('Initialize_Constant_Parameters')
408
+ initialize_constant_parameters.setCallingPoint('BeginNewEnvironment')
409
+ initialize_constant_parameters.addProgram(set_constant_values_prg)
410
+ end
411
+
412
+ initialize_constant_parameters_after_warmup = model.getEnergyManagementSystemProgramCallingManagerByName('Initialize_Constant_Parameters_After_Warmup')
413
+ if initialize_constant_parameters_after_warmup.is_initialized
414
+ initialize_constant_parameters_after_warmup = initialize_constant_parameters_after_warmup.get
415
+ # add program if it does not exist in manager
416
+ existing_program_names = initialize_constant_parameters_after_warmup.programs.collect { |prg| prg.name.get.downcase }
417
+ unless existing_program_names.include? set_constant_values_prg.name.get.downcase
418
+ initialize_constant_parameters_after_warmup.addProgram(set_constant_values_prg)
419
+ end
420
+ else
421
+ initialize_constant_parameters_after_warmup = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(model)
422
+ initialize_constant_parameters_after_warmup.setName('Initialize_Constant_Parameters_After_Warmup')
423
+ initialize_constant_parameters_after_warmup.setCallingPoint('AfterNewEnvironmentWarmUpIsComplete')
424
+ initialize_constant_parameters_after_warmup.addProgram(set_constant_values_prg)
425
+ end
426
+
427
+ zone_initialize_constant_parameters = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(model)
428
+ zone_initialize_constant_parameters.setName("#{zone_name}_Initialize_Constant_Parameters")
429
+ zone_initialize_constant_parameters.setCallingPoint('BeginNewEnvironment')
430
+ zone_initialize_constant_parameters.addProgram(set_constant_zone_values_prg)
431
+
432
+ zone_initialize_constant_parameters_after_warmup = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(model)
433
+ zone_initialize_constant_parameters_after_warmup.setName("#{zone_name}_Initialize_Constant_Parameters_After_Warmup")
434
+ zone_initialize_constant_parameters_after_warmup.setCallingPoint('AfterNewEnvironmentWarmUpIsComplete')
435
+ zone_initialize_constant_parameters_after_warmup.addProgram(set_constant_zone_values_prg)
436
+
437
+ average_building_temperature = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(model)
438
+ average_building_temperature.setName("#{zone_name}_Average_Building_Temperature")
439
+ average_building_temperature.setCallingPoint('EndOfZoneTimestepAfterZoneReporting')
440
+ average_building_temperature.addProgram(calculate_minmax_ctrl_temp_prg)
441
+ average_building_temperature.addProgram(calculate_errors_from_comfort_prg)
442
+
443
+ programs_at_beginning_of_timestep = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(model)
444
+ programs_at_beginning_of_timestep.setName("#{zone_name}_Programs_At_Beginning_Of_Timestep")
445
+ programs_at_beginning_of_timestep.setCallingPoint('BeginTimestepBeforePredictor')
446
+ programs_at_beginning_of_timestep.addProgram(calculate_slab_ctrl_setpoint_prg)
447
+
448
+ #####
449
+ # List of variables for output.
450
+ ####
451
+
452
+ zone_max_ctrl_temp_output = OpenStudio::Model::EnergyManagementSystemOutputVariable.new(model, zone_max_ctrl_temp)
453
+ zone_max_ctrl_temp_output.setName("#{zone_name} Maximum occupied temperature in zone")
454
+ zone_min_ctrl_temp_output = OpenStudio::Model::EnergyManagementSystemOutputVariable.new(model, zone_min_ctrl_temp)
455
+ zone_min_ctrl_temp_output.setName("#{zone_name} Minimum occupied temperature in zone")
456
+ end
457
+
458
+ # Native EnergyPlus objects implement a control for a single thermal zone with a radiant system.
459
+ # @param zone [OpenStudio::Model::ThermalZone>] zone to add radiant controls
460
+ # @param radiant_loop [OpenStudio::Model::ZoneHVACLowTempRadiantVarFlow>] radiant loop in thermal zone
461
+ # @param radiant_temperature_control_type [String] determines the controlled temperature for the radiant system
462
+ # options are 'SurfaceFaceTemperature', 'SurfaceInteriorTemperature'
463
+ # @param slab_setpoint_oa_control [Bool] True if slab setpoint is to be varied based on outdoor air temperature
464
+ # @param switch_over_time [Double] Time limitation for when the system can switch between heating and cooling
465
+ # @param slab_sp_at_oat_low [Double] radiant slab temperature setpoint, in F, at the outdoor high temperature.
466
+ # @param slab_oat_low [Double] outdoor drybulb air temperature, in F, for low radiant slab setpoint.
467
+ # @param slab_sp_at_oat_high [Double] radiant slab temperature setpoint, in F, at the outdoor low temperature.
468
+ # @param slab_oat_high [Double] outdoor drybulb air temperature, in F, for high radiant slab setpoint.
469
+ def self.model_add_radiant_basic_controls(model, zone, radiant_loop,
470
+ radiant_temperature_control_type: 'SurfaceFaceTemperature',
471
+ slab_setpoint_oa_control: false,
472
+ switch_over_time: 24.0,
473
+ slab_sp_at_oat_low: 73,
474
+ slab_oat_low: 65,
475
+ slab_sp_at_oat_high: 68,
476
+ slab_oat_high: 80)
477
+ zone_name = zone.name.to_s.gsub(/[ +-.]/, '_')
478
+
479
+ if model.version < OpenStudio::VersionString.new('3.1.1')
480
+ coil_cooling_radiant = radiant_loop.coolingCoil.to_CoilCoolingLowTempRadiantVarFlow.get
481
+ coil_heating_radiant = radiant_loop.heatingCoil.to_CoilHeatingLowTempRadiantVarFlow.get
482
+ else
483
+ coil_cooling_radiant = radiant_loop.coolingCoil.get.to_CoilCoolingLowTempRadiantVarFlow.get
484
+ coil_heating_radiant = radiant_loop.heatingCoil.get.to_CoilHeatingLowTempRadiantVarFlow.get
485
+ end
486
+
487
+ #####
488
+ # Define radiant system parameters
489
+ ####
490
+ # set radiant system temperature and setpoint control type
491
+ unless ['surfacefacetemperature', 'surfaceinteriortemperature'].include? radiant_temperature_control_type.downcase
492
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.Model.Model',
493
+ "Control sequences not compatible with '#{radiant_temperature_control_type}' radiant system control. Defaulting to 'SurfaceFaceTemperature'.")
494
+ radiant_temperature_control_type = 'SurfaceFaceTemperature'
495
+ end
496
+
497
+ radiant_loop.setTemperatureControlType(radiant_temperature_control_type)
498
+
499
+ # get existing switchover time schedule or create one if needed
500
+ sch_radiant_switchover = model.getScheduleRulesetByName('Radiant System Switchover')
501
+ if sch_radiant_switchover.is_initialized
502
+ sch_radiant_switchover = sch_radiant_switchover.get
503
+ else
504
+ sch_radiant_switchover = OpenstudioStandards::Schedules.create_constant_schedule_ruleset(model,
505
+ switch_over_time,
506
+ name: 'Radiant System Switchover',
507
+ schedule_type_limit: 'Dimensionless')
508
+ end
509
+
510
+ # set radiant system switchover schedule
511
+ radiant_loop.setChangeoverDelayTimePeriodSchedule(sch_radiant_switchover.to_Schedule.get)
512
+
513
+ if slab_setpoint_oa_control
514
+ # get weather file from model
515
+ weather_file = model.getWeatherFile
516
+ if weather_file.initialized
517
+ # get annual outdoor dry bulb temperature
518
+ annual_oat = weather_file.file.get.data.collect { |dat| dat.dryBulbTemperature.get }
519
+
520
+ # calculate a nhrs rolling average from annual outdoor dry bulb temperature
521
+ nhrs = 24
522
+ last_nhrs_oat_in_year = annual_oat.last(nhrs - 1)
523
+ combined_oat = last_nhrs_oat_in_year + annual_oat
524
+ oat_rolling_average = combined_oat.each_cons(nhrs).map { |e| e.reduce(&:+).fdiv(nhrs).round(2) }
525
+
526
+ # use rolling average to calculate slab setpoint temperature
527
+
528
+ # convert temperature from IP to SI units
529
+ slab_sp_at_oat_low_si = OpenStudio.convert(slab_sp_at_oat_low, 'F', 'C').get
530
+ slab_oat_low_si = OpenStudio.convert(slab_oat_low, 'F', 'C').get
531
+ slab_sp_at_oat_high_si = OpenStudio.convert(slab_sp_at_oat_high, 'F', 'C').get
532
+ slab_oat_high_si = OpenStudio.convert(slab_oat_high, 'F', 'C').get
533
+
534
+ # calculate relationship between slab setpoint and slope
535
+ slope_num = slab_sp_at_oat_high_si - slab_sp_at_oat_low_si
536
+ slope_den = slab_oat_high_si - slab_oat_low_si
537
+ sp_and_oat_slope = slope_num.fdiv(slope_den).round(4)
538
+
539
+ slab_setpoint = oat_rolling_average.map { |e| (slab_sp_at_oat_low_si + ((e - slab_oat_low_si) * sp_and_oat_slope)).round(1) }
540
+
541
+ # input upper limits on slab setpoint
542
+ slab_sp_upper_limit = [slab_sp_at_oat_high_si, slab_sp_at_oat_low_si].max
543
+ slab_sp_lower_limit = [slab_sp_at_oat_high_si, slab_sp_at_oat_low_si].min
544
+ slab_setpoint.map! { |e| e > slab_sp_upper_limit ? slab_sp_upper_limit.round(1) : e }
545
+
546
+ # input lower limits on slab setpoint
547
+ slab_setpoint.map! { |e| e < slab_sp_lower_limit ? slab_sp_lower_limit.round(1) : e }
548
+
549
+ # convert to timeseries
550
+ yd = model.getYearDescription
551
+ start_date = yd.makeDate(1, 1)
552
+ interval = OpenStudio::Time.new(1.0 / 24.0)
553
+ time_series = OpenStudio::TimeSeries.new(start_date, interval, OpenStudio.createVector(slab_setpoint), 'C')
554
+
555
+ # check for pre-existing schedule in model
556
+ schedule_interval = model.getScheduleByName('Sch_Radiant_SlabSetP_Based_On_Rolling_Mean_OAT')
557
+ if schedule_interval.is_initialized && schedule_interval.get.to_ScheduleFixedInterval.is_initialized
558
+ schedule_interval = schedule_interval.get.to_ScheduleFixedInterval.get
559
+ schedule_interval.setTimeSeries(time_series)
560
+ else
561
+ # create fixed interval schedule for slab setpoint
562
+ schedule_interval = OpenStudio::Model::ScheduleFixedInterval.new(model)
563
+ schedule_interval.setName('Sch_Radiant_SlabSetP_Based_On_Rolling_Mean_OAT')
564
+ schedule_interval.setTimeSeries(time_series)
565
+ sch_type_limits_obj = OpenstudioStandards::Schedules.create_schedule_type_limits(model, standard_schedule_type_limit: 'Temperature')
566
+ schedule_interval.setScheduleTypeLimits(sch_type_limits_obj)
567
+ end
568
+
569
+ # assign slab setpoint schedule
570
+ coil_heating_radiant.setHeatingControlTemperatureSchedule(sch_radiant_slab_setp)
571
+ coil_cooling_radiant.setCoolingControlTemperatureSchedule(sch_radiant_slab_setp)
572
+ else
573
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.Model.Model',
574
+ 'Model does not have a weather file associated with it. Define to implement slab setpoint based on outdoor weather.')
575
+ end
576
+ else
577
+ # radiant system cooling control setpoint
578
+ slab_setpoint = 22
579
+ sch_radiant_clgsetp = OpenstudioStandards::Schedules.create_constant_schedule_ruleset(model,
580
+ slab_setpoint + 0.1,
581
+ name: "#{zone_name}_Sch_Radiant_ClgSetP",
582
+ schedule_type_limit: 'Temperature')
583
+ coil_cooling_radiant.setCoolingControlTemperatureSchedule(sch_radiant_clgsetp)
584
+
585
+ # radiant system heating control setpoint
586
+ sch_radiant_htgsetp = OpenstudioStandards::Schedules.create_constant_schedule_ruleset(model,
587
+ slab_setpoint,
588
+ name: "#{zone_name}_Sch_Radiant_HtgSetP",
589
+ schedule_type_limit: 'Temperature')
590
+ coil_heating_radiant.setHeatingControlTemperatureSchedule(sch_radiant_htgsetp)
591
+ end
592
+ end
593
+ end
594
+ end