buildingsync 0.2.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.
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,102 @@
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 'buildingsync/helpers/helper'
40
+ require 'buildingsync/helpers/xml_get_set'
41
+
42
+ module BuildingSync
43
+ # LightingSystemType class
44
+ class LightingSystemType
45
+ include BuildingSync::Helper
46
+ include BuildingSync::XmlGetSet
47
+ # initialize
48
+ # @param doc [REXML::Document]
49
+ # @param ns [String]
50
+ def initialize(base_xml, ns)
51
+ @base_xml = base_xml
52
+ @ns = ns
53
+
54
+ help_element_class_type_check(@base_xml, 'LightingSystem')
55
+
56
+ read_xml
57
+ end
58
+
59
+ # read
60
+ def read_xml; end
61
+
62
+ # add exterior lights
63
+ # @param model [OpenStudio::Model]
64
+ # @param standard [Standard]
65
+ # @param onsite_parking_fraction [Float]
66
+ # @param exterior_lighting_zone [String]
67
+ # @param remove_objects [Boolean]
68
+ # @return boolean
69
+ def add_exterior_lights(model, standard, onsite_parking_fraction, exterior_lighting_zone, remove_objects)
70
+ if remove_objects
71
+ model.getExteriorLightss.each do |ext_light|
72
+ next if ext_light.name.to_s.include?('Fuel equipment') # some prototype building types model exterior elevators by this name
73
+
74
+ ext_light.remove
75
+ end
76
+ end
77
+
78
+ exterior_lights = standard.model_add_typical_exterior_lights(model, exterior_lighting_zone.chars[0].to_i, onsite_parking_fraction)
79
+ exterior_lights.each do |k, v|
80
+ OpenStudio.logFree(OpenStudio::Info, 'BuildingSync.LightingSystem.add_exterior_lights', "Adding Exterior Lights named #{v.exteriorLightsDefinition.name} with design level of #{v.exteriorLightsDefinition.designLevel} * #{OpenStudio.toNeatString(v.multiplier, 0, true)}.")
81
+ end
82
+ return true
83
+ end
84
+
85
+ # add daylighting controls
86
+ # @param model [OpenStudio::Model]
87
+ # @param standard [Standard]
88
+ # @param template [String]
89
+ # @param main_output_dir [String] main output path, not scenario specific. i.e. SR should be a subdirectory
90
+ # @return boolean
91
+ def add_daylighting_controls(model, standard, template, main_output_dir)
92
+ # add daylight controls, need to perform a sizing run for 2010
93
+ if template == '90.1-2010'
94
+ if standard.model_run_sizing_run(model, "#{main_output_dir}/SRvt") == false
95
+ return false
96
+ end
97
+ end
98
+ standard.model_add_daylighting_controls(model)
99
+ return true
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,287 @@
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_schedules.rb'
40
+
41
+ require 'buildingsync/helpers/helper'
42
+ require_relative 'building_system'
43
+
44
+ module BuildingSync
45
+ # LoadsSystem class that manages internal and external loads
46
+ class LoadsSystem < BuildingSystem
47
+ include BuildingSync::Helper
48
+ # initialize
49
+ # @param system_element [REXML::Element]
50
+ # @param ns [String]
51
+ def initialize(system_element = '', ns = '')
52
+ # code to initialize
53
+ end
54
+
55
+ # add internal loads from standard definitions
56
+ # @param model [OpenStudio::Model]
57
+ # @param standard [Standard]
58
+ # @param template [String]
59
+ # @param building_sections [REXML:Element]
60
+ # @param remove_objects [Boolean]
61
+ # @return [Boolean]
62
+ def add_internal_loads(model, standard, template, building_sections, remove_objects)
63
+ # remove internal loads
64
+ if remove_objects
65
+ model.getSpaceLoads.each do |instance|
66
+ next if instance.name.to_s.include?('Elevator') # most prototype building types model exterior elevators with name Elevator
67
+ next if instance.to_InternalMass.is_initialized
68
+ next if instance.to_WaterUseEquipment.is_initialized
69
+
70
+ instance.remove
71
+ end
72
+ model.getDesignSpecificationOutdoorAirs.each(&:remove)
73
+ model.getDefaultScheduleSets.each(&:remove)
74
+ end
75
+
76
+ OpenStudio.logFree(OpenStudio::Warn, 'BuildingSync.LoadsSystem.add_internal_loads', 'Adding internal loads')
77
+ count_not_found = 0
78
+ model.getSpaceTypes.each do |space_type|
79
+ data = standard.space_type_get_standards_data(space_type)
80
+ if data.empty?
81
+ original_building_type = space_type.standardsBuildingType.get
82
+ alternate_building_type = standard.model_get_lookup_name(original_building_type)
83
+ if alternate_building_type != original_building_type
84
+ space_type.setStandardsBuildingType(alternate_building_type)
85
+ data = standard.space_type_get_standards_data(space_type)
86
+ if data.empty?
87
+ OpenStudio.logFree(OpenStudio::Warn, 'BuildingSync.LoadsSystem.add_internal_loads', "Unable to get standards data for Space Type: #{space_type.name}. Tried standards building type: #{original_building_type} and #{alternate_building_type} with standards space type: #{space_type.standardsSpaceType.get}")
88
+ count_not_found += 1
89
+ next
90
+ else
91
+ OpenStudio.logFree(OpenStudio::Warn, 'BuildingSync.LoadsSystem.add_internal_loads', "Space Type: #{space_type.name}. Standards building type changed from #{original_building_type} to #{alternate_building_type} with standards space type: #{space_type.standardsSpaceType.get}")
92
+ end
93
+ else
94
+ OpenStudio.logFree(OpenStudio::Warn, 'BuildingSync.LoadsSystem.add_internal_loads', "Unable to get standards data for Space Type: #{space_type.name}. Standards building type: #{space_type.standardsBuildingType.get}, space type: #{space_type.standardsSpaceType.get}")
95
+ count_not_found += 1
96
+ next
97
+ end
98
+ end
99
+ # Don't add infiltration here; will be added later in the script
100
+ test = standard.space_type_apply_internal_loads(space_type, true, true, true, true, true, false)
101
+ if test == false
102
+ OpenStudio.logFree(OpenStudio::Warn, 'BuildingSync.LoadsSystem.add_internal_loads', "Could not add loads for #{space_type.name}. Not expected for #{template}")
103
+ next
104
+ end
105
+
106
+ # apply internal load schedules
107
+ # the last bool test it to make thermostat schedules. They are now added in HVAC section instead of here
108
+ success = standard.space_type_apply_internal_load_schedules(space_type, true, true, true, true, true, true, false)
109
+ if !success
110
+ OpenStudio.logFree(OpenStudio::Warn, 'BuildingSync.LoadsSystem.add_internal_loads', "space_type_apply_internal_load_schedules unsuccessful for #{space_type.name}")
111
+ end
112
+
113
+ # here we adjust the people schedules according to user input of hours per week and weeks per year
114
+ if !building_sections.empty?
115
+ adjust_schedules(standard, space_type, get_building_occupancy_hours(building_sections), model)
116
+ end
117
+ # extend space type name to include the template. Consider this as well for load defs
118
+ space_type.setName("#{space_type.name} - #{template}")
119
+ OpenStudio.logFree(OpenStudio::Info, 'BuildingSync.LoadsSystem.add_internal_loads', "Adding loads to space type named #{space_type.name}")
120
+ end
121
+
122
+ if count_not_found > 0
123
+ OpenStudio.logFree(OpenStudio::Warn, 'BuildingSync.LoadsSystem.add_internal_loads', "#{count_not_found} of #{model.getSpaceTypes.size} Space Types have no internal loads")
124
+ end
125
+
126
+ # warn if spaces in model without space type
127
+ spaces_without_space_types = []
128
+ model.getSpaces.each do |space|
129
+ next if space.spaceType.is_initialized
130
+
131
+ spaces_without_space_types << space
132
+ end
133
+ if !spaces_without_space_types.empty?
134
+ OpenStudio.logFree(OpenStudio::Warn, 'BuildingSync.LoadsSystem.add_internal_loads', "#{spaces_without_space_types.size} spaces do not have space types assigned, and wont' receive internal loads from standards space type lookups.")
135
+ end
136
+ return true
137
+ end
138
+
139
+ # add occupancy peak
140
+ # @param model [OpenStudio::Model]
141
+ # @param new_occupancy_peak [String]
142
+ # @param area [String]
143
+ # @param space_types [REXML:Element]
144
+ def adjust_occupancy_peak(model, new_occupancy_peak, area, space_types)
145
+ # we assume that the standard always generate people per area
146
+ sum_of_people_per_area = 0.0
147
+ count = 0
148
+ if !space_types.nil?
149
+ sorted_space_types = model.getSpaceTypes.sort
150
+ sorted_space_types.each do |space_type|
151
+ if space_types.include? space_type
152
+ peoples = space_type.people
153
+ peoples.each do |people|
154
+ sum_of_people_per_area += people.peoplePerFloorArea.get
155
+ count += 1
156
+ end
157
+ end
158
+ end
159
+ average_people_per_area = sum_of_people_per_area / count
160
+ puts "existing occupancy: #{average_people_per_area} new target value: #{new_occupancy_peak.to_f / area.to_f}"
161
+ new_sum_of_people_per_area = 0.0
162
+ sorted_space_types.each do |space_type|
163
+ if space_types.include? space_type
164
+ peoples = space_type.people
165
+ peoples.each do |people|
166
+ ratio = people.peoplePerFloorArea.get.to_f / average_people_per_area.to_f
167
+ new_value = ratio * new_occupancy_peak.to_f / area.to_f
168
+ puts "adjusting occupancy per area value from: #{people.peoplePerFloorArea.get} by ratio #{ratio} to #{new_value}"
169
+ people.peopleDefinition.setPeopleperSpaceFloorArea(new_value)
170
+ new_sum_of_people_per_area += new_value
171
+ end
172
+ end
173
+ end
174
+ puts "resulting total absolute occupancy value: #{new_sum_of_people_per_area * area.to_f} occupancy per area value: #{new_sum_of_people_per_area / count}"
175
+ else
176
+ puts 'space types are empty'
177
+ end
178
+ end
179
+
180
+ # get building occupancy hours
181
+ # @param building_sections [array]
182
+ # @return [Float]
183
+ def get_building_occupancy_hours(building_sections)
184
+ if building_sections.count == 1
185
+ return building_sections[0].typical_occupant_usage_value_hours.to_f
186
+ end
187
+ occupancy_hours = nil
188
+ count = 0.0
189
+ building_sections.each do |section|
190
+ occupancy_hours = 0.0 if occupancy_hours.nil?
191
+ occupancy_hours += section.typical_occupant_usage_value_hours.to_f if section.typical_occupant_usage_value_hours.nil?
192
+ count += 1 if section.typical_occupant_usage_value_hours.nil?
193
+ end
194
+ return nil if occupancy_hours.nil?
195
+ return occupancy_hours / count
196
+ end
197
+
198
+ # adjust schedules
199
+ # @param standard [Standard]
200
+ # @param space_type [OpenStudio::Model::SpaceType]
201
+ # @param building_occupant_hours_per_week [Float]
202
+ # @param model [OpenStudio::Model]
203
+ # @return boolean
204
+ def adjust_schedules(standard, space_type, building_occupant_hours_per_week, model)
205
+ # this uses code from https://github.com/NREL/openstudio-extension-gem/blob/6f8f7a46de496c3ab95ed9c72d4d543bd4b67740/lib/openstudio/extension/core/os_lib_model_generation.rb#L3007
206
+ #
207
+ # currently this works for all schedules in the model
208
+ # in the future we would want to make this more flexible to adjusted based on space_types or building sections
209
+ return unless !building_occupant_hours_per_week.nil?
210
+ hours_per_week = building_occupant_hours_per_week
211
+
212
+ default_schedule_set = help_get_default_schedule_set(model)
213
+ existing_number_of_people_sched = help_get_schedule_rule_set_from_schedule(default_schedule_set.numberofPeopleSchedule)
214
+ return false if existing_number_of_people_sched.nil?
215
+ calc_hours_per_week = help_calculate_hours(existing_number_of_people_sched)
216
+ ratio_hours_per_week = hours_per_week / calc_hours_per_week
217
+
218
+ wkdy_start_time = help_get_start_time_weekday(existing_number_of_people_sched)
219
+ wkdy_end_time = help_get_end_time_weekday(existing_number_of_people_sched)
220
+ wkdy_hours = wkdy_end_time - wkdy_start_time
221
+
222
+ sat_start_time = help_get_start_time_sat(existing_number_of_people_sched)
223
+ sat_end_time = help_get_end_time_sat(existing_number_of_people_sched)
224
+ sat_hours = sat_end_time - sat_start_time
225
+
226
+ sun_start_time = help_get_start_time_sun(existing_number_of_people_sched)
227
+ sun_end_time = help_get_end_time_sun(existing_number_of_people_sched)
228
+ sun_hours = sun_end_time - sun_start_time
229
+
230
+ # determine new end times via ratios
231
+ wkdy_end_time = wkdy_start_time + OpenStudio::Time.new(ratio_hours_per_week * wkdy_hours.totalDays)
232
+ sat_end_time = sat_start_time + OpenStudio::Time.new(ratio_hours_per_week * sat_hours.totalDays)
233
+ sun_end_time = sun_start_time + OpenStudio::Time.new(ratio_hours_per_week * sun_hours.totalDays)
234
+
235
+ # Infer the current hours of operation schedule for the building
236
+ op_sch = standard.model_infer_hours_of_operation_building(model)
237
+ default_schedule_set.setHoursofOperationSchedule(op_sch)
238
+
239
+ # help_print_all_schedules("org_schedules-#{space_type.name}.csv", default_schedule_set)
240
+
241
+ # Convert existing schedules in the model to parametric schedules based on current hours of operation
242
+ standard.model_setup_parametric_schedules(model)
243
+
244
+ # Modify hours of operation, using weekdays values for all weekdays and weekend values for Saturday and Sunday
245
+ standard.schedule_ruleset_set_hours_of_operation(op_sch,
246
+ wkdy_start_time: wkdy_start_time,
247
+ wkdy_end_time: wkdy_end_time,
248
+ sat_start_time: sat_start_time,
249
+ sat_end_time: sat_end_time,
250
+ sun_start_time: sun_start_time,
251
+ sun_end_time: sun_end_time)
252
+
253
+ # Apply new operating hours to parametric schedules to make schedules in model reflect modified hours of operation
254
+ parametric_schedules = standard.model_apply_parametric_schedules(model, error_on_out_of_order: false)
255
+ puts "Updated #{parametric_schedules.size} schedules with new hours of operation."
256
+ return true
257
+ end
258
+
259
+ # add elevator
260
+ # @param model [OpenStudio::Model]
261
+ # @param standard [Standard]
262
+ # @return boolean
263
+ def add_elevator(model, standard)
264
+ # remove elevators as spaceLoads or exteriorLights
265
+ model.getSpaceLoads.each do |instance|
266
+ next if !instance.name.to_s.include?('Elevator') # most prototype building types model exterior elevators with name Elevator
267
+
268
+ instance.remove
269
+ end
270
+ model.getExteriorLightss.each do |ext_light|
271
+ next if !ext_light.name.to_s.include?('Fuel equipment') # some prototype building types model exterior elevators by this name
272
+
273
+ ext_light.remove
274
+ end
275
+
276
+ elevators = standard.model_add_elevators(model)
277
+ if elevators.nil?
278
+ OpenStudio.logFree(OpenStudio::Info, 'BuildingSync.LoadsSystem.add_elevator', 'No elevators added to the building.')
279
+ else
280
+ elevator_def = elevators.electricEquipmentDefinition
281
+ design_level = elevator_def.designLevel.get
282
+ OpenStudio.logFree(OpenStudio::Info, 'BuildingSync.LoadsSystem.add_elevator', "Adding #{elevators.multiplier.round(1)} elevators each with power of #{OpenStudio.toNeatString(design_level, 0, true)} (W), plus lights and fans.")
283
+ end
284
+ return true
285
+ end
286
+ end
287
+ end
@@ -0,0 +1,129 @@
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
+ # base class for objects that will configure workflows based on building sync files
42
+ class LocationElement < SpatialElement
43
+ # initialize LocationElement class
44
+ # @param base_xml [REXML::Element] an element corresponding to a locational element
45
+ # either an auc:Site or auc:Building
46
+ # @param ns [String] namespace, likely 'auc'
47
+ def initialize(base_xml, ns)
48
+ super(base_xml, ns)
49
+ @base_xml = base_xml
50
+ @ns = ns
51
+
52
+ @climate_zone = nil
53
+ @climate_zone_ashrae = nil
54
+ @climate_zone_ca_t24 = nil
55
+ @city_name = nil
56
+ @state_name = nil
57
+
58
+ read_location_values
59
+ end
60
+
61
+ # read location values
62
+ def read_location_values
63
+ # read in the ASHRAE climate zone
64
+ read_climate_zone
65
+
66
+ # read city and state name
67
+ read_city_and_state_name
68
+ end
69
+
70
+ def determine_climate_zone(standard_to_be_used = nil)
71
+ if standard_to_be_used == ASHRAE90_1
72
+ if !@climate_zone_ashrae.nil?
73
+ @climate_zone = @climate_zone_ashrae
74
+ elsif @climate_zone.nil? && !@climate_zone_ca_t24.nil?
75
+ @climate_zone = @climate_zone_ca_t24
76
+ OpenStudio.logFree(OpenStudio::Warn, 'BuildingSync.LocationElement.determine_climate_zone', "Element ID: #{xget_id} - Standard to use is #{standard_to_be_used} but ASHRAE Climate Zone is nil. Using CA T24: #{@climate_zone}")
77
+ end
78
+ elsif standard_to_be_used == CA_TITLE24
79
+ if !@climate_zone_ca_t24.nil?
80
+ @climate_zone = @climate_zone_ca_t24
81
+ elsif @climate_zone.nil? && !@climate_zone_ashrae.nil?
82
+ @climate_zone = @climate_zone_ashrae
83
+ OpenStudio.logFree(OpenStudio::Warn, 'BuildingSync.LocationElement.determine_climate_zone', "Element ID: #{xget_id} - Standard to use is #{standard_to_be_used} but CA T24 Climate Zone is nil. Using ASHRAE: #{@climate_zone}")
84
+ end
85
+ end
86
+ end
87
+
88
+ # get climate zone
89
+ # @param standard_to_be_used [String]
90
+ # @return [String]
91
+ def get_climate_zone
92
+ return @climate_zone
93
+ end
94
+
95
+ # read climate zone
96
+ def read_climate_zone
97
+ if @base_xml.elements["#{@ns}:ClimateZoneType/#{@ns}:ASHRAE"]
98
+ @climate_zone_ashrae = @base_xml.elements["#{@ns}:ClimateZoneType/#{@ns}:ASHRAE/#{@ns}:ClimateZone"].text
99
+ OpenStudio.logFree(OpenStudio::Info, 'BuildingSync.LocationElement.read_climate_zone', "Element ID: #{xget_id} - ASHRAE Climate Zone: #{@climate_zone_ashrae}")
100
+ else
101
+ @climate_zone_ashrae = nil
102
+ end
103
+ if @base_xml.elements["#{@ns}:ClimateZoneType/#{@ns}:CaliforniaTitle24"]
104
+ @climate_zone_ca_t24 = @base_xml.elements["#{@ns}:ClimateZoneType/#{@ns}:CaliforniaTitle24/#{@ns}:ClimateZone"].text
105
+ OpenStudio.logFree(OpenStudio::Info, 'BuildingSync.LocationElement.read_climate_zone', "Element ID: #{xget_id} - Title24 Climate Zone: #{@climate_zone_ca_t24}")
106
+ else
107
+ @climate_zone_ca_t24 = nil
108
+ end
109
+
110
+ if @climate_zone_ashrae.nil? && @climate_zone_ca_t24.nil?
111
+ OpenStudio.logFree(OpenStudio::Warn, 'BuildingSync.LocationElement.read_climate_zone', "Element ID: #{xget_id} - Title24 Climate Zone and ASHRAE Climate Zone not found")
112
+ end
113
+ end
114
+
115
+ # read city and state name
116
+ def read_city_and_state_name
117
+ if @base_xml.elements["#{@ns}:Address/#{@ns}:City"]
118
+ @city_name = @base_xml.elements["#{@ns}:Address/#{@ns}:City"].text
119
+ else
120
+ @city_name = nil
121
+ end
122
+ if @base_xml.elements["#{@ns}:Address/#{@ns}:State"]
123
+ @state_name = @base_xml.elements["#{@ns}:Address/#{@ns}:State"].text
124
+ else
125
+ @state_name = nil
126
+ end
127
+ end
128
+ end
129
+ end