openstudio-ee 0.2.0 → 0.2.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 +4 -4
- data/CHANGELOG.md +16 -0
- data/Rakefile +2 -0
- data/lib/measures/ImproveFanTotalEfficiencybyPercentage/measure.rb +333 -0
- data/lib/measures/ImproveFanTotalEfficiencybyPercentage/measure.xml +150 -0
- data/lib/measures/ReplaceFanTotalEfficiency/measure.rb +330 -0
- data/lib/measures/ReplaceFanTotalEfficiency/measure.xml +150 -0
- data/lib/measures/add_apszhp_to_each_zone/measure.rb +607 -0
- data/lib/measures/add_apszhp_to_each_zone/measure.xml +184 -0
- data/lib/measures/add_energy_recovery_ventilator/measure.rb +354 -0
- data/lib/measures/add_energy_recovery_ventilator/measure.xml +78 -0
- data/lib/measures/improve_simple_glazing_by_percentage/measure.rb +81 -0
- data/lib/measures/improve_simple_glazing_by_percentage/measure.xml +70 -0
- data/lib/measures/reduce_water_use_by_percentage/measure.rb +61 -0
- data/lib/measures/reduce_water_use_by_percentage/measure.xml +62 -0
- data/lib/measures/replace_hvac_with_gshp_and_doas/measure.rb +511 -0
- data/lib/measures/replace_hvac_with_gshp_and_doas/measure.xml +375 -0
- data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_AedgMeasures.rb +454 -0
- data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_Constructions.rb +221 -0
- data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_Geometry.rb +41 -0
- data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_HVAC.rb +1682 -0
- data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_HelperMethods.rb +114 -0
- data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_LightingAndEquipment.rb +99 -0
- data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_Schedules.rb +142 -0
- data/lib/measures/replace_simple_glazing/measure.rb +86 -0
- data/lib/measures/replace_simple_glazing/measure.xml +78 -0
- data/lib/measures/set_boiler_thermal_efficiency/measure.rb +520 -0
- data/lib/measures/set_boiler_thermal_efficiency/measure.xml +78 -0
- data/lib/measures/set_water_heater_efficiency_heat_lossand_peak_water_flow_rate/measure.rb +207 -0
- data/lib/measures/set_water_heater_efficiency_heat_lossand_peak_water_flow_rate/measure.xml +78 -0
- data/lib/measures/tenant_star_internal_loads/measure.rb +134 -0
- data/lib/measures/tenant_star_internal_loads/measure.xml +67 -0
- data/lib/measures/tenant_star_internal_loads/resources/os_lib_helper_methods.rb +401 -0
- data/lib/measures/vr_fwith_doas/measure.rb +468 -0
- data/lib/measures/vr_fwith_doas/measure.xml +298 -0
- data/lib/measures/vr_fwith_doas/resources/OsLib_AedgMeasures.rb +454 -0
- data/lib/measures/vr_fwith_doas/resources/OsLib_Constructions.rb +221 -0
- data/lib/measures/vr_fwith_doas/resources/OsLib_Geometry.rb +41 -0
- data/lib/measures/vr_fwith_doas/resources/OsLib_HVAC.rb +1516 -0
- data/lib/measures/vr_fwith_doas/resources/OsLib_HelperMethods.rb +114 -0
- data/lib/measures/vr_fwith_doas/resources/OsLib_LightingAndEquipment.rb +99 -0
- data/lib/measures/vr_fwith_doas/resources/OsLib_Schedules.rb +142 -0
- data/lib/openstudio/ee_measures/version.rb +1 -1
- data/openstudio-ee.gemspec +7 -5
- metadata +48 -9
@@ -0,0 +1,468 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# see the URL below for information on how to write OpenStudio measures
|
4
|
+
# http://openstudio.nrel.gov/openstudio-measure-writing-guide
|
5
|
+
|
6
|
+
# see the URL below for information on using life cycle cost objects in OpenStudio
|
7
|
+
# http://openstudio.nrel.gov/openstudio-life-cycle-examples
|
8
|
+
|
9
|
+
# see the URL below for access to C++ documentation on model objects (click on "model" in the main window to view model objects)
|
10
|
+
# http://openstudio.nrel.gov/sites/openstudio.nrel.gov/files/nv_data/cpp_documentation_it/model/html/namespaces.html
|
11
|
+
|
12
|
+
# load OpenStudio measure libraries
|
13
|
+
# require "#{File.dirname(__FILE__)}/resources/OsLib_AedgMeasures"
|
14
|
+
require "#{File.dirname(__FILE__)}/resources/OsLib_HelperMethods"
|
15
|
+
require "#{File.dirname(__FILE__)}/resources/OsLib_HVAC"
|
16
|
+
require "#{File.dirname(__FILE__)}/resources/OsLib_Schedules"
|
17
|
+
|
18
|
+
# start the measure
|
19
|
+
class VRFwithDOAS < OpenStudio::Ruleset::ModelUserScript
|
20
|
+
# define the name that a user will see, this method may be deprecated as
|
21
|
+
# the display name in PAT comes from the name field in measure.xml
|
22
|
+
def name
|
23
|
+
return 'VRFwithDOAS'
|
24
|
+
end
|
25
|
+
|
26
|
+
# define the arguments that the user will input
|
27
|
+
def arguments(model)
|
28
|
+
args = OpenStudio::Ruleset::OSArgumentVector.new
|
29
|
+
|
30
|
+
# create an argument for a space type to be used in the model, to see if one should be mapped as ceiling return air plenum
|
31
|
+
spaceTypes = model.getSpaceTypes
|
32
|
+
usedSpaceTypes_handle = OpenStudio::StringVector.new
|
33
|
+
usedSpaceTypes_displayName = OpenStudio::StringVector.new
|
34
|
+
spaceTypes.each do |spaceType| # TODO: - I need to update this to use helper so GUI sorts by display name
|
35
|
+
if !spaceType.spaces.empty? # only show space types used in the building
|
36
|
+
usedSpaceTypes_handle << spaceType.handle.to_s
|
37
|
+
usedSpaceTypes_displayName << spaceType.name.to_s
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# make an argument for space type
|
42
|
+
ceilingReturnPlenumSpaceType = OpenStudio::Ruleset::OSArgument.makeChoiceArgument('ceilingReturnPlenumSpaceType', usedSpaceTypes_handle, usedSpaceTypes_displayName, false)
|
43
|
+
ceilingReturnPlenumSpaceType.setDisplayName('This space type should be part of a ceiling return air plenum.')
|
44
|
+
# ceilingReturnPlenumSpaceType.setDefaultValue("We don't want a default, this is an optional argument")
|
45
|
+
args << ceilingReturnPlenumSpaceType
|
46
|
+
|
47
|
+
# make a list of space types that will be changed
|
48
|
+
spaceTypes = model.getSpaceTypes
|
49
|
+
spaceTypes.each do |spaceType|
|
50
|
+
if !spaceType.spaces.empty?
|
51
|
+
space_type_to_edit = OpenStudio::Ruleset::OSArgument.makeBoolArgument(spaceType.name.get.to_s, true)
|
52
|
+
# make a bool argument for each space type
|
53
|
+
space_type_to_edit.setDisplayName("Add #{spaceType.name.get} space type to VRF system?")
|
54
|
+
space_type_to_edit.setDefaultValue(false)
|
55
|
+
args << space_type_to_edit
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# VRF Condenser Type
|
60
|
+
condenserChs = OpenStudio::StringVector.new
|
61
|
+
# condenserChs << "WaterCooled"
|
62
|
+
# condenserChs << "EvaporativelyCooled"
|
63
|
+
condenserChs << 'AirCooled'
|
64
|
+
vrfCondenserType = OpenStudio::Ruleset::OSArgument.makeChoiceArgument('vrfCondenserType', condenserChs, true)
|
65
|
+
vrfCondenserType.setDisplayName('VRF Condenser Type')
|
66
|
+
vrfCondenserType.setDefaultValue('AirCooled')
|
67
|
+
args << vrfCondenserType
|
68
|
+
|
69
|
+
# Cooling COP of VRF
|
70
|
+
vrfCoolCOP = OpenStudio::Ruleset::OSArgument.makeDoubleArgument('vrfCoolCOP', false)
|
71
|
+
vrfCoolCOP.setDisplayName('VRF Rated Cooling COP (Not Including Supply Fan)')
|
72
|
+
vrfCoolCOP.setDefaultValue(4.0)
|
73
|
+
args << vrfCoolCOP
|
74
|
+
|
75
|
+
# Heating COP of VRF
|
76
|
+
vrfHeatCOP = OpenStudio::Ruleset::OSArgument.makeDoubleArgument('vrfHeatCOP', false)
|
77
|
+
vrfHeatCOP.setDisplayName('VRF Rated Heating COP (Not Including Supply Fan)')
|
78
|
+
vrfHeatCOP.setDefaultValue(4.0)
|
79
|
+
args << vrfHeatCOP
|
80
|
+
|
81
|
+
# Minimum Outdoor Temperature in Heating Mode
|
82
|
+
vrfMinOATHPHeat = OpenStudio::Ruleset::OSArgument.makeDoubleArgument('vrfMinOATHPHeat', false)
|
83
|
+
vrfMinOATHPHeat.setDisplayName('Minimum Outdoor Temperature in Heat Pump Heating Mode (F)')
|
84
|
+
vrfMinOATHPHeat.setDefaultValue(-4.0)
|
85
|
+
args << vrfMinOATHPHeat
|
86
|
+
|
87
|
+
# Defrost Strategy
|
88
|
+
defrostChs = OpenStudio::StringVector.new
|
89
|
+
# defrostChs << "ReverseCycle"
|
90
|
+
defrostChs << 'Resistive'
|
91
|
+
vrfDefrost = OpenStudio::Ruleset::OSArgument.makeChoiceArgument('vrfDefrost', defrostChs, true)
|
92
|
+
vrfDefrost.setDisplayName('Defrost Strategy')
|
93
|
+
vrfDefrost.setDefaultValue('Resistive')
|
94
|
+
args << vrfDefrost
|
95
|
+
|
96
|
+
# Heat Pump Waste Heat Recovery
|
97
|
+
chs = OpenStudio::StringVector.new
|
98
|
+
chs << 'Yes'
|
99
|
+
chs << 'No'
|
100
|
+
vrfHPHeatRecovery = OpenStudio::Ruleset::OSArgument.makeChoiceArgument('vrfHPHeatRecovery', chs, true)
|
101
|
+
vrfHPHeatRecovery.setDisplayName('Heat Pump Waste Heat Recovery')
|
102
|
+
vrfHPHeatRecovery.setDefaultValue('Yes')
|
103
|
+
args << vrfHPHeatRecovery
|
104
|
+
|
105
|
+
# Equivalent Piping Length used for Piping Correction Factor in Cooling and Heating Mode
|
106
|
+
vrfEquivPipingLength = OpenStudio::Ruleset::OSArgument.makeDoubleArgument('vrfEquivPipingLength', false)
|
107
|
+
vrfEquivPipingLength.setDisplayName('Equivalent Piping Length Used for Piping Correction Factor (ft)')
|
108
|
+
vrfEquivPipingLength.setDefaultValue(100.0)
|
109
|
+
args << vrfEquivPipingLength
|
110
|
+
|
111
|
+
# Vertical Height Used for Piping Correction Factor
|
112
|
+
vrfPipingHeight = OpenStudio::Ruleset::OSArgument.makeDoubleArgument('vrfPipingHeight', false)
|
113
|
+
vrfPipingHeight.setDisplayName('Vertical Height used for Piping Correction Factor (ft)')
|
114
|
+
vrfPipingHeight.setDefaultValue(35.0)
|
115
|
+
args << vrfPipingHeight
|
116
|
+
|
117
|
+
# DOAS Fan Type
|
118
|
+
doasFanChs = OpenStudio::StringVector.new
|
119
|
+
doasFanChs << 'Constant'
|
120
|
+
doasFanChs << 'Variable'
|
121
|
+
doasFanType = OpenStudio::Ruleset::OSArgument.makeChoiceArgument('doasFanType', doasFanChs, true)
|
122
|
+
doasFanType.setDisplayName('DOAS Fan Flow Control - Variable means DCV controls')
|
123
|
+
doasFanType.setDefaultValue('Variable')
|
124
|
+
args << doasFanType
|
125
|
+
|
126
|
+
# DOAS Energy Recovery
|
127
|
+
ervChs = OpenStudio::StringVector.new
|
128
|
+
ervChs << 'plate w/o economizer lockout'
|
129
|
+
ervChs << 'plate w/ economizer lockout'
|
130
|
+
ervChs << 'rotary wheel w/o economizer lockout'
|
131
|
+
ervChs << 'rotary wheel w/ economizer lockout'
|
132
|
+
ervChs << 'none'
|
133
|
+
doasERV = OpenStudio::Ruleset::OSArgument.makeChoiceArgument('doasERV', ervChs, true)
|
134
|
+
doasERV.setDisplayName('DOAS Energy Recovery?')
|
135
|
+
doasERV.setDefaultValue('none')
|
136
|
+
args << doasERV
|
137
|
+
|
138
|
+
# DOAS Evaporative Cooling
|
139
|
+
evapChs = OpenStudio::StringVector.new
|
140
|
+
evapChs << 'Direct Evaporative Cooler'
|
141
|
+
evapChs << 'none'
|
142
|
+
doasEvap = OpenStudio::Ruleset::OSArgument.makeChoiceArgument('doasEvap', evapChs, true)
|
143
|
+
doasEvap.setDisplayName('DOAS Direct Evaporative Cooling ?')
|
144
|
+
doasEvap.setDefaultValue('none')
|
145
|
+
args << doasEvap
|
146
|
+
|
147
|
+
# DOAS DX Cooling
|
148
|
+
doasDXEER = OpenStudio::Ruleset::OSArgument.makeDoubleArgument('doasDXEER', false)
|
149
|
+
doasDXEER.setDisplayName('DOAS DX Cooling EER')
|
150
|
+
doasDXEER.setDefaultValue(10.0)
|
151
|
+
args << doasDXEER
|
152
|
+
|
153
|
+
# make an argument for material and installation cost
|
154
|
+
# todo - I would like to split the costing out to the air loops weighted by area of building served vs. just sticking it on the building
|
155
|
+
costTotalHVACSystem = OpenStudio::Ruleset::OSArgument.makeDoubleArgument('costTotalHVACSystem', true)
|
156
|
+
costTotalHVACSystem.setDisplayName('Total Cost for HVAC System ($).')
|
157
|
+
costTotalHVACSystem.setDefaultValue(0.0)
|
158
|
+
args << costTotalHVACSystem
|
159
|
+
|
160
|
+
# make an argument to remove existing costs
|
161
|
+
remake_schedules = OpenStudio::Ruleset::OSArgument.makeBoolArgument('remake_schedules', true)
|
162
|
+
remake_schedules.setDisplayName('Apply recommended availability and ventilation schedules for air handlers?')
|
163
|
+
remake_schedules.setDefaultValue(true)
|
164
|
+
args << remake_schedules
|
165
|
+
|
166
|
+
return args
|
167
|
+
end # end the arguments method
|
168
|
+
|
169
|
+
# define what happens when the measure is run
|
170
|
+
def run(model, runner, user_arguments)
|
171
|
+
super(model, runner, user_arguments)
|
172
|
+
|
173
|
+
# use the built-in error checking
|
174
|
+
if !runner.validateUserArguments(arguments(model), user_arguments)
|
175
|
+
return false
|
176
|
+
end
|
177
|
+
|
178
|
+
# assign the user inputs to variables
|
179
|
+
space_type_to_edits_hash = {}
|
180
|
+
space_types = model.getSpaceTypes
|
181
|
+
space_types.each do |space_type|
|
182
|
+
if model.getSpaceTypeByName(space_type.name.get).is_initialized && !space_type.spaces.empty?
|
183
|
+
space_type = model.getSpaceTypeByName(space_type.name.get).get
|
184
|
+
space_type_to_edit = runner.getBoolArgumentValue(space_type.name.get.to_s, user_arguments)
|
185
|
+
space_type_to_edits_hash[space_type] = space_type_to_edit
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
vrfCondenserType = runner.getStringArgumentValue('vrfCondenserType', user_arguments)
|
190
|
+
vrfCoolCOP = runner.getDoubleArgumentValue('vrfCoolCOP', user_arguments)
|
191
|
+
vrfHeatCOP = runner.getDoubleArgumentValue('vrfHeatCOP', user_arguments)
|
192
|
+
vrfMinOATHPHeat = runner.getDoubleArgumentValue('vrfMinOATHPHeat', user_arguments)
|
193
|
+
vrfDefrost = runner.getStringArgumentValue('vrfDefrost', user_arguments)
|
194
|
+
vrfHPHeatRecovery = runner.getStringArgumentValue('vrfHPHeatRecovery', user_arguments)
|
195
|
+
vrfEquivPipingLength = runner.getDoubleArgumentValue('vrfEquivPipingLength', user_arguments)
|
196
|
+
vrfPipingHeight = runner.getDoubleArgumentValue('vrfPipingHeight', user_arguments)
|
197
|
+
doasFanType = runner.getStringArgumentValue('doasFanType', user_arguments)
|
198
|
+
doasERV = runner.getStringArgumentValue('doasERV', user_arguments)
|
199
|
+
doasEvap = runner.getStringArgumentValue('doasEvap', user_arguments)
|
200
|
+
doasDXEER = runner.getDoubleArgumentValue('doasDXEER', user_arguments)
|
201
|
+
|
202
|
+
parameters = { 'vrfCondenserType' => vrfCondenserType,
|
203
|
+
'vrfCoolCOP' => vrfCoolCOP,
|
204
|
+
'vrfHeatCOP' => vrfHeatCOP,
|
205
|
+
'vrfMinOATHPHeat' => vrfMinOATHPHeat,
|
206
|
+
'vrfDefrost' => vrfDefrost,
|
207
|
+
'vrfHPHeatRecovery' => vrfHPHeatRecovery,
|
208
|
+
'vrfEquivPipingLength' => vrfEquivPipingLength,
|
209
|
+
'vrfPipingHeight' => vrfPipingHeight,
|
210
|
+
'doasFanType' => doasFanType,
|
211
|
+
'doasERV' => doasERV,
|
212
|
+
'doasEvap' => doasEvap,
|
213
|
+
'doasDXEER' => doasDXEER }
|
214
|
+
|
215
|
+
### START INPUTS
|
216
|
+
# assign the user inputs to variables
|
217
|
+
ceilingReturnPlenumSpaceType = runner.getOptionalWorkspaceObjectChoiceValue('ceilingReturnPlenumSpaceType', user_arguments, model)
|
218
|
+
costTotalHVACSystem = runner.getDoubleArgumentValue('costTotalHVACSystem', user_arguments)
|
219
|
+
remake_schedules = runner.getBoolArgumentValue('remake_schedules', user_arguments)
|
220
|
+
# check that spaceType was chosen and exists in model
|
221
|
+
ceilingReturnPlenumSpaceTypeCheck = OsLib_HelperMethods.checkOptionalChoiceArgFromModelObjects(ceilingReturnPlenumSpaceType, 'ceilingReturnPlenumSpaceType', 'to_SpaceType', runner, user_arguments)
|
222
|
+
ceilingReturnPlenumSpaceTypeCheck == false ? (return false) : (ceilingReturnPlenumSpaceType = ceilingReturnPlenumSpaceTypeCheck['modelObject'])
|
223
|
+
# default building/ secondary space types
|
224
|
+
standardBuildingTypeTest = [] # ML Not used yet
|
225
|
+
standardBuildingTypeTest = ['Office'] # ML Not used yet
|
226
|
+
secondarySpaceTypeTest = [] # empty for office
|
227
|
+
primarySpaceType = 'Office'
|
228
|
+
if doasFanType == 'Variable'
|
229
|
+
primaryHVAC = { 'doas' => true, 'fan' => 'Variable', 'heat' => 'Gas', 'cool' => 'SingleDX' }
|
230
|
+
else
|
231
|
+
primaryHVAC = { 'doas' => true, 'fan' => 'Constant', 'heat' => 'Gas', 'cool' => 'SingleDX' }
|
232
|
+
end
|
233
|
+
secondaryHVAC = { 'fan' => 'None', 'heat' => 'None', 'cool' => 'None' } # ML not used for office; leave or empty?
|
234
|
+
zoneHVAC = 'VRF'
|
235
|
+
chillerType = 'None' # set to none if chiller not used
|
236
|
+
radiantChillerType = 'None' # set to none if not radiant system
|
237
|
+
allHVAC = { 'primary' => primaryHVAC, 'secondary' => secondaryHVAC, 'zone' => zoneHVAC }
|
238
|
+
|
239
|
+
### END INPUTS
|
240
|
+
|
241
|
+
### START SORT ZONES
|
242
|
+
options = { 'standardBuildingTypeTest' => standardBuildingTypeTest, # ML Not used yet
|
243
|
+
'secondarySpaceTypeTest' => secondarySpaceTypeTest,
|
244
|
+
'ceilingReturnPlenumSpaceType' => ceilingReturnPlenumSpaceType }
|
245
|
+
zonesSorted = OsLib_HVAC.sortZones(model, runner, options, space_type_to_edits_hash)
|
246
|
+
zonesPrimary = zonesSorted['zonesPrimary']
|
247
|
+
zonesSecondary = zonesSorted['zonesSecondary']
|
248
|
+
zonesPlenum = zonesSorted['zonesPlenum']
|
249
|
+
zonesUnconditioned = zonesSorted['zonesUnconditioned']
|
250
|
+
### END SORT ZONES
|
251
|
+
|
252
|
+
### START REPORT INITIAL CONDITIONS
|
253
|
+
OsLib_HVAC.reportConditions(model, runner, 'initial')
|
254
|
+
### END REPORT INITIAL CONDITIONS
|
255
|
+
|
256
|
+
### START ASSIGN HVAC SCHEDULES
|
257
|
+
options = { 'primarySpaceType' => primarySpaceType,
|
258
|
+
'allHVAC' => allHVAC,
|
259
|
+
'remake_schedules' => remake_schedules }
|
260
|
+
schedulesHVAC = OsLib_HVAC.assignHVACSchedules(model, runner, options)
|
261
|
+
# assign schedules
|
262
|
+
primary_SAT_schedule = schedulesHVAC['primary_sat']
|
263
|
+
building_HVAC_schedule = schedulesHVAC['hvac']
|
264
|
+
building_ventilation_schedule = schedulesHVAC['ventilation']
|
265
|
+
make_hot_water_plant = false
|
266
|
+
unless schedulesHVAC['hot_water'].nil?
|
267
|
+
hot_water_setpoint_schedule = schedulesHVAC['hot_water']
|
268
|
+
make_hot_water_plant = true
|
269
|
+
end
|
270
|
+
make_chilled_water_plant = false
|
271
|
+
unless schedulesHVAC['chilled_water'].nil?
|
272
|
+
chilled_water_setpoint_schedule = schedulesHVAC['chilled_water']
|
273
|
+
make_chilled_water_plant = true
|
274
|
+
end
|
275
|
+
make_radiant_hot_water_plant = false
|
276
|
+
unless schedulesHVAC['radiant_hot_water'].nil?
|
277
|
+
radiant_hot_water_setpoint_schedule = schedulesHVAC['radiant_hot_water']
|
278
|
+
make_radiant_hot_water_plant = true
|
279
|
+
end
|
280
|
+
make_radiant_chilled_water_plant = false
|
281
|
+
unless schedulesHVAC['radiant_chilled_water'].nil?
|
282
|
+
radiant_chilled_water_setpoint_schedule = schedulesHVAC['radiant_chilled_water']
|
283
|
+
make_radiant_chilled_water_plant = true
|
284
|
+
end
|
285
|
+
unless schedulesHVAC['hp_loop'].nil?
|
286
|
+
heat_pump_loop_setpoint_schedule = schedulesHVAC['hp_loop']
|
287
|
+
end
|
288
|
+
unless schedulesHVAC['hp_loop_cooling'].nil?
|
289
|
+
heat_pump_loop_cooling_setpoint_schedule = schedulesHVAC['hp_loop_cooling']
|
290
|
+
end
|
291
|
+
unless schedulesHVAC['hp_loop_heating'].nil?
|
292
|
+
heat_pump_loop_heating_setpoint_schedule = schedulesHVAC['hp_loop_heating']
|
293
|
+
end
|
294
|
+
unless schedulesHVAC['mean_radiant_heating'].nil?
|
295
|
+
mean_radiant_heating_setpoint_schedule = schedulesHVAC['mean_radiant_heating']
|
296
|
+
end
|
297
|
+
unless schedulesHVAC['mean_radiant_cooling'].nil?
|
298
|
+
mean_radiant_cooling_setpoint_schedule = schedulesHVAC['mean_radiant_cooling']
|
299
|
+
end
|
300
|
+
### END ASSIGN HVAC SCHEDULES
|
301
|
+
|
302
|
+
# START REMOVE EQUIPMENT
|
303
|
+
options = {}
|
304
|
+
options['zonesPrimary'] = zonesPrimary
|
305
|
+
if options['zonesPrimary'].empty?
|
306
|
+
runner.registerInfo('User did not pick any zones to be added to VRF system, no changes to the model were made.')
|
307
|
+
else
|
308
|
+
OsLib_HVAC.removeEquipment(model, runner, options)
|
309
|
+
end
|
310
|
+
### END REMOVE EQUIPMENT
|
311
|
+
|
312
|
+
### START CREATE NEW PLANTS
|
313
|
+
# create new plants
|
314
|
+
# hot water plant
|
315
|
+
if make_hot_water_plant
|
316
|
+
hot_water_plant = OsLib_HVAC.createHotWaterPlant(model, runner, hot_water_setpoint_schedule, 'Hot Water', parameters)
|
317
|
+
end
|
318
|
+
# chilled water plant
|
319
|
+
if make_chilled_water_plant
|
320
|
+
chilled_water_plant = OsLib_HVAC.createChilledWaterPlant(model, runner, chilled_water_setpoint_schedule, 'Chilled Water', chillerType)
|
321
|
+
end
|
322
|
+
# radiant hot water plant
|
323
|
+
if make_radiant_hot_water_plant
|
324
|
+
radiant_hot_water_plant = OsLib_HVAC.createHotWaterPlant(model, runner, radiant_hot_water_setpoint_schedule, 'Radiant Hot Water')
|
325
|
+
end
|
326
|
+
# chilled water plant
|
327
|
+
if make_radiant_chilled_water_plant
|
328
|
+
radiant_chilled_water_plant = OsLib_HVAC.createChilledWaterPlant(model, runner, radiant_chilled_water_setpoint_schedule, 'Radiant Chilled Water', radiantChillerType)
|
329
|
+
end
|
330
|
+
# condenser loop
|
331
|
+
# need condenser loop if there is a water-cooled chiller or if there is a water source heat pump loop or a water cooled VRF condenser
|
332
|
+
options = {}
|
333
|
+
options['zonesPrimary'] = zonesPrimary
|
334
|
+
options['zoneHVAC'] = zoneHVAC
|
335
|
+
if zoneHVAC.include?('SHP') || (zoneHVAC == 'VRF') && (parameters['vrfCondenserType'] == 'WaterCooled')
|
336
|
+
options['loop_setpoint_schedule'] = heat_pump_loop_setpoint_schedule
|
337
|
+
options['cooling_setpoint_schedule'] = heat_pump_loop_cooling_setpoint_schedule
|
338
|
+
options['heating_setpoint_schedule'] = heat_pump_loop_heating_setpoint_schedule
|
339
|
+
runner.registerInfo('yes, loop schedule created')
|
340
|
+
end
|
341
|
+
if parameters['vrfCondenserType'] == 'WaterCooled'
|
342
|
+
condenserLoops = OsLib_HVAC.createCondenserLoop(model, runner, options, parameters)
|
343
|
+
else
|
344
|
+
condenserLoops = {}
|
345
|
+
end
|
346
|
+
unless condenserLoops['condenser_loop'].nil?
|
347
|
+
condenser_loop = condenserLoops['condenser_loop']
|
348
|
+
end
|
349
|
+
unless condenserLoops['heat_pump_loop'].nil?
|
350
|
+
heat_pump_loop = condenserLoops['heat_pump_loop']
|
351
|
+
runner.registerInfo('vrf condenser loop is created')
|
352
|
+
end
|
353
|
+
### END CREATE NEW PLANTS
|
354
|
+
|
355
|
+
### START CREATE PRIMARY AIRLOOPS
|
356
|
+
# populate inputs hash for create primary airloops method
|
357
|
+
options = {}
|
358
|
+
options['zonesPrimary'] = zonesPrimary
|
359
|
+
options['primaryHVAC'] = primaryHVAC
|
360
|
+
options['zoneHVAC'] = zoneHVAC
|
361
|
+
if primaryHVAC['doas']
|
362
|
+
options['hvac_schedule'] = building_ventilation_schedule
|
363
|
+
options['ventilation_schedule'] = building_ventilation_schedule
|
364
|
+
else
|
365
|
+
# primary HVAC is multizone VAV
|
366
|
+
if zoneHVAC == 'DualDuct'
|
367
|
+
# primary system is a multizone VAV that cools only (primary system ventilation schedule is set to always off; hvac set to always on)
|
368
|
+
options['hvac_schedule'] = model.alwaysOnDiscreteSchedule
|
369
|
+
else
|
370
|
+
# primary system is multizone VAV that cools and ventilates
|
371
|
+
options['hvac_schedule'] = building_HVAC_schedule
|
372
|
+
options['ventilation_schedule'] = building_ventilation_schedule
|
373
|
+
end
|
374
|
+
end
|
375
|
+
options['primary_sat_schedule'] = primary_SAT_schedule
|
376
|
+
if make_hot_water_plant
|
377
|
+
options['hot_water_plant'] = hot_water_plant
|
378
|
+
end
|
379
|
+
if make_chilled_water_plant
|
380
|
+
options['chilled_water_plant'] = chilled_water_plant
|
381
|
+
end
|
382
|
+
primary_airloops = OsLib_HVAC.createPrimaryAirLoops(model, runner, options, parameters)
|
383
|
+
### END CREATE PRIMARY AIRLOOPS
|
384
|
+
if zoneHVAC.include? 'VRF'
|
385
|
+
options['heat_pump_loop'] = heat_pump_loop
|
386
|
+
end
|
387
|
+
vrf_airconditioners = OsLib_HVAC.createVRFAirConditioners(model, runner, options, parameters)
|
388
|
+
### START CREATE SECONDARY AIRLOOPS
|
389
|
+
# populate inputs hash for create primary airloops method
|
390
|
+
options = {}
|
391
|
+
options['zonesSecondary'] = zonesSecondary
|
392
|
+
options['secondaryHVAC'] = secondaryHVAC
|
393
|
+
options['hvac_schedule'] = building_HVAC_schedule
|
394
|
+
options['ventilation_schedule'] = building_ventilation_schedule
|
395
|
+
if make_hot_water_plant
|
396
|
+
options['hot_water_plant'] = hot_water_plant
|
397
|
+
end
|
398
|
+
if make_chilled_water_plant
|
399
|
+
options['chilled_water_plant'] = chilled_water_plant
|
400
|
+
end
|
401
|
+
# secondary_airloops = OsLib_HVAC.createSecondaryAirLoops(model, runner, options)
|
402
|
+
### END CREATE SECONDARY AIRLOOPS
|
403
|
+
|
404
|
+
### START ASSIGN PLENUMS
|
405
|
+
options = { 'zonesPrimary' => zonesPrimary, 'zonesPlenum' => zonesPlenum }
|
406
|
+
zone_plenum_hash = OsLib_HVAC.validateAndAddPlenumZonesToSystem(model, runner, options)
|
407
|
+
### END ASSIGN PLENUMS
|
408
|
+
|
409
|
+
### START CREATE PRIMARY ZONE EQUIPMENT
|
410
|
+
options = {}
|
411
|
+
options['zonesPrimary'] = zonesPrimary
|
412
|
+
options['zoneHVAC'] = zoneHVAC
|
413
|
+
if make_hot_water_plant
|
414
|
+
options['hot_water_plant'] = hot_water_plant
|
415
|
+
end
|
416
|
+
if make_chilled_water_plant
|
417
|
+
options['chilled_water_plant'] = chilled_water_plant
|
418
|
+
end
|
419
|
+
if zoneHVAC.include?('SHP') || (zoneHVAC == 'VRF')
|
420
|
+
options['heat_pump_loop'] = heat_pump_loop
|
421
|
+
end
|
422
|
+
if zoneHVAC == 'DualDuct'
|
423
|
+
options['ventilation_schedule'] = building_ventilation_schedule
|
424
|
+
end
|
425
|
+
if zoneHVAC == 'Radiant'
|
426
|
+
options['radiant_hot_water_plant'] = radiant_hot_water_plant
|
427
|
+
options['radiant_chilled_water_plant'] = radiant_chilled_water_plant
|
428
|
+
options['mean_radiant_heating_setpoint_schedule'] = mean_radiant_heating_setpoint_schedule
|
429
|
+
options['mean_radiant_cooling_setpoint_schedule'] = mean_radiant_cooling_setpoint_schedule
|
430
|
+
end
|
431
|
+
OsLib_HVAC.createPrimaryZoneEquipment(model, runner, options, parameters)
|
432
|
+
### END CREATE PRIMARY ZONE EQUIPMENT
|
433
|
+
|
434
|
+
# START ADD DCV
|
435
|
+
options = {}
|
436
|
+
unless zoneHVAC == 'DualDuct'
|
437
|
+
options['primary_airloops'] = primary_airloops
|
438
|
+
end
|
439
|
+
# options["secondary_airloops"] = secondary_airloops
|
440
|
+
options['allHVAC'] = allHVAC
|
441
|
+
OsLib_HVAC.addDCV(model, runner, options)
|
442
|
+
# END ADD DCV
|
443
|
+
|
444
|
+
# TODO: - add in lifecycle costs
|
445
|
+
expected_life = 25
|
446
|
+
years_until_costs_start = 0
|
447
|
+
costHVAC = costTotalHVACSystem
|
448
|
+
lcc_mat = OpenStudio::Model::LifeCycleCost.createLifeCycleCost('HVAC System', model.getBuilding, costHVAC, 'CostPerEach', 'Construction', expected_life, years_until_costs_start).get
|
449
|
+
|
450
|
+
# # add AEDG tips
|
451
|
+
# aedgTips = ["HV04","HV10","HV12"]
|
452
|
+
|
453
|
+
# # populate how to tip messages
|
454
|
+
# aedgTipsLong = OsLib_AedgMeasures.getLongHowToTips("SmMdOff",aedgTips.uniq.sort,runner)
|
455
|
+
# if not aedgTipsLong
|
456
|
+
# return false # this should only happen if measure writer passes bad values to getLongHowToTips
|
457
|
+
# end
|
458
|
+
|
459
|
+
### START REPORT FINAL CONDITIONS
|
460
|
+
OsLib_HVAC.reportConditions(model, runner, 'final')
|
461
|
+
### END REPORT FINAL CONDITIONS
|
462
|
+
|
463
|
+
return true
|
464
|
+
end # end the run method
|
465
|
+
end # end the measure
|
466
|
+
|
467
|
+
# this allows the measure to be used by the application
|
468
|
+
VRFwithDOAS.new.registerWithApplication
|