openstudio-standards 0.8.3 → 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.
- checksums.yaml +4 -4
- data/lib/openstudio-standards/btap/costing/README.md +502 -0
- data/lib/openstudio-standards/btap/costing/btap_costing.rb +473 -0
- data/lib/openstudio-standards/btap/costing/btap_measure_helper.rb +359 -0
- data/lib/openstudio-standards/btap/costing/btap_workflow.rb +117 -0
- data/lib/openstudio-standards/btap/costing/common_paths.rb +78 -0
- data/lib/openstudio-standards/btap/costing/common_resources/ConstructionProperties.csv +52 -0
- data/lib/openstudio-standards/btap/costing/common_resources/Constructions.csv +37 -0
- data/lib/openstudio-standards/btap/costing/common_resources/construction_sets.csv +1270 -0
- data/lib/openstudio-standards/btap/costing/common_resources/constructions_glazing.csv +61 -0
- data/lib/openstudio-standards/btap/costing/common_resources/constructions_opaque.csv +2256 -0
- data/lib/openstudio-standards/btap/costing/common_resources/costs.csv +1904 -0
- data/lib/openstudio-standards/btap/costing/common_resources/costs_local_factors.csv +2315 -0
- data/lib/openstudio-standards/btap/costing/common_resources/hvac_vent_ahu.csv +925 -0
- data/lib/openstudio-standards/btap/costing/common_resources/lighting.csv +364 -0
- data/lib/openstudio-standards/btap/costing/common_resources/lighting_sets.csv +2667 -0
- data/lib/openstudio-standards/btap/costing/common_resources/locations.csv +75 -0
- data/lib/openstudio-standards/btap/costing/common_resources/materials_glazing.csv +35 -0
- data/lib/openstudio-standards/btap/costing/common_resources/materials_hvac.csv +1699 -0
- data/lib/openstudio-standards/btap/costing/common_resources/materials_lighting.csv +267 -0
- data/lib/openstudio-standards/btap/costing/common_resources/materials_opaque.csv +164 -0
- data/lib/openstudio-standards/btap/costing/copy_test_results_files_to_expected_results.rb +11 -0
- data/lib/openstudio-standards/btap/costing/cost_building_from_file.rb +136 -0
- data/lib/openstudio-standards/btap/costing/costing_database_wrapper.rb +177 -0
- data/lib/openstudio-standards/btap/costing/daylighting_sensor_control_costing.rb +353 -0
- data/lib/openstudio-standards/btap/costing/dcv_costing.rb +314 -0
- data/lib/openstudio-standards/btap/costing/dummy.epw +8768 -0
- data/lib/openstudio-standards/btap/costing/dummy.osm +5320 -0
- data/lib/openstudio-standards/btap/costing/envelope_costing.rb +284 -0
- data/lib/openstudio-standards/btap/costing/heating_cooling_costing.rb +2584 -0
- data/lib/openstudio-standards/btap/costing/led_lighting_costing.rb +155 -0
- data/lib/openstudio-standards/btap/costing/lighting_costing.rb +209 -0
- data/lib/openstudio-standards/btap/costing/mech_sizing.json +502 -0
- data/lib/openstudio-standards/btap/costing/neb_end_use_prices.csv +42 -0
- data/lib/openstudio-standards/btap/costing/necb_2011_spacetype_info.csv +225 -0
- data/lib/openstudio-standards/btap/costing/necb_reference_runs.csv +28705 -0
- data/lib/openstudio-standards/btap/costing/nv_costing.rb +547 -0
- data/lib/openstudio-standards/btap/costing/parallel_tests.rb +92 -0
- data/lib/openstudio-standards/btap/costing/pv_ground_costing.rb +687 -0
- data/lib/openstudio-standards/btap/costing/shw_costing.rb +705 -0
- data/lib/openstudio-standards/btap/costing/test_list.txt +17 -0
- data/lib/openstudio-standards/btap/costing/test_run_all_test_locally.rb +26 -0
- data/lib/openstudio-standards/btap/costing/test_run_costing_tests.rb +80 -0
- data/lib/openstudio-standards/btap/costing/ventilation_costing.rb +2616 -0
- data/lib/openstudio-standards/constructions/modify.rb +2 -1
- data/lib/openstudio-standards/standards/Standards.Model.rb +39 -9
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Model.rb +2 -2
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/ashrae_90_1_prm.UserData.rb +6 -1
- data/lib/openstudio-standards/standards/necb/BTAPPRE1980/btap_pre1980.rb +2 -27
- data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_3_and_8_single_speed.rb +68 -27
- data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_4.rb +64 -25
- data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_6.rb +9 -14
- data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +46 -20
- data/lib/openstudio-standards/standards/necb/NECB2011/autozone.rb +635 -248
- data/lib/openstudio-standards/standards/necb/NECB2011/data/constants.json +43 -7
- data/lib/openstudio-standards/standards/necb/NECB2011/data/fuel_type_sets.json +7 -1
- data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/HighriseApartmentMult.osm +14272 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/data/necb_2015_table_c1.json +1 -1
- data/lib/openstudio-standards/standards/necb/NECB2011/data/space_types.json +437 -437
- data/lib/openstudio-standards/standards/necb/NECB2011/data/systems.json +516 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/data/systems_including_sys5.json +588 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_namer.rb +489 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_1_single_speed.rb +16 -6
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_2_and_5.rb +48 -5
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_multi_speed.rb +2 -2
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_single_speed.rb +35 -27
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_4.rb +34 -23
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_6.rb +8 -6
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +42 -13
- data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +214 -25
- data/lib/openstudio-standards/standards/necb/NECB2011/system_fuels.rb +61 -1
- data/lib/openstudio-standards/standards/necb/NECB2015/data/space_types.json +636 -636
- data/lib/openstudio-standards/standards/necb/NECB2015/data/unitary_acs.json +38 -38
- data/lib/openstudio-standards/standards/necb/NECB2015/hvac_systems.rb +15 -6
- data/lib/openstudio-standards/standards/necb/NECB2017/data/space_types.json +636 -636
- data/lib/openstudio-standards/standards/necb/NECB2020/data/chillers.json +71 -71
- data/lib/openstudio-standards/standards/necb/README.md +343 -0
- data/lib/openstudio-standards/standards/necb/common/btap_data.rb +190 -28
- data/lib/openstudio-standards/standards/necb/common/btap_datapoint.rb +14 -5
- data/lib/openstudio-standards/standards/necb/common/eccc_electric_grid_intensity_20250311.csv +14 -0
- data/lib/openstudio-standards/standards/necb/common/nir_gas_grid_intensity_20250311.csv +14 -0
- data/lib/openstudio-standards/standards/necb/common/system_types.yaml +0 -0
- data/lib/openstudio-standards/utilities/logging.rb +18 -14
- data/lib/openstudio-standards/version.rb +1 -1
- data/lib/openstudio-standards/weather/modify.rb +2 -2
- data/lib/openstudio-standards.rb +12 -0
- metadata +53 -2
@@ -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
|