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,64 @@
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
+
40
+ module BuildingSync
41
+ # Exterior Floor System Type
42
+ class ExteriorFloorSystemType
43
+ # initialize a specific floor system type given a ref
44
+ # @param doc [REXML::Document]
45
+ # @param ns [String]
46
+ # @param ref [String]
47
+ def initialize(doc, ns, ref)
48
+ @id = nil
49
+ doc.elements.each("#{ns}:Systems/#{ns}:ExteriorFloorSystems/#{ns}:ExteriorFloorSystem") do |floor_system|
50
+ if floor_system.attributes['ID'] == ref
51
+ read(floor_system, ns)
52
+ end
53
+ end
54
+ end
55
+
56
+ # read
57
+ # @param floor_system [REXML:Element]
58
+ # @param ns [String]
59
+ def read(floor_system, ns)
60
+ # ID
61
+ @id = floor_system.attributes['ID'] if floor_system.attributes['ID']
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,439 @@
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
+ require 'openstudio/extension/core/os_lib_geometry'
40
+
41
+ require 'buildingsync/report'
42
+ require 'buildingsync/contact'
43
+ require 'buildingsync/helpers/helper'
44
+ require 'buildingsync/helpers/xml_get_set'
45
+ require 'buildingsync/helpers/Model.hvac'
46
+
47
+ require_relative 'site'
48
+ require_relative 'loads_system'
49
+ require_relative 'envelope_system'
50
+ require_relative 'hvac_system'
51
+ require_relative 'lighting_system'
52
+ require_relative 'service_hot_water_system'
53
+ require_relative 'measure'
54
+
55
+ module BuildingSync
56
+ # Facility class
57
+ class Facility
58
+ include OsLib_Geometry
59
+ include BuildingSync::Helper
60
+ include BuildingSync::XmlGetSet
61
+ # initialize
62
+ # @param base_xml [REXML:Element]
63
+ # @param ns [String]
64
+ def initialize(base_xml, ns)
65
+ @base_xml = base_xml
66
+ @ns = ns
67
+ @g = BuildingSync::Generator.new(ns)
68
+
69
+ help_element_class_type_check(base_xml, 'Facility')
70
+
71
+ @report_xml = nil
72
+ @site_xml = nil
73
+
74
+ @site = nil
75
+ @report = nil
76
+
77
+ @measures = []
78
+ @contacts = []
79
+ @systems_map = {}
80
+
81
+ # TODO: Go under Report
82
+ @utility_name = nil
83
+ @utility_meter_numbers = []
84
+ @metering_configuration = nil
85
+ @spaces_excluded_from_gross_floor_area = nil
86
+
87
+ @load_system = nil
88
+ @hvac_system = nil
89
+
90
+ # reading the xml
91
+ read_xml
92
+ end
93
+
94
+ # read xml
95
+ def read_xml
96
+ # Site - checks
97
+ site_xml_temp = @base_xml.get_elements("#{@ns}:Sites/#{@ns}:Site")
98
+ if site_xml_temp.nil? || site_xml_temp.empty?
99
+ OpenStudio.logFree(OpenStudio::Error, 'BuildingSync.Facility.read_xml', "Facility ID: #{xget_id} has no Site elements. Cannot initialize Facility.")
100
+ raise StandardError, "Facility with ID: #{xget_id} has no Site elements. Cannot initialize Facility."
101
+ elsif site_xml_temp.size > 1
102
+ @site_xml = site_xml_temp.first
103
+ OpenStudio.logFree(OpenStudio::Error, 'BuildingSync.Facility.read_xml', "Facility ID: #{xget_id}. There is more than one (#{site_xml_temp.size}) Site elements. Only the first Site will be considered (ID: #{@site_xml.attributes['ID']}")
104
+ else
105
+ @site_xml = site_xml_temp.first
106
+ end
107
+ # Create new Site
108
+ @site = BuildingSync::Site.new(@site_xml, @ns)
109
+
110
+ # Report - checks
111
+ report_xml_temp = @base_xml.get_elements("#{@ns}:Reports/#{@ns}:Report")
112
+ if report_xml_temp.nil? || report_xml_temp.empty?
113
+ OpenStudio.logFree(OpenStudio::Error, 'BuildingSync.Facility.read_xml', "Facility with ID: #{xget_id} has no Report elements. Cannot initialize Facility.")
114
+ raise StandardError, "Facility with ID: #{xget_id} has no Report elements. Cannot initialize Facility."
115
+ elsif report_xml_temp.size > 1
116
+ @report_xml = report_xml_temp.first
117
+ OpenStudio.logFree(OpenStudio::Warn, 'BuildingSync.Facility.read_xml', "There are more than one (#{report_xml_temp.size}) Report elements in your BuildingSync file. Only the first Report will be considered (ID: #{@report_xml.attributes['ID']}")
118
+ else
119
+ @report_xml = report_xml_temp.first
120
+ end
121
+ # Create new Report
122
+ @report = BuildingSync::Report.new(@report_xml, @ns)
123
+
124
+ measures_xml_temp = @base_xml.get_elements("#{@ns}:Measures/#{@ns}:Measure")
125
+
126
+ # Measures - create
127
+ if !measures_xml_temp.nil?
128
+ measures_xml_temp.each do |measure_xml|
129
+ if measure_xml.is_a? REXML::Element
130
+ @measures.push(BuildingSync::Measure.new(measure_xml, @ns))
131
+ end
132
+ end
133
+ OpenStudio.logFree(OpenStudio::Info, 'BuildingSync.Facility.read_xml', "Facility with ID: #{xget_id} has #{@measures.size} Measure Objects")
134
+ end
135
+
136
+ read_other_details
137
+ read_and_create_initial_systems
138
+ end
139
+
140
+ # set_all wrapper for Site
141
+ def set_all
142
+ @site.set_all
143
+ end
144
+
145
+ # determine open studio standard
146
+ # @param standard_to_be_used [String]
147
+ # @return [Standard]
148
+ def determine_open_studio_standard(standard_to_be_used)
149
+ return @site.determine_open_studio_standard(standard_to_be_used)
150
+ end
151
+
152
+ # generating the OpenStudio model based on the imported BuildingSync Data
153
+ # @param epw_file_path [String]
154
+ # @param output_path [String]
155
+ # @param standard_to_be_used [String]
156
+ # @param ddy_file [String]
157
+ # @return [Boolean]
158
+ def generate_baseline_osm(epw_file_path, output_path, standard_to_be_used, ddy_file = nil)
159
+ @site.generate_baseline_osm(epw_file_path, standard_to_be_used, ddy_file)
160
+
161
+ @epw_file_path = @site.get_epw_file_path
162
+ zone_hash = build_zone_hash(@site)
163
+ create_building_systems(main_output_dir: output_path, zone_hash: zone_hash, remove_objects: true)
164
+ return true
165
+ end
166
+
167
+ # build zone hash
168
+ # @param site [BuildingSync::Site]
169
+ # @return [Hash]
170
+ def build_zone_hash(site)
171
+ return site.build_zone_hash
172
+ end
173
+
174
+ # get space types
175
+ # @return [Array<OpenStudio::Model::SpaceType>]
176
+ def get_space_types
177
+ return @site.get_space_types
178
+ end
179
+
180
+ # get epw_file_path
181
+ # @return [String]
182
+ def get_epw_file_path
183
+ @site.get_epw_file_path
184
+ end
185
+
186
+ # Get the ContactName specified by the AuditorContactID/@IDref
187
+ # @return [String] if exists
188
+ # @return [nil] if not
189
+ def get_auditor_contact_name
190
+ auditor_id = @report.get_auditor_contact_id
191
+ if !auditor_id.nil?
192
+ contact = @contacts.find { |contact| contact.xget_id == auditor_id }
193
+ return contact.xget_text('ContactName')
194
+ end
195
+ return nil
196
+ end
197
+
198
+ # get OpenStudio model
199
+ # @return [OpenStudio::Model]
200
+ def get_model
201
+ return @site.get_model
202
+ end
203
+
204
+ # determine OpenStudio system standard
205
+ # @return [Standard]
206
+ def determine_open_studio_system_standard
207
+ return @site.determine_open_studio_system_standard
208
+ end
209
+
210
+ # read systems
211
+ def read_and_create_initial_systems
212
+ systems_xml = xget_or_create('Systems')
213
+ if !systems_xml.elements.empty?
214
+ systems_xml.elements.each do |system_type|
215
+ @systems_map[system_type.name] = []
216
+ system_type.elements.each do |system_xml|
217
+ if system_xml.name == 'HVACSystem'
218
+ @systems_map[system_type.name] << BuildingSync::HVACSystem.new(system_xml, @ns)
219
+ elsif system_xml.name == 'LightingSystem'
220
+ @systems_map[system_type.name] << BuildingSync::LightingSystemType.new(system_xml, @ns)
221
+ else
222
+ @systems_map[system_type.name] << system_xml
223
+ end
224
+ end
225
+ end
226
+ else
227
+ hvac_xml = @g.add_hvac_system_to_facility(@base_xml)
228
+ lighting_xml = @g.add_lighting_system_to_facility(@base_xml)
229
+ @hvac_system = HVACSystem.new(hvac_xml, @ns)
230
+ @lighting_system = LightingSystemType.new(lighting_xml, @ns)
231
+ @load_system = LoadsSystem.new
232
+ end
233
+ end
234
+
235
+ # @see BuildingSync::Report.add_cb_modeled
236
+ def add_cb_modeled(id = 'Scenario-Baseline')
237
+ @report.add_cb_modeled(id)
238
+ end
239
+
240
+ # Add a minimal lighting system in the doc and as an object
241
+ # @param premise_id [String] id of the premise which the system will be linked to
242
+ # @param premise_type [String] type of premise, i.e. Building, Section, etc.
243
+ # @param lighting_system_id [String] id for new lighting system
244
+ # @return [BuildingSync::LightingSystemType] new lighting system object
245
+ def add_blank_lighting_system(premise_id, premise_type, lighting_system_id = 'LightingSystem-1')
246
+ # Create new lighting system and link it
247
+ lighting_system_xml = @g.add_lighting_system_to_facility(@base_xml, lighting_system_id)
248
+ @g.add_linked_premise(lighting_system_xml, premise_id, premise_type)
249
+
250
+ # Create a new array if doesn't yet exist
251
+ if !@systems_map.key?('LightingSystems')
252
+ @systems_map['LightingSystems'] = []
253
+ end
254
+
255
+ # Create new lighting system and add to array
256
+ new_system = BuildingSync::LightingSystemType.new(lighting_system_xml, @ns)
257
+ @systems_map['LightingSystems'] << new_system
258
+ return new_system
259
+ end
260
+
261
+ # read other details from the xml
262
+ # - contact information
263
+ # - audit levels and dates
264
+ # - Utility information
265
+ # - UDFs
266
+ def read_other_details
267
+ # Get Contact information
268
+ @base_xml.elements.each("#{@ns}:Contacts/#{@ns}:Contact") do |contact|
269
+ @contacts << BuildingSync::Contact.new(contact, @ns)
270
+ end
271
+ end
272
+
273
+ # create building systems
274
+ # @param main_output_dir [String] main output path, not scenario specific. i.e. SR should be a subdirectory
275
+ # @param zone_hash [Hash]
276
+ # @param hvac_delivery_type [String]
277
+ # @param htg_src [String]
278
+ # @param clg_src [String]
279
+ # @param add_space_type_loads [Boolean]
280
+ # @param add_constructions [Boolean]
281
+ # @param add_elevators [Boolean]
282
+ # @param add_exterior_lights [Boolean]
283
+ # @param add_exhaust [Boolean]
284
+ # @param add_swh [Boolean]
285
+ # @param add_hvac [Boolean]
286
+ # @param add_thermostat [Boolean]
287
+ # @param remove_objects [Boolean]
288
+ def create_building_systems(main_output_dir:, zone_hash: nil, hvac_delivery_type: 'Forced Air', htg_src: 'NaturalGas', clg_src: 'Electricity',
289
+ add_space_type_loads: true, add_constructions: true, add_elevators: false, add_exterior_lights: false,
290
+ add_exhaust: true, add_swh: true, add_hvac: true, add_thermostat: true, remove_objects: false)
291
+ model = @site.get_model
292
+ template = @site.get_standard_template
293
+ system_type = @site.get_system_type
294
+ climate_zone = @site.get_climate_zone
295
+
296
+ onsite_parking_fraction = 1.0
297
+ exterior_lighting_zone = '3 - All Other Areas'
298
+
299
+ initial_objects = model.getModelObjects.size
300
+
301
+ OpenStudio.logFree(OpenStudio::Info, 'BuildingSync.Facility.create_building_system', "The building started with #{initial_objects} objects.")
302
+ puts "BuildingSync.Facility.create_building_system - The building started with #{initial_objects} objects."
303
+
304
+ # TODO: systems_xml.elements["#{@ns}:LightingSystems"]
305
+ # Make the open_studio_system_standard applier
306
+ open_studio_system_standard = determine_open_studio_system_standard
307
+ OpenStudio.logFree(OpenStudio::Info, 'BuildingSync.Facility.create_building_system', "Building Standard with template: #{template}.")
308
+
309
+ # add internal loads to space types
310
+ if add_space_type_loads
311
+ @load_system.add_internal_loads(model, open_studio_system_standard, template, @site.get_building_sections, remove_objects)
312
+ new_occupancy_peak = @site.get_peak_occupancy
313
+ new_occupancy_peak.each do |id, occupancy_peak|
314
+ floor_area = @site.get_floor_area[id]
315
+ if occupancy_peak && floor_area && floor_area > 0.0
316
+ puts "new peak occupancy value found: absolute occupancy: #{occupancy_peak} occupancy per area: #{occupancy_peak.to_f / floor_area.to_f} and area: #{floor_area} m2"
317
+ @load_system.adjust_occupancy_peak(model, occupancy_peak, floor_area, @site.get_space_types_from_hash(id))
318
+ end
319
+ end
320
+ end
321
+
322
+ # identify primary building type (used for construction, and ideally HVAC as well)
323
+ building_types = {}
324
+ model.getSpaceTypes.each do |space_type|
325
+ # populate hash of building types
326
+ if space_type.standardsBuildingType.is_initialized
327
+ bldg_type = space_type.standardsBuildingType.get
328
+ if !building_types.key?(bldg_type)
329
+ building_types[bldg_type] = space_type.floorArea
330
+ else
331
+ building_types[bldg_type] += space_type.floorArea
332
+ end
333
+ else
334
+ OpenStudio.logFree(OpenStudio::Warn, 'BuildingSync.Facility.create_building_system', "Can't identify building type for #{space_type.name}")
335
+ end
336
+ end
337
+ primary_bldg_type = building_types.key(building_types.values.max) # TODO: - this fails if no space types, or maybe just no space types with standards
338
+ lookup_building_type = open_studio_system_standard.model_get_lookup_name(primary_bldg_type) # Used for some lookups in the standards gem
339
+ model.getBuilding.setStandardsBuildingType(primary_bldg_type)
340
+
341
+ envelope_system = nil
342
+ # make construction set and apply to building
343
+ if add_constructions
344
+ envelope_system = EnvelopeSystem.new
345
+ envelope_system.create(model, open_studio_system_standard, primary_bldg_type, lookup_building_type, remove_objects)
346
+ end
347
+
348
+ # add elevators (returns ElectricEquipment object)
349
+ if add_elevators
350
+ @load_system.add_elevator(model, open_studio_system_standard)
351
+ end
352
+
353
+ # add exterior lights (returns a hash where key is lighting type and value is exteriorLights object)
354
+ if add_exterior_lights
355
+ if !@systems_map['LightingSystems'].nil?
356
+ @systems_map['LightingSystems'].each do |lighting_system|
357
+ lighting_system.add_exterior_lights(model, open_studio_system_standard, onsite_parking_fraction, exterior_lighting_zone, remove_objects)
358
+ end
359
+ else
360
+ new_lighting_system = add_blank_lighting_system(@site.get_building.xget_id, 'Building')
361
+ new_lighting_system.add_exterior_lights(model, open_studio_system_standard, onsite_parking_fraction, exterior_lighting_zone, remove_objects)
362
+ end
363
+ end
364
+
365
+ # add_exhaust
366
+ if add_exhaust
367
+ @hvac_system.add_exhaust(model, open_studio_system_standard, 'Adjacent', remove_objects)
368
+ end
369
+
370
+ # add service water heating demand and supply
371
+ if add_swh
372
+ service_hot_water_system = ServiceHotWaterSystem.new
373
+ service_hot_water_system.add(model, open_studio_system_standard, remove_objects)
374
+ end
375
+
376
+ # TODO: Make this better
377
+ @lighting_system.add_daylighting_controls(model, open_studio_system_standard, template, main_output_dir)
378
+
379
+ # TODO: - add internal mass
380
+ # TODO: - add slab modeling and slab insulation
381
+ # TODO: - fuel customization for cooking and laundry
382
+ # TODO: - add refrigeration
383
+ # remove refrigeration equipment
384
+ if remove_objects
385
+ model.getRefrigerationSystems.each(&:remove)
386
+ end
387
+
388
+ # works by switching some fraction of electric loads to gas if requested (assuming base load is electric)
389
+ # add thermostats
390
+ if add_thermostat
391
+ @hvac_system.add_thermostats(model, open_studio_system_standard, remove_objects)
392
+ end
393
+
394
+ # add hvac system
395
+ if add_hvac
396
+ @hvac_system.add_hvac(model, zone_hash, open_studio_system_standard, system_type, hvac_delivery_type, htg_src, clg_src, remove_objects)
397
+ end
398
+
399
+ # set hvac controls and efficiencies (this should be last model articulation element)
400
+ if add_hvac
401
+ if remove_objects
402
+ model.purgeUnusedResourceObjects
403
+ objects_after_cleanup = initial_objects - model.getModelObjects.size
404
+ OpenStudio.logFree(OpenStudio::Warn, 'BuildingSync.Facility.create_building_system', "Removing #{objects_after_cleanup} objects from model")
405
+ end
406
+ @hvac_system.apply_sizing_and_assumptions(model, main_output_dir, open_studio_system_standard, primary_bldg_type, system_type, climate_zone)
407
+ end
408
+
409
+ # remove everything but spaces, zones, and stub space types (extend as needed for additional objects, may make bool arg for this)
410
+ if remove_objects
411
+ model.purgeUnusedResourceObjects
412
+ objects_after_cleanup = initial_objects - model.getModelObjects.size
413
+ if objects_after_cleanup > 0
414
+ OpenStudio.logFree(OpenStudio::Info, 'BuildingSync.Facility.create_building_system', "Removing #{objects_after_cleanup} objects from model")
415
+ end
416
+ end
417
+
418
+ # report final condition of model
419
+ OpenStudio.logFree(OpenStudio::Info, 'BuildingSync.Facility.create_building_system', "The building finished with #{model.getModelObjects.size} objects.")
420
+ puts "BuildingSync.Facility.create_building_system - The building finished with #{model.getModelObjects.size} objects."
421
+ end
422
+
423
+ # write osm
424
+ # @param dir [String]
425
+ # @return [Array]
426
+ def write_osm(dir)
427
+ scenario_types = @site.write_osm(dir)
428
+ return scenario_types
429
+ end
430
+
431
+ # TODO: I don't think we want any of this.
432
+ # write parameters to xml
433
+ def prepare_final_xml
434
+ @site.prepare_final_xml
435
+ end
436
+
437
+ attr_reader :systems_map, :site, :report, :measures, :contacts
438
+ end
439
+ end