buildingsync 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|