openstudio-standards 0.4.0 → 0.5.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (376) hide show
  1. checksums.yaml +4 -4
  2. data/data/inventory/thermal_bridging.csv +90 -0
  3. data/data/standards/OpenStudio_Standards-deer-comstock.xlsx +0 -0
  4. data/data/standards/manage_OpenStudio_Standards.rb +1 -1
  5. data/data/standards/test_performance_expected_dd_results.csv +2014 -1891
  6. data/lib/openstudio-standards/btap/analysis.rb +8 -8
  7. data/lib/openstudio-standards/btap/bridging.rb +664 -645
  8. data/lib/openstudio-standards/btap/btap.model.rb +14 -14
  9. data/lib/openstudio-standards/btap/btap.rb +7 -7
  10. data/lib/openstudio-standards/btap/btap_result.rb +1 -1
  11. data/lib/openstudio-standards/btap/economics.rb +23 -23
  12. data/lib/openstudio-standards/btap/envelope.rb +8 -8
  13. data/lib/openstudio-standards/btap/equest.rb +1 -1
  14. data/lib/openstudio-standards/btap/geometry.rb +2 -2
  15. data/lib/openstudio-standards/btap/mpc.rb +7 -7
  16. data/lib/openstudio-standards/btap/schedules.rb +1 -1
  17. data/lib/openstudio-standards/btap/simmanager.rb +4 -4
  18. data/lib/openstudio-standards/btap/spaceloads.rb +26 -26
  19. data/lib/openstudio-standards/btap/utilities.rb +6 -6
  20. data/lib/openstudio-standards/btap/vintagizer.rb +1 -1
  21. data/lib/openstudio-standards/constructions/information.rb +83 -0
  22. data/lib/openstudio-standards/constructions/materials/modify.rb +72 -0
  23. data/lib/openstudio-standards/constructions/modify.rb +80 -0
  24. data/lib/openstudio-standards/create_typical/create_typical.rb +983 -0
  25. data/lib/openstudio-standards/create_typical/enumerations.rb +484 -0
  26. data/lib/openstudio-standards/create_typical/space_type_blend.rb +791 -0
  27. data/lib/openstudio-standards/create_typical/space_type_ratios.rb +494 -0
  28. data/lib/openstudio-standards/daylighting/space.rb +47 -0
  29. data/lib/openstudio-standards/geometry/create.rb +801 -0
  30. data/lib/openstudio-standards/geometry/create_bar.rb +2171 -0
  31. data/lib/openstudio-standards/geometry/information.rb +462 -0
  32. data/lib/openstudio-standards/geometry/modify.rb +48 -0
  33. data/lib/openstudio-standards/hvac/air_loop/information.rb +79 -0
  34. data/lib/openstudio-standards/hvac/cbecs_hvac.rb +616 -0
  35. data/lib/openstudio-standards/hvac/setpoint_managers/information.rb +91 -0
  36. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.AirTerminalSingleDuctVAVReheat.rb +1 -1
  37. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.AirTerminalSingleDuctVAVReheat.rb +1 -1
  38. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.AirTerminalSingleDuctVAVReheat.rb +1 -1
  39. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.Model.rb +1 -1
  40. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.AirTerminalSingleDuctVAVReheat.rb +1 -1
  41. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.Model.rb +2 -2
  42. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.hvac_systems.rb +1 -1
  43. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirTerminalSingleDuctVAVReheat.rb +1 -1
  44. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Model.rb +4 -36
  45. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.hvac_systems.rb +1 -1
  46. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirTerminalSingleDuctVAVReheat.rb +1 -1
  47. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Model.rb +4 -36
  48. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Space.rb +3 -3
  49. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.hvac_systems.rb +1 -1
  50. data/lib/openstudio-standards/prototypes/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.AirTerminalSingleDuctVAVReheat.rb +1 -1
  51. data/lib/openstudio-standards/prototypes/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.Model.elevators.rb +1 -1
  52. data/lib/openstudio-standards/prototypes/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.AirTerminalSingleDuctVAVReheat.rb +1 -1
  53. data/lib/openstudio-standards/prototypes/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.CoilHeatingGas.rb +1 -1
  54. data/lib/openstudio-standards/prototypes/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.Model.elevators.rb +1 -1
  55. data/lib/openstudio-standards/prototypes/ashrae_90_1/nrel_nze_ready_2017/nrel_zne_ready_2017.AirTerminalSingleDuctVAVReheat.rb +1 -1
  56. data/lib/openstudio-standards/prototypes/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.AirTerminalSingleDuctVAVReheat.rb +1 -1
  57. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.College.rb +7 -7
  58. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Courthouse.rb +8 -8
  59. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.FullServiceRestaurant.rb +14 -14
  60. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.HighRiseApartment.rb +9 -9
  61. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Hospital.rb +16 -16
  62. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Laboratory.rb +7 -7
  63. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeDataCenterHighITE.rb +8 -8
  64. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeDataCenterLowITE.rb +8 -8
  65. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeHotel.rb +11 -11
  66. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeOffice.rb +7 -7
  67. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeOfficeDetailed.rb +9 -9
  68. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.MediumOffice.rb +8 -8
  69. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.MediumOfficeDetailed.rb +11 -11
  70. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.MidriseApartment.rb +9 -9
  71. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Outpatient.rb +19 -19
  72. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.PrimarySchool.rb +10 -10
  73. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.QuickServiceRestaurant.rb +13 -13
  74. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.RetailStandalone.rb +6 -6
  75. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.RetailStripmall.rb +6 -6
  76. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SecondarySchool.rb +9 -9
  77. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallDataCenterHighITE.rb +8 -8
  78. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallDataCenterLowITE.rb +8 -8
  79. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallHotel.rb +8 -8
  80. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallOffice.rb +8 -8
  81. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallOfficeDetailed.rb +11 -11
  82. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SuperMarket.rb +10 -10
  83. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SuperTallBuilding.rb +19 -19
  84. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.TallBuilding.rb +18 -18
  85. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Warehouse.rb +6 -6
  86. data/lib/openstudio-standards/prototypes/common/do_not_edit_metaclasses.rb +957 -957
  87. data/lib/openstudio-standards/prototypes/common/objects/Prototype.AirConditionerVariableRefrigerantFlow.rb +1 -1
  88. data/lib/openstudio-standards/prototypes/common/objects/Prototype.AirTerminalSingleDuctVAVReheat.rb +1 -1
  89. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingWaterToAirHeatPumpEquationFit.rb +84 -16
  90. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingDXSingleSpeed.rb +1 -1
  91. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingGas.rb +1 -1
  92. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingWaterToAirHeatPumpEquationFit.rb +61 -10
  93. data/lib/openstudio-standards/prototypes/common/objects/Prototype.ControllerWaterCoil.rb +1 -1
  94. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoolingTower.rb +1 -1
  95. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Fan.rb +1 -1
  96. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanConstantVolume.rb +1 -1
  97. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanOnOff.rb +1 -1
  98. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanVariableVolume.rb +1 -1
  99. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanZoneExhaust.rb +1 -1
  100. data/lib/openstudio-standards/prototypes/common/objects/Prototype.HeatExchangerAirToAirSensibleAndLatent.rb +2 -2
  101. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.exterior_lights.rb +4 -4
  102. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.hvac.rb +4 -4
  103. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.rb +43 -30
  104. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.swh.rb +1 -1
  105. data/lib/openstudio-standards/prototypes/common/objects/Prototype.ServiceWaterHeating.rb +18 -11
  106. data/lib/openstudio-standards/prototypes/common/objects/Prototype.SizingSystem.rb +1 -1
  107. data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +774 -117
  108. data/lib/openstudio-standards/prototypes/common/objects/Prototype.radiant_system_controls.rb +340 -481
  109. data/lib/openstudio-standards/prototypes/common/objects/Prototype.refrigeration.rb +3 -3
  110. data/lib/openstudio-standards/prototypes/common/objects/Prototype.utilities.rb +3 -3
  111. data/lib/openstudio-standards/prototypes/common/prototype_metaprogramming.rb +22 -22
  112. data/lib/openstudio-standards/prototypes/deer/deer.Model.rb +1 -1
  113. data/lib/openstudio-standards/qaqc/calibration.rb +131 -0
  114. data/lib/openstudio-standards/qaqc/create_results.rb +983 -0
  115. data/lib/openstudio-standards/qaqc/envelope.rb +399 -0
  116. data/lib/openstudio-standards/qaqc/eui.rb +213 -0
  117. data/lib/openstudio-standards/qaqc/hvac.rb +1943 -0
  118. data/lib/openstudio-standards/qaqc/internal_loads.rb +568 -0
  119. data/lib/openstudio-standards/qaqc/reporting.rb +141 -0
  120. data/lib/openstudio-standards/qaqc/schedules.rb +129 -0
  121. data/lib/openstudio-standards/qaqc/service_water_heating.rb +273 -0
  122. data/lib/openstudio-standards/qaqc/weather_files.rb +497 -0
  123. data/lib/openstudio-standards/qaqc/zone_conditions.rb +278 -0
  124. data/lib/openstudio-standards/schedules/create.rb +364 -0
  125. data/lib/openstudio-standards/schedules/information.rb +169 -0
  126. data/lib/openstudio-standards/schedules/modify.rb +445 -0
  127. data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +110 -71
  128. data/lib/openstudio-standards/standards/Standards.AirTerminalSingleDuctParallelPIUReheat.rb +3 -3
  129. data/lib/openstudio-standards/standards/Standards.AirTerminalSingleDuctVAVReheat.rb +4 -4
  130. data/lib/openstudio-standards/standards/Standards.BoilerHotWater.rb +2 -1
  131. data/lib/openstudio-standards/standards/Standards.ChillerElectricEIR.rb +16 -10
  132. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXSingleSpeed.rb +4 -4
  133. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXTwoSpeed.rb +1 -1
  134. data/lib/openstudio-standards/standards/Standards.CoilCoolingWaterToAirHeatPumpEquationFit.rb +1 -1
  135. data/lib/openstudio-standards/standards/Standards.CoilDX.rb +4 -4
  136. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXMultiSpeed.rb +1 -1
  137. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXSingleSpeed.rb +5 -5
  138. data/lib/openstudio-standards/standards/Standards.CoilHeatingGas.rb +1 -1
  139. data/lib/openstudio-standards/standards/Standards.CoilHeatingGasMultiStage.rb +1 -1
  140. data/lib/openstudio-standards/standards/Standards.CoilHeatingWaterToAirHeatPumpEquationFit.rb +1 -1
  141. data/lib/openstudio-standards/standards/Standards.Construction.rb +17 -18
  142. data/lib/openstudio-standards/standards/Standards.CoolingTower.rb +6 -6
  143. data/lib/openstudio-standards/standards/Standards.CoolingTowerSingleSpeed.rb +1 -1
  144. data/lib/openstudio-standards/standards/Standards.CoolingTowerTwoSpeed.rb +1 -1
  145. data/lib/openstudio-standards/standards/Standards.CoolingTowerVariableSpeed.rb +1 -1
  146. data/lib/openstudio-standards/standards/Standards.Fan.rb +6 -12
  147. data/lib/openstudio-standards/standards/Standards.FanVariableVolume.rb +2 -2
  148. data/lib/openstudio-standards/standards/Standards.FluidCooler.rb +1 -1
  149. data/lib/openstudio-standards/standards/Standards.HeaderedPumpsVariableSpeed.rb +1 -1
  150. data/lib/openstudio-standards/standards/Standards.HeatExchangerSensLat.rb +3 -3
  151. data/lib/openstudio-standards/standards/Standards.Model.rb +411 -261
  152. data/lib/openstudio-standards/standards/Standards.PlanarSurface.rb +2 -2
  153. data/lib/openstudio-standards/standards/Standards.PlantLoop.rb +94 -29
  154. data/lib/openstudio-standards/standards/Standards.Pump.rb +2 -2
  155. data/lib/openstudio-standards/standards/Standards.ScheduleConstant.rb +2 -2
  156. data/lib/openstudio-standards/standards/Standards.ScheduleRuleset.rb +14 -14
  157. data/lib/openstudio-standards/standards/Standards.Space.rb +37 -30
  158. data/lib/openstudio-standards/standards/Standards.SpaceType.rb +38 -29
  159. data/lib/openstudio-standards/standards/Standards.SubSurface.rb +7 -7
  160. data/lib/openstudio-standards/standards/Standards.Surface.rb +13 -13
  161. data/lib/openstudio-standards/standards/Standards.ThermalZone.rb +109 -66
  162. data/lib/openstudio-standards/standards/Standards.WaterHeaterMixed.rb +11 -4
  163. data/lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb +6 -6
  164. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.AirLoopHVAC.rb +1 -1
  165. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.PlantLoop.rb +1 -1
  166. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.Space.rb +1 -1
  167. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.Space.rb +1 -1
  168. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.AirLoopHVAC.rb +4 -4
  169. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.AirTerminalSingleDuctVAVReheat.rb +1 -1
  170. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.Space.rb +4 -4
  171. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.AirLoopHVAC.rb +4 -4
  172. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.AirTerminalSingleDuctVAVReheat.rb +1 -1
  173. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.CoolingTowerVariableSpeed.rb +1 -1
  174. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.Model.rb +5 -21
  175. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.Space.rb +4 -4
  176. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.WaterHeaterMixed.rb +1 -1
  177. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.ZoneHVACComponent.rb +1 -1
  178. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirLoopHVAC.rb +36 -4
  179. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirTerminalSingleDuctVAVReheat.rb +1 -1
  180. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.CoolingTowerVariableSpeed.rb +1 -1
  181. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Space.rb +4 -4
  182. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.ZoneHVACComponent.rb +1 -1
  183. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/comstock_ashrae_90_1_2016/comstock_ashrae_90_1_2016.AirLoopHVAC.rb +26 -0
  184. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +53 -10
  185. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirTerminalSingleDuctVAVReheat.rb +1 -1
  186. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.CoolingTowerVariableSpeed.rb +1 -1
  187. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Space.rb +6 -6
  188. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.ZoneHVACComponent.rb +2 -2
  189. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/comstock_ashrae_90_1_2019/comstock_ashrae_90_1_2019.AirLoopHVAC.rb +26 -0
  190. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.curves.json +211 -211
  191. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.economizers.json +14 -14
  192. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.AirLoopHVAC.rb +4 -4
  193. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.Model.rb +1 -1
  194. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.PlantLoop.rb +1 -1
  195. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.economizers.json +14 -14
  196. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.AirLoopHVAC.rb +4 -4
  197. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.Model.rb +1 -1
  198. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.PlantLoop.rb +1 -1
  199. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.AirLoopHVAC.rb +6 -6
  200. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.AirTerminalSingleDuctVAVReheat.rb +1 -1
  201. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.CoolingTowerVariableSpeed.rb +1 -1
  202. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.PlantLoop.rb +1 -1
  203. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.Space.rb +4 -4
  204. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.AirLoopHVAC.rb +6 -6
  205. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.AirTerminalSingleDuctVAVReheat.rb +1 -1
  206. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.CoolingTowerVariableSpeed.rb +1 -1
  207. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.PlantLoop.rb +1 -1
  208. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.Space.rb +4 -4
  209. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirLoopHVAC.rb +22 -28
  210. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirTerminalSingleDuctParallelPIUReheat.rb +1 -1
  211. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirTerminalSingleDuctVAVReheat.rb +2 -2
  212. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.BoilerHotWater.rb +1 -74
  213. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ChillerElectricEIR.rb +7 -59
  214. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilCoolingDXSingleSpeed.rb +1 -1
  215. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilCoolingDXTwoSpeed.rb +1 -1
  216. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilDX.rb +1 -1
  217. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingDXSingleSpeed.rb +1 -1
  218. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingGas.rb +1 -21
  219. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.DesignSpecificationOutdoorAir.rb +101 -0
  220. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanConstantVolume.rb +1 -1
  221. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanOnOff.rb +1 -1
  222. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanVariableVolume.rb +1 -1
  223. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.HeatExchangerSensLat.rb +1 -1
  224. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Model.rb +643 -526
  225. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlanarSurface.rb +8 -2
  226. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlantLoop.rb +17 -77
  227. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Space.rb +74 -16
  228. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.SpaceType.rb +96 -44
  229. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Surface.rb +6 -6
  230. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ThermalZone.rb +18 -6
  231. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ZoneHVACComponent.rb +1 -1
  232. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.rb +328 -74
  233. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019.Model.rb +0 -118
  234. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019.rb +2 -1
  235. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.heat_rejection.json +1 -1
  236. data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/baseline_outdoor_air.md +35 -0
  237. data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/set_plug_load_measures.md +1 -1
  238. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/ashrae_90_1_prm.UserData.rb +228 -0
  239. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_enums.rb +131 -0
  240. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_space.csv +1 -1
  241. data/lib/openstudio-standards/standards/cbes/cbes.AirLoopHVAC.rb +5 -5
  242. data/lib/openstudio-standards/standards/cbes/cbes.Model.rb +1 -1
  243. data/lib/openstudio-standards/standards/cbes/cbes.PlantLoop.rb +1 -1
  244. data/lib/openstudio-standards/standards/cbes/cbes.Space.rb +1 -1
  245. data/lib/openstudio-standards/standards/cbes/cbes_t24_2005/cbes_t24_2005.Space.rb +1 -1
  246. data/lib/openstudio-standards/standards/cbes/cbes_t24_2008/cbes_t24_2008.Space.rb +1 -1
  247. data/lib/openstudio-standards/standards/deer/deer.AirLoopHVAC.rb +109 -27
  248. data/lib/openstudio-standards/standards/deer/deer.Space.rb +1 -1
  249. data/lib/openstudio-standards/standards/deer/deer_1985/data/deer_1985.economizers.json +246 -4
  250. data/lib/openstudio-standards/standards/deer/deer_1996/data/deer_1996.economizers.json +246 -4
  251. data/lib/openstudio-standards/standards/deer/deer_2003/data/deer_2003.economizers.json +246 -4
  252. data/lib/openstudio-standards/standards/deer/deer_2003/deer_2003.ThermalZone.rb +18 -18
  253. data/lib/openstudio-standards/standards/deer/deer_2007/data/deer_2007.economizers.json +246 -4
  254. data/lib/openstudio-standards/standards/deer/deer_2007/deer_2007.ThermalZone.rb +18 -18
  255. data/lib/openstudio-standards/standards/deer/deer_2011/data/deer_2011.economizers.json +246 -4
  256. data/lib/openstudio-standards/standards/deer/deer_2011/deer_2011.ThermalZone.rb +18 -18
  257. data/lib/openstudio-standards/standards/deer/deer_2014/data/deer_2014.economizers.json +248 -6
  258. data/lib/openstudio-standards/standards/deer/deer_2014/deer_2014.Space.rb +3 -3
  259. data/lib/openstudio-standards/standards/deer/deer_2014/deer_2014.ThermalZone.rb +18 -18
  260. data/lib/openstudio-standards/standards/deer/deer_2015/data/deer_2015.economizers.json +248 -6
  261. data/lib/openstudio-standards/standards/deer/deer_2015/deer_2015.Space.rb +3 -3
  262. data/lib/openstudio-standards/standards/deer/deer_2015/deer_2015.ThermalZone.rb +18 -18
  263. data/lib/openstudio-standards/standards/deer/deer_2017/data/deer_2017.economizers.json +248 -6
  264. data/lib/openstudio-standards/standards/deer/deer_2017/deer_2017.Space.rb +3 -3
  265. data/lib/openstudio-standards/standards/deer/deer_2017/deer_2017.ThermalZone.rb +18 -18
  266. data/lib/openstudio-standards/standards/deer/deer_2020/data/deer_2020.economizers.json +248 -6
  267. data/lib/openstudio-standards/standards/deer/deer_2020/deer_2020.AirLoopHVAC.rb +18 -5
  268. data/lib/openstudio-standards/standards/deer/deer_2020/deer_2020.FanVariableVolume.rb +1 -1
  269. data/lib/openstudio-standards/standards/deer/deer_2020/deer_2020.Space.rb +3 -3
  270. data/lib/openstudio-standards/standards/deer/deer_2020/deer_2020.ThermalZone.rb +18 -18
  271. data/lib/openstudio-standards/standards/deer/deer_2025/data/deer_2025.economizers.json +248 -6
  272. data/lib/openstudio-standards/standards/deer/deer_2025/deer_2025.AirLoopHVAC.rb +3 -3
  273. data/lib/openstudio-standards/standards/deer/deer_2025/deer_2025.FanVariableVolume.rb +1 -1
  274. data/lib/openstudio-standards/standards/deer/deer_2025/deer_2025.Space.rb +3 -3
  275. data/lib/openstudio-standards/standards/deer/deer_2030/data/deer_2030.economizers.json +248 -6
  276. data/lib/openstudio-standards/standards/deer/deer_2030/data/deer_2030.heat_pumps.json +2 -2
  277. data/lib/openstudio-standards/standards/deer/deer_2030/deer_2030.AirLoopHVAC.rb +3 -3
  278. data/lib/openstudio-standards/standards/deer/deer_2030/deer_2030.FanVariableVolume.rb +1 -1
  279. data/lib/openstudio-standards/standards/deer/deer_2030/deer_2030.Space.rb +3 -3
  280. data/lib/openstudio-standards/standards/deer/deer_2035/data/deer_2035.economizers.json +248 -6
  281. data/lib/openstudio-standards/standards/deer/deer_2035/deer_2035.AirLoopHVAC.rb +3 -3
  282. data/lib/openstudio-standards/standards/deer/deer_2035/deer_2035.FanVariableVolume.rb +1 -1
  283. data/lib/openstudio-standards/standards/deer/deer_2035/deer_2035.Space.rb +3 -3
  284. data/lib/openstudio-standards/standards/deer/deer_2040/data/deer_2040.economizers.json +248 -6
  285. data/lib/openstudio-standards/standards/deer/deer_2040/deer_2040.AirLoopHVAC.rb +3 -3
  286. data/lib/openstudio-standards/standards/deer/deer_2040/deer_2040.FanVariableVolume.rb +1 -1
  287. data/lib/openstudio-standards/standards/deer/deer_2040/deer_2040.Space.rb +3 -3
  288. data/lib/openstudio-standards/standards/deer/deer_2045/data/deer_2045.economizers.json +260 -0
  289. data/lib/openstudio-standards/standards/deer/deer_2045/deer_2045.AirLoopHVAC.rb +3 -3
  290. data/lib/openstudio-standards/standards/deer/deer_2045/deer_2045.FanVariableVolume.rb +1 -1
  291. data/lib/openstudio-standards/standards/deer/deer_2045/deer_2045.Space.rb +3 -3
  292. data/lib/openstudio-standards/standards/deer/deer_2050/data/deer_2050.economizers.json +248 -6
  293. data/lib/openstudio-standards/standards/deer/deer_2050/deer_2050.AirLoopHVAC.rb +3 -3
  294. data/lib/openstudio-standards/standards/deer/deer_2050/deer_2050.FanVariableVolume.rb +1 -1
  295. data/lib/openstudio-standards/standards/deer/deer_2050/deer_2050.Space.rb +3 -3
  296. data/lib/openstudio-standards/standards/deer/deer_2055/data/deer_2055.economizers.json +248 -6
  297. data/lib/openstudio-standards/standards/deer/deer_2055/deer_2055.AirLoopHVAC.rb +3 -3
  298. data/lib/openstudio-standards/standards/deer/deer_2055/deer_2055.FanVariableVolume.rb +1 -1
  299. data/lib/openstudio-standards/standards/deer/deer_2055/deer_2055.Space.rb +3 -3
  300. data/lib/openstudio-standards/standards/deer/deer_2060/data/deer_2060.economizers.json +248 -6
  301. data/lib/openstudio-standards/standards/deer/deer_2060/deer_2060.AirLoopHVAC.rb +3 -3
  302. data/lib/openstudio-standards/standards/deer/deer_2060/deer_2060.FanVariableVolume.rb +1 -1
  303. data/lib/openstudio-standards/standards/deer/deer_2060/deer_2060.Space.rb +3 -3
  304. data/lib/openstudio-standards/standards/deer/deer_2065/data/deer_2065.economizers.json +248 -6
  305. data/lib/openstudio-standards/standards/deer/deer_2065/deer_2065.AirLoopHVAC.rb +3 -3
  306. data/lib/openstudio-standards/standards/deer/deer_2065/deer_2065.FanVariableVolume.rb +1 -1
  307. data/lib/openstudio-standards/standards/deer/deer_2065/deer_2065.Space.rb +3 -3
  308. data/lib/openstudio-standards/standards/deer/deer_2070/data/deer_2070.economizers.json +248 -6
  309. data/lib/openstudio-standards/standards/deer/deer_2070/deer_2070.AirLoopHVAC.rb +3 -3
  310. data/lib/openstudio-standards/standards/deer/deer_2070/deer_2070.FanVariableVolume.rb +1 -1
  311. data/lib/openstudio-standards/standards/deer/deer_2070/deer_2070.Space.rb +3 -3
  312. data/lib/openstudio-standards/standards/deer/deer_2075/data/deer_2075.economizers.json +248 -6
  313. data/lib/openstudio-standards/standards/deer/deer_2075/deer_2075.AirLoopHVAC.rb +3 -3
  314. data/lib/openstudio-standards/standards/deer/deer_2075/deer_2075.FanVariableVolume.rb +1 -1
  315. data/lib/openstudio-standards/standards/deer/deer_2075/deer_2075.Space.rb +3 -3
  316. data/lib/openstudio-standards/standards/deer/deer_pre_1975/data/deer_pre_1975.economizers.json +246 -4
  317. data/lib/openstudio-standards/standards/necb/BTAP1980TO2010/data/space_types.json +447 -223
  318. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/building_envelope.rb +1 -1
  319. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/data/space_types.json +447 -223
  320. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_systems.rb +5 -2
  321. data/lib/openstudio-standards/standards/necb/ECMS/data/chiller_types.json +25 -0
  322. data/lib/openstudio-standards/standards/necb/ECMS/data/chillers.json +44 -0
  323. data/lib/openstudio-standards/standards/necb/ECMS/data/curves.json +225 -0
  324. data/lib/openstudio-standards/standards/necb/ECMS/ecms.rb +2 -2
  325. data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +193 -73
  326. data/lib/openstudio-standards/standards/necb/ECMS/pv_ground.rb +1 -1
  327. data/lib/openstudio-standards/standards/necb/NECB2011/autozone.rb +10 -4
  328. data/lib/openstudio-standards/standards/necb/NECB2011/beps_compliance_path.rb +7 -7
  329. data/lib/openstudio-standards/standards/necb/NECB2011/building_envelope.rb +4 -5
  330. data/lib/openstudio-standards/standards/necb/NECB2011/data/chiller_types.json +32 -0
  331. data/lib/openstudio-standards/standards/necb/NECB2011/data/chillers.json +1 -1
  332. data/lib/openstudio-standards/standards/necb/NECB2011/data/constants.json +36 -0
  333. data/lib/openstudio-standards/standards/necb/NECB2011/data/fuel_type_sets.json +7 -7
  334. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/NorthernEducation.osm +47587 -0
  335. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/NorthernHealthCare.osm +49764 -0
  336. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/Warehouse.osm +283 -297
  337. data/lib/openstudio-standards/standards/necb/NECB2011/data/space_type_unit_definitions.txt +2 -1
  338. data/lib/openstudio-standards/standards/necb/NECB2011/data/space_types.json +447 -223
  339. data/lib/openstudio-standards/standards/necb/NECB2011/data/standards_data.rb +3 -3
  340. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_1_multi_speed.rb +1 -1
  341. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +49 -27
  342. data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +400 -202
  343. data/lib/openstudio-standards/standards/necb/NECB2011/service_water_heating.rb +4 -4
  344. data/lib/openstudio-standards/standards/necb/NECB2015/data/space_types.json +637 -318
  345. data/lib/openstudio-standards/standards/necb/NECB2015/hvac_systems.rb +18 -1
  346. data/lib/openstudio-standards/standards/necb/NECB2015/necb_2015.rb +3 -3
  347. data/lib/openstudio-standards/standards/necb/NECB2017/data/space_types.json +637 -318
  348. data/lib/openstudio-standards/standards/necb/NECB2017/hvac_systems.rb +1 -1
  349. data/lib/openstudio-standards/standards/necb/NECB2017/necb_2017.rb +3 -3
  350. data/lib/openstudio-standards/standards/necb/NECB2020/building_envelope.rb +1 -1
  351. data/lib/openstudio-standards/standards/necb/NECB2020/data/space_types.json +615 -307
  352. data/lib/openstudio-standards/standards/necb/NECB2020/service_water_heating.rb +4 -4
  353. data/lib/openstudio-standards/standards/necb/common/btap_data.rb +10 -5
  354. data/lib/openstudio-standards/standards/necb/common/btap_datapoint.rb +1 -1
  355. data/lib/openstudio-standards/utilities/assertion.rb +128 -0
  356. data/lib/openstudio-standards/utilities/logging.rb +2 -3
  357. data/lib/openstudio-standards/utilities/object_info.rb +39 -18
  358. data/lib/openstudio-standards/utilities/schedule_translator.rb +8 -6
  359. data/lib/openstudio-standards/utilities/simulation.rb +24 -11
  360. data/lib/openstudio-standards/utilities/sqlfile.rb +10 -5
  361. data/lib/openstudio-standards/version.rb +1 -1
  362. data/lib/openstudio-standards/weather/Weather.Model.rb +8 -9
  363. data/lib/openstudio-standards/weather/Weather.stat_file.rb +3 -3
  364. data/lib/openstudio-standards/weather/information.rb +35 -0
  365. data/lib/openstudio-standards.rb +69 -5
  366. metadata +52 -16
  367. data/data/standards/OpenStudio_Standards-deer-ALL-comstock(space_types).xlsx +0 -0
  368. data/lib/openstudio-standards/hvac_sizing/Siz.AirLoopHVAC.rb +0 -59
  369. data/lib/openstudio-standards/hvac_sizing/Siz.CoilCoolingWater.rb +0 -13
  370. data/lib/openstudio-standards/hvac_sizing/Siz.HVACComponent.rb +0 -36
  371. data/lib/openstudio-standards/hvac_sizing/Siz.HeatingCoolingFuels.rb +0 -898
  372. data/lib/openstudio-standards/hvac_sizing/Siz.Model.rb +0 -126
  373. data/lib/openstudio-standards/hvac_sizing/Siz.ThermalZone.rb +0 -356
  374. data/lib/openstudio-standards/prototypes/ashrae_90_1/nrel_nze_ready_2017/nrel_zne_ready_2017.Model.rb +0 -35
  375. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoolingTower.rb +0 -110
  376. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoolingTowerVariableSpeed.rb +0 -5
@@ -0,0 +1,983 @@
1
+ # Module to apply QAQC checks to a model
2
+ module OpenstudioStandards
3
+ module QAQC
4
+ # @!group Make Results
5
+
6
+ # Reports out the detailed simulation results needed by EDAPT and other QAQC programs
7
+ # Results are output as OpenStudio::Attributes
8
+ #
9
+ # @param skip_weekends [Bool] if true, weekends will not be included in the peak demand window
10
+ # @param skip_holidays [Bool] if true, holidays will not be included in the peak demand window
11
+ # @param start_mo [String] the start month for the peak demand window
12
+ # @param start_day [Integer] the start day for the peak demand window
13
+ # @param start_hr [Integer] the start hour for the peak demand window, using 24-hr clock
14
+ # @param end_mo [String] the end month for the peak demand window
15
+ # @param end_day [Integer] the end day for the peak demand window
16
+ # @param end_hr [Integer] the end hour for the peak demand window, using 24-hr clock
17
+ # @param electricity_consumption_tou_periods [Array<Hash>] optional array of hashes to add
18
+ # time-of-use electricity consumption values to the annual consumption information.
19
+ # Periods may overlap, but should be listed in the order in which they must be checked,
20
+ # where the value will be assigned to the first encountered period it falls into.
21
+ # An example hash looks like this:
22
+ # {
23
+ # 'tou_name' => 'system_peak',
24
+ # 'tou_id' => 1,
25
+ # 'skip_weekends' => true,
26
+ # 'skip_holidays' => true,
27
+ # 'start_mo' => 'July',
28
+ # 'start_day' => 1,
29
+ # 'start_hr' => 14,
30
+ # 'end_mo' => 'August',
31
+ # 'end_day' => 31,
32
+ # 'end_hr' => 18
33
+ # }
34
+ # @return [OpenStudio::AttributeVector] a vector of results needed by EDAPT
35
+ def self.make_qaqc_results_vector(skip_weekends = true,
36
+ skip_holidays = true,
37
+ start_mo = 'June',
38
+ start_day = 1,
39
+ start_hr = 14,
40
+ end_mo = 'September',
41
+ end_day = 30,
42
+ end_hr = 18,
43
+ electricity_consumption_tou_periods = [])
44
+
45
+ # get the current version of OS being used to determine if sql query
46
+ # changes are needed (for when E+ changes).
47
+ os_version = OpenStudio::VersionString.new(OpenStudio.openStudioVersion)
48
+
49
+ # make an attribute vector to hold results
50
+ result_elems = OpenStudio::AttributeVector.new
51
+
52
+ # floor_area
53
+ floor_area_query = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='AnnualBuildingUtilityPerformanceSummary' AND ReportForString='Entire Facility' AND TableName='Building Area' AND RowName='Net Conditioned Building Area' AND ColumnName='Area' AND Units='m2'"
54
+ floor_area = @sql.execAndReturnFirstDouble(floor_area_query)
55
+ if floor_area.is_initialized
56
+ result_elems << OpenStudio::Attribute.new('floor_area', floor_area.get, 'm^2')
57
+ else
58
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.QAQC', 'Building floor area not found')
59
+ return false
60
+ end
61
+
62
+ # inflation approach
63
+ inf_appr_query = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='Life-Cycle Cost Report' AND ReportForString='Entire Facility' AND TableName='Life-Cycle Cost Parameters' AND RowName='Inflation Approach' AND ColumnName='Value'"
64
+ inf_appr = @sql.execAndReturnFirstString(inf_appr_query)
65
+ if inf_appr.is_initialized
66
+ if inf_appr.get == 'ConstantDollar'
67
+ inf_appr = 'Constant Dollar'
68
+ elsif inf_appr.get == 'CurrentDollar'
69
+ inf_appr = 'Current Dollar'
70
+ else
71
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.QAQC', "Inflation approach: #{inf_appr.get} not recognized")
72
+ return OpenStudio::Attribute.new('report', result_elems)
73
+ end
74
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.QAQC', "Inflation approach = #{inf_appr}")
75
+ else
76
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.QAQC', 'Could not determine inflation approach used')
77
+ return OpenStudio::Attribute.new('report', result_elems)
78
+ end
79
+
80
+ # base year
81
+ base_yr_query = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='Life-Cycle Cost Report' AND ReportForString='Entire Facility' AND TableName='Life-Cycle Cost Parameters' AND RowName='Base Date' AND ColumnName='Value'"
82
+ base_yr = @sql.execAndReturnFirstString(base_yr_query)
83
+ if base_yr.is_initialized
84
+ if base_yr.get =~ /\d\d\d\d/
85
+ base_yr = base_yr.get.match(/\d\d\d\d/)[0].to_f
86
+ else
87
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.QAQC', "Could not determine the analysis start year from #{base_yr.get}")
88
+ return OpenStudio::Attribute.new('report', result_elems)
89
+ end
90
+ else
91
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.QAQC', 'Could not determine analysis start year')
92
+ return OpenStudio::Attribute.new('report', result_elems)
93
+ end
94
+
95
+ # analysis length
96
+ length_yrs_query = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='Life-Cycle Cost Report' AND ReportForString='Entire Facility' AND TableName='Life-Cycle Cost Parameters' AND RowName='Length of Study Period in Years' AND ColumnName='Value'"
97
+ length_yrs = @sql.execAndReturnFirstInt(length_yrs_query)
98
+ if length_yrs.is_initialized
99
+ OpenStudio.logFree(OpenStudio::Error, "Analysis length = #{length_yrs.get} yrs")
100
+ length_yrs = length_yrs.get
101
+ else
102
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.QAQC', 'Could not determine analysis length')
103
+ return OpenStudio::Attribute.new('report', result_elems)
104
+ end
105
+
106
+ # cash flows
107
+ cash_flow_elems = OpenStudio::AttributeVector.new
108
+
109
+ # setup a vector for each type of cash flow
110
+ cap_cash_flow_elems = OpenStudio::AttributeVector.new
111
+ om_cash_flow_elems = OpenStudio::AttributeVector.new
112
+ energy_cash_flow_elems = OpenStudio::AttributeVector.new
113
+ water_cash_flow_elems = OpenStudio::AttributeVector.new
114
+ tot_cash_flow_elems = OpenStudio::AttributeVector.new
115
+
116
+ # add the type to the element
117
+ cap_cash_flow_elems << OpenStudio::Attribute.new('type', "#{inf_appr} Capital Costs")
118
+ om_cash_flow_elems << OpenStudio::Attribute.new('type', "#{inf_appr} Operating Costs")
119
+ energy_cash_flow_elems << OpenStudio::Attribute.new('type', "#{inf_appr} Energy Costs")
120
+ water_cash_flow_elems << OpenStudio::Attribute.new('type', "#{inf_appr} Water Costs")
121
+ tot_cash_flow_elems << OpenStudio::Attribute.new('type', "#{inf_appr} Total Costs")
122
+
123
+ # record the cash flow in these hashes
124
+ cap_cash_flow = {}
125
+ om_cash_flow = {}
126
+ energy_cash_flow = {}
127
+ water_cash_flow = {}
128
+ tot_cash_flow = {}
129
+
130
+ # loop through each year and record the cash flow
131
+ for i in 0..(length_yrs - 1) do
132
+ new_yr = base_yr + i
133
+
134
+ yr = nil
135
+ if os_version > OpenStudio::VersionString.new('1.5.3')
136
+ yr = "January #{new_yr.round}"
137
+ else
138
+ yr = "January #{new_yr.round}"
139
+ end
140
+
141
+ ann_cap_cash = 0.0
142
+ ann_om_cash = 0.0
143
+ ann_energy_cash = 0.0
144
+ ann_water_cash = 0.0
145
+ ann_tot_cash = 0.0
146
+
147
+ # capital cash flow
148
+ cap_cash_query = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='Life-Cycle Cost Report' AND ReportForString='Entire Facility' AND TableName='Capital Cash Flow by Category (Without Escalation)' AND RowName='#{yr}' AND ColumnName='Total'"
149
+ cap_cash = @sql.execAndReturnFirstDouble(cap_cash_query)
150
+ if cap_cash.is_initialized
151
+ ann_cap_cash += cap_cash.get
152
+ ann_tot_cash += cap_cash.get
153
+ end
154
+
155
+ # o&m cash flow (excluding utility costs)
156
+ om_types = ['Maintenance', 'Repair', 'Operation', 'Replacement', 'MinorOverhaul', 'MajorOverhaul', 'OtherOperational']
157
+ om_types.each do |om_type|
158
+ om_cash_query = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='Life-Cycle Cost Report' AND ReportForString='Entire Facility' AND TableName='Operating Cash Flow by Category (Without Escalation)' AND RowName='#{yr}' AND ColumnName='#{om_type}'"
159
+ om_cash = @sql.execAndReturnFirstDouble(om_cash_query)
160
+ if om_cash.is_initialized
161
+ ann_om_cash += om_cash.get
162
+ ann_tot_cash += om_cash.get
163
+ end
164
+ end
165
+
166
+ # energy cash flow
167
+ energy_cash_query = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='Life-Cycle Cost Report' AND ReportForString='Entire Facility' AND TableName='Operating Cash Flow by Category (Without Escalation)' AND RowName='#{yr}' AND ColumnName='Energy'"
168
+ energy_cash = @sql.execAndReturnFirstDouble(energy_cash_query)
169
+ if energy_cash.is_initialized
170
+ ann_energy_cash += energy_cash.get
171
+ ann_tot_cash += energy_cash.get
172
+ end
173
+
174
+ # water cash flow
175
+ water_cash_query = "SELECT Value FROM tabulardatawithstrings WHERE ReportName='Life-Cycle Cost Report' AND ReportForString='Entire Facility' AND TableName='Operating Cash Flow by Category (Without Escalation)' AND RowName='#{yr}' AND ColumnName='Water'"
176
+ water_cash = @sql.execAndReturnFirstDouble(water_cash_query)
177
+ if water_cash.is_initialized
178
+ ann_water_cash += water_cash.get
179
+ ann_tot_cash += water_cash.get
180
+ end
181
+
182
+ # log the values for this year
183
+ cap_cash_flow[yr] = ann_cap_cash
184
+ om_cash_flow[yr] = ann_om_cash
185
+ energy_cash_flow[yr] = ann_energy_cash
186
+ water_cash_flow[yr] = ann_water_cash
187
+ tot_cash_flow[yr] = ann_tot_cash
188
+
189
+ cap_cash_flow_elems << OpenStudio::Attribute.new('year', ann_cap_cash, 'dollars')
190
+ om_cash_flow_elems << OpenStudio::Attribute.new('year', ann_om_cash, 'dollars')
191
+ energy_cash_flow_elems << OpenStudio::Attribute.new('year', ann_energy_cash, 'dollars')
192
+ water_cash_flow_elems << OpenStudio::Attribute.new('year', ann_water_cash, 'dollars')
193
+ tot_cash_flow_elems << OpenStudio::Attribute.new('year', ann_tot_cash, 'dollars')
194
+ end
195
+
196
+ # end cash flows
197
+ cash_flow_elems << OpenStudio::Attribute.new('cash_flow', cap_cash_flow_elems)
198
+ cash_flow_elems << OpenStudio::Attribute.new('cash_flow', om_cash_flow_elems)
199
+ cash_flow_elems << OpenStudio::Attribute.new('cash_flow', energy_cash_flow_elems)
200
+ cash_flow_elems << OpenStudio::Attribute.new('cash_flow', water_cash_flow_elems)
201
+ cash_flow_elems << OpenStudio::Attribute.new('cash_flow', tot_cash_flow_elems)
202
+ result_elems << OpenStudio::Attribute.new('cash_flows', cash_flow_elems)
203
+
204
+ # list of all end uses in OpenStudio
205
+ end_use_cat_types = []
206
+ OpenStudio::EndUseCategoryType.getValues.each do |end_use_val|
207
+ end_use_cat_types << OpenStudio::EndUseCategoryType.new(end_use_val)
208
+ end
209
+
210
+ # list of all end use fule types in OpenStudio
211
+ end_use_fuel_types = []
212
+ OpenStudio::EndUseFuelType.getValues.each do |end_use_fuel_type_val|
213
+ end_use_fuel_types << OpenStudio::EndUseFuelType.new(end_use_fuel_type_val)
214
+ end
215
+
216
+ # list of the 12 months of the year in OpenStudio
217
+ months = []
218
+ OpenStudio::MonthOfYear.getValues.each do |month_of_year_val|
219
+ if (month_of_year_val >= 1) && (month_of_year_val <= 12)
220
+ months << OpenStudio::MonthOfYear.new(month_of_year_val)
221
+ end
222
+ end
223
+
224
+ # map each end use category type to the name that will be used in the xml
225
+ end_use_map = {
226
+ OpenStudio::EndUseCategoryType.new('Heating').value => 'heating',
227
+ OpenStudio::EndUseCategoryType.new('Cooling').value => 'cooling',
228
+ OpenStudio::EndUseCategoryType.new('InteriorLights').value => 'lighting_interior',
229
+ OpenStudio::EndUseCategoryType.new('ExteriorLights').value => 'lighting_exterior',
230
+ OpenStudio::EndUseCategoryType.new('InteriorEquipment').value => 'equipment_interior',
231
+ OpenStudio::EndUseCategoryType.new('ExteriorEquipment').value => 'equipment_exterior',
232
+ OpenStudio::EndUseCategoryType.new('Fans').value => 'fans',
233
+ OpenStudio::EndUseCategoryType.new('Pumps').value => 'pumps',
234
+ OpenStudio::EndUseCategoryType.new('HeatRejection').value => 'heat_rejection',
235
+ OpenStudio::EndUseCategoryType.new('Humidifier').value => 'humidification',
236
+ OpenStudio::EndUseCategoryType.new('HeatRecovery').value => 'heat_recovery',
237
+ OpenStudio::EndUseCategoryType.new('WaterSystems').value => 'water_systems',
238
+ OpenStudio::EndUseCategoryType.new('Refrigeration').value => 'refrigeration',
239
+ OpenStudio::EndUseCategoryType.new('Generators').value => 'generators'
240
+ }
241
+
242
+ # map each fuel type in EndUseFuelTypes to a specific FuelTypes
243
+ fuel_type_map = {
244
+ OpenStudio::EndUseFuelType.new('Electricity').value => OpenStudio::FuelType.new('Electricity'),
245
+ OpenStudio::EndUseFuelType.new('Gas').value => OpenStudio::FuelType.new('Gas'),
246
+ OpenStudio::EndUseFuelType.new('AdditionalFuel').value => OpenStudio::FuelType.new('Diesel'), # TODO: add other fuel types
247
+ OpenStudio::EndUseFuelType.new('DistrictCooling').value => OpenStudio::FuelType.new('DistrictCooling'),
248
+ OpenStudio::EndUseFuelType.new('DistrictHeating').value => OpenStudio::FuelType.new('DistrictHeating'),
249
+ OpenStudio::EndUseFuelType.new('Water').value => OpenStudio::FuelType.new('Water')
250
+ }
251
+
252
+ # map each fuel type in EndUseFuelTypes to a specific FuelTypes
253
+ fuel_type_alias_map = {
254
+ OpenStudio::EndUseFuelType.new('Electricity').value => 'electricity',
255
+ OpenStudio::EndUseFuelType.new('Gas').value => 'gas',
256
+ OpenStudio::EndUseFuelType.new('AdditionalFuel').value => 'other_energy',
257
+ OpenStudio::EndUseFuelType.new('DistrictCooling').value => 'district_cooling',
258
+ OpenStudio::EndUseFuelType.new('DistrictHeating').value => 'district_heating',
259
+ OpenStudio::EndUseFuelType.new('Water').value => 'water'
260
+ }
261
+
262
+ # annual "annual"
263
+ annual_elems = OpenStudio::AttributeVector.new
264
+
265
+ # consumption "consumption"
266
+ cons_elems = OpenStudio::AttributeVector.new
267
+
268
+ # electricity
269
+ electricity = @sql.electricityTotalEndUses
270
+ if electricity.is_initialized
271
+ cons_elems << OpenStudio::Attribute.new('electricity', electricity.get, 'GJ')
272
+ else
273
+ cons_elems << OpenStudio::Attribute.new('electricity', 0.0, 'GJ')
274
+ end
275
+
276
+ # gas
277
+ gas = @sql.naturalGasTotalEndUses
278
+ if gas.is_initialized
279
+ cons_elems << OpenStudio::Attribute.new('gas', gas.get, 'GJ')
280
+ else
281
+ cons_elems << OpenStudio::Attribute.new('gas', 0.0, 'GJ')
282
+ end
283
+
284
+ # other_energy
285
+ other_energy = @sql.otherFuelTotalEndUses
286
+ if other_energy.is_initialized
287
+ cons_elems << OpenStudio::Attribute.new('other_energy', other_energy.get, 'GJ')
288
+ else
289
+ cons_elems << OpenStudio::Attribute.new('other_energy', 0.0, 'GJ')
290
+ end
291
+
292
+ # district_cooling
293
+ district_cooling = @sql.districtCoolingTotalEndUses
294
+ if district_cooling.is_initialized
295
+ cons_elems << OpenStudio::Attribute.new('district_cooling', district_cooling.get, 'GJ')
296
+ else
297
+ cons_elems << OpenStudio::Attribute.new('district_cooling', 0.0, 'GJ')
298
+ end
299
+
300
+ # district_heating
301
+ district_heating = @sql.districtHeatingTotalEndUses
302
+ if district_heating.is_initialized
303
+ cons_elems << OpenStudio::Attribute.new('district_heating', district_heating.get, 'GJ')
304
+ else
305
+ cons_elems << OpenStudio::Attribute.new('district_heating', 0.0, 'GJ')
306
+ end
307
+
308
+ # water
309
+ water = @sql.waterTotalEndUses
310
+ if water.is_initialized
311
+ cons_elems << OpenStudio::Attribute.new('water', water.get, 'm^3')
312
+ else
313
+ cons_elems << OpenStudio::Attribute.new('water', 0.0, 'm^3')
314
+ end
315
+
316
+ # end consumption
317
+ annual_elems << OpenStudio::Attribute.new('consumption', cons_elems)
318
+
319
+ # demand "demand"
320
+ demand_elems = OpenStudio::AttributeVector.new
321
+
322
+ # get the weather file run period (as opposed to design day run period)
323
+ ann_env_pd = nil
324
+ @sql.availableEnvPeriods.each do |env_pd|
325
+ env_type = @sql.environmentType(env_pd)
326
+ if env_type.is_initialized
327
+ if env_type.get == OpenStudio::EnvironmentType.new('WeatherRunPeriod')
328
+ ann_env_pd = env_pd
329
+ end
330
+ end
331
+ end
332
+
333
+ # only try to get the annual peak demand if an annual simulation was run
334
+ if ann_env_pd
335
+
336
+ # make some units to use
337
+ joule_unit = OpenStudio.createUnit('J').get
338
+ gigajoule_unit = OpenStudio.createUnit('GJ').get
339
+ hrs_unit = OpenStudio.createUnit('h').get
340
+ kilowatt_unit = OpenStudio.createUnit('kW').get
341
+
342
+ # get the annual hours simulated
343
+ hrs_sim = '(0 - no partial annual simulation)'
344
+ if @sql.hoursSimulated.is_initialized
345
+ hrs_sim = @sql.hoursSimulated.get
346
+ if hrs_sim != 8760
347
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.QAQC', "Simulation was only #{hrs_sim} hrs; EDA requires an annual simulation (8760 hrs)")
348
+ return OpenStudio::Attribute.new('report', result_elems)
349
+ end
350
+ end
351
+
352
+ # Get the electricity timeseries to determine the year used
353
+ elec = @sql.timeSeries(ann_env_pd, 'Zone Timestep', 'Electricity:Facility', '')
354
+ timeseries_yr = nil
355
+ if elec.is_initialized
356
+ timeseries_yr = elec.get.dateTimes[0].date.year
357
+ else
358
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.QAQC', 'Peak Demand timeseries (Electricity:Facility at zone timestep) could not be found, cannot determine the informatino needed to calculate savings or incentives.')
359
+ end
360
+ # Setup the peak demand time window based on input arguments.
361
+ # Note that holidays and weekends are not excluded because
362
+ # of a bug in EnergyPlus dates.
363
+ # This will only impact corner-case buildings that have
364
+ # peak demand on weekends or holidays, which is unusual.
365
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.QAQC', "Peak Demand window is #{start_mo} #{start_day} to #{end_mo} #{end_day} from #{start_hr}:00 to #{end_hr}:00.")
366
+ start_date = OpenStudio::DateTime.new(OpenStudio::Date.new(OpenStudio::MonthOfYear.new(start_mo), start_day, timeseries_yr), OpenStudio::Time.new(0, 0, 0, 0))
367
+ end_date = OpenStudio::DateTime.new(OpenStudio::Date.new(OpenStudio::MonthOfYear.new(end_mo), end_day, timeseries_yr), OpenStudio::Time.new(0, 24, 0, 0))
368
+ start_time = OpenStudio::Time.new(0, start_hr, 0, 0)
369
+ end_time = OpenStudio::Time.new(0, end_hr, 0, 0)
370
+
371
+ # Get the day type timeseries.
372
+ day_types = nil
373
+ day_type_indices = @sql.timeSeries(ann_env_pd, 'Zone Timestep', 'Site Day Type Index', 'Environment')
374
+ if day_type_indices.is_initialized
375
+ # Put values into array
376
+ day_types = []
377
+ day_type_vals = day_type_indices.get.values
378
+ for i in 0..(day_type_vals.size - 1)
379
+ day_types << day_type_vals[i]
380
+ end
381
+ else
382
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.QAQC', 'Day Type timeseries (Site Day Type Index at zone timestep) could not be found, cannot accurately determine the peak demand.')
383
+ end
384
+
385
+ # electricity_peak_demand
386
+ electricity_peak_demand = -1.0
387
+ electricity_peak_demand_time = nil
388
+ # deduce the timestep based on the hours simulated and the number of datapoints in the timeseries
389
+ if elec.is_initialized && day_types
390
+ elec = elec.get
391
+ num_int = elec.values.size
392
+ int_len_hrs = OpenStudio::Quantity.new(hrs_sim / num_int, hrs_unit)
393
+
394
+ # Put timeseries into array
395
+ elec_vals = []
396
+ ann_elec_vals = elec.values
397
+ for i in 0..(ann_elec_vals.size - 1)
398
+ elec_vals << ann_elec_vals[i]
399
+ end
400
+
401
+ # Put values into array
402
+ elec_times = []
403
+ ann_elec_times = elec.dateTimes
404
+ for i in 0..(ann_elec_times.size - 1)
405
+ elec_times << ann_elec_times[i]
406
+ end
407
+
408
+ # Loop through the time/value pairs and find the peak
409
+ # excluding the times outside of the Xcel peak demand window
410
+ elec_times.zip(elec_vals).each_with_index do |vs, ind|
411
+ date_time = vs[0]
412
+ val = vs[1]
413
+ day_type = day_types[ind]
414
+ time = date_time.time
415
+ date = date_time.date
416
+ day_of_week = date.dayOfWeek
417
+ # Convert the peak demand to kW
418
+ val_J_per_hr = val / int_len_hrs.value
419
+ val_kW = OpenStudio.convert(val_J_per_hr, 'J/h', 'kW').get
420
+
421
+ # puts("#{val_kW}kW; #{date}; #{time}; #{day_of_week.valueName}")
422
+
423
+ # Skip times outside of the correct months
424
+ next if date_time < start_date || date_time > end_date
425
+ # Skip times before 2pm and after 6pm
426
+ next if time < start_time || time > end_time
427
+
428
+ # Skip weekends if asked
429
+ if skip_weekends
430
+ # Sunday = 1, Saturday = 7
431
+ next if day_type == 1 || day_type == 7
432
+ end
433
+ # Skip holidays if asked
434
+ if skip_holidays
435
+ # Holiday = 8
436
+ next if day_type == 8
437
+ end
438
+
439
+ # puts("VALID #{val_kW}kW; #{date}; #{time}; #{day_of_week.valueName}")
440
+
441
+ # Check peak demand against this timestep
442
+ # and update if this timestep is higher.
443
+ if val > electricity_peak_demand
444
+ electricity_peak_demand = val
445
+ electricity_peak_demand_time = date_time
446
+ end
447
+ end
448
+ elec_peak_demand_timestep_J = OpenStudio::Quantity.new(electricity_peak_demand, joule_unit)
449
+ num_int = elec.values.size
450
+ int_len_hrs = OpenStudio::Quantity.new(hrs_sim / num_int, hrs_unit)
451
+ elec_peak_demand_hourly_J_per_hr = elec_peak_demand_timestep_J / int_len_hrs
452
+ electricity_peak_demand = OpenStudio.convert(elec_peak_demand_hourly_J_per_hr, kilowatt_unit).get.value
453
+ demand_elems << OpenStudio::Attribute.new('electricity_peak_demand', electricity_peak_demand, 'kW')
454
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.QAQC', "Peak Demand = #{electricity_peak_demand.round(2)}kW on #{electricity_peak_demand_time}")
455
+ else
456
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.QAQC', 'Peak Demand timeseries (Electricity:Facility at zone timestep) could not be found, cannot determine the informatino needed to calculate savings or incentives.')
457
+ demand_elems << OpenStudio::Attribute.new('electricity_peak_demand', 0.0, 'kW')
458
+ end
459
+
460
+ # Describe the TOU periods
461
+ electricity_consumption_tou_periods.each do |tou_pd|
462
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.QAQC', "TOU period #{tou_pd['tou_id']} represents #{tou_pd['tou_name']} and covers #{tou_pd['start_mo']}-#{tou_pd['start_day']} to #{tou_pd['end_mo']}-#{tou_pd['end_day']} from #{tou_pd['start_hr']} to #{tou_pd['end_hr']}, skip weekends = #{tou_pd['skip_weekends']}, skip holidays = #{tou_pd['skip_holidays']}")
463
+ end
464
+
465
+ # electricity time-of-use periods
466
+ elec = @sql.timeSeries(ann_env_pd, 'Zone Timestep', 'Electricity:Facility', '')
467
+ if elec.is_initialized && day_types
468
+ elec = elec.get
469
+ # Put timeseries into array
470
+ elec_vals = []
471
+ ann_elec_vals = elec.values
472
+ for i in 0..(ann_elec_vals.size - 1)
473
+ elec_vals << ann_elec_vals[i]
474
+ end
475
+
476
+ # Put values into array
477
+ elec_times = []
478
+ ann_elec_times = elec.dateTimes
479
+ for i in 0..(ann_elec_times.size - 1)
480
+ elec_times << ann_elec_times[i]
481
+ end
482
+
483
+ # Loop through the time/value pairs and find the peak
484
+ # excluding the times outside of the Xcel peak demand window
485
+ electricity_tou_vals = Hash.new(0)
486
+ elec_times.zip(elec_vals).each_with_index do |vs, ind|
487
+ date_time = vs[0]
488
+ joules = vs[1]
489
+ day_type = day_types[ind]
490
+ time = date_time.time
491
+ date = date_time.date
492
+
493
+ # puts("#{val_kW}kW; #{date}; #{time}; #{day_of_week.valueName}")
494
+
495
+ # Determine which TOU period this hour falls into
496
+ tou_period_assigned = false
497
+ electricity_consumption_tou_periods.each do |tou_pd|
498
+ pd_start_date = OpenStudio::DateTime.new(OpenStudio::Date.new(OpenStudio::MonthOfYear.new(tou_pd['start_mo']), tou_pd['start_day'], timeseries_yr), OpenStudio::Time.new(0, 0, 0, 0))
499
+ pd_end_date = OpenStudio::DateTime.new(OpenStudio::Date.new(OpenStudio::MonthOfYear.new(tou_pd['end_mo']), tou_pd['end_day'], timeseries_yr), OpenStudio::Time.new(0, 24, 0, 0))
500
+ pd_start_time = OpenStudio::Time.new(0, tou_pd['start_hr'], 0, 0)
501
+ pd_end_time = OpenStudio::Time.new(0, tou_pd['end_hr'], 0, 0)
502
+ # Skip times outside of the correct months
503
+ next if date_time < pd_start_date || date_time > pd_end_date
504
+ # Skip times before some time and after another time
505
+ next if time < pd_start_time || time > pd_end_time
506
+
507
+ # Skip weekends if asked
508
+ if tou_pd['skip_weekends']
509
+ # Sunday = 1, Saturday = 7
510
+ next if day_type == 1 || day_type == 7
511
+ end
512
+ # Skip holidays if asked
513
+ if tou_pd['skip_holidays']
514
+ # Holiday = 8
515
+ next if day_type == 8
516
+ end
517
+ # If here, this hour falls into the specified period
518
+ tou_period_assigned = true
519
+ electricity_tou_vals[tou_pd['tou_id']] += joules
520
+ break
521
+ end
522
+ # Ensure that the value fell into a period
523
+ unless tou_period_assigned
524
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.QAQC', "Did not find a TOU period covering #{time} on #{date}, kWh will not be included in any TOU period.")
525
+ end
526
+ end
527
+ # Register values for any time-of-use period with kWh
528
+ electricity_tou_vals.each do |tou_pd_id, joules_in_pd|
529
+ gj_in_pd = OpenStudio.convert(joules_in_pd, 'J', 'GJ').get
530
+ kwh_in_pd = OpenStudio.convert(joules_in_pd, 'J', 'kWh').get
531
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.QAQC', "TOU period #{tou_pd_id} annual electricity consumption = #{kwh_in_pd} kWh.")
532
+ end
533
+ else
534
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.QAQC', 'Electricity timeseries (Electricity:Facility at zone timestep) could not be found, cannot determine the information needed to calculate savings or incentives.')
535
+ end
536
+
537
+ # electricity_annual_avg_peak_demand
538
+ val = @sql.electricityTotalEndUses
539
+ if val.is_initialized
540
+ ann_elec_gj = OpenStudio::Quantity.new(val.get, gigajoule_unit)
541
+ ann_hrs = OpenStudio::Quantity.new(hrs_sim, hrs_unit)
542
+ elec_ann_avg_peak_demand_hourly_GJ_per_hr = ann_elec_gj / ann_hrs
543
+ electricity_annual_avg_peak_demand = OpenStudio.convert(elec_ann_avg_peak_demand_hourly_GJ_per_hr, kilowatt_unit).get.value
544
+ demand_elems << OpenStudio::Attribute.new('electricity_annual_avg_peak_demand', electricity_annual_avg_peak_demand, 'kW')
545
+ else
546
+ demand_elems << OpenStudio::Attribute.new('electricity_annual_avg_peak_demand', 0.0, 'kW')
547
+ end
548
+
549
+ # district_cooling_peak_demand
550
+ district_cooling_peak_demand = -1.0
551
+ ann_dist_clg_peak_demand_time = nil
552
+ dist_clg = @sql.timeSeries(ann_env_pd, 'Zone Timestep', 'DistrictCooling:Facility', '')
553
+ # deduce the timestep based on the hours simulated and the number of datapoints in the timeseries
554
+ if dist_clg.is_initialized && day_types
555
+ dist_clg = dist_clg.get
556
+ num_int = dist_clg.values.size
557
+ int_len_hrs = OpenStudio::Quantity.new(hrs_sim / num_int, hrs_unit)
558
+
559
+ # Put timeseries into array
560
+ dist_clg_vals = []
561
+ ann_dist_clg_vals = dist_clg.values
562
+ for i in 0..(ann_dist_clg_vals.size - 1)
563
+ dist_clg_vals << ann_dist_clg_vals[i]
564
+ end
565
+
566
+ # Put values into array
567
+ dist_clg_times = []
568
+ ann_dist_clg_times = dist_clg.dateTimes
569
+ for i in 0..(ann_dist_clg_times.size - 1)
570
+ dist_clg_times << ann_dist_clg_times[i]
571
+ end
572
+
573
+ # Loop through the time/value pairs and find the peak
574
+ # excluding the times outside of the Xcel peak demand window
575
+ dist_clg_times.zip(dist_clg_vals).each_with_index do |vs, ind|
576
+ date_time = vs[0]
577
+ val = vs[1]
578
+ day_type = day_types[ind]
579
+ time = date_time.time
580
+ date = date_time.date
581
+ day_of_week = date.dayOfWeek
582
+ # Convert the peak demand to kW
583
+ val_J_per_hr = val / int_len_hrs.value
584
+ val_kW = OpenStudio.convert(val_J_per_hr, 'J/h', 'kW').get
585
+
586
+ # puts("#{val_kW}kW; #{date}; #{time}; #{day_of_week.valueName}")
587
+
588
+ # Skip times outside of the correct months
589
+ next if date_time < start_date || date_time > end_date
590
+ # Skip times before 2pm and after 6pm
591
+ next if time < start_time || time > end_time
592
+
593
+ # Skip weekends if asked
594
+ if skip_weekends
595
+ # Sunday = 1, Saturday = 7
596
+ next if day_type == 1 || day_type == 7
597
+ end
598
+ # Skip holidays if asked
599
+ if skip_holidays
600
+ # Holiday = 8
601
+ next if day_type == 8
602
+ end
603
+
604
+ # puts("VALID #{val_kW}kW; #{date}; #{time}; #{day_of_week.valueName}")
605
+
606
+ # Check peak demand against this timestep
607
+ # and update if this timestep is higher.
608
+ if val > district_cooling_peak_demand
609
+ district_cooling_peak_demand = val
610
+ ann_dist_clg_peak_demand_time = date_time
611
+ end
612
+ end
613
+ dist_clg_peak_demand_timestep_J = OpenStudio::Quantity.new(district_cooling_peak_demand, joule_unit)
614
+ num_int = dist_clg.values.size
615
+ int_len_hrs = OpenStudio::Quantity.new(hrs_sim / num_int, hrs_unit)
616
+ dist_clg_peak_demand_hourly_J_per_hr = dist_clg_peak_demand_timestep_J / int_len_hrs
617
+ district_cooling_peak_demand = OpenStudio.convert(dist_clg_peak_demand_hourly_J_per_hr, kilowatt_unit).get.value
618
+ demand_elems << OpenStudio::Attribute.new('district_cooling_peak_demand', district_cooling_peak_demand, 'kW')
619
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.QAQC', "District Cooling Peak Demand = #{district_cooling_peak_demand.round(2)}kW on #{ann_dist_clg_peak_demand_time}")
620
+ else
621
+ demand_elems << OpenStudio::Attribute.new('district_cooling_peak_demand', 0.0, 'kW')
622
+ end
623
+
624
+ # district cooling time-of-use periods
625
+ dist_clg = @sql.timeSeries(ann_env_pd, 'Zone Timestep', 'DistrictCooling:Facility', '')
626
+ if dist_clg.is_initialized && day_types
627
+ dist_clg = dist_clg.get
628
+ # Put timeseries into array
629
+ dist_clg_vals = []
630
+ ann_dist_clg_vals = dist_clg.values
631
+ for i in 0..(ann_dist_clg_vals.size - 1)
632
+ dist_clg_vals << ann_dist_clg_vals[i]
633
+ end
634
+
635
+ # Put values into array
636
+ dist_clg_times = []
637
+ ann_dist_clg_times = dist_clg.dateTimes
638
+ for i in 0..(ann_dist_clg_times.size - 1)
639
+ dist_clg_times << ann_dist_clg_times[i]
640
+ end
641
+
642
+ # Loop through the time/value pairs and find the peak
643
+ # excluding the times outside of the Xcel peak demand window
644
+ dist_clg_tou_vals = Hash.new(0)
645
+ dist_clg_times.zip(dist_clg_vals).each_with_index do |vs, ind|
646
+ date_time = vs[0]
647
+ joules = vs[1]
648
+ day_type = day_types[ind]
649
+ time = date_time.time
650
+ date = date_time.date
651
+
652
+ # puts("#{val_kW}kW; #{date}; #{time}; #{day_of_week.valueName}")
653
+
654
+ # Determine which TOU period this hour falls into
655
+ tou_period_assigned = false
656
+ electricity_consumption_tou_periods.each do |tou_pd|
657
+ pd_start_date = OpenStudio::DateTime.new(OpenStudio::Date.new(OpenStudio::MonthOfYear.new(tou_pd['start_mo']), tou_pd['start_day'], timeseries_yr), OpenStudio::Time.new(0, 0, 0, 0))
658
+ pd_end_date = OpenStudio::DateTime.new(OpenStudio::Date.new(OpenStudio::MonthOfYear.new(tou_pd['end_mo']), tou_pd['end_day'], timeseries_yr), OpenStudio::Time.new(0, 24, 0, 0))
659
+ pd_start_time = OpenStudio::Time.new(0, tou_pd['start_hr'], 0, 0)
660
+ pd_end_time = OpenStudio::Time.new(0, tou_pd['end_hr'], 0, 0)
661
+ # Skip times outside of the correct months
662
+ next if date_time < pd_start_date || date_time > pd_end_date
663
+ # Skip times before some time and after another time
664
+ next if time < pd_start_time || time > pd_end_time
665
+
666
+ # Skip weekends if asked
667
+ if tou_pd['skip_weekends']
668
+ # Sunday = 1, Saturday = 7
669
+ next if day_type == 1 || day_type == 7
670
+ end
671
+ # Skip holidays if asked
672
+ if tou_pd['skip_holidays']
673
+ # Holiday = 8
674
+ next if day_type == 8
675
+ end
676
+ # If here, this hour falls into the specified period
677
+ tou_period_assigned = true
678
+ dist_clg_tou_vals[tou_pd['tou_id']] += joules
679
+ break
680
+ end
681
+ # Ensure that the value fell into a period
682
+ unless tou_period_assigned
683
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.QAQC', "Did not find a TOU period covering #{time} on #{date}, kWh will not be included in any TOU period.")
684
+ end
685
+ end
686
+ # Register values for any time-of-use period with kWh
687
+ dist_clg_tou_vals.each do |tou_pd_id, joules_in_pd|
688
+ gj_in_pd = OpenStudio.convert(joules_in_pd, 'J', 'GJ').get
689
+ kwh_in_pd = OpenStudio.convert(joules_in_pd, 'J', 'kWh').get
690
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.QAQC', "TOU period #{tou_pd_id} annual district cooling consumption = #{kwh_in_pd} kWh.")
691
+ end
692
+ else
693
+ # If TOU periods were specified but this model has no district cooling, report zeroes
694
+ if !electricity_consumption_tou_periods.empty?
695
+ # Get the TOU ids
696
+ tou_ids = []
697
+ electricity_consumption_tou_periods.each do |tou_pd|
698
+ tou_ids << tou_pd['tou_id']
699
+ end
700
+ end
701
+ end
702
+
703
+ else
704
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.QAQC', 'Could not find an annual run period')
705
+ return OpenStudio::Attribute.new('report', result_elems)
706
+ end
707
+
708
+ # end demand
709
+ annual_elems << OpenStudio::Attribute.new('demand', demand_elems)
710
+
711
+ # utility_cost
712
+ utility_cost_elems = OpenStudio::AttributeVector.new
713
+ annual_utility_cost_map = {}
714
+
715
+ # electricity
716
+ electricity = @sql.annualTotalCost(OpenStudio::FuelType.new('Electricity'))
717
+ if electricity.is_initialized
718
+ utility_cost_elems << OpenStudio::Attribute.new('electricity', electricity.get, 'dollars')
719
+ annual_utility_cost_map[OpenStudio::EndUseFuelType.new('Electricity').valueName] = electricity.get
720
+ else
721
+ utility_cost_elems << OpenStudio::Attribute.new('electricity', 0.0, 'dollars')
722
+ annual_utility_cost_map[OpenStudio::EndUseFuelType.new('Electricity').valueName] = 0.0
723
+ end
724
+
725
+ # electricity_consumption_charge and electricity_demand_charge
726
+ electric_consumption_charge = 0.0
727
+ electric_demand_charge = 0.0
728
+
729
+ electric_rate_query = "SELECT value FROM tabulardatawithstrings WHERE ReportName='LEEDsummary' AND ReportForString='Entire Facility' AND TableName='EAp2-3. Energy Type Summary' AND RowName='Electricity' AND ColumnName='Utility Rate'"
730
+ electric_rate_name = @sql.execAndReturnFirstString(electric_rate_query)
731
+ if electric_rate_name.is_initialized
732
+ electric_rate_name = electric_rate_name.get.strip
733
+
734
+ # electricity_consumption_charge
735
+ electric_consumption_charge_query = "SELECT value FROM tabulardatawithstrings WHERE ReportName='Tariff Report' AND ReportForString='#{electric_rate_name}' AND TableName='Categories' AND RowName='EnergyCharges (~~$~~)' AND ColumnName='Sum'"
736
+ val = @sql.execAndReturnFirstDouble(electric_consumption_charge_query)
737
+ if val.is_initialized
738
+ electric_consumption_charge = val.get
739
+ end
740
+
741
+ # electricity_demand_charge
742
+ electric_demand_charge_query = "SELECT value FROM tabulardatawithstrings WHERE ReportName='Tariff Report' AND ReportForString='#{electric_rate_name}' AND TableName='Categories' AND RowName='DemandCharges (~~$~~)' AND ColumnName='Sum'"
743
+ val = @sql.execAndReturnFirstDouble(electric_demand_charge_query)
744
+ if val.is_initialized
745
+ electric_demand_charge = val.get
746
+ end
747
+
748
+ end
749
+ utility_cost_elems << OpenStudio::Attribute.new('electricity_consumption_charge', electric_consumption_charge, 'dollars')
750
+ utility_cost_elems << OpenStudio::Attribute.new('electricity_demand_charge', electric_demand_charge, 'dollars')
751
+
752
+ # gas
753
+ gas = @sql.annualTotalCost(OpenStudio::FuelType.new('Gas'))
754
+ if gas.is_initialized
755
+ annual_utility_cost_map[OpenStudio::EndUseFuelType.new('Gas').valueName] = gas.get
756
+ else
757
+ annual_utility_cost_map[OpenStudio::EndUseFuelType.new('Gas').valueName] = 0.0
758
+ end
759
+
760
+ # district_cooling
761
+ district_cooling_charge = 0.0
762
+
763
+ district_cooling_rate_query = "SELECT value FROM tabulardatawithstrings WHERE ReportName='LEEDsummary' AND ReportForString='Entire Facility' AND TableName='EAp2-3. Energy Type Summary' AND RowName='District Cooling' AND ColumnName='Utility Rate'"
764
+ district_cooling_rate_name = @sql.execAndReturnFirstString(district_cooling_rate_query)
765
+ if district_cooling_rate_name.is_initialized
766
+ district_cooling_rate_name = district_cooling_rate_name.get.strip
767
+
768
+ # district_cooling_charge
769
+ district_cooling_charge_query = "SELECT value FROM tabulardatawithstrings WHERE ReportName='Tariff Report' AND ReportForString='#{district_cooling_rate_name}' AND TableName='Categories' AND RowName='Basis (~~$~~)' AND ColumnName='Sum'"
770
+ val = @sql.execAndReturnFirstDouble(district_cooling_charge_query)
771
+ if val.is_initialized
772
+ district_cooling_charge = val.get
773
+ end
774
+
775
+ end
776
+ annual_utility_cost_map[OpenStudio::EndUseFuelType.new('DistrictCooling').valueName] = district_cooling_charge
777
+
778
+ # district_heating
779
+ district_heating_charge = 0.0
780
+
781
+ district_heating_rate_query = "SELECT value FROM tabulardatawithstrings WHERE ReportName='LEEDsummary' AND ReportForString='Entire Facility' AND TableName='EAp2-3. Energy Type Summary' AND RowName='District Heating' AND ColumnName='Utility Rate'"
782
+ district_heating_rate_name = @sql.execAndReturnFirstString(district_heating_rate_query)
783
+ if district_heating_rate_name.is_initialized
784
+ district_heating_rate_name = district_heating_rate_name.get.strip
785
+
786
+ # district_heating_charge
787
+ district_heating_charge_query = "SELECT value FROM tabulardatawithstrings WHERE ReportName='Tariff Report' AND ReportForString='#{district_heating_rate_name}' AND TableName='Categories' AND RowName='Basis (~~$~~)' AND ColumnName='Sum'"
788
+ val = @sql.execAndReturnFirstDouble(district_heating_charge_query)
789
+ if val.is_initialized
790
+ district_heating_charge = val.get
791
+ end
792
+
793
+ end
794
+ annual_utility_cost_map[OpenStudio::EndUseFuelType.new('DistrictHeating').valueName] = district_heating_charge
795
+
796
+ # water
797
+ water = @sql.annualTotalCost(OpenStudio::FuelType.new('Water'))
798
+ if water.is_initialized
799
+ annual_utility_cost_map[OpenStudio::EndUseFuelType.new('Water').valueName] = water.get
800
+ else
801
+ annual_utility_cost_map[OpenStudio::EndUseFuelType.new('Water').valueName] = 0.0
802
+ end
803
+
804
+ # total
805
+ total_query = "SELECT Value from tabulardatawithstrings where (reportname = 'Economics Results Summary Report') and (ReportForString = 'Entire Facility') and (TableName = 'Annual Cost') and (ColumnName ='Total') and (((RowName = 'Cost') and (Units = '~~$~~')) or (RowName = 'Cost (~~$~~)'))"
806
+ total = @sql.execAndReturnFirstDouble(total_query)
807
+
808
+ # other_energy
809
+ # Subtract off the already accounted for fuel types from the total
810
+ # to account for fuels on custom meters where the fuel type is not known.
811
+ prev_tot = 0.0
812
+ annual_utility_cost_map.each do |fuel, val|
813
+ prev_tot += val
814
+ end
815
+ if total.is_initialized
816
+ other_val = total.get - prev_tot
817
+ annual_utility_cost_map[OpenStudio::EndUseFuelType.new('AdditionalFuel').valueName] = other_val
818
+ else
819
+ annual_utility_cost_map[OpenStudio::EndUseFuelType.new('AdditionalFuel').valueName] = 0.0
820
+ end
821
+
822
+ # export remaining costs in the correct order
823
+ # gas
824
+ utility_cost_elems << OpenStudio::Attribute.new('gas', annual_utility_cost_map[OpenStudio::EndUseFuelType.new('Gas').valueName], 'dollars')
825
+ # other_energy
826
+ utility_cost_elems << OpenStudio::Attribute.new('other_energy', annual_utility_cost_map[OpenStudio::EndUseFuelType.new('AdditionalFuel').valueName], 'dollars')
827
+ # district_cooling
828
+ utility_cost_elems << OpenStudio::Attribute.new('district_cooling', annual_utility_cost_map[OpenStudio::EndUseFuelType.new('DistrictCooling').valueName], 'dollars')
829
+ # district_heating
830
+ utility_cost_elems << OpenStudio::Attribute.new('district_heating', annual_utility_cost_map[OpenStudio::EndUseFuelType.new('DistrictHeating').valueName], 'dollars')
831
+ # water
832
+ utility_cost_elems << OpenStudio::Attribute.new('water', annual_utility_cost_map[OpenStudio::EndUseFuelType.new('Water').valueName], 'dollars')
833
+ # total
834
+ if total.is_initialized
835
+ utility_cost_elems << OpenStudio::Attribute.new('total', total.get, 'dollars')
836
+ else
837
+ utility_cost_elems << OpenStudio::Attribute.new('total', 0.0, 'dollars')
838
+ end
839
+
840
+ # end_uses - utility costs by end use using average blended cost
841
+ end_uses_elems = OpenStudio::AttributeVector.new
842
+ # map to store the costs by end use
843
+ cost_by_end_use = {}
844
+
845
+ # fill the map with 0.0's to start
846
+ end_use_cat_types.each do |end_use_cat_type|
847
+ cost_by_end_use[end_use_cat_type] = 0.0
848
+ end
849
+
850
+ # only attempt to get monthly data if enduses table is available
851
+ if @sql.endUses.is_initialized
852
+ end_uses_table = @sql.endUses.get
853
+ # loop through all the fuel types
854
+ end_use_fuel_types.each do |end_use_fuel_type|
855
+ # get the annual total cost for this fuel type
856
+ ann_cost = annual_utility_cost_map[end_use_fuel_type.valueName]
857
+ # get the total annual usage for this fuel type in all end use categories
858
+ # loop through all end uses, adding the annual usage value to the aggregator
859
+ ann_usg = 0.0
860
+ end_use_cat_types.each do |end_use_cat_type|
861
+ ann_usg += end_uses_table.getEndUse(end_use_fuel_type, end_use_cat_type)
862
+ end
863
+ # figure out the annual blended rate for this fuel type
864
+ avg_ann_rate = 0.0
865
+ if ann_cost > 0 && ann_usg > 0
866
+ avg_ann_rate = ann_cost / ann_usg
867
+ end
868
+ # for each end use category, figure out the cost if using
869
+ # the avg ann rate; add this cost to the map
870
+ end_use_cat_types.each do |end_use_cat_type|
871
+ cost_by_end_use[end_use_cat_type] += end_uses_table.getEndUse(end_use_fuel_type, end_use_cat_type) * avg_ann_rate
872
+ end
873
+ end
874
+ # loop through the end uses and record the annual total cost based on the avg annual rate
875
+ end_use_cat_types.each do |end_use_cat_type|
876
+ # record the value
877
+ end_uses_elems << OpenStudio::Attribute.new(end_use_map[end_use_cat_type.value], cost_by_end_use[end_use_cat_type], 'dollars')
878
+ end
879
+ else
880
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.QAQC', 'End-Use table not available in results; could not retrieve monthly costs by end use')
881
+ return OpenStudio::Attribute.new('report', result_elems)
882
+ end
883
+
884
+ # end end_uses
885
+ utility_cost_elems << OpenStudio::Attribute.new('end_uses', end_uses_elems)
886
+
887
+ # end utility_costs
888
+ annual_elems << OpenStudio::Attribute.new('utility_cost', utility_cost_elems)
889
+
890
+ # end annual
891
+ result_elems << OpenStudio::Attribute.new('annual', annual_elems)
892
+
893
+ # monthly
894
+ monthly_elems = OpenStudio::AttributeVector.new
895
+
896
+ # consumption
897
+ cons_elems = OpenStudio::AttributeVector.new
898
+ # loop through all end uses
899
+ end_use_cat_types.each do |end_use_cat|
900
+ end_use_elems = OpenStudio::AttributeVector.new
901
+ end_use_name = end_use_map[end_use_cat.value]
902
+ # in each end use, loop through all fuel types
903
+ end_use_fuel_types.each do |end_use_fuel_type|
904
+ fuel_type_elems = OpenStudio::AttributeVector.new
905
+ fuel_type_name = fuel_type_alias_map[end_use_fuel_type.value]
906
+ ann_energy_cons = 0.0
907
+ # in each end use, loop through months and get monthly enedy consumption
908
+ months.each_with_index do |month, i|
909
+ mon_energy_cons = 0.0
910
+ val = @sql.energyConsumptionByMonth(end_use_fuel_type, end_use_cat, month)
911
+ if val.is_initialized
912
+ monthly_consumption_J = OpenStudio::Quantity.new(val.get, joule_unit)
913
+ monthly_consumption_GJ = OpenStudio.convert(monthly_consumption_J, gigajoule_unit).get.value
914
+ mon_energy_cons = monthly_consumption_GJ
915
+ ann_energy_cons += monthly_consumption_GJ
916
+ end
917
+ # record the monthly value
918
+ if end_use_fuel_type == OpenStudio::EndUseFuelType.new('Water')
919
+ fuel_type_elems << OpenStudio::Attribute.new('month', mon_energy_cons, 'm^3')
920
+ else
921
+ fuel_type_elems << OpenStudio::Attribute.new('month', mon_energy_cons, 'GJ')
922
+ end
923
+ end
924
+ # record the annual total
925
+ fuel_type_elems << OpenStudio::Attribute.new('year', ann_energy_cons, 'GJ')
926
+ # add this fuel type
927
+ end_use_elems << OpenStudio::Attribute.new(fuel_type_alias_map[end_use_fuel_type.value], fuel_type_elems)
928
+ end
929
+ # add this end use
930
+ cons_elems << OpenStudio::Attribute.new(end_use_map[end_use_cat.value], end_use_elems)
931
+ end
932
+ # end consumption
933
+ monthly_elems << OpenStudio::Attribute.new('consumption', cons_elems)
934
+
935
+ # create a unit to use
936
+ watt_unit = OpenStudio.createUnit('W').get
937
+ kilowatt_unit = OpenStudio.createUnit('kW').get
938
+
939
+ # demand
940
+ demand_elems = OpenStudio::AttributeVector.new
941
+ # loop through all end uses
942
+ end_use_cat_types.each do |end_use_cat|
943
+ end_use_elems = OpenStudio::AttributeVector.new
944
+ end_use_name = end_use_map[end_use_cat.value]
945
+ # in each end use, loop through all fuel types
946
+ end_use_fuel_types.each do |end_use_fuel_type|
947
+ fuel_type_elems = OpenStudio::AttributeVector.new
948
+ fuel_type_name = fuel_type_alias_map[end_use_fuel_type.value]
949
+ ann_peak_demand = 0.0
950
+ # in each end use, loop through months and get monthly enedy consumption
951
+ months.each_with_index do |month, i|
952
+ mon_peak_demand = 0.0
953
+ val = @sql.peakEnergyDemandByMonth(end_use_fuel_type, end_use_cat, month)
954
+ if val.is_initialized
955
+ mon_peak_demand_W = OpenStudio::Quantity.new(val.get, watt_unit)
956
+ mon_peak_demand = OpenStudio.convert(mon_peak_demand_W, kilowatt_unit).get.value
957
+ end
958
+ # record the monthly value
959
+ fuel_type_elems << OpenStudio::Attribute.new('month', mon_peak_demand, 'kW')
960
+ # if month peak demand > ann peak demand make this new ann peak demand
961
+ if mon_peak_demand > ann_peak_demand
962
+ ann_peak_demand = mon_peak_demand
963
+ end
964
+ end
965
+ # record the annual peak demand
966
+ fuel_type_elems << OpenStudio::Attribute.new('year', ann_peak_demand, 'kW')
967
+ # add this fuel type
968
+ end_use_elems << OpenStudio::Attribute.new(fuel_type_alias_map[end_use_fuel_type.value], fuel_type_elems)
969
+ end
970
+ # add this end use
971
+ demand_elems << OpenStudio::Attribute.new(end_use_map[end_use_cat.value], end_use_elems)
972
+ end
973
+ # end demand
974
+ monthly_elems << OpenStudio::Attribute.new('demand', demand_elems)
975
+
976
+ # end monthly
977
+ result_elems << OpenStudio::Attribute.new('monthly', monthly_elems)
978
+
979
+ result_elem = OpenStudio::Attribute.new('results', result_elems)
980
+ return result_elem
981
+ end
982
+ end
983
+ end