openstudio-geb 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/lib/measures/{add_rooftop_pv → add_rooftop_pv_simple}/LICENSE.md +0 -0
- data/lib/measures/{add_rooftop_pv → add_rooftop_pv_simple}/README.md +0 -0
- data/lib/measures/{Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/measures/Enable Demand Controlled Ventilation → add_rooftop_pv_simple}/README.md.erb +0 -0
- data/lib/measures/{add_rooftop_pv → add_rooftop_pv_simple}/measure.rb +0 -0
- data/lib/measures/{add_rooftop_pv → add_rooftop_pv_simple}/measure.xml +0 -0
- data/lib/measures/{add_rooftop_pv → add_rooftop_pv_simple}/tests/CZ06RV2.epw +0 -0
- data/lib/measures/{add_rooftop_pv → add_rooftop_pv_simple}/tests/add_rooftop_pv_test.rb +0 -0
- data/lib/measures/{add_rooftop_pv → add_rooftop_pv_simple}/tests/pv_test_input.osm +0 -0
- data/lib/openstudio/geb/utilities.rb +34 -6
- data/lib/openstudio/geb/version.rb +1 -1
- data/openstudio-geb.gemspec +1 -1
- metadata +10 -126
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/files/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.epw +0 -8768
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/files/USA_NY_Buffalo.Niagara.Intl.AP.725280_TMY3.epw +0 -8768
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/measures/Enable Demand Controlled Ventilation/LICENSE.md +0 -27
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/measures/Enable Demand Controlled Ventilation/README.md +0 -32
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/measures/Enable Demand Controlled Ventilation/measure.rb +0 -156
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/measures/Enable Demand Controlled Ventilation/measure.xml +0 -117
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/measures/Enable Demand Controlled Ventilation/tests/0320_ModelWithHVAC_01.osm +0 -22223
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/measures/Enable Demand Controlled Ventilation/tests/EnableDemandControlledVentilation_Test.rb +0 -123
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/measures/Set Electric Equipment loads by EPD/LICENSE.md +0 -27
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/measures/Set Electric Equipment loads by EPD/README.md +0 -136
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/measures/Set Electric Equipment loads by EPD/README.md.erb +0 -47
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/measures/Set Electric Equipment loads by EPD/measure.rb +0 -586
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/measures/Set Electric Equipment loads by EPD/measure.xml +0 -200
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/measures/Set Electric Equipment loads by EPD/tests/EnvelopeAndLoadTestModel_01.osm +0 -14352
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/measures/Set Electric Equipment loads by EPD/tests/EnvelopeAndLoadTestModel_01_Costed.osm +0 -14438
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/measures/Set Electric Equipment loads by EPD/tests/HasSpaceWithNoLightsOrElec.osm +0 -16531
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/measures/Set Electric Equipment loads by EPD/tests/ReplaceElectricEquipmentWithEPD_Test.rb +0 -592
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/out.osw +0 -68
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/reports/eplustbl.html +0 -27183
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/data_point.zip +0 -0
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/data_point_out.json +0 -6
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/eplusout.audit +0 -49
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/eplusout.bnd +0 -1103
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/eplusout.eio +0 -630
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/eplusout.end +0 -1
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/eplusout.err +0 -331
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/eplusout.eso +0 -158559
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/eplusout.mdd +0 -336
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/eplusout.mtd +0 -2519
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/eplusout.rdd +0 -638
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/eplusout.shd +0 -902
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/eplusout.sql +0 -0
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/eplusssz.csv +0 -147
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/eplustbl.htm +0 -27183
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/epluszsz.csv +0 -148
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/finished.job +0 -1
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/in.idf +0 -10384
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/in.osm +0 -13809
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/measure_attributes.json +0 -6
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/objectives.json +0 -2
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/pre-preprocess.idf +0 -10134
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/results.json +0 -6
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/run.log +0 -0
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/sqlite.err +0 -1
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/started.job +0 -1
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/stdout-energyplus +0 -271
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/run/stdout-expandobject +0 -3
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/stderr +0 -0
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/stdout +0 -0
- data/lib/measures/Enable Demand Controlled Ventilation/tests/MediumOffice-90.1-2010-ASHRAE 169-2013-5A_dcv/workflow.osw +0 -19
- data/lib/measures/add_rooftop_pv/README.md.erb +0 -42
@@ -1,586 +0,0 @@
|
|
1
|
-
# *******************************************************************************
|
2
|
-
# OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC.
|
3
|
-
# All rights reserved.
|
4
|
-
# Redistribution and use in source and binary forms, with or without
|
5
|
-
# modification, are permitted provided that the following conditions are met:
|
6
|
-
#
|
7
|
-
# (1) Redistributions of source code must retain the above copyright notice,
|
8
|
-
# this list of conditions and the following disclaimer.
|
9
|
-
#
|
10
|
-
# (2) Redistributions in binary form must reproduce the above copyright notice,
|
11
|
-
# this list of conditions and the following disclaimer in the documentation
|
12
|
-
# and/or other materials provided with the distribution.
|
13
|
-
#
|
14
|
-
# (3) Neither the name of the copyright holder nor the names of any contributors
|
15
|
-
# may be used to endorse or promote products derived from this software without
|
16
|
-
# specific prior written permission from the respective party.
|
17
|
-
#
|
18
|
-
# (4) Other than as required in clauses (1) and (2), distributions in any form
|
19
|
-
# of modifications or other derivative works may not use the "OpenStudio"
|
20
|
-
# trademark, "OS", "os", or any other confusingly similar designation without
|
21
|
-
# specific prior written permission from Alliance for Sustainable Energy, LLC.
|
22
|
-
#
|
23
|
-
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS
|
24
|
-
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
25
|
-
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
26
|
-
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE
|
27
|
-
# UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF
|
28
|
-
# THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
29
|
-
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
30
|
-
# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
31
|
-
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
32
|
-
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
33
|
-
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
34
|
-
# *******************************************************************************
|
35
|
-
|
36
|
-
# start the measure
|
37
|
-
class SetElectricEquipmentLoadsByEPD < OpenStudio::Measure::ModelMeasure
|
38
|
-
# define the name that a user will see
|
39
|
-
def name
|
40
|
-
return 'Set Electric Equipment loads by EPD'
|
41
|
-
end
|
42
|
-
|
43
|
-
# human readable description
|
44
|
-
def description
|
45
|
-
return 'Set the electric equipment power density (W/ft^2) in the to a specified value for all spaces that have electric equipment. This can be applied to the entire building or a specific space type. Cost can be added per floor area'
|
46
|
-
end
|
47
|
-
|
48
|
-
# human readable description of modeling approach
|
49
|
-
def modeler_description
|
50
|
-
return 'Delete all of the existing electric equipment in the model. Add electric equipment with the user defined electric equipment power density to all spaces that initially had electric equipment, using the schedule from the original electric equipment. If multiple electric equipment existed the schedule will be pulled from the one with the highest electric equipment power density value. Demolition costs from electric equipment removed by this measure can be included in the analysis.'
|
51
|
-
end
|
52
|
-
|
53
|
-
# define the arguments that the user will input
|
54
|
-
def arguments(model)
|
55
|
-
args = OpenStudio::Measure::OSArgumentVector.new
|
56
|
-
|
57
|
-
# make a choice argument for model objects
|
58
|
-
space_type_handles = OpenStudio::StringVector.new
|
59
|
-
space_type_display_names = OpenStudio::StringVector.new
|
60
|
-
|
61
|
-
# putting model object and names into hash
|
62
|
-
space_type_args = model.getSpaceTypes
|
63
|
-
space_type_args_hash = {}
|
64
|
-
space_type_args.each do |space_type_arg|
|
65
|
-
space_type_args_hash[space_type_arg.name.to_s] = space_type_arg
|
66
|
-
end
|
67
|
-
|
68
|
-
# looping through sorted hash of model objects
|
69
|
-
space_type_args_hash.sort.map do |key, value|
|
70
|
-
# only include if space type is used in the model
|
71
|
-
if !value.spaces.empty?
|
72
|
-
space_type_handles << value.handle.to_s
|
73
|
-
space_type_display_names << key
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
# add building to string vector with space type
|
78
|
-
building = model.getBuilding
|
79
|
-
space_type_handles << building.handle.to_s
|
80
|
-
space_type_display_names << '*Entire Building*'
|
81
|
-
|
82
|
-
# make a choice argument for space type or entire building
|
83
|
-
space_type = OpenStudio::Measure::OSArgument.makeChoiceArgument('space_type', space_type_handles, space_type_display_names, true)
|
84
|
-
space_type.setDisplayName('Apply the Measure to a Specific Space Type or to the Entire Model')
|
85
|
-
space_type.setDefaultValue('*Entire Building*') # if no space type is chosen this will run on the entire building
|
86
|
-
args << space_type
|
87
|
-
|
88
|
-
# make an argument EPD
|
89
|
-
epd = OpenStudio::Measure::OSArgument.makeDoubleArgument('epd', true)
|
90
|
-
epd.setDisplayName('Lighting Power Density (W/ft^2)')
|
91
|
-
epd.setDefaultValue(1.0)
|
92
|
-
args << epd
|
93
|
-
|
94
|
-
# add in argument to add electric equipment to all spaces that are included in building floor area even if original space didn't have electric equipment
|
95
|
-
add_instance_all_spaces = OpenStudio::Measure::OSArgument.makeBoolArgument('add_instance_all_spaces', true)
|
96
|
-
add_instance_all_spaces.setDisplayName('Add electric equipment to all spaces included in floor area, including spaces that did not originally include electric equipment')
|
97
|
-
add_instance_all_spaces.setDefaultValue(false)
|
98
|
-
args << add_instance_all_spaces
|
99
|
-
|
100
|
-
# make an argument for material and installation cost
|
101
|
-
material_cost = OpenStudio::Measure::OSArgument.makeDoubleArgument('material_cost', true)
|
102
|
-
material_cost.setDisplayName('Material and Installation Costs for Lights per Floor Area ($/ft^2).')
|
103
|
-
material_cost.setDefaultValue(0.0)
|
104
|
-
args << material_cost
|
105
|
-
|
106
|
-
# make an argument for demolition cost
|
107
|
-
demolition_cost = OpenStudio::Measure::OSArgument.makeDoubleArgument('demolition_cost', true)
|
108
|
-
demolition_cost.setDisplayName('Demolition Costs for Lights per Floor Area ($/ft^2).')
|
109
|
-
demolition_cost.setDefaultValue(0.0)
|
110
|
-
args << demolition_cost
|
111
|
-
|
112
|
-
# make an argument for duration in years until costs start
|
113
|
-
years_until_costs_start = OpenStudio::Measure::OSArgument.makeIntegerArgument('years_until_costs_start', true)
|
114
|
-
years_until_costs_start.setDisplayName('Years Until Costs Start (whole years).')
|
115
|
-
years_until_costs_start.setDefaultValue(0)
|
116
|
-
args << years_until_costs_start
|
117
|
-
|
118
|
-
# make an argument to determine if demolition costs should be included in initial construction
|
119
|
-
demo_cost_initial_const = OpenStudio::Measure::OSArgument.makeBoolArgument('demo_cost_initial_const', true)
|
120
|
-
demo_cost_initial_const.setDisplayName('Demolition Costs Occur During Initial Construction?')
|
121
|
-
demo_cost_initial_const.setDefaultValue(false)
|
122
|
-
args << demo_cost_initial_const
|
123
|
-
|
124
|
-
# make an argument for expected life
|
125
|
-
expected_life = OpenStudio::Measure::OSArgument.makeIntegerArgument('expected_life', true)
|
126
|
-
expected_life.setDisplayName('Expected Life (whole years).')
|
127
|
-
expected_life.setDefaultValue(20)
|
128
|
-
args << expected_life
|
129
|
-
|
130
|
-
# make an argument for o&m cost
|
131
|
-
om_cost = OpenStudio::Measure::OSArgument.makeDoubleArgument('om_cost', true)
|
132
|
-
om_cost.setDisplayName('O & M Costs for Lights per Floor Area ($/ft^2).')
|
133
|
-
om_cost.setDefaultValue(0.0)
|
134
|
-
args << om_cost
|
135
|
-
|
136
|
-
# make an argument for o&m frequency
|
137
|
-
om_frequency = OpenStudio::Measure::OSArgument.makeIntegerArgument('om_frequency', true)
|
138
|
-
om_frequency.setDisplayName('O & M Frequency (whole years).')
|
139
|
-
om_frequency.setDefaultValue(1)
|
140
|
-
args << om_frequency
|
141
|
-
|
142
|
-
return args
|
143
|
-
end
|
144
|
-
|
145
|
-
# define what happens when the measure is run
|
146
|
-
def run(model, runner, user_arguments)
|
147
|
-
super(model, runner, user_arguments)
|
148
|
-
|
149
|
-
# use the built-in error checking
|
150
|
-
if !runner.validateUserArguments(arguments(model), user_arguments)
|
151
|
-
return false
|
152
|
-
end
|
153
|
-
|
154
|
-
# assign the user inputs to variables
|
155
|
-
object = runner.getOptionalWorkspaceObjectChoiceValue('space_type', user_arguments, model)
|
156
|
-
epd = runner.getDoubleArgumentValue('epd', user_arguments)
|
157
|
-
add_instance_all_spaces = runner.getBoolArgumentValue('add_instance_all_spaces', user_arguments)
|
158
|
-
material_cost = runner.getDoubleArgumentValue('material_cost', user_arguments)
|
159
|
-
demolition_cost = runner.getDoubleArgumentValue('demolition_cost', user_arguments)
|
160
|
-
years_until_costs_start = runner.getIntegerArgumentValue('years_until_costs_start', user_arguments)
|
161
|
-
demo_cost_initial_const = runner.getBoolArgumentValue('demo_cost_initial_const', user_arguments)
|
162
|
-
expected_life = runner.getIntegerArgumentValue('expected_life', user_arguments)
|
163
|
-
om_cost = runner.getDoubleArgumentValue('om_cost', user_arguments)
|
164
|
-
om_frequency = runner.getIntegerArgumentValue('om_frequency', user_arguments)
|
165
|
-
|
166
|
-
# check the space_type for reasonableness and see if measure should run on space type or on the entire building
|
167
|
-
apply_to_building = false
|
168
|
-
space_type = nil
|
169
|
-
if object.empty?
|
170
|
-
handle = runner.getStringArgumentValue('space_type', user_arguments)
|
171
|
-
if handle.empty?
|
172
|
-
runner.registerError('No SpaceType was chosen.')
|
173
|
-
else
|
174
|
-
runner.registerError("The selected space type with handle '#{handle}' was not found in the model. It may have been removed by another measure.")
|
175
|
-
end
|
176
|
-
return false
|
177
|
-
else
|
178
|
-
if !object.get.to_SpaceType.empty?
|
179
|
-
space_type = object.get.to_SpaceType.get
|
180
|
-
elsif !object.get.to_Building.empty?
|
181
|
-
apply_to_building = true
|
182
|
-
# space_type = model.getSpaceTypes
|
183
|
-
else
|
184
|
-
runner.registerError('Script Error - argument not showing up as space type or building.')
|
185
|
-
return false
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
# check the epd for reasonableness
|
190
|
-
if (epd < 0) || (epd > 50)
|
191
|
-
runner.registerError("A Lighting Power Density of #{epd} W/ft^2 is above the measure limit.")
|
192
|
-
return false
|
193
|
-
elsif epd > 21
|
194
|
-
runner.registerWarning("A Lighting Power Density of #{epd} W/ft^2 is abnormally high.")
|
195
|
-
end
|
196
|
-
|
197
|
-
# set flags to use later
|
198
|
-
costs_requested = false
|
199
|
-
|
200
|
-
# check costs for reasonableness
|
201
|
-
if material_cost.abs + demolition_cost.abs + om_cost.abs == 0
|
202
|
-
runner.registerInfo('No costs were requested for Exterior Lights.')
|
203
|
-
else
|
204
|
-
costs_requested = true
|
205
|
-
end
|
206
|
-
|
207
|
-
# check lifecycle arguments for reasonableness
|
208
|
-
if (years_until_costs_start < 0) && (years_until_costs_start > expected_life)
|
209
|
-
runner.registerError('Years until costs start should be a non-negative integer less than Expected Life.')
|
210
|
-
end
|
211
|
-
if (expected_life < 1) && (expected_life > 100)
|
212
|
-
runner.registerError('Choose an integer greater than 0 and less than or equal to 100 for Expected Life.')
|
213
|
-
end
|
214
|
-
if om_frequency < 1
|
215
|
-
runner.registerError('Choose an integer greater than 0 for O & M Frequency.')
|
216
|
-
end
|
217
|
-
|
218
|
-
# helper to make it easier to do unit conversions on the fly. The definition be called through this measure.
|
219
|
-
def unit_helper(number, from_unit_string, to_unit_string)
|
220
|
-
converted_number = OpenStudio.convert(OpenStudio::Quantity.new(number, OpenStudio.createUnit(from_unit_string).get), OpenStudio.createUnit(to_unit_string).get).get.value
|
221
|
-
end
|
222
|
-
|
223
|
-
# short def to make numbers pretty (converts 4125001.25641 to 4,125,001.26 or 4,125,001). The definition be called through this measure
|
224
|
-
def neat_numbers(number, roundto = 2) # round to 0 or 2)
|
225
|
-
if roundto == 2
|
226
|
-
number = format '%.2f', number
|
227
|
-
else
|
228
|
-
number = number.round
|
229
|
-
end
|
230
|
-
# regex to add commas
|
231
|
-
number.to_s.reverse.gsub(/([0-9]{3}(?=([0-9])))/, '\\1,').reverse
|
232
|
-
end
|
233
|
-
|
234
|
-
# helper that loops through lifecycle costs getting total costs under "Construction" or "Salvage" category and add to counter if occurs during year 0
|
235
|
-
def get_total_costs_for_objects(objects)
|
236
|
-
counter = 0
|
237
|
-
objects.each do |object|
|
238
|
-
object_LCCs = object.lifeCycleCosts
|
239
|
-
object_LCCs.each do |object_LCC|
|
240
|
-
if (object_LCC.category == 'Construction') || (object_LCC.category == 'Salvage')
|
241
|
-
if object_LCC.yearsFromStart == 0
|
242
|
-
counter += object_LCC.totalCost
|
243
|
-
end
|
244
|
-
end
|
245
|
-
end
|
246
|
-
end
|
247
|
-
return counter
|
248
|
-
end
|
249
|
-
|
250
|
-
# helper def to add to demo cost related to baseline objects
|
251
|
-
def add_to_baseline_demo_cost_counter(baseline_object) # removed if statement from def
|
252
|
-
counter = 0
|
253
|
-
baseline_object_LCCs = baseline_object.lifeCycleCosts
|
254
|
-
baseline_object_LCCs.each do |baseline_object_LCC|
|
255
|
-
if baseline_object_LCC.category == 'Salvage'
|
256
|
-
counter += baseline_object_LCC.totalCost
|
257
|
-
end
|
258
|
-
end
|
259
|
-
return counter
|
260
|
-
end
|
261
|
-
|
262
|
-
# setup OpenStudio units that we will need
|
263
|
-
unit_epd_ip = OpenStudio.createUnit('W/ft^2').get
|
264
|
-
unit_epd_si = OpenStudio.createUnit('W/m^2').get
|
265
|
-
|
266
|
-
# define starting units
|
267
|
-
epd_ip = OpenStudio::Quantity.new(epd, unit_epd_ip)
|
268
|
-
|
269
|
-
# unit conversion of epd from IP units (W/ft^2) to SI units (W/m^2)
|
270
|
-
epd_si = OpenStudio.convert(epd_ip, unit_epd_si).get
|
271
|
-
|
272
|
-
# calculate the initial electric equipment
|
273
|
-
elec_equip_defs = model.getElectricEquipmentDefinitions
|
274
|
-
initial_electric_equipment_cost = 0
|
275
|
-
initial_electric_equipment_cost += get_total_costs_for_objects(elec_equip_defs)
|
276
|
-
|
277
|
-
# counter for demo cost of baseline objects
|
278
|
-
demo_costs_of_baseline_objects = 0
|
279
|
-
|
280
|
-
# get demo cost if all existing electric equipment
|
281
|
-
if demo_cost_initial_const
|
282
|
-
elec_equip_defs.each do |elec_equip_def|
|
283
|
-
demo_costs_of_baseline_objects += add_to_baseline_demo_cost_counter(elec_equip_def)
|
284
|
-
end
|
285
|
-
end
|
286
|
-
|
287
|
-
# find most common electric equipment schedule for use in spaces that do not have electric equipment
|
288
|
-
elec_equip_sch_hash = {}
|
289
|
-
# add schedules or electric equipment directly assigned to space
|
290
|
-
model.getSpaces.each do |space|
|
291
|
-
space.electricEquipment.each do |elec_equip|
|
292
|
-
if elec_equip.schedule.is_initialized
|
293
|
-
sch = elec_equip.schedule.get
|
294
|
-
if elec_equip_sch_hash.key?(sch)
|
295
|
-
elec_equip_sch_hash[sch] += 1
|
296
|
-
else
|
297
|
-
elec_equip_sch_hash[sch] = 1
|
298
|
-
end
|
299
|
-
end
|
300
|
-
end
|
301
|
-
# add schedule for electric equipment assigned to space types
|
302
|
-
if space.spaceType.is_initialized
|
303
|
-
space.spaceType.get.electricEquipment.each do |elec_equip|
|
304
|
-
if elec_equip.schedule.is_initialized
|
305
|
-
sch = elec_equip.schedule.get
|
306
|
-
if elec_equip_sch_hash.key?(sch)
|
307
|
-
elec_equip_sch_hash[sch] += 1
|
308
|
-
else
|
309
|
-
elec_equip_sch_hash[sch] = 1
|
310
|
-
end
|
311
|
-
end
|
312
|
-
end
|
313
|
-
end
|
314
|
-
end
|
315
|
-
most_comm_sch = elec_equip_sch_hash.key(elec_equip_sch_hash.values.max)
|
316
|
-
|
317
|
-
# report initial condition
|
318
|
-
building = model.getBuilding
|
319
|
-
building_start_epd_si = OpenStudio::Quantity.new(building.electricEquipmentPowerPerFloorArea, unit_epd_si)
|
320
|
-
building_start_epd_ip = OpenStudio.convert(building_start_epd_si, unit_epd_ip).get
|
321
|
-
runner.registerInitialCondition("The model's initial EPD is #{building_start_epd_ip}. Initial Year 0 cost for building electric equipment is $#{neat_numbers(initial_electric_equipment_cost, 0)}.")
|
322
|
-
|
323
|
-
# add if statement for NA if EPD = 0
|
324
|
-
if building_start_epd_ip.value <= 0
|
325
|
-
runner.registerAsNotApplicable('The model has no electric equipment, nothing will be changed.')
|
326
|
-
end
|
327
|
-
|
328
|
-
# create a new ElectricEquipmentDefinition and new Lights object to use with setLightingPowerPerFloorArea
|
329
|
-
template_elec_equip_def = OpenStudio::Model::ElectricEquipmentDefinition.new(model)
|
330
|
-
template_elec_equip_def.setName("EPD #{epd_ip} - ElecEquipDef")
|
331
|
-
template_elec_equip_def.setWattsperSpaceFloorArea(epd_si.value)
|
332
|
-
|
333
|
-
template_elec_equip_inst = OpenStudio::Model::ElectricEquipment.new(template_elec_equip_def)
|
334
|
-
template_elec_equip_inst.setName("EPD #{epd_ip} - ElecEquipInstance")
|
335
|
-
|
336
|
-
# add lifeCycleCost objects if there is a non-zero value in one of the cost arguments
|
337
|
-
if costs_requested == true
|
338
|
-
|
339
|
-
starting_lcc_counter = template_elec_equip_def.lifeCycleCosts.size
|
340
|
-
|
341
|
-
# get si input values for lcc objects
|
342
|
-
material_cost_si = unit_helper(material_cost, '1/ft^2', '1/m^2')
|
343
|
-
demolition_cost_si = unit_helper(demolition_cost, '1/ft^2', '1/m^2')
|
344
|
-
om_cost_si = unit_helper(om_cost, '1/ft^2', '1/m^2')
|
345
|
-
|
346
|
-
# adding new cost items
|
347
|
-
lcc_mat = OpenStudio::Model::LifeCycleCost.createLifeCycleCost("LCC_Mat - #{template_elec_equip_def.name}", template_elec_equip_def, material_cost_si, 'CostPerArea', 'Construction', expected_life, years_until_costs_start)
|
348
|
-
lcc_demo = OpenStudio::Model::LifeCycleCost.createLifeCycleCost("LCC_Demo - #{template_elec_equip_def.name}", template_elec_equip_def, demolition_cost_si, 'CostPerArea', 'Salvage', expected_life, years_until_costs_start + expected_life)
|
349
|
-
lcc_om = OpenStudio::Model::LifeCycleCost.createLifeCycleCost("LCC_OM - #{template_elec_equip_def.name}", template_elec_equip_def, om_cost_si, 'CostPerArea', 'Maintenance', om_frequency, 0)
|
350
|
-
|
351
|
-
if template_elec_equip_def.lifeCycleCosts.size - starting_lcc_counter != 3
|
352
|
-
runner.registerWarning("The measure did not function as expected. #{template_elec_equip_def.lifeCycleCosts.size - starting_lcc_counter} LifeCycleCost objects were made, 3 were expected.")
|
353
|
-
end
|
354
|
-
|
355
|
-
end
|
356
|
-
|
357
|
-
# show as not applicable if no cost requested
|
358
|
-
if costs_requested == false
|
359
|
-
runner.registerAsNotApplicable('No new lifecycle costs objects were requested.')
|
360
|
-
end
|
361
|
-
|
362
|
-
# get space types in model
|
363
|
-
if apply_to_building
|
364
|
-
space_types = model.getSpaceTypes
|
365
|
-
else
|
366
|
-
space_types = []
|
367
|
-
space_types << space_type # only run on a single space type
|
368
|
-
end
|
369
|
-
|
370
|
-
# loop through space types
|
371
|
-
space_types.each do |space_type|
|
372
|
-
space_type_electric_equipment = space_type.electricEquipment
|
373
|
-
space_type_spaces = space_type.spaces
|
374
|
-
multiple_schedules = false
|
375
|
-
|
376
|
-
space_type_electric_equipment_array = []
|
377
|
-
|
378
|
-
# if space type has electric equipment and is used in the model
|
379
|
-
if !space_type_electric_equipment.empty? && !space_type_spaces.empty?
|
380
|
-
electric_equipment_schedules = []
|
381
|
-
space_type_electric_equipment.each do |space_type_elec_equip|
|
382
|
-
electric_equipment_data_for_array = []
|
383
|
-
if !space_type_elec_equip.schedule.empty?
|
384
|
-
space_type_elec_equip_new_schedule = space_type_elec_equip.schedule
|
385
|
-
if !space_type_elec_equip_new_schedule.empty?
|
386
|
-
electric_equipment_schedules << space_type_elec_equip.powerPerFloorArea
|
387
|
-
if !space_type_elec_equip.powerPerFloorArea.empty?
|
388
|
-
electric_equipment_data_for_array << space_type_elec_equip.powerPerFloorArea.get
|
389
|
-
else
|
390
|
-
electric_equipment_data_for_array << 0.0
|
391
|
-
end
|
392
|
-
electric_equipment_data_for_array << space_type_elec_equip_new_schedule.get
|
393
|
-
electric_equipment_data_for_array << space_type_elec_equip.isScheduleDefaulted
|
394
|
-
space_type_electric_equipment_array << electric_equipment_data_for_array
|
395
|
-
end
|
396
|
-
end
|
397
|
-
end
|
398
|
-
|
399
|
-
# pick schedule to use and see if it is defaulted
|
400
|
-
space_type_electric_equipment_array = space_type_electric_equipment_array.sort.reverse[0]
|
401
|
-
if !space_type_electric_equipment_array.nil? # this is need if schedule is empty but also not defaulted
|
402
|
-
if space_type_electric_equipment_array[2] != true # if not schedule defaulted
|
403
|
-
preferred_schedule = space_type_electric_equipment_array[1]
|
404
|
-
else
|
405
|
-
# leave schedule blank, it is defaulted
|
406
|
-
end
|
407
|
-
end
|
408
|
-
|
409
|
-
# flag if electric_equipment_schedules has more than one unique object
|
410
|
-
if electric_equipment_schedules.uniq.size > 1
|
411
|
-
multiple_schedules = true
|
412
|
-
end
|
413
|
-
|
414
|
-
# delete electric equipment and add in new electric equipment.
|
415
|
-
space_type_electric_equipment = space_type.electricEquipment
|
416
|
-
space_type_electric_equipment.each(&:remove)
|
417
|
-
space_type_elec_equip_new = template_elec_equip_inst.clone(model)
|
418
|
-
space_type_elec_equip_new = space_type_elec_equip_new.to_ElectricEquipment.get
|
419
|
-
space_type_elec_equip_new.setSpaceType(space_type)
|
420
|
-
|
421
|
-
# assign preferred schedule to new electric equipment object
|
422
|
-
if defined? space_type_electric_equipment_array
|
423
|
-
if !space_type_elec_equip_new.schedule.empty? && (space_type_electric_equipment_array[2] != true)
|
424
|
-
space_type_elec_equip_new.setSchedule(preferred_schedule)
|
425
|
-
end
|
426
|
-
else
|
427
|
-
runner.registerWarning("Not adding schedule for electric equipment in #{space_type.name}, no original electric equipment to harvest schedule from.")
|
428
|
-
end
|
429
|
-
|
430
|
-
# if schedules had to be removed due to multiple electric equipment add warning
|
431
|
-
if !space_type_elec_equip_new.schedule.empty? && (multiple_schedules == true)
|
432
|
-
space_type_elec_equip_new_schedule = space_type_elec_equip_new.schedule
|
433
|
-
runner.registerWarning("The space type named '#{space_type.name}' had more than one electric equipment object with unique schedules. The schedule named '#{space_type_elec_equip_new_schedule.get.name}' was used for the new EPD electric equipment object.")
|
434
|
-
end
|
435
|
-
|
436
|
-
elsif space_type_electric_equipment.empty? && !space_type_spaces.empty?
|
437
|
-
runner.registerInfo("The space type named '#{space_type.name}' doesn't have any electric equipment, none will be added.")
|
438
|
-
end
|
439
|
-
end
|
440
|
-
|
441
|
-
# getting spaces in the model
|
442
|
-
spaces = model.getSpaces
|
443
|
-
|
444
|
-
# get space types in model
|
445
|
-
if apply_to_building
|
446
|
-
spaces = model.getSpaces
|
447
|
-
else
|
448
|
-
if !space_type.spaces.empty?
|
449
|
-
spaces = space_type.spaces # only run on a single space type
|
450
|
-
end
|
451
|
-
end
|
452
|
-
|
453
|
-
spaces.each do |space|
|
454
|
-
space_electric_equipment = space.electricEquipment
|
455
|
-
space_space_type = space.spaceType
|
456
|
-
if !space_space_type.empty?
|
457
|
-
space_space_type_electric_equipment = space_space_type.get.electricEquipment
|
458
|
-
else
|
459
|
-
space_space_type_electric_equipment = []
|
460
|
-
end
|
461
|
-
|
462
|
-
# array to manage electric equipment schedules within a space
|
463
|
-
space_electric_equipment_array = []
|
464
|
-
|
465
|
-
# if space has electric equipment and space type also has electric equipment
|
466
|
-
if !space_electric_equipment.empty? && !space_space_type_electric_equipment.empty?
|
467
|
-
|
468
|
-
# loop through and remove all electric equipment
|
469
|
-
space_electric_equipment.each(&:remove)
|
470
|
-
runner.registerWarning("The space named '#{space.name}' had one or more electric equipment objects. These were deleted and a new EPD electric equipment object was added to the parent space type named '#{space_space_type.get.name}'.")
|
471
|
-
|
472
|
-
elsif !space_electric_equipment.empty? && space_space_type_electric_equipment.empty?
|
473
|
-
|
474
|
-
# inspect schedules for electric equipment objects
|
475
|
-
multiple_schedules = false
|
476
|
-
electric_equipment_schedules = []
|
477
|
-
space_electric_equipment.each do |space_elec_equip|
|
478
|
-
electric_equipment_data_for_array = []
|
479
|
-
if !space_elec_equip.schedule.empty?
|
480
|
-
space_elec_equip_new_schedule = space_elec_equip.schedule
|
481
|
-
if !space_elec_equip_new_schedule.empty?
|
482
|
-
electric_equipment_schedules << space_elec_equip.powerPerFloorArea
|
483
|
-
if !space_elec_equip.powerPerFloorArea.empty?
|
484
|
-
electric_equipment_data_for_array << space_elec_equip.powerPerFloorArea.get
|
485
|
-
else
|
486
|
-
electric_equipment_data_for_array << 0.0
|
487
|
-
end
|
488
|
-
electric_equipment_data_for_array << space_elec_equip_new_schedule.get
|
489
|
-
electric_equipment_data_for_array << space_elec_equip.isScheduleDefaulted
|
490
|
-
space_electric_equipment_array << electric_equipment_data_for_array
|
491
|
-
end
|
492
|
-
end
|
493
|
-
end
|
494
|
-
|
495
|
-
# pick schedule to use and see if it is defaulted
|
496
|
-
space_electric_equipment_array = space_electric_equipment_array.sort.reverse[0]
|
497
|
-
if !space_electric_equipment_array.nil?
|
498
|
-
if space_electric_equipment_array[2] != true
|
499
|
-
preferred_schedule = space_electric_equipment_array[1]
|
500
|
-
else
|
501
|
-
# leave schedule blank, it is defaulted
|
502
|
-
end
|
503
|
-
end
|
504
|
-
|
505
|
-
# flag if electric_equipment_schedules has more than one unique object
|
506
|
-
if electric_equipment_schedules.uniq.size > 1
|
507
|
-
multiple_schedules = true
|
508
|
-
end
|
509
|
-
|
510
|
-
# delete electric equipment and add in new electric equipment
|
511
|
-
space_electric_equipment.each(&:remove)
|
512
|
-
space_elec_equip_new = template_elec_equip_inst.clone(model)
|
513
|
-
space_elec_equip_new = space_elec_equip_new.to_ElectricEquipment.get
|
514
|
-
space_elec_equip_new.setSpace(space)
|
515
|
-
|
516
|
-
# assign preferred schedule to new electric equipment object
|
517
|
-
if defined? space_type_electric_equipment_array
|
518
|
-
if !space_elec_equip_new.schedule.empty? && (space_type_electric_equipment_array[2] != true)
|
519
|
-
space_elec_equip_new.setSchedule(preferred_schedule)
|
520
|
-
end
|
521
|
-
else
|
522
|
-
runner.registerWarning("Not adding schedule for electric equipment in #{space.name}, no original electric equipment to harvest schedule from.")
|
523
|
-
end
|
524
|
-
|
525
|
-
# if schedules had to be removed due to multiple electric equipment add warning here
|
526
|
-
if !space_elec_equip_new.schedule.empty? && (multiple_schedules == true)
|
527
|
-
space_elec_equip_new_schedule = space_elec_equip_new.schedule
|
528
|
-
runner.registerWarning("The space type named '#{space.name}' had more than one electric equipment object with unique schedules. The schedule named '#{space_elec_equip_new_schedule.get.name}' was used for the new EPD electric equipment object.")
|
529
|
-
end
|
530
|
-
|
531
|
-
elsif space_electric_equipment.empty? && space_space_type_electric_equipment.empty?
|
532
|
-
|
533
|
-
# add in electric equipment for spaces that do not have any with most common schedule
|
534
|
-
if add_instance_all_spaces && space.partofTotalFloorArea
|
535
|
-
space_elec_equip_new = template_elec_equip_inst.clone(model)
|
536
|
-
space_elec_equip_new = space_elec_equip_new.to_ElectricEquipment.get
|
537
|
-
space_elec_equip_new.setSpace(space)
|
538
|
-
space_elec_equip_new.setSchedule(most_comm_sch)
|
539
|
-
runner.registerInfo("Adding electric equipment to #{space.name} using #{most_comm_sch.name} as fractional schedule.")
|
540
|
-
else
|
541
|
-
# issue warning that the space does not have any direct or inherited electric equipment.
|
542
|
-
runner.registerInfo("The space named '#{space.name}' does not have any direct or inherited electric equipment. No electric equipment object was added")
|
543
|
-
end
|
544
|
-
|
545
|
-
end
|
546
|
-
end
|
547
|
-
|
548
|
-
# subtract demo cost of electric equipment that were not deleted so the demo costs are not counted
|
549
|
-
if demo_cost_initial_const
|
550
|
-
elec_equip_defs.each do |elec_equip_def| # this does not loop through the new def (which is the desired behavior)
|
551
|
-
demo_costs_of_baseline_objects += -1 * add_to_baseline_demo_cost_counter(elec_equip_def)
|
552
|
-
puts "#{elec_equip_def.name},#{add_to_baseline_demo_cost_counter(elec_equip_def)}"
|
553
|
-
end
|
554
|
-
end
|
555
|
-
|
556
|
-
# clean up template electric equipment instance. Will EnergyPlus will fail if you have an instance that isn't associated with a space or space type
|
557
|
-
template_elec_equip_inst.remove
|
558
|
-
|
559
|
-
# calculate the final electric equipment and cost for initial condition.
|
560
|
-
elec_equip_defs = model.getElectricEquipmentDefinitions # this is done again to get the new def made by the measure
|
561
|
-
final_electric_equipment_cost = 0
|
562
|
-
final_electric_equipment_cost += get_total_costs_for_objects(elec_equip_defs)
|
563
|
-
|
564
|
-
# add one time demo cost of removed electric equipment if appropriate
|
565
|
-
if demo_cost_initial_const == true
|
566
|
-
building = model.getBuilding
|
567
|
-
lcc_baseline_demo = OpenStudio::Model::LifeCycleCost.createLifeCycleCost('LCC_baseline_demo', building, demo_costs_of_baseline_objects, 'CostPerEach', 'Salvage', 0, years_until_costs_start).get # using 0 for repeat period since one time cost.
|
568
|
-
runner.registerInfo("Adding one time cost of $#{neat_numbers(lcc_baseline_demo.totalCost, 0)} related to demolition of baseline objects.")
|
569
|
-
|
570
|
-
# if demo occurs on year 0 then add to initial capital cost counter
|
571
|
-
if lcc_baseline_demo.yearsFromStart == 0
|
572
|
-
final_electric_equipment_cost += lcc_baseline_demo.totalCost
|
573
|
-
end
|
574
|
-
end
|
575
|
-
|
576
|
-
# report final condition
|
577
|
-
building_final_epd_si = OpenStudio::Quantity.new(building.electricEquipmentPowerPerFloorArea, unit_epd_si)
|
578
|
-
building_final_epd_ip = OpenStudio.convert(building_final_epd_si, unit_epd_ip).get
|
579
|
-
runner.registerFinalCondition("Your model's final EPD is #{building_final_epd_ip}. Final Year 0 cost for building electric equipment is $#{neat_numbers(final_electric_equipment_cost, 0)}.")
|
580
|
-
|
581
|
-
return true
|
582
|
-
end
|
583
|
-
end
|
584
|
-
|
585
|
-
# this allows the measure to be used by the application
|
586
|
-
SetElectricEquipmentLoadsByEPD.new.registerWithApplication
|