openstudio-standards 0.8.3 → 0.8.5.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (330) hide show
  1. checksums.yaml +4 -4
  2. data/data/geometry/ASHRAECollege.osm +30 -30
  3. data/data/geometry/ASHRAECourthouse.osm +22 -22
  4. data/data/geometry/ASHRAESmallOfficeDetailed.osm +2 -2
  5. data/data/geometry/DEER_Asm.osm +1 -1
  6. data/data/geometry/DEER_ECC.osm +1 -1
  7. data/data/geometry/DEER_EPr.osm +1 -1
  8. data/data/geometry/DEER_ERC.osm +1 -1
  9. data/data/geometry/DEER_ESe.osm +1 -1
  10. data/data/geometry/DEER_EUn.osm +1 -1
  11. data/data/geometry/DEER_Hsp.osm +1 -1
  12. data/data/geometry/DEER_Htl.osm +1 -1
  13. data/data/geometry/DEER_MBT.osm +1 -1
  14. data/data/geometry/DEER_MFm.osm +1 -1
  15. data/data/geometry/DEER_Nrs.osm +1 -1
  16. data/data/geometry/DEER_OfL.osm +1 -1
  17. data/data/geometry/DEER_OfS.osm +1 -1
  18. data/data/geometry/DEER_RFF.osm +1 -1
  19. data/data/geometry/DEER_RSD.osm +1 -1
  20. data/data/geometry/DEER_Rt3.osm +1 -1
  21. data/data/geometry/DEER_RtS.osm +1 -1
  22. data/data/standards/export_OpenStudio_libraries.rb +2 -3
  23. data/data/standards/test_performance_expected_dd_results.csv +42 -42
  24. data/lib/openstudio-standards/btap/NECB_building_types.csv +35 -0
  25. data/lib/openstudio-standards/btap/NECB_space_types.csv +109 -0
  26. data/lib/openstudio-standards/btap/activity.rb +480 -0
  27. data/lib/openstudio-standards/btap/attributes.rb +166 -0
  28. data/lib/openstudio-standards/btap/bridging.rb +561 -1402
  29. data/lib/openstudio-standards/btap/btap.rb +4 -2
  30. data/lib/openstudio-standards/btap/btap_test_helper.rb +86 -0
  31. data/lib/openstudio-standards/btap/carbon/btap_carbon.rb +177 -0
  32. data/lib/openstudio-standards/btap/common_paths.rb +81 -0
  33. data/lib/openstudio-standards/btap/common_resources/ConstructionProperties.csv +52 -0
  34. data/lib/openstudio-standards/btap/common_resources/Constructions.csv +37 -0
  35. data/lib/openstudio-standards/btap/common_resources/carbon_frame.csv +35 -0
  36. data/lib/openstudio-standards/btap/common_resources/carbon_glazing.csv +35 -0
  37. data/lib/openstudio-standards/btap/common_resources/carbon_opaque.csv +164 -0
  38. data/lib/openstudio-standards/btap/common_resources/construction_sets.csv +1270 -0
  39. data/lib/openstudio-standards/btap/common_resources/constructions_glazing.csv +121 -0
  40. data/lib/openstudio-standards/btap/common_resources/constructions_opaque.csv +2256 -0
  41. data/lib/openstudio-standards/btap/common_resources/costs.csv +1897 -0
  42. data/lib/openstudio-standards/btap/common_resources/costs_local_factors.csv +2315 -0
  43. data/lib/openstudio-standards/btap/common_resources/hvac_vent_ahu.csv +925 -0
  44. data/lib/openstudio-standards/btap/common_resources/lighting.csv +364 -0
  45. data/lib/openstudio-standards/btap/common_resources/lighting_sets.csv +2667 -0
  46. data/lib/openstudio-standards/btap/common_resources/locations.csv +75 -0
  47. data/lib/openstudio-standards/btap/common_resources/materials_glazing.csv +35 -0
  48. data/lib/openstudio-standards/btap/common_resources/materials_hvac.csv +1686 -0
  49. data/lib/openstudio-standards/btap/common_resources/materials_lighting.csv +267 -0
  50. data/lib/openstudio-standards/btap/common_resources/materials_opaque.csv +164 -0
  51. data/lib/openstudio-standards/btap/costing/README.md +502 -0
  52. data/lib/openstudio-standards/btap/costing/btap_costing.rb +469 -0
  53. data/lib/openstudio-standards/btap/costing/btap_measure_helper.rb +359 -0
  54. data/lib/openstudio-standards/btap/costing/btap_workflow.rb +117 -0
  55. data/lib/openstudio-standards/btap/costing/copy_test_results_files_to_expected_results.rb +11 -0
  56. data/lib/openstudio-standards/btap/costing/cost_building_from_file.rb +136 -0
  57. data/lib/openstudio-standards/btap/costing/costing_database_wrapper.rb +173 -0
  58. data/lib/openstudio-standards/btap/costing/daylighting_sensor_control_costing.rb +354 -0
  59. data/lib/openstudio-standards/btap/costing/dcv_costing.rb +314 -0
  60. data/lib/openstudio-standards/btap/costing/dummy.epw +8768 -0
  61. data/lib/openstudio-standards/btap/costing/dummy.osm +5320 -0
  62. data/lib/openstudio-standards/btap/costing/envelope_costing.rb +215 -0
  63. data/lib/openstudio-standards/btap/costing/heating_cooling_costing.rb +2584 -0
  64. data/lib/openstudio-standards/btap/costing/led_lighting_costing.rb +156 -0
  65. data/lib/openstudio-standards/btap/costing/lighting_costing.rb +209 -0
  66. data/lib/openstudio-standards/btap/costing/mech_sizing.json +502 -0
  67. data/lib/openstudio-standards/btap/costing/neb_end_use_prices.csv +42 -0
  68. data/lib/openstudio-standards/btap/costing/necb_2011_spacetype_info.csv +225 -0
  69. data/lib/openstudio-standards/btap/costing/necb_reference_runs.csv +28705 -0
  70. data/lib/openstudio-standards/btap/costing/nv_costing.rb +547 -0
  71. data/lib/openstudio-standards/btap/costing/parallel_tests.rb +92 -0
  72. data/lib/openstudio-standards/btap/costing/pv_ground_costing.rb +687 -0
  73. data/lib/openstudio-standards/btap/costing/shw_costing.rb +705 -0
  74. data/lib/openstudio-standards/btap/costing/test_list.txt +15 -0
  75. data/lib/openstudio-standards/btap/costing/test_run_all_test_locally.rb +27 -0
  76. data/lib/openstudio-standards/btap/costing/test_run_costing_tests.rb +80 -0
  77. data/lib/openstudio-standards/btap/costing/ventilation_costing.rb +2616 -0
  78. data/lib/openstudio-standards/btap/geometry.rb +86 -6
  79. data/lib/openstudio-standards/btap/structure.rb +657 -0
  80. data/lib/openstudio-standards/constructions/modify.rb +2 -1
  81. data/lib/openstudio-standards/create_typical/create_typical.rb +17 -33
  82. data/lib/openstudio-standards/create_typical/space_type_ratios.rb +36 -36
  83. data/lib/openstudio-standards/equipment/create_transformer.rb +104 -0
  84. data/lib/openstudio-standards/equipment/create_typical_equipment.rb +117 -0
  85. data/lib/openstudio-standards/equipment/data/electric_equipment_space_types.json +1514 -0
  86. data/lib/openstudio-standards/equipment/data/gas_equipment_space_types.json +227 -0
  87. data/lib/openstudio-standards/exterior_lighting/create.rb +22 -22
  88. data/lib/openstudio-standards/exterior_lighting/information.rb +3 -2
  89. data/lib/openstudio-standards/hvac/components/air_conditioner_vrf.rb +482 -0
  90. data/lib/openstudio-standards/hvac/components/air_terminal.rb +31 -0
  91. data/lib/openstudio-standards/hvac/components/boiler_hot_water.rb +163 -0
  92. data/lib/openstudio-standards/hvac/components/central_air_source_heat_pump.rb +220 -0
  93. data/lib/openstudio-standards/hvac/components/chiller.rb +25 -0
  94. data/lib/openstudio-standards/hvac/components/coil.rb +276 -0
  95. data/lib/openstudio-standards/hvac/components/coil_cooling_dx_multi_speed.rb +40 -0
  96. data/lib/openstudio-standards/hvac/components/coil_cooling_dx_single_speed.rb +300 -0
  97. data/lib/openstudio-standards/hvac/components/coil_cooling_dx_two_speed.rb +187 -0
  98. data/lib/openstudio-standards/hvac/components/coil_cooling_water.rb +80 -0
  99. data/lib/openstudio-standards/hvac/components/coil_cooling_water_to_air_heat_pump_equation_fit.rb +182 -0
  100. data/lib/openstudio-standards/hvac/components/coil_heating_dx_single_speed.rb +220 -0
  101. data/lib/openstudio-standards/hvac/components/coil_heating_electric.rb +56 -0
  102. data/lib/openstudio-standards/hvac/components/coil_heating_gas.rb +90 -0
  103. data/lib/openstudio-standards/hvac/components/coil_heating_gas_multi_stage.rb +33 -0
  104. data/lib/openstudio-standards/hvac/components/coil_heating_water.rb +98 -0
  105. data/lib/openstudio-standards/hvac/components/coil_heating_water_to_air_heat_pump_equation_fit.rb +147 -0
  106. data/lib/openstudio-standards/hvac/components/component.rb +39 -0
  107. data/lib/openstudio-standards/{standards/ashrae_90_1/data/ashrae_90_1.fans.json → hvac/components/data/fans.json} +6 -6
  108. data/lib/openstudio-standards/hvac/components/fan.rb +363 -0
  109. data/lib/openstudio-standards/hvac/components/heat_exchanger_air_to_air.rb +203 -0
  110. data/lib/openstudio-standards/hvac/components/pump.rb +181 -0
  111. data/lib/openstudio-standards/hvac/controls/radiant_system_controls.rb +594 -0
  112. data/lib/openstudio-standards/hvac/conversions.rb +222 -0
  113. data/lib/openstudio-standards/hvac/curves.rb +192 -0
  114. data/lib/openstudio-standards/hvac/helpers.rb +357 -0
  115. data/lib/openstudio-standards/hvac/setpoint_managers/information.rb +4 -4
  116. data/lib/openstudio-standards/interior_lighting/create_lights.rb +52 -0
  117. data/lib/openstudio-standards/interior_lighting/create_typical_interior_lighting.rb +254 -0
  118. data/lib/openstudio-standards/interior_lighting/data/convert_lighting_data.rb +249 -0
  119. data/lib/openstudio-standards/interior_lighting/data/lighting_space_types.csv +96 -0
  120. data/lib/openstudio-standards/interior_lighting/data/lighting_space_types.json +1429 -0
  121. data/lib/openstudio-standards/interior_lighting/data/lighting_technology.csv +46 -0
  122. data/lib/openstudio-standards/interior_lighting/data/lighting_technology.json +859 -0
  123. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.AirTerminalSingleDuctVAVReheat.rb +1 -1
  124. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.AirTerminalSingleDuctVAVReheat.rb +1 -1
  125. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirTerminalSingleDuctVAVReheat.rb +1 -1
  126. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Model.rb +4 -4
  127. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirTerminalSingleDuctVAVReheat.rb +1 -1
  128. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Model.rb +4 -4
  129. data/lib/openstudio-standards/prototypes/ashrae_90_1/nrel_nze_ready_2017/nrel_zne_ready_2017.AirTerminalSingleDuctVAVReheat.rb +1 -1
  130. data/lib/openstudio-standards/prototypes/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.AirTerminalSingleDuctVAVReheat.rb +1 -1
  131. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.HighRiseApartment.rb +6 -7
  132. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Hospital.rb +15 -15
  133. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeHotel.rb +4 -4
  134. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeOffice.rb +5 -5
  135. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.MediumOffice.rb +6 -6
  136. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Outpatient.rb +7 -7
  137. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.PrimarySchool.rb +4 -4
  138. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SecondarySchool.rb +6 -6
  139. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallOfficeDetailed.rb +5 -1
  140. data/lib/openstudio-standards/prototypes/common/data/prototype_space_type_map.json +2594 -0
  141. data/lib/openstudio-standards/prototypes/common/data/thermostat_schedule_lookup.json +2108 -0
  142. data/lib/openstudio-standards/prototypes/common/objects/Prototype.AirTerminalSingleDuctVAVReheat.rb +33 -0
  143. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Fan.rb +0 -140
  144. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanConstantVolume.rb +1 -73
  145. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanOnOff.rb +1 -69
  146. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanVariableVolume.rb +0 -116
  147. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanZoneExhaust.rb +0 -61
  148. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.hvac.rb +2 -2
  149. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.rb +128 -13
  150. data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +606 -607
  151. data/lib/openstudio-standards/prototypes/common/prototype_space_type_map.rb +41 -0
  152. data/lib/openstudio-standards/prototypes/common/space_type_equipment_map.rb +184 -0
  153. data/lib/openstudio-standards/prototypes/common/space_type_thermostat_schedule_map.rb +116 -0
  154. data/lib/openstudio-standards/qaqc/hvac.rb +12 -12
  155. data/lib/openstudio-standards/refrigeration/create_compressor.rb +2 -5
  156. data/lib/openstudio-standards/refrigeration/data/refrigeration_compressors.csv +4 -4
  157. data/lib/openstudio-standards/service_water_heating/create_water_heater.rb +1 -2
  158. data/lib/openstudio-standards/service_water_heating/create_water_use.rb +5 -5
  159. data/lib/openstudio-standards/space_type/data/level_1_space_types.json +612 -0
  160. data/lib/openstudio-standards/space_type/standards_space_type.rb +53 -0
  161. data/lib/openstudio-standards/standards/Standards.AirConditionerVariableRefrigerantFlow.rb +8 -26
  162. data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +13 -13
  163. data/lib/openstudio-standards/standards/Standards.AirTerminalSingleDuctVAVReheat.rb +0 -24
  164. data/lib/openstudio-standards/standards/Standards.BoilerHotWater.rb +6 -43
  165. data/lib/openstudio-standards/standards/Standards.ChillerElectricEIR.rb +7 -24
  166. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXMultiSpeed.rb +19 -44
  167. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXSingleSpeed.rb +25 -50
  168. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXTwoSpeed.rb +25 -33
  169. data/lib/openstudio-standards/standards/Standards.CoilCoolingWaterToAirHeatPumpEquationFit.rb +9 -22
  170. data/lib/openstudio-standards/standards/Standards.CoilDX.rb +15 -157
  171. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXMultiSpeed.rb +2 -2
  172. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXSingleSpeed.rb +18 -105
  173. data/lib/openstudio-standards/standards/Standards.CoilHeatingGas.rb +3 -23
  174. data/lib/openstudio-standards/standards/Standards.CoilHeatingGasMultiStage.rb +0 -24
  175. data/lib/openstudio-standards/standards/Standards.CoilHeatingWaterToAirHeatPumpEquationFit.rb +2 -86
  176. data/lib/openstudio-standards/standards/Standards.FanVariableVolume.rb +0 -107
  177. data/lib/openstudio-standards/standards/Standards.Model.rb +45 -20
  178. data/lib/openstudio-standards/standards/Standards.People.rb +113 -0
  179. data/lib/openstudio-standards/standards/Standards.PlantLoop.rb +11 -11
  180. data/lib/openstudio-standards/standards/Standards.Pump.rb +2 -147
  181. data/lib/openstudio-standards/standards/Standards.PumpVariableSpeed.rb +57 -41
  182. data/lib/openstudio-standards/standards/Standards.SpaceType.rb +30 -153
  183. data/lib/openstudio-standards/standards/Standards.Ventilation.rb +74 -0
  184. data/lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb +1 -1
  185. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.PlantLoop.rb +4 -4
  186. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.heat_pumps_heating.json +3 -3
  187. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.spc_typ.json +37 -112
  188. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/comstock_ashrae_90_1_2007/data/comstock_ashrae_90_1_2007.spc_typ.json +37 -102
  189. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.heat_pumps_heating.json +3 -3
  190. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.spc_typ.json +37 -112
  191. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.AirTerminalSingleDuctVAVReheat.rb +1 -1
  192. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/comstock_ashrae_90_1_2010/data/comstock_ashrae_90_1_2010.spc_typ.json +37 -37
  193. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.heat_pumps_heating.json +6 -6
  194. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.spc_typ.json +37 -37
  195. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.AirTerminalSingleDuctVAVReheat.rb +1 -1
  196. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.BoilerHotWater.rb +1 -1
  197. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/comstock_ashrae_90_1_2013/data/comstock_ashrae_90_1_2013.spc_typ.json +37 -102
  198. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.heat_pumps_heating.json +6 -6
  199. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.spc_typ.json +37 -37
  200. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirTerminalSingleDuctVAVReheat.rb +1 -1
  201. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.BoilerHotWater.rb +1 -1
  202. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/comstock_ashrae_90_1_2016/data/comstock_ashrae_90_1_2016.spc_typ.json +45 -109
  203. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.heat_pumps_heating.json +6 -6
  204. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.spc_typ.json +37 -37
  205. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +1 -1
  206. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirTerminalSingleDuctVAVReheat.rb +1 -1
  207. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.BoilerHotWater.rb +1 -1
  208. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.CoilHeatingGas.rb +1 -1
  209. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/comstock_ashrae_90_1_2019/data/comstock_ashrae_90_1_2019.spc_typ.json +45 -109
  210. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.heat_pumps_heating.json +6 -6
  211. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.spc_typ.json +37 -37
  212. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.curves.json +0 -200
  213. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/comstock_doe_ref_1980_2004/data/comstock_doe_ref_1980_2004.spc_typ.json +37 -37
  214. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.spc_typ.json +37 -37
  215. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/comstock_doe_ref_pre_1980/data/comstock_doe_ref_pre_1980.spc_typ.json +37 -37
  216. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.spc_typ.json +37 -37
  217. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.AirTerminalSingleDuctVAVReheat.rb +1 -1
  218. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.PlantLoop.rb +5 -5
  219. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.AirTerminalSingleDuctVAVReheat.rb +1 -1
  220. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.PlantLoop.rb +5 -5
  221. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirLoopHVAC.rb +1 -1
  222. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ChillerElectricEIR.rb +2 -2
  223. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilCoolingDXSingleSpeed.rb +2 -68
  224. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilCoolingDXTwoSpeed.rb +2 -35
  225. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilDX.rb +42 -0
  226. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingDXSingleSpeed.rb +5 -2
  227. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingGas.rb +2 -2
  228. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Model.rb +2 -2
  229. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlantLoop.rb +3 -3
  230. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.SpaceType.rb +1 -1
  231. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019.Model.rb +1 -0
  232. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019_WaterHeaterMixed.rb +2 -4
  233. data/lib/openstudio-standards/standards/ashrae_90_1_prm/data/ashrae_90_1_prm.curves.json +0 -200
  234. data/lib/openstudio-standards/standards/ashrae_90_1_prm/data/ashrae_90_1_prm.fans.json +5 -5
  235. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/ashrae_90_1_prm.UserData.rb +7 -1
  236. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_enums.rb +0 -1
  237. data/lib/openstudio-standards/standards/cbes/data/cbes.curves.json +0 -200
  238. data/lib/openstudio-standards/standards/deer/data/deer.curves.json +0 -200
  239. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/btap_pre1980.rb +21 -37
  240. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/building_envelope.rb +12 -11
  241. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_3_and_8_single_speed.rb +68 -27
  242. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_4.rb +64 -25
  243. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_6.rb +9 -14
  244. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_systems.rb +4 -4
  245. data/lib/openstudio-standards/standards/necb/ECMS/ecms.rb +1 -1
  246. data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +115 -112
  247. data/lib/openstudio-standards/standards/necb/NECB2011/autozone.rb +637 -249
  248. data/lib/openstudio-standards/standards/necb/NECB2011/beps_compliance_path.rb +16 -12
  249. data/lib/openstudio-standards/standards/necb/NECB2011/building_envelope.rb +799 -46
  250. data/lib/openstudio-standards/standards/necb/NECB2011/data/chillers.json +33 -51
  251. data/lib/openstudio-standards/standards/necb/NECB2011/data/constants.json +75 -7
  252. data/lib/openstudio-standards/standards/necb/NECB2011/data/fuel_type_sets.json +25 -1
  253. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/HighriseApartmentMult.osm +14272 -0
  254. data/lib/openstudio-standards/standards/necb/NECB2011/data/heat_pumps_heating.json +21 -15
  255. data/lib/openstudio-standards/standards/necb/NECB2011/data/necb_2015_table_c1.json +1 -1
  256. data/lib/openstudio-standards/standards/necb/NECB2011/data/space_types.json +437 -437
  257. data/lib/openstudio-standards/standards/necb/NECB2011/data/systems.json +516 -0
  258. data/lib/openstudio-standards/standards/necb/NECB2011/data/systems_including_sys5.json +588 -0
  259. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_namer.rb +489 -0
  260. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_1_single_speed.rb +18 -6
  261. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_2_and_5.rb +48 -5
  262. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_multi_speed.rb +2 -2
  263. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_single_speed.rb +35 -27
  264. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_4.rb +34 -23
  265. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_6.rb +8 -6
  266. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +68 -150
  267. data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +444 -134
  268. data/lib/openstudio-standards/standards/necb/NECB2011/system_fuels.rb +61 -1
  269. data/lib/openstudio-standards/standards/necb/NECB2015/data/heat_pumps_heating.json +10 -2
  270. data/lib/openstudio-standards/standards/necb/NECB2015/data/space_types.json +636 -636
  271. data/lib/openstudio-standards/standards/necb/NECB2015/data/unitary_acs.json +38 -38
  272. data/lib/openstudio-standards/standards/necb/NECB2015/hvac_systems.rb +17 -8
  273. data/lib/openstudio-standards/standards/necb/NECB2017/data/space_types.json +636 -636
  274. data/lib/openstudio-standards/standards/necb/NECB2020/data/chillers.json +71 -71
  275. data/lib/openstudio-standards/standards/necb/NECB2020/data/heat_pumps_heating.json +16 -6
  276. data/lib/openstudio-standards/standards/necb/NECB2020/data/unitary_acs.json +60 -61
  277. data/lib/openstudio-standards/standards/necb/NECB2020/service_water_heating.rb +30 -30
  278. data/lib/openstudio-standards/standards/necb/README.md +343 -0
  279. data/lib/openstudio-standards/standards/necb/common/btap_analysis.rb +79 -0
  280. data/lib/openstudio-standards/standards/necb/common/btap_data.rb +206 -32
  281. data/lib/openstudio-standards/standards/necb/common/btap_datapoint.rb +75 -43
  282. data/lib/openstudio-standards/standards/necb/common/eccc_electric_grid_intensity_20250311.csv +14 -0
  283. data/lib/openstudio-standards/standards/necb/common/nir_gas_grid_intensity_20250311.csv +14 -0
  284. data/lib/openstudio-standards/standards/necb/common/system_types.yaml +0 -0
  285. data/lib/openstudio-standards/thermal_zone/{thermal_zone.rb → information.rb} +12 -45
  286. data/lib/openstudio-standards/thermal_zone/thermostat_schedules.rb +152 -0
  287. data/lib/openstudio-standards/utilities/logging.rb +18 -14
  288. data/lib/openstudio-standards/version.rb +1 -1
  289. data/lib/openstudio-standards/weather/modify.rb +2 -2
  290. data/lib/openstudio-standards/weather/stat_file.rb +2 -2
  291. data/lib/openstudio-standards.rb +67 -38
  292. metadata +141 -50
  293. data/lib/openstudio-standards/hvac/components/create.rb +0 -169
  294. data/lib/openstudio-standards/hvac/components/modify.rb +0 -42
  295. data/lib/openstudio-standards/prototypes/common/objects/Prototype.AirConditionerVariableRefrigerantFlow.rb +0 -438
  296. data/lib/openstudio-standards/prototypes/common/objects/Prototype.BoilerHotWater.rb +0 -123
  297. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CentralAirSourceHeatPump.rb +0 -216
  298. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingDXSingleSpeed.rb +0 -273
  299. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingDXTwoSpeed.rb +0 -159
  300. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingWater.rb +0 -77
  301. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingWaterToAirHeatPumpEquationFit.rb +0 -154
  302. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingDXSingleSpeed.rb +0 -214
  303. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingElectric.rb +0 -53
  304. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingGas.rb +0 -72
  305. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingWater.rb +0 -95
  306. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingWaterToAirHeatPumpEquationFit.rb +0 -125
  307. data/lib/openstudio-standards/prototypes/common/objects/Prototype.ControllerWaterCoil.rb +0 -17
  308. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.transformers.rb +0 -90
  309. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Pump.rb +0 -4
  310. data/lib/openstudio-standards/prototypes/common/objects/Prototype.PumpVariableSpeed.rb +0 -70
  311. data/lib/openstudio-standards/prototypes/common/objects/Prototype.radiant_system_controls.rb +0 -590
  312. data/lib/openstudio-standards/prototypes/common/objects/Prototype.utilities.rb +0 -901
  313. data/lib/openstudio-standards/standards/Standards.FanConstantVolume.rb +0 -5
  314. data/lib/openstudio-standards/standards/Standards.FanOnOff.rb +0 -5
  315. data/lib/openstudio-standards/standards/Standards.FanZoneExhaust.rb +0 -5
  316. data/lib/openstudio-standards/standards/Standards.HeaderedPumpsConstantSpeed.rb +0 -5
  317. data/lib/openstudio-standards/standards/Standards.HeaderedPumpsVariableSpeed.rb +0 -55
  318. data/lib/openstudio-standards/standards/Standards.PumpConstantSpeed.rb +0 -5
  319. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanConstantVolume.rb +0 -5
  320. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanOnOff.rb +0 -5
  321. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanZoneExhaust.rb +0 -5
  322. data/lib/openstudio-standards/standards/cbes/data/cbes.fans.json +0 -328
  323. data/lib/openstudio-standards/standards/deer/data/deer.fans.json +0 -328
  324. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.PumpVariableSpeed.rb +0 -0
  325. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.PumpVariableSpeed.rb +0 -0
  326. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.PumpVariableSpeed.rb +0 -0
  327. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.PumpVariableSpeed.rb +0 -0
  328. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.PumpVariableSpeed.rb +0 -0
  329. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Pump.rb +0 -0
  330. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.PumpVariableSpeed.rb +0 -0
@@ -0,0 +1,469 @@
1
+ require 'json'
2
+ require_relative 'costing_database_wrapper'
3
+
4
+ class SimpleLinearRegression
5
+ #https://gist.github.com/rweald/3516193#file-full-slr-class-snippet-rb
6
+ def initialize(xs, ys)
7
+ @xs, @ys = xs, ys
8
+ if @xs.length != @ys.length
9
+ raise "Unbalanced data. xs need to be same length as ys"
10
+ end
11
+ end
12
+
13
+ def y_intercept
14
+ return mean(@ys) - (slope * mean(@xs))
15
+ end
16
+
17
+ def slope
18
+ x_mean = mean(@xs)
19
+ y_mean = mean(@ys)
20
+
21
+ numerator = (0...@xs.length).reduce(0) do |sum, i|
22
+ sum + ((@xs[i] - x_mean) * (@ys[i] - y_mean))
23
+ end
24
+
25
+ denominator = @xs.reduce(0) do |sum, x|
26
+ sum + ((x - x_mean) ** 2)
27
+ end
28
+
29
+ return (numerator / denominator)
30
+ end
31
+
32
+ def mean(values)
33
+ total = values.reduce(0) { |sum, x| x + sum }
34
+ return Float(total) / Float(values.length)
35
+ end
36
+ end
37
+
38
+
39
+ class BTAPCosting
40
+ # May be initialized with custom databases:
41
+ # costs_csv: Path to custom costing
42
+ # factors_csv: Path to custom localization factors
43
+ def initialize(costs_csv: nil, factors_csv: nil, attributes:)
44
+ @cp = CommonPaths.instance
45
+ @costing_database = CostingDatabase.instance
46
+ @attributes = attributes
47
+
48
+ # If the path for custom costing is defined, use custom costing.
49
+ if (not costs_csv.nil?) and File.exist?(costs_csv)
50
+ @cp.costs_path = costs_csv
51
+ end
52
+
53
+ # If the path for custom factors is defined, use custom factors.
54
+ if (not factors_csv.nil?) and File.exist?(factors_csv)
55
+ @cp.costs_local_factors_path = factors_csv
56
+ end
57
+ end
58
+
59
+ def validate_database()
60
+ @costing_database.validate_database
61
+ end
62
+
63
+ def generate_construction_cost_database_for_all_cities()
64
+ result = Array.new
65
+ @costing_database['raw']['locations'].each do |location|
66
+ province_state = location["province_state"]
67
+ city = location['city']
68
+ result.concat(generate_construction_cost_database_for_city(city, province_state))
69
+ end
70
+ return result
71
+ end
72
+
73
+ def generate_construction_cost_database_for_city(city, province_state)
74
+ @costing_database['constructions_costs'] = Array.new
75
+ puts "Costing for: #{province_state},#{city}"
76
+ @costing_database["raw"]['constructions_opaque'].each do |construction|
77
+ cost_construction(construction, {"province_state" => province_state, "city" => city}, 'opaque')
78
+ end
79
+ @costing_database["raw"]['constructions_glazing'].each do |construction|
80
+ cost_construction(construction, {"province_state" => province_state, "city" => city}, 'glazing')
81
+ end
82
+ puts "#{@costing_database['constructions_costs'].size} Costed Constructions for #{province_state},#{city}."
83
+ return @costing_database['constructions_costs']
84
+ end
85
+
86
+
87
+ def cost_audit_all(model:,
88
+ prototype_creator:,
89
+ envelope_costing: true,
90
+ lighting_costing: true,
91
+ boilers_costing: true,
92
+ chillers_costing: true,
93
+ cooling_towers_costing: true,
94
+ shw_costing: true,
95
+ ventilation_costing: true,
96
+ zone_system_costing: true,
97
+ renewables_costing: true,
98
+ template_type: nil
99
+ )
100
+ # Create a Hash to collect costing data.
101
+ @costing_report = {}
102
+
103
+ #Use closest city.
104
+ closest_loc = get_closest_cost_location(model.getWeatherFile.latitude, model.getWeatherFile.longitude)
105
+ @costing_report['city'] = closest_loc['city']
106
+ @costing_report['province_state'] = closest_loc['province_state']
107
+
108
+ # Create array to collect costed item information. First element is the costing location.
109
+ @cost_items = {
110
+ 'City' => closest_loc['city'],
111
+ 'Province' => closest_loc['province_state'],
112
+ 'Items' => []
113
+ }
114
+
115
+ # Create a Hash in the hash for categories of costing.
116
+ @costing_report['envelope'] = {}
117
+ @costing_report['lighting'] = {}
118
+ @costing_report['lighting']['daylighting_sensor_control'] = []
119
+ @costing_report['lighting']['led_lighting'] = []
120
+ @costing_report['heating_and_cooling'] = {}
121
+ @costing_report['heating_and_cooling']['plant_equipment'] = []
122
+ @costing_report['heating_and_cooling']['zonal_systems'] = []
123
+ @costing_report['shw'] = {}
124
+ @costing_report['ventilation'] = {}
125
+ @costing_report['renewables'] = {}
126
+ @costing_report['renewables']['pv'] = []
127
+ @costing_report['totals'] = {}
128
+
129
+ # Check to see if standards building type and the number of stories has been defined. The former may be omitted in the future.
130
+ if model.getBuilding.standardsBuildingType.empty? or model.getBuilding.standardsNumberOfAboveGroundStories.empty?
131
+ raise("Building information is not complete, please ensure that the standardsBuildingType and standardsNumberOfAboveGroundStories are entered in the model. ")
132
+ end
133
+
134
+ # Find the mechanical room
135
+ mech_room, cond_spaces = prototype_creator.find_mech_room(model)
136
+
137
+ envCost = envelope_costing ? self.cost_audit_envelope(model, prototype_creator) : 0.0
138
+ lgtCost = lighting_costing ? self.cost_audit_lighting(model, prototype_creator) : 0.0
139
+ boilerCost = boilers_costing ? self.boiler_costing(model, prototype_creator) : 0.0
140
+ chillerCost = chillers_costing ? self.chiller_costing(model, prototype_creator) : 0.0
141
+ coolingTowerCost = cooling_towers_costing ? self.coolingtower_costing(model, prototype_creator) : 0.0
142
+ shwCost = shw_costing ? self.shw_costing(model, prototype_creator) : 0.0
143
+ ventCost = ventilation_costing ? self.ventilation_costing(model, prototype_creator,template_type, mech_room, cond_spaces) : 0.0
144
+ zonalSystemCost = zone_system_costing ? self.zonalsys_costing(model, prototype_creator, mech_room, cond_spaces) : 0.0
145
+ pvGroundCost = renewables_costing ? self.cost_audit_pv_ground(model, prototype_creator) : 0.0
146
+ thermalBridgingCost = 0.0
147
+
148
+ @costing_report["totals"] = {
149
+ 'envelope' => envCost.round(0),
150
+ 'thermal_bridging' => thermalBridgingCost.round(0),
151
+ 'lighting' => lgtCost.round(0),
152
+ 'heating_and_cooling' => (boilerCost + chillerCost + coolingTowerCost + zonalSystemCost).round(0),
153
+ 'shw' => shwCost.round(0),
154
+ 'ventilation' => ventCost.round(0),
155
+ 'renewables' => pvGroundCost.round(0),
156
+ 'grand_total' => (envCost + thermalBridgingCost + lgtCost + boilerCost + chillerCost + coolingTowerCost +
157
+ shwCost + ventCost + zonalSystemCost + pvGroundCost).round(0)
158
+ }
159
+
160
+ return @costing_report, @cost_items
161
+ end
162
+
163
+ def get_regional_cost_factors(provinceState, city, material)
164
+ @costing_database['localization_factors'].select { |code|
165
+ code['province_state'] == provinceState && code['city'] == city }.each do |code|
166
+ prefix_id = material['id'][0..1]
167
+ prefix_stored = code['code_prefix']
168
+ if prefix_id == prefix_stored
169
+ return code['material'], code['installation'], code['total']
170
+ end
171
+
172
+ end
173
+ error = [material, "Could not find regional adjustment factor for material used in #{city}, #{provinceState}."]
174
+ @costing_database['db_errors'] << error unless @costing_database['db_errors'].include?(error)
175
+ return 100.0, 100.0, 100.0
176
+ end
177
+
178
+ # Interpolate array of hashes that contain 2 values (key=rsi, data=cost)
179
+ def interpolate(x_y_array:, x2:, exterpolate_percentage_range: 30.0)
180
+ ratio_range = exterpolate_percentage_range / 100.0
181
+ array = x_y_array.uniq.sort { |a, b| a[0] <=> b[0] }
182
+ #if there is only one...return what you got.
183
+ if array.size == 1
184
+ return array.first[1].to_f
185
+ end
186
+ # Check if value x2 is within range of array for interpolation
187
+ # Extrapolate when x2 is out-of-range by +/- 10% of end values.
188
+ if array.empty? || x2 < ((1.0 - ratio_range) * array.first[0].to_f) || x2 > ((1.0 + ratio_range) * array.last[0].to_f)
189
+ return nil
190
+ elsif x2 < array.first[0].to_f
191
+ # Extrapolate down using first and second cost value to this out-of-range input
192
+ x_array = [array[0][0].to_f, array[1][0].to_f]
193
+ y_array = [array[0][1].to_f, array[1][1].to_f]
194
+ linear_model = SimpleLinearRegression.new(x_array, y_array)
195
+ y2 = linear_model.y_intercept + linear_model.slope * x2
196
+ return y2
197
+ elsif x2 > array.last[0].to_f
198
+ # Extrapolate up using second to last and last cost value to this out-of-range input
199
+ x_array = [array[-2][0].to_f, array[-1][0].to_f]
200
+ y_array = [array[-2][1].to_f, array[-1][1].to_f]
201
+ linear_model = SimpleLinearRegression.new(x_array, y_array)
202
+ y2 = linear_model.y_intercept + linear_model.slope * x2
203
+ return y2
204
+ else
205
+ array.each_index do |counter|
206
+
207
+ # skip last value.
208
+ next if array[counter] == array.last
209
+
210
+ x0 = array[counter][0]
211
+ y0 = array[counter][1]
212
+ x1 = array[counter + 1][0]
213
+ y1 = array[counter + 1][1]
214
+
215
+ # skip to next if x2 is not between x0 and x1
216
+ next if x2 < x0 || x2 > x1
217
+
218
+ # Do interpolation
219
+ y2 = y0 # just in-case x0, x1 and x2 are identical!
220
+ if (x1 - x0) > 0.0
221
+ y2 = y0.to_f + ((y1 - y0).to_f * (x2 - x0).to_f / (x1 - x0).to_f)
222
+ end
223
+ return y2
224
+ end
225
+ end
226
+ end
227
+
228
+ # Enter in [latitude, longitude] for each loc and this method will return the distance.
229
+ def distance(loc1, loc2)
230
+ rad_per_deg = Math::PI / 180 # PI / 180
231
+ rkm = 6371 # Earth radius in kilometers
232
+ rm = rkm * 1000 # Radius in meters
233
+
234
+ dlat_rad = (loc2[0] - loc1[0]) * rad_per_deg # Delta, converted to rad
235
+ dlon_rad = (loc2[1] - loc1[1]) * rad_per_deg
236
+
237
+ lat1_rad, lon1_rad = loc1.map { |i| i * rad_per_deg }
238
+ lat2_rad, lon2_rad = loc2.map { |i| i * rad_per_deg }
239
+
240
+ a = Math.sin(dlat_rad / 2) ** 2 + Math.cos(lat1_rad) * Math.cos(lat2_rad) * Math.sin(dlon_rad / 2) ** 2
241
+ c = 2 * Math::atan2(Math::sqrt(a), Math::sqrt(1 - a))
242
+ rm * c # Delta in meters
243
+ end
244
+
245
+ def get_closest_cost_location(lat, long)
246
+ dist = 1000000000000000000000.0
247
+ closest_loc = nil
248
+ # province_state city latitude longitude source
249
+ @costing_database['raw']['locations'].each do |location|
250
+ if distance([lat, long], [location['latitude'].to_f, location['longitude'].to_f]) < dist
251
+ closest_loc = location
252
+ dist = distance([lat, long], [location['latitude'].to_f, location['longitude'].to_f])
253
+ end
254
+ end
255
+ return closest_loc
256
+ end
257
+
258
+ # This will expand the two letter province abbreviation to a full uppercase province name
259
+ def expandProvAbbrev(abbrev)
260
+
261
+ # Note that the proper abbreviation for Quebec is QC not PQ. However, we've used PQ in openstudio-standards!
262
+ Hash provAbbrev = {"AB" => "ALBERTA",
263
+ "BC" => "BRITISH COLUMBIA",
264
+ "MB" => "MANITOBA",
265
+ "NB" => "NEW BRUNSWICK",
266
+ "NL" => "NEWFOUNDLAND AND LABRADOR",
267
+ "NT" => "NORTHWEST TERRITORIES",
268
+ "NS" => "NOVA SCOTIA",
269
+ "NU" => "NUNAVUT",
270
+ "ON" => "ONTARIO",
271
+ "PE" => "PRINCE EDWARD ISLAND",
272
+ "PQ" => "QUEBEC",
273
+ "SK" => "SASKATCHEWAN",
274
+ "YT" => "YUKON"
275
+ }
276
+ return provAbbrev[abbrev]
277
+ end
278
+
279
+ def read_mech_sizing()
280
+ file = File.read(@cp.mech_sizing_data_file)
281
+ return JSON.parse(file)
282
+ end
283
+
284
+ # This adds costed items to the array of cousted items which end up in btap_itmes.json. Note that the array this
285
+ # method uses is created in the cost_audit_all method. The array is created with an initial element that contains the
286
+ # city and province whose localiazation factors are used for costing.
287
+ # The inputs are:
288
+ # id: (string) The costing database id for the item being costed.
289
+ # quantity: (float) The total amount of the item being costed in whatever units the item is costed in. This should
290
+ # include all multiplier used to determine this cost (e.g. such as thermal_zone multipliers). As
291
+ # an example, if 32 ft. of wire were required for a piece of equipment used in a thermal zone with
292
+ # a multiplier of 10, the quantity would be 3.2 (32 ft. * 10 / 100 since wire is costed per
293
+ # 100 ft.).
294
+ # material_mult: (float) The multiplier used to estimate the cost of an item from the base cost. For example, high
295
+ # efficiency SHW tanks are estimated to cost 30% higher than regular SHW tanks so the cost of these
296
+ # tanks are calculated by the cost * 1.3. Thus, the material_mult for high efficiency tanks
297
+ # would be 1.3. This is defauted to 1.0 if it is not provided.
298
+ # labour_mult: (float) Similar to material_mult only applied to labour costs. The labour_mult can be different than
299
+ # the material_mult. This is defaulted to 1.0 if it is not provided.
300
+ # equipment_mult: (float) Similar to material_mult and labour_mult only for equipment. This will always be 1.0 until
301
+ # equipment costs are supported.
302
+ # tags: (array of strings) This is an array which links the costed item to a component of the model that is being
303
+ # costed. For example, a material_id related to a boiler pump might have tags like ["boiler", "pump"].
304
+ #
305
+ def add_costed_item(material_id:, quantity:, material_mult: 1.0, labour_mult: 1.0, equip_mult: 1.0, tags: [])
306
+ # Do some error handling for the tags argument
307
+ tags_out = [tags] if tags.kind_of?(String)
308
+ tags_out = tags if tags.kind_of?(Array)
309
+
310
+ # Validate the type of the arguments.
311
+ if (tags_out.kind_of?(Array) == false)
312
+ raise("The tags for the item #{material_id} were not properly defined. Please search for where the item is being added to the @cost_items hash via the add_costed_item method and correct the entry.")
313
+ end
314
+
315
+ if (material_id.kind_of?(String) == false)
316
+ raise("The material_id for the item #{material_id} is not a string. Please search for where the item is being added to the @cost_items hash via the add_costed_item method and correct the entry.")
317
+ end
318
+
319
+ if (quantity.kind_of?(Float) == false)
320
+ raise("The quantity for the item #{material_id} is not a float. Please search for where the item is being added to the @cost_items hash via the add_costed_item method and correct the entry.")
321
+ end
322
+
323
+ if (material_mult.kind_of?(Float) == false)
324
+ raise("The material_mult for the item #{material_id} is not a float. Please search for where the item is being added to the @cost_items hash via the add_costed_item method and correct the entry.")
325
+ end
326
+
327
+ if (labour_mult.kind_of?(Float) == false)
328
+ raise("The labour_mult for the item #{material_id} is not a float. Please search for where the item is being added to the @cost_items hash via the add_costed_item method and correct the entry.")
329
+ end
330
+
331
+ if (equip_mult.kind_of?(Float) == false)
332
+ raise("The equip_mult for the item #{material_id} is not a float. Please search for where the item is being added to the @cost_items hash via the add_costed_item method and correct the entry.")
333
+ end
334
+
335
+ # Add the costed item to the output output hash.
336
+ @cost_items['Items'] << {
337
+ 'id' => material_id,
338
+ 'quantity' => quantity,
339
+ 'material_mult' => material_mult,
340
+ 'labour_mult' => labour_mult,
341
+ 'equipment_mult' => equip_mult,
342
+ 'tags' => tags_out
343
+ }
344
+ end
345
+
346
+ # This method takes the list of costed items in the building generated with the help of the above add_costed_item
347
+ # method and finds the costs for the list of items. It takes in:
348
+ # btap_items: (array of hashes) This array contains all the items that must be costed. The first element of the
349
+ # array is:
350
+ # {
351
+ # City: (string) City used for cost lacalization factor
352
+ # Province: (string) Province used for cost localization factor
353
+ # }
354
+ # The remaining arrays look like:
355
+ # {
356
+ # id: (string) ID of the coested item in question.
357
+ # quantity: (float) Amount of costed item (should include all multipliers except localization factors,
358
+ # material_mult, labour_mult, equipment_mult).
359
+ # material_mult: (float) Material multiplier from cost spreadsheet used mainly for higher performance equipment
360
+ # (for example, regular and high performance boilers share the same id but high performance
361
+ # boilers have a material_mult of around 1.3-that is they are estimated to be 1.3 times as
362
+ # expensive as regular boilers).
363
+ # labour_mult: (float) Same idea as material_mult only for labour (often this will be 1.0 even if material_mult
364
+ # is something else).
365
+ # equipment_mult: (float) Same idea as labour_mult only for equipment. It will always be 1.0 until equipment
366
+ # costs are implemented in costing.
367
+ # tags: (array of strings) An array of strings used to define what part of the building is being costed (e.g.
368
+ # an component for a ccashp might have these tags: "Ventilation", "CCASHP", "ccashp_condensor")
369
+ # }
370
+ # custom_costing: (array of hashes) A custom costing database if you do not want to use the default one. This must
371
+ # have the same format as that found by @costing_database['costs']
372
+ # custCity: (string) A custom cost localization city if you do not want to use the one in the first item in the
373
+ # btap_itmes hash.
374
+ # custProvince: (string) A custom cost localization province if you do not want to use the one in the first item in
375
+ # the btap_items hash.
376
+ #
377
+ # The output of the method is a hash containing these summary costs:
378
+ # costRetHash = {
379
+ # envelope: (float) Building envelope costs (to 2 decimal places).
380
+ # lighting: (float) Ligting costs (to 2 decimal places).
381
+ # heating_and_cooling: (float) Heating and cooling costs (not related to ventilation) (to 2 decimal places).
382
+ # shw: (float) Service hot water costs (to 2 decimal places).
383
+ # ventilation: (float) Ventilation (including ventilation air heating and cooling) costs (to 2 decimal places).
384
+ # grand_total: (float) Total costs (to 2 decimal places).
385
+ # }
386
+ #
387
+ def cost_list_items(btap_items:, custom_costing: nil, custCity: nil, custProvince: nil)
388
+ # Check if costing is for a custom city and province. If not use the city and province found in the first entry
389
+ # of the array of costed items.
390
+ if custCity.nil? || custProvince.nil?
391
+ costCity = btap_items['City'].to_s
392
+ costProvince = btap_items['Province'].to_s
393
+ else
394
+ costCity = custCity
395
+ costProvince = custProvince
396
+ end
397
+
398
+ # Initialize cost counters
399
+ totCost = 0.0
400
+ envCost = 0.0
401
+ lightCost = 0.0
402
+ heatCoolCost = 0.0
403
+ shwCost = 0.0
404
+ ventCost = 0.0
405
+ renewCost = 0.0
406
+
407
+ custom_costing.nil? ? costingDB = @costing_database['costs'] : costingDB = custom_costing
408
+
409
+ btap_items['Items'].each do |costing_item|
410
+ # Look for the costing information for the piece of equipment in the costing database.
411
+ costing_data = costingDB.detect {|data| data['id'].to_s.upcase == costing_item['id'].to_s.upcase}
412
+ # If no costing information is found then return an error.
413
+ if costing_data.nil?
414
+ raise "Error: no costing information available for material id #{costing_item['id']}!"
415
+ elsif costing_data['baseCosts']['materialOpCost'].nil? && costing_data['baseCosts']['laborOpCost'].nil?
416
+ #This is a stub for some work that needs to be done to account for equipment costing. For now this is zeroed out.
417
+ # A similar test is done on reading the data from the database and collected in the error file when the
418
+ # costing database is generated.
419
+ raise "Error: costing information for material id #{costing_item['id']} is nil. Please check costing data."
420
+ end
421
+ costing_data['baseCosts']['equipmentOpCost'].nil? ? equip_base_cost = 0.0 : equip_base_cost = costing_data['baseCosts']['equipmentOpCost'].to_f
422
+ costing_data['baseCosts']['materialOpCost'].nil? ? mat_base_cost = 0.0 : mat_base_cost = costing_data['baseCosts']['materialOpCost'].to_f
423
+ costing_data['baseCosts']['laborOpCost'].nil? ? lab_base_cost = 0.0 : lab_base_cost = costing_data['baseCosts']['laborOpCost'].to_f
424
+
425
+ # The costs from the costing database are US national average costs (for placeholder costs) or whatever is in the
426
+ # 'province_state' and 'city' fields (for custom costs). These costs need to be adjusted to reflect the costs
427
+ # expected in the location of interest. The 'get_regional_cost_factors' method finds the appropriate cost
428
+ # adjustment factors.
429
+
430
+ mat_mult, inst_mult, eq_mult = get_regional_cost_factors(costProvince, costCity, costing_item)
431
+ if mat_mult.nil? || inst_mult.nil?
432
+ raise("Error: no localization information available for material id #{costing_item['material_id']}!")
433
+ end
434
+ # Get any associated material or labour multiplier for the equipment present in the 'materials_hvac' sheet in the
435
+ # costing spreadsheet.
436
+ costing_item['material_mult'].to_f == 0 ? mat_quant = 1.0 : mat_quant = costing_item['material_mult'].to_f
437
+ costing_item['labour_mult'].to_f == 0 ? lab_quant = 1.0 : lab_quant = costing_item['labour_mult'].to_f
438
+ costing_item['equipment_mult'].to_f == 0 || costing_item['equipment_mult'].nil? ? eq_quant = 1.0 : eq_quant = costing_item['equipment_mult'].to_f
439
+ # Calculate the adjusted material and labour costs.
440
+ mat_cost = mat_base_cost*(mat_mult/100.0)*mat_quant
441
+ lab_cost = lab_base_cost*(inst_mult/100.0)*lab_quant
442
+ eq_cost = equip_base_cost*(eq_mult/100.0)*eq_quant
443
+ # Calculate the total item cost.
444
+ item_cost = (mat_cost + lab_cost + eq_cost)*(costing_item["quantity"].to_f)
445
+
446
+ # Add cost to sub-type counters
447
+ envCost += item_cost unless (costing_item['tags'].select{|data| data.to_s.upcase == "ENVELOPE"}).empty?
448
+ lightCost += item_cost unless (costing_item['tags'].select{|data| data.to_s.upcase == "LIGHTING"}).empty?
449
+ heatCoolCost += item_cost unless (costing_item['tags'].select{|data| data.to_s.upcase == "HEATING_COOLING"}).empty?
450
+ shwCost += item_cost unless (costing_item['tags'].select{|data| data.to_s.upcase == "SHW"}).empty?
451
+ ventCost += item_cost unless (costing_item['tags'].select{|data| data.to_s.upcase == "VENTILATION"}).empty?
452
+ renewCost += item_cost unless (costing_item['tags'].select{|data| data.to_s.upcase == "RENEWABLES"}).empty?
453
+ totCost += item_cost
454
+ end
455
+
456
+ # Create and return hash containing costing results
457
+ costRetHash = {
458
+ 'envelope' => envCost.round(2),
459
+ 'lighting' => lightCost.round(2),
460
+ 'heating_and_cooling' => heatCoolCost.round(2),
461
+ 'shw' => shwCost.round(2),
462
+ 'ventilation' => ventCost.round(2),
463
+ 'renewables' => renewCost.round(2),
464
+ 'grand_total' => totCost.round(2)
465
+ }
466
+ return costRetHash
467
+ end
468
+
469
+ end