Module: BTAP

Defined in:
lib/openstudio-standards/btap/btap.rb,
lib/openstudio-standards/btap/fileio.rb,
lib/openstudio-standards/btap/bridging.rb,
lib/openstudio-standards/btap/envelope.rb,
lib/openstudio-standards/btap/geometry.rb,
lib/openstudio-standards/btap/schedules.rb,
lib/openstudio-standards/btap/btap_result.rb,
lib/openstudio-standards/btap/visualization.rb

Overview

A set of methods developed by NRCan to simplify building model creation and analysis. These methods are meant to compliment the OpenStudio classes and methods For full access to the OpenStudio API please refer to the OpenStudio Website. openstudio.nrel.gov/latest-c-sdk-documentation/model

Defined Under Namespace

Modules: BridgingData, Common, FileIO, Geometry, Reports, Resources, SimulationSettings, Visualization Classes: Bridging, OpenStudioLibrary

Constant Summary collapse

ENERGY_PLUS_MAJOR_VERSION =

EnergyPlus version

8
ENERGY_PLUS_MINOR_VERSION =
3
OS_RUBY_PATH =

Path constants

File.expand_path("..\\..\\..", __FILE__)
TESTING_FOLDER =
"C:\\test"

Class Method Summary collapse

Class Method Details

.gut_building(model) ⇒ Object



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/openstudio-standards/btap/btap.rb', line 149

def self.gut_building(model)
  #clean up any remaining items that we don't need for NECB.
  puts "Removing casual loads."
  BTAP::Resources::SpaceLoads::remove_all_casual_loads(model)
  puts "Removing space loads."
  BTAP::Resources::SpaceLoads::remove_all_SpaceLoads(model)
  puts "Removing OA loads."
  BTAP::Resources::SpaceLoads::remove_all_DesignSpecificationOutdoorAir(model)
  puts "Removing Envelope"
  BTAP::Resources::Envelope::remove_all_envelope_information(model)
  puts "Removing Infiltration"
  BTAP::Resources::SpaceLoads::remove_all_SpaceInfiltrationDesignFlowRate(model)
  puts "Removing all Schedules"
  BTAP::Resources::Schedules::remove_all_schedules( model )
  puts "Removing HVAC"
  BTAP::Resources::HVAC.clear_all_hvac_from_model( model )
end

.perform_qaqc(model) ⇒ Object



2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
# File 'lib/openstudio-standards/btap/btap_result.rb', line 2

def self.perform_qaqc(model)
  surfaces = {}
  outdoor_surfaces = BTAP::Geometry::Surfaces::filter_by_boundary_condition(model.getSurfaces(), "Outdoors")
  outdoor_walls = BTAP::Geometry::Surfaces::filter_by_surface_types(outdoor_surfaces, "Wall")
  outdoor_roofs = BTAP::Geometry::Surfaces::filter_by_surface_types(outdoor_surfaces, "RoofCeiling")
  outdoor_floors = BTAP::Geometry::Surfaces::filter_by_surface_types(outdoor_surfaces, "Floor")
  outdoor_subsurfaces = outdoor_surfaces.flat_map(&:subSurfaces)
  ground_surfaces = BTAP::Geometry::Surfaces::filter_by_boundary_condition(model.getSurfaces(), "Ground")
  ground_walls = BTAP::Geometry::Surfaces::filter_by_surface_types(ground_surfaces, "Wall")
  ground_roofs = BTAP::Geometry::Surfaces::filter_by_surface_types(ground_surfaces, "RoofCeiling")
  ground_floors = BTAP::Geometry::Surfaces::filter_by_surface_types(ground_surfaces, "Floor")

  windows = BTAP::Geometry::Surfaces::filter_subsurfaces_by_types(outdoor_subsurfaces, ["FixedWindow" , "OperableWindow" ])
  skylights = BTAP::Geometry::Surfaces::filter_subsurfaces_by_types(outdoor_subsurfaces, ["Skylight", "TubularDaylightDiffuser","TubularDaylightDome" ])
  doors = BTAP::Geometry::Surfaces::filter_subsurfaces_by_types(outdoor_subsurfaces, ["Door" , "GlassDoor" ])
  overhead_doors = BTAP::Geometry::Surfaces::filter_subsurfaces_by_types(outdoor_subsurfaces, ["OverheadDoor" ])
  electric_peak = model.sqlFile().get().execAndReturnFirstDouble("SELECT Value FROM tabulardatawithstrings WHERE ReportName='EnergyMeters'" +
      " AND ReportForString='Entire Facility' AND TableName='Annual and Peak Values - Electricity' AND RowName='Electricity:Facility'" +
      " AND ColumnName='Electricity Maximum Value' AND Units='W'")
  natural_gas_peak = model.sqlFile().get().execAndReturnFirstDouble("SELECT Value FROM tabulardatawithstrings WHERE ReportName='EnergyMeters'" +
      " AND ReportForString='Entire Facility' AND TableName='Annual and Peak Values - Natural Gas' AND RowName='NaturalGas:Facility'" +
      " AND ColumnName='Natural Gas Maximum Value' AND Units='W'")

  # Create hash to store all the collected data.
  qaqc = {}
  error_warning=[]
  # Store Building data.
  qaqc[:building] = {}
  qaqc[:building][:name] = model.building.get.name.get
  qaqc[:building][:conditioned_floor_area_m2]=nil
  unless model.building.get.conditionedFloorArea().empty?
    qaqc[:building][:conditioned_floor_area_m2] = model.building.get.conditionedFloorArea().get
  else
    error_warning <<  "model.building.get.conditionedFloorArea() is empty for #{model.building.get.name.get}"
  end
  qaqc[:building][:exterior_area_m2] = model.building.get.exteriorSurfaceArea() #m2
  qaqc[:building][:volume] = model.building.get.airVolume() #m3
  qaqc[:building][:number_of_stories] = model.getBuildingStorys.size
  # Store Geography Data
  qaqc[:geography] ={}
  weather_file_path = model.weatherFile.get.path.get.to_s
  stat_file_path = weather_file_path.gsub('.epw', '.stat')
  stat_file = OpenstudioStandards::Weather::StatFile.new(stat_file_path)
  qaqc[:geography][:hdd] = stat_file.hdd18
  qaqc[:geography][:cdd] = stat_file.cdd18
  qaqc[:geography][:climate_zone] = NECB2011.new().get_climate_zone_name(qaqc[:geography][:hdd])
  qaqc[:geography][:city] = model.getWeatherFile.city
  qaqc[:geography][:state_province_region] = model.getWeatherFile.stateProvinceRegion
  qaqc[:geography][:country] = model.getWeatherFile.country
  qaqc[:geography][:latitude] = model.getWeatherFile.latitude
  qaqc[:geography][:longitude] = model.getWeatherFile.longitude

  #Spacetype Breakdown
  qaqc[:spacetype_area_breakdown]={}
  model.getSpaceTypes.sort.each do |spaceType|
    next if spaceType.floorArea == 0

    # data for space type breakdown
    display = spaceType.name.get
    floor_area_si = 0
    # loop through spaces so I can skip if not included in floor area
    spaceType.spaces.sort.each do |space|
      next if not space.partofTotalFloorArea
      floor_area_si += space.floorArea * space.multiplier
    end
    qaqc[:spacetype_area_breakdown][spaceType.name.get.gsub(/\s+/, "_").downcase.to_sym] = floor_area_si
  end



  #Economics Section
  qaqc[:economics] = {}
  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'")
  #==> ["Electricity", "Natural Gas", "Additional", "Total"]
  costing_rownames = validate_optional(costing_rownames, model, "N/A")
  unless costing_rownames == "N/A"
    costing_rownames.each do |rowname|
      case rowname
      when "Electricity"
        qaqc[:economics][:electricity_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
        qaqc[:economics][:electricity_cost_per_m2]=qaqc[:economics][:electricity_cost]/qaqc[:building][:conditioned_floor_area_m2] unless model.building.get.conditionedFloorArea().empty?
      when "Natural Gas"
        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
        qaqc[:economics][:natural_gas_cost_per_m2]=qaqc[:economics][:natural_gas_cost]/qaqc[:building][:conditioned_floor_area_m2] unless model.building.get.conditionedFloorArea().empty?

      when "Additional"
        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
        qaqc[:economics][:additional_cost_per_m2]=qaqc[:economics][:additional_cost]/qaqc[:building][:conditioned_floor_area_m2] unless model.building.get.conditionedFloorArea().empty?

      when "Total"
        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
        qaqc[:economics][:total_cost_per_m2]=qaqc[:economics][:total_cost]/qaqc[:building][:conditioned_floor_area_m2] unless model.building.get.conditionedFloorArea().empty?
      end
    end
  else
    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'"
  end

  #Store end_use data
  end_uses = [
    'Heating',
    'Cooling',
    'Interior Lighting',
    'Exterior Lighting',
    'Interior Equipment',
    'Exterior Equipment',
    'Fans',
    'Pumps',
    'Heat Rejection',
    'Humidification',
    'Heat Recovery',
    'Water Systems',
    'Refrigeration',
    'Generators',
    'Total End Uses'
  ]

  fuels = [
    ['Electricity', 'GJ'],
    ['Natural Gas', 'GJ'] ,
    ['Additional Fuel', 'GJ'],
    ['District Cooling','GJ'],
    ['District Heating', 'GJ'],
  ]

  qaqc[:end_uses] = {}
  qaqc[:end_uses_eui] = {}
  end_uses.each do |use_type|
    qaqc[:end_uses]["#{use_type.gsub(/\s+/, "_").downcase.to_sym}_gj"] = 0
    qaqc[:end_uses_eui]["#{use_type.gsub(/\s+/, "_").downcase.to_sym}_gj_per_m2"] = 0
    fuels.each do |fuel_type|
      value = model.sqlFile().get().execAndReturnFirstDouble("SELECT Value FROM tabulardatawithstrings WHERE ReportName='AnnualBuildingUtilityPerformanceSummary' AND ReportForString='Entire Facility' AND TableName='End Uses' AND RowName='#{use_type}' AND ColumnName='#{fuel_type[0]}' AND Units='#{fuel_type[1]}'")
      if value.empty? or value.get == 0
      else
        qaqc[:end_uses]["#{use_type.gsub(/\s+/, "_").downcase.to_sym}_gj"] += value.get
        unless qaqc[:building][:conditioned_floor_area_m2].nil?
          qaqc[:end_uses_eui]["#{use_type.gsub(/\s+/, "_").downcase.to_sym}_gj_per_m2"] += value.get / qaqc[:building][:conditioned_floor_area_m2]
        end
      end
    end
    value = model.sqlFile().get().execAndReturnFirstDouble("SELECT Value FROM tabulardatawithstrings WHERE ReportName='AnnualBuildingUtilityPerformanceSummary' AND ReportForString='Entire Facility' AND TableName='End Uses' AND RowName='#{use_type}' AND ColumnName='Water' AND Units='m3'")
   if value.empty? or value.get == 0
    else
      qaqc[:end_uses]["#{use_type.gsub(/\s+/, "_").downcase.to_sym}_water_m3"] = value.get
      unless qaqc[:building][:conditioned_floor_area_m2].nil?
        qaqc[:end_uses_eui]["#{use_type.gsub(/\s+/, "_").downcase.to_sym}_water_m3_per_m2"] = value.get / qaqc[:building][:conditioned_floor_area_m2]
      end
    end
  end

  # Store Peak Data
  qaqc[:meter_peaks] = {}
  qaqc[:meter_peaks][:electric_w] = electric_peak.empty? ? "NA" : electric_peak.get
  qaqc[:meter_peaks][:natural_gas_w] = natural_gas_peak.empty? ? "NA" : natural_gas_peak.get


  #Store unmet hour data
  qaqc[:unmet_hours] = {}
  qaqc[:unmet_hours][:cooling] = model.getFacility.hoursCoolingSetpointNotMet().get unless model.getFacility.hoursCoolingSetpointNotMet().empty?
  qaqc[:unmet_hours][:heating] = model.getFacility.hoursHeatingSetpointNotMet().get unless model.getFacility.hoursHeatingSetpointNotMet().empty?






  #puts "\n\n\n#{costing_rownames}\n\n\n"
  #Padmassun's Code -- Tarrif end


  #Padmassun's Code -- Service Hotwater Heating *start*
  qaqc[:service_water_heating] = {}
  qaqc[:service_water_heating][:total_nominal_occupancy]=-1
  #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, :+)
  qaqc[:service_water_heating][:total_nominal_occupancy]=get_total_nominal_capacity(model)

  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'")
  qaqc[:service_water_heating][:electricity_per_year]= validate_optional(qaqc[:service_water_heating][:electricity_per_year], model, -1)

  qaqc[:service_water_heating][:electricity_per_day]=qaqc[:service_water_heating][:electricity_per_year]/365.5
  qaqc[:service_water_heating][:electricity_per_day_per_occupant]=qaqc[:service_water_heating][:electricity_per_day]/qaqc[:service_water_heating][:total_nominal_occupancy]


  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'")
  qaqc[:service_water_heating][:natural_gas_per_year]=validate_optional(qaqc[:service_water_heating][:natural_gas_per_year], model, -1)

  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'")
  qaqc[:service_water_heating][:additional_fuel_per_year] = validate_optional(qaqc[:service_water_heating][:additional_fuel_per_year], model, -1)

  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'")
  qaqc[:service_water_heating][:water_m3_per_year]=validate_optional(qaqc[:service_water_heating][:water_m3_per_year], model, -1)

  qaqc[:service_water_heating][:water_m3_per_day]=qaqc[:service_water_heating][:water_m3_per_year]/365.5
  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]
  #puts qaqc[:service_water_heating][:total_nominal_occupancy]
  #Padmassun's Code -- Service Hotwater Heating *end*

  #Store Envelope data.
  qaqc[:envelope] = {}

  qaqc[:envelope][:outdoor_walls_average_conductance_w_per_m2_k] 	= OpenstudioStandards::Constructions.surfaces_get_conductance(outdoor_walls).round(4) if outdoor_walls.size > 0
  qaqc[:envelope][:outdoor_roofs_average_conductance_w_per_m2_k]  = OpenstudioStandards::Constructions.surfaces_get_conductance(outdoor_roofs).round(4) if outdoor_roofs.size > 0
  qaqc[:envelope][:outdoor_floors_average_conductance_w_per_m2_k] = OpenstudioStandards::Constructions.surfaces_get_conductance(outdoor_floors).round(4) if outdoor_floors.size > 0
  qaqc[:envelope][:ground_walls_average_conductance_w_per_m2_k]  	= OpenstudioStandards::Constructions.surfaces_get_conductance(ground_walls).round(4) if ground_walls.size > 0
  qaqc[:envelope][:ground_roofs_average_conductance_w_per_m2_k]  	= OpenstudioStandards::Constructions.surfaces_get_conductance(ground_roofs).round(4) if ground_roofs.size > 0
  qaqc[:envelope][:ground_floors_average_conductance_w_per_m2_k]  = OpenstudioStandards::Constructions.surfaces_get_conductance(ground_floors).round(4) if ground_floors.size > 0
  qaqc[:envelope][:windows_average_conductance_w_per_m2_k]  		= OpenstudioStandards::Constructions.surfaces_get_conductance(windows).round(4) if windows.size > 0
  qaqc[:envelope][:skylights_average_conductance_w_per_m2_k]  	= OpenstudioStandards::Constructions.surfaces_get_conductance(skylights).round(4) if skylights.size > 0
  qaqc[:envelope][:doors_average_conductance_w_per_m2_k]  		= OpenstudioStandards::Constructions.surfaces_get_conductance(doors).round(4) if doors.size > 0
  qaqc[:envelope][:overhead_doors_average_conductance_w_per_m2_k] = OpenstudioStandards::Constructions.surfaces_get_conductance(overhead_doors).round(4) if overhead_doors.size > 0
  qaqc[:envelope][:fdwr]  										= (BTAP::Geometry::get_fwdr(model) * 100.0).round(1)
  qaqc[:envelope][:srr]  											= (BTAP::Geometry::get_srr(model) * 100.0).round(1)


  qaqc[:envelope][:constructions] = {}
  qaqc[:envelope][:constructions][:exterior_fenestration] = []
  constructions = []
  outdoor_subsurfaces.each { |surface| constructions << surface.construction.get }
  ext_const_base = Hash.new(0)
  constructions.each { |name| ext_const_base[name] += 1 }
  #iterate thought each construction and get store data
  ext_const_base.sort.each do |construction, count|
    construction_info = {}
    qaqc[:envelope][:constructions][:exterior_fenestration] << construction_info
    construction_info[:name] = construction.name.get
    construction_info[:net_area_m2] = construction.getNetArea.round(2)
    construction_info[:thermal_conductance_m2_w_per_k] = OpenstudioStandards::Constructions.construction_get_conductance(construction).round(3)
    construction_info[:solar_transmittance] = OpenstudioStandards::Constructions.construction_get_solar_transmittance(construction).round(3)
    construction_info[:visible_tranmittance] = OpenstudioStandards::Constructions.construction_get_visible_transmittance(construction).round(3)
  end

  #Exterior
  qaqc[:envelope][:constructions][:exterior_opaque] = []
  constructions = []
  outdoor_surfaces.each { |surface| constructions << surface.construction.get }
  ext_const_base = Hash.new(0)
  constructions.each { |name| ext_const_base[name] += 1 }
  #iterate thought each construction and get store data
  ext_const_base.sort.each do |construction, count|
    construction_info = {}
    qaqc[:envelope][:constructions][:exterior_opaque] << construction_info
    construction_info[:name] = construction.name.get
    construction_info[:net_area_m2] = construction.getNetArea.round(2)
    construction_info[:thermal_conductance_m2_w_per_k] = construction.thermalConductance.get.round(3) if construction.thermalConductance.is_initialized
    construction_info[:net_area_m2] = construction.to_Construction.get.getNetArea.round(2)
    construction_info[:solar_absorptance] = construction.to_Construction.get.layers[0].exteriorVisibleAbsorptance.get
  end

  #Ground
  qaqc[:envelope][:constructions][:ground] = []
  constructions = []
  ground_surfaces.each { |surface| constructions << surface.construction.get }
  ext_const_base = Hash.new(0)
  constructions.each { |name| ext_const_base[name] += 1 }
  #iterate thought each construction and get store data
  ext_const_base.sort.each do |construction, count|
    construction_info = {}
    qaqc[:envelope][:constructions][:ground] << construction_info
    construction_info[:name] = construction.name.get
    construction_info[:net_area_m2] = construction.getNetArea.round(2)
    construction_info[:thermal_conductance_m2_w_per_k] = construction.thermalConductance.get.round(3) if construction.thermalConductance.is_initialized
    construction_info[:net_area_m2] = construction.to_Construction.get.getNetArea.round(2)
    construction_info[:solar_absorptance] = construction.to_Construction.get.layers[0].exteriorVisibleAbsorptance.get
  end


  # Store Space data.
  qaqc[:spaces] =[]
  model.getSpaces.sort.each do |space|
    spaceinfo = {}
    qaqc[:spaces] << spaceinfo
    spaceinfo[:name] = space.name.get #name should be defined test
    spaceinfo[:multiplier] = space.multiplier
    spaceinfo[:volume] = space.volume # should be greater than zero
    spaceinfo[:exterior_wall_area] = space.exteriorWallArea # just for information.
    spaceinfo[:space_type_name] = space.spaceType.get.name.get unless space.spaceType.empty? #should have a space types name defined.
    spaceinfo[:thermal_zone] = space.thermalZone.get.name.get unless space.thermalZone.empty? # should be assigned a thermalzone name.
    #puts space.name.get
    #puts space.thermalZone.empty?
    spaceinfo[:breathing_zone_outdoor_airflow_vbz] =-1
    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}' ")
    spaceinfo[:breathing_zone_outdoor_airflow_vbz] =breathing_zone_outdoor_airflow_vbz.get unless breathing_zone_outdoor_airflow_vbz.empty?
    spaceinfo[:infiltration_method] = 'N/A'
    spaceinfo[:infiltration_flow_per_m2]  =-1.0
    unless space.spaceInfiltrationDesignFlowRates[0].nil?
      spaceinfo[:infiltration_method] = space.spaceInfiltrationDesignFlowRates[0].designFlowRateCalculationMethod
      spaceinfo[:infiltration_flow_per_m2] = "N/A"
      spaceinfo[:infiltration_flow_per_m2] = space.spaceInfiltrationDesignFlowRates[0].flowperExteriorSurfaceArea.get.round(5) unless space.spaceInfiltrationDesignFlowRates[0].flowperExteriorSurfaceArea.empty?
    else
      error_warning <<  "space.spaceInfiltrationDesignFlowRates[0] is empty for #{spaceinfo[:name]}"
      error_warning <<  "space.spaceInfiltrationDesignFlowRates[0].designFlowRateCalculationMethod is empty for #{spaceinfo[:name]}"
      error_warning <<  "space.spaceInfiltrationDesignFlowRates[0].flowperExteriorSurfaceArea is empty for #{spaceinfo[:name]}"
    end

    #the following should have values unless the spacetype is "undefined" other they should be set to the correct NECB values.
    unless space.spaceType.empty?
      spaceinfo[:occupancy_schedule] = nil
      unless (space.spaceType.get.defaultScheduleSet.empty?)
        unless space.spaceType.get.defaultScheduleSet.get.numberofPeopleSchedule.empty?
          spaceinfo[:occupancy_schedule] = space.spaceType.get.defaultScheduleSet.get.numberofPeopleSchedule.get.name.get  #should not empty.
        else
          error_warning <<  "space.spaceType.get.defaultScheduleSet.get.numberofPeopleSchedule is empty for #{space.name.get }"
        end
      else
        error_warning <<  "space.spaceType.get.defaultScheduleSet is empty for #{space.name.get }"
      end

      spaceinfo[:occ_per_m2] = space.spaceType.get.people[0].peopleDefinition.peopleperSpaceFloorArea.get.round(3) unless space.spaceType.get.people[0].nil?
      unless space.spaceType.get.lights[0].nil?
        spaceinfo[:lighting_w_per_m2] = space.spaceType.get.lights[0].lightsDefinition.wattsperSpaceFloorArea#.get.round(3) unless space.spaceType.get.lights[0].nil?
        spaceinfo[:lighting_w_per_m2] = validate_optional(spaceinfo[:lighting_w_per_m2], model, -1.0)
        unless spaceinfo[:lighting_w_per_m2].nil?
          spaceinfo[:lighting_w_per_m2] = spaceinfo[:lighting_w_per_m2].round(3)
        end
      end
      #spaceinfo[:electric_w_per_m2] = space.spaceType.get.electricEquipment[0].electricEquipmentDefinition.wattsperSpaceFloorArea.get.round(3) unless space.spaceType.get.electricEquipment[0].nil?

      unless space.spaceType.get.electricEquipment[0].nil?
        unless space.spaceType.get.electricEquipment[0].electricEquipmentDefinition.wattsperSpaceFloorArea.empty?
          spaceinfo[:electric_w_per_m2] = space.spaceType.get.electricEquipment[0].electricEquipmentDefinition.wattsperSpaceFloorArea.get.round(3)
        end
      end
      spaceinfo[:shw_m3_per_s] = space.waterUseEquipment[0].waterUseEquipmentDefinition.peakFlowRate.round(3) unless space.waterUseEquipment[0].nil?
      spaceinfo[:waterUseEquipment] = []
      if !space.waterUseEquipment.empty?
        waterUseEquipment_info={}
        spaceinfo[:waterUseEquipment] << waterUseEquipment_info
        waterUseEquipment_info[:peak_flow_rate]= space.waterUseEquipment[0].waterUseEquipmentDefinition.peakFlowRate
        waterUseEquipment_info[:peak_flow_rate_per_area] = waterUseEquipment_info[:peak_flow_rate] / space.floorArea
        area_per_occ = space.spaceType.get.people[0].spaceFloorAreaPerPerson.get
        #                             Watt per person =             m3/s/m3                * 1000W/kW * (specific heat * dT) * m2/person
        waterUseEquipment_info[:shw_watts_per_person] = waterUseEquipment_info[:peak_flow_rate_per_area] * 1000 * (4.19 * 44.4) * 1000 * area_per_occ
        #puts waterUseEquipment_info[:shw_watts_per_person]
        #puts "\n\n\n"
      end
    else
      error_warning <<  "space.spaceType is empty for #{space.name.get }"
    end
  end

  # Store Thermal zone data
  qaqc[:thermal_zones] = []
  model.getThermalZones.sort.each do  |zone|
    zoneinfo = {}
    qaqc[:thermal_zones] << zoneinfo
    zoneinfo[:name] = zone.name.get
    zoneinfo[:floor_area] = zone.floorArea
    zoneinfo[:multiplier] = zone.multiplier
    zoneinfo[:is_conditioned] = "N/A"
    unless zone.isConditioned.empty?
      zoneinfo[:is_conditioned] = zone.isConditioned.get
    else
      error_warning <<  "zone.isConditioned is empty for #{zone.name.get}"
    end

    zoneinfo[:is_ideal_air_loads] = zone.useIdealAirLoads
    zoneinfo[:heating_sizing_factor] = -1.0
    unless zone.sizingZone.zoneHeatingSizingFactor.empty?
      zoneinfo[:heating_sizing_factor] = zone.sizingZone.zoneHeatingSizingFactor.get
    else
      error_warning <<  "zone.sizingZone.zoneHeatingSizingFactor is empty for #{zone.name.get}"
    end

    zoneinfo[:cooling_sizing_factor] = -1.0 #zone.sizingZone.zoneCoolingSizingFactor.get
    unless zone.sizingZone.zoneCoolingSizingFactor.empty?
      zoneinfo[:cooling_sizing_factor] = zone.sizingZone.zoneCoolingSizingFactor.get
    else
      error_warning <<  "zone.sizingZone.zoneCoolingSizingFactor is empty for #{zone.name.get}"
    end

    zoneinfo[:zone_heating_design_supply_air_temperature] = zone.sizingZone.zoneHeatingDesignSupplyAirTemperature
    zoneinfo[:zone_cooling_design_supply_air_temperature] = zone.sizingZone.zoneCoolingDesignSupplyAirTemperature
    zoneinfo[:spaces] = []
    zone.spaces.sort.each do |space|
      spaceinfo ={}
      zoneinfo[:spaces] << spaceinfo
      spaceinfo[:name] = space.name.get
      spaceinfo[:type] = space.spaceType.get.name.get unless space.spaceType.empty?
    end
    zoneinfo[:equipment] = []
    zone.equipmentInHeatingOrder.each do |equipment|
      item = {}
      zoneinfo[:equipment] << item
      item[:name] = equipment.name.get
      if equipment.to_ZoneHVACComponent.is_initialized
        item[:type] = 'ZoneHVACComponent'
      elsif  equipment.to_StraightComponent.is_initialized
        item[:type] = 'StraightComponent'
      end
    end
  end #zone
  # Store Air Loop Information
  qaqc[:air_loops] = []
  model.getAirLoopHVACs.sort.each do |air_loop|
    air_loop_info = {}
    air_loop_info[:name] = air_loop.name.get
    air_loop_info[:thermal_zones] = []
    air_loop_info[:total_floor_area_served] = 0.0
    air_loop_info[:total_breathing_zone_outdoor_airflow_vbz] = 0.0
    air_loop.thermalZones.sort.each do |zone|
      air_loop_info[:thermal_zones] << zone.name.get
      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='#{zone.name.get.to_s.upcase}' ")
      vbz = validate_optional(vbz, model, 0)
      air_loop_info[:total_breathing_zone_outdoor_airflow_vbz] += vbz
      air_loop_info[:total_floor_area_served] += zone.floorArea
    end
    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}' ")
    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)

    air_loop_info[:outdoor_air_L_per_s] = -1.0
    unless air_loop_info[:area_outdoor_air_rate_m3_per_s_m2] ==-1.0
      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
    end
    #Fan

    unless air_loop.supplyFan.empty?
      air_loop_info[:supply_fan] = {}
      if air_loop.supplyFan.get.to_FanConstantVolume.is_initialized
        air_loop_info[:supply_fan][:type] = 'CV'
        fan = air_loop.supplyFan.get.to_FanConstantVolume.get
      elsif air_loop.supplyFan.get.to_FanVariableVolume.is_initialized
        air_loop_info[:supply_fan][:type]  = 'VV'
        fan = air_loop.supplyFan.get.to_FanVariableVolume.get
      end
      air_loop_info[:supply_fan][:name] = fan.name.get
      #puts "\n\n\n\n#{fan.name.get}\n\n\n\n"
      air_loop_info[:supply_fan][:fan_efficiency] = fan.fanEfficiency
      air_loop_info[:supply_fan][:motor_efficiency] = fan.motorEfficiency
      air_loop_info[:supply_fan][:pressure_rise] = fan.pressureRise
      air_loop_info[:supply_fan][:max_air_flow_rate_m3_per_s]  = -1.0

      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' ")
      max_air_flow_info = validate_optional(max_air_flow_info, model, "N/A")
      unless max_air_flow_info == "N/A"
        if max_air_flow_info.include? "#{air_loop_info[:supply_fan][:name].to_s.upcase}"
          air_loop_info[:supply_fan][:max_air_flow_rate_m3_per_s] = model.sqlFile().get().execAndReturnFirstDouble("SELECT Value FROM TabularDataWithStrings WHERE ReportName='EquipmentSummary' AND ReportForString='Entire Facility' AND TableName='Fans' AND ColumnName='Max Air Flow Rate' AND Units='m3/s' AND RowName='#{air_loop_info[:supply_fan][:name].upcase}' ").get
          air_loop_info[:supply_fan][:rated_electric_power_w] = model.sqlFile().get().execAndReturnFirstDouble("SELECT Value FROM TabularDataWithStrings WHERE ReportName='EquipmentSummary' AND ReportForString='Entire Facility' AND TableName='Fans' AND ColumnName='Rated Electric Power' AND Units='W' AND RowName='#{air_loop_info[:supply_fan][:name].upcase}' ").get
        else
          error_warning <<  "#{air_loop_info[:supply_fan][:name]} does not exist in sql file WHERE ReportName='EquipmentSummary' AND ReportForString='Entire Facility' AND TableName='Fans' AND ColumnName='Max Air Flow Rate' AND Units='m3/s'"
        end
      else
        error_warning <<  "max_air_flow_info is nil because the following sql statement returned nil: RowName FROM TabularDataWithStrings WHERE ReportName='EquipmentSummary' AND ReportForString='Entire Facility' AND TableName='Fans' AND ColumnName='Max Air Flow Rate' AND Units='m3/s' "
      end
    end

    #economizer
    air_loop_info[:economizer] = {}
    air_loop_info[:economizer][:name] = air_loop.airLoopHVACOutdoorAirSystem.get.getControllerOutdoorAir.name.get
    air_loop_info[:economizer][:control_type] = air_loop.airLoopHVACOutdoorAirSystem.get.getControllerOutdoorAir.getEconomizerControlType

    #DX cooling coils
    air_loop_info[:cooling_coils] ={}
    air_loop_info[:cooling_coils][:dx_single_speed]=[]
    air_loop_info[:cooling_coils][:dx_two_speed]=[]

    #Heating Coil
    air_loop_info[:heating_coils] = {}
    air_loop_info[:heating_coils][:coil_heating_gas] = []
    air_loop_info[:heating_coils][:coil_heating_electric]= []
    air_loop_info[:heating_coils][:coil_heating_water]= []

    #Heat Excahnger
    air_loop_info[:heat_exchanger] = {}

    air_loop.supplyComponents.each do |supply_comp|
      if supply_comp.to_CoilHeatingGas.is_initialized
        coil={}
        air_loop_info[:heating_coils][:coil_heating_gas] << coil
        gas = supply_comp.to_CoilHeatingGas.get
        coil[:name]=gas.name.get
        coil[:type]="Gas"
        coil[:efficency] = gas.gasBurnerEfficiency
        #coil[:nominal_capacity]= gas.nominalCapacity()
        coil[:nominal_capacity]= model.sqlFile().get().execAndReturnFirstDouble("SELECT Value FROM TabularDataWithStrings WHERE ReportName='EquipmentSummary' AND ReportForString='Entire Facility' AND TableName='Heating Coils' AND ColumnName='Nominal Total Capacity' AND RowName='#{coil[:name].to_s.upcase}'")
        coil[:nominal_capacity]=validate_optional(coil[:nominal_capacity],model,-1.0 )
      end
      if supply_comp.to_CoilHeatingElectric.is_initialized
        coil={}
        air_loop_info[:heating_coils][:coil_heating_electric] << coil
        electric = supply_comp.to_CoilHeatingElectric.get
        coil[:name]= electric.name.get
        coil[:type]= "Electric"
        coil[:nominal_capacity]= model.sqlFile().get().execAndReturnFirstDouble("SELECT Value FROM TabularDataWithStrings WHERE ReportName='EquipmentSummary' AND ReportForString='Entire Facility' AND TableName='Heating Coils' AND ColumnName='Nominal Total Capacity' AND RowName='#{coil[:name].to_s.upcase}'")
        coil[:nominal_capacity]=validate_optional(coil[:nominal_capacity],model,-1.0 )
      end
      if supply_comp.to_CoilHeatingWater.is_initialized
        coil={}
        air_loop_info[:heating_coils][:coil_heating_water] << coil
        water = supply_comp.to_CoilHeatingWater.get
        coil[:name]= water.name.get
        coil[:type]= "Water"
        coil[:nominal_capacity]= model.sqlFile().get().execAndReturnFirstDouble("SELECT Value FROM TabularDataWithStrings WHERE ReportName='EquipmentSummary' AND ReportForString='Entire Facility' AND TableName='Heating Coils' AND ColumnName='Nominal Total Capacity' AND RowName='#{coil[:name].to_s.upcase}'")
        coil[:nominal_capacity]=validate_optional(coil[:nominal_capacity],model,-1.0 )
      end
      if supply_comp.to_HeatExchangerAirToAirSensibleAndLatent.is_initialized
        heatExchanger = supply_comp.to_HeatExchangerAirToAirSensibleAndLatent.get
        air_loop_info[:heat_exchanger][:name] = heatExchanger.name.get
      end
    end

    #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
    #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}'


    #Collect all the fans into the the array.
    air_loop.supplyComponents.each do |supply_comp|
      if supply_comp.to_CoilCoolingDXSingleSpeed.is_initialized
        coil = {}
        air_loop_info[:cooling_coils][:dx_single_speed] << coil
        single_speed = supply_comp.to_CoilCoolingDXSingleSpeed.get
        coil[:name] = single_speed.name.get
        coil[:cop] = single_speed.ratedCOP.to_f
        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}' ")
        coil[:nominal_total_capacity_w] = validate_optional(coil[:nominal_total_capacity_w], model, -1.0)
      end
      if supply_comp.to_CoilCoolingDXTwoSpeed.is_initialized
        coil = {}
        air_loop_info[:cooling_coils][:dx_two_speed] << coil
        two_speed = supply_comp.to_CoilCoolingDXTwoSpeed.get
        coil[:name] = two_speed.name.get
        coil[:cop_low] = two_speed.ratedLowSpeedCOP.to_f
        coil[:cop_high] =  two_speed.ratedHighSpeedCOP.to_f
        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}' ")
        coil[:nominal_total_capacity_w] = validate_optional(coil[:nominal_total_capacity_w] , model,-1.0)
      end
    end
    qaqc[:air_loops] << air_loop_info
  end


  qaqc[:plant_loops] = []
  model.getPlantLoops.sort.each do |plant_loop|
    plant_loop_info = {}
    qaqc[:plant_loops] << plant_loop_info
    plant_loop_info[:name] = plant_loop.name.get

    sizing = plant_loop.sizingPlant
    plant_loop_info[:design_loop_exit_temperature] = sizing.designLoopExitTemperature
    plant_loop_info[:loop_design_temperature_difference] = sizing.loopDesignTemperatureDifference

    #Create Container for plant equipment arrays.
    plant_loop_info[:pumps] = []
    plant_loop_info[:boilers] = []
    plant_loop_info[:chiller_electric_eir] = []
    plant_loop_info[:cooling_tower_single_speed] = []
    plant_loop_info[:water_heater_mixed] =[]
    plant_loop.supplyComponents.each do |supply_comp|

      #Collect Constant Speed
      if supply_comp.to_PumpConstantSpeed.is_initialized
        pump = supply_comp.to_PumpConstantSpeed.get
        pump_info = {}
        plant_loop_info[:pumps] << pump_info
        pump_info[:name] = pump.name.get
        pump_info[:type] = "Pump:ConstantSpeed"
        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}' ")
        pump_info[:head_pa] = validate_optional(pump_info[:head_pa], model, -1.0)
        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}' ")
        pump_info[:water_flow_m3_per_s] = validate_optional(pump_info[:water_flow_m3_per_s], model, -1.0)
        pump_info[:electric_power_w] = model.sqlFile().get().execAndReturnFirstDouble("SELECT Value FROM TabularDataWithStrings WHERE ReportName='EquipmentSummary' AND ReportForString='Entire Facility' AND TableName='Pumps' AND ColumnName='Electric Power' AND RowName='#{pump_info[:name].upcase}' ")
        pump_info[:electric_power_w] = validate_optional(pump_info[:electric_power_w], model, -1.0)
        pump_info[:motor_efficency] = pump.motorEfficiency
      end

      #Collect Variable Speed
      if supply_comp.to_PumpVariableSpeed.is_initialized
        pump = supply_comp.to_PumpVariableSpeed.get
        pump_info = {}
        plant_loop_info[:pumps] << pump_info
        pump_info[:name] = pump.name.get
        pump_info[:type] = "Pump:VariableSpeed"
        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}' ")
        pump_info[:head_pa] = validate_optional(pump_info[:head_pa], model, -1.0)
        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}' ")
        pump_info[:water_flow_m3_per_s] = validate_optional(pump_info[:water_flow_m3_per_s], model, -1.0)
        pump_info[:electric_power_w] = model.sqlFile().get().execAndReturnFirstDouble("SELECT Value FROM TabularDataWithStrings WHERE ReportName='EquipmentSummary' AND ReportForString='Entire Facility' AND TableName='Pumps' AND ColumnName='Electric Power' AND RowName='#{pump_info[:name].upcase}' ")
        pump_info[:electric_power_w] = validate_optional(pump_info[:electric_power_w], model, -1.0)
        pump_info[:motor_efficency] = pump.motorEfficiency
      end

      # Collect HotWaterBoilers
      if supply_comp.to_BoilerHotWater.is_initialized
        boiler = supply_comp.to_BoilerHotWater.get
        boiler_info = {}
        plant_loop_info[:boilers] << boiler_info
        boiler_info[:name] = boiler.name.get
        boiler_info[:type] = "Boiler:HotWater"
        boiler_info[:fueltype] = boiler.fuelType
        boiler_info[:nominal_capacity] = boiler.nominalCapacity
        boiler_info[:nominal_capacity] = validate_optional(boiler_info[:nominal_capacity], model, -1.0)
      end

      # Collect ChillerElectricEIR
      if supply_comp.to_ChillerElectricEIR.is_initialized
        chiller = supply_comp.to_ChillerElectricEIR.get
        chiller_info = {}
        plant_loop_info[:chiller_electric_eir] << chiller_info
        chiller_info[:name] = chiller.name.get
        chiller_info[:type] = "Chiller:Electric:EIR"
        chiller_info[:reference_capacity] = validate_optional(chiller.referenceCapacity, model, -1.0)
        chiller_info[:reference_leaving_chilled_water_temperature] =chiller.referenceLeavingChilledWaterTemperature
      end

      # Collect CoolingTowerSingleSpeed
      if supply_comp.to_CoolingTowerSingleSpeed.is_initialized
        coolingTower = supply_comp.to_CoolingTowerSingleSpeed.get
        coolingTower_info = {}
        plant_loop_info[:cooling_tower_single_speed] << coolingTower_info
        coolingTower_info[:name] = coolingTower.name.get
        coolingTower_info[:type] = "CoolingTower:SingleSpeed"
        coolingTower_info[:fan_power_at_design_air_flow_rate] = validate_optional(coolingTower.fanPoweratDesignAirFlowRate, model, -1.0)

      end

      # Collect WaterHeaterMixed
      if supply_comp.to_WaterHeaterMixed.is_initialized
        waterHeaterMixed = supply_comp.to_WaterHeaterMixed.get
        waterHeaterMixed_info = {}
        plant_loop_info[:water_heater_mixed] << waterHeaterMixed_info
        waterHeaterMixed_info[:name] = waterHeaterMixed.name.get
        waterHeaterMixed_info[:type] = "WaterHeater:Mixed"
        waterHeaterMixed_info[:heater_thermal_efficiency] = waterHeaterMixed.heaterThermalEfficiency.get unless waterHeaterMixed.heaterThermalEfficiency.empty?
        waterHeaterMixed_info[:heater_fuel_type] = waterHeaterMixed.heaterFuelType
      end
    end

    qaqc[:eplusout_err] ={}
    warnings = model.sqlFile().get().execAndReturnVectorOfString("SELECT ErrorMessage FROM Errors WHERE ErrorType='0' ")
    warnings = validate_optional(warnings, model, "N/A")
    unless warnings == "N/A"
      qaqc[:eplusout_err][:warnings] = model.sqlFile().get().execAndReturnVectorOfString("SELECT ErrorMessage FROM Errors WHERE ErrorType='0' ").get
      qaqc[:eplusout_err][:fatal] =model.sqlFile().get().execAndReturnVectorOfString("SELECT ErrorMessage FROM Errors WHERE ErrorType='2' ").get
      qaqc[:eplusout_err][:severe] =model.sqlFile().get().execAndReturnVectorOfString("SELECT ErrorMessage FROM Errors WHERE ErrorType='1' ").get
    end

    qaqc[:ruby_warnings] = error_warning
  end


  # Perform qaqc
  necb_2011_qaqc(qaqc, model) if qaqc[:building][:name].include?("NECB2011") #had to nodify this because this is specifically for "NECB-2011" standard
  sanity_check(qaqc)

  qaqc[:information] = qaqc[:information].sort
  qaqc[:warnings] = qaqc[:warnings].sort
  qaqc[:errors] = qaqc[:errors].sort
  qaqc[:unique_errors]= qaqc[:unique_errors].sort

  return qaqc
end

.runner_register(type, text, runner = nil) ⇒ Object

A wrapper for outputing feedback to users and developers.

BTAP::runner_register("InitialCondition",   "Your Information Message Here", runner)
BTAP::runner_register("Info",    "Your Information Message Here", runner)
BTAP::runner_register("Warning", "Your Information Message Here", runner)
BTAP::runner_register("Error",   "Your Information Message Here", runner)
BTAP::runner_register("Debug",   "Your Information Message Here", runner)
BTAP::runner_register("FinalCondition",   "Your Information Message Here", runner)
@params type [String]
@params runner [OpenStudio::Ruleset::OSRunner] # or a nil.


115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/openstudio-standards/btap/btap.rb', line 115

def self.runner_register(type,text,runner = nil)

  #dump to console.
  puts "#{type.upcase}: #{text}"
  #dump to runner.
  if runner.is_a?(OpenStudio::Ruleset::OSRunner)
    case type.downcase
    when "info"
      runner.registerInfo(text)
    when "warning"
      runner.registerWarning(text)
    when "error"
      runner.registerError(text)
    when "notapplicable"
      runner.registerAsNotApplicable(text)
    when "finalcondition"
      runner.registerFinalCondition(text)
    when "initialcondition"
      runner.registerInitialCondition(text)
    when "debug"
    when "macro"
    else
      raise("Runner Register type #{type.downcase} not info,warning,error,notapplicable,finalcondition,initialcondition,macro.")
    end
  end
end

.runner_register_value(name, value, runner = nil) ⇒ Object



142
143
144
145
146
147
# File 'lib/openstudio-standards/btap/btap.rb', line 142

def self.runner_register_value(name,value,runner = nil)
  if runner.is_a?(OpenStudio::Ruleset::OSRunner)
    runner.registerValue( name,value.to_s)
    BTAP::runner_register("Info", "#{name} = #{value} has been registered in the runner", runner)
  end
end