openstudio-standards 0.2.16 → 0.2.17.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (181) hide show
  1. checksums.yaml +4 -4
  2. data/data/standards/manage_OpenStudio_Standards.rb +31 -4
  3. data/lib/openstudio-standards/btap/geometry.rb +1 -1
  4. data/lib/openstudio-standards/hvac_sizing/Siz.HeatingCoolingFuels.rb +354 -2
  5. data/lib/openstudio-standards/hvac_sizing/Siz.ThermalZone.rb +79 -0
  6. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.College.rb +1 -1
  7. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Laboratory.rb +1 -1
  8. data/lib/openstudio-standards/prototypes/common/do_not_edit_metaclasses.rb +3313 -0
  9. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Fan.rb +12 -0
  10. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.rb +3 -4
  11. data/lib/openstudio-standards/prototypes/common/objects/Prototype.SizingSystem.rb +1 -1
  12. data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +167 -93
  13. data/lib/openstudio-standards/prototypes/common/objects/Prototype.utilities.rb +2 -4
  14. data/lib/openstudio-standards/prototypes/common/prototype_metaprogramming.rb +1 -0
  15. data/lib/openstudio-standards/refs/references.rb +3 -0
  16. data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +279 -6
  17. data/lib/openstudio-standards/standards/Standards.AirTerminalSingleDuctParallelPIUReheat.rb +50 -2
  18. data/lib/openstudio-standards/standards/Standards.ChillerElectricEIR.rb +4 -0
  19. data/lib/openstudio-standards/standards/Standards.CoilCoolingWaterToAirHeatPumpEquationFit.rb +0 -1
  20. data/lib/openstudio-standards/standards/Standards.Construction.rb +185 -3
  21. data/lib/openstudio-standards/standards/Standards.Fan.rb +14 -6
  22. data/lib/openstudio-standards/standards/Standards.HeatExchangerSensLat.rb +1 -0
  23. data/lib/openstudio-standards/standards/Standards.Model.rb +1751 -383
  24. data/lib/openstudio-standards/standards/Standards.PlanarSurface.rb +130 -9
  25. data/lib/openstudio-standards/standards/Standards.PlantLoop.rb +50 -3
  26. data/lib/openstudio-standards/standards/Standards.ScheduleCompact.rb +44 -0
  27. data/lib/openstudio-standards/standards/Standards.ScheduleConstant.rb +27 -0
  28. data/lib/openstudio-standards/standards/Standards.ScheduleRuleset.rb +543 -0
  29. data/lib/openstudio-standards/standards/Standards.Space.rb +665 -15
  30. data/lib/openstudio-standards/standards/Standards.SpaceType.rb +141 -4
  31. data/lib/openstudio-standards/standards/Standards.SubSurface.rb +2 -1
  32. data/lib/openstudio-standards/standards/Standards.Surface.rb +117 -0
  33. data/lib/openstudio-standards/standards/Standards.ThermalZone.rb +197 -49
  34. data/lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb +41 -0
  35. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.Model.rb +6 -8
  36. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/comstock_ashrae_90_1_2004/data/ashrae_90_1.schedules.json +45 -45
  37. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/comstock_ashrae_90_1_2004/data/comstock_ashrae_90_1_2004.spc_typ.json +7 -7
  38. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/comstock_ashrae_90_1_2007/data/ashrae_90_1.schedules.json +45 -45
  39. 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 +7 -7
  40. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/comstock_ashrae_90_1_2010/data/ashrae_90_1.schedules.json +45 -45
  41. 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 +9 -9
  42. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/comstock_ashrae_90_1_2013/data/ashrae_90_1.schedules.json +45 -45
  43. 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 +4 -4
  44. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/comstock_ashrae_90_1_2016/data/ashrae_90_1.schedules.json +45 -45
  45. 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 +5 -5
  46. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +5 -5
  47. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/comstock_ashrae_90_1_2019/data/ashrae_90_1.schedules.json +45 -45
  48. 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 +5 -5
  49. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.constructions.json +2 -2
  50. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.fans.json +12 -0
  51. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/comstock_doe_ref_1980_2004/data/ashrae_90_1.schedules.json +45 -45
  52. 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 +10 -10
  53. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/comstock_doe_ref_pre_1980/data/ashrae_90_1.schedules.json +45 -45
  54. 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 +10 -10
  55. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.AirLoopHVAC.rb +1 -0
  56. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirLoopHVAC.rb +792 -0
  57. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirTerminalSingleDuctParallelPIUReheat.rb +10 -0
  58. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirTerminalSingleDuctVAVReheat.rb +31 -0
  59. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.BoilerHotWater.rb +91 -0
  60. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ChillerElectricEIR.rb +84 -0
  61. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilCoolingDXSingleSpeed.rb +145 -0
  62. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilCoolingDXTwoSpeed.rb +106 -0
  63. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilDX.rb +71 -0
  64. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingDXSingleSpeed.rb +194 -0
  65. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingGas.rb +120 -0
  66. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoolingTower.rb +110 -0
  67. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoolingTowerVariableSpeed.rb +5 -0
  68. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Fan.rb +73 -0
  69. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanConstantVolume.rb +5 -0
  70. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanOnOff.rb +5 -0
  71. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanVariableVolume.rb +24 -0
  72. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanZoneExhaust.rb +5 -0
  73. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.HeatExchangerSensLat.rb +55 -0
  74. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Model.rb +3045 -0
  75. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlanarSurface.rb +187 -0
  76. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlantLoop.rb +450 -0
  77. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Space.rb +106 -0
  78. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.SpaceType.rb +666 -0
  79. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Surface.rb +54 -0
  80. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ThermalZone.rb +168 -0
  81. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ZoneHVACComponent.rb +132 -0
  82. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.rb +239 -0
  83. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019.Model.rb +176 -0
  84. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019.rb +25 -0
  85. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.boilers.json +52 -0
  86. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.chillers.json +112 -0
  87. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.climate_zone_sets.json +210 -0
  88. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.construction_properties.json +10384 -0
  89. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.construction_sets.json +133 -0
  90. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.furnaces.json +43 -0
  91. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.heat_pumps.json +119 -0
  92. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.heat_pumps_heating.json +130 -0
  93. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.heat_rejection.json +13 -0
  94. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.lpd_space_type.json +568 -0
  95. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.motors.json +264 -0
  96. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_baseline_hvac.json +439 -0
  97. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_constructions.json +685 -0
  98. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_economizers.json +213 -0
  99. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_ext_ltg.json +32 -0
  100. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_heat_type.json +136 -0
  101. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_hvac_bldg_type.json +32 -0
  102. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_interior_lighting.json +1837 -0
  103. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_swh_bldg_type.json +184 -0
  104. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_wwr_bldg_type.json +84 -0
  105. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.unitary_acs.json +148 -0
  106. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.water_heaters.json +157 -0
  107. data/lib/openstudio-standards/standards/ashrae_90_1_prm/data/ashrae_90_1_prm.climate_zone_sets.json +210 -0
  108. data/lib/openstudio-standards/standards/ashrae_90_1_prm/data/ashrae_90_1_prm.curves.json +18329 -0
  109. data/lib/openstudio-standards/standards/ashrae_90_1_prm/data/ashrae_90_1_prm.fans.json +340 -0
  110. data/lib/openstudio-standards/standards/ashrae_90_1_prm/data/ashrae_90_1_prm.materials.json +49924 -0
  111. data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/baseline_building_rotation_exception.md +44 -0
  112. data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/check_pump_power_and_control.md +71 -0
  113. data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/dcv.md +68 -0
  114. data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/dcv_implementation.png +0 -0
  115. data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/elevators.md +14 -0
  116. data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/exhaust_air_energy_recovery.md +36 -0
  117. data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/f_c_factors.md +19 -0
  118. data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/fan_power_credits.md +15 -0
  119. data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/preheat_coil.md +59 -0
  120. data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/pump_power_control.md +46 -0
  121. data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/return_air_type.md +31 -0
  122. data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/set_baseline_wwr.md +191 -0
  123. data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/set_hw_and_chw_supply_water_temp_reset_control.md +24 -0
  124. data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/set_num_boilers_chillers_towers.md +49 -0
  125. data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/set_plug_load_measures.md +80 -0
  126. data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/set_space_lpd.md +73 -0
  127. data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/unenclosed_and_unconditioned_spaces.md +11 -0
  128. data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/unmet_load_hours.md +20 -0
  129. data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/vav_parallel_piu_terminals_fan_control.md +23 -0
  130. data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/vav_terminals_min_flow_setpoint.md +21 -0
  131. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_airloop_hvac.csv +1 -0
  132. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_airloop_hvac_doas.csv +1 -0
  133. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_building.csv +1 -0
  134. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_design_specification_outdoor_air.csv +1 -0
  135. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_electric_equipment.csv +1 -0
  136. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_exterior_lights.csv +1 -0
  137. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_gas_equipment.csv +1 -0
  138. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_lights.csv +1 -0
  139. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_space.csv +1 -0
  140. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_spacetype.csv +1 -0
  141. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_thermal_zone.csv +1 -0
  142. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_wateruse_connections.csv +1 -0
  143. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_wateruse_equipment.csv +1 -0
  144. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_wateruse_equipment_definition.csv +1 -0
  145. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_zone_hvac.csv +1 -0
  146. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_zone_infiltration.csv +1 -0
  147. data/lib/openstudio-standards/standards/cbes/data/cbes.fans.json +12 -0
  148. data/lib/openstudio-standards/standards/deer/data/deer.fans.json +12 -0
  149. data/lib/openstudio-standards/standards/necb/ECMS/data/heat_pumps.json +1 -1
  150. data/lib/openstudio-standards/standards/necb/ECMS/data/heat_pumps_heating.json +1 -1
  151. data/lib/openstudio-standards/standards/necb/ECMS/data/unitary_acs.json +24 -11
  152. data/lib/openstudio-standards/standards/necb/ECMS/erv.rb +13 -15
  153. data/lib/openstudio-standards/standards/necb/NECB2011/data/province_map.json +17 -0
  154. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_multi_speed.rb +1 -1
  155. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_single_speed.rb +1 -1
  156. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_4.rb +2 -2
  157. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_6.rb +6 -5
  158. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +3 -2
  159. data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +2 -3
  160. data/lib/openstudio-standards/standards/necb/NECB2020/data/chillers.json +2 -2
  161. data/lib/openstudio-standards/standards/necb/NECB2020/data/space_types.json +33 -924
  162. data/lib/openstudio-standards/standards/necb/NECB2020/data/unitary_acs.json +15 -15
  163. data/lib/openstudio-standards/standards/necb/common/btap_data.rb +135 -29
  164. data/lib/openstudio-standards/standards/necb/common/btap_datapoint.rb +16 -4
  165. data/lib/openstudio-standards/standards/necb/common/neb_end_use_prices.csv +40 -42
  166. data/lib/openstudio-standards/standards/necb/common/necb_reference_runs.csv +1 -1
  167. data/lib/openstudio-standards/standards/necb/common/space_type_upgrade_map.json +89 -89
  168. data/lib/openstudio-standards/utilities/array.rb +11 -0
  169. data/lib/openstudio-standards/utilities/logging.rb +48 -0
  170. data/lib/openstudio-standards/utilities/object_info.rb +20 -0
  171. data/lib/openstudio-standards/utilities/schedule_translator.rb +348 -0
  172. data/lib/openstudio-standards/utilities/sqlfile.rb +68 -0
  173. data/lib/openstudio-standards/version.rb +2 -2
  174. data/lib/openstudio-standards/weather/Weather.Model.rb +42 -55
  175. data/lib/openstudio-standards/weather/Weather.stat_file.rb +1 -1
  176. data/lib/openstudio-standards.rb +35 -1
  177. metadata +111 -6
  178. data/data/standards/OpenStudio_Standards-ashrae_90_1.xlsx +0 -0
  179. data/data/standards/OpenStudio_Standards-ashrae_90_1_28Jan2022.xlsx +0 -0
  180. data/data/standards/OpenStudio_Standards-ashrae_90_1_28_Jan2022_2.xlsx +0 -0
  181. data/data/standards/openstudio_standards_duplicates_log.csv +0 -143
@@ -0,0 +1,54 @@
1
+ class ASHRAE901PRM < Standard
2
+ # Adjust the fenestration area to the values specified by the reduction value in a surface
3
+ #
4
+ # @param surface [OpenStudio::Model:Surface] openstudio surface object
5
+ # @param reduction [Float] ratio of adjustments
6
+ # @param model [OpenStudio::Model::Model] openstudio model
7
+ # @return [Bool] return true if successful, false if not
8
+ def surface_adjust_fenestration_in_a_surface(surface, reduction, model)
9
+ # do nothing for cases when reduction == 1.0
10
+ if reduction < 1.0
11
+ surface.subSurfaces.sort.each do |ss|
12
+ next unless ss.subSurfaceType == 'FixedWindow' || ss.subSurfaceType == 'OperableWindow' || ss.subSurfaceType == 'GlassDoor'
13
+
14
+ sub_surface_reduce_area_by_percent_by_shrinking_toward_centroid(ss, reduction)
15
+ end
16
+ elsif reduction > 1.0
17
+ # case increase the window
18
+ surface_wwr = surface_get_wwr_of_a_surface(surface)
19
+ if surface_wwr == 0.0
20
+ # In this case, we are adding fenestration
21
+ wwr_adjusted = reduction - 1.0
22
+ # add the value to additional properties in case of readjusting WWR for doors
23
+ surface.additionalProperties.setFeature('added_wwr', wwr_adjusted)
24
+ else
25
+ wwr_adjusted = surface_wwr * reduction
26
+ end
27
+ # Save doors to a temp list
28
+ door_list = []
29
+ surface.subSurfaces.sort.each do |sub|
30
+ if sub.subSurfaceType == 'Door'
31
+ door = {}
32
+ door['name'] = sub.name.get
33
+ door['vertices'] = sub.vertices
34
+ door['construction'] = sub.construction.get
35
+ door_list << door
36
+ end
37
+ end
38
+ # remove all existing windows and set the window to wall ratio to the calculated new WWR
39
+ # Remove all sub-surfaces including doors
40
+ surface.subSurfaces.sort.each(&:remove)
41
+ # Apply default construction to the subsurface - the standard construction will be applied later.
42
+ surface.setWindowToWallRatio(wwr_adjusted, 0.6, true)
43
+ # add door back.
44
+ unless door_list.empty?
45
+ door_list.each do |door|
46
+ os_door = OpenStudio::Model::SubSurface.new(door['vertices'], model)
47
+ os_door.setName(door['name'])
48
+ os_door.setConstruction(door['construction'])
49
+ os_door.setSurface(surface)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,168 @@
1
+ class ASHRAE901PRM < Standard
2
+ # @!group ThermalZone
3
+
4
+ # Determine the fan power limitation pressure drop adjustment
5
+ # Per Table 6.5.3.1-2 (90.1-2019)
6
+ #
7
+ # @param thermal_zone
8
+ def thermal_zone_get_fan_power_limitations(thermal_zone, is_energy_recovery_required)
9
+ fan_pwr_adjustment_in_wc = 0
10
+ # Get autosized zone design supply air flow rate
11
+ dsn_zone_air_flow_m3_per_s = thermal_zone.designAirFlowRate.to_f
12
+ dsn_zone_air_flow_cfm = OpenStudio.convert(dsn_zone_air_flow_m3_per_s, 'm^3/s', 'cfm').get
13
+
14
+ # Retrieve credits from zone additional features
15
+ # Fully ducted return and/or exhaust air systems
16
+ if thermal_zone.additionalProperties.hasFeature('has_fan_power_credit_fully_ducted')
17
+ mult = thermal_zone.additionalProperties.getFeatureAsDouble('has_fan_power_credit_fully_ducted').to_f
18
+ adj_in_wc = 0.5 * mult
19
+ fan_pwr_adjustment_in_wc += adj_in_wc
20
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Added #{adj_in_wc} in wc for fully ducted return and/or exhaust air systems")
21
+ end
22
+
23
+ # Return and/or exhaust airflow control devices
24
+ if thermal_zone.additionalProperties.hasFeature('has_fan_power_credit_return_or_exhaust_flow_control')
25
+ mult = thermal_zone.additionalProperties.getFeatureAsDouble('has_fan_power_credit_return_or_exhaust_flow_control').to_f
26
+ adj_in_wc = 0.5 * mult
27
+ fan_pwr_adjustment_in_wc += adj_in_wc
28
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Added #{adj_in_wc} in wc for return and/or exhaust airflow control devices")
29
+ end
30
+
31
+ # Exhaust filters, scrubbers, or other exhaust treatment
32
+ if thermal_zone.additionalProperties.hasFeature('fan_power_credit_exhaust_treatment')
33
+ adj_in_wc = thermal_zone.additionalProperties.getFeatureAsDouble('fan_power_credit_exhaust_treatment').to_f
34
+ fan_pwr_adjustment_in_wc += adj_in_wc
35
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Added #{adj_in_wc} in wc for exhaust filters, scrubbers, or other exhaust treatment")
36
+ end
37
+
38
+ # MERV 9 through 12
39
+ if thermal_zone.additionalProperties.hasFeature('has_fan_power_credit_filtration_m9to12')
40
+ mult = thermal_zone.additionalProperties.getFeatureAsDouble('has_fan_power_credit_filtration_m9to12').to_f
41
+ adj_in_wc = 0.5 * mult
42
+ fan_pwr_adjustment_in_wc += adj_in_wc
43
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Added #{adj_in_wc} in wc for particulate Filtration Credit: MERV 9 through 12")
44
+ end
45
+
46
+ # MERV 13 through 15
47
+ if thermal_zone.additionalProperties.hasFeature('has_fan_power_credit_filtration_m13to15')
48
+ mult = thermal_zone.additionalProperties.getFeatureAsDouble('has_fan_power_credit_filtration_m13to15').to_f
49
+ adj_in_wc = 0.9 * mult
50
+ fan_pwr_adjustment_in_wc += adj_in_wc
51
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Added #{adj_in_wc} in wc for particulate Filtration Credit: MERV 13 through 15")
52
+ end
53
+
54
+ # MERV 16 and greater and electronically enhanced filters
55
+ if thermal_zone.additionalProperties.hasFeature('clean_filter_pressure_drop_for_fan_power_credit_filtration_m16plus')
56
+ adj_in_wc = thermal_zone.additionalProperties.getFeatureAsDouble('clean_filter_pressure_drop_for_fan_power_credit_filtration_m16plus').to_f
57
+ fan_pwr_adjustment_in_wc += adj_in_wc
58
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Added #{adj_in_wc} in wc for particulate Filtration Credit: MERV 16 and greater and electronically enhanced filters")
59
+ end
60
+
61
+ # Carbon and other gas-phase air cleaners
62
+ if thermal_zone.additionalProperties.hasFeature('fan_power_credit_gas_phase_cleaners')
63
+ adj_in_wc = thermal_zone.additionalProperties.getFeatureAsDouble('fan_power_credit_gas_phase_cleaners').to_f
64
+ fan_pwr_adjustment_in_wc += adj_in_wc
65
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Added #{adj_in_wc} in wc for carbon and other gas-phase air cleaners")
66
+ end
67
+
68
+ # Biosafety cabinet
69
+ if thermal_zone.additionalProperties.hasFeature('fan_power_credit_biosafety')
70
+ adj_in_wc = thermal_zone.additionalProperties.getFeatureAsDouble('fan_power_credit_biosafety').to_f
71
+ fan_pwr_adjustment_in_wc += adj_in_wc
72
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Added #{adj_in_wc} in wc for biosafety cabinet")
73
+ end
74
+
75
+ # Energy recovery device, other than coil runaround loop
76
+ if thermal_zone.additionalProperties.hasFeature('fan_power_credit_other_than_coil_runaround')
77
+ if is_energy_recovery_required
78
+ adj_in_wc = thermal_zone.additionalProperties.getFeatureAsDouble('fan_power_credit_other_than_coil_runaround').to_f
79
+ fan_pwr_adjustment_in_wc += adj_in_wc
80
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Added #{adj_in_wc} in wc for energy recovery device other than coil runaround loop")
81
+ end
82
+ end
83
+
84
+ # Coil runaround loop
85
+ if thermal_zone.additionalProperties.hasFeature('has_fan_power_credit_coil_runaround')
86
+ if is_energy_recovery_required
87
+ mult = thermal_zone.additionalProperties.getFeatureAsDouble('has_fan_power_credit_coil_runaround').to_f
88
+ adj_in_wc = 0.6 * 2 * mult # for each stream
89
+ fan_pwr_adjustment_in_wc += adj_in_wc
90
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Added #{adj_in_wc} in wc for coil runaround loop")
91
+ end
92
+ end
93
+
94
+ # Evaporative humidifier/cooler in series with another cooling coil
95
+ if thermal_zone.additionalProperties.hasFeature('fan_power_credit_evaporative_humidifier_or_cooler')
96
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', '--Added 0 in wc for evaporative humidifier/cooler in series with another coil as per Table G3.1.2.9 Note 2')
97
+ end
98
+
99
+ # Sound attenuation section (fans serving spoaces with design background noise goals below NC35)
100
+ if thermal_zone.additionalProperties.hasFeature('has_fan_power_credit_sound_attenuation')
101
+ mult = thermal_zone.additionalProperties.getFeatureAsDouble('has_fan_power_credit_sound_attenuation').to_f
102
+ adj_in_wc = 0.15 * mult
103
+ fan_pwr_adjustment_in_wc += adj_in_wc
104
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Added #{adj_in_wc} in wc for sound attenuation section")
105
+ end
106
+
107
+ # Exhaust system serving fume hoods
108
+ if thermal_zone.additionalProperties.hasFeature('has_fan_power_credit_exhaust_serving_fume_hoods')
109
+ mult = thermal_zone.additionalProperties.getFeatureAsDouble('has_fan_power_credit_exhaust_serving_fume_hoods').to_f
110
+ adj_in_wc = 0.35 * mult
111
+ fan_pwr_adjustment_in_wc += adj_in_wc
112
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Added #{adj_in_wc} in wc for exhaust system serving fume hoods")
113
+ end
114
+
115
+ # Laboratory and vivarium exhaust systems in high-rise buildings
116
+ if thermal_zone.additionalProperties.hasFeature('has_fan_power_credit_lab_or_vivarium_highrise_vertical_duct')
117
+ mult = thermal_zone.additionalProperties.getFeatureAsDouble('has_fan_power_credit_lab_or_vivarium_highrise_vertical_duct').to_f
118
+ adj_in_wc = 0.35 * mult
119
+ fan_pwr_adjustment_in_wc += adj_in_wc
120
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Added #{adj_in_wc} in wc for laboratory and vivarium exhaust systems in high-rise buildings")
121
+ end
122
+
123
+ # Deductions
124
+ # Systems without central cooling device
125
+ if thermal_zone.additionalProperties.hasFeature('has_fan_power_deduction_system_without_central_cooling_device')
126
+ mult = thermal_zone.additionalProperties.getFeatureAsDouble('has_fan_power_deduction_system_without_central_cooling_device').to_f
127
+ adj_in_wc = 0.60 * mult
128
+ fan_pwr_adjustment_in_wc -= adj_in_wc
129
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Removed #{adj_in_wc} in wc for system without central cooling device")
130
+ end
131
+
132
+ # Systems without central heating device
133
+ if thermal_zone.additionalProperties.hasFeature('has_fan_power_deduction_system_without_central_heating_device')
134
+ mult = thermal_zone.additionalProperties.getFeatureAsDouble('has_fan_power_deduction_system_without_central_heating_device').to_f
135
+ adj_in_wc = 0.30 * mult
136
+ fan_pwr_adjustment_in_wc -= adj_in_wc
137
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Removed #{adj_in_wc} in wc for system without central heating device")
138
+ end
139
+
140
+ # Systems with central electric resistance heat
141
+ if thermal_zone.additionalProperties.hasFeature('has_fan_power_deduction_system_with_central_electric_resistance_heat')
142
+ mult = thermal_zone.additionalProperties.getFeatureAsDouble('has_fan_power_deduction_system_with_central_electric_resistance_heat').to_f
143
+ adj_in_wc = 0.20 * mult
144
+ fan_pwr_adjustment_in_wc -= adj_in_wc
145
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Removed #{adj_in_wc} in wc for system with central electric resistance heat")
146
+ end
147
+
148
+ # Convert the pressure drop adjustment to brake horsepower (bhp)
149
+ # assuming that all supply air passes through all devices
150
+ return fan_pwr_adjustment_in_wc * dsn_zone_air_flow_cfm / 4131
151
+ end
152
+
153
+ # Identify if zone has district energy for occ_and_fuel_type method
154
+ # @param themal_zone
155
+ # @return [string] with applicable DistrictHeating and/or DistrictCooling
156
+ def thermal_zone_get_zone_fuels_for_occ_and_fuel_type(zone)
157
+ zone_fuels = ''
158
+ htg_fuels = zone.heating_fuels
159
+ if htg_fuels.include?('DistrictHeating')
160
+ zone_fuels = 'DistrictHeating'
161
+ end
162
+ clg_fuels = zone.cooling_fuels
163
+ if clg_fuels.include?('DistrictCooling')
164
+ zone_fuels += 'DistrictCooling'
165
+ end
166
+ return zone_fuels
167
+ end
168
+ end
@@ -0,0 +1,132 @@
1
+ class ASHRAE901PRM < Standard
2
+ # @!group ZoneHVACComponent
3
+
4
+ # Sets the fan power of zone level HVAC equipment
5
+ # (Fan coils, Unit Heaters, PTACs, PTHPs, VRF Terminals, WSHPs, ERVs)
6
+ # based on the W/cfm specified in the standard.
7
+ #
8
+ # @return [Bool] returns true if successful, false if not
9
+ def zone_hvac_component_apply_prm_baseline_fan_power(zone_hvac_component)
10
+ OpenStudio.logFree(OpenStudio::Debug, 'openstudio.ashrae_90_1_prm.ZoneHVACComponent', "Setting fan power for #{zone_hvac_component.name}.")
11
+
12
+ # Convert this to the actual class type
13
+ zone_hvac = if zone_hvac_component.to_ZoneHVACFourPipeFanCoil.is_initialized
14
+ zone_hvac_component.to_ZoneHVACFourPipeFanCoil.get
15
+ elsif zone_hvac_component.to_ZoneHVACUnitHeater.is_initialized
16
+ zone_hvac_component.to_ZoneHVACUnitHeater.get
17
+ elsif zone_hvac_component.to_ZoneHVACPackagedTerminalAirConditioner.is_initialized
18
+ zone_hvac_component.to_ZoneHVACPackagedTerminalAirConditioner.get
19
+ elsif zone_hvac_component.to_ZoneHVACPackagedTerminalHeatPump.is_initialized
20
+ zone_hvac_component.to_ZoneHVACPackagedTerminalHeatPump.get
21
+ elsif zone_hvac_component.to_ZoneHVACTerminalUnitVariableRefrigerantFlow.is_initialized
22
+ zone_hvac_component.to_ZoneHVACTerminalUnitVariableRefrigerantFlow.get
23
+ elsif zone_hvac_component.to_ZoneHVACWaterToAirHeatPump.is_initialized
24
+ zone_hvac_component.to_ZoneHVACWaterToAirHeatPump.get
25
+ elsif zone_hvac_component.to_ZoneHVACEnergyRecoveryVentilator.is_initialized
26
+ zone_hvac_component.to_ZoneHVACEnergyRecoveryVentilator.get
27
+ end
28
+
29
+ # Do nothing for other types of zone HVAC equipment
30
+ return false if zone_hvac.nil?
31
+
32
+ # Do nothing if zone hav component isn't assigned to thermal zone
33
+ return false unless zone_hvac.thermalZone.is_initialized
34
+
35
+ # Get baseline system type
36
+ system_type = zone_hvac.thermalZone.get.additionalProperties.getFeatureAsString('baseline_system_type').get
37
+
38
+ # Get non-mechanically cooled flag
39
+ if zone_hvac.thermalZone.get.additionalProperties.hasFeature('non_mechanically_cooled')
40
+ nmc_flag = zone_hvac.thermalZone.get.additionalProperties.hasFeature('non_mechanically_cooled')
41
+ else nmc_flag = false
42
+ end
43
+
44
+ # Get the fan
45
+ fan = if zone_hvac.supplyAirFan.to_FanConstantVolume.is_initialized
46
+ zone_hvac.supplyAirFan.to_FanConstantVolume.get
47
+ elsif zone_hvac.supplyAirFan.to_FanVariableVolume.is_initialized
48
+ zone_hvac.supplyAirFan.to_FanVariableVolume.get
49
+ elsif zone_hvac.supplyAirFan.to_FanOnOff.is_initialized
50
+ zone_hvac.supplyAirFan.to_FanOnOff.get
51
+ elsif zone_hvac.supplyAirFan.to_FanSystemModel.is_initialized
52
+ zone_hvac.supplyAirFan.to_FanSystemModel.get
53
+ end
54
+
55
+ if system_type == 'SZ_CV' # System 12, 13
56
+ # Get design supply air flow rate (whether autosized or hard-sized)
57
+ dsn_air_flow_m3_per_s = 0
58
+ dsn_air_flow_cfm = 0
59
+ if fan.isMaximumFlowRateAutosized
60
+ dsn_air_flow_m3_per_s = fan.autosizedMaximumFlowRate.get
61
+ else
62
+ dsn_air_flow_m3_per_s = fan.maximumFlowRate.get
63
+ end
64
+ dsn_air_flow_cfm = OpenStudio.convert(dsn_air_flow_m3_per_s, 'm^3/s', 'cfm').get
65
+
66
+ # Determine allowable fan BHP and power
67
+ allowable_fan_bhp = 0.00094 * dsn_air_flow_cfm + thermal_zone_get_fan_power_limitations(zone_hvac.thermalZone.get, false)
68
+ fan_apply_standard_minimum_motor_efficiency(fan, allowable_fan_bhp)
69
+ allowable_power_w = allowable_fan_bhp * 746 / fan.motorEfficiency
70
+
71
+ # Modify fan pressure rise to match target fan power
72
+ fan_adjust_pressure_rise_to_meet_fan_power(fan, allowable_power_w)
73
+ else # System 1, 2
74
+ # Determine the W/cfm
75
+ fan_efficacy_w_per_cfm = 0.0
76
+ case system_type
77
+ when 'PTAC', 'PTHP'
78
+ fan_efficacy_w_per_cfm = 0.3 # System 9, 10
79
+ when 'Gas_Furnace', 'Electric_Furnace'
80
+ # Zone heater cannot provide cooling
81
+ if nmc_flag & !zone_hvac_component.to_ZoneHVACUnitHeater.is_initialized
82
+ fan_efficacy_w_per_cfm = 0.054
83
+ else
84
+ fan_efficacy_w_per_cfm = 0.3
85
+ end
86
+ else OpenStudio.logFree(OpenStudio::Error, 'openstudio.ashrae_90_1_prm.ZoneHVACComponent', 'Zone HVAC system fan power lookup missing.')
87
+ end
88
+
89
+ # Convert efficacy to metric
90
+ fan_efficacy_w_per_m3_per_s = OpenStudio.convert(fan_efficacy_w_per_cfm, 'm^3/s', 'cfm').get
91
+
92
+ # Get the maximum flow rate through the fan
93
+ max_air_flow_rate = nil
94
+ if fan.autosizedMaximumFlowRate.is_initialized
95
+ max_air_flow_rate = fan.autosizedMaximumFlowRate.get
96
+ elsif fan.maximumFlowRate.is_initialized
97
+ max_air_flow_rate = fan.maximumFlowRate.get
98
+ end
99
+ max_air_flow_rate_cfm = OpenStudio.convert(max_air_flow_rate, 'm^3/s', 'ft^3/min').get
100
+
101
+ # Set the impeller efficiency
102
+ fan_change_impeller_efficiency(fan, fan_baseline_impeller_efficiency(fan))
103
+
104
+ # Get fan BHP
105
+ fan_bhp = fan_brake_horsepower(fan)
106
+
107
+ # Set the motor efficiency, preserving the impeller efficiency.
108
+ # For zone HVAC fans, a bhp lookup of 0.5bhp is always used because
109
+ # they are assumed to represent a series of small fans in reality.
110
+ fan_apply_standard_minimum_motor_efficiency(fan, fan_bhp)
111
+
112
+ # Calculate a new pressure rise to hit the target W/cfm
113
+ fan_tot_eff = fan.fanEfficiency
114
+ fan_rise_new_pa = fan_efficacy_w_per_m3_per_s * fan_tot_eff
115
+ fan.setPressureRise(fan_rise_new_pa)
116
+
117
+ # Calculate the newly set efficacy
118
+ fan_power_new_w = fan_rise_new_pa * max_air_flow_rate / fan_tot_eff
119
+ fan_efficacy_new_w_per_cfm = fan_power_new_w / max_air_flow_rate_cfm
120
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.ashrae_90_1_prm.ZoneHVACComponent', "For #{zone_hvac_component.name}: fan efficacy set to #{fan_efficacy_new_w_per_cfm.round(2)} W/cfm.")
121
+ end
122
+ return true
123
+ end
124
+
125
+ # Default occupancy fraction threshold for determining if the spaces served by the zone hvac are occupied
126
+ #
127
+ # @return [Double] unoccupied threshold
128
+ def zone_hvac_unoccupied_threshold
129
+ # Use 10% based on PRM-RM
130
+ return 0.10
131
+ end
132
+ end
@@ -0,0 +1,239 @@
1
+ require 'csv'
2
+
3
+ # This abstract class holds methods that many versions of ASHRAE 90.1 share.
4
+ # If a method in this class is redefined by a subclass,
5
+ # the implementation in the subclass is used.
6
+ # @abstract
7
+ class ASHRAE901PRM < Standard
8
+ def initialize
9
+ load_standards_database
10
+ end
11
+
12
+ def load_standards_database(data_directories = [])
13
+ super([__dir__] + data_directories)
14
+ end
15
+
16
+ # Convert user data csv files to json format and save to project folder
17
+ # Method will create the json_folder in the project_path
18
+ # @author Doug Maddox, PNNL
19
+ # @param user_data_folder [string] path to folder containing csv files
20
+ # @param project_folder [string] path to project folder
21
+ # @return [string] path to json files
22
+ def convert_userdata_csv_to_json(user_data_path, project_path)
23
+ # Get list of possible files from lib\openstudio-standards\standards\ashrae_90_1_prm\userdata_csv
24
+ stds_dir = __dir__
25
+ src_csv_dir = "#{stds_dir}/userdata_csv/*.csv"
26
+ json_objs = {}
27
+ Dir.glob(src_csv_dir) do |csv_full_name|
28
+ json_rows = []
29
+ csv_file_name = File.basename(csv_full_name, File.extname(csv_full_name))
30
+ json_objs[csv_file_name] = json_rows
31
+ end
32
+
33
+ # Read all valid files in user_data_folder and load into json array
34
+ unless user_data_path == ''
35
+ user_data_validation_outcome = true
36
+ Dir.glob("#{user_data_path}/*.csv") do |csv_full_name|
37
+ csv_file_name = File.basename(csv_full_name, File.extname(csv_full_name))
38
+ if json_objs.key?(csv_file_name)
39
+ # Load csv file into array of hashes
40
+ json_rows = CSV.foreach(csv_full_name, headers: true).map { |row| user_data_preprocessor(row) }
41
+ next if json_rows.empty?
42
+
43
+ # validate the user_data in json_rows
44
+ unless user_data_validation(csv_file_name, json_rows)
45
+ user_data_validation_outcome = false
46
+ end
47
+
48
+ # remove file extension
49
+ file_name = File.basename(csv_full_name, File.extname(csv_full_name))
50
+ json_objs[file_name] = json_rows
51
+ end
52
+ end
53
+ unless user_data_validation_outcome
54
+ terminate_prm_write_log('Error found in the user data. Check output log to see detail error messages', project_path, false)
55
+ end
56
+ end
57
+
58
+ # Make folder for json files; remove pre-existing first, if needed
59
+ json_path = "#{project_path}/user_data_json"
60
+ if !Dir.exist?(json_path)
61
+ Dir.mkdir(json_path)
62
+ else
63
+ FileUtils.rm_rf(json_path)
64
+ Dir.mkdir(json_path)
65
+ end
66
+
67
+ # Write all json files
68
+ json_objs.each do |file_name, json_rows|
69
+ json_obj = {}
70
+ json_obj[file_name] = json_rows
71
+ json_path_file = "#{json_path}/#{file_name}.json"
72
+ File.open(json_path_file, 'w:UTF-8') do |file|
73
+ file << JSON.pretty_generate(json_obj)
74
+ end
75
+ end
76
+
77
+ return json_path
78
+ end
79
+
80
+ # Load user data from project folder into standards database data structure
81
+ # Each user data object type is a new item in the @standards_data hash
82
+ # @author Doug Maddox, PNNL
83
+ # @param json_path [string] path to folder containing json files
84
+ def load_userdata_to_standards_database(json_path)
85
+ files = Dir.glob("#{json_path}/*.json").select { |e| File.file? e }
86
+ files.each do |file|
87
+ data = JSON.parse(File.read(file))
88
+ data.each_pair do |key, objs|
89
+ # Override the template in inherited files to match the instantiated template
90
+ if @standards_data[key].nil?
91
+ OpenStudio.logFree(OpenStudio::Debug, 'openstudio.standards.standard', "Adding #{key} from #{File.basename(file)}")
92
+ else
93
+ OpenStudio.logFree(OpenStudio::Debug, 'openstudio.standards.standard', "Overriding #{key} with #{File.basename(file)}")
94
+ end
95
+ @standards_data[key] = objs
96
+ end
97
+ end
98
+ end
99
+
100
+ # Perform user data preprocessing
101
+ # @param [CSV::ROW] row 2D array for each row.
102
+ def user_data_preprocessor(row)
103
+ new_array = []
104
+
105
+ # Strip the strings in the value
106
+ row.each do |sub_array|
107
+ new_array << sub_array.collect { |e| e ? e.strip : e }
108
+ end
109
+ # TODO: Future expansion can added to here.
110
+ # Convert the 2d array to hash
111
+ return new_array.to_h
112
+ end
113
+
114
+ # Perform user data validation
115
+
116
+ # @param object_name [String] name of user data csv file to check
117
+ # @param user_data [Hash] hash of data from user data csv file
118
+
119
+ # @return [Boolean] true if data is valid, false if error found
120
+ def user_data_validation(object_name, user_data)
121
+ # 1. Check user_spacetype and user_space LPD total % = 1.0
122
+ case object_name
123
+ when 'userdata_space', 'userdata_spacetype'
124
+ return check_userdata_space_and_spacetype(object_name, user_data)
125
+ when 'user_electric_equipment'
126
+ return check_userdata_electric_equipment(object_name, user_data)
127
+ else
128
+ return true
129
+ end
130
+ end
131
+
132
+ # Check for incorrect data in electric equipment user data
133
+
134
+ # @param object_name [String] name of user data csv file to check
135
+ # @param user_data [Hash] hash of data from user data csv file
136
+
137
+ # @return [Boolean] true if data is valid, false if error found
138
+ def check_userdata_electric_equipment(object_name, user_data)
139
+ userdata_valid = true
140
+ user_data.each do |electric_row|
141
+ if electric_row['motor_horsepower'].nil? || electric_row['motor_efficiency'].nil? || electric_row['motor_is_exempt'].nil?
142
+ unless electric_row['motor_horsepower'].nil? && electric_row['motor_efficiency'].nil? && electric_row['motor_is_exempt'].nil?
143
+ userdata_valid = false
144
+ OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data: #{object_name}: One or more motor data are not available for electric equipment #{electric_row['name']}. motor_horsepower: #{electric_row['motor_horsepower']}; motor_efficiency: #{electric_row['motor_efficiency']}; motor_is_exempt: #{electric_row['motor_is_exempt']}")
145
+ end
146
+ else
147
+ # check for data type
148
+ if electric_row['motor_horsepower'].to_f == 0.0
149
+ userdata_valid = false
150
+ OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data: #{object_name}: Motor #{electric_row['name']}'s horsepower data is either 0.0 or unavailable. Check the inputs.")
151
+ end
152
+ if electric_row['motor_efficiency'].to_f == 0.0
153
+ userdata_valid = false
154
+ OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data: #{object_name}: Motor #{electric_row['name']}'s efficiency data is either 0.0 or unavailable. Check the inputs.")
155
+ end
156
+ if electric_row['motor_is_exempt'].casecmp?('yes') || electric_row['motor_is_exempt'].casecmp?('no')
157
+ userdata_valid = false
158
+ OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data: #{object_name}: Motor #{electric_row['name']} is exempt data should be either Yes or No. But get data #{electric_row['motor_is_exempt']}")
159
+ end
160
+ end
161
+ # We may need to do the same for refrigeration and elevator?
162
+ # Check elevator
163
+ if electric_row['elevator_weight_of_car'].nil? || electric_row['elevator_rated_load'].nil? || electric_row['elevator_counter_weight_of_car'].nil? || electric_row['elevator_speed_of_car'].nil? || electric_row['elevator_number_of_stories'].nil?
164
+ if electric_row['elevator_weight_of_car'].nil? && electric_row['elevator_rated_load'].nil? && electric_row['elevator_counter_weight_of_car'].nil? && electric_row['elevator_speed_of_car'].nil? && electric_row['elevator_number_of_stories'].nil?
165
+ userdata_valid = false
166
+ OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data: #{object_name}: One or more elevator data is not available for electric equipment #{electric_row['name']}. elevator_weight_of_car: #{electric_row['elevator_weight_of_car']}; elevator_rated_load: #{electric_row['elevator_rated_load']}; elevator_counter_weight_of_car: #{electric_row['elevator_counter_weight_of_car']}; elevator_speed_of_car: #{electric_row['elevator_speed_of_car']}; elevator_number_of_stories: #{electric_row['elevator_number_of_stories']}")
167
+ end
168
+ else
169
+ # check for data type
170
+ if electric_row['elevator_weight_of_car'].to_f == 0.0
171
+ userdata_valid = false
172
+ OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data: #{object_name}: Elevator #{electric_row['name']}'s weight of car data is either 0.0 or unavailable. Check the inputs.")
173
+ end
174
+ if electric_row['elevator_rated_load'].to_f == 0.0
175
+ userdata_valid = false
176
+ OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data: #{object_name}: Elevator #{electric_row['name']}'s rated load data is either 0.0 or unavailable. Check the inputs.")
177
+ end
178
+ if electric_row['elevator_counter_weight_of_car'].to_f == 0.0
179
+ userdata_valid = false
180
+ OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data: #{object_name}: Elevator #{electric_row['name']}'s counter weight of car data is either 0.0 or unavailable. Check the inputs.")
181
+ end
182
+ if electric_row['elevator_speed_of_car'].to_f == 0.0
183
+ userdata_valid = false
184
+ OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data: #{object_name}: Elevator #{electric_row['name']}'s speed of car data is either 0.0 or unavailable. Check the inputs.")
185
+ end
186
+ if electric_row['elevator_number_of_stories'].to_i > 1
187
+ userdata_valid = false
188
+ OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data: #{object_name}: Elevator #{electric_row['name']}'s serves number of stories data is either smaller or equal to 1 or unavailable. Check the inputs.")
189
+ end
190
+ end
191
+ # Check refrigeration
192
+ if electric_row['refrigeration_equipment_class'].nil? || electric_row['refrigeration_equipment_volume'].nil? || electric_row['refrigeration_equipment_total_display_area'].nil?
193
+ if electric_row['refrigeration_equipment_class'].nil? && electric_row['refrigeration_equipment_volume'].nil? && electric_row['refrigeration_equipment_total_display_area'].nil?
194
+ userdata_valid = false
195
+ OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data: #{object_name}: One or more refrigeration data is not available for electric equipment #{electric_row['name']}. refrigeration_equipment_class: #{electric_row['refrigeration_equipment_class']}; refrigeration_equipment_volume: #{electric_row['refrigeration_equipment_volume']}; refrigeration_equipment_total_display_area: #{electric_row['refrigeration_equipment_total_display_area']}")
196
+ end
197
+ else
198
+ # Check data type
199
+ # The equipment class shall be verified at the implementation level
200
+ if electric_row['refrigeration_equipment_volume'].to_f == 0.0
201
+ userdata_valid = false
202
+ OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data: #{object_name}: Refrigeration #{electric_row['name']}'s equipment volume data is either 0.0 or unavailable. Check the inputs.")
203
+ end
204
+ if electric_row['refrigeration_equipment_total_display_area'].to_f == 0.0
205
+ userdata_valid = false
206
+ OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data: #{object_name}: Refrigeration #{electric_row['name']}'s total display area data is either 0.0 or unavailable. Check the inputs.")
207
+ end
208
+ end
209
+ end
210
+ return userdata_valid
211
+ end
212
+
213
+ # Check for incorrect data in space and spacetype user data
214
+
215
+ # @param object_name [String] name of user data csv file to check
216
+ # @param user_data [Hash] hash of data from user data csv file
217
+
218
+ # @return [Boolean] true if data is valid, false if error found
219
+ def check_userdata_space_and_spacetype(object_name, user_data)
220
+ userdata_valid = true
221
+ user_data.each do |lpd_row|
222
+ unless lpd_row['num_std_ltg_types'].to_i == 0
223
+ num_ltg_type = lpd_row['num_std_ltg_types'].to_i
224
+ total_ltg_percent = 0.0
225
+ std_ltg_index = 0
226
+ while std_ltg_index < num_ltg_type
227
+ frac_key = format('std_ltg_type_frac%02d', (std_ltg_index + 1))
228
+ total_ltg_percent += lpd_row[frac_key].to_f
229
+ std_ltg_index += 1
230
+ end
231
+ if (total_ltg_percent - 1.0).abs > 0.01
232
+ OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data #{object_name}: The fraction of user defined lighting types in Space/SpaceType: #{lpd_row['name']} does not add up to 1.0. The calculated fraction is #{total_ltg_percent}.")
233
+ userdata_valid = false
234
+ end
235
+ end
236
+ end
237
+ return userdata_valid
238
+ end
239
+ end