openstudio-extension 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  # *******************************************************************************
4
2
  # OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC.
5
3
  # All rights reserved.
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  # *******************************************************************************
4
2
  # OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC.
5
3
  # All rights reserved.
@@ -93,6 +91,7 @@ module OpenStudio
93
91
 
94
92
  result << obj
95
93
  end
94
+
96
95
  return result.uniq
97
96
  end
98
97
 
@@ -107,7 +106,7 @@ module OpenStudio
107
106
  result << dir if dir
108
107
  rescue StandardError
109
108
  end
110
- return result.uniq
109
+ return result.uniq.sort
111
110
  end
112
111
 
113
112
  ##
@@ -121,7 +120,7 @@ module OpenStudio
121
120
  result << dir if dir
122
121
  rescue StandardError
123
122
  end
124
- return result.uniq
123
+ return result.uniq.sort
125
124
  end
126
125
 
127
126
  ##
@@ -228,5 +227,26 @@ module OpenStudio
228
227
 
229
228
  return osw
230
229
  end
230
+
231
+ ##
232
+ # Module method used to check whether a measure is present in an OSW file
233
+ ##
234
+ # @param [Hash] in_osw Initial OSW object as a Hash, keys should be symbolized
235
+ # @param [String] measure_dir_name Directory name of measure to set argument on
236
+ # @param [String] step_name Optional argument, if present used to further identify the measure
237
+ #
238
+ # @return [Boolean] true or false
239
+ def self.measure_in_osw(osw, measure_dir_name, step_name = nil)
240
+ result = false
241
+ osw[:steps].each do |step|
242
+ if step[:measure_dir_name] == measure_dir_name
243
+ if step_name.nil? || step[:name] == step_name
244
+ result = true
245
+ end
246
+ end
247
+ end
248
+
249
+ return result
250
+ end
231
251
  end
232
252
  end
@@ -765,7 +765,7 @@ module OsLib_Geometry
765
765
  story_hash.each_with_index do |(story_name, story_data), index|
766
766
  # make new story unless story at requested height already exists.
767
767
  story = nil
768
- model.getBuildingStorys.each do |ext_story|
768
+ model.getBuildingStorys.sort.each do |ext_story|
769
769
  if (ext_story.nominalZCoordinate.to_f - story_data[:space_origin_z].to_f).abs < 0.01
770
770
  story = ext_story
771
771
  end
@@ -1133,11 +1133,11 @@ module OsLib_Geometry
1133
1133
  # todo - also odd with multi-height spaces
1134
1134
  def self.calculate_perimeter(model)
1135
1135
  perimeter = 0
1136
- model.getSpaces.each do |space|
1136
+ model.getSpaces.sort.each do |space|
1137
1137
  # counter to use later
1138
1138
  edge_hash = {}
1139
1139
  edge_counter = 0
1140
- space.surfaces.each do |surface|
1140
+ space.surfaces.sort.each do |surface|
1141
1141
  # get vertices
1142
1142
  vertex_hash = {}
1143
1143
  vertex_counter = 0
@@ -117,7 +117,7 @@ module OsLib_HVAC
117
117
  zonesUnconditioned = []
118
118
 
119
119
  # get thermal zones
120
- zones = model.getThermalZones
120
+ zones = model.getThermalZones.sort
121
121
  zones.each do |zone|
122
122
  # assign appropriate zones to zonesPlenum or zonesUnconditioned (those that don't have thermostats or zone HVAC equipment)
123
123
  # if not conditioned then add to zonesPlenum or zonesUnconditioned
@@ -177,9 +177,9 @@ module OsLib_HVAC
177
177
 
178
178
  def self.reportConditions(model, runner, condition,extra_string = '')
179
179
 
180
- airloops = model.getAirLoopHVACs
181
- plantLoops = model.getPlantLoops
182
- zones = model.getThermalZones
180
+ airloops = model.getAirLoopHVACs.sort
181
+ plantLoops = model.getPlantLoops.sort
182
+ zones = model.getThermalZones.sort
183
183
 
184
184
  # count up zone equipment (not counting zone exhaust fans)
185
185
  zoneHasEquip = false
@@ -205,9 +205,9 @@ module OsLib_HVAC
205
205
  end
206
206
 
207
207
  def self.removeEquipment(model, runner)
208
- airloops = model.getAirLoopHVACs
209
- plantLoops = model.getPlantLoops
210
- zones = model.getThermalZones
208
+ airloops = model.getAirLoopHVACs.sort
209
+ plantLoops = model.getPlantLoops.sort
210
+ zones = model.getThermalZones.sort
211
211
 
212
212
  # remove all airloops
213
213
  airloops.each(&:remove)
@@ -244,7 +244,7 @@ module OsLib_HVAC
244
244
  require "#{File.dirname(__FILE__)}/os_lib_schedules"
245
245
 
246
246
  schedulesHVAC = {}
247
- airloops = model.getAirLoopHVACs
247
+ airloops = model.getAirLoopHVACs.sort
248
248
 
249
249
  # find airloop with most primary spaces
250
250
  max_primary_spaces = 0
@@ -628,7 +628,7 @@ module OsLib_HVAC
628
628
 
629
629
  # check for water-cooled chillers
630
630
  waterCooledChiller = false
631
- model.getChillerElectricEIRs.each do |chiller|
631
+ model.getChillerElectricEIRs.sort.each do |chiller|
632
632
  next if waterCooledChiller == true
633
633
  if chiller.condenserType == 'WaterCooled'
634
634
  waterCooledChiller = true
@@ -678,7 +678,7 @@ module OsLib_HVAC
678
678
  pipe_supply_outlet.addToNode(condenser_loop.supplyOutletNode)
679
679
  setpoint_manager_follow_oa.addToNode(condenser_loop.supplyOutletNode)
680
680
  # demand side components
681
- model.getChillerElectricEIRs.each do |chiller|
681
+ model.getChillerElectricEIRs.sort.each do |chiller|
682
682
  if chiller.condenserType == 'WaterCooled' # works only if chillers not already connected to condenser loop(s)
683
683
  condenser_loop.addDemandBranchForComponent(chiller)
684
684
  end
@@ -771,7 +771,7 @@ module OsLib_HVAC
771
771
  primary_airloops = []
772
772
  # create primary airloop for each story
773
773
  assignedThermalZones = []
774
- model.getBuildingStorys.each do |building_story|
774
+ model.getBuildingStorys.sort.each do |building_story|
775
775
  # ML stories need to be reordered from the ground up
776
776
  thermalZonesToAdd = []
777
777
  building_story.spaces.each do |space|
@@ -1069,7 +1069,7 @@ module OsLib_HVAC
1069
1069
  def self.createSecondaryAirLoops(model, runner, options)
1070
1070
  secondary_airloops = []
1071
1071
  # create secondary airloop for each secondary zone
1072
- model.getThermalZones.each do |zone|
1072
+ model.getThermalZones.sort.each do |zone|
1073
1073
  if options['zonesSecondary'].include? zone
1074
1074
  # create secondary airloop
1075
1075
  airloop_secondary = OpenStudio::Model::AirLoopHVAC.new(model)
@@ -1314,7 +1314,7 @@ module OsLib_HVAC
1314
1314
  end
1315
1315
 
1316
1316
  def self.createPrimaryZoneEquipment(model, runner, options)
1317
- model.getThermalZones.each do |zone|
1317
+ model.getThermalZones.sort.each do |zone|
1318
1318
  if options['zonesPrimary'].include? zone
1319
1319
  if options['zoneHVAC'] == 'FanCoil'
1320
1320
  # create fan coil
@@ -1521,7 +1521,7 @@ module OsLib_HVAC
1521
1521
  def self.get_or_add_hot_water_loop(model)
1522
1522
  # How water loop
1523
1523
  hw_loop = nil
1524
- model.getLoops.each do |loop|
1524
+ model.getLoops.sort.each do |loop|
1525
1525
  if loop.name.to_s == 'Hot Water Loop' # sizingPlant has loopType method to do this better
1526
1526
  hw_loop = loop.to_PlantLoop.get
1527
1527
  end
@@ -1580,7 +1580,7 @@ module OsLib_HVAC
1580
1580
  # Chilled Water Plant
1581
1581
  # todo - add in logic here that if existing chw_loop is air cooled, replace it with this one.
1582
1582
  chw_loop = nil
1583
- model.getLoops.each do |loop|
1583
+ model.getLoops.sort.each do |loop|
1584
1584
  if loop.name.to_s == 'Chilled Water Loop'
1585
1585
  chw_loop = loop.to_PlantLoop.get
1586
1586
  end
@@ -1658,7 +1658,7 @@ module OsLib_HVAC
1658
1658
 
1659
1659
  # Condenser System
1660
1660
  cw_loop = nil
1661
- model.getLoops.each do |loop|
1661
+ model.getLoops.sort.each do |loop|
1662
1662
  if loop.name.to_s == 'Condenser Water Loop'
1663
1663
  cw_loop = loop.to_PlantLoop.get
1664
1664
  end
@@ -1702,7 +1702,7 @@ module OsLib_HVAC
1702
1702
  def self.get_or_add_air_cooled_chiller_loop(model)
1703
1703
  # Chilled Water Plant
1704
1704
  chw_loop = nil
1705
- model.getLoops.each do |loop|
1705
+ model.getLoops.sort.each do |loop|
1706
1706
  if loop.name.to_s == 'Chilled Water Loop'
1707
1707
  chw_loop = loop.to_PlantLoop.get
1708
1708
  end
@@ -79,6 +79,11 @@ module OsLib_ModelGeneration
79
79
  array << 'Hospital'
80
80
  array << 'Outpatient'
81
81
  array << 'SuperMarket'
82
+ array << 'Laboratory'
83
+ array << 'LargeDataCenterLowITE'
84
+ array << 'LargeDataCenterHighITE'
85
+ array << 'SmallDataCenterLowITE'
86
+ array << 'SmallDataCenterHighITE'
82
87
 
83
88
  return array
84
89
  end
@@ -328,7 +333,7 @@ module OsLib_ModelGeneration
328
333
  supermarket_a = 45001.0
329
334
  supermarket_p = 866.0
330
335
  supermarket_wwr = 1880.0 / (supermarket_p * 20.0)
331
- supermarket_aspet_ratio = calc_aspect_ratio(supermarket_a, supermarket_p)
336
+ supermarket_aspect_ratio = calc_aspect_ratio(supermarket_a, supermarket_p)
332
337
 
333
338
  hash['SmallOffice'] = { aspect_ratio: 1.5, wwr: 0.15, typical_story: 10.0, perim_mult: 1.0 }
334
339
  hash['MediumOffice'] = { aspect_ratio: 1.5, wwr: 0.33, typical_story: 13.0, perim_mult: 1.0 }
@@ -351,7 +356,14 @@ module OsLib_ModelGeneration
351
356
  hash['MidriseApartment'] = { aspect_ratio: 2.75, wwr: 0.15, typical_story: 10.0, perim_mult: 1.0 }
352
357
  hash['HighriseApartment'] = { aspect_ratio: 2.75, wwr: 0.15, typical_story: 10.0, perim_mult: 1.0 }
353
358
  # SuperMarket inputs come from prototype model
354
- hash['SuperMarket'] = { aspect_ratio: supermarket_aspet_ratio.round(1), wwr: supermarket_wwr.round(2), typical_story: 20.0, perim_mult: 1.0 }
359
+ hash['SuperMarket'] = { aspect_ratio: supermarket_aspect_ratio.round(1), wwr: supermarket_wwr.round(2), typical_story: 20.0, perim_mult: 1.0 }
360
+
361
+ # Add Laboratory and Data Centers
362
+ hash['Laboratory'] = { aspect_ratio: 1.33, wwr: 0.12, typical_story: 10.0, perim_mult: 1.0 }
363
+ hash['LargeDataCenterLowITE'] = { aspect_ratio: 1.67, wwr: 0.0, typical_story: 14.0, perim_mult: 1.0 }
364
+ hash['LargeDataCenterHighITE'] = { aspect_ratio: 1.67, wwr: 0.0, typical_story: 14.0, perim_mult: 1.0 }
365
+ hash['SmallDataCenterLowITE'] = { aspect_ratio: 1.5, wwr: 0.0, typical_story: 14.0, perim_mult: 1.0 }
366
+ hash['SmallDataCenterHighITE'] = { aspect_ratio: 1.5, wwr: 0.0, typical_story: 14.0, perim_mult: 1.0 }
355
367
 
356
368
  # DEER Prototypes
357
369
  hash['Asm'] = { aspect_ratio: 1.0, wwr: 0.19, typical_story: 15.0 }
@@ -664,6 +676,19 @@ module OsLib_ModelGeneration
664
676
  hash['Meeting'] = { ratio: 0.99, space_type_gen: true, default: true }
665
677
  hash['Restroom'] = { ratio: 0.99, space_type_gen: true, default: true }
666
678
  hash['Vestibule'] = { ratio: 0.99, space_type_gen: true, default: true }
679
+ elsif building_type == 'Laboratory'
680
+ hash['Office'] = { ratio: 0.50, space_type_gen: true, default: true }
681
+ hash['Open lab'] = { ratio: 0.35, space_type_gen: true, default: true }
682
+ hash['Equipment corridor'] = { ratio: 0.05, space_type_gen: true, default: true }
683
+ hash['Lab with fume hood'] = { ratio: 0.10, space_type_gen: true, default: true }
684
+ elsif building_type == 'LargeDataCenterHighITE'
685
+ hash['StandaloneDataCenter'] = { ratio: 1.0, space_type_gen: true, default: true }
686
+ elsif building_type == 'LargeDataCenterLowITE'
687
+ hash['StandaloneDataCenter'] = { ratio: 1.0, space_type_gen: true, default: true }
688
+ elsif building_type == 'SmallDataCenterHighITE'
689
+ hash['ComputerRoom'] = { ratio: 1.0, space_type_gen: true, default: true }
690
+ elsif building_type == 'SmallDataCenterLowITE'
691
+ hash['ComputerRoom'] = { ratio: 1.0, space_type_gen: true, default: true }
667
692
  # DEER Prototypes
668
693
  elsif building_type == 'Asm'
669
694
  hash['Auditorium'] = { ratio: 0.7658, space_type_gen: true, default: true }
@@ -884,6 +909,7 @@ module OsLib_ModelGeneration
884
909
  stories_flat = []
885
910
  stories_flat_counter = 0
886
911
  bar_hash[:stories].each_with_index do |(k, v), i|
912
+ #runner.registerInfo("STORY: k: #{k}, v: #{v}, index: #{i}")
887
913
  # k is invalid in some cases, old story object that has been removed, should be from low to high including basement
888
914
  # skip if source story insn't included in building area
889
915
  if v[:story_included_in_building_area].nil? || (v[:story_included_in_building_area] == true)
@@ -1024,7 +1050,7 @@ module OsLib_ModelGeneration
1024
1050
  # only intersect if make_mid_story_surfaces_adiabatic false
1025
1051
  if diagnostic_intersect
1026
1052
 
1027
- model.getPlanarSurfaces.each do |surface|
1053
+ model.getPlanarSurfaces.sort.each do |surface|
1028
1054
  array = []
1029
1055
  vertices = surface.vertices
1030
1056
  fixed = false
@@ -1050,7 +1076,7 @@ module OsLib_ModelGeneration
1050
1076
  end
1051
1077
 
1052
1078
  # remove collinear points in a surface
1053
- model.getPlanarSurfaces.each do |surface|
1079
+ model.getPlanarSurfaces.sort.each do |surface|
1054
1080
  new_vertices = OpenStudio.removeCollinear(surface.vertices)
1055
1081
  starting_count = surface.vertices.size
1056
1082
  final_count = new_vertices.size
@@ -1061,7 +1087,7 @@ module OsLib_ModelGeneration
1061
1087
  end
1062
1088
 
1063
1089
  # remove duplicate surfaces in a space (should be done after remove duplicate and collinear points)
1064
- model.getSpaces.each do |space|
1090
+ model.getSpaces.sort.each do |space|
1065
1091
 
1066
1092
  # secondary array to compare against
1067
1093
  surfaces_b = space.surfaces.sort
@@ -1105,7 +1131,7 @@ module OsLib_ModelGeneration
1105
1131
  end
1106
1132
  runner.registerInfo('Intersecting and matching surfaces in model, this will create additional geometry.')
1107
1133
  else #elsif bar_hash[:double_loaded_corridor] # only intersect spaces in each story, not between wtory
1108
- model.getBuilding.buildingStories.each do |story|
1134
+ model.getBuilding.buildingStories.sort.each do |story|
1109
1135
  # intersect and surface match two pair by pair
1110
1136
  spaces_b = story.spaces.sort
1111
1137
  # looping through vector of each space
@@ -1136,7 +1162,7 @@ module OsLib_ModelGeneration
1136
1162
  runner.registerInfo('Intersecting and matching surfaces in model, this will create additional geometry.')
1137
1163
  end
1138
1164
  else #elsif bar_hash[:double_loaded_corridor] # only intersect spaces in each story, not between wtory
1139
- model.getBuilding.buildingStories.each do |story|
1165
+ model.getBuilding.buildingStories.sort.each do |story|
1140
1166
  story_spaces = OpenStudio::Model::SpaceVector.new
1141
1167
  story.spaces.sort.each do |space|
1142
1168
  story_spaces << space
@@ -1152,11 +1178,11 @@ module OsLib_ModelGeneration
1152
1178
  # set boundary conditions if not already set when geometry was created
1153
1179
  # todo - update this to use space original z value vs. story name
1154
1180
  if bar_hash[:num_stories_below_grade] > 0
1155
- model.getBuildingStorys.each do |story|
1181
+ model.getBuildingStorys.sort.each do |story|
1156
1182
  next if !story.name.to_s.include?('Story B')
1157
- story.spaces.each do |space|
1183
+ story.spaces.sort.each do |space|
1158
1184
  next if not new_spaces.include?(space)
1159
- space.surfaces.each do |surface|
1185
+ space.surfaces.sort.each do |surface|
1160
1186
  next if surface.surfaceType != 'Wall'
1161
1187
  next if surface.outsideBoundaryCondition != 'Outdoors'
1162
1188
  surface.setOutsideBoundaryCondition('Ground')
@@ -1621,10 +1647,7 @@ module OsLib_ModelGeneration
1621
1647
  end
1622
1648
  end
1623
1649
  end
1624
-
1625
1650
  end
1626
-
1627
-
1628
1651
  end
1629
1652
 
1630
1653
  # bar_from_building_type_ratios
@@ -2354,7 +2377,7 @@ module OsLib_ModelGeneration
2354
2377
  if args['party_wall_fraction'] > 0
2355
2378
  actual_ext_wall_area = model.getBuilding.exteriorWallArea
2356
2379
  actual_party_wall_area = 0.0
2357
- model.getSurfaces.each do |surface|
2380
+ model.getSurfaces.sort.each do |surface|
2358
2381
  next if surface.outsideBoundaryCondition != 'Adiabatic'
2359
2382
  next if surface.surfaceType != 'Wall'
2360
2383
  actual_party_wall_area += surface.grossArea * surface.space.get.multiplier
@@ -2365,7 +2388,7 @@ module OsLib_ModelGeneration
2365
2388
  end
2366
2389
 
2367
2390
  # check ns/ew aspect ratio (harder to check when party walls are added)
2368
- wall_and_window_by_orientation = OsLib_Geometry.getExteriorWindowAndWllAreaByOrientation(model,model.getSpaces)
2391
+ wall_and_window_by_orientation = OsLib_Geometry.getExteriorWindowAndWllAreaByOrientation(model,model.getSpaces.sort)
2369
2392
  wall_ns = (wall_and_window_by_orientation['northWall'] + wall_and_window_by_orientation['southWall'])
2370
2393
  wall_ew = wall_and_window_by_orientation['eastWall'] + wall_and_window_by_orientation['westWall']
2371
2394
  wall_ns_ip = OpenStudio.convert(wall_ns,'m^2','ft^2').get
@@ -2560,6 +2583,19 @@ module OsLib_ModelGeneration
2560
2583
  # Make the standard applier
2561
2584
  standard = Standard.build((args['template']).to_s)
2562
2585
 
2586
+ # validate climate zone
2587
+ if !args.has_key?('climate_zone') || args['climate_zone'] == 'Lookup From Model'
2588
+ climate_zone = standard.model_get_building_climate_zone_and_building_type(model)['climate_zone']
2589
+ runner.registerInfo("Using climate zone #{climate_zone} from model")
2590
+ else
2591
+ climate_zone = args['climate_zone']
2592
+ runner.registerInfo("Using climate zone #{climate_zone} from user arguments")
2593
+ end
2594
+ if climate_zone == ''
2595
+ runner.registerError("Could not determine climate zone from measure arguments or model.")
2596
+ return false
2597
+ end
2598
+
2563
2599
  # make sure daylight savings is turned on up prior to any sizing runs being done.
2564
2600
  if args['enable_dst']
2565
2601
  start_date = '2nd Sunday in March'
@@ -2575,7 +2611,7 @@ module OsLib_ModelGeneration
2575
2611
 
2576
2612
  # remove internal loads
2577
2613
  if args['remove_objects']
2578
- model.getSpaceLoads.each do |instance|
2614
+ model.getSpaceLoads.sort.each do |instance|
2579
2615
  next if instance.name.to_s.include?('Elevator') # most prototype building types model exterior elevators with name Elevator
2580
2616
  next if instance.to_InternalMass.is_initialized
2581
2617
  next if instance.to_WaterUseEquipment.is_initialized
@@ -2585,7 +2621,7 @@ module OsLib_ModelGeneration
2585
2621
  model.getDefaultScheduleSets.each(&:remove)
2586
2622
  end
2587
2623
 
2588
- model.getSpaceTypes.each do |space_type|
2624
+ model.getSpaceTypes.sort.each do |space_type|
2589
2625
  # Don't add infiltration here; will be added later in the script
2590
2626
  test = standard.space_type_apply_internal_loads(space_type, true, true, true, true, true, false)
2591
2627
  if test == false
@@ -2604,7 +2640,7 @@ module OsLib_ModelGeneration
2604
2640
 
2605
2641
  # warn if spaces in model without space type
2606
2642
  spaces_without_space_types = []
2607
- model.getSpaces.each do |space|
2643
+ model.getSpaces.sort.each do |space|
2608
2644
  next if space.spaceType.is_initialized
2609
2645
  spaces_without_space_types << space
2610
2646
  end
@@ -2615,7 +2651,7 @@ module OsLib_ModelGeneration
2615
2651
 
2616
2652
  # identify primary building type (used for construction, and ideally HVAC as well)
2617
2653
  building_types = {}
2618
- model.getSpaceTypes.each do |space_type|
2654
+ model.getSpaceTypes.sort.each do |space_type|
2619
2655
  # populate hash of building types
2620
2656
  if space_type.standardsBuildingType.is_initialized
2621
2657
  bldg_type = space_type.standardsBuildingType.get
@@ -2646,13 +2682,6 @@ module OsLib_ModelGeneration
2646
2682
  else
2647
2683
  is_residential = 'No'
2648
2684
  end
2649
- if !args.has_key?('climate_zone') || args['climate_zone'] == 'Lookup From Model'
2650
- climate_zone = standard.model_get_building_climate_zone_and_building_type(model)['climate_zone']
2651
- runner.registerInfo("Using climate zone #{climate_zone} from model")
2652
- else
2653
- climate_zone = args['climate_zone']
2654
- runner.registerInfo("Using climate zone #{climate_zone} from user arguments")
2655
- end
2656
2685
  bldg_def_const_set = standard.model_add_construction_set(model, climate_zone, lookup_building_type, nil, is_residential)
2657
2686
  if bldg_def_const_set.is_initialized
2658
2687
  bldg_def_const_set = bldg_def_const_set.get
@@ -2666,7 +2695,7 @@ module OsLib_ModelGeneration
2666
2695
  end
2667
2696
 
2668
2697
  # address any adiabatic surfaces that don't have hard assigned constructions
2669
- model.getSurfaces.each do |surface|
2698
+ model.getSurfaces.sort.each do |surface|
2670
2699
  next if surface.outsideBoundaryCondition != 'Adiabatic'
2671
2700
  next if surface.construction.is_initialized
2672
2701
  surface.setAdjacentSurface(surface)
@@ -2690,11 +2719,11 @@ module OsLib_ModelGeneration
2690
2719
  if args['add_elevators']
2691
2720
 
2692
2721
  # remove elevators as spaceLoads or exteriorLights
2693
- model.getSpaceLoads.each do |instance|
2722
+ model.getSpaceLoads.sort.each do |instance|
2694
2723
  next if !instance.name.to_s.include?('Elevator') # most prototype building types model exterior elevators with name Elevator
2695
2724
  instance.remove
2696
2725
  end
2697
- model.getExteriorLightss.each do |ext_light|
2726
+ model.getExteriorLightss.sort.each do |ext_light|
2698
2727
  next if !ext_light.name.to_s.include?('Fuel equipment') # some prototype building types model exterior elevators by this name
2699
2728
  ext_light.remove
2700
2729
  end
@@ -2715,7 +2744,7 @@ module OsLib_ModelGeneration
2715
2744
  if args['add_exterior_lights']
2716
2745
 
2717
2746
  if args['remove_objects']
2718
- model.getExteriorLightss.each do |ext_light|
2747
+ model.getExteriorLightss.sort.each do |ext_light|
2719
2748
  next if ext_light.name.to_s.include?('Fuel equipment') # some prototype building types model exterior elevators by this name
2720
2749
  ext_light.remove
2721
2750
  end
@@ -2797,16 +2826,25 @@ module OsLib_ModelGeneration
2797
2826
  end
2798
2827
  end
2799
2828
 
2800
- # TODO: - when add methods below add bool to enable/disable them with default value to true
2829
+ # add_daylighting_controls (since outdated measure don't have this default to true if arg not found)
2830
+ if !args.has_key?('add_daylighting_controls')
2831
+ args['add_daylighting_controls'] = true
2832
+ end
2833
+ if args['add_daylighting_controls']
2834
+ # remove add_daylighting_controls objects
2835
+ if args['remove_objects']
2836
+ model.getDaylightingControls.each(&:remove)
2837
+ end
2801
2838
 
2802
- # add daylight controls, need to perform a sizing run for 2010
2803
- if args['template'] == '90.1-2010'
2804
- if standard.model_run_sizing_run(model, "#{Dir.pwd}/SRvt") == false
2805
- log_messages_to_runner(runner, debug = true)
2806
- return false
2839
+ # add daylight controls, need to perform a sizing run for 2010
2840
+ if args['template'] == '90.1-2010'
2841
+ if standard.model_run_sizing_run(model, "#{Dir.pwd}/SRvt") == false
2842
+ log_messages_to_runner(runner, debug = true)
2843
+ return false
2844
+ end
2807
2845
  end
2808
- end
2809
2846
  standard.model_add_daylighting_controls(model)
2847
+ end
2810
2848
 
2811
2849
  # add refrigeration
2812
2850
  if args['add_refrigeration']
@@ -2824,7 +2862,7 @@ module OsLib_ModelGeneration
2824
2862
  if args['add_internal_mass']
2825
2863
 
2826
2864
  if args['remove_objects']
2827
- model.getSpaceLoads.each do |instance|
2865
+ model.getSpaceLoads.sort.each do |instance|
2828
2866
  next unless instance.to_InternalMass.is_initialized
2829
2867
  instance.remove
2830
2868
  end
@@ -2847,7 +2885,7 @@ module OsLib_ModelGeneration
2847
2885
  model.getThermostatSetpointDualSetpoints.each(&:remove)
2848
2886
  end
2849
2887
 
2850
- model.getSpaceTypes.each do |space_type|
2888
+ model.getSpaceTypes.sort.each do |space_type|
2851
2889
  # create thermostat schedules
2852
2890
  # skip un-recognized space types
2853
2891
  next if standard.space_type_get_standards_data(space_type).empty?
@@ -2855,12 +2893,12 @@ module OsLib_ModelGeneration
2855
2893
  standard.space_type_apply_internal_load_schedules(space_type, false, false, false, false, false, false, true)
2856
2894
 
2857
2895
  # identify thermal thermostat and apply to zones (apply_internal_load_schedules names )
2858
- model.getThermostatSetpointDualSetpoints.each do |thermostat|
2896
+ model.getThermostatSetpointDualSetpoints.sort.each do |thermostat|
2859
2897
  next if thermostat.name.to_s != "#{space_type.name} Thermostat"
2860
2898
  next if !thermostat.coolingSetpointTemperatureSchedule.is_initialized
2861
2899
  next if !thermostat.heatingSetpointTemperatureSchedule.is_initialized
2862
2900
  runner.registerInfo("Assigning #{thermostat.name} to thermal zones with #{space_type.name} assigned.")
2863
- space_type.spaces.each do |space|
2901
+ space_type.spaces.sort.each do |space|
2864
2902
  next if !space.thermalZone.is_initialized
2865
2903
  space.thermalZone.get.setThermostatSetpointDualSetpoint(thermostat)
2866
2904
  end
@@ -3038,7 +3076,7 @@ module OsLib_ModelGeneration
3038
3076
  if args['add_internal_mass']
3039
3077
 
3040
3078
  if args['remove_objects']
3041
- model.getSpaceLoads.each do |instance|
3079
+ model.getSpaceLoads.sort.each do |instance|
3042
3080
  next unless instance.to_InternalMass.is_initialized
3043
3081
  instance.remove
3044
3082
  end
@@ -3091,8 +3129,8 @@ module OsLib_ModelGeneration
3091
3129
  set_building_defaults = runner.getBoolArgumentValue('set_building_defaults', user_arguments)
3092
3130
 
3093
3131
  # reporting initial condition of model
3094
- starting_spaceTypes = model.getSpaceTypes
3095
- starting_constructionSets = model.getDefaultConstructionSets
3132
+ starting_spaceTypes = model.getSpaceTypes.sort
3133
+ starting_constructionSets = model.getDefaultConstructionSets.sort
3096
3134
  runner.registerInitialCondition("The building started with #{starting_spaceTypes.size} space types and #{starting_constructionSets.size} construction sets.")
3097
3135
 
3098
3136
  # lookup space types for specified building type (false indicates not to use whole building type only)
@@ -3129,7 +3167,7 @@ module OsLib_ModelGeneration
3129
3167
  if create_space_types
3130
3168
 
3131
3169
  # array of starting space types
3132
- space_types_starting = model.getSpaceTypes
3170
+ space_types_starting = model.getSpaceTypes.sort
3133
3171
 
3134
3172
  # create stub space types
3135
3173
  space_type_hash.each do |space_type_name, hash|
@@ -3242,11 +3280,10 @@ module OsLib_ModelGeneration
3242
3280
  end
3243
3281
 
3244
3282
  # reporting final condition of model
3245
- finishing_spaceTypes = model.getSpaceTypes
3246
- finishing_constructionSets = model.getDefaultConstructionSets
3283
+ finishing_spaceTypes = model.getSpaceTypes.sort
3284
+ finishing_constructionSets = model.getDefaultConstructionSets.sort
3247
3285
  runner.registerFinalCondition("The building finished with #{finishing_spaceTypes.size} space types and #{finishing_constructionSets.size} construction sets.")
3248
3286
 
3249
3287
  return true
3250
3288
  end
3251
-
3252
3289
  end