openstudio-standards 0.8.2 → 0.8.4

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 (152) hide show
  1. checksums.yaml +4 -4
  2. data/data/standards/OpenStudio_Standards-ashrae_90_1-ALL-comstock(space_types).xlsx +0 -0
  3. data/data/standards/openstudio_standards_duplicates_log.csv +7962 -0
  4. data/lib/openstudio-standards/btap/costing/README.md +502 -0
  5. data/lib/openstudio-standards/btap/costing/btap_costing.rb +473 -0
  6. data/lib/openstudio-standards/btap/costing/btap_measure_helper.rb +359 -0
  7. data/lib/openstudio-standards/btap/costing/btap_workflow.rb +117 -0
  8. data/lib/openstudio-standards/btap/costing/common_paths.rb +78 -0
  9. data/lib/openstudio-standards/btap/costing/common_resources/ConstructionProperties.csv +52 -0
  10. data/lib/openstudio-standards/btap/costing/common_resources/Constructions.csv +37 -0
  11. data/lib/openstudio-standards/btap/costing/common_resources/construction_sets.csv +1270 -0
  12. data/lib/openstudio-standards/btap/costing/common_resources/constructions_glazing.csv +61 -0
  13. data/lib/openstudio-standards/btap/costing/common_resources/constructions_opaque.csv +2256 -0
  14. data/lib/openstudio-standards/btap/costing/common_resources/costs.csv +1904 -0
  15. data/lib/openstudio-standards/btap/costing/common_resources/costs_local_factors.csv +2315 -0
  16. data/lib/openstudio-standards/btap/costing/common_resources/hvac_vent_ahu.csv +925 -0
  17. data/lib/openstudio-standards/btap/costing/common_resources/lighting.csv +364 -0
  18. data/lib/openstudio-standards/btap/costing/common_resources/lighting_sets.csv +2667 -0
  19. data/lib/openstudio-standards/btap/costing/common_resources/locations.csv +75 -0
  20. data/lib/openstudio-standards/btap/costing/common_resources/materials_glazing.csv +35 -0
  21. data/lib/openstudio-standards/btap/costing/common_resources/materials_hvac.csv +1699 -0
  22. data/lib/openstudio-standards/btap/costing/common_resources/materials_lighting.csv +267 -0
  23. data/lib/openstudio-standards/btap/costing/common_resources/materials_opaque.csv +164 -0
  24. data/lib/openstudio-standards/btap/costing/copy_test_results_files_to_expected_results.rb +11 -0
  25. data/lib/openstudio-standards/btap/costing/cost_building_from_file.rb +136 -0
  26. data/lib/openstudio-standards/btap/costing/costing_database_wrapper.rb +177 -0
  27. data/lib/openstudio-standards/btap/costing/daylighting_sensor_control_costing.rb +353 -0
  28. data/lib/openstudio-standards/btap/costing/dcv_costing.rb +314 -0
  29. data/lib/openstudio-standards/btap/costing/dummy.epw +8768 -0
  30. data/lib/openstudio-standards/btap/costing/dummy.osm +5320 -0
  31. data/lib/openstudio-standards/btap/costing/envelope_costing.rb +284 -0
  32. data/lib/openstudio-standards/btap/costing/heating_cooling_costing.rb +2584 -0
  33. data/lib/openstudio-standards/btap/costing/led_lighting_costing.rb +155 -0
  34. data/lib/openstudio-standards/btap/costing/lighting_costing.rb +209 -0
  35. data/lib/openstudio-standards/btap/costing/mech_sizing.json +502 -0
  36. data/lib/openstudio-standards/btap/costing/neb_end_use_prices.csv +42 -0
  37. data/lib/openstudio-standards/btap/costing/necb_2011_spacetype_info.csv +225 -0
  38. data/lib/openstudio-standards/btap/costing/necb_reference_runs.csv +28705 -0
  39. data/lib/openstudio-standards/btap/costing/nv_costing.rb +547 -0
  40. data/lib/openstudio-standards/btap/costing/parallel_tests.rb +92 -0
  41. data/lib/openstudio-standards/btap/costing/pv_ground_costing.rb +687 -0
  42. data/lib/openstudio-standards/btap/costing/shw_costing.rb +705 -0
  43. data/lib/openstudio-standards/btap/costing/test_list.txt +17 -0
  44. data/lib/openstudio-standards/btap/costing/test_run_all_test_locally.rb +26 -0
  45. data/lib/openstudio-standards/btap/costing/test_run_costing_tests.rb +80 -0
  46. data/lib/openstudio-standards/btap/costing/ventilation_costing.rb +2616 -0
  47. data/lib/openstudio-standards/constructions/modify.rb +2 -1
  48. data/lib/openstudio-standards/refrigeration/create_case.rb +58 -21
  49. data/lib/openstudio-standards/refrigeration/create_typical_refrigeration.rb +4 -2
  50. data/lib/openstudio-standards/refrigeration/create_walkin.rb +57 -22
  51. data/lib/openstudio-standards/refrigeration/data/refrigerated_cases.csv +31 -31
  52. data/lib/openstudio-standards/refrigeration/data/refrigerated_walkins.csv +76 -76
  53. data/lib/openstudio-standards/service_water_heating/create_typical.rb +10 -10
  54. data/lib/openstudio-standards/service_water_heating/create_water_heater.rb +10 -0
  55. data/lib/openstudio-standards/service_water_heating/create_water_heating_loop.rb +16 -3
  56. data/lib/openstudio-standards/service_water_heating/data/convert_data.rb +9 -9
  57. data/lib/openstudio-standards/service_water_heating/data/typical_water_use_equipment.csv +49 -49
  58. data/lib/openstudio-standards/service_water_heating/data/typical_water_use_equipment.json +159 -159
  59. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXMultiSpeed.rb +7 -18
  60. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXSingleSpeed.rb +10 -20
  61. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXTwoSpeed.rb +6 -15
  62. data/lib/openstudio-standards/standards/Standards.CoilCoolingWaterToAirHeatPumpEquationFit.rb +5 -6
  63. data/lib/openstudio-standards/standards/Standards.CoilDX.rb +93 -43
  64. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXMultiSpeed.rb +5 -5
  65. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXSingleSpeed.rb +135 -37
  66. data/lib/openstudio-standards/standards/Standards.CoilHeatingWaterToAirHeatPumpEquationFit.rb +2 -2
  67. data/lib/openstudio-standards/standards/Standards.Model.rb +48 -13
  68. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.computer_room_acs.json +302 -140
  69. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.heat_pumps.json +648 -326
  70. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.heat_pumps_heating.json +371 -90
  71. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.water_heaters.json +66 -22
  72. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.computer_room_acs.json +302 -140
  73. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.heat_pumps.json +1012 -296
  74. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.heat_pumps_heating.json +443 -79
  75. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.water_heaters.json +66 -22
  76. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.computer_room_acs.json +302 -140
  77. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.heat_pumps.json +672 -306
  78. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.heat_pumps_heating.json +354 -74
  79. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.water_heaters.json +72 -24
  80. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.computer_room_acs.json +302 -140
  81. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.energy_recovery.json +8 -8
  82. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.heat_pumps.json +930 -604
  83. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.heat_pumps_heating.json +415 -111
  84. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.water_heaters.json +72 -24
  85. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.computer_room_acs.json +602 -140
  86. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.heat_pumps.json +1005 -333
  87. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.heat_pumps_heating.json +642 -88
  88. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.water_heaters.json +78 -26
  89. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.computer_room_acs.json +722 -140
  90. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.heat_pumps.json +1741 -426
  91. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.heat_pumps_heating.json +1108 -111
  92. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.water_heaters.json +186 -62
  93. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.schedules.json +62 -232
  94. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilCoolingDXSingleSpeed.rb +2 -3
  95. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilCoolingDXTwoSpeed.rb +1 -1
  96. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilDX.rb +7 -18
  97. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingDXSingleSpeed.rb +9 -7
  98. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingGas.rb +1 -1
  99. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Model.rb +2 -2
  100. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.heat_pumps.json +154 -69
  101. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.heat_pumps_heating.json +72 -72
  102. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.water_heaters.json +382 -295
  103. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/ashrae_90_1_prm.UserData.rb +6 -1
  104. data/lib/openstudio-standards/standards/deer/data/deer.schedules.json +62 -232
  105. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/btap_pre1980.rb +2 -27
  106. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/data/heat_pumps.json +16 -0
  107. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/data/heat_pumps_heating.json +6 -0
  108. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_3_and_8_single_speed.rb +68 -27
  109. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_4.rb +64 -25
  110. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_6.rb +9 -14
  111. data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +46 -20
  112. data/lib/openstudio-standards/standards/necb/NECB2011/autozone.rb +635 -248
  113. data/lib/openstudio-standards/standards/necb/NECB2011/data/constants.json +43 -7
  114. data/lib/openstudio-standards/standards/necb/NECB2011/data/fuel_type_sets.json +7 -1
  115. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/HighriseApartmentMult.osm +14272 -0
  116. data/lib/openstudio-standards/standards/necb/NECB2011/data/heat_pumps.json +16 -0
  117. data/lib/openstudio-standards/standards/necb/NECB2011/data/heat_pumps_heating.json +6 -0
  118. data/lib/openstudio-standards/standards/necb/NECB2011/data/necb_2015_table_c1.json +1 -1
  119. data/lib/openstudio-standards/standards/necb/NECB2011/data/space_types.json +437 -437
  120. data/lib/openstudio-standards/standards/necb/NECB2011/data/systems.json +516 -0
  121. data/lib/openstudio-standards/standards/necb/NECB2011/data/systems_including_sys5.json +588 -0
  122. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_namer.rb +489 -0
  123. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_1_single_speed.rb +16 -6
  124. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_2_and_5.rb +48 -5
  125. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_multi_speed.rb +2 -2
  126. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_single_speed.rb +35 -27
  127. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_4.rb +34 -23
  128. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_6.rb +8 -6
  129. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +43 -14
  130. data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +214 -25
  131. data/lib/openstudio-standards/standards/necb/NECB2011/system_fuels.rb +61 -1
  132. data/lib/openstudio-standards/standards/necb/NECB2015/data/heat_pumps.json +16 -0
  133. data/lib/openstudio-standards/standards/necb/NECB2015/data/heat_pumps_heating.json +8 -0
  134. data/lib/openstudio-standards/standards/necb/NECB2015/data/space_types.json +636 -636
  135. data/lib/openstudio-standards/standards/necb/NECB2015/data/unitary_acs.json +38 -38
  136. data/lib/openstudio-standards/standards/necb/NECB2015/hvac_systems.rb +15 -6
  137. data/lib/openstudio-standards/standards/necb/NECB2017/data/space_types.json +636 -636
  138. data/lib/openstudio-standards/standards/necb/NECB2020/data/chillers.json +71 -71
  139. data/lib/openstudio-standards/standards/necb/NECB2020/data/heat_pumps.json +20 -0
  140. data/lib/openstudio-standards/standards/necb/NECB2020/data/heat_pumps_heating.json +10 -0
  141. data/lib/openstudio-standards/standards/necb/README.md +343 -0
  142. data/lib/openstudio-standards/standards/necb/common/btap_data.rb +190 -28
  143. data/lib/openstudio-standards/standards/necb/common/btap_datapoint.rb +14 -5
  144. data/lib/openstudio-standards/standards/necb/common/eccc_electric_grid_intensity_20250311.csv +14 -0
  145. data/lib/openstudio-standards/standards/necb/common/nir_gas_grid_intensity_20250311.csv +14 -0
  146. data/lib/openstudio-standards/standards/necb/common/system_types.yaml +0 -0
  147. data/lib/openstudio-standards/utilities/logging.rb +18 -14
  148. data/lib/openstudio-standards/utilities/simulation.rb +3 -2
  149. data/lib/openstudio-standards/version.rb +1 -1
  150. data/lib/openstudio-standards/weather/modify.rb +2 -2
  151. data/lib/openstudio-standards.rb +12 -0
  152. metadata +56 -3
@@ -0,0 +1,547 @@
1
+ class BTAPCosting
2
+
3
+ def cost_audit_nv(model:, prototype_creator:)
4
+ @costing_report['ventilation'][:natural_ventilation] = []
5
+ #TODO: expected results file will be updated once labour cost for zn controller, sensor, and usb are updated in costing database
6
+
7
+ nv_total_cost = 0.0
8
+ nv_total_cost_tz = 0.0
9
+ nv_total_cost_ahu = 0.0
10
+
11
+ nv_airloop_vertical_conduit_hash = {}
12
+ nv_airloop_vertical_conduit_wiring_hash = {}
13
+ nv_airloop_vertical_conduit_box_hash = {}
14
+ nv_airloop_roof_conduit_hash = {}
15
+ nv_airloop_roof_wiring_hash = {}
16
+ nv_airloop_roof_box_hash = {}
17
+ nv_airloop_controller_hash = {}
18
+
19
+ #-----------------------------------------------------------------------------------------------------------------
20
+ ##### Get number of stories and nominal floor to floor height.
21
+ ##### These inputs are required for the calculation of the length of conduit for each AirLoopHVAC
22
+ ##### if any thermal zone served by that AirLoopHVAC has the potential for NV.
23
+ util_dist, ht_roof, nominal_flr2flr_height_ft, horizontal_dist, standards_number_of_stories, mechRmInBsmt = getGeometryData(model, prototype_creator)
24
+
25
+ #-----------------------------------------------------------------------------------------------------------------
26
+ ##### Find which airloop serves the thermal zone
27
+ thermal_zones_airloop_hash = {}
28
+ model.getAirLoopHVACs.sort.each do |air_loop|
29
+ # puts air_loop.name().to_s
30
+ air_loop.thermalZones.sort.each do |thermal_zone|
31
+ # puts thermal_zone.name().to_s
32
+ thermal_zones_airloop_hash[thermal_zone.name.to_s] = air_loop.name.to_s
33
+ end
34
+ end
35
+ # puts "thermal_zones_airloop_hash is #{thermal_zones_airloop_hash}"
36
+
37
+ #-----------------------------------------------------------------------------------------------------------------
38
+ ##### Loop through ZoneHVACEquipmentLists to see which thermal zone(s) has(have) been set to use NV where applicable.
39
+ model.getZoneHVACEquipmentLists.sort.each do |zone_hvac_equipment_list|
40
+ # puts "zone_hvac_equipment_list.name is #{zone_hvac_equipment_list.name}"
41
+
42
+ nv_exist = 0.0 #this variable is to check the thermal zone has been set to use NV where applicable. (1.0: NV is allowed; 0.0: NV is not allowed)
43
+
44
+ ### Loop through ZoneHVACEquipmentLists to see which thermal zone(s) has(have) ZoneVentilationWindandStackOpenArea
45
+ hvac_equipment = zone_hvac_equipment_list.equipment
46
+ for i in 0..hvac_equipment.length()
47
+ unless hvac_equipment[i].nil?
48
+ if hvac_equipment[i].to_ZoneVentilationWindandStackOpenArea.is_initialized
49
+ nv_exist = 1.0 #this means that the thermal zone has NV.
50
+ end
51
+ end
52
+ end
53
+ # puts "Is NV allowed? #{nv_exist}"
54
+
55
+ ### Loop through thermal zone's spaces to count how many spaces of them have windows to exterior
56
+ if nv_exist == 1.0
57
+ tags = ['ventilation', 'natural_ventilation']
58
+ thermal_zone = zone_hvac_equipment_list.thermalZone
59
+ thermal_zone_name = thermal_zone.name
60
+ thermal_zone_multiplier = thermal_zone.multiplier()
61
+ # puts "thermal_zone_name is #{thermal_zone.name}"
62
+
63
+ ##### Find which airloop serves the thermal zone
64
+ thermal_zone_sys = thermal_zones_airloop_hash[thermal_zone_name.to_s]
65
+ # puts "thermal_zone_sys is #{thermal_zone_sys}"
66
+
67
+ if !thermal_zone_sys.nil?
68
+
69
+ ################################################## Step I: costing for each thermal zone ############################################################
70
+ ##### costing for each thermal zone: natural ventilation controller -------------------------------------------------------------------------------------------------------------------
71
+ quantity_tz_nv_controller = 1.0 * thermal_zone_multiplier
72
+ # puts "quantity_tz_nv_controller is #{quantity_tz_nv_controller}"
73
+ search_tz_nv_controller = {
74
+ row_id_1: 'nat_vent_control',
75
+ row_id_2: 1537
76
+ }
77
+ sheet_name = 'materials_hvac'
78
+ column_1 = 'Material'
79
+ column_2 = 'material_id'
80
+ nv_costing_tz_nv_controller = assembly_cost(cost_info:search_tz_nv_controller,
81
+ sheet_name:sheet_name,
82
+ column_1:column_1,
83
+ column_2:column_2,
84
+ quantity: quantity_tz_nv_controller,
85
+ tags: tags)
86
+ # puts "quantity_tz_nv_controller is #{quantity_tz_nv_controller}"
87
+ # puts "nv_costing_tz_nv_controller is #{nv_costing_tz_nv_controller}"
88
+
89
+ ##### costing for each thermal zone: natural ventilation sensor -------------------------------------------------------------------------------------------------------------------
90
+ quantity_tz_nv_sensor = 1.0 * thermal_zone_multiplier
91
+ search_tz_nv_sensor = {
92
+ row_id_1: 'nat_vent_sensor',
93
+ row_id_2: 1538
94
+ }
95
+ sheet_name = 'materials_hvac'
96
+ column_1 = 'Material'
97
+ column_2 = 'material_id'
98
+ nv_costing_tz_nv_sensor = assembly_cost(cost_info:search_tz_nv_sensor,
99
+ sheet_name:sheet_name,
100
+ column_1:column_1,
101
+ column_2:column_2,
102
+ quantity: quantity_tz_nv_sensor,
103
+ tags: tags)
104
+ # puts "quantity_tz_nv_sensor is #{quantity_tz_nv_sensor}"
105
+ # puts "nv_costing_tz_nv_sensor is #{nv_costing_tz_nv_sensor}"
106
+
107
+ ##### costing for each thermal zone: natural ventilation USB -------------------------------------------------------------------------------------------------------------------
108
+ quantity_tz_nv_usb = 1.0 * thermal_zone_multiplier
109
+ search_tz_nv_usb = {
110
+ row_id_1: 'nat_vent_usb',
111
+ row_id_2: 1539
112
+ }
113
+ sheet_name = 'materials_hvac'
114
+ column_1 = 'Material'
115
+ column_2 = 'material_id'
116
+ nv_costing_tz_nv_usb = assembly_cost(cost_info:search_tz_nv_usb,
117
+ sheet_name:sheet_name,
118
+ column_1:column_1,
119
+ column_2:column_2,
120
+ quantity: quantity_tz_nv_usb,
121
+ tags: tags)
122
+ # puts "quantity_tz_nv_usb is #{quantity_tz_nv_usb}"
123
+ # puts "nv_costing_tz_nv_usb is #{nv_costing_tz_nv_usb}"
124
+
125
+ ##### costing for each thermal zone: Tin_sensor_wiring -------------------------------------------------------------------------------------------------------------------
126
+ # Note: assuming distance of 30 ft to each thermal zone per floor
127
+ # for each outdoor sensor (Tout and wind speed) and
128
+ # Tin sensor to the natural ventilation controller,
129
+ # total wiring is 90 ft in below equation.
130
+ quantity_tz_Tin_sensor_wiring = (90.0/100.0) * thermal_zone_multiplier #unit: CLF (hundred linear feet)
131
+ search_tz_Tin_sensor_wiring = {
132
+ row_id_1: 'CLF',
133
+ row_id_2: 10
134
+ }
135
+ sheet_name = 'materials_lighting'
136
+ column_1 = 'unit'
137
+ column_2 = 'lighting_type_id'
138
+ nv_costing_tz_Tin_sensor_wiring = assembly_cost(cost_info:search_tz_Tin_sensor_wiring,
139
+ sheet_name:sheet_name,
140
+ column_1:column_1,
141
+ column_2:column_2,
142
+ quantity: quantity_tz_Tin_sensor_wiring,
143
+ tags: tags)
144
+ # puts "quantity_tz_Tin_sensor_wiring is #{quantity_tz_Tin_sensor_wiring}"
145
+ # puts "nv_costing_tz_Tin_sensor_wiring is #{nv_costing_tz_Tin_sensor_wiring}"
146
+
147
+ ##### costing for each thermal zone: PVC_conduit -------------------------------------------------------------------------------------------------------------------
148
+ quantity_tz_Tin_sensor_conduit = 2.0 * 30.0 * thermal_zone_multiplier #unit: LF (linear feet)
149
+ search_tz_Tin_sensor_conduit = {
150
+ row_id_1: 'LF',
151
+ row_id_2: 17
152
+ }
153
+ sheet_name = 'materials_lighting'
154
+ column_1 = 'unit'
155
+ column_2 = 'lighting_type_id'
156
+ nv_costing_tz_Tin_sensor_conduit = assembly_cost(cost_info:search_tz_Tin_sensor_conduit,
157
+ sheet_name:sheet_name,
158
+ column_1:column_1,
159
+ column_2:column_2,
160
+ quantity: quantity_tz_Tin_sensor_conduit,
161
+ tags: tags)
162
+ # puts "quantity_tz_Tin_sensor_conduit is #{quantity_tz_Tin_sensor_conduit}"
163
+ # puts "nv_costing_tz_Tin_sensor_conduit is #{nv_costing_tz_Tin_sensor_conduit}"
164
+
165
+ ##### costing for each thermal zone: junction box -------------------------------------------------------------------------------------------------------------------
166
+ quantity_tz_Tin_sensor_box = 1.0 * thermal_zone_multiplier #unit: Ea
167
+ search_tz_Tin_sensor_box = {
168
+ row_id_1: 'Ea',
169
+ row_id_2: 14
170
+ }
171
+ sheet_name = 'materials_lighting'
172
+ column_1 = 'unit'
173
+ column_2 = 'lighting_type_id'
174
+ nv_costing_tz_Tin_sensor_box = assembly_cost(cost_info:search_tz_Tin_sensor_box,
175
+ sheet_name:sheet_name,
176
+ column_1:column_1,
177
+ column_2:column_2,
178
+ quantity: quantity_tz_Tin_sensor_box,
179
+ tags: tags)
180
+ # puts "quantity_tz_Tin_sensor_box is #{quantity_tz_Tin_sensor_box}"
181
+ # puts "nv_costing_tz_Tin_sensor_box is #{nv_costing_tz_Tin_sensor_box}"
182
+
183
+ ##### costing for each thermal zone: duct_damper_motor -------------------------------------------------------------------------------------------------------------------
184
+ # calculate how many dampers are needed, depending on the system type
185
+ nv_a = ['sys_1', 'sys_2', 'sys_3', 'sys_4', 'sys_5', 'sys_7']
186
+ nv_b = ['sys_6']
187
+ nv_c = thermal_zone_sys
188
+ if nv_a.any? { |s| nv_c.include? s}
189
+ damper_mult = 1.0
190
+ elsif nv_b.any? { |s| nv_c.include? s}
191
+ damper_mult = 2.0
192
+ end
193
+ # puts "damper_mult is #{damper_mult}"
194
+
195
+ quantity_tz_duct_damper_motor = 1.0 * damper_mult * thermal_zone_multiplier #unit: Ea
196
+ search_tz_duct_damper_motor = {
197
+ row_id_1: 'duct_damper_motor',
198
+ row_id_2: 6
199
+ }
200
+ sheet_name = 'materials_hvac'
201
+ column_1 = 'Material'
202
+ column_2 = 'Size'
203
+ nv_costing_tz_duct_damper_motor = assembly_cost(cost_info:search_tz_duct_damper_motor,
204
+ sheet_name:sheet_name,
205
+ column_1:column_1,
206
+ column_2:column_2,
207
+ quantity: quantity_tz_duct_damper_motor,
208
+ tags: tags)
209
+ # puts "quantity_tz_duct_damper_motor is #{quantity_tz_duct_damper_motor}"
210
+ # puts "nv_costing_tz_duct_damper_motor is #{nv_costing_tz_duct_damper_motor}"
211
+
212
+ ##### costing for each thermal zone: duct_damper_wiring -------------------------------------------------------------------------------------------------------------------
213
+ quantity_tz_duct_damper_wiring = (30.0/100.0) * damper_mult * thermal_zone_multiplier #unit: CLF
214
+ search_tz_duct_damper_wiring = {
215
+ row_id_1: 'CLF',
216
+ row_id_2: 10
217
+ }
218
+ sheet_name = 'materials_lighting'
219
+ column_1 = 'unit'
220
+ column_2 = 'lighting_type_id'
221
+ nv_costing_tz_duct_damper_wiring = assembly_cost(cost_info:search_tz_duct_damper_wiring,
222
+ sheet_name:sheet_name,
223
+ column_1:column_1,
224
+ column_2:column_2,
225
+ quantity: quantity_tz_duct_damper_wiring,
226
+ tags: tags)
227
+ # puts "quantity_tz_duct_damper_wiring is #{quantity_tz_duct_damper_wiring}"
228
+ # puts "nv_costing_tz_duct_damper_wiring is #{nv_costing_tz_duct_damper_wiring}"
229
+
230
+ ##### costing for each thermal zone: duct_damper_conduit -------------------------------------------------------------------------------------------------------------------
231
+ quantity_tz_duct_damper_conduit = 30.0 * damper_mult * thermal_zone_multiplier #unit: CLF
232
+ search_tz_duct_damper_conduit = {
233
+ row_id_1: 'LF',
234
+ row_id_2: 17
235
+ }
236
+ sheet_name = 'materials_lighting'
237
+ column_1 = 'unit'
238
+ column_2 = 'lighting_type_id'
239
+ nv_costing_tz_duct_damper_conduit = assembly_cost(cost_info:search_tz_duct_damper_conduit,
240
+ sheet_name:sheet_name,
241
+ column_1:column_1,
242
+ column_2:column_2,
243
+ quantity: quantity_tz_duct_damper_conduit,
244
+ tags: tags)
245
+ # puts "quantity_tz_duct_damper_conduit is #{quantity_tz_duct_damper_conduit}"
246
+ # puts "nv_costing_tz_duct_damper_conduit is #{nv_costing_tz_duct_damper_conduit}"
247
+
248
+ ##### costing for each thermal zone: duct_damper_box -------------------------------------------------------------------------------------------------------------------
249
+ quantity_tz_duct_damper_box = 1.0 * damper_mult * thermal_zone_multiplier #unit: CLF
250
+ search_tz_duct_damper_box = {
251
+ row_id_1: 'Ea',
252
+ row_id_2: 14
253
+ }
254
+ sheet_name = 'materials_lighting'
255
+ column_1 = 'unit'
256
+ column_2 = 'lighting_type_id'
257
+ nv_costing_tz_duct_damper_box = assembly_cost(cost_info:search_tz_duct_damper_box,
258
+ sheet_name:sheet_name,
259
+ column_1:column_1,
260
+ column_2:column_2,
261
+ quantity: quantity_tz_duct_damper_box,
262
+ tags: tags)
263
+ # puts "quantity_tz_duct_damper_box is #{quantity_tz_duct_damper_box}"
264
+ # puts "nv_costing_tz_duct_damper_box is #{nv_costing_tz_duct_damper_box}"
265
+
266
+ ################################################## Step II: costing for each AirLoopHVAC - Vertical Conduit ############################################################
267
+ ##### Note: This is completed twice for each AirLoopHVAC:
268
+ # (1) for the wiring and conduit to the rooftop AHU
269
+ # (2) for the wiring and conduit to the rooftop outdoor air temperature and wind speed sensors
270
+ ##### costing for each AirLoopHVAC-VerticalConduit: a single conduit runs the entire height of the building -------------------------------------------------------------------------------------------------------------------
271
+ quantity_nv_vertical_conduit = 2.0 * nominal_flr2flr_height_ft * standards_number_of_stories
272
+ search_nv_vertical_conduit = {
273
+ row_id_1: 'LF',
274
+ row_id_2: 13
275
+ }
276
+ sheet_name = 'materials_lighting'
277
+ column_1 = 'unit'
278
+ column_2 = 'lighting_type_id'
279
+ if nv_airloop_vertical_conduit_hash.key?(thermal_zone_sys.to_s) == false
280
+ nv_costing_vertical_conduit = assembly_cost(cost_info:search_nv_vertical_conduit,
281
+ sheet_name:sheet_name,
282
+ column_1:column_1,
283
+ column_2:column_2,
284
+ quantity: quantity_nv_vertical_conduit,
285
+ tags: tags)
286
+ nv_airloop_vertical_conduit_hash[thermal_zone_sys.to_s] = nv_costing_vertical_conduit
287
+ else
288
+ nv_costing_vertical_conduit = 0.0
289
+ end
290
+ # puts "quantity_nv_vertical_conduit is #{quantity_nv_vertical_conduit}"
291
+ # puts "nv_costing_vertical_conduit is #{nv_costing_vertical_conduit}"
292
+
293
+ ##### costing for each AirLoopHVAC-VerticalConduit: wiring -------------------------------------------------------------------------------------------------------------------
294
+ quantity_nv_vertical_conduit_wiring = 2.0 * nominal_flr2flr_height_ft * standards_number_of_stories / 100.0
295
+ search_nv_vertical_conduit_wiring = {
296
+ row_id_1: 'CLF',
297
+ row_id_2: 10
298
+ }
299
+ sheet_name = 'materials_lighting'
300
+ column_1 = 'unit'
301
+ column_2 = 'lighting_type_id'
302
+ if nv_airloop_vertical_conduit_wiring_hash.key?(thermal_zone_sys.to_s) == false
303
+ nv_costing_vertical_conduit_wiring = assembly_cost(cost_info:search_nv_vertical_conduit_wiring,
304
+ sheet_name:sheet_name,
305
+ column_1:column_1,
306
+ column_2:column_2,
307
+ quantity: quantity_nv_vertical_conduit_wiring,
308
+ tags: tags)
309
+ nv_airloop_vertical_conduit_wiring_hash[thermal_zone_sys.to_s] = nv_costing_vertical_conduit_wiring
310
+ else
311
+ nv_costing_vertical_conduit_wiring = 0.0
312
+ end
313
+ # puts "quantity_nv_vertical_conduit_wiring is #{quantity_nv_vertical_conduit_wiring}"
314
+ # puts "nv_costing_vertical_conduit_wiring is #{nv_costing_vertical_conduit_wiring}"
315
+
316
+ ##### costing for each AirLoopHVAC-VerticalConduit: box -------------------------------------------------------------------------------------------------------------------
317
+ quantity_nv_vertical_conduit_box = 2.0 * standards_number_of_stories
318
+ search_nv_vertical_conduit_box = {
319
+ row_id_1: 'Ea',
320
+ row_id_2: 14
321
+ }
322
+ sheet_name = 'materials_lighting'
323
+ column_1 = 'unit'
324
+ column_2 = 'lighting_type_id'
325
+ if nv_airloop_vertical_conduit_box_hash.key?(thermal_zone_sys.to_s) == false
326
+ nv_costing_vertical_conduit_box = assembly_cost(cost_info:search_nv_vertical_conduit_box,
327
+ sheet_name:sheet_name,
328
+ column_1:column_1,
329
+ column_2:column_2,
330
+ quantity: quantity_nv_vertical_conduit_box,
331
+ tags: tags)
332
+ nv_airloop_vertical_conduit_box_hash[thermal_zone_sys.to_s] = nv_costing_vertical_conduit_box
333
+ else
334
+ nv_costing_vertical_conduit_box = 0.0
335
+ end
336
+ # puts "quantity_nv_vertical_conduit_box is #{quantity_nv_vertical_conduit_box}"
337
+ # puts "nv_costing_vertical_conduit_box is #{nv_costing_vertical_conduit_box}"
338
+
339
+ ################################################## Step III: costing for each AirLoopHVAC - Roof ############################################################
340
+ ##### costing for each AirLoopHVAC-Roof: conduit -------------------------------------------------------------------------------------------------------------------
341
+ quantity_nv_roof_conduit = 20.0
342
+ search_nv_roof_conduit = {
343
+ row_id_1: 'LF',
344
+ row_id_2: 13
345
+ }
346
+ sheet_name = 'materials_lighting'
347
+ column_1 = 'unit'
348
+ column_2 = 'lighting_type_id'
349
+ if nv_airloop_roof_conduit_hash.key?(thermal_zone_sys.to_s) == false
350
+ nv_costing_roof_conduit = assembly_cost(cost_info:search_nv_roof_conduit,
351
+ sheet_name:sheet_name,
352
+ column_1:column_1,
353
+ column_2:column_2,
354
+ quantity: quantity_nv_roof_conduit,
355
+ tags: tags)
356
+ nv_airloop_roof_conduit_hash[thermal_zone_sys.to_s] = nv_costing_roof_conduit
357
+ else
358
+ nv_costing_roof_conduit = 0.0
359
+ end
360
+ # puts "quantity_nv_roof_conduit is #{quantity_nv_roof_conduit}"
361
+ # puts "nv_costing_roof_conduit is #{nv_costing_roof_conduit}"
362
+
363
+ ##### costing for each AirLoopHVAC-Roof: wiring -------------------------------------------------------------------------------------------------------------------
364
+ quantity_nv_roof_wiring = 20.0 / 100.0
365
+ search_nv_roof_wiring = {
366
+ row_id_1: 'CLF',
367
+ row_id_2: 10
368
+ }
369
+ sheet_name = 'materials_lighting'
370
+ column_1 = 'unit'
371
+ column_2 = 'lighting_type_id'
372
+ if nv_airloop_roof_wiring_hash.key?(thermal_zone_sys.to_s) == false
373
+ nv_costing_roof_wiring = assembly_cost(cost_info:search_nv_roof_wiring,
374
+ sheet_name:sheet_name,
375
+ column_1:column_1,
376
+ column_2:column_2,
377
+ quantity: quantity_nv_roof_wiring,
378
+ tags: tags)
379
+ nv_airloop_roof_wiring_hash[thermal_zone_sys.to_s] = nv_costing_roof_wiring
380
+ else
381
+ nv_costing_roof_wiring = 0.0
382
+ end
383
+ # puts "quantity_nv_roof_wiring is #{quantity_nv_roof_wiring}"
384
+ # puts "nv_costing_roof_wiring is #{nv_costing_roof_wiring}"
385
+
386
+ ##### costing for each AirLoopHVAC-Roof: box -------------------------------------------------------------------------------------------------------------------
387
+ quantity_nv_roof_box = 1.0
388
+ search_nv_roof_box = {
389
+ row_id_1: 'Ea',
390
+ row_id_2: 14
391
+ }
392
+ sheet_name = 'materials_lighting'
393
+ column_1 = 'unit'
394
+ column_2 = 'lighting_type_id'
395
+ if nv_airloop_roof_box_hash.key?(thermal_zone_sys.to_s) == false
396
+ nv_costing_roof_box = assembly_cost(cost_info:search_nv_roof_box,
397
+ sheet_name:sheet_name,
398
+ column_1:column_1,
399
+ column_2:column_2,
400
+ quantity: quantity_nv_roof_box,
401
+ tags: tags)
402
+ nv_airloop_roof_box_hash[thermal_zone_sys.to_s] = nv_costing_roof_box
403
+ else
404
+ nv_costing_roof_box = 0.0
405
+ end
406
+ # puts "quantity_nv_roof_box is #{quantity_nv_roof_box}"
407
+ # puts "nv_costing_roof_box is #{nv_costing_roof_box}"
408
+
409
+ ################################################## Step IV: costing for each AirLoopHVAC - Controller ############################################################
410
+ quantity_nv_ahu_controller = 1.0
411
+ search_nv_ahu_controller = {
412
+ row_id_1: 'Ea',
413
+ row_id_2: 400
414
+ }
415
+ sheet_name = 'materials_lighting'
416
+ column_1 = 'unit'
417
+ column_2 = 'lighting_type_id'
418
+ if nv_airloop_controller_hash.key?(thermal_zone_sys.to_s) == false
419
+ nv_costing_ahu_controller = assembly_cost(cost_info:search_nv_ahu_controller,
420
+ sheet_name:sheet_name,
421
+ column_1:column_1,
422
+ column_2:column_2,
423
+ quantity: quantity_nv_ahu_controller,
424
+ tags: tags)
425
+ nv_airloop_controller_hash[thermal_zone_sys.to_s] = nv_costing_ahu_controller
426
+ else
427
+ nv_costing_ahu_controller = 0.0
428
+ end
429
+ # puts "quantity_nv_ahu_controller is #{quantity_nv_ahu_controller}"
430
+ # puts "nv_costing_ahu_controller is #{nv_costing_ahu_controller}"
431
+
432
+ ################################################## Step V: costing for each thermal zone (total); also all previous thermal zones including current thermal zone ############################################################
433
+ costing_for_each_ThermalZone = nv_costing_tz_nv_controller +
434
+ nv_costing_tz_nv_sensor +
435
+ nv_costing_tz_nv_usb +
436
+ nv_costing_tz_Tin_sensor_wiring +
437
+ nv_costing_tz_Tin_sensor_conduit +
438
+ nv_costing_tz_Tin_sensor_box +
439
+ nv_costing_tz_duct_damper_motor +
440
+ nv_costing_tz_duct_damper_wiring +
441
+ nv_costing_tz_duct_damper_conduit +
442
+ nv_costing_tz_duct_damper_box
443
+ # puts "costing_for_each_ThermalZone is #{costing_for_each_ThermalZone}"
444
+ nv_total_cost_tz += costing_for_each_ThermalZone
445
+
446
+ ################################################## Step VI: costing for each AirLoopHVAC - Total ############################################################
447
+ costing_for_each_AirLoopHVAC = nv_costing_vertical_conduit +
448
+ nv_costing_vertical_conduit_wiring +
449
+ nv_costing_vertical_conduit_box +
450
+ nv_costing_roof_conduit +
451
+ nv_costing_roof_wiring +
452
+ nv_costing_roof_box +
453
+ nv_costing_ahu_controller
454
+
455
+ ##### Gather information for reporting
456
+ @costing_report['ventilation'][:natural_ventilation] << {
457
+ zone: thermal_zone_name.to_s,
458
+ ahu_serves_the_zone: thermal_zone_sys,
459
+ costing_for_the_zone: costing_for_each_ThermalZone,
460
+ costing_for_the_ahu: costing_for_each_AirLoopHVAC
461
+ }
462
+ ########################################################################################################################################################
463
+ end #if !thermal_zone_sys.nil?
464
+ end #if nv_exist == 1.0
465
+ end #model.getZoneHVACEquipmentLists.sort.each do |zone_hvac_equipment_list|
466
+
467
+ ########################################################################################################################################################
468
+ # costing for all AirLoopHVACs if they serve at least one thermal zone with the potential for using NV
469
+ nv_airloop_vertical_conduit_hash.each do |k, v|
470
+ nv_total_cost_ahu += v
471
+ end
472
+ nv_airloop_vertical_conduit_wiring_hash.each do |k, v|
473
+ nv_total_cost_ahu += v
474
+ end
475
+ nv_airloop_vertical_conduit_box_hash.each do |k, v|
476
+ nv_total_cost_ahu += v
477
+ end
478
+ nv_airloop_roof_conduit_hash.each do |k, v|
479
+ nv_total_cost_ahu += v
480
+ end
481
+ nv_airloop_roof_wiring_hash.each do |k, v|
482
+ nv_total_cost_ahu += v
483
+ end
484
+ nv_airloop_roof_box_hash.each do |k, v|
485
+ nv_total_cost_ahu += v
486
+ end
487
+ nv_airloop_controller_hash.each do |k, v|
488
+ nv_total_cost_ahu += v
489
+ end
490
+ # puts "nv_total_cost_ahu is #{nv_total_cost_ahu}"
491
+
492
+ ########################################################################################################################################################
493
+ ##### costing for the roof-top outdoor air temperature sensor and wind speed sensor
494
+ if nv_total_cost_tz > 0.0
495
+ tags = ['ventilation', 'natural_ventilation']
496
+ ### roof-top outdoor air temperature sensor ----------------------------------------------------------------------------------------
497
+ quantity_nv_rooftop_sensor_Tout = 1.0
498
+ search_nv_rooftop_sensor_Tout = {
499
+ row_id_1: 'Temperaturesensor',
500
+ row_id_2: 1326
501
+ }
502
+ sheet_name = 'materials_hvac'
503
+ column_1 = 'Material'
504
+ column_2 = 'material_id'
505
+ nv_costing_nv_rooftop_sensor_Tout = assembly_cost(cost_info:search_nv_rooftop_sensor_Tout,
506
+ sheet_name:sheet_name,
507
+ column_1:column_1,
508
+ column_2:column_2,
509
+ quantity: quantity_nv_rooftop_sensor_Tout,
510
+ tags: tags)
511
+ # puts "nv_costing_nv_rooftop_sensor_Tout is #{nv_costing_nv_rooftop_sensor_Tout}"
512
+
513
+ ### roof-top wind speed sensor -----------------------------------------------------------------------------------------------------
514
+ quantity_nv_rooftop_sensor_wind_speed = 1.0
515
+ search_nv_rooftop_sensor_wind_speed = {
516
+ row_id_1: 'Ea',
517
+ row_id_2: 407
518
+ }
519
+ sheet_name = 'materials_lighting'
520
+ column_1 = 'unit'
521
+ column_2 = 'lighting_type_id'
522
+ nv_costing_nv_rooftop_sensor_wind_speed = assembly_cost(cost_info:search_nv_rooftop_sensor_wind_speed,
523
+ sheet_name:sheet_name,
524
+ column_1:column_1,
525
+ column_2:column_2,
526
+ quantity: quantity_nv_rooftop_sensor_wind_speed,
527
+ tags: tags)
528
+ # puts "nv_costing_nv_rooftop_sensor_wind_speed is #{nv_costing_nv_rooftop_sensor_wind_speed}"
529
+
530
+ ### roof-top sensors -----------------------------------------------------------------------------------------------------
531
+ nv_total_cost_rooftop_sensors = nv_costing_nv_rooftop_sensor_Tout + nv_costing_nv_rooftop_sensor_wind_speed
532
+ ########################################################################################################################################################
533
+ nv_total_cost = nv_total_cost_tz + nv_total_cost_ahu + nv_total_cost_rooftop_sensors
534
+ ##### Gather information for reporting
535
+ @costing_report['ventilation'][:natural_ventilation] << {
536
+ costing_for_rooftop_sensors: nv_total_cost_rooftop_sensors,
537
+ nv_total_cost: nv_total_cost
538
+ }
539
+ end
540
+
541
+ puts "\nNatural ventilation costing data successfully generated. Total NV costs: $#{nv_total_cost.round(2)}"
542
+
543
+ return nv_total_cost
544
+ end #def cost_audit_nv(model, prototype_creator)
545
+
546
+
547
+ end
@@ -0,0 +1,92 @@
1
+ require 'fileutils'
2
+ require 'parallel'
3
+ require 'open3'
4
+
5
+ TestOutputFolder = File.join(File.dirname(__FILE__), 'local_test_output')
6
+ ProcessorsUsed = (Parallel.processor_count * 4 / 5).floor
7
+ #ProcessorsUsed = 20
8
+
9
+ class String
10
+ # colorization
11
+ def colorize(color_code)
12
+ "\e[#{color_code}m#{self}\e[0m"
13
+ end
14
+
15
+ def red
16
+ colorize(31)
17
+ end
18
+
19
+ def green
20
+ colorize(32)
21
+ end
22
+
23
+ def yellow
24
+ colorize(33)
25
+ end
26
+
27
+ def blue
28
+ colorize(34)
29
+ end
30
+
31
+ def pink
32
+ colorize(35)
33
+ end
34
+
35
+ def light_blue
36
+ colorize(36)
37
+ end
38
+ end
39
+
40
+
41
+ def write_results(result, test_file)
42
+ test_file_output = File.join(TestOutputFolder, "#{File.basename(test_file)}_test_output.json")
43
+ File.delete(test_file_output) if File.exist?(test_file_output)
44
+ test_result = false
45
+ if result[2].success?
46
+ puts "PASSED: #{test_file}".green
47
+ return true
48
+ else
49
+ #store output for failed run.
50
+ output = {"test" => test_file,
51
+ "test_result" => test_result,
52
+ "output" => {
53
+ "status" => result[2],
54
+ "std_out" => result[0].split(/\r?\n/),
55
+ "std_err" => result[1].split(/\r?\n/)
56
+ }
57
+ }
58
+
59
+ #puts test_file_output
60
+ File.open(test_file_output, 'w') {|f| f.write(JSON.pretty_generate(output))}
61
+ puts "FAILED: #{test_file_output}".red
62
+ return false
63
+ end
64
+ end
65
+
66
+ class ParallelTests
67
+
68
+ def run(file_list)
69
+ did_all_tests_pass = true
70
+
71
+ @full_file_list = nil
72
+ FileUtils.rm_rf(TestOutputFolder)
73
+ FileUtils.mkpath(TestOutputFolder)
74
+
75
+ # load test files from file.
76
+ @full_file_list = file_list.shuffle
77
+
78
+ puts "Running #{@full_file_list.size} tests suites in parallel using #{ProcessorsUsed} of available cpus."
79
+ puts "To increase or decrease the ProcessorsUsed, please edit the test/test_run_all_locally.rb file."
80
+ timings_json = Hash.new()
81
+ Parallel.each_with_index(@full_file_list, in_threads: (ProcessorsUsed), progress: "Progress :") do |test_file, index|
82
+ file_name = test_file.gsub(/^.+(openstudio-standards\/test\/)/, '')
83
+ timings_json[file_name.to_s] = {}
84
+ timings_json[file_name.to_s]['start'] = Time.now.to_i
85
+ did_all_tests_pass = false unless write_results(Open3.capture3("bundle exec ruby #{test_file}"), test_file)
86
+ timings_json[file_name.to_s]['end'] = Time.now.to_i
87
+ timings_json[file_name.to_s]['total'] = timings_json[file_name.to_s]['end'] - timings_json[file_name.to_s]['start']
88
+ end
89
+
90
+ return did_all_tests_pass
91
+ end
92
+ end