openstudio-ee 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -0
  3. data/Rakefile +2 -0
  4. data/lib/measures/ImproveFanTotalEfficiencybyPercentage/measure.rb +333 -0
  5. data/lib/measures/ImproveFanTotalEfficiencybyPercentage/measure.xml +150 -0
  6. data/lib/measures/ReplaceFanTotalEfficiency/measure.rb +330 -0
  7. data/lib/measures/ReplaceFanTotalEfficiency/measure.xml +150 -0
  8. data/lib/measures/add_apszhp_to_each_zone/measure.rb +607 -0
  9. data/lib/measures/add_apszhp_to_each_zone/measure.xml +184 -0
  10. data/lib/measures/add_energy_recovery_ventilator/measure.rb +354 -0
  11. data/lib/measures/add_energy_recovery_ventilator/measure.xml +78 -0
  12. data/lib/measures/improve_simple_glazing_by_percentage/measure.rb +81 -0
  13. data/lib/measures/improve_simple_glazing_by_percentage/measure.xml +70 -0
  14. data/lib/measures/reduce_water_use_by_percentage/measure.rb +61 -0
  15. data/lib/measures/reduce_water_use_by_percentage/measure.xml +62 -0
  16. data/lib/measures/replace_hvac_with_gshp_and_doas/measure.rb +511 -0
  17. data/lib/measures/replace_hvac_with_gshp_and_doas/measure.xml +375 -0
  18. data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_AedgMeasures.rb +454 -0
  19. data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_Constructions.rb +221 -0
  20. data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_Geometry.rb +41 -0
  21. data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_HVAC.rb +1682 -0
  22. data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_HelperMethods.rb +114 -0
  23. data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_LightingAndEquipment.rb +99 -0
  24. data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_Schedules.rb +142 -0
  25. data/lib/measures/replace_simple_glazing/measure.rb +86 -0
  26. data/lib/measures/replace_simple_glazing/measure.xml +78 -0
  27. data/lib/measures/set_boiler_thermal_efficiency/measure.rb +520 -0
  28. data/lib/measures/set_boiler_thermal_efficiency/measure.xml +78 -0
  29. data/lib/measures/set_water_heater_efficiency_heat_lossand_peak_water_flow_rate/measure.rb +207 -0
  30. data/lib/measures/set_water_heater_efficiency_heat_lossand_peak_water_flow_rate/measure.xml +78 -0
  31. data/lib/measures/tenant_star_internal_loads/measure.rb +134 -0
  32. data/lib/measures/tenant_star_internal_loads/measure.xml +67 -0
  33. data/lib/measures/tenant_star_internal_loads/resources/os_lib_helper_methods.rb +401 -0
  34. data/lib/measures/vr_fwith_doas/measure.rb +468 -0
  35. data/lib/measures/vr_fwith_doas/measure.xml +298 -0
  36. data/lib/measures/vr_fwith_doas/resources/OsLib_AedgMeasures.rb +454 -0
  37. data/lib/measures/vr_fwith_doas/resources/OsLib_Constructions.rb +221 -0
  38. data/lib/measures/vr_fwith_doas/resources/OsLib_Geometry.rb +41 -0
  39. data/lib/measures/vr_fwith_doas/resources/OsLib_HVAC.rb +1516 -0
  40. data/lib/measures/vr_fwith_doas/resources/OsLib_HelperMethods.rb +114 -0
  41. data/lib/measures/vr_fwith_doas/resources/OsLib_LightingAndEquipment.rb +99 -0
  42. data/lib/measures/vr_fwith_doas/resources/OsLib_Schedules.rb +142 -0
  43. data/lib/openstudio/ee_measures/version.rb +1 -1
  44. data/openstudio-ee.gemspec +7 -5
  45. metadata +48 -9
@@ -0,0 +1,330 @@
1
+ # frozen_string_literal: true
2
+
3
+ # start the measure
4
+ class ReplaceFanTotalEfficiency < OpenStudio::Ruleset::ModelUserScript
5
+ # define the name that a user will see, this method may be deprecated as
6
+ # the display name in PAT comes from the name field in measure.xml
7
+ def name
8
+ return 'Replace Fan Total Efficiency'
9
+ end
10
+
11
+ # define the arguments that the user will input
12
+ def arguments(model)
13
+ args = OpenStudio::Ruleset::OSArgumentVector.new
14
+
15
+ # populate choice argument for constructions that are applied to surfaces in the model
16
+ loop_handles = OpenStudio::StringVector.new
17
+ loop_display_names = OpenStudio::StringVector.new
18
+
19
+ # putting air loops and names into hash
20
+ loop_args = model.getAirLoopHVACs
21
+ loop_args_hash = {}
22
+ loop_args.each do |loop_arg|
23
+ loop_args_hash[loop_arg.name.to_s] = loop_arg
24
+ end
25
+
26
+ # looping through sorted hash of air loops
27
+ loop_args_hash.sort.map do |key, value|
28
+ show_loop = false
29
+ components = value.supplyComponents
30
+ components.each do |component|
31
+ if !component.to_FanConstantVolume.empty?
32
+ show_loop = true
33
+ end
34
+ if !component.to_FanVariableVolume.empty?
35
+ show_loop = true
36
+ end
37
+ if !component.to_FanOnOff.empty?
38
+ show_loop = true
39
+ end
40
+ end
41
+
42
+ # if loop as object of correct type then add to hash.
43
+ if show_loop == true
44
+ loop_handles << value.handle.to_s
45
+ loop_display_names << key
46
+ end
47
+ end
48
+
49
+ # add building to string vector with air loops
50
+ building = model.getBuilding
51
+ loop_handles << building.handle.to_s
52
+ loop_display_names << '*All Air Loops*'
53
+
54
+ # make an argument for air loops
55
+ object = OpenStudio::Ruleset::OSArgument.makeChoiceArgument('object', loop_handles, loop_display_names, true)
56
+ object.setDisplayName('Choose an Air Loop to Alter.')
57
+ object.setDefaultValue('*All Air Loops*') # if no loop is chosen this will run on all air loops
58
+ args << object
59
+
60
+ # TODO: - change this to choice list from design document
61
+ # make an argument to add new space true/false
62
+ motor_eff = OpenStudio::Ruleset::OSArgument.makeDoubleArgument('motor_eff', true)
63
+ motor_eff.setDisplayName('Fan Total Efficiency Replacement in %')
64
+ motor_eff.setDefaultValue(70)
65
+ args << motor_eff
66
+
67
+ # bool argument to remove existing costs
68
+ remove_costs = OpenStudio::Ruleset::OSArgument.makeBoolArgument('remove_costs', true)
69
+ remove_costs.setDisplayName('Remove Baseline Costs From Effected Fans?')
70
+ remove_costs.setDefaultValue(false)
71
+ args << remove_costs
72
+
73
+ # make an argument for material and installation cost
74
+ material_cost = OpenStudio::Ruleset::OSArgument.makeDoubleArgument('material_cost', true)
75
+ material_cost.setDisplayName('Material and Installation Costs per Motor ($).')
76
+ material_cost.setDefaultValue(0.0)
77
+ args << material_cost
78
+
79
+ # make an argument for demolition cost
80
+ demolition_cost = OpenStudio::Ruleset::OSArgument.makeDoubleArgument('demolition_cost', true)
81
+ demolition_cost.setDisplayName('Demolition Costs per Motor ($).')
82
+ demolition_cost.setDefaultValue(0.0)
83
+ args << demolition_cost
84
+
85
+ # make an argument for duration in years until costs start
86
+ years_until_costs_start = OpenStudio::Ruleset::OSArgument.makeIntegerArgument('years_until_costs_start', true)
87
+ years_until_costs_start.setDisplayName('Years Until Costs Start (whole years).')
88
+ years_until_costs_start.setDefaultValue(0)
89
+ args << years_until_costs_start
90
+
91
+ # make an argument to determine if demolition costs should be included in initial construction
92
+ demo_cost_initial_const = OpenStudio::Ruleset::OSArgument.makeBoolArgument('demo_cost_initial_const', true)
93
+ demo_cost_initial_const.setDisplayName('Demolition Costs Occur During Initial Construction?')
94
+ demo_cost_initial_const.setDefaultValue(false)
95
+ args << demo_cost_initial_const
96
+
97
+ # make an argument for expected life
98
+ expected_life = OpenStudio::Ruleset::OSArgument.makeIntegerArgument('expected_life', true)
99
+ expected_life.setDisplayName('Expected Life (whole years).')
100
+ expected_life.setDefaultValue(20)
101
+ args << expected_life
102
+
103
+ # make an argument for o&m cost
104
+ om_cost = OpenStudio::Ruleset::OSArgument.makeDoubleArgument('om_cost', true)
105
+ om_cost.setDisplayName('O & M Costs per Motor ($).')
106
+ om_cost.setDefaultValue(0.0)
107
+ args << om_cost
108
+
109
+ # make an argument for o&m frequency
110
+ om_frequency = OpenStudio::Ruleset::OSArgument.makeIntegerArgument('om_frequency', true)
111
+ om_frequency.setDisplayName('O & M Frequency (whole years).')
112
+ om_frequency.setDefaultValue(1)
113
+ args << om_frequency
114
+
115
+ return args
116
+ end # end the arguments method
117
+
118
+ # define what happens when the measure is cop
119
+ def run(model, runner, user_arguments)
120
+ super(model, runner, user_arguments)
121
+
122
+ # use the built-in error checking
123
+ if !runner.validateUserArguments(arguments(model), user_arguments)
124
+ return false
125
+ end
126
+
127
+ # assign the user inputs to variables
128
+ object = runner.getOptionalWorkspaceObjectChoiceValue('object', user_arguments, model) # model is passed in because of argument type
129
+ motor_eff = runner.getDoubleArgumentValue('motor_eff', user_arguments)
130
+ remove_costs = runner.getBoolArgumentValue('remove_costs', user_arguments)
131
+ material_cost = runner.getDoubleArgumentValue('material_cost', user_arguments)
132
+ demolition_cost = runner.getDoubleArgumentValue('demolition_cost', user_arguments)
133
+ years_until_costs_start = runner.getIntegerArgumentValue('years_until_costs_start', user_arguments)
134
+ demo_cost_initial_const = runner.getBoolArgumentValue('demo_cost_initial_const', user_arguments)
135
+ expected_life = runner.getIntegerArgumentValue('expected_life', user_arguments)
136
+ om_cost = runner.getDoubleArgumentValue('om_cost', user_arguments)
137
+ om_frequency = runner.getIntegerArgumentValue('om_frequency', user_arguments)
138
+
139
+ # check the loop for reasonableness
140
+ apply_to_all_loops = false
141
+ loop = nil
142
+ if object.empty?
143
+ handle = runner.getStringArgumentValue('loop', user_arguments)
144
+ if handle.empty?
145
+ runner.registerError('No loop was chosen.')
146
+ else
147
+ runner.registerError("The selected loop with handle '#{handle}' was not found in the model. It may have been removed by another measure.")
148
+ end
149
+ return false
150
+ else
151
+ if !object.get.to_Loop.empty?
152
+ loop = object.get.to_Loop.get
153
+ elsif !object.get.to_Building.empty?
154
+ apply_to_all_loops = true
155
+ else
156
+ runner.registerError('Script Error - argument not showing up as loop.')
157
+ return false
158
+ end
159
+ end # end of if loop.empty?
160
+
161
+ # set flags to use later
162
+ costs_requested = false
163
+
164
+ # set values to use later
165
+ yr0_capital_totalCosts_baseline = 0
166
+ yr0_capital_totalCosts_proposed = 0
167
+
168
+ # If demo_cost_initial_const is true then will be applied once in the lifecycle. Future replacements use the demo cost of the new construction.
169
+ demo_costs_of_baseline_objects = 0
170
+
171
+ # check costs for reasonableness
172
+ if material_cost.abs + demolition_cost.abs + om_cost.abs == 0
173
+ runner.registerInfo('No costs were requested for motors improvements.')
174
+ else
175
+ costs_requested = true
176
+ end
177
+
178
+ # check lifecycle arguments for reasonableness
179
+ if (years_until_costs_start < 0) && (years_until_costs_start > expected_life)
180
+ runner.registerError('Years until costs start should be a non-negative integer less than Expected Life.')
181
+ end
182
+ if (expected_life < 1) && (expected_life > 100)
183
+ runner.registerError('Choose an integer greater than 0 and less than or equal to 100 for Expected Life.')
184
+ end
185
+ if om_frequency < 1
186
+ runner.registerError('Choose an integer greater than 0 for O & M Frequency.')
187
+ end
188
+
189
+ # 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
190
+ def neat_numbers(number, roundto = 2) # round to 0 or 2)
191
+ if roundto == 2
192
+ number = format '%.2f', number
193
+ else
194
+ number = number.round
195
+ end
196
+ # regex to add commas
197
+ number.to_s.reverse.gsub(/([0-9]{3}(?=([0-9])))/, '\\1,').reverse
198
+ end # end def neat_numbers
199
+
200
+ # helper that loops through lifecycle costs getting total costs under "Construction" or "Salvage" category and add to counter if occurs during year 0
201
+ def get_total_costs_for_objects(objects)
202
+ counter = 0
203
+ objects.each do |object|
204
+ object_LCCs = object.lifeCycleCosts
205
+ object_LCCs.each do |object_LCC|
206
+ if (object_LCC.category == 'Construction') || (object_LCC.category == 'Salvage')
207
+ if object_LCC.yearsFromStart == 0
208
+ counter += object_LCC.totalCost
209
+ end
210
+ end
211
+ end
212
+ end
213
+ return counter
214
+ end # end of def get_total_costs_for_objects(objects)
215
+
216
+ # get loops for measure
217
+ if apply_to_all_loops
218
+ loops = model.getAirLoopHVACs
219
+ else
220
+ loops = []
221
+ loops << loop # only run on a single space type
222
+ end
223
+
224
+ # get cop values
225
+ initial_motor_efficiency_values = []
226
+ missing_initial_motor_efficiency = 0
227
+
228
+ # loop through air loops
229
+ loops.each do |loop|
230
+ supply_components = loop.supplyComponents
231
+
232
+ # find fans on loop
233
+ supply_components.each do |supply_component|
234
+ hVACComponent = supply_component.to_FanConstantVolume
235
+ if hVACComponent.empty?
236
+ hVACComponent = supply_component.to_FanVariableVolume
237
+ end
238
+ if hVACComponent.empty?
239
+ hVACComponent = supply_component.to_FanOnOff
240
+ end
241
+
242
+ # alter components of correct type
243
+ if !hVACComponent.empty?
244
+ hVACComponent = hVACComponent.get
245
+
246
+ # change and report changes to fans and motors
247
+ initial_motor_efficiency = hVACComponent.fanEfficiency
248
+ target_motor_efficiency = motor_eff * 0.01
249
+ initial_motor_efficiency_values << initial_motor_efficiency
250
+ if target_motor_efficiency > 1
251
+ hVACComponent.setFanEfficiency(1.0)
252
+ runner.registerWarning("Requested efficiency of #{target_motor_efficiency * 100}% for #{hVACComponent.name} is not possible. Setting motor efficiency to 100%.")
253
+ elsif target_motor_efficiency < 0
254
+ hVACComponent.setFanEfficiency(0.0)
255
+ runner.registerWarning("Requested efficiency of #{target_motor_efficiency * 100}% for #{hVACComponent.name} is not possible. Setting motor efficiency to 0%.")
256
+ elsif target_motor_efficiency < initial_motor_efficiency
257
+ hVACComponent.setFanEfficiency(initial_motor_efficiency)
258
+ runner.registerWarning("Requested efficiency of #{target_motor_efficiency * 100}% for #{hVACComponent.name} is the same as the initial efficiency. No changes.")
259
+ else
260
+ hVACComponent.setFanEfficiency(target_motor_efficiency)
261
+ runner.registerInfo("Changing the motor efficiency from #{initial_motor_efficiency * 100}% to #{target_motor_efficiency * 100}% for '#{hVACComponent.name}' onloop '#{loop.name}.'")
262
+ if target_motor_efficiency > 0.96
263
+ runner.registerWarning("Requested efficiency for #{hVACComponent.name} is greater than 96%.")
264
+ end
265
+ end
266
+
267
+ # get initial year 0 cost
268
+ yr0_capital_totalCosts_baseline += get_total_costs_for_objects([hVACComponent])
269
+
270
+ # demo value of baseline costs associated with unit
271
+ demo_LCCs = hVACComponent.lifeCycleCosts
272
+ demo_LCCs.each do |demo_LCC|
273
+ if demo_LCC.category == 'Salvage'
274
+ demo_costs_of_baseline_objects += demo_LCC.totalCost
275
+ end
276
+ end
277
+
278
+ # remove all old costs
279
+ if !hVACComponent.lifeCycleCosts.empty? && (remove_costs == true)
280
+ runner.registerInfo("Removing existing lifecycle cost objects associated with #{hVACComponent.name}")
281
+ removed_costs = hVACComponent.removeLifeCycleCosts
282
+ end
283
+
284
+ # add new costs
285
+ if costs_requested == true
286
+
287
+ # adding new cost items
288
+ lcc_mat = OpenStudio::Model::LifeCycleCost.createLifeCycleCost("LCC_Mat - #{hVACComponent.name}", hVACComponent, material_cost, 'CostPerEach', 'Construction', expected_life, years_until_costs_start)
289
+ # cost for if demo_initial_Construction == true is added at the end of the measure
290
+ lcc_demo = OpenStudio::Model::LifeCycleCost.createLifeCycleCost("LCC_Demo - #{hVACComponent.name}", hVACComponent, demolition_cost, 'CostPerEach', 'Salvage', expected_life, years_until_costs_start + expected_life)
291
+ lcc_om = OpenStudio::Model::LifeCycleCost.createLifeCycleCost("LCC_OM - #{hVACComponent.name}", hVACComponent, om_cost, 'CostPerEach', 'Maintenance', om_frequency, 0)
292
+
293
+ # get final year 0 cost
294
+ yr0_capital_totalCosts_proposed += get_total_costs_for_objects([hVACComponent])
295
+
296
+ end # end of costs_requested == true
297
+
298
+ end # end if not hVACComponent.empty?
299
+ end # end supply_components.each do
300
+ end # end loops.each do
301
+
302
+ # add one time demo cost of removed windows if appropriate
303
+ if demo_cost_initial_const == true
304
+ building = model.getBuilding
305
+ 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.
306
+ runner.registerInfo("Adding one time cost of $#{neat_numbers(lcc_baseline_demo.totalCost, 0)} related to demolition of baseline objects.")
307
+
308
+ # if demo occurs on year 0 then add to initial capital cost counter
309
+ if lcc_baseline_demo.yearsFromStart == 0
310
+ yr0_capital_totalCosts_proposed += lcc_baseline_demo.totalCost
311
+ end
312
+ end
313
+
314
+ if initial_motor_efficiency_values.size + missing_initial_motor_efficiency == 0
315
+ runner.registerAsNotApplicable('The affected loop(s) does not contain any fans, the model will not be altered.')
316
+ return true
317
+ end
318
+
319
+ # reporting initial condition of model
320
+ runner.registerInitialCondition("The starting motor efficiency values in affected loop(s) range from #{initial_motor_efficiency_values.min * 100}% to #{initial_motor_efficiency_values.max * 100}%. Initial year 0 capital costs for affected fans is $#{neat_numbers(yr0_capital_totalCosts_baseline, 0)}.")
321
+
322
+ # reporting final condition of model
323
+ runner.registerFinalCondition("#{initial_motor_efficiency_values.size + missing_initial_motor_efficiency} fans had motor efficiency values set to altered. Final year 0 capital costs for affected fans is $#{neat_numbers(yr0_capital_totalCosts_proposed, 0)}.")
324
+
325
+ return true
326
+ end # end the cop method
327
+ end # end the measure
328
+
329
+ # this allows the measure to be used by the application
330
+ ReplaceFanTotalEfficiency.new.registerWithApplication
@@ -0,0 +1,150 @@
1
+ <measure>
2
+ <schema_version>3.0</schema_version>
3
+ <name>replace_fan_total_efficiency</name>
4
+ <uid>ebeca0aa-a432-4283-a714-17116f7c8f8c</uid>
5
+ <version_id>348976a4-526f-4a56-b819-74c78f8a07e3</version_id>
6
+ <version_modified>20190212T002510Z</version_modified>
7
+ <xml_checksum>F78494F2</xml_checksum>
8
+ <class_name>ReplaceFanTotalEfficiency</class_name>
9
+ <display_name>Replace Fan Total Efficiency</display_name>
10
+ <description></description>
11
+ <modeler_description></modeler_description>
12
+ <arguments>
13
+ <argument>
14
+ <name>object</name>
15
+ <display_name>Choose an Air Loop to Alter.</display_name>
16
+ <type>Choice</type>
17
+ <required>true</required>
18
+ <model_dependent>false</model_dependent>
19
+ <default_value>*All Air Loops*</default_value>
20
+ <choices>
21
+ <choice>
22
+ <value>{7d3f0300-6b06-458a-ad5e-0d5d7ec180cc}</value>
23
+ <display_name>*All Air Loops*</display_name>
24
+ </choice>
25
+ </choices>
26
+ </argument>
27
+ <argument>
28
+ <name>motor_eff</name>
29
+ <display_name>Fan Total Efficiency Replacement in %</display_name>
30
+ <type>Double</type>
31
+ <required>true</required>
32
+ <model_dependent>false</model_dependent>
33
+ <default_value>70</default_value>
34
+ </argument>
35
+ <argument>
36
+ <name>remove_costs</name>
37
+ <display_name>Remove Baseline Costs From Effected Fans?</display_name>
38
+ <type>Boolean</type>
39
+ <required>true</required>
40
+ <model_dependent>false</model_dependent>
41
+ <default_value>false</default_value>
42
+ <choices>
43
+ <choice>
44
+ <value>true</value>
45
+ <display_name>true</display_name>
46
+ </choice>
47
+ <choice>
48
+ <value>false</value>
49
+ <display_name>false</display_name>
50
+ </choice>
51
+ </choices>
52
+ </argument>
53
+ <argument>
54
+ <name>material_cost</name>
55
+ <display_name>Material and Installation Costs per Motor ($).</display_name>
56
+ <type>Double</type>
57
+ <required>true</required>
58
+ <model_dependent>false</model_dependent>
59
+ <default_value>0</default_value>
60
+ </argument>
61
+ <argument>
62
+ <name>demolition_cost</name>
63
+ <display_name>Demolition Costs per Motor ($).</display_name>
64
+ <type>Double</type>
65
+ <required>true</required>
66
+ <model_dependent>false</model_dependent>
67
+ <default_value>0</default_value>
68
+ </argument>
69
+ <argument>
70
+ <name>years_until_costs_start</name>
71
+ <display_name>Years Until Costs Start (whole years).</display_name>
72
+ <type>Integer</type>
73
+ <required>true</required>
74
+ <model_dependent>false</model_dependent>
75
+ <default_value>0</default_value>
76
+ </argument>
77
+ <argument>
78
+ <name>demo_cost_initial_const</name>
79
+ <display_name>Demolition Costs Occur During Initial Construction?</display_name>
80
+ <type>Boolean</type>
81
+ <required>true</required>
82
+ <model_dependent>false</model_dependent>
83
+ <default_value>false</default_value>
84
+ <choices>
85
+ <choice>
86
+ <value>true</value>
87
+ <display_name>true</display_name>
88
+ </choice>
89
+ <choice>
90
+ <value>false</value>
91
+ <display_name>false</display_name>
92
+ </choice>
93
+ </choices>
94
+ </argument>
95
+ <argument>
96
+ <name>expected_life</name>
97
+ <display_name>Expected Life (whole years).</display_name>
98
+ <type>Integer</type>
99
+ <required>true</required>
100
+ <model_dependent>false</model_dependent>
101
+ <default_value>20</default_value>
102
+ </argument>
103
+ <argument>
104
+ <name>om_cost</name>
105
+ <display_name>O &amp; M Costs per Motor ($).</display_name>
106
+ <type>Double</type>
107
+ <required>true</required>
108
+ <model_dependent>false</model_dependent>
109
+ <default_value>0</default_value>
110
+ </argument>
111
+ <argument>
112
+ <name>om_frequency</name>
113
+ <display_name>O &amp; M Frequency (whole years).</display_name>
114
+ <type>Integer</type>
115
+ <required>true</required>
116
+ <model_dependent>false</model_dependent>
117
+ <default_value>1</default_value>
118
+ </argument>
119
+ </arguments>
120
+ <outputs/>
121
+ <provenances/>
122
+ <tags>
123
+ <tag>HVAC.Distribution</tag>
124
+ </tags>
125
+ <attributes>
126
+ <attribute>
127
+ <name>Measure Type</name>
128
+ <value>ModelMeasure</value>
129
+ <datatype>string</datatype>
130
+ </attribute>
131
+ <attribute>
132
+ <name>Uses SketchUp API</name>
133
+ <value>false</value>
134
+ <datatype>boolean</datatype>
135
+ </attribute>
136
+ </attributes>
137
+ <files>
138
+ <file>
139
+ <version>
140
+ <software_program>OpenStudio</software_program>
141
+ <identifier>1.0.3</identifier>
142
+ <min_compatible>1.0.3</min_compatible>
143
+ </version>
144
+ <filename>measure.rb</filename>
145
+ <filetype>rb</filetype>
146
+ <usage_type>script</usage_type>
147
+ <checksum>FCCFD3DA</checksum>
148
+ </file>
149
+ </files>
150
+ </measure>