buildingsync 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/continuous_integration.yml +146 -0
  3. data/.gitignore +33 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +10 -0
  6. data/CHANGELOG.md +50 -0
  7. data/Gemfile +31 -0
  8. data/Jenkinsfile +10 -0
  9. data/LICENSE.md +29 -0
  10. data/README.md +105 -0
  11. data/Rakefile +77 -0
  12. data/bin/console +15 -0
  13. data/bin/setup +8 -0
  14. data/buildingsync.gemspec +37 -0
  15. data/config.rb.in +26 -0
  16. data/doc_templates/LICENSE.md +29 -0
  17. data/doc_templates/README.md.erb +42 -0
  18. data/doc_templates/copyright_erb.txt +38 -0
  19. data/doc_templates/copyright_js.txt +5 -0
  20. data/doc_templates/copyright_ruby.txt +36 -0
  21. data/lib/buildingsync.rb +43 -0
  22. data/lib/buildingsync/all_resource_total.rb +54 -0
  23. data/lib/buildingsync/audit_date.rb +54 -0
  24. data/lib/buildingsync/constants.rb +49 -0
  25. data/lib/buildingsync/contact.rb +54 -0
  26. data/lib/buildingsync/extension.rb +57 -0
  27. data/lib/buildingsync/generator.rb +584 -0
  28. data/lib/buildingsync/get_bcl_weather_file.rb +326 -0
  29. data/lib/buildingsync/helpers/Model.hvac.rb +216 -0
  30. data/lib/buildingsync/helpers/helper.rb +494 -0
  31. data/lib/buildingsync/helpers/xml_get_set.rb +215 -0
  32. data/lib/buildingsync/makers/phase_zero_base.osw +178 -0
  33. data/lib/buildingsync/makers/workflow_maker.json +811 -0
  34. data/lib/buildingsync/makers/workflow_maker.rb +581 -0
  35. data/lib/buildingsync/makers/workflow_maker_base.rb +167 -0
  36. data/lib/buildingsync/model_articulation/building.rb +1119 -0
  37. data/lib/buildingsync/model_articulation/building_and_system_types.json +121 -0
  38. data/lib/buildingsync/model_articulation/building_section.rb +190 -0
  39. data/lib/buildingsync/model_articulation/building_system.rb +49 -0
  40. data/lib/buildingsync/model_articulation/envelope_system.rb +102 -0
  41. data/lib/buildingsync/model_articulation/exterior_floor_system_type.rb +64 -0
  42. data/lib/buildingsync/model_articulation/facility.rb +439 -0
  43. data/lib/buildingsync/model_articulation/foundation_system_type.rb +64 -0
  44. data/lib/buildingsync/model_articulation/hvac_system.rb +395 -0
  45. data/lib/buildingsync/model_articulation/lighting_system.rb +102 -0
  46. data/lib/buildingsync/model_articulation/loads_system.rb +287 -0
  47. data/lib/buildingsync/model_articulation/location_element.rb +129 -0
  48. data/lib/buildingsync/model_articulation/measure.rb +57 -0
  49. data/lib/buildingsync/model_articulation/roof_system_type.rb +64 -0
  50. data/lib/buildingsync/model_articulation/service_hot_water_system.rb +87 -0
  51. data/lib/buildingsync/model_articulation/site.rb +242 -0
  52. data/lib/buildingsync/model_articulation/spatial_element.rb +343 -0
  53. data/lib/buildingsync/model_articulation/wall_system_type.rb +64 -0
  54. data/lib/buildingsync/report.rb +217 -0
  55. data/lib/buildingsync/resource_use.rb +55 -0
  56. data/lib/buildingsync/scenario.rb +622 -0
  57. data/lib/buildingsync/selection_tool.rb +98 -0
  58. data/lib/buildingsync/time_series.rb +85 -0
  59. data/lib/buildingsync/translator.rb +167 -0
  60. data/lib/buildingsync/utility.rb +67 -0
  61. data/lib/buildingsync/version.rb +45 -0
  62. metadata +223 -0
@@ -0,0 +1,494 @@
1
+ # frozen_string_literal: true
2
+
3
+ # *******************************************************************************
4
+ # OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC.
5
+ # BuildingSync(R), Copyright (c) 2015-2020, Alliance for Sustainable Energy, LLC.
6
+ # All rights reserved.
7
+ #
8
+ # Redistribution and use in source and binary forms, with or without
9
+ # modification, are permitted provided that the following conditions are met:
10
+ #
11
+ # (1) Redistributions of source code must retain the above copyright notice,
12
+ # this list of conditions and the following disclaimer.
13
+ #
14
+ # (2) Redistributions in binary form must reproduce the above copyright notice,
15
+ # this list of conditions and the following disclaimer in the documentation
16
+ # and/or other materials provided with the distribution.
17
+ #
18
+ # (3) Neither the name of the copyright holder nor the names of any contributors
19
+ # may be used to endorse or promote products derived from this software without
20
+ # specific prior written permission from the respective party.
21
+ #
22
+ # (4) Other than as required in clauses (1) and (2), distributions in any form
23
+ # of modifications or other derivative works may not use the "OpenStudio"
24
+ # trademark, "OS", "os", or any other confusingly similar designation without
25
+ # specific prior written permission from Alliance for Sustainable Energy, LLC.
26
+ #
27
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS
28
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
29
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE
31
+ # UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF
32
+ # THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
33
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
34
+ # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36
+ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37
+ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
+ # *******************************************************************************
39
+ module BuildingSync
40
+ # helper class for helper methods in BuildingSync
41
+ module Helper
42
+ def help_element_class_type_check(xml_element, expected_type)
43
+ if xml_element.name != expected_type
44
+ OpenStudio.logFree(OpenStudio::Error, "BuildingSync.#{expected_type}.initialize", "Attempted to initialize #{expected_type} object with Element name of: #{xml_element.name}")
45
+ raise StandardError, "Attempted to initialize #{expected_type} object with Element name of: #{xml_element.name}"
46
+ end
47
+ end
48
+
49
+ def help_get_or_create(parent, new_element_type)
50
+ new_element = parent.elements[new_element_type]
51
+ if new_element.nil?
52
+ new_element = REXML::Element.new(new_element_type, parent)
53
+ end
54
+ return new_element
55
+ end
56
+
57
+ # get text value from xml element
58
+ # @param xml_element [REXML::Element]
59
+ # @return [String] if text value exists
60
+ # @return [nil] if text value doesnt exist or element is complex (has children)
61
+ def help_get_text_value(xml_element)
62
+ if xml_element && !xml_element.text.nil?
63
+ return xml_element.text
64
+ end
65
+ return nil
66
+ end
67
+
68
+ def help_get_text_value_as_float(xml_element)
69
+ v = help_get_text_value(xml_element)
70
+ return v.to_f
71
+ end
72
+
73
+ def help_get_text_value_as_integer(xml_element)
74
+ v = help_get_text_value(xml_element)
75
+ return v.to_i
76
+ end
77
+
78
+ def help_get_text_value_as_bool(xml_element)
79
+ v = help_get_text_value(xml_element)
80
+ return v.to_bool
81
+ end
82
+
83
+ # convert between supported units
84
+ # @param val [Numeric] value to convert, i.e. 1
85
+ # @param from_unit [String] starting units
86
+ # @param to_unit [String] desired end units
87
+ # @return [Float] if successful, converted value
88
+ # @return [nil] if unsuccessful
89
+ def help_convert(val, from_unit, to_unit)
90
+ if from_unit == to_unit
91
+ return val
92
+ end
93
+
94
+ btu_multiples = [
95
+ {
96
+ 'from' => 'Btu',
97
+ 'kBtu' => 0.001,
98
+ 'MMBtu' => 0.000001
99
+ },
100
+ {
101
+ 'from' => 'kBtu',
102
+ 'Btu' => 1000,
103
+ 'MMBtu' => 0.001
104
+ },
105
+ {
106
+ 'from' => 'MMBtu',
107
+ 'Btu' => 1000000,
108
+ 'kBtu' => 1000
109
+ }
110
+ ]
111
+ map = btu_multiples.find { |from| from['from'] == from_unit }
112
+ if !map.nil? && !map.empty?
113
+ mult = map[to_unit]
114
+ if !mult.nil?
115
+ return val * mult
116
+ else
117
+ OpenStudio.logFree(OpenStudio::Error, 'BuildingSync.Helper.help_convert', "Unable to convert from: #{from_unit} to #{to_unit}")
118
+ end
119
+ else
120
+ OpenStudio.logFree(OpenStudio::Error, 'BuildingSync.Helper.help_convert', "Unable to convert from: #{from_unit} to #{to_unit}")
121
+ return nil
122
+ end
123
+ end
124
+
125
+ # get attribute value from xml element
126
+ # @param xml_element [REXML::Element]
127
+ # @param attribute_name [String] name of attribute to get the value for
128
+ # @return [String] if attribute
129
+ # @return [nil] if attribute doesnt exist
130
+ def help_get_attribute_value(xml_element, attribute_name)
131
+ if xml_element && !xml_element.attribute(attribute_name).nil?
132
+ return xml_element.attribute(attribute_name).value
133
+ end
134
+ return nil
135
+ end
136
+
137
+ # get date value from xml element
138
+ # @param xml_element [REXML::Element]
139
+ # @return [Date] if the text can be parsed as a date
140
+ # @return [nil] if the text cant be parsed as a date
141
+ def help_get_text_value_as_date(xml_element)
142
+ if xml_element && !xml_element.text.nil?
143
+ begin
144
+ return Date.parse(xml_element.text)
145
+ rescue ArgumentError
146
+ return nil
147
+ end
148
+ end
149
+ return nil
150
+ end
151
+
152
+ # get date datetime from xml element
153
+ # @param xml_element [REXML::Element]
154
+ # @return [DateTime] if the text can be parsed as a date
155
+ # @return [nil] if the text cant be parsed as a date
156
+ def help_get_text_value_as_datetime(xml_element)
157
+ if xml_element && !xml_element.text.nil?
158
+ begin
159
+ return DateTime.parse(xml_element.text)
160
+ rescue ArgumentError
161
+ return nil
162
+ end
163
+ end
164
+ return nil
165
+ end
166
+
167
+ # get zone name list
168
+ # @param zones [array<OpenStudio::Model::ThermalZone>]
169
+ # @return array
170
+ def help_get_zone_name_list(zones)
171
+ names = []
172
+ zones.each do |zone|
173
+ names << zone.name.get
174
+ end
175
+ return names
176
+ end
177
+
178
+ # read xml file document
179
+ # @param xml_file_path [String]
180
+ # @return REXML::Document
181
+ def help_load_doc(xml_file_path)
182
+ doc = nil
183
+ File.open(xml_file_path, 'r') do |file_content|
184
+ doc = REXML::Document.new(file_content, ignore_whitespace_nodes: :all)
185
+ end
186
+ return doc
187
+ end
188
+
189
+ # print all schedules to a file
190
+ # @param file_name [String]
191
+ # @param default_schedule_set [OpenStudio::Model::DefaultScheduleSet]
192
+ def help_print_all_schedules(file_name, default_schedule_set)
193
+ f = File.open(file_name, 'w')
194
+ help_print_schedule(f, default_schedule_set.numberofPeopleSchedule)
195
+ help_print_schedule(f, default_schedule_set.hoursofOperationSchedule)
196
+ help_print_schedule(f, default_schedule_set.peopleActivityLevelSchedule)
197
+ help_print_schedule(f, default_schedule_set.lightingSchedule)
198
+ help_print_schedule(f, default_schedule_set.electricEquipmentSchedule)
199
+ help_print_schedule(f, default_schedule_set.gasEquipmentSchedule)
200
+ help_print_schedule(f, default_schedule_set.hotWaterEquipmentSchedule)
201
+ help_print_schedule(f, default_schedule_set.infiltrationSchedule)
202
+ help_print_schedule(f, default_schedule_set.steamEquipmentSchedule)
203
+ help_print_schedule(f, default_schedule_set.otherEquipmentSchedule)
204
+ f.close
205
+ end
206
+
207
+ # write a schedule profile
208
+ # @param f [File]
209
+ # @param profile [OpenStudio::Model::ScheduleDay]
210
+ # @param rule [OpenStudio::Model::ScheduleRule]
211
+ # @param cut_off_value [Float]
212
+ def help_write_profile(f, profile, rule, cut_off_value = 0.5)
213
+ time_row = "#{profile.name},"
214
+ if rule.nil?
215
+ time_row += ',,,,,,,'
216
+ else
217
+ if rule.applySunday
218
+ time_row += 'X,'
219
+ else
220
+ time_row += ','
221
+ end
222
+ if rule.applyMonday
223
+ time_row += 'X,'
224
+ else
225
+ time_row += ','
226
+ end
227
+ if rule.applyTuesday
228
+ time_row += 'X,'
229
+ else
230
+ time_row += ','
231
+ end
232
+ if rule.applyWednesday
233
+ time_row += 'X,'
234
+ else
235
+ time_row += ','
236
+ end
237
+ if rule.applyThursday
238
+ time_row += 'X,'
239
+ else
240
+ time_row += ','
241
+ end
242
+ if rule.applyFriday
243
+ time_row += 'X,'
244
+ else
245
+ time_row += ','
246
+ end
247
+ if rule.applySaturday
248
+ time_row += 'X,'
249
+ else
250
+ time_row += ','
251
+ end
252
+ end
253
+ time_row += ','
254
+ value_row = ",,,,,,,,#{help_get_duration(profile, cut_off_value)},"
255
+
256
+ profile.times.each do |time|
257
+ time_row += "#{time},"
258
+ value_row += "#{profile.getValue(time)},"
259
+ end
260
+ f.write time_row + "\n"
261
+ f.write value_row + "\n"
262
+ end
263
+
264
+ # print schedule
265
+ # @param f [File]
266
+ # @param optional_schedule [OpenStudio::Model::OptionalSchedule]
267
+ # @param cut_off_value [Float]
268
+ def help_print_schedule(f, optional_schedule, cut_off_value = 0.5)
269
+ if optional_schedule.is_a?(OpenStudio::Model::OptionalSchedule) && optional_schedule.is_initialized
270
+ schedule = optional_schedule.get
271
+ if schedule.is_a?(OpenStudio::Model::OptionalSchedule) && schedule.is_initialized
272
+ schedule = schedule.get
273
+ end
274
+ else
275
+ schedule = optional_schedule
276
+ end
277
+ if schedule.is_a?(OpenStudio::Model::Schedule)
278
+ schedule_rule_set = schedule.to_ScheduleRuleset.get
279
+ f.puts "schedule_rule_set name: ,#{schedule_rule_set.name}, duration:, #{help_calculate_hours(optional_schedule, cut_off_value)}"
280
+ defaultProfile = schedule_rule_set.defaultDaySchedule
281
+
282
+ f.puts 'Name, Su, Mo, Tu, We, Th, Fr, Sa, Duration, TimeValue1, TV2, ...'
283
+ help_write_profile(f, defaultProfile, nil, cut_off_value)
284
+
285
+ schedule_rule_set.scheduleRules.each do |rule|
286
+ help_write_profile(f, rule.daySchedule, rule, cut_off_value)
287
+ end
288
+ f.puts
289
+ else
290
+ puts "schedule: #{schedule}"
291
+ end
292
+ end
293
+
294
+ # get start time weekday
295
+ # @param schedule_rule_set [OpenStudio::Model::ScheduleRuleSet]
296
+ # @param cut_off_value [Float]
297
+ def help_get_start_time_weekday(schedule_rule_set, cut_off_value = 0.5)
298
+ profile = schedule_rule_set.defaultDaySchedule
299
+ schedule_rule_set.scheduleRules.each do |rule|
300
+ if rule.applyMonday
301
+ profile = rule.daySchedule
302
+ end
303
+ end
304
+
305
+ return help_get_start_time(profile, cut_off_value)
306
+ end
307
+
308
+ # get end time weekday
309
+ # @param schedule_rule_set [OpenStudio::Model::ScheduleRuleSet]
310
+ # @param cut_off_value [Float]
311
+ def help_get_end_time_weekday(schedule_rule_set, cut_off_value = 0.5)
312
+ profile = schedule_rule_set.defaultDaySchedule
313
+ schedule_rule_set.scheduleRules.each do |rule|
314
+ if rule.applyMonday
315
+ profile = rule.daySchedule
316
+ end
317
+ end
318
+
319
+ return help_get_end_time(profile, cut_off_value)
320
+ end
321
+
322
+ # get start time Saturday
323
+ # @param schedule_rule_set [OpenStudio::Model::ScheduleRuleSet]
324
+ # @param cut_off_value [Float]
325
+ def help_get_start_time_sat(schedule_rule_set, cut_off_value = 0.5)
326
+ profile = schedule_rule_set.defaultDaySchedule
327
+ schedule_rule_set.scheduleRules.each do |rule|
328
+ if rule.applySaturday
329
+ profile = rule.daySchedule
330
+ end
331
+ end
332
+
333
+ return help_get_start_time(profile, cut_off_value)
334
+ end
335
+
336
+ # get end time Saturday
337
+ # @param schedule_rule_set [OpenStudio::Model::ScheduleRuleSet]
338
+ # @param cut_off_value [Float]
339
+ def help_get_end_time_sat(schedule_rule_set, cut_off_value = 0.5)
340
+ profile = schedule_rule_set.defaultDaySchedule
341
+ schedule_rule_set.scheduleRules.each do |rule|
342
+ if rule.applySaturday
343
+ profile = rule.daySchedule
344
+ end
345
+ end
346
+
347
+ return help_get_end_time(profile, cut_off_value)
348
+ end
349
+
350
+ # get start time Sunday
351
+ # @param schedule_rule_set [OpenStudio::Model::ScheduleRuleSet]
352
+ # @param cut_off_value [Float]
353
+ def help_get_start_time_sun(schedule_rule_set, cut_off_value = 0.5)
354
+ profile = schedule_rule_set.defaultDaySchedule
355
+ schedule_rule_set.scheduleRules.each do |rule|
356
+ if rule.applySunday
357
+ profile = rule.daySchedule
358
+ end
359
+ end
360
+
361
+ return help_get_start_time(profile, cut_off_value)
362
+ end
363
+
364
+ # get end time Sunday
365
+ # @param schedule_rule_set [OpenStudio::Model::ScheduleRuleSet]
366
+ # @param cut_off_value [Float]
367
+ def help_get_end_time_sun(schedule_rule_set, cut_off_value = 0.5)
368
+ profile = schedule_rule_set.defaultDaySchedule
369
+ schedule_rule_set.scheduleRules.each do |rule|
370
+ if rule.applySunday
371
+ profile = rule.daySchedule
372
+ end
373
+ end
374
+
375
+ return help_get_end_time(profile, cut_off_value)
376
+ end
377
+
378
+ # get start time
379
+ # @param profile [OpenStudio::Model::ScheduleDay]
380
+ # @param cut_off_value [Float]
381
+ def help_get_start_time(profile, cut_off_value)
382
+ last_time = OpenStudio::Time.new
383
+ profile.times.each do |time|
384
+ if profile.getValue(time) >= cut_off_value
385
+ return last_time
386
+ end
387
+ last_time = time
388
+ end
389
+ return OpenStudio::Time.new
390
+ end
391
+
392
+ # get end time
393
+ # @param profile [OpenStudio::Model::ScheduleDay]
394
+ # @param cut_off_value [Float]
395
+ def help_get_end_time(profile, cut_off_value)
396
+ last_time = nil
397
+ profile.times.each do |time|
398
+ if profile.getValue(time) >= cut_off_value
399
+ last_time = time
400
+ elsif profile.getValue(time) < cut_off_value && !last_time.nil?
401
+ return last_time
402
+ end
403
+ end
404
+ return OpenStudio::Time.new
405
+ end
406
+
407
+ # get schedule rule set from schedule
408
+ # @param optional_schedule [OpenStudio::Model::OptionalSchedule]
409
+ # @return [OpenStudio::Model::ScheduleRuleSet]
410
+ def help_get_schedule_rule_set_from_schedule(optional_schedule)
411
+ if optional_schedule.is_a?(OpenStudio::Model::OptionalSchedule)
412
+ if optional_schedule.is_initialized
413
+ schedule = optional_schedule.get
414
+ else
415
+ return nil
416
+ end
417
+ else
418
+ schedule = optional_schedule
419
+ end
420
+ return schedule.to_ScheduleRuleset.get
421
+ end
422
+
423
+ # calculate schedule hours that are at or above the cut off value
424
+ # @param optional_schedule [OpenStudio::Model::OptionalSchedule]
425
+ # @return [OpenStudio::Model::ScheduleRuleSet]
426
+ # @ return [Float]
427
+ def help_calculate_hours(optional_schedule, cut_off_value = 0.5)
428
+ calculated_hours_per_week = 0.0
429
+ schedule_rule_set = help_get_schedule_rule_set_from_schedule(optional_schedule)
430
+ return 0.0 if schedule_rule_set.nil?
431
+ defaultProfile = schedule_rule_set.defaultDaySchedule
432
+ default_profile_duration = help_get_duration(defaultProfile, cut_off_value)
433
+ default_number_of_days = 7
434
+ schedule_rule_set.scheduleRules.each do |rule|
435
+ profile_duration = help_get_duration(rule.daySchedule, cut_off_value)
436
+ number_of_days = help_count_number_of_days(rule)
437
+ default_number_of_days -= number_of_days
438
+ calculated_hours_per_week += profile_duration * number_of_days
439
+ end
440
+ calculated_hours_per_week += default_profile_duration * default_number_of_days
441
+ return calculated_hours_per_week
442
+ end
443
+
444
+ # count number of days
445
+ # @param rule [OpenStudio::Model::ScheduleRule]
446
+ # return [Integer]
447
+ def help_count_number_of_days(rule)
448
+ count = 0
449
+ count += 1 if rule.applyFriday
450
+ count += 1 if rule.applyMonday
451
+ count += 1 if rule.applySaturday
452
+ count += 1 if rule.applySunday
453
+ count += 1 if rule.applyThursday
454
+ count += 1 if rule.applyTuesday
455
+ count += 1 if rule.applyWednesday
456
+ return count
457
+ end
458
+
459
+ # get duration
460
+ # @param profile [OpenStudio::Model::ScheduleDay]
461
+ # @param cut_off_value [Float]
462
+ # return [Float]
463
+ def help_get_duration(profile, cut_off_value)
464
+ last_time = nil
465
+ duration_above_cut_off = 0.0
466
+ profile.times.each do |time|
467
+ if profile.getValue(time) >= cut_off_value
468
+ if last_time.nil?
469
+ duration_above_cut_off += time.totalHours
470
+ else
471
+ duration_above_cut_off += time.totalHours - last_time.totalHours
472
+ end
473
+ end
474
+ last_time = time
475
+ end
476
+
477
+ return duration_above_cut_off
478
+ end
479
+
480
+ # get default schedule set
481
+ # @param model [OpenStudio::Model]
482
+ # return [OpenStudio::Model::DefaultScheduleSet]
483
+ def help_get_default_schedule_set(model)
484
+ if model.getBuilding.defaultScheduleSet.is_initialized
485
+ return model.getBuilding.defaultScheduleSet.get
486
+ else
487
+ space_types = model.getSpaceTypes
488
+ space_types.each do |space_type|
489
+ return space_type.defaultScheduleSet.get
490
+ end
491
+ end
492
+ end
493
+ end
494
+ end