openstudio-extension 0.2.1 → 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.
@@ -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