openstudio-standards 0.2.17.rc1 → 0.3.0
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/data/standards/OpenStudio_Standards-ashrae_90_1.xlsx +0 -0
- data/data/standards/openstudio_standards_duplicates_log.csv +5 -0
- data/lib/openstudio-standards/btap/btap_result.rb +138 -138
- data/lib/openstudio-standards/btap/economics.rb +58 -53
- data/lib/openstudio-standards/btap/envelope.rb +1 -1
- data/lib/openstudio-standards/btap/fileio.rb +12 -12
- data/lib/openstudio-standards/btap/measures.rb +63 -59
- data/lib/openstudio-standards/btap/vintagizer.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.exterior_lights.rb +7 -7
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.rb +5 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.ServiceWaterHeating.rb +8 -0
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.SizingSystem.rb +9 -3
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +53 -23
- data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +15 -1
- data/lib/openstudio-standards/standards/Standards.Construction.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.Model.rb +18 -18
- data/lib/openstudio-standards/standards/Standards.PlanarSurface.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.ThermalZone.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.WaterHeaterMixed.rb +5 -5
- data/lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb +3 -2
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +43 -40
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.ZoneHVACComponent.rb +2 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.entryways.json +19 -8
- data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.parking.json +13 -4
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.AirLoopHVAC.rb +11 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.AirLoopHVAC.rb +11 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirLoopHVAC.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Model.rb +9 -9
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlanarSurface.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlantLoop.rb +5 -1
- data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_6.rb +5 -1
- data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +8 -4
- data/lib/openstudio-standards/standards/necb/ECMS/nv.rb +8 -2
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +7 -3
- data/lib/openstudio-standards/standards/necb/NECB2011/qaqc/necb_qaqc.rb +4 -4
- data/lib/openstudio-standards/standards/necb/NECB2011/service_water_heating.rb +1 -1
- data/lib/openstudio-standards/standards/necb/NECB2020/service_water_heating.rb +1 -1
- data/lib/openstudio-standards/version.rb +1 -1
- data/lib/openstudio-standards/weather/Weather.Model.rb +5 -0
- metadata +4 -2
@@ -23,17 +23,17 @@ module BTAP
|
|
23
23
|
" AND ReportForString='Entire Facility' AND TableName='Annual and Peak Values - Natural Gas' AND RowName='NaturalGas:Facility'" +
|
24
24
|
" AND ColumnName='Natural Gas Maximum Value' AND Units='W'")
|
25
25
|
|
26
|
-
# Create hash to store all the collected data.
|
26
|
+
# Create hash to store all the collected data.
|
27
27
|
qaqc = {}
|
28
28
|
error_warning=[]
|
29
29
|
qaqc[:os_standards_revision] = OpenstudioStandards::git_revision
|
30
30
|
qaqc[:os_standards_version] = OpenstudioStandards::VERSION
|
31
|
-
# Store Building data.
|
31
|
+
# Store Building data.
|
32
32
|
qaqc[:building] = {}
|
33
33
|
qaqc[:building][:name] = model.building.get.name.get
|
34
34
|
qaqc[:building][:conditioned_floor_area_m2]=nil
|
35
35
|
unless model.building.get.conditionedFloorArea().empty?
|
36
|
-
qaqc[:building][:conditioned_floor_area_m2] = model.building.get.conditionedFloorArea().get
|
36
|
+
qaqc[:building][:conditioned_floor_area_m2] = model.building.get.conditionedFloorArea().get
|
37
37
|
else
|
38
38
|
error_warning << "model.building.get.conditionedFloorArea() is empty for #{model.building.get.name.get}"
|
39
39
|
end
|
@@ -50,7 +50,7 @@ module BTAP
|
|
50
50
|
qaqc[:geography][:country] = model.getWeatherFile.country
|
51
51
|
qaqc[:geography][:latitude] = model.getWeatherFile.latitude
|
52
52
|
qaqc[:geography][:longitude] = model.getWeatherFile.longitude
|
53
|
-
|
53
|
+
|
54
54
|
#Spacetype Breakdown
|
55
55
|
qaqc[:spacetype_area_breakdown]={}
|
56
56
|
model.getSpaceTypes.sort.each do |spaceType|
|
@@ -66,9 +66,9 @@ module BTAP
|
|
66
66
|
end
|
67
67
|
qaqc[:spacetype_area_breakdown][spaceType.name.get.gsub(/\s+/, "_").downcase.to_sym] = floor_area_si
|
68
68
|
end
|
69
|
-
|
70
|
-
|
71
|
-
|
69
|
+
|
70
|
+
|
71
|
+
|
72
72
|
#Economics Section
|
73
73
|
qaqc[:economics] = {}
|
74
74
|
costing_rownames = model.sqlFile().get().execAndReturnVectorOfString("SELECT RowName FROM TabularDataWithStrings WHERE ReportName='LEEDsummary' AND ReportForString='Entire Facility' AND TableName='EAp2-7. Energy Cost Summary' AND ColumnName='Total Energy Cost'")
|
@@ -83,11 +83,11 @@ module BTAP
|
|
83
83
|
when "Natural Gas"
|
84
84
|
qaqc[:economics][:natural_gas_cost] = model.sqlFile().get().execAndReturnFirstDouble("SELECT Value FROM TabularDataWithStrings WHERE ReportName='LEEDsummary' AND ReportForString='Entire Facility' AND TableName='EAp2-7. Energy Cost Summary' AND ColumnName='Total Energy Cost' AND RowName='#{rowname}'").get
|
85
85
|
qaqc[:economics][:natural_gas_cost_per_m2]=qaqc[:economics][:natural_gas_cost]/qaqc[:building][:conditioned_floor_area_m2] unless model.building.get.conditionedFloorArea().empty?
|
86
|
-
|
86
|
+
|
87
87
|
when "Additional"
|
88
88
|
qaqc[:economics][:additional_cost] = model.sqlFile().get().execAndReturnFirstDouble("SELECT Value FROM TabularDataWithStrings WHERE ReportName='LEEDsummary' AND ReportForString='Entire Facility' AND TableName='EAp2-7. Energy Cost Summary' AND ColumnName='Total Energy Cost' AND RowName='#{rowname}'").get
|
89
89
|
qaqc[:economics][:additional_cost_per_m2]=qaqc[:economics][:additional_cost]/qaqc[:building][:conditioned_floor_area_m2] unless model.building.get.conditionedFloorArea().empty?
|
90
|
-
|
90
|
+
|
91
91
|
when "Total"
|
92
92
|
qaqc[:economics][:total_cost] = model.sqlFile().get().execAndReturnFirstDouble("SELECT Value FROM TabularDataWithStrings WHERE ReportName='LEEDsummary' AND ReportForString='Entire Facility' AND TableName='EAp2-7. Energy Cost Summary' AND ColumnName='Total Energy Cost' AND RowName='#{rowname}'").get
|
93
93
|
qaqc[:economics][:total_cost_per_m2]=qaqc[:economics][:total_cost]/qaqc[:building][:conditioned_floor_area_m2] unless model.building.get.conditionedFloorArea().empty?
|
@@ -96,7 +96,7 @@ module BTAP
|
|
96
96
|
else
|
97
97
|
error_warning << "costing is unavailable because the sql statement is nil RowName FROM TabularDataWithStrings WHERE ReportName='LEEDsummary' AND ReportForString='Entire Facility' AND TableName='EAp2-7. Energy Cost Summary' AND ColumnName='Total Energy Cost'"
|
98
98
|
end
|
99
|
-
|
99
|
+
|
100
100
|
#Store end_use data
|
101
101
|
end_uses = [
|
102
102
|
'Heating',
|
@@ -112,18 +112,18 @@ module BTAP
|
|
112
112
|
'Heat Recovery',
|
113
113
|
'Water Systems',
|
114
114
|
'Refrigeration',
|
115
|
-
'Generators',
|
115
|
+
'Generators',
|
116
116
|
'Total End Uses'
|
117
117
|
]
|
118
|
-
|
119
|
-
fuels = [
|
120
|
-
['Electricity', 'GJ'],
|
121
|
-
['Natural Gas', 'GJ'] ,
|
118
|
+
|
119
|
+
fuels = [
|
120
|
+
['Electricity', 'GJ'],
|
121
|
+
['Natural Gas', 'GJ'] ,
|
122
122
|
['Additional Fuel', 'GJ'],
|
123
|
-
['District Cooling','GJ'],
|
124
|
-
['District Heating', 'GJ'],
|
123
|
+
['District Cooling','GJ'],
|
124
|
+
['District Heating', 'GJ'],
|
125
125
|
]
|
126
|
-
|
126
|
+
|
127
127
|
qaqc[:end_uses] = {}
|
128
128
|
qaqc[:end_uses_eui] = {}
|
129
129
|
end_uses.each do |use_type|
|
@@ -148,23 +148,23 @@ module BTAP
|
|
148
148
|
end
|
149
149
|
end
|
150
150
|
end
|
151
|
-
|
151
|
+
|
152
152
|
# Store Peak Data
|
153
153
|
qaqc[:meter_peaks] = {}
|
154
|
-
qaqc[:meter_peaks][:electric_w] = electric_peak.empty? ? "NA" : electric_peak.get
|
155
|
-
qaqc[:meter_peaks][:natural_gas_w] = natural_gas_peak.empty? ? "NA" : natural_gas_peak.get
|
156
|
-
|
157
|
-
|
154
|
+
qaqc[:meter_peaks][:electric_w] = electric_peak.empty? ? "NA" : electric_peak.get
|
155
|
+
qaqc[:meter_peaks][:natural_gas_w] = natural_gas_peak.empty? ? "NA" : natural_gas_peak.get
|
156
|
+
|
157
|
+
|
158
158
|
#Store unmet hour data
|
159
159
|
qaqc[:unmet_hours] = {}
|
160
160
|
qaqc[:unmet_hours][:cooling] = model.getFacility.hoursCoolingSetpointNotMet().get unless model.getFacility.hoursCoolingSetpointNotMet().empty?
|
161
161
|
qaqc[:unmet_hours][:heating] = model.getFacility.hoursHeatingSetpointNotMet().get unless model.getFacility.hoursHeatingSetpointNotMet().empty?
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
162
|
+
|
163
|
+
|
164
|
+
|
165
|
+
|
166
|
+
|
167
|
+
|
168
168
|
#puts "\n\n\n#{costing_rownames}\n\n\n"
|
169
169
|
#Padmassun's Code -- Tarrif end
|
170
170
|
|
@@ -174,23 +174,23 @@ module BTAP
|
|
174
174
|
qaqc[:service_water_heating][:total_nominal_occupancy]=-1
|
175
175
|
#qaqc[:service_water_heating][:total_nominal_occupancy]=model.sqlFile().get().execAndReturnVectorOfDouble("SELECT Value FROM TabularDataWithStrings WHERE ReportName='OutdoorAirSummary' AND ReportForString='Entire Facility' AND TableName='Average Outdoor Air During Occupied Hours' AND ColumnName='Nominal Number of Occupants'").get.inject(0, :+)
|
176
176
|
qaqc[:service_water_heating][:total_nominal_occupancy]=get_total_nominal_capacity(model)
|
177
|
-
|
177
|
+
|
178
178
|
qaqc[:service_water_heating][:electricity_per_year]=model.sqlFile().get().execAndReturnFirstDouble("SELECT Value FROM TabularDataWithStrings WHERE ReportName='AnnualBuildingUtilityPerformanceSummary' AND ReportForString='Entire Facility' AND TableName='End Uses' AND ColumnName='Electricity' AND RowName='Water Systems'")
|
179
179
|
qaqc[:service_water_heating][:electricity_per_year]= validate_optional(qaqc[:service_water_heating][:electricity_per_year], model, -1)
|
180
180
|
|
181
181
|
qaqc[:service_water_heating][:electricity_per_day]=qaqc[:service_water_heating][:electricity_per_year]/365.5
|
182
182
|
qaqc[:service_water_heating][:electricity_per_day_per_occupant]=qaqc[:service_water_heating][:electricity_per_day]/qaqc[:service_water_heating][:total_nominal_occupancy]
|
183
|
-
|
184
|
-
|
183
|
+
|
184
|
+
|
185
185
|
qaqc[:service_water_heating][:natural_gas_per_year]=model.sqlFile().get().execAndReturnFirstDouble("SELECT Value FROM TabularDataWithStrings WHERE ReportName='AnnualBuildingUtilityPerformanceSummary' AND ReportForString='Entire Facility' AND TableName='End Uses' AND ColumnName='Natural Gas' AND RowName='Water Systems'")
|
186
186
|
qaqc[:service_water_heating][:natural_gas_per_year]=validate_optional(qaqc[:service_water_heating][:natural_gas_per_year], model, -1)
|
187
187
|
|
188
188
|
qaqc[:service_water_heating][:additional_fuel_per_year]=model.sqlFile().get().execAndReturnFirstDouble("SELECT Value FROM TabularDataWithStrings WHERE ReportName='AnnualBuildingUtilityPerformanceSummary' AND ReportForString='Entire Facility' AND TableName='End Uses' AND ColumnName='Additional Fuel' AND RowName='Water Systems'")
|
189
189
|
qaqc[:service_water_heating][:additional_fuel_per_year] = validate_optional(qaqc[:service_water_heating][:additional_fuel_per_year], model, -1)
|
190
|
-
|
190
|
+
|
191
191
|
qaqc[:service_water_heating][:water_m3_per_year]=model.sqlFile().get().execAndReturnFirstDouble("SELECT Value FROM TabularDataWithStrings WHERE ReportName='AnnualBuildingUtilityPerformanceSummary' AND ReportForString='Entire Facility' AND TableName='End Uses' AND ColumnName='Water' AND RowName='Water Systems'")
|
192
192
|
qaqc[:service_water_heating][:water_m3_per_year]=validate_optional(qaqc[:service_water_heating][:water_m3_per_year], model, -1)
|
193
|
-
|
193
|
+
|
194
194
|
qaqc[:service_water_heating][:water_m3_per_day]=qaqc[:service_water_heating][:water_m3_per_year]/365.5
|
195
195
|
qaqc[:service_water_heating][:water_m3_per_day_per_occupant]=qaqc[:service_water_heating][:water_m3_per_day]/qaqc[:service_water_heating][:total_nominal_occupancy]
|
196
196
|
#puts qaqc[:service_water_heating][:total_nominal_occupancy]
|
@@ -198,7 +198,7 @@ module BTAP
|
|
198
198
|
|
199
199
|
#Store Envelope data.
|
200
200
|
qaqc[:envelope] = {}
|
201
|
-
|
201
|
+
|
202
202
|
qaqc[:envelope][:outdoor_walls_average_conductance_w_per_m2_k] = BTAP::Geometry::Surfaces::get_weighted_average_surface_conductance(outdoor_walls).round(4) if outdoor_walls.size > 0
|
203
203
|
qaqc[:envelope][:outdoor_roofs_average_conductance_w_per_m2_k] = BTAP::Geometry::Surfaces::get_weighted_average_surface_conductance(outdoor_roofs).round(4) if outdoor_roofs.size > 0
|
204
204
|
qaqc[:envelope][:outdoor_floors_average_conductance_w_per_m2_k] = BTAP::Geometry::Surfaces::get_weighted_average_surface_conductance(outdoor_floors).round(4) if outdoor_floors.size > 0
|
@@ -211,8 +211,8 @@ module BTAP
|
|
211
211
|
qaqc[:envelope][:overhead_doors_average_conductance_w_per_m2_k] = BTAP::Geometry::Surfaces::get_weighted_average_surface_conductance(overhead_doors).round(4) if overhead_doors.size > 0
|
212
212
|
qaqc[:envelope][:fdwr] = (BTAP::Geometry::get_fwdr(model) * 100.0).round(1)
|
213
213
|
qaqc[:envelope][:srr] = (BTAP::Geometry::get_srr(model) * 100.0).round(1)
|
214
|
-
|
215
|
-
|
214
|
+
|
215
|
+
|
216
216
|
qaqc[:envelope][:constructions] = {}
|
217
217
|
qaqc[:envelope][:constructions][:exterior_fenestration] = []
|
218
218
|
constructions = []
|
@@ -228,8 +228,8 @@ module BTAP
|
|
228
228
|
construction_info[:thermal_conductance_m2_w_per_k] = BTAP::Resources::Envelope::Constructions::get_conductance(construction).round(3)
|
229
229
|
construction_info[:solar_transmittance] = BTAP::Resources::Envelope::Constructions::get_shgc(model, construction).round(3)
|
230
230
|
construction_info[:visible_tranmittance] = BTAP::Resources::Envelope::Constructions::get_tvis(model,construction).round(3)
|
231
|
-
end
|
232
|
-
|
231
|
+
end
|
232
|
+
|
233
233
|
#Exterior
|
234
234
|
qaqc[:envelope][:constructions][:exterior_opaque] = []
|
235
235
|
constructions = []
|
@@ -246,7 +246,7 @@ module BTAP
|
|
246
246
|
construction_info[:net_area_m2] = construction.to_Construction.get.getNetArea.round(2)
|
247
247
|
construction_info[:solar_absorptance] = construction.to_Construction.get.layers[0].exteriorVisibleAbsorptance.get
|
248
248
|
end
|
249
|
-
|
249
|
+
|
250
250
|
#Ground
|
251
251
|
qaqc[:envelope][:constructions][:ground] = []
|
252
252
|
constructions = []
|
@@ -263,7 +263,7 @@ module BTAP
|
|
263
263
|
construction_info[:net_area_m2] = construction.to_Construction.get.getNetArea.round(2)
|
264
264
|
construction_info[:solar_absorptance] = construction.to_Construction.get.layers[0].exteriorVisibleAbsorptance.get
|
265
265
|
end
|
266
|
-
|
266
|
+
|
267
267
|
|
268
268
|
# Store Space data.
|
269
269
|
qaqc[:spaces] =[]
|
@@ -271,17 +271,17 @@ module BTAP
|
|
271
271
|
spaceinfo = {}
|
272
272
|
qaqc[:spaces] << spaceinfo
|
273
273
|
spaceinfo[:name] = space.name.get #name should be defined test
|
274
|
-
spaceinfo[:multiplier] = space.multiplier
|
274
|
+
spaceinfo[:multiplier] = space.multiplier
|
275
275
|
spaceinfo[:volume] = space.volume # should be greater than zero
|
276
|
-
spaceinfo[:exterior_wall_area] = space.exteriorWallArea # just for information.
|
277
|
-
spaceinfo[:space_type_name] = space.spaceType.get.name.get unless space.spaceType.empty? #should have a space types name defined.
|
276
|
+
spaceinfo[:exterior_wall_area] = space.exteriorWallArea # just for information.
|
277
|
+
spaceinfo[:space_type_name] = space.spaceType.get.name.get unless space.spaceType.empty? #should have a space types name defined.
|
278
278
|
spaceinfo[:thermal_zone] = space.thermalZone.get.name.get unless space.thermalZone.empty? # should be assigned a thermalzone name.
|
279
279
|
#puts space.name.get
|
280
280
|
#puts space.thermalZone.empty?
|
281
281
|
spaceinfo[:breathing_zone_outdoor_airflow_vbz] =-1
|
282
282
|
breathing_zone_outdoor_airflow_vbz= model.sqlFile().get().execAndReturnFirstDouble("SELECT Value FROM TabularDataWithStrings WHERE ReportName='Standard62.1Summary' AND ReportForString='Entire Facility' AND TableName='Zone Ventilation Parameters' AND ColumnName='Breathing Zone Outdoor Airflow - Vbz' AND Units='m3/s' AND RowName='#{spaceinfo[:thermal_zone].to_s.upcase}' ")
|
283
283
|
spaceinfo[:breathing_zone_outdoor_airflow_vbz] =breathing_zone_outdoor_airflow_vbz.get unless breathing_zone_outdoor_airflow_vbz.empty?
|
284
|
-
spaceinfo[:infiltration_method] = 'N/A'
|
284
|
+
spaceinfo[:infiltration_method] = 'N/A'
|
285
285
|
spaceinfo[:infiltration_flow_per_m2] =-1.0
|
286
286
|
unless space.spaceInfiltrationDesignFlowRates[0].nil?
|
287
287
|
spaceinfo[:infiltration_method] = space.spaceInfiltrationDesignFlowRates[0].designFlowRateCalculationMethod
|
@@ -291,9 +291,9 @@ module BTAP
|
|
291
291
|
error_warning << "space.spaceInfiltrationDesignFlowRates[0] is empty for #{spaceinfo[:name]}"
|
292
292
|
error_warning << "space.spaceInfiltrationDesignFlowRates[0].designFlowRateCalculationMethod is empty for #{spaceinfo[:name]}"
|
293
293
|
error_warning << "space.spaceInfiltrationDesignFlowRates[0].flowperExteriorSurfaceArea is empty for #{spaceinfo[:name]}"
|
294
|
-
end
|
294
|
+
end
|
295
295
|
|
296
|
-
#the following should have values unless the spacetype is "undefined" other they should be set to the correct NECB values.
|
296
|
+
#the following should have values unless the spacetype is "undefined" other they should be set to the correct NECB values.
|
297
297
|
unless space.spaceType.empty?
|
298
298
|
spaceinfo[:occupancy_schedule] = nil
|
299
299
|
unless (space.spaceType.get.defaultScheduleSet.empty?)
|
@@ -305,8 +305,8 @@ module BTAP
|
|
305
305
|
else
|
306
306
|
error_warning << "space.spaceType.get.defaultScheduleSet is empty for #{space.name.get }"
|
307
307
|
end
|
308
|
-
|
309
|
-
spaceinfo[:occ_per_m2] = space.spaceType.get.people[0].peopleDefinition.peopleperSpaceFloorArea.get.round(3) unless space.spaceType.get.people[0].nil?
|
308
|
+
|
309
|
+
spaceinfo[:occ_per_m2] = space.spaceType.get.people[0].peopleDefinition.peopleperSpaceFloorArea.get.round(3) unless space.spaceType.get.people[0].nil?
|
310
310
|
unless space.spaceType.get.lights[0].nil?
|
311
311
|
spaceinfo[:lighting_w_per_m2] = space.spaceType.get.lights[0].lightsDefinition.wattsperSpaceFloorArea#.get.round(3) unless space.spaceType.get.lights[0].nil?
|
312
312
|
spaceinfo[:lighting_w_per_m2] = validate_optional(spaceinfo[:lighting_w_per_m2], model, -1.0)
|
@@ -315,7 +315,7 @@ module BTAP
|
|
315
315
|
end
|
316
316
|
end
|
317
317
|
#spaceinfo[:electric_w_per_m2] = space.spaceType.get.electricEquipment[0].electricEquipmentDefinition.wattsperSpaceFloorArea.get.round(3) unless space.spaceType.get.electricEquipment[0].nil?
|
318
|
-
|
318
|
+
|
319
319
|
unless space.spaceType.get.electricEquipment[0].nil?
|
320
320
|
unless space.spaceType.get.electricEquipment[0].electricEquipmentDefinition.wattsperSpaceFloorArea.empty?
|
321
321
|
spaceinfo[:electric_w_per_m2] = space.spaceType.get.electricEquipment[0].electricEquipmentDefinition.wattsperSpaceFloorArea.get.round(3)
|
@@ -338,9 +338,9 @@ module BTAP
|
|
338
338
|
error_warning << "space.spaceType is empty for #{space.name.get }"
|
339
339
|
end
|
340
340
|
end
|
341
|
-
|
341
|
+
|
342
342
|
# Store Thermal zone data
|
343
|
-
qaqc[:thermal_zones] = []
|
343
|
+
qaqc[:thermal_zones] = []
|
344
344
|
model.getThermalZones.sort.each do |zone|
|
345
345
|
zoneinfo = {}
|
346
346
|
qaqc[:thermal_zones] << zoneinfo
|
@@ -353,29 +353,29 @@ module BTAP
|
|
353
353
|
else
|
354
354
|
error_warning << "zone.isConditioned is empty for #{zone.name.get}"
|
355
355
|
end
|
356
|
-
|
356
|
+
|
357
357
|
zoneinfo[:is_ideal_air_loads] = zone.useIdealAirLoads
|
358
358
|
zoneinfo[:heating_sizing_factor] = -1.0
|
359
359
|
unless zone.sizingZone.zoneHeatingSizingFactor.empty?
|
360
360
|
zoneinfo[:heating_sizing_factor] = zone.sizingZone.zoneHeatingSizingFactor.get
|
361
361
|
else
|
362
362
|
error_warning << "zone.sizingZone.zoneHeatingSizingFactor is empty for #{zone.name.get}"
|
363
|
-
end
|
364
|
-
|
363
|
+
end
|
364
|
+
|
365
365
|
zoneinfo[:cooling_sizing_factor] = -1.0 #zone.sizingZone.zoneCoolingSizingFactor.get
|
366
366
|
unless zone.sizingZone.zoneCoolingSizingFactor.empty?
|
367
367
|
zoneinfo[:cooling_sizing_factor] = zone.sizingZone.zoneCoolingSizingFactor.get
|
368
368
|
else
|
369
369
|
error_warning << "zone.sizingZone.zoneCoolingSizingFactor is empty for #{zone.name.get}"
|
370
|
-
end
|
371
|
-
|
370
|
+
end
|
371
|
+
|
372
372
|
zoneinfo[:zone_heating_design_supply_air_temperature] = zone.sizingZone.zoneHeatingDesignSupplyAirTemperature
|
373
373
|
zoneinfo[:zone_cooling_design_supply_air_temperature] = zone.sizingZone.zoneCoolingDesignSupplyAirTemperature
|
374
374
|
zoneinfo[:spaces] = []
|
375
375
|
zone.spaces.sort.each do |space|
|
376
376
|
spaceinfo ={}
|
377
377
|
zoneinfo[:spaces] << spaceinfo
|
378
|
-
spaceinfo[:name] = space.name.get
|
378
|
+
spaceinfo[:name] = space.name.get
|
379
379
|
spaceinfo[:type] = space.spaceType.get.name.get unless space.spaceType.empty?
|
380
380
|
end
|
381
381
|
zoneinfo[:equipment] = []
|
@@ -407,7 +407,7 @@ module BTAP
|
|
407
407
|
end
|
408
408
|
air_loop_info[:area_outdoor_air_rate_m3_per_s_m2] = model.sqlFile().get().execAndReturnFirstDouble("SELECT Value FROM TabularDataWithStrings WHERE ReportName='Standard62.1Summary' AND ReportForString='Entire Facility' AND TableName='System Ventilation Parameters' AND ColumnName='Area Outdoor Air Rate - Ra' AND Units='m3/s-m2' AND RowName='#{air_loop_info[:name].to_s.upcase}' ")
|
409
409
|
air_loop_info[:area_outdoor_air_rate_m3_per_s_m2] = validate_optional(air_loop_info[:area_outdoor_air_rate_m3_per_s_m2], model, -1.0)
|
410
|
-
|
410
|
+
|
411
411
|
air_loop_info[:outdoor_air_L_per_s] = -1.0
|
412
412
|
unless air_loop_info[:area_outdoor_air_rate_m3_per_s_m2] ==-1.0
|
413
413
|
air_loop_info[:outdoor_air_L_per_s] = air_loop_info[:area_outdoor_air_rate_m3_per_s_m2]*air_loop_info[:total_floor_area_served]*1000
|
@@ -416,10 +416,10 @@ module BTAP
|
|
416
416
|
|
417
417
|
unless air_loop.supplyFan.empty?
|
418
418
|
air_loop_info[:supply_fan] = {}
|
419
|
-
if air_loop.supplyFan.get.to_FanConstantVolume.is_initialized
|
419
|
+
if air_loop.supplyFan.get.to_FanConstantVolume.is_initialized
|
420
420
|
air_loop_info[:supply_fan][:type] = 'CV'
|
421
421
|
fan = air_loop.supplyFan.get.to_FanConstantVolume.get
|
422
|
-
elsif air_loop.supplyFan.get.to_FanVariableVolume.is_initialized
|
422
|
+
elsif air_loop.supplyFan.get.to_FanVariableVolume.is_initialized
|
423
423
|
air_loop_info[:supply_fan][:type] = 'VV'
|
424
424
|
fan = air_loop.supplyFan.get.to_FanVariableVolume.get
|
425
425
|
end
|
@@ -429,7 +429,7 @@ module BTAP
|
|
429
429
|
air_loop_info[:supply_fan][:motor_efficiency] = fan.motorEfficiency
|
430
430
|
air_loop_info[:supply_fan][:pressure_rise] = fan.pressureRise
|
431
431
|
air_loop_info[:supply_fan][:max_air_flow_rate_m3_per_s] = -1.0
|
432
|
-
|
432
|
+
|
433
433
|
max_air_flow_info = model.sqlFile().get().execAndReturnVectorOfString("SELECT RowName FROM TabularDataWithStrings WHERE ReportName='EquipmentSummary' AND ReportForString='Entire Facility' AND TableName='Fans' AND ColumnName='Max Air Flow Rate' AND Units='m3/s' ")
|
434
434
|
max_air_flow_info = validate_optional(max_air_flow_info, model, "N/A")
|
435
435
|
unless max_air_flow_info == "N/A"
|
@@ -444,7 +444,7 @@ module BTAP
|
|
444
444
|
end
|
445
445
|
end
|
446
446
|
|
447
|
-
#economizer
|
447
|
+
#economizer
|
448
448
|
air_loop_info[:economizer] = {}
|
449
449
|
air_loop_info[:economizer][:name] = air_loop.airLoopHVACOutdoorAirSystem.get.getControllerOutdoorAir.name.get
|
450
450
|
air_loop_info[:economizer][:control_type] = air_loop.airLoopHVACOutdoorAirSystem.get.getControllerOutdoorAir.getEconomizerControlType
|
@@ -462,7 +462,7 @@ module BTAP
|
|
462
462
|
|
463
463
|
#Heat Excahnger
|
464
464
|
air_loop_info[:heat_exchanger] = {}
|
465
|
-
|
465
|
+
|
466
466
|
air_loop.supplyComponents.each do |supply_comp|
|
467
467
|
if supply_comp.to_CoilHeatingGas.is_initialized
|
468
468
|
coil={}
|
@@ -498,11 +498,11 @@ module BTAP
|
|
498
498
|
air_loop_info[:heat_exchanger][:name] = heatExchanger.name.get
|
499
499
|
end
|
500
500
|
end
|
501
|
-
|
501
|
+
|
502
502
|
#I dont think i need to get the type of heating coil from the sql file, because the coils are differentiated by class, and I have hard coded the information
|
503
503
|
#model.sqlFile().get().execAndReturnFirstDouble("SELECT Value FROM TabularDataWithStrings WHERE ReportName='EquipmentSummary' AND ReportForString='Entire Facility' AND TableName= 'Heating Coils' AND ColumnName='Type' ").get #padmussen to complete #AND RowName='#{air_loop_info[:heating_coils][:name].upcase}'
|
504
|
-
|
505
|
-
|
504
|
+
|
505
|
+
|
506
506
|
#Collect all the fans into the the array.
|
507
507
|
air_loop.supplyComponents.each do |supply_comp|
|
508
508
|
if supply_comp.to_CoilCoolingDXSingleSpeed.is_initialized
|
@@ -510,7 +510,7 @@ module BTAP
|
|
510
510
|
air_loop_info[:cooling_coils][:dx_single_speed] << coil
|
511
511
|
single_speed = supply_comp.to_CoilCoolingDXSingleSpeed.get
|
512
512
|
coil[:name] = single_speed.name.get
|
513
|
-
coil[:cop] = single_speed.ratedCOP.
|
513
|
+
coil[:cop] = single_speed.ratedCOP.to_f
|
514
514
|
coil[:nominal_total_capacity_w] = model.sqlFile().get().execAndReturnFirstDouble("SELECT Value FROM TabularDataWithStrings WHERE ReportName='EquipmentSummary' AND ReportForString='Entire Facility' AND TableName='Cooling Coils' AND ColumnName='Nominal Total Capacity' AND RowName='#{coil[:name].upcase}' ")
|
515
515
|
coil[:nominal_total_capacity_w] = validate_optional(coil[:nominal_total_capacity_w], model, -1.0)
|
516
516
|
end
|
@@ -519,8 +519,8 @@ module BTAP
|
|
519
519
|
air_loop_info[:cooling_coils][:dx_two_speed] << coil
|
520
520
|
two_speed = supply_comp.to_CoilCoolingDXTwoSpeed.get
|
521
521
|
coil[:name] = two_speed.name.get
|
522
|
-
coil[:cop_low] = two_speed.ratedLowSpeedCOP.
|
523
|
-
coil[:cop_high] = two_speed.ratedHighSpeedCOP.
|
522
|
+
coil[:cop_low] = two_speed.ratedLowSpeedCOP.to_f
|
523
|
+
coil[:cop_high] = two_speed.ratedHighSpeedCOP.to_f
|
524
524
|
coil[:nominal_total_capacity_w] = model.sqlFile().get().execAndReturnFirstDouble("SELECT Value FROM TabularDataWithStrings WHERE ReportName='EquipmentSummary' AND ReportForString='Entire Facility' AND TableName='Cooling Coils' AND ColumnName='Nominal Total Capacity' AND RowName='#{coil[:name].upcase}' ")
|
525
525
|
coil[:nominal_total_capacity_w] = validate_optional(coil[:nominal_total_capacity_w] , model,-1.0)
|
526
526
|
end
|
@@ -534,11 +534,11 @@ module BTAP
|
|
534
534
|
plant_loop_info = {}
|
535
535
|
qaqc[:plant_loops] << plant_loop_info
|
536
536
|
plant_loop_info[:name] = plant_loop.name.get
|
537
|
-
|
537
|
+
|
538
538
|
sizing = plant_loop.sizingPlant
|
539
539
|
plant_loop_info[:design_loop_exit_temperature] = sizing.designLoopExitTemperature
|
540
540
|
plant_loop_info[:loop_design_temperature_difference] = sizing.loopDesignTemperatureDifference
|
541
|
-
|
541
|
+
|
542
542
|
#Create Container for plant equipment arrays.
|
543
543
|
plant_loop_info[:pumps] = []
|
544
544
|
plant_loop_info[:boilers] = []
|
@@ -546,7 +546,7 @@ module BTAP
|
|
546
546
|
plant_loop_info[:cooling_tower_single_speed] = []
|
547
547
|
plant_loop_info[:water_heater_mixed] =[]
|
548
548
|
plant_loop.supplyComponents.each do |supply_comp|
|
549
|
-
|
549
|
+
|
550
550
|
#Collect Constant Speed
|
551
551
|
if supply_comp.to_PumpConstantSpeed.is_initialized
|
552
552
|
pump = supply_comp.to_PumpConstantSpeed.get
|
@@ -562,14 +562,14 @@ module BTAP
|
|
562
562
|
pump_info[:electric_power_w] = validate_optional(pump_info[:electric_power_w], model, -1.0)
|
563
563
|
pump_info[:motor_efficency] = pump.motorEfficiency
|
564
564
|
end
|
565
|
-
|
565
|
+
|
566
566
|
#Collect Variable Speed
|
567
567
|
if supply_comp.to_PumpVariableSpeed.is_initialized
|
568
568
|
pump = supply_comp.to_PumpVariableSpeed.get
|
569
569
|
pump_info = {}
|
570
570
|
plant_loop_info[:pumps] << pump_info
|
571
571
|
pump_info[:name] = pump.name.get
|
572
|
-
pump_info[:type] = "Pump:VariableSpeed"
|
572
|
+
pump_info[:type] = "Pump:VariableSpeed"
|
573
573
|
pump_info[:head_pa] = model.sqlFile().get().execAndReturnFirstDouble("SELECT Value FROM TabularDataWithStrings WHERE ReportName='EquipmentSummary' AND ReportForString='Entire Facility' AND TableName='Pumps' AND ColumnName='Head' AND RowName='#{pump_info[:name].upcase}' ")
|
574
574
|
pump_info[:head_pa] = validate_optional(pump_info[:head_pa], model, -1.0)
|
575
575
|
pump_info[:water_flow_m3_per_s] = model.sqlFile().get().execAndReturnFirstDouble("SELECT Value FROM TabularDataWithStrings WHERE ReportName='EquipmentSummary' AND ReportForString='Entire Facility' AND TableName='Pumps' AND ColumnName='Water Flow' AND RowName='#{pump_info[:name].upcase}' ")
|
@@ -578,37 +578,37 @@ module BTAP
|
|
578
578
|
pump_info[:electric_power_w] = validate_optional(pump_info[:electric_power_w], model, -1.0)
|
579
579
|
pump_info[:motor_efficency] = pump.motorEfficiency
|
580
580
|
end
|
581
|
-
|
581
|
+
|
582
582
|
# Collect HotWaterBoilers
|
583
583
|
if supply_comp.to_BoilerHotWater.is_initialized
|
584
584
|
boiler = supply_comp.to_BoilerHotWater.get
|
585
585
|
boiler_info = {}
|
586
586
|
plant_loop_info[:boilers] << boiler_info
|
587
587
|
boiler_info[:name] = boiler.name.get
|
588
|
-
boiler_info[:type] = "Boiler:HotWater"
|
588
|
+
boiler_info[:type] = "Boiler:HotWater"
|
589
589
|
boiler_info[:fueltype] = boiler.fuelType
|
590
590
|
boiler_info[:nominal_capacity] = boiler.nominalCapacity
|
591
591
|
boiler_info[:nominal_capacity] = validate_optional(boiler_info[:nominal_capacity], model, -1.0)
|
592
592
|
end
|
593
|
-
|
593
|
+
|
594
594
|
# Collect ChillerElectricEIR
|
595
595
|
if supply_comp.to_ChillerElectricEIR.is_initialized
|
596
596
|
chiller = supply_comp.to_ChillerElectricEIR.get
|
597
597
|
chiller_info = {}
|
598
598
|
plant_loop_info[:chiller_electric_eir] << chiller_info
|
599
599
|
chiller_info[:name] = chiller.name.get
|
600
|
-
chiller_info[:type] = "Chiller:Electric:EIR"
|
600
|
+
chiller_info[:type] = "Chiller:Electric:EIR"
|
601
601
|
chiller_info[:reference_capacity] = validate_optional(chiller.referenceCapacity, model, -1.0)
|
602
602
|
chiller_info[:reference_leaving_chilled_water_temperature] =chiller.referenceLeavingChilledWaterTemperature
|
603
603
|
end
|
604
|
-
|
604
|
+
|
605
605
|
# Collect CoolingTowerSingleSpeed
|
606
606
|
if supply_comp.to_CoolingTowerSingleSpeed.is_initialized
|
607
607
|
coolingTower = supply_comp.to_CoolingTowerSingleSpeed.get
|
608
608
|
coolingTower_info = {}
|
609
609
|
plant_loop_info[:cooling_tower_single_speed] << coolingTower_info
|
610
610
|
coolingTower_info[:name] = coolingTower.name.get
|
611
|
-
coolingTower_info[:type] = "CoolingTower:SingleSpeed"
|
611
|
+
coolingTower_info[:type] = "CoolingTower:SingleSpeed"
|
612
612
|
coolingTower_info[:fan_power_at_design_air_flow_rate] = validate_optional(coolingTower.fanPoweratDesignAirFlowRate, model, -1.0)
|
613
613
|
|
614
614
|
end
|
@@ -624,8 +624,8 @@ module BTAP
|
|
624
624
|
waterHeaterMixed_info[:heater_fuel_type] = waterHeaterMixed.heaterFuelType
|
625
625
|
end
|
626
626
|
end
|
627
|
-
|
628
|
-
qaqc[:eplusout_err] ={}
|
627
|
+
|
628
|
+
qaqc[:eplusout_err] ={}
|
629
629
|
warnings = model.sqlFile().get().execAndReturnVectorOfString("SELECT ErrorMessage FROM Errors WHERE ErrorType='0' ")
|
630
630
|
warnings = validate_optional(warnings, model, "N/A")
|
631
631
|
unless warnings == "N/A"
|
@@ -633,20 +633,20 @@ module BTAP
|
|
633
633
|
qaqc[:eplusout_err][:fatal] =model.sqlFile().get().execAndReturnVectorOfString("SELECT ErrorMessage FROM Errors WHERE ErrorType='2' ").get
|
634
634
|
qaqc[:eplusout_err][:severe] =model.sqlFile().get().execAndReturnVectorOfString("SELECT ErrorMessage FROM Errors WHERE ErrorType='1' ").get
|
635
635
|
end
|
636
|
-
|
636
|
+
|
637
637
|
qaqc[:ruby_warnings] = error_warning
|
638
638
|
end
|
639
|
-
|
640
|
-
|
639
|
+
|
640
|
+
|
641
641
|
# Perform qaqc
|
642
642
|
necb_2011_qaqc(qaqc, model) if qaqc[:building][:name].include?("NECB2011") #had to nodify this because this is specifically for "NECB-2011" standard
|
643
643
|
sanity_check(qaqc)
|
644
|
-
|
644
|
+
|
645
645
|
qaqc[:information] = qaqc[:information].sort
|
646
646
|
qaqc[:warnings] = qaqc[:warnings].sort
|
647
647
|
qaqc[:errors] = qaqc[:errors].sort
|
648
648
|
qaqc[:unique_errors]= qaqc[:unique_errors].sort
|
649
|
-
|
649
|
+
|
650
650
|
return qaqc
|
651
651
|
end
|
652
652
|
end
|
@@ -672,7 +672,7 @@ def look_up_csv_data(csv_fname, search_criteria)
|
|
672
672
|
CSV.open( csv_fname, "r", options ) do |csv|
|
673
673
|
|
674
674
|
# Since CSV includes Enumerable we can use 'find_all'
|
675
|
-
# which will return all the elements of the Enumerble for
|
675
|
+
# which will return all the elements of the Enumerble for
|
676
676
|
# which the block returns true
|
677
677
|
|
678
678
|
matches = csv.find_all do |row|
|
@@ -704,7 +704,7 @@ def necb_section_test(qaqc,result_value,bool_operator,expected_value,necb_sectio
|
|
704
704
|
end
|
705
705
|
test = eval(command)
|
706
706
|
test == 'true' ? true :false
|
707
|
-
raise ("Eval command failed #{test}") if !!test != test
|
707
|
+
raise ("Eval command failed #{test}") if !!test != test
|
708
708
|
if test
|
709
709
|
qaqc[:information] << "[Info][TEST-PASS][#{necb_section_name}]:#{test_text} result value:#{result_value} #{bool_operator} expected value:#{expected_value}"
|
710
710
|
else
|
@@ -721,8 +721,8 @@ def check_boolean_value (value,varname)
|
|
721
721
|
|
722
722
|
raise ArgumentError.new "invalid value for #{varname}: #{value}"
|
723
723
|
end
|
724
|
-
|
725
|
-
|
724
|
+
|
725
|
+
|
726
726
|
def get_total_nominal_capacity (model)
|
727
727
|
total_nominal_capacity = 0
|
728
728
|
model.getSpaces.sort.each do |space|
|
@@ -764,23 +764,23 @@ def sanity_check(qaqc)
|
|
764
764
|
qaqc[:sanity_check][:pass] << "[TEST-PASS][SANITY_CHECK-PASS] for [SPACE][#{space[:name]}] and [THERMAL ZONE] [#{zoneinfo[:name]}] where isConditioned is supposed to be [""Yes""] and found as #{zoneinfo[:is_conditioned]}"
|
765
765
|
elsif zoneinfo[:name]
|
766
766
|
qaqc[:sanity_check][:fail] << "[ERROR][SANITY_CHECK-FAIL] for [SPACE][#{space[:name]}] and [THERMAL ZONE] [#{zoneinfo[:name]}] where isConditioned is supposed to be [""Yes""] but found as #{zoneinfo[:is_conditioned]}"
|
767
|
-
end
|
767
|
+
end
|
768
768
|
end
|
769
769
|
end
|
770
|
-
end
|
770
|
+
end
|
771
771
|
qaqc[:sanity_check][:fail] = qaqc[:sanity_check][:fail].sort
|
772
772
|
qaqc[:sanity_check][:pass] = qaqc[:sanity_check][:pass].sort
|
773
773
|
#Padmassun's code for isConditioned end
|
774
774
|
end
|
775
|
-
|
776
|
-
|
775
|
+
|
776
|
+
|
777
777
|
def necb_2011_qaqc(qaqc, model)
|
778
|
-
#Now perform basic QA/QC on items for NECB2011
|
778
|
+
#Now perform basic QA/QC on items for NECB2011
|
779
779
|
qaqc[:information] = []
|
780
780
|
qaqc[:warnings] =[]
|
781
781
|
qaqc[:errors] = []
|
782
782
|
qaqc[:unique_errors]=[]
|
783
|
-
|
783
|
+
|
784
784
|
|
785
785
|
# #Padmassun's Code Start
|
786
786
|
csv_file_name ="#{File.dirname(__FILE__)}/necb_2011_spacetype_info.csv"
|
@@ -802,20 +802,20 @@ def necb_2011_qaqc(qaqc, model)
|
|
802
802
|
puts "space type of [#{space_type}] and/or building type of [#{building_type}] was not found in the excel sheet for space: [#{space[:name]}]"
|
803
803
|
else
|
804
804
|
#correct the data from the csv file to include a multiplier of 0.9 for specific space types.
|
805
|
-
|
805
|
+
|
806
806
|
reduceLPDSpaces = ["Classroom/lecture/training", "Conf./meet./multi-purpose", "Lounge/recreation",
|
807
|
-
"Washroom-sch-A", "Washroom-sch-B", "Washroom-sch-C", "Washroom-sch-D", "Washroom-sch-E",
|
808
|
-
"Washroom-sch-F", "Washroom-sch-G", "Washroom-sch-H", "Washroom-sch-I", "Dress./fitt. - performance arts",
|
807
|
+
"Washroom-sch-A", "Washroom-sch-B", "Washroom-sch-C", "Washroom-sch-D", "Washroom-sch-E",
|
808
|
+
"Washroom-sch-F", "Washroom-sch-G", "Washroom-sch-H", "Washroom-sch-I", "Dress./fitt. - performance arts",
|
809
809
|
"Locker room", "Retail - dressing/fitting","Locker room-sch-A","Locker room-sch-B","Locker room-sch-C",
|
810
810
|
"Locker room-sch-D","Locker room-sch-E","Locker room-sch-F","Locker room-sch-G","Locker room-sch-H",
|
811
811
|
"Locker room-sch-I", "Office - open plan - occsens", "Office - enclosed - occsens", "Storage area - occsens",
|
812
812
|
"Hospital - medical supply - occsens", "Storage area - refrigerated - occsens"]
|
813
|
-
|
813
|
+
|
814
814
|
if reduceLPDSpaces.include?(space_type)
|
815
815
|
row[3] = row[3]*0.9
|
816
816
|
puts "\n============================\nspace_type: #{space_type}\n============================\n"
|
817
817
|
end
|
818
|
-
|
818
|
+
|
819
819
|
# Start of Space Compliance
|
820
820
|
necb_section_name = "NECB2011-Section 8.4.3.6"
|
821
821
|
data = {}
|
@@ -838,13 +838,13 @@ def necb_2011_qaqc(qaqc, model)
|
|
838
838
|
end#space Compliance
|
839
839
|
end
|
840
840
|
#Padmassun's Code End
|
841
|
-
|
841
|
+
|
842
842
|
|
843
843
|
# Envelope
|
844
844
|
necb_section_name = "NECB2011-Section 3.2.1.4"
|
845
845
|
#store hdd in short form
|
846
846
|
hdd = qaqc[:geography][:hdd]
|
847
|
-
#calculate fdwr based on hdd.
|
847
|
+
#calculate fdwr based on hdd.
|
848
848
|
fdwr = 0
|
849
849
|
if hdd < 4000
|
850
850
|
fdwr = 0.40
|
@@ -853,15 +853,15 @@ def necb_2011_qaqc(qaqc, model)
|
|
853
853
|
elsif hdd >7000
|
854
854
|
fdwr = 0.20
|
855
855
|
end
|
856
|
-
#hardset srr to 0.05
|
856
|
+
#hardset srr to 0.05
|
857
857
|
srr = 0.05
|
858
858
|
#create table of expected values and results.
|
859
859
|
data = {}
|
860
860
|
data[:fenestration_to_door_and_window_percentage] = [ fdwr * 100,qaqc[:envelope][:fdwr].round(3)]
|
861
861
|
data[:skylight_to_roof_percentage] = [ srr * 100,qaqc[:envelope][:srr].round(3)]
|
862
862
|
#perform test. result must be less than or equal to.
|
863
|
-
data.each {|key,value| necb_section_test(
|
864
|
-
qaqc,
|
863
|
+
data.each {|key,value| necb_section_test(
|
864
|
+
qaqc,
|
865
865
|
value[0],
|
866
866
|
'>=',
|
867
867
|
value[1],
|
@@ -875,11 +875,11 @@ def necb_2011_qaqc(qaqc, model)
|
|
875
875
|
necb_section_name = "NECB2011-Section 8.4.3.6"
|
876
876
|
qaqc[:spaces].each do |spaceinfo|
|
877
877
|
data = {}
|
878
|
-
data[:infiltration_method] = [ "Flow/ExteriorArea", spaceinfo[:infiltration_method] , nil ]
|
878
|
+
data[:infiltration_method] = [ "Flow/ExteriorArea", spaceinfo[:infiltration_method] , nil ]
|
879
879
|
data[:infiltration_flow_per_m2] = [ 0.00025, spaceinfo[:infiltration_flow_per_m2], 5 ]
|
880
880
|
data.each do |key,value|
|
881
881
|
#puts key
|
882
|
-
necb_section_test(
|
882
|
+
necb_section_test(
|
883
883
|
qaqc,
|
884
884
|
value[0],
|
885
885
|
'==',
|
@@ -899,8 +899,8 @@ def necb_2011_qaqc(qaqc, model)
|
|
899
899
|
data[:ext_wall_conductances] = [0.315,0.278,0.247,0.210,0.210,0.183,qaqc[:envelope][:outdoor_walls_average_conductance_w_per_m2_k]] unless qaqc[:envelope][:outdoor_walls_average_conductance_w_per_m2_k].nil?
|
900
900
|
data[:ext_roof_conductances] = [0.227,0.183,0.183,0.162,0.162,0.142,qaqc[:envelope][:outdoor_roofs_average_conductance_w_per_m2_k]] unless qaqc[:envelope][:outdoor_roofs_average_conductance_w_per_m2_k].nil?
|
901
901
|
data[:ext_floor_conductances] = [0.227,0.183,0.183,0.162,0.162,0.142,qaqc[:envelope][:outdoor_floors_average_conductance_w_per_m2_k]] unless qaqc[:envelope][:outdoor_floors_average_conductance_w_per_m2_k].nil?
|
902
|
-
|
903
|
-
data.each {|key,value| necb_section_test(
|
902
|
+
|
903
|
+
data.each {|key,value| necb_section_test(
|
904
904
|
qaqc,
|
905
905
|
value[result_value_index],
|
906
906
|
'==',
|
@@ -921,9 +921,9 @@ def necb_2011_qaqc(qaqc, model)
|
|
921
921
|
data[:ext_overhead_door_conductances] = [2.400,2.200,2.200,2.200,2.200,1.600,qaqc[:envelope][:overhead_doors_average_conductance_w_per_m2_k]] unless qaqc[:envelope][:overhead_doors_average_conductance_w_per_m2_k].nil?
|
922
922
|
data[:ext_skylight_conductances] = [2.400,2.200,2.200,2.200,2.200,1.600,qaqc[:envelope][:skylights_average_conductance_w_per_m2_k]] unless qaqc[:envelope][:skylights_average_conductance_w_per_m2_k].nil?
|
923
923
|
data.each do |key,value|
|
924
|
-
|
924
|
+
|
925
925
|
#puts key
|
926
|
-
necb_section_test(
|
926
|
+
necb_section_test(
|
927
927
|
qaqc,
|
928
928
|
value[result_value_index].round(round_precision),
|
929
929
|
'==',
|
@@ -932,7 +932,7 @@ def necb_2011_qaqc(qaqc, model)
|
|
932
932
|
"[ENVELOPE]#{key}",
|
933
933
|
round_precision
|
934
934
|
)
|
935
|
-
end
|
935
|
+
end
|
936
936
|
#Exterior Ground surfaces
|
937
937
|
necb_section_name = "NECB2011-Section 3.2.3.1"
|
938
938
|
climate_index = NECB2011.new().get_climate_zone_index(qaqc[:geography][:hdd])
|
@@ -942,7 +942,7 @@ def necb_2011_qaqc(qaqc, model)
|
|
942
942
|
data[:ground_wall_conductances] = [ 0.568,0.379,0.284,0.284,0.284,0.210, qaqc[:envelope][:ground_walls_average_conductance_w_per_m2_k] ] unless qaqc[:envelope][:ground_walls_average_conductance_w_per_m2_k].nil?
|
943
943
|
data[:ground_roof_conductances] = [ 0.568,0.379,0.284,0.284,0.284,0.210, qaqc[:envelope][:ground_roofs_average_conductance_w_per_m2_k] ] unless qaqc[:envelope][:ground_roofs_average_conductance_w_per_m2_k].nil?
|
944
944
|
data[:ground_floor_conductances] = [ 0.757,0.757,0.757,0.757,0.757,0.379, qaqc[:envelope][:ground_floors_average_conductance_w_per_m2_k] ] unless qaqc[:envelope][:ground_floors_average_conductance_w_per_m2_k].nil?
|
945
|
-
data.each {|key,value| necb_section_test(
|
945
|
+
data.each {|key,value| necb_section_test(
|
946
946
|
qaqc,
|
947
947
|
value[result_value_index],
|
948
948
|
'==',
|
@@ -964,9 +964,9 @@ def necb_2011_qaqc(qaqc, model)
|
|
964
964
|
data[:cooling_sizing_factor] = [1.1 ,zoneinfo[:cooling_sizing_factor]]
|
965
965
|
data[:heating_design_supply_air_temp] = [43.0, zoneinfo[:zone_heating_design_supply_air_temperature] ] #unless zoneinfo[:zone_heating_design_supply_air_temperature].nil?
|
966
966
|
data[:cooling_design_supply_temp] = [13.0, zoneinfo[:zone_cooling_design_supply_air_temperature] ]
|
967
|
-
data.each do |key,value|
|
967
|
+
data.each do |key,value|
|
968
968
|
#puts key
|
969
|
-
necb_section_test(
|
969
|
+
necb_section_test(
|
970
970
|
qaqc,
|
971
971
|
value[0],
|
972
972
|
'==',
|
@@ -976,26 +976,26 @@ def necb_2011_qaqc(qaqc, model)
|
|
976
976
|
round_precision
|
977
977
|
)
|
978
978
|
end
|
979
|
-
end
|
979
|
+
end
|
980
980
|
#Air flow sizing check
|
981
981
|
#determine correct economizer usage according to section 5.2.2.7 of NECB2011
|
982
982
|
necb_section_name = "NECB2011-5.2.2.7"
|
983
983
|
qaqc[:air_loops].each do |air_loop_info|
|
984
|
-
# air_loop_info[:name]
|
985
|
-
# air_loop_info[:thermal_zones]
|
984
|
+
# air_loop_info[:name]
|
985
|
+
# air_loop_info[:thermal_zones]
|
986
986
|
# air_loop_info[:total_floor_area_served]
|
987
987
|
# air_loop_info[:cooling_coils][:dx_single_speed]
|
988
988
|
# air_loop_info[:cooling_coils][:dx_two_speed]
|
989
989
|
# air_loop_info[:supply_fan][:max_air_flow_rate]
|
990
|
-
#
|
990
|
+
#
|
991
991
|
# air_loop_info[:heating_coils][:coil_heating_gas][:nominal_capacity]
|
992
992
|
# air_loop_info[:heating_coils][:coil_heating_electric][:nominal_capacity]
|
993
993
|
# air_loop_info[:heating_coils][:coil_heating_water][:nominal_capacity]
|
994
|
-
#
|
994
|
+
#
|
995
995
|
# air_loop_info[:economizer][:control_type]
|
996
|
-
|
996
|
+
|
997
997
|
capacity = -1.0
|
998
|
-
|
998
|
+
|
999
999
|
if !air_loop_info[:cooling_coils][:dx_single_speed][0].nil?
|
1000
1000
|
puts "air_loop_info[:heating_coils][:coil_heating_gas][0][:nominal_capacity]"
|
1001
1001
|
capacity = air_loop_info[:cooling_coils][:dx_single_speed][0][:nominal_total_capacity_w]
|
@@ -1015,7 +1015,7 @@ def necb_2011_qaqc(qaqc, model)
|
|
1015
1015
|
if capacity > 20000 or air_loop_info[:supply_fan][:max_air_flow_rate_m3_per_s]*1000 >1500
|
1016
1016
|
#diff enth
|
1017
1017
|
#puts "diff"
|
1018
|
-
necb_section_test(
|
1018
|
+
necb_section_test(
|
1019
1019
|
qaqc,
|
1020
1020
|
"DifferentialEnthalpy",
|
1021
1021
|
'==',
|
@@ -1026,7 +1026,7 @@ def necb_2011_qaqc(qaqc, model)
|
|
1026
1026
|
else
|
1027
1027
|
#no economizer
|
1028
1028
|
#puts "no econ"
|
1029
|
-
necb_section_test(
|
1029
|
+
necb_section_test(
|
1030
1030
|
qaqc,
|
1031
1031
|
'NoEconomizer',
|
1032
1032
|
'==',
|
@@ -1038,7 +1038,7 @@ def necb_2011_qaqc(qaqc, model)
|
|
1038
1038
|
end
|
1039
1039
|
end
|
1040
1040
|
end
|
1041
|
-
|
1041
|
+
|
1042
1042
|
#*TODO*
|
1043
1043
|
necb_section_name = "NECB2011-5.2.10.1"
|
1044
1044
|
qaqc[:air_loops].each do |air_loop_info|
|
@@ -1050,7 +1050,7 @@ def necb_2011_qaqc(qaqc, model)
|
|
1050
1050
|
unless air_loop_info[:heat_exchanger].empty?
|
1051
1051
|
hrv_present = true
|
1052
1052
|
end
|
1053
|
-
necb_section_test(
|
1053
|
+
necb_section_test(
|
1054
1054
|
qaqc,
|
1055
1055
|
hrv_reqd,
|
1056
1056
|
'==',
|
@@ -1058,10 +1058,10 @@ def necb_2011_qaqc(qaqc, model)
|
|
1058
1058
|
necb_section_name,
|
1059
1059
|
"[AIR LOOP][:heat_exchanger] for [#{air_loop_info[:name]}] is present?"
|
1060
1060
|
)
|
1061
|
-
|
1061
|
+
|
1062
1062
|
end
|
1063
1063
|
end
|
1064
|
-
|
1064
|
+
|
1065
1065
|
necb_section_name = "NECB2011-5.2.3.3"
|
1066
1066
|
qaqc[:air_loops].each do |air_loop_info|
|
1067
1067
|
#necb_clg_cop = air_loop_info[:cooling_coils][:dx_single_speed][:cop] #*assuming that the cop is defined correctly*
|
@@ -1098,7 +1098,7 @@ def necb_2011_qaqc(qaqc, model)
|
|
1098
1098
|
else
|
1099
1099
|
#The test should pass if and only if the percent difference is less than 10%
|
1100
1100
|
percent_diff = ((necb_supply_fan_w - supply_fan_w).to_f.abs/necb_supply_fan_w * 100).round(3)
|
1101
|
-
necb_section_test(
|
1101
|
+
necb_section_test(
|
1102
1102
|
qaqc,
|
1103
1103
|
10,
|
1104
1104
|
'>=',
|
@@ -1108,9 +1108,9 @@ def necb_2011_qaqc(qaqc, model)
|
|
1108
1108
|
)
|
1109
1109
|
end
|
1110
1110
|
end
|
1111
|
-
|
1111
|
+
|
1112
1112
|
necb_section_name = "SANITY-??"
|
1113
|
-
qaqc[:plant_loops].each do |plant_loop_info|
|
1113
|
+
qaqc[:plant_loops].each do |plant_loop_info|
|
1114
1114
|
pump_head = plant_loop_info[:pumps][0][:head_pa]
|
1115
1115
|
flow_rate = plant_loop_info[:pumps][0][:water_flow_m3_per_s]*1000
|
1116
1116
|
hp_check = ((flow_rate*60*60)/1000*1000*9.81*pump_head*0.000101997)/3600000
|
@@ -1121,13 +1121,13 @@ def necb_2011_qaqc(qaqc, model)
|
|
1121
1121
|
puts "hp_check #{hp_check}\n"
|
1122
1122
|
pump_power_hp = plant_loop_info[:pumps][0][:electric_power_w]/1000*0.746
|
1123
1123
|
percent_diff = (hp_check - pump_power_hp).to_f.abs/hp_check * 100
|
1124
|
-
|
1124
|
+
|
1125
1125
|
if percent_diff.nan?
|
1126
1126
|
qaqc[:ruby_warnings] << "(hp_check - pump_power_hp).to_f.abs/hp_check * 100 for #{plant_loop_info[:name]} is NaN"
|
1127
1127
|
next
|
1128
1128
|
end
|
1129
|
-
|
1130
|
-
necb_section_test(
|
1129
|
+
|
1130
|
+
necb_section_test(
|
1131
1131
|
qaqc,
|
1132
1132
|
20, #diff of 20%
|
1133
1133
|
'>=',
|
@@ -1135,6 +1135,6 @@ def necb_2011_qaqc(qaqc, model)
|
|
1135
1135
|
necb_section_name,
|
1136
1136
|
"[PLANT LOOP][#{plant_loop_info[:name]}][:pumps][0][:electric_power_hp] [#{pump_power_hp}] Percent Diff from NECB value [#{hp_check}]"
|
1137
1137
|
)
|
1138
|
-
|
1138
|
+
|
1139
1139
|
end
|
1140
1140
|
end
|