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,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