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.
- checksums.yaml +7 -0
- data/.github/workflows/continuous_integration.yml +146 -0
- data/.gitignore +33 -0
- data/.rspec +3 -0
- data/.rubocop.yml +10 -0
- data/CHANGELOG.md +50 -0
- data/Gemfile +31 -0
- data/Jenkinsfile +10 -0
- data/LICENSE.md +29 -0
- data/README.md +105 -0
- data/Rakefile +77 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/buildingsync.gemspec +37 -0
- data/config.rb.in +26 -0
- data/doc_templates/LICENSE.md +29 -0
- data/doc_templates/README.md.erb +42 -0
- data/doc_templates/copyright_erb.txt +38 -0
- data/doc_templates/copyright_js.txt +5 -0
- data/doc_templates/copyright_ruby.txt +36 -0
- data/lib/buildingsync.rb +43 -0
- data/lib/buildingsync/all_resource_total.rb +54 -0
- data/lib/buildingsync/audit_date.rb +54 -0
- data/lib/buildingsync/constants.rb +49 -0
- data/lib/buildingsync/contact.rb +54 -0
- data/lib/buildingsync/extension.rb +57 -0
- data/lib/buildingsync/generator.rb +584 -0
- data/lib/buildingsync/get_bcl_weather_file.rb +326 -0
- data/lib/buildingsync/helpers/Model.hvac.rb +216 -0
- data/lib/buildingsync/helpers/helper.rb +494 -0
- data/lib/buildingsync/helpers/xml_get_set.rb +215 -0
- data/lib/buildingsync/makers/phase_zero_base.osw +178 -0
- data/lib/buildingsync/makers/workflow_maker.json +811 -0
- data/lib/buildingsync/makers/workflow_maker.rb +581 -0
- data/lib/buildingsync/makers/workflow_maker_base.rb +167 -0
- data/lib/buildingsync/model_articulation/building.rb +1119 -0
- data/lib/buildingsync/model_articulation/building_and_system_types.json +121 -0
- data/lib/buildingsync/model_articulation/building_section.rb +190 -0
- data/lib/buildingsync/model_articulation/building_system.rb +49 -0
- data/lib/buildingsync/model_articulation/envelope_system.rb +102 -0
- data/lib/buildingsync/model_articulation/exterior_floor_system_type.rb +64 -0
- data/lib/buildingsync/model_articulation/facility.rb +439 -0
- data/lib/buildingsync/model_articulation/foundation_system_type.rb +64 -0
- data/lib/buildingsync/model_articulation/hvac_system.rb +395 -0
- data/lib/buildingsync/model_articulation/lighting_system.rb +102 -0
- data/lib/buildingsync/model_articulation/loads_system.rb +287 -0
- data/lib/buildingsync/model_articulation/location_element.rb +129 -0
- data/lib/buildingsync/model_articulation/measure.rb +57 -0
- data/lib/buildingsync/model_articulation/roof_system_type.rb +64 -0
- data/lib/buildingsync/model_articulation/service_hot_water_system.rb +87 -0
- data/lib/buildingsync/model_articulation/site.rb +242 -0
- data/lib/buildingsync/model_articulation/spatial_element.rb +343 -0
- data/lib/buildingsync/model_articulation/wall_system_type.rb +64 -0
- data/lib/buildingsync/report.rb +217 -0
- data/lib/buildingsync/resource_use.rb +55 -0
- data/lib/buildingsync/scenario.rb +622 -0
- data/lib/buildingsync/selection_tool.rb +98 -0
- data/lib/buildingsync/time_series.rb +85 -0
- data/lib/buildingsync/translator.rb +167 -0
- data/lib/buildingsync/utility.rb +67 -0
- data/lib/buildingsync/version.rb +45 -0
- 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
|