openstudio-metadata 0.0.1
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/.gitignore +49 -0
- data/.rakeTasks +7 -0
- data/.rspec +1 -0
- data/.rubocop.yml +9 -0
- data/.travis.yml +20 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +23 -0
- data/README.md +66 -0
- data/Rakefile +22 -0
- data/doc_templates/LICENSE.md +27 -0
- data/doc_templates/README.md.erb +42 -0
- data/doc_templates/copyright_erb.txt +36 -0
- data/doc_templates/copyright_js.txt +4 -0
- data/doc_templates/copyright_ruby.txt +34 -0
- data/lib/.DS_Store +0 -0
- data/lib/files/brick/1.1/Brick.ttl +11144 -0
- data/lib/files/haystack/3.9.9/defs.ttl +5205 -0
- data/lib/files/mappings.json +388 -0
- data/lib/files/templates.yaml +361 -0
- data/lib/measures/haystack/measure.rb +574 -0
- data/lib/measures/haystack/measure.xml +83 -0
- data/lib/openstudio/metadata/controls.rb +220 -0
- data/lib/openstudio/metadata/creator.rb +432 -0
- data/lib/openstudio/metadata/helpers.rb +184 -0
- data/lib/openstudio/metadata/serializer.rb +141 -0
- data/lib/openstudio/metadata/version.rb +40 -0
- data/lib/openstudio/metadata/writer.rb +107 -0
- data/lib/openstudio/metadata.rb +55 -0
- data/lib/openstudio-metadata.rb +1 -0
- data/openstudio-metadata.gemspec +32 -0
- data/test.rb +15 -0
- metadata +165 -0
@@ -0,0 +1,574 @@
|
|
1
|
+
########################################################################################################################
|
2
|
+
# Copyright (c) 2008-2018, Alliance for Sustainable Energy, LLC, and other contributors. All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
|
5
|
+
# following conditions are met:
|
6
|
+
#
|
7
|
+
# (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following
|
8
|
+
# disclaimer.
|
9
|
+
#
|
10
|
+
# (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
|
11
|
+
# disclaimer in the documentation and/or other materials provided with the distribution.
|
12
|
+
#
|
13
|
+
# (3) Neither the name of the copyright holder nor the names of any contributors may be used to endorse or promote products
|
14
|
+
# derived from this software without specific prior written permission from the respective party.
|
15
|
+
#
|
16
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
17
|
+
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE UNITED STATES GOVERNMENT, OR THE UNITED
|
19
|
+
# STATES DEPARTMENT OF ENERGY, NOR ANY OF THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
20
|
+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
21
|
+
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
22
|
+
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
23
|
+
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
24
|
+
########################################################################################################################
|
25
|
+
|
26
|
+
require 'json'
|
27
|
+
require_relative 'resources/openstudio-metadata-gem/lib/openstudio/metadata'
|
28
|
+
|
29
|
+
# start the measure
|
30
|
+
class Haystack < OpenStudio::Ruleset::ModelUserScript
|
31
|
+
# human readable name
|
32
|
+
def name
|
33
|
+
return 'Haystack'
|
34
|
+
end
|
35
|
+
|
36
|
+
# human readable description
|
37
|
+
def description
|
38
|
+
return 'This measure will find economizers on airloops and add haystack tags.'
|
39
|
+
end
|
40
|
+
|
41
|
+
# human readable description of modeling approach
|
42
|
+
def modeler_description
|
43
|
+
return 'This measure loops through the existing airloops, looking for loops that have outdoor airsystems with economizers'
|
44
|
+
end
|
45
|
+
|
46
|
+
# define the arguments that the user will input
|
47
|
+
def arguments(model)
|
48
|
+
args = OpenStudio::Ruleset::OSArgumentVector.new
|
49
|
+
|
50
|
+
local_test = OpenStudio::Ruleset::OSArgument.makeBoolArgument('local_test', false)
|
51
|
+
local_test.setDisplayName('Local Test')
|
52
|
+
local_test.setDescription('Use EMS for Local Testing')
|
53
|
+
local_test.setDefaultValue(true)
|
54
|
+
args << local_test
|
55
|
+
|
56
|
+
return args
|
57
|
+
end # end the arguments method
|
58
|
+
|
59
|
+
# define what happens when the measure is run
|
60
|
+
def run(model, runner, user_arguments)
|
61
|
+
super(model, runner, user_arguments)
|
62
|
+
|
63
|
+
# Use the built-in error checking
|
64
|
+
if !runner.validateUserArguments(arguments(model), user_arguments)
|
65
|
+
return false
|
66
|
+
end
|
67
|
+
|
68
|
+
local_test = runner.getBoolArgumentValue('local_test', user_arguments)
|
69
|
+
runner.registerInfo("local_test = #{local_test}")
|
70
|
+
|
71
|
+
# initialize tagger
|
72
|
+
tagger = OpenStudio::Metadata::Tagger.new(model)
|
73
|
+
|
74
|
+
# Global Vars
|
75
|
+
report_freq = 'timestep'
|
76
|
+
|
77
|
+
# initialize variables
|
78
|
+
haystack_json = []
|
79
|
+
mapping_json = []
|
80
|
+
num_economizers = 0
|
81
|
+
airloops = []
|
82
|
+
|
83
|
+
# Master Enable
|
84
|
+
if local_test == false
|
85
|
+
# External Interface version
|
86
|
+
runner.registerInitialCondition('Initializing ExternalInterface')
|
87
|
+
master_enable = OpenStudio::Model::ExternalInterfaceVariable.new(model, 'MasterEnable', 1)
|
88
|
+
# TODO: uncomment out for real use
|
89
|
+
externalInterface = model.getExternalInterface
|
90
|
+
externalInterface.setNameofExternalInterface('PtolemyServer')
|
91
|
+
else
|
92
|
+
# EMS Version
|
93
|
+
runner.registerInitialCondition('Initializing EnergyManagementSystem')
|
94
|
+
master_enable = OpenStudio::Model::EnergyManagementSystemGlobalVariable.new(model, 'MasterEnable')
|
95
|
+
end
|
96
|
+
|
97
|
+
# initialization program
|
98
|
+
program = OpenStudio::Model::EnergyManagementSystemProgram.new(model)
|
99
|
+
program.setName('Master_Enable')
|
100
|
+
program.addLine("SET #{master_enable.handle} = 1")
|
101
|
+
|
102
|
+
pcm = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(model)
|
103
|
+
pcm.setName('Master_Enable_Prgm_Mgr')
|
104
|
+
pcm.setCallingPoint('BeginNewEnvironment')
|
105
|
+
pcm.addProgram(program)
|
106
|
+
|
107
|
+
# Site and WeatherFile Data
|
108
|
+
if model.weatherFile.is_initialized
|
109
|
+
|
110
|
+
wf = model.weatherFile.get
|
111
|
+
building = model.getBuilding
|
112
|
+
simCon = model.getSimulationControl
|
113
|
+
|
114
|
+
# Define the site, weather, and floor for haystack
|
115
|
+
tagger.tag_site
|
116
|
+
tagger.tag_weather
|
117
|
+
tagger.tag_thermal_zones
|
118
|
+
tagger.tag_air_loop_fans
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
## Add tags to the time-variable outputs
|
123
|
+
# #output_vars = model.getOutputVariables
|
124
|
+
# output_vars = model.getEnergyManagementSystemOutputVariables
|
125
|
+
# output_vars_sorted = output_vars.sort_by{ |m| [ m.nameString.downcase]}
|
126
|
+
# output_vars_sorted.each do |outvar|
|
127
|
+
# #if (outvar.keyValue.to_s == "*")
|
128
|
+
# #print outvar
|
129
|
+
# print "\n The haystack tag is beding added to time-variables!!!"
|
130
|
+
# haystack_temp_json, temp_uuid = tagger.create_point_timevars(outvar, model.getBuilding.handle)
|
131
|
+
# haystack_json << haystack_temp_json
|
132
|
+
# temp_mapping = tagger.create_mapping_timevars(outvar,temp_uuid)
|
133
|
+
# mapping_json << temp_mapping
|
134
|
+
# #end
|
135
|
+
#
|
136
|
+
# end # end of do loop
|
137
|
+
|
138
|
+
# Export all user defined OutputVariable objects
|
139
|
+
# as haystack sensor points
|
140
|
+
building = model.getBuilding
|
141
|
+
output_vars = model.getOutputVariables
|
142
|
+
output_vars.each do |outvar|
|
143
|
+
if outvar.exportToBCVTB
|
144
|
+
|
145
|
+
user_defined_sensor_point = tagger.tag_sensor(outvar.handle, outvar.nameString, building.handle)
|
146
|
+
haystack_json << user_defined_sensor_point
|
147
|
+
|
148
|
+
uuid = tagger.haystack_format_as_ref(outvar.handle)
|
149
|
+
var_map_json = {}
|
150
|
+
var_map_json[:id] = uuid
|
151
|
+
var_map_json[:source] = 'EnergyPlus'
|
152
|
+
var_map_json[:type] = outvar.variableName
|
153
|
+
var_map_json[:name] = outvar.keyValue
|
154
|
+
var_map_json[:variable] = ''
|
155
|
+
mapping_json << var_map_json
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# Tag thermal zones
|
160
|
+
|
161
|
+
# Tag fans
|
162
|
+
|
163
|
+
# Export all user defined EnergyManagementSystemGlobalVariable objects
|
164
|
+
# as haystack writable points
|
165
|
+
global_vars = model.getEnergyManagementSystemGlobalVariables
|
166
|
+
global_vars.each do |globalvar|
|
167
|
+
if globalvar.exportToBCVTB
|
168
|
+
uuid = tagger.haystack_format_as_ref(globalvar.handle)
|
169
|
+
if !globalvar.nameString.end_with?('_Enable')
|
170
|
+
user_defined_writable_point = tagger.tag_writable_point(globalvar.nameString, building.handle, uuid)
|
171
|
+
haystack_json << user_defined_writable_point
|
172
|
+
end
|
173
|
+
|
174
|
+
var_mapping_json = {}
|
175
|
+
var_mapping_json[:id] = uuid
|
176
|
+
var_mapping_json[:source] = 'Ptolemy'
|
177
|
+
var_mapping_json[:name] = ''
|
178
|
+
var_mapping_json[:type] = ''
|
179
|
+
var_mapping_json[:variable] = globalvar.nameString
|
180
|
+
mapping_json << var_mapping_json
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# loop through air loops and find economizers
|
185
|
+
model.getAirLoopHVACs.each do |airloop|
|
186
|
+
supply_components = airloop.supplyComponents
|
187
|
+
# find AirLoopHVACOutdoorAirSystem on loop
|
188
|
+
supply_components.each do |supply_component|
|
189
|
+
sc = supply_component.to_AirLoopHVACOutdoorAirSystem
|
190
|
+
if sc.is_initialized
|
191
|
+
sc = sc.get
|
192
|
+
# get ControllerOutdoorAir
|
193
|
+
controller_oa = sc.getControllerOutdoorAir
|
194
|
+
# log initial economizer type
|
195
|
+
if controller_oa.getEconomizerControlType != 'NoEconomizer'
|
196
|
+
runner.registerInfo("found economizer on airloop #{airloop.name}")
|
197
|
+
# puts "found economizer on airloop #{airloop.name.to_s}"
|
198
|
+
num_economizers += 1
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
# loop through economizer loops and find fans and cooling coils
|
205
|
+
model.getAirLoopHVACs.each do |airloop|
|
206
|
+
ahu_json = tagger.create_ahu(airloop.handle, airloop.name.to_s, building.handle, simCon.handle)
|
207
|
+
|
208
|
+
# AHU discharge sensors
|
209
|
+
# discharge air node
|
210
|
+
discharge_air_node = airloop.supplyOutletNode
|
211
|
+
# Tag Temp, Pressure, Humidity, and Flow Sensors
|
212
|
+
discharge_temp_sensor, discharge_temp_uuid = tagger.create_point_uuid('sensor', "#{airloop.name} Discharge Air Temp Sensor", building.handle, airloop.handle, simCon.handle, 'discharge', 'air', 'temp', 'Number', 'C')
|
213
|
+
discharge_pressure_sensor, discharge_pressure_uuid = tagger.create_point_uuid('sensor', "#{airloop.name} Discharge Air Pressure Sensor", building.handle, airloop.handle, simCon.handle, 'discharge', 'air', 'pressure', 'Number', 'Pa')
|
214
|
+
discharge_humidity_sensor, discharge_humidity_uuid = tagger.create_point_uuid('sensor', "#{airloop.name} Discharge Air Humidity Sensor", building.handle, airloop.handle, simCon.handle, 'discharge', 'air', 'humidity', 'Number', '%')
|
215
|
+
discharge_flow_sensor, discharge_flow_uuid = tagger.create_point_uuid('sensor', "#{airloop.name} Discharge Air Flow Sensor", building.handle, airloop.handle, simCon.handle, 'discharge', 'air', 'flow', 'Number', 'Kg/s')
|
216
|
+
haystack_json.push(discharge_temp_sensor, discharge_pressure_sensor, discharge_humidity_sensor, discharge_flow_sensor)
|
217
|
+
|
218
|
+
# Controls Definitions and assignments
|
219
|
+
discharge_air_temp_sensor, temp_json = tagger.create_EMS_sensor_bcvtb('System Node Temperature', discharge_air_node, "#{airloop.name} Discharge Air Temp Sensor", discharge_temp_uuid, report_freq, model)
|
220
|
+
mapping_json << temp_json
|
221
|
+
discharge_air_pressure_sensor = tagger.create_EMS_sensor('System Node Pressure', discharge_air_node, "#{airloop.name} Discharge Air Pressure Sensor", report_freq, model)
|
222
|
+
discharge_air_humidity_sensor = tagger.create_EMS_sensor('System Node Relative Humidity', discharge_air_node, "#{airloop.name} Discharge Air Humidity Sensor", report_freq, model)
|
223
|
+
discharge_air_flow_sensor, temp_json = tagger.create_EMS_sensor_bcvtb('System Node Mass Flow Rate', discharge_air_node, "#{airloop.name} Discharge Air Flow Sensor", discharge_flow_uuid, report_freq, model)
|
224
|
+
mapping_json << temp_json
|
225
|
+
|
226
|
+
supply_components = airloop.supplyComponents
|
227
|
+
|
228
|
+
# find fan, cooling coil and heating coil on loop
|
229
|
+
supply_components.each do |sc|
|
230
|
+
# get economizer on outdoor air system
|
231
|
+
if sc.to_AirLoopHVACOutdoorAirSystem.is_initialized
|
232
|
+
sc = sc.to_AirLoopHVACOutdoorAirSystem.get
|
233
|
+
# get ControllerOutdoorAir
|
234
|
+
controller_oa = sc.getControllerOutdoorAir
|
235
|
+
# create damper sensor and cmd points
|
236
|
+
damper_command = tagger.create_ems_str("#{airloop.name} Outside Air Damper CMD")
|
237
|
+
damper_command_enable = tagger.create_ems_str("#{airloop.name} Outside Air Damper CMD Enable")
|
238
|
+
damper_position = tagger.create_ems_str("#{airloop.name} Outside Air Damper Sensor position")
|
239
|
+
# Damper Sensor
|
240
|
+
haystack_temp_json, temp_uuid = tagger.create_point2_uuid('sensor', 'position', damper_position, building.handle, airloop.handle, simCon.handle, 'outside', 'air', 'damper', 'Number', '%')
|
241
|
+
haystack_json << haystack_temp_json
|
242
|
+
outside_air_damper_sensor, temp_json = tagger.create_EMS_sensor_bcvtb('Air System Outdoor Air Flow Fraction', airloop, "#{airloop.name} Outside Air Damper Sensor", temp_uuid, report_freq, model)
|
243
|
+
mapping_json << temp_json
|
244
|
+
|
245
|
+
# add EMS Actuator for Damper
|
246
|
+
damper_actuator = OpenStudio::Model::EnergyManagementSystemActuator.new(controller_oa, 'Outdoor Air Controller', 'Air Mass Flow Rate')
|
247
|
+
damper_actuator.setName(tagger.create_ems_str("#{airloop.name} Outside Air Mass Flow Rate"))
|
248
|
+
# Variable to read the Damper CMD
|
249
|
+
if local_test == false
|
250
|
+
# ExternalInterfaceVariables
|
251
|
+
damper_variable_enable = OpenStudio::Model::ExternalInterfaceVariable.new(model, damper_command_enable, 1)
|
252
|
+
mapping_json << tagger.create_mapping_output_uuid(damper_command_enable, damper_variable_enable.handle)
|
253
|
+
damper_variable = OpenStudio::Model::ExternalInterfaceVariable.new(model, damper_command, 0.5)
|
254
|
+
mapping_json << tagger.create_mapping_output_uuid(damper_command, damper_variable.handle)
|
255
|
+
# Damper CMD
|
256
|
+
haystack_temp_json = tagger.create_controlpoint2('cmd', 'writable', damper_command, damper_variable.handle, building.handle, airloop.handle, simCon.handle, 'outside', 'air', 'damper', 'Number', '%')
|
257
|
+
haystack_json << haystack_temp_json
|
258
|
+
else
|
259
|
+
# EnergyManagementSystemVariables
|
260
|
+
damper_variable_enable = OpenStudio::Model::EnergyManagementSystemGlobalVariable.new(model, damper_command_enable.to_s)
|
261
|
+
mapping_json << tagger.create_mapping_output_uuid(damper_command_enable, damper_variable_enable.handle)
|
262
|
+
damper_variable = OpenStudio::Model::EnergyManagementSystemGlobalVariable.new(model, damper_command.to_s)
|
263
|
+
mapping_json << tagger.create_mapping_output_uuid(damper_command, damper_variable.handle)
|
264
|
+
# Damper CMD
|
265
|
+
haystack_temp_json = tagger.create_controlpoint2('cmd', 'writable', damper_command, damper_variable.handle, building.handle, airloop.handle, simCon.handle, 'outside', 'air', 'damper', 'Number', '%')
|
266
|
+
haystack_json << haystack_temp_json
|
267
|
+
# initialization program
|
268
|
+
program = OpenStudio::Model::EnergyManagementSystemProgram.new(model)
|
269
|
+
program.setName("#{damper_command}_Prgm_init")
|
270
|
+
# Turn off for now
|
271
|
+
program.addLine("SET #{damper_variable_enable.handle} = 0")
|
272
|
+
program.addLine("SET #{damper_variable.handle} = 0.5")
|
273
|
+
|
274
|
+
pcm = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(model)
|
275
|
+
pcm.setName("#{damper_command}_Prgm_Mgr_init")
|
276
|
+
pcm.setCallingPoint('BeginNewEnvironment')
|
277
|
+
pcm.addProgram(program)
|
278
|
+
end
|
279
|
+
# mixed air node
|
280
|
+
if sc.mixedAirModelObject.is_initialized
|
281
|
+
# AHU mixed sensors
|
282
|
+
# mixed air node
|
283
|
+
mix_air_node = sc.mixedAirModelObject.get.to_Node.get
|
284
|
+
runner.registerInfo("found mixed air node #{mix_air_node.name} on airloop #{airloop.name}")
|
285
|
+
# Temp Sensor
|
286
|
+
haystack_temp_json, temp_uuid = tagger.create_point_uuid('sensor', "#{airloop.name} Mixed Air Temp Sensor", building.handle, airloop.handle, simCon.handle, 'mixed', 'air', 'temp', 'Number', 'C')
|
287
|
+
haystack_json << haystack_temp_json
|
288
|
+
mixed_air_temp_sensor, temp_json = tagger.create_EMS_sensor_bcvtb('System Node Temperature', mix_air_node, "#{airloop.name} Mixed Air Temp Sensor", temp_uuid, report_freq, model)
|
289
|
+
mapping_json << temp_json
|
290
|
+
# Pressure Sensor
|
291
|
+
haystack_temp_json, temp_uuid = tagger.create_point_uuid('sensor', "#{airloop.name} Mixed Air Pressure Sensor", building.handle, airloop.handle, simCon.handle, 'mixed', 'air', 'pressure', 'Number', 'Pa')
|
292
|
+
haystack_json << haystack_temp_json
|
293
|
+
mixed_air_pressure_sensor = tagger.create_EMS_sensor('System Node Pressure', mix_air_node, "#{airloop.name} Mixed Air Pressure Sensor", report_freq, model)
|
294
|
+
# Humidity Sensor
|
295
|
+
haystack_temp_json, temp_uuid = tagger.create_point_uuid('sensor', "#{airloop.name} Mixed Air Humidity Sensor", building.handle, airloop.handle, simCon.handle, 'mixed', 'air', 'humidity', 'Number', '%')
|
296
|
+
haystack_json << haystack_temp_json
|
297
|
+
mixed_air_humidity_sensor = tagger.create_EMS_sensor('System Node Relative Humidity', mix_air_node, "#{airloop.name} Mixed Air Humidity Sensor", report_freq, model)
|
298
|
+
# Flow Sensor
|
299
|
+
haystack_temp_json, temp_uuid = tagger.create_point_uuid('sensor', "#{airloop.name} Mixed Air Flow Sensor", building.handle, airloop.handle, simCon.handle, 'mixed', 'air', 'flow', 'Number', 'Kg/s')
|
300
|
+
haystack_json << haystack_temp_json
|
301
|
+
mixed_air_flow_sensor, temp_json = tagger.create_EMS_sensor_bcvtb('System Node Mass Flow Rate', mix_air_node, "#{airloop.name} Mixed Air Flow Sensor", temp_uuid, report_freq, model)
|
302
|
+
mapping_json << temp_json
|
303
|
+
end
|
304
|
+
# outdoor air node
|
305
|
+
if sc.outdoorAirModelObject.is_initialized
|
306
|
+
# AHU outside sensors
|
307
|
+
# outdoor air node
|
308
|
+
outdoor_air_node = sc.outdoorAirModelObject.get.to_Node.get
|
309
|
+
runner.registerInfo("found outdoor air node #{outdoor_air_node.name} on airloop #{airloop.name}")
|
310
|
+
# Temp Sensor
|
311
|
+
haystack_temp_json, temp_uuid = tagger.create_point_uuid('sensor', "#{airloop.name} Outside Air Temp Sensor", building.handle, airloop.handle, simCon.handle, 'outside', 'air', 'temp', 'Number', 'C')
|
312
|
+
haystack_json << haystack_temp_json
|
313
|
+
outside_air_temp_sensor, temp_json = tagger.create_EMS_sensor_bcvtb('System Node Temperature', outdoor_air_node, "#{airloop.name} Outside Air Temp Sensor", temp_uuid, report_freq, model)
|
314
|
+
mapping_json << temp_json
|
315
|
+
# Pressure Sensor
|
316
|
+
haystack_temp_json, temp_uuid = tagger.create_point_uuid('sensor', "#{airloop.name} Outside Air Pressure Sensor", building.handle, airloop.handle, simCon.handle, 'outside', 'air', 'pressure', 'Number', 'Pa')
|
317
|
+
haystack_json << haystack_temp_json
|
318
|
+
outside_air_pressure_sensor = tagger.create_EMS_sensor('System Node Pressure', outdoor_air_node, "#{airloop.name} Outside Air Pressure Sensor", report_freq, model)
|
319
|
+
# Humidity Sensor
|
320
|
+
haystack_temp_json, temp_uuid = tagger.create_point_uuid('sensor', "#{airloop.name} Outside Air Humidity Sensor", building.handle, airloop.handle, simCon.handle, 'outside', 'air', 'humidity', 'Number', '%')
|
321
|
+
haystack_json << haystack_temp_json
|
322
|
+
outside_air_humidity_sensor = tagger.create_EMS_sensor('System Node Relative Humidity', outdoor_air_node, "#{airloop.name} Outside Air Humidity Sensor", report_freq, model)
|
323
|
+
# Flow Sensor
|
324
|
+
haystack_temp_json, temp_uuid = tagger.create_point_uuid('sensor', "#{airloop.name} Outside Air Flow Sensor", building.handle, airloop.handle, simCon.handle, 'outside', 'air', 'flow', 'Number', 'Kg/s')
|
325
|
+
haystack_json << haystack_temp_json
|
326
|
+
outside_air_flow_sensor, temp_json = tagger.create_EMS_sensor_bcvtb('System Node Mass Flow Rate', outdoor_air_node, "#{airloop.name} Outside Air Flow Sensor", temp_uuid, report_freq, model)
|
327
|
+
mapping_json << temp_json
|
328
|
+
end
|
329
|
+
# return air node
|
330
|
+
if sc.returnAirModelObject.is_initialized
|
331
|
+
# AHU return sensors
|
332
|
+
# return air node
|
333
|
+
return_air_node = sc.returnAirModelObject.get.to_Node.get
|
334
|
+
runner.registerInfo("found return air node #{return_air_node.name} on airloop #{airloop.name}")
|
335
|
+
# Temp Sensor
|
336
|
+
haystack_temp_json, temp_uuid = tagger.create_point_uuid('sensor', "#{airloop.name} Return Air Temp Sensor", building.handle, airloop.handle, simCon.handle, 'return', 'air', 'temp', 'Number', 'C')
|
337
|
+
haystack_json << haystack_temp_json
|
338
|
+
return_air_temp_sensor, temp_json = tagger.create_EMS_sensor_bcvtb('System Node Temperature', return_air_node, "#{airloop.name} Return Air Temp Sensor", temp_uuid, report_freq, model)
|
339
|
+
mapping_json << temp_json
|
340
|
+
# Pressure Sensor
|
341
|
+
haystack_temp_json, temp_uuid = tagger.create_point_uuid('sensor', "#{airloop.name} Return Air Pressure Sensor", building.handle, airloop.handle, simCon.handle, 'return', 'air', 'pressure', 'Number', 'Pa')
|
342
|
+
haystack_json << haystack_temp_json
|
343
|
+
return_air_pressure_sensor = tagger.create_EMS_sensor('System Node Pressure', return_air_node, "#{airloop.name} Return Air Pressure Sensor", report_freq, model)
|
344
|
+
# Humidity Sensor
|
345
|
+
haystack_temp_json, temp_uuid = tagger.create_point_uuid('sensor', "#{airloop.name} Return Air Humidity Sensor", building.handle, airloop.handle, simCon.handle, 'return', 'air', 'humidity', 'Number', '%')
|
346
|
+
haystack_json << haystack_temp_json
|
347
|
+
return_air_humidity_sensor = tagger.create_EMS_sensor('System Node Relative Humidity', return_air_node, "#{airloop.name} Return Air Humidity Sensor", report_freq, model)
|
348
|
+
# Flow Sensor
|
349
|
+
haystack_temp_json, temp_uuid = tagger.create_point_uuid('sensor', "#{airloop.name} Return Air Flow Sensor", building.handle, airloop.handle, simCon.handle, 'return', 'air', 'flow', 'Number', 'Kg/s')
|
350
|
+
haystack_json << haystack_temp_json
|
351
|
+
return_air_flow_sensor, temp_json = tagger.create_EMS_sensor_bcvtb('System Node Mass Flow Rate', return_air_node, "#{airloop.name} Return Air Flow Sensor", temp_uuid, report_freq, model)
|
352
|
+
mapping_json << temp_json
|
353
|
+
end
|
354
|
+
# relief air node
|
355
|
+
if sc.reliefAirModelObject.is_initialized
|
356
|
+
# AHU exhaust sensors
|
357
|
+
# exhaust air node
|
358
|
+
exhaust_air_node = sc.reliefAirModelObject.get.to_Node.get
|
359
|
+
runner.registerInfo("found relief air node #{exhaust_air_node.name} on airloop #{airloop.name}")
|
360
|
+
# Temp Sensor
|
361
|
+
haystack_temp_json, temp_uuid = tagger.create_point_uuid('sensor', "#{airloop.name} Exhaust Air Temp Sensor", building.handle, airloop.handle, simCon.handle, 'exhaust', 'air', 'temp', 'Number', 'C')
|
362
|
+
haystack_json << haystack_temp_json
|
363
|
+
exhaust_air_temp_sensor, temp_json = tagger.create_EMS_sensor_bcvtb('System Node Temperature', exhaust_air_node, "#{airloop.name} Exhaust Air Temp Sensor", temp_uuid, report_freq, model)
|
364
|
+
mapping_json << temp_json
|
365
|
+
# Pressure Sensor
|
366
|
+
haystack_temp_json, temp_uuid = tagger.create_point_uuid('sensor', "#{airloop.name} Exhaust Air Pressure Sensor", building.handle, airloop.handle, simCon.handle, 'exhaust', 'air', 'pressure', 'Number', 'Pa')
|
367
|
+
haystack_json << haystack_temp_json
|
368
|
+
exhaust_air_pressure_sensor = tagger.create_EMS_sensor('System Node Pressure', exhaust_air_node, "#{airloop.name} Exhaust Air Pressure Sensor", report_freq, model)
|
369
|
+
# Humidity Sensor
|
370
|
+
haystack_temp_json, temp_uuid = tagger.create_point_uuid('sensor', "#{airloop.name} Exhaust Air Humidity Sensor", building.handle, airloop.handle, simCon.handle, 'exhaust', 'air', 'humidity', 'Number', '%')
|
371
|
+
haystack_json << haystack_temp_json
|
372
|
+
exhaust_air_humidity_sensor = tagger.create_EMS_sensor('System Node Relative Humidity', exhaust_air_node, "#{airloop.name} Exhaust Air Humidity Sensor", report_freq, model)
|
373
|
+
# Flow Sensor
|
374
|
+
haystack_temp_json, temp_uuid = tagger.create_point_uuid('sensor', "#{airloop.name} Exhaust Air Flow Sensor", building.handle, airloop.handle, simCon.handle, 'exhaust', 'air', 'flow', 'Number', 'Kg/s')
|
375
|
+
haystack_json << haystack_temp_json
|
376
|
+
exhaust_air_flow_sensor, temp_json = tagger.create_EMS_sensor_bcvtb('System Node Mass Flow Rate', exhaust_air_node, "#{airloop.name} Exhaust Air Flow Sensor", temp_uuid, report_freq, model)
|
377
|
+
mapping_json << temp_json
|
378
|
+
end
|
379
|
+
|
380
|
+
# Program to set the Damper Position
|
381
|
+
program = OpenStudio::Model::EnergyManagementSystemProgram.new(model)
|
382
|
+
program.setName("#{damper_command}_Prgm")
|
383
|
+
program.addLine("SET #{damper_actuator.handle} = Null")
|
384
|
+
program.addLine("IF #{master_enable.handle} == 1")
|
385
|
+
program.addLine(" SET DampPos = #{damper_variable.handle}")
|
386
|
+
program.addLine(" SET MixAir = #{mixed_air_flow_sensor.handle}")
|
387
|
+
program.addLine(" IF #{damper_variable_enable.handle} == 1")
|
388
|
+
program.addLine(" SET #{damper_actuator.handle} = DampPos*MixAir")
|
389
|
+
program.addLine(' ENDIF')
|
390
|
+
program.addLine('ENDIF')
|
391
|
+
|
392
|
+
pcm = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(model)
|
393
|
+
pcm.setName("#{damper_command}_Prgm_Mgr")
|
394
|
+
pcm.setCallingPoint('AfterPredictorAfterHVACManagers')
|
395
|
+
pcm.addProgram(program)
|
396
|
+
|
397
|
+
# its a UnitarySystem so get sub components
|
398
|
+
elsif sc.to_AirLoopHVACUnitarySystem.is_initialized
|
399
|
+
sc = sc.to_AirLoopHVACUnitarySystem.get
|
400
|
+
runner.registerInfo("found #{sc.name} on airloop #{airloop.name}")
|
401
|
+
ahu_json[:rooftop] = 'm:'
|
402
|
+
fan = sc.supplyFan
|
403
|
+
if fan.is_initialized
|
404
|
+
# AHU FAN equip
|
405
|
+
if fan.get.to_FanVariableVolume.is_initialized
|
406
|
+
runner.registerInfo("found VAV #{fan.get.name} on airloop #{airloop.name}")
|
407
|
+
ahu_json[:variableVolume] = 'm:'
|
408
|
+
haystack_json << tagger.create_fan(fan.get.handle, fan.get.name.to_s, building.handle, airloop.handle, simCon.handle, true)
|
409
|
+
else
|
410
|
+
runner.registerInfo("found CAV #{fan.get.name} on airloop #{airloop.name}")
|
411
|
+
ahu_json[:constantVolume] = 'm:'
|
412
|
+
haystack_json << tagger.create_fan(fan.get.handle, fan.get.name.to_s, building.handle, airloop.handle, simCon.handle, false)
|
413
|
+
end
|
414
|
+
end
|
415
|
+
cc = sc.coolingCoil
|
416
|
+
if cc.is_initialized
|
417
|
+
if cc.get.to_CoilCoolingWater.is_initialized || cc.get.to_CoilCoolingWaterToAirHeatPumpEquationFit.is_initialized
|
418
|
+
runner.registerInfo("found WATER #{cc.get.name} on airloop #{airloop.name}")
|
419
|
+
ahu_json[:chilledWaterCool] = 'm:'
|
420
|
+
if cc.get.plantLoop.is_initialized
|
421
|
+
pl = cc.get.plantLoop.get
|
422
|
+
ahu_json[:chilledWaterPlantRef] = tagger.haystack_format_as_ref(pl.handle)
|
423
|
+
end
|
424
|
+
if cc.get.to_CoilCoolingWaterToAirHeatPumpEquationFit.is_initialized
|
425
|
+
ahu_json[:heatPump] = 'm:'
|
426
|
+
end
|
427
|
+
else
|
428
|
+
runner.registerInfo("found DX #{cc.get.name} on airloop #{airloop.name}")
|
429
|
+
ahu_json[:dxCool] = 'm:'
|
430
|
+
end
|
431
|
+
end
|
432
|
+
hc = sc.heatingCoil
|
433
|
+
if hc.is_initialized
|
434
|
+
if hc.get.to_CoilHeatingElectric.is_initialized
|
435
|
+
runner.registerInfo("found ELECTRIC #{hc.get.name} on airloop #{airloop.name}")
|
436
|
+
ahu_json[:elecHeat] = 'm:'
|
437
|
+
elsif hc.get.to_CoilHeatingGas.is_initialized
|
438
|
+
runner.registerInfo("found GAS #{hc.get.name} on airloop #{airloop.name}")
|
439
|
+
ahu_json[:gasHeat] = 'm:'
|
440
|
+
elsif hc.get.to_CoilHeatingWater.is_initialized || hc.get.to_CoilHeatingWaterToAirHeatPumpEquationFit.is_initialized
|
441
|
+
runner.registerInfo("found WATER #{hc.get.name} on airloop #{airloop.name}")
|
442
|
+
ahu_json[:hotWaterHeat] = 'm:'
|
443
|
+
if hc.get.plantLoop.is_initialized
|
444
|
+
pl = hc.get.plantLoop.get
|
445
|
+
ahu_json[:hotWaterPlantRef] = tagger.haystack_format_as_ref(pl.handle)
|
446
|
+
end
|
447
|
+
if hc.get.to_CoilHeatingWaterToAirHeatPumpEquationFit.is_initialized
|
448
|
+
ahu_json[:heatPump] = 'm:'
|
449
|
+
end
|
450
|
+
end
|
451
|
+
end
|
452
|
+
# END UnitarySystem
|
453
|
+
elsif sc.to_FanConstantVolume.is_initialized
|
454
|
+
sc = sc.to_FanConstantVolume.get
|
455
|
+
runner.registerInfo("found #{sc.name} on airloop #{airloop.name}")
|
456
|
+
ahu_json[:constantVolume] = 'm:'
|
457
|
+
haystack_json << tagger.create_fan(sc.handle, sc.name.to_s, building.handle, airloop.handle, simCon.handle, false)
|
458
|
+
elsif sc.to_FanVariableVolume.is_initialized
|
459
|
+
sc = sc.to_FanVariableVolume.get
|
460
|
+
runner.registerInfo("found #{sc.name} on airloop #{airloop.name}")
|
461
|
+
ahu_json[:variableVolume] = 'm:'
|
462
|
+
haystack_json << tagger.create_fan(sc.handle, sc.name.to_s, building.handle, airloop.handle, simCon.handle, true)
|
463
|
+
elsif sc.to_FanOnOff.is_initialized
|
464
|
+
sc = sc.to_FanOnOff.get
|
465
|
+
runner.registerInfo("found #{sc.name} on airloop #{airloop.name}")
|
466
|
+
ahu_json[:constantVolume] = 'm:'
|
467
|
+
haystack_json << tagger.create_fan(sc.handle, sc.name.to_s, building.handle, airloop.handle, simCon.handle, false)
|
468
|
+
elsif sc.to_CoilCoolingWater.is_initialized
|
469
|
+
sc = sc.to_CoilCoolingWater.get
|
470
|
+
runner.registerInfo("found #{sc.name} on airloop #{airloop.name}")
|
471
|
+
ahu_json[:chilledWaterCool] = 'm:'
|
472
|
+
if sc.plantLoop.is_initialized
|
473
|
+
pl = sc.plantLoop.get
|
474
|
+
ahu_json[:chilledWaterPlantRef] = tagger.haystack_format_as_ref(pl.handle)
|
475
|
+
end
|
476
|
+
elsif sc.to_CoilHeatingWater.is_initialized
|
477
|
+
sc = sc.to_CoilHeatingWater.get
|
478
|
+
runner.registerInfo("found #{sc.name} on airloop #{airloop.name}")
|
479
|
+
ahu_json[:hotWaterHeat] = 'm:'
|
480
|
+
if sc.plantLoop.is_initialized
|
481
|
+
pl = sc.plantLoop.get
|
482
|
+
ahu_json[:hotWaterPlantRef] = tagger.haystack_format_as_ref(pl.handle)
|
483
|
+
end
|
484
|
+
elsif sc.to_CoilHeatingElectric.is_initialized
|
485
|
+
sc = sc.to_CoilHeatingElectric.get
|
486
|
+
runner.registerInfo("found #{sc.name} on airloop #{airloop.name}")
|
487
|
+
ahu_json[:elecHeat] = 'm:'
|
488
|
+
end
|
489
|
+
end # end supplycomponents
|
490
|
+
|
491
|
+
demand_components = airloop.demandComponents
|
492
|
+
demand_components.each do |dc|
|
493
|
+
if dc.to_ThermalZone.is_initialized
|
494
|
+
tz = dc.to_ThermalZone.get
|
495
|
+
# create sensor points
|
496
|
+
zone_json_temp, dummyvar = tagger.create_point_uuid('sensor', "#{tz.name} Zone Air Temp Sensor", building.handle, airloop.handle, simCon.handle, 'zone', 'air', 'temp', 'Number', 'C')
|
497
|
+
zone_json_humidity, dummyvar = tagger.create_point_uuid('sensor', "#{tz.name} Zone Air Humidity Sensor", building.handle, airloop.handle, simCon.handle, 'zone', 'air', 'humidity', 'Number', '%')
|
498
|
+
|
499
|
+
if tz.thermostatSetpointDualSetpoint.is_initialized
|
500
|
+
if tz.thermostatSetpointDualSetpoint.get.coolingSetpointTemperatureSchedule.is_initialized
|
501
|
+
cool_thermostat = tz.thermostatSetpointDualSetpoint.get.coolingSetpointTemperatureSchedule.get
|
502
|
+
runner.registerInfo("found #{cool_thermostat.name} on airloop #{airloop.name} in thermalzone #{tz.name}")
|
503
|
+
zone_json_cooling, dummyvar = tagger.create_point_uuid('sp', "#{tz.name} Zone Air Cooling sp", building.handle, airloop.handle, simCon.handle, 'zone', 'air', 'temp', 'Number', 'C')
|
504
|
+
zone_json_cooling[:cooling] = 'm:'
|
505
|
+
end
|
506
|
+
if tz.thermostatSetpointDualSetpoint.get.heatingSetpointTemperatureSchedule.is_initialized
|
507
|
+
heat_thermostat = tz.thermostatSetpointDualSetpoint.get.heatingSetpointTemperatureSchedule.get
|
508
|
+
runner.registerInfo("found #{heat_thermostat.name} on airloop #{airloop.name} in thermalzone #{tz.name}")
|
509
|
+
zone_json_heating, dummyvar = tagger.create_point_uuid('sp', "#{tz.name} Zone Air Heating sp", building.handle, airloop.handle, simCon.handle, 'zone', 'air', 'temp', 'Number', 'C')
|
510
|
+
zone_json_heating[:heating] = 'm:'
|
511
|
+
end
|
512
|
+
end
|
513
|
+
zone_json_temp[:area] = tagger.haystack_format_as_num(tz.floorArea)
|
514
|
+
if tz.volume.is_initialized
|
515
|
+
zone_json_temp[:volume] = tagger.haystack_format_as_num(tz.volume)
|
516
|
+
else
|
517
|
+
zone_json_temp[:volume] = tagger.haystack_format_as_num(0)
|
518
|
+
end
|
519
|
+
zone_json_humidity[:area] = tagger.haystack_format_as_num(tz.floorArea)
|
520
|
+
if tz.volume.is_initialized
|
521
|
+
zone_json_humidity[:volume] = tagger.haystack_format_as_num(tz.volume)
|
522
|
+
else
|
523
|
+
zone_json_humidity[:volume] = tagger.haystack_format_as_num(0)
|
524
|
+
end
|
525
|
+
|
526
|
+
tz.equipment.each do |equip|
|
527
|
+
if equip.to_AirTerminalSingleDuctVAVReheat.is_initialized
|
528
|
+
zone_json_temp[:vav] = 'm:'
|
529
|
+
zone_json_humidity[:vav] = 'm:'
|
530
|
+
zone_json_cooling[:vav] = 'm:'
|
531
|
+
zone_json_heating[:vav] = 'm:'
|
532
|
+
ahu_json[:vavZone] = 'm:'
|
533
|
+
|
534
|
+
vav_json = tagger.create_vav(equip.handle, equip.name.to_s)
|
535
|
+
|
536
|
+
haystack_json << vav_json
|
537
|
+
# entering and discharge sensors
|
538
|
+
entering_node = equip.to_AirTerminalSingleDuctVAVReheat.get.inletModelObject.get.to_Node
|
539
|
+
haystack_json_temp, temp_uuid = tagger.create_point_uuid('sensor', "#{equip.name} Entering Air Temp Sensor", building.handle, equip.handle, simCon.handle, 'entering', 'air', 'temp', 'Number', 'C')
|
540
|
+
haystack_json << haystack_json_temp
|
541
|
+
discharge_node = equip.to_AirTerminalSingleDuctVAVReheat.get.outletModelObject.get.to_Node
|
542
|
+
haystack_json_temp, temp_uuid = tagger.create_point_uuid('sensor', "#{equip.name} Discharge Air Temp Sensor", building.handle, equip.handle, simCon.handle, 'discharge', 'air', 'temp', 'Number', 'C')
|
543
|
+
haystack_json << haystack_json_temp
|
544
|
+
avail_sch = discharge_node = equip.to_AirTerminalSingleDuctVAVReheat.get.availabilitySchedule
|
545
|
+
# TODO: 'reheat cmd'
|
546
|
+
elsif equip.to_AirTerminalSingleDuctUncontrolled.is_initialized
|
547
|
+
ahu_json[:directZone] = 'm:'
|
548
|
+
end
|
549
|
+
end
|
550
|
+
haystack_json << zone_json_temp
|
551
|
+
haystack_json << zone_json_humidity
|
552
|
+
haystack_json << zone_json_cooling
|
553
|
+
haystack_json << zone_json_heating
|
554
|
+
end # end thermalzone
|
555
|
+
end # end demandcomponents
|
556
|
+
haystack_json << ahu_json
|
557
|
+
end # end airloops
|
558
|
+
|
559
|
+
runner.registerFinalCondition("The building has #{num_economizers} economizers")
|
560
|
+
# write out the haystack json
|
561
|
+
File.open('./report_haystack.json', 'w') do |f|
|
562
|
+
f.write(haystack_json.to_json)
|
563
|
+
end
|
564
|
+
# write out the mapping json
|
565
|
+
File.open('./report_mapping.json', 'w') do |f|
|
566
|
+
f.write(mapping_json.to_json)
|
567
|
+
end
|
568
|
+
|
569
|
+
return true
|
570
|
+
end # end the run method
|
571
|
+
end # end the measure
|
572
|
+
|
573
|
+
# register the measure to be used by the application
|
574
|
+
Haystack.new.registerWithApplication
|
@@ -0,0 +1,83 @@
|
|
1
|
+
<measure>
|
2
|
+
<schema_version>3.0</schema_version>
|
3
|
+
<name>haystack</name>
|
4
|
+
<uid>a3201f8c-bc3d-4fe1-a945-4a4f22471c06</uid>
|
5
|
+
<version_id>967b2a78-232e-479d-bf84-f21e146f6737</version_id>
|
6
|
+
<version_modified>20180109T180541Z</version_modified>
|
7
|
+
<xml_checksum>A9D5932A</xml_checksum>
|
8
|
+
<class_name>Haystack</class_name>
|
9
|
+
<display_name>Haystack</display_name>
|
10
|
+
<description>This measure will find economizers on airloops and add haystack tags.</description>
|
11
|
+
<modeler_description>This measure loops through the existing airloops, looking for loops that have outdoor airsystems with economizers</modeler_description>
|
12
|
+
<arguments>
|
13
|
+
<argument>
|
14
|
+
<name>local_test</name>
|
15
|
+
<display_name>Local Test</display_name>
|
16
|
+
<description>Use EMS for Local Testing</description>
|
17
|
+
<type>Boolean</type>
|
18
|
+
<required>false</required>
|
19
|
+
<model_dependent>false</model_dependent>
|
20
|
+
<default_value>true</default_value>
|
21
|
+
<choices>
|
22
|
+
<choice>
|
23
|
+
<value>true</value>
|
24
|
+
<display_name>true</display_name>
|
25
|
+
</choice>
|
26
|
+
<choice>
|
27
|
+
<value>false</value>
|
28
|
+
<display_name>false</display_name>
|
29
|
+
</choice>
|
30
|
+
</choices>
|
31
|
+
</argument>
|
32
|
+
</arguments>
|
33
|
+
<outputs/>
|
34
|
+
<provenances/>
|
35
|
+
<tags>
|
36
|
+
<tag>HVAC.Whole System</tag>
|
37
|
+
</tags>
|
38
|
+
<attributes>
|
39
|
+
<attribute>
|
40
|
+
<name>Measure Type</name>
|
41
|
+
<value>ModelMeasure</value>
|
42
|
+
<datatype>string</datatype>
|
43
|
+
</attribute>
|
44
|
+
<attribute>
|
45
|
+
<name>Intended Software Tool</name>
|
46
|
+
<value>Apply Measure Now</value>
|
47
|
+
<datatype>string</datatype>
|
48
|
+
</attribute>
|
49
|
+
<attribute>
|
50
|
+
<name>Intended Software Tool</name>
|
51
|
+
<value>OpenStudio Application</value>
|
52
|
+
<datatype>string</datatype>
|
53
|
+
</attribute>
|
54
|
+
<attribute>
|
55
|
+
<name>Intended Software Tool</name>
|
56
|
+
<value>Parametric Analysis Tool</value>
|
57
|
+
<datatype>string</datatype>
|
58
|
+
</attribute>
|
59
|
+
<attribute>
|
60
|
+
<name>Intended Use Case</name>
|
61
|
+
<value>Model Articulation</value>
|
62
|
+
<datatype>string</datatype>
|
63
|
+
</attribute>
|
64
|
+
<attribute>
|
65
|
+
<name>Intended Use Case</name>
|
66
|
+
<value>New Construction EE</value>
|
67
|
+
<datatype>string</datatype>
|
68
|
+
</attribute>
|
69
|
+
</attributes>
|
70
|
+
<files>
|
71
|
+
<file>
|
72
|
+
<version>
|
73
|
+
<software_program>OpenStudio</software_program>
|
74
|
+
<identifier>1.12.2</identifier>
|
75
|
+
<min_compatible>1.12.2</min_compatible>
|
76
|
+
</version>
|
77
|
+
<filename>measure.rb</filename>
|
78
|
+
<filetype>rb</filetype>
|
79
|
+
<usage_type>script</usage_type>
|
80
|
+
<checksum>5D641FEE</checksum>
|
81
|
+
</file>
|
82
|
+
</files>
|
83
|
+
</measure>
|