openstudio-ee 0.12.3 → 0.12.5
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/.coverage +0 -0
- data/.github/workflows/test-with-openstudio.yml +109 -74
- data/.gitignore +21 -0
- data/.rubocop.yml +15 -2
- data/CHANGELOG.md +6 -0
- data/Gemfile +7 -8
- data/README.md +3 -2
- data/WORKFLOW_CHANGES.md +74 -0
- data/lib/measures/AddDaylightSensors/measure.rb +79 -79
- data/lib/measures/AddDaylightSensors/measure.xml +4 -4
- data/lib/measures/AddOverhangsByProjectionFactor/measure.rb +38 -41
- data/lib/measures/AddOverhangsByProjectionFactor/measure.xml +4 -4
- data/lib/measures/EnableDemandControlledVentilation/measure.rb +37 -40
- data/lib/measures/EnableDemandControlledVentilation/measure.xml +4 -4
- data/lib/measures/EnableEconomizerControl/measure.rb +36 -37
- data/lib/measures/EnableEconomizerControl/measure.xml +4 -4
- data/lib/measures/GLHEProExportLoadsforGroundHeatExchangerSizing/measure.rb +27 -41
- data/lib/measures/GLHEProExportLoadsforGroundHeatExchangerSizing/measure.xml +4 -4
- data/lib/measures/GLHEProGFunctionImport/measure.rb +11 -15
- data/lib/measures/GLHEProGFunctionImport/measure.xml +4 -4
- data/lib/measures/GLHEProSetupExportLoadsforGroundHeatExchangerSizing/measure.rb +5 -9
- data/lib/measures/GLHEProSetupExportLoadsforGroundHeatExchangerSizing/measure.xml +3 -3
- data/lib/measures/ImproveFanBeltEfficiency/measure.rb +78 -95
- data/lib/measures/ImproveFanBeltEfficiency/measure.xml +6 -6
- data/lib/measures/ImproveMotorEfficiency/measure.rb +75 -100
- data/lib/measures/ImproveMotorEfficiency/measure.xml +6 -6
- data/lib/measures/IncreaseInsulationRValueForExteriorWalls/measure.rb +137 -130
- data/lib/measures/IncreaseInsulationRValueForExteriorWalls/measure.xml +4 -4
- data/lib/measures/IncreaseInsulationRValueForExteriorWallsByPercentage/measure.rb +114 -115
- data/lib/measures/IncreaseInsulationRValueForExteriorWallsByPercentage/measure.xml +3 -3
- data/lib/measures/IncreaseInsulationRValueForRoofs/measure.rb +137 -130
- data/lib/measures/IncreaseInsulationRValueForRoofs/measure.xml +4 -4
- data/lib/measures/IncreaseInsulationRValueForRoofsByPercentage/measure.rb +114 -115
- data/lib/measures/IncreaseInsulationRValueForRoofsByPercentage/measure.xml +3 -3
- data/lib/measures/ReduceElectricEquipmentLoadsByPercentage/measure.rb +69 -63
- data/lib/measures/ReduceElectricEquipmentLoadsByPercentage/measure.xml +6 -6
- data/lib/measures/ReduceLightingLoadsByPercentage/measure.rb +77 -66
- data/lib/measures/ReduceLightingLoadsByPercentage/measure.xml +6 -6
- data/lib/measures/ReduceNightTimeElectricEquipmentLoads/measure.rb +45 -43
- data/lib/measures/ReduceNightTimeElectricEquipmentLoads/measure.xml +4 -4
- data/lib/measures/ReduceNightTimeLightingLoads/measure.rb +45 -43
- data/lib/measures/ReduceNightTimeLightingLoads/measure.xml +4 -4
- data/lib/measures/ReduceSpaceInfiltrationByPercentage/measure.rb +58 -52
- data/lib/measures/ReduceSpaceInfiltrationByPercentage/measure.xml +6 -6
- data/lib/measures/ReduceVentilationByPercentage/measure.rb +49 -46
- data/lib/measures/ReduceVentilationByPercentage/measure.xml +6 -6
- data/lib/measures/add_variable_speed_rtu_control_logic/measure.rb +31 -23
- data/lib/measures/add_variable_speed_rtu_control_logic/measure.xml +4 -4
- data/lib/measures/create_variable_speed_rtu/measure.rb +166 -174
- data/lib/measures/create_variable_speed_rtu/measure.xml +6 -6
- data/lib/measures/fan_assist_night_ventilation/measure.rb +33 -32
- data/lib/measures/fan_assist_night_ventilation/measure.xml +4 -4
- data/lib/measures/nze_hvac/measure.rb +72 -62
- data/lib/measures/nze_hvac/measure.xml +4 -4
- data/lib/measures/replace_water_heater_mixed_with_thermal_storage_chilled_water/measure.rb +16 -19
- data/lib/measures/replace_water_heater_mixed_with_thermal_storage_chilled_water/measure.xml +4 -4
- data/lib/measures/window_enhancement/LICENSE.md +14 -0
- data/lib/measures/window_enhancement/README.md +112 -0
- data/lib/measures/window_enhancement/docs/.gitkeep +0 -0
- data/lib/measures/window_enhancement/measure.py +386 -0
- data/lib/measures/window_enhancement/measure.xml +271 -0
- data/lib/measures/window_enhancement/resources/EC3_lookup.py +321 -0
- data/lib/measures/window_enhancement/resources/Test_API.py +32 -0
- data/lib/measures/window_enhancement/resources/__pycache__/EC3_lookup.cpython-39.pyc +0 -0
- data/lib/measures/window_enhancement/resources/__pycache__/Original_EC3_lookup.py +322 -0
- data/lib/measures/window_enhancement/resources/__pycache__/Test_API.cpython-39.pyc +0 -0
- data/lib/measures/window_enhancement/resources/calculate_perimeter.py +39 -0
- data/lib/measures/window_enhancement/test_output.log +39 -0
- data/lib/openstudio/ee_measures/version.rb +1 -1
- data/openstudio-ee.gemspec +10 -8
- data/test-workflow-locally.sh +152 -0
- metadata +64 -35
- data/Jenkinsfile +0 -11
@@ -10,7 +10,7 @@ class ImproveFanBeltEfficiency < OpenStudio::Measure::ModelMeasure
|
|
10
10
|
# define the name that a user will see, this method may be deprecated as
|
11
11
|
# the display name in PAT comes from the name field in measure.xml
|
12
12
|
def name
|
13
|
-
|
13
|
+
'Improve Fan Belt Efficiency'
|
14
14
|
end
|
15
15
|
|
16
16
|
# define the arguments that the user will input
|
@@ -33,15 +33,9 @@ class ImproveFanBeltEfficiency < OpenStudio::Measure::ModelMeasure
|
|
33
33
|
show_loop = false
|
34
34
|
components = value.supplyComponents
|
35
35
|
components.each do |component|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
if !component.to_FanVariableVolume.empty?
|
40
|
-
show_loop = true
|
41
|
-
end
|
42
|
-
if !component.to_FanOnOff.empty?
|
43
|
-
show_loop = true
|
44
|
-
end
|
36
|
+
show_loop = true unless component.to_FanConstantVolume.empty?
|
37
|
+
show_loop = true unless component.to_FanVariableVolume.empty?
|
38
|
+
show_loop = true unless component.to_FanOnOff.empty?
|
45
39
|
end
|
46
40
|
|
47
41
|
# if loop as object of correct type then add to hash.
|
@@ -117,7 +111,7 @@ class ImproveFanBeltEfficiency < OpenStudio::Measure::ModelMeasure
|
|
117
111
|
om_frequency.setDefaultValue(1)
|
118
112
|
args << om_frequency
|
119
113
|
|
120
|
-
|
114
|
+
args
|
121
115
|
end
|
122
116
|
|
123
117
|
# define what happens when the measure is cop
|
@@ -125,9 +119,7 @@ class ImproveFanBeltEfficiency < OpenStudio::Measure::ModelMeasure
|
|
125
119
|
super(model, runner, user_arguments)
|
126
120
|
|
127
121
|
# use the built-in error checking
|
128
|
-
|
129
|
-
return false
|
130
|
-
end
|
122
|
+
return false unless runner.validateUserArguments(arguments(model), user_arguments)
|
131
123
|
|
132
124
|
# assign the user inputs to variables
|
133
125
|
object = runner.getOptionalWorkspaceObjectChoiceValue('object', user_arguments, model) # model is passed in because of argument type
|
@@ -152,15 +144,13 @@ class ImproveFanBeltEfficiency < OpenStudio::Measure::ModelMeasure
|
|
152
144
|
runner.registerError("The selected loop with handle '#{handle}' was not found in the model. It may have been removed by another measure.")
|
153
145
|
end
|
154
146
|
return false
|
147
|
+
elsif !object.get.to_Loop.empty?
|
148
|
+
loop = object.get.to_Loop.get
|
149
|
+
elsif !object.get.to_Building.empty?
|
150
|
+
apply_to_all_loops = true
|
155
151
|
else
|
156
|
-
|
157
|
-
|
158
|
-
elsif !object.get.to_Building.empty?
|
159
|
-
apply_to_all_loops = true
|
160
|
-
else
|
161
|
-
runner.registerError('Script Error - argument not showing up as loop.')
|
162
|
-
return false
|
163
|
-
end
|
152
|
+
runner.registerError('Script Error - argument not showing up as loop.')
|
153
|
+
return false
|
164
154
|
end
|
165
155
|
|
166
156
|
# check the user_name for reasonableness
|
@@ -193,17 +183,15 @@ class ImproveFanBeltEfficiency < OpenStudio::Measure::ModelMeasure
|
|
193
183
|
if (expected_life < 1) && (expected_life > 100)
|
194
184
|
runner.registerError('Choose an integer greater than 0 and less than or equal to 100 for Expected Life.')
|
195
185
|
end
|
196
|
-
if om_frequency < 1
|
197
|
-
runner.registerError('Choose an integer greater than 0 for O & M Frequency.')
|
198
|
-
end
|
186
|
+
runner.registerError('Choose an integer greater than 0 for O & M Frequency.') if om_frequency < 1
|
199
187
|
|
200
188
|
# 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
|
201
189
|
def neat_numbers(number, roundto = 2) # round to 0 or 2)
|
202
|
-
if roundto == 2
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
190
|
+
number = if roundto == 2
|
191
|
+
format '%.2f', number
|
192
|
+
else
|
193
|
+
number.round
|
194
|
+
end
|
207
195
|
# regex to add commas
|
208
196
|
number.to_s.reverse.gsub(/([0-9]{3}(?=([0-9])))/, '\\1,').reverse
|
209
197
|
end
|
@@ -214,14 +202,12 @@ class ImproveFanBeltEfficiency < OpenStudio::Measure::ModelMeasure
|
|
214
202
|
objects.each do |object|
|
215
203
|
object_LCCs = object.lifeCycleCosts
|
216
204
|
object_LCCs.each do |object_LCC|
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
end
|
221
|
-
end
|
205
|
+
next unless (object_LCC.category == 'Construction') || (object_LCC.category == 'Salvage')
|
206
|
+
|
207
|
+
counter += object_LCC.totalCost if object_LCC.yearsFromStart == 0
|
222
208
|
end
|
223
209
|
end
|
224
|
-
|
210
|
+
counter
|
225
211
|
end
|
226
212
|
|
227
213
|
# get loops for measure
|
@@ -243,67 +229,61 @@ class ImproveFanBeltEfficiency < OpenStudio::Measure::ModelMeasure
|
|
243
229
|
# find fans on loop
|
244
230
|
supply_components.each do |supply_component|
|
245
231
|
hVACComponent = supply_component.to_FanConstantVolume
|
246
|
-
if hVACComponent.empty?
|
247
|
-
|
248
|
-
end
|
249
|
-
if hVACComponent.empty?
|
250
|
-
hVACComponent = supply_component.to_FanOnOff
|
251
|
-
end
|
232
|
+
hVACComponent = supply_component.to_FanVariableVolume if hVACComponent.empty?
|
233
|
+
hVACComponent = supply_component.to_FanOnOff if hVACComponent.empty?
|
252
234
|
|
253
235
|
# alter components of correct type
|
254
|
-
if
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
end
|
274
|
-
|
275
|
-
# get initial year 0 cost
|
276
|
-
yr0_capital_totalCosts_baseline += get_total_costs_for_objects([hVACComponent])
|
277
|
-
|
278
|
-
# demo value of baseline costs associated with unit
|
279
|
-
demo_LCCs = hVACComponent.lifeCycleCosts
|
280
|
-
demo_LCCs.each do |demo_LCC|
|
281
|
-
if demo_LCC.category == 'Salvage'
|
282
|
-
demo_costs_of_baseline_objects += demo_LCC.totalCost
|
283
|
-
end
|
236
|
+
next if hVACComponent.empty?
|
237
|
+
|
238
|
+
hVACComponent = hVACComponent.get
|
239
|
+
|
240
|
+
# change and report changes to fans and motors
|
241
|
+
initial_motor_efficiency = hVACComponent.motorEfficiency
|
242
|
+
target_motor_efficiency = initial_motor_efficiency + (motor_eff * 0.01)
|
243
|
+
initial_motor_efficiency_values << initial_motor_efficiency
|
244
|
+
if target_motor_efficiency > 1
|
245
|
+
hVACComponent.setMotorEfficiency(1.0)
|
246
|
+
runner.registerWarning("Requested efficiency of #{target_motor_efficiency * 100}% for #{hVACComponent.name} is not possible. Setting motor efficiency to 100%.")
|
247
|
+
elsif target_motor_efficiency < 0
|
248
|
+
hVACComponent.setMotorEfficiency(0.0)
|
249
|
+
runner.registerWarning("Requested efficiency of #{target_motor_efficiency * 100}% for #{hVACComponent.name} is not possible. Setting motor efficiency to 0%.")
|
250
|
+
else
|
251
|
+
hVACComponent.setMotorEfficiency(target_motor_efficiency)
|
252
|
+
runner.registerInfo("Changing the motor efficiency from #{initial_motor_efficiency * 100}% to #{target_motor_efficiency * 100}% for '#{hVACComponent.name}' onloop '#{loop.name}.'")
|
253
|
+
if target_motor_efficiency > 0.96
|
254
|
+
runner.registerWarning("Requested efficiency for #{hVACComponent.name} is greater than 96%.")
|
284
255
|
end
|
256
|
+
end
|
285
257
|
|
286
|
-
|
287
|
-
|
288
|
-
runner.registerInfo("Removing existing lifecycle cost objects associated with #{hVACComponent.name}")
|
289
|
-
removed_costs = hVACComponent.removeLifeCycleCosts
|
290
|
-
end
|
258
|
+
# get initial year 0 cost
|
259
|
+
yr0_capital_totalCosts_baseline += get_total_costs_for_objects([hVACComponent])
|
291
260
|
|
292
|
-
|
293
|
-
|
261
|
+
# demo value of baseline costs associated with unit
|
262
|
+
demo_LCCs = hVACComponent.lifeCycleCosts
|
263
|
+
demo_LCCs.each do |demo_LCC|
|
264
|
+
demo_costs_of_baseline_objects += demo_LCC.totalCost if demo_LCC.category == 'Salvage'
|
265
|
+
end
|
294
266
|
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
267
|
+
# remove all old costs
|
268
|
+
if !hVACComponent.lifeCycleCosts.empty? && (remove_costs == true)
|
269
|
+
runner.registerInfo("Removing existing lifecycle cost objects associated with #{hVACComponent.name}")
|
270
|
+
removed_costs = hVACComponent.removeLifeCycleCosts
|
271
|
+
end
|
300
272
|
|
301
|
-
|
302
|
-
|
273
|
+
# add new costs
|
274
|
+
next unless costs_requested == true
|
303
275
|
|
304
|
-
|
276
|
+
# adding new cost items
|
277
|
+
lcc_mat = OpenStudio::Model::LifeCycleCost.createLifeCycleCost("LCC_Mat - #{hVACComponent.name}",
|
278
|
+
hVACComponent, material_cost, 'CostPerEach', 'Construction', expected_life, years_until_costs_start)
|
279
|
+
# cost for if demo_initial_Construction == true is added at the end of the measure
|
280
|
+
lcc_demo = OpenStudio::Model::LifeCycleCost.createLifeCycleCost("LCC_Demo - #{hVACComponent.name}",
|
281
|
+
hVACComponent, demolition_cost, 'CostPerEach', 'Salvage', expected_life, years_until_costs_start + expected_life)
|
282
|
+
lcc_om = OpenStudio::Model::LifeCycleCost.createLifeCycleCost("LCC_OM - #{hVACComponent.name}",
|
283
|
+
hVACComponent, om_cost, 'CostPerEach', 'Maintenance', om_frequency, 0)
|
305
284
|
|
306
|
-
|
285
|
+
# get final year 0 cost
|
286
|
+
yr0_capital_totalCosts_proposed += get_total_costs_for_objects([hVACComponent])
|
307
287
|
end
|
308
288
|
end
|
309
289
|
|
@@ -311,12 +291,11 @@ class ImproveFanBeltEfficiency < OpenStudio::Measure::ModelMeasure
|
|
311
291
|
if demo_cost_initial_const == true
|
312
292
|
building = model.getBuilding
|
313
293
|
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.
|
314
|
-
runner.registerInfo("Adding one time cost of $#{neat_numbers(lcc_baseline_demo.totalCost,
|
294
|
+
runner.registerInfo("Adding one time cost of $#{neat_numbers(lcc_baseline_demo.totalCost,
|
295
|
+
0)} related to demolition of baseline objects.")
|
315
296
|
|
316
297
|
# if demo occurs on year 0 then add to initial capital cost counter
|
317
|
-
if lcc_baseline_demo.yearsFromStart == 0
|
318
|
-
yr0_capital_totalCosts_proposed += lcc_baseline_demo.totalCost
|
319
|
-
end
|
298
|
+
yr0_capital_totalCosts_proposed += lcc_baseline_demo.totalCost if lcc_baseline_demo.yearsFromStart == 0
|
320
299
|
end
|
321
300
|
|
322
301
|
if initial_motor_efficiency_values.size + missing_initial_motor_efficiency == 0
|
@@ -325,12 +304,16 @@ class ImproveFanBeltEfficiency < OpenStudio::Measure::ModelMeasure
|
|
325
304
|
end
|
326
305
|
|
327
306
|
# reporting initial condition of model
|
328
|
-
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(
|
307
|
+
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(
|
308
|
+
yr0_capital_totalCosts_baseline, 0
|
309
|
+
)}.")
|
329
310
|
|
330
311
|
# reporting final condition of model
|
331
|
-
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(
|
312
|
+
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(
|
313
|
+
yr0_capital_totalCosts_proposed, 0
|
314
|
+
)}.")
|
332
315
|
|
333
|
-
|
316
|
+
true
|
334
317
|
end
|
335
318
|
end
|
336
319
|
|
@@ -3,8 +3,8 @@
|
|
3
3
|
<schema_version>3.1</schema_version>
|
4
4
|
<name>improve_fan_belt_efficiency</name>
|
5
5
|
<uid>ebeca0aa-a432-4283-a714-17116f7c8f8c</uid>
|
6
|
-
<version_id>
|
7
|
-
<version_modified>2025-
|
6
|
+
<version_id>b8f329e9-87df-4d83-96b2-9358e169a121</version_id>
|
7
|
+
<version_modified>2025-09-25T15:33:44Z</version_modified>
|
8
8
|
<xml_checksum>F78494F2</xml_checksum>
|
9
9
|
<class_name>ImproveFanBeltEfficiency</class_name>
|
10
10
|
<display_name>Improve Fan Belt Efficiency</display_name>
|
@@ -47,10 +47,10 @@ Well-adjusted belts run cooler, last longer, and operate at higher efficiency th
|
|
47
47
|
<type>Choice</type>
|
48
48
|
<required>true</required>
|
49
49
|
<model_dependent>false</model_dependent>
|
50
|
-
<default_value>{
|
50
|
+
<default_value>{eb63161e-e882-4957-a540-b6e7bb7abfd4}</default_value>
|
51
51
|
<choices>
|
52
52
|
<choice>
|
53
|
-
<value>{
|
53
|
+
<value>{eb63161e-e882-4957-a540-b6e7bb7abfd4}</value>
|
54
54
|
<display_name>*All Air Loops*</display_name>
|
55
55
|
</choice>
|
56
56
|
</choices>
|
@@ -193,7 +193,7 @@ Well-adjusted belts run cooler, last longer, and operate at higher efficiency th
|
|
193
193
|
<filename>measure.rb</filename>
|
194
194
|
<filetype>rb</filetype>
|
195
195
|
<usage_type>script</usage_type>
|
196
|
-
<checksum>
|
196
|
+
<checksum>1691AE3F</checksum>
|
197
197
|
</file>
|
198
198
|
<file>
|
199
199
|
<filename>0320_ModelWithHVAC_01.osm</filename>
|
@@ -205,7 +205,7 @@ Well-adjusted belts run cooler, last longer, and operate at higher efficiency th
|
|
205
205
|
<filename>ImproveFanBeltEfficiency_Test.rb</filename>
|
206
206
|
<filetype>rb</filetype>
|
207
207
|
<usage_type>test</usage_type>
|
208
|
-
<checksum>
|
208
|
+
<checksum>19994729</checksum>
|
209
209
|
</file>
|
210
210
|
</files>
|
211
211
|
</measure>
|
@@ -10,7 +10,7 @@ class ImproveMotorEfficiency < OpenStudio::Measure::ModelMeasure
|
|
10
10
|
# define the name that a user will see, this method may be deprecated as
|
11
11
|
# the display name in PAT comes from the name field in measure.xml
|
12
12
|
def name
|
13
|
-
|
13
|
+
'Improve Motor Efficiency in Selected Fans and Pumps'
|
14
14
|
end
|
15
15
|
|
16
16
|
# define the arguments that the user will input
|
@@ -33,21 +33,11 @@ class ImproveMotorEfficiency < OpenStudio::Measure::ModelMeasure
|
|
33
33
|
show_loop = false
|
34
34
|
components = value.supplyComponents
|
35
35
|
components.each do |component|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
42
|
-
if !component.to_FanOnOff.empty?
|
43
|
-
show_loop = true
|
44
|
-
end
|
45
|
-
if !component.to_PumpConstantSpeed.empty?
|
46
|
-
show_loop = true
|
47
|
-
end
|
48
|
-
if !component.to_PumpVariableSpeed.empty?
|
49
|
-
show_loop = true
|
50
|
-
end
|
36
|
+
show_loop = true unless component.to_FanConstantVolume.empty?
|
37
|
+
show_loop = true unless component.to_FanVariableVolume.empty?
|
38
|
+
show_loop = true unless component.to_FanOnOff.empty?
|
39
|
+
show_loop = true unless component.to_PumpConstantSpeed.empty?
|
40
|
+
show_loop = true unless component.to_PumpVariableSpeed.empty?
|
51
41
|
end
|
52
42
|
|
53
43
|
# if loop as object of correct type then add to hash.
|
@@ -122,7 +112,7 @@ class ImproveMotorEfficiency < OpenStudio::Measure::ModelMeasure
|
|
122
112
|
om_frequency.setDefaultValue(1)
|
123
113
|
args << om_frequency
|
124
114
|
|
125
|
-
|
115
|
+
args
|
126
116
|
end
|
127
117
|
|
128
118
|
# define what happens when the measure is cop
|
@@ -130,9 +120,7 @@ class ImproveMotorEfficiency < OpenStudio::Measure::ModelMeasure
|
|
130
120
|
super(model, runner, user_arguments)
|
131
121
|
|
132
122
|
# use the built-in error checking
|
133
|
-
|
134
|
-
return false
|
135
|
-
end
|
123
|
+
return false unless runner.validateUserArguments(arguments(model), user_arguments)
|
136
124
|
|
137
125
|
# assign the user inputs to variables
|
138
126
|
object = runner.getOptionalWorkspaceObjectChoiceValue('object', user_arguments, model) # model is passed in because of argument type
|
@@ -157,15 +145,13 @@ class ImproveMotorEfficiency < OpenStudio::Measure::ModelMeasure
|
|
157
145
|
runner.registerError("The selected loop with handle '#{handle}' was not found in the model. It may have been removed by another measure.")
|
158
146
|
end
|
159
147
|
return false
|
148
|
+
elsif !object.get.to_Loop.empty?
|
149
|
+
loop = object.get.to_Loop.get
|
150
|
+
elsif !object.get.to_Building.empty?
|
151
|
+
apply_to_all_loops = true
|
160
152
|
else
|
161
|
-
|
162
|
-
|
163
|
-
elsif !object.get.to_Building.empty?
|
164
|
-
apply_to_all_loops = true
|
165
|
-
else
|
166
|
-
runner.registerError('Script Error - argument not showing up as loop.')
|
167
|
-
return false
|
168
|
-
end
|
153
|
+
runner.registerError('Script Error - argument not showing up as loop.')
|
154
|
+
return false
|
169
155
|
end
|
170
156
|
|
171
157
|
# check the user_name for reasonableness
|
@@ -198,17 +184,15 @@ class ImproveMotorEfficiency < OpenStudio::Measure::ModelMeasure
|
|
198
184
|
if (expected_life < 1) && (expected_life > 100)
|
199
185
|
runner.registerError('Choose an integer greater than 0 and less than or equal to 100 for Expected Life.')
|
200
186
|
end
|
201
|
-
if om_frequency < 1
|
202
|
-
runner.registerError('Choose an integer greater than 0 for O & M Frequency.')
|
203
|
-
end
|
187
|
+
runner.registerError('Choose an integer greater than 0 for O & M Frequency.') if om_frequency < 1
|
204
188
|
|
205
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
|
206
190
|
def neat_numbers(number, roundto = 2) # round to 0 or 2)
|
207
|
-
if roundto == 2
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
191
|
+
number = if roundto == 2
|
192
|
+
format '%.2f', number
|
193
|
+
else
|
194
|
+
number.round
|
195
|
+
end
|
212
196
|
# regex to add commas
|
213
197
|
number.to_s.reverse.gsub(/([0-9]{3}(?=([0-9])))/, '\\1,').reverse
|
214
198
|
end
|
@@ -219,14 +203,12 @@ class ImproveMotorEfficiency < OpenStudio::Measure::ModelMeasure
|
|
219
203
|
objects.each do |object|
|
220
204
|
object_LCCs = object.lifeCycleCosts
|
221
205
|
object_LCCs.each do |object_LCC|
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
end
|
226
|
-
end
|
206
|
+
next unless (object_LCC.category == 'Construction') || (object_LCC.category == 'Salvage')
|
207
|
+
|
208
|
+
counter += object_LCC.totalCost if object_LCC.yearsFromStart == 0
|
227
209
|
end
|
228
210
|
end
|
229
|
-
|
211
|
+
counter
|
230
212
|
end
|
231
213
|
|
232
214
|
# get loops for measure
|
@@ -248,61 +230,51 @@ class ImproveMotorEfficiency < OpenStudio::Measure::ModelMeasure
|
|
248
230
|
# find fans and pumps on loop
|
249
231
|
supply_components.each do |supply_component|
|
250
232
|
hVACComponent = supply_component.to_FanConstantVolume
|
251
|
-
if hVACComponent.empty?
|
252
|
-
|
253
|
-
|
254
|
-
if hVACComponent.empty?
|
255
|
-
hVACComponent = supply_component.to_FanOnOff
|
256
|
-
end
|
257
|
-
if hVACComponent.empty?
|
258
|
-
hVACComponent = supply_component.to_PumpConstantSpeed
|
259
|
-
end
|
260
|
-
if hVACComponent.empty?
|
261
|
-
hVACComponent = supply_component.to_PumpVariableSpeed
|
262
|
-
end
|
233
|
+
hVACComponent = supply_component.to_FanVariableVolume if hVACComponent.empty?
|
234
|
+
hVACComponent = supply_component.to_FanOnOff if hVACComponent.empty?
|
235
|
+
hVACComponent = supply_component.to_PumpConstantSpeed if hVACComponent.empty?
|
236
|
+
hVACComponent = supply_component.to_PumpVariableSpeed if hVACComponent.empty?
|
263
237
|
|
264
238
|
# alter components of correct type
|
265
|
-
if
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
# demo value of baseline costs associated with unit
|
278
|
-
demo_LCCs = hVACComponent.lifeCycleCosts
|
279
|
-
demo_LCCs.each do |demo_LCC|
|
280
|
-
if demo_LCC.category == 'Salvage'
|
281
|
-
demo_costs_of_baseline_objects += demo_LCC.totalCost
|
282
|
-
end
|
283
|
-
end
|
284
|
-
|
285
|
-
# remove all old costs
|
286
|
-
if !hVACComponent.lifeCycleCosts.empty? && (remove_costs == true)
|
287
|
-
runner.registerInfo("Removing existing lifecycle cost objects associated with #{hVACComponent.name}")
|
288
|
-
removed_costs = hVACComponent.removeLifeCycleCosts
|
289
|
-
end
|
290
|
-
|
291
|
-
# add new costs
|
292
|
-
if costs_requested == true
|
293
|
-
|
294
|
-
# adding new cost items
|
295
|
-
lcc_mat = OpenStudio::Model::LifeCycleCost.createLifeCycleCost("LCC_Mat - #{hVACComponent.name}", hVACComponent, material_cost, 'CostPerEach', 'Construction', expected_life, years_until_costs_start)
|
296
|
-
# cost for if demo_initial_Construction == true is added at the end of the measure
|
297
|
-
lcc_demo = OpenStudio::Model::LifeCycleCost.createLifeCycleCost("LCC_Demo - #{hVACComponent.name}", hVACComponent, demolition_cost, 'CostPerEach', 'Salvage', expected_life, years_until_costs_start + expected_life)
|
298
|
-
lcc_om = OpenStudio::Model::LifeCycleCost.createLifeCycleCost("LCC_OM - #{hVACComponent.name}", hVACComponent, om_cost, 'CostPerEach', 'Maintenance', om_frequency, 0)
|
299
|
-
|
300
|
-
# get final year 0 cost
|
301
|
-
yr0_capital_totalCosts_proposed += get_total_costs_for_objects([hVACComponent])
|
302
|
-
|
303
|
-
end
|
239
|
+
next if hVACComponent.empty?
|
240
|
+
|
241
|
+
hVACComponent = hVACComponent.get
|
242
|
+
|
243
|
+
# change and report changes to fans and motors
|
244
|
+
initial_motor_efficiency = hVACComponent.motorEfficiency
|
245
|
+
runner.registerInfo("Changing the motor efficiency from #{initial_motor_efficiency * 100}% to #{motor_eff}% for '#{hVACComponent.name}' onloop '#{loop.name}.'")
|
246
|
+
initial_motor_efficiency_values << initial_motor_efficiency
|
247
|
+
hVACComponent.setMotorEfficiency(motor_eff * 0.01)
|
248
|
+
|
249
|
+
# get initial year 0 cost
|
250
|
+
yr0_capital_totalCosts_baseline += get_total_costs_for_objects([hVACComponent])
|
304
251
|
|
252
|
+
# demo value of baseline costs associated with unit
|
253
|
+
demo_LCCs = hVACComponent.lifeCycleCosts
|
254
|
+
demo_LCCs.each do |demo_LCC|
|
255
|
+
demo_costs_of_baseline_objects += demo_LCC.totalCost if demo_LCC.category == 'Salvage'
|
305
256
|
end
|
257
|
+
|
258
|
+
# remove all old costs
|
259
|
+
if !hVACComponent.lifeCycleCosts.empty? && (remove_costs == true)
|
260
|
+
runner.registerInfo("Removing existing lifecycle cost objects associated with #{hVACComponent.name}")
|
261
|
+
removed_costs = hVACComponent.removeLifeCycleCosts
|
262
|
+
end
|
263
|
+
|
264
|
+
# add new costs
|
265
|
+
next unless costs_requested == true
|
266
|
+
|
267
|
+
# adding new cost items
|
268
|
+
lcc_mat = OpenStudio::Model::LifeCycleCost.createLifeCycleCost("LCC_Mat - #{hVACComponent.name}",
|
269
|
+
hVACComponent, material_cost, 'CostPerEach', 'Construction', expected_life, years_until_costs_start)
|
270
|
+
# cost for if demo_initial_Construction == true is added at the end of the measure
|
271
|
+
lcc_demo = OpenStudio::Model::LifeCycleCost.createLifeCycleCost("LCC_Demo - #{hVACComponent.name}",
|
272
|
+
hVACComponent, demolition_cost, 'CostPerEach', 'Salvage', expected_life, years_until_costs_start + expected_life)
|
273
|
+
lcc_om = OpenStudio::Model::LifeCycleCost.createLifeCycleCost("LCC_OM - #{hVACComponent.name}",
|
274
|
+
hVACComponent, om_cost, 'CostPerEach', 'Maintenance', om_frequency, 0)
|
275
|
+
|
276
|
+
# get final year 0 cost
|
277
|
+
yr0_capital_totalCosts_proposed += get_total_costs_for_objects([hVACComponent])
|
306
278
|
end
|
307
279
|
end
|
308
280
|
|
@@ -310,12 +282,11 @@ class ImproveMotorEfficiency < OpenStudio::Measure::ModelMeasure
|
|
310
282
|
if demo_cost_initial_const == true
|
311
283
|
building = model.getBuilding
|
312
284
|
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.
|
313
|
-
runner.registerInfo("Adding one time cost of $#{neat_numbers(lcc_baseline_demo.totalCost,
|
285
|
+
runner.registerInfo("Adding one time cost of $#{neat_numbers(lcc_baseline_demo.totalCost,
|
286
|
+
0)} related to demolition of baseline objects.")
|
314
287
|
|
315
288
|
# if demo occurs on year 0 then add to initial capital cost counter
|
316
|
-
if lcc_baseline_demo.yearsFromStart == 0
|
317
|
-
yr0_capital_totalCosts_proposed += lcc_baseline_demo.totalCost
|
318
|
-
end
|
289
|
+
yr0_capital_totalCosts_proposed += lcc_baseline_demo.totalCost if lcc_baseline_demo.yearsFromStart == 0
|
319
290
|
end
|
320
291
|
|
321
292
|
if initial_motor_efficiency_values.size + missing_initial_motor_efficiency == 0
|
@@ -324,12 +295,16 @@ class ImproveMotorEfficiency < OpenStudio::Measure::ModelMeasure
|
|
324
295
|
end
|
325
296
|
|
326
297
|
# reporting initial condition of model
|
327
|
-
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 or pumps is $#{neat_numbers(
|
298
|
+
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 or pumps is $#{neat_numbers(
|
299
|
+
yr0_capital_totalCosts_baseline, 0
|
300
|
+
)}.")
|
328
301
|
|
329
302
|
# reporting final condition of model
|
330
|
-
runner.registerFinalCondition("#{initial_motor_efficiency_values.size + missing_initial_motor_efficiency} fans or pumps had motor efficiency values set to #{motor_eff}%. Final year 0 capital costs for affected fans and pumps is $#{neat_numbers(
|
303
|
+
runner.registerFinalCondition("#{initial_motor_efficiency_values.size + missing_initial_motor_efficiency} fans or pumps had motor efficiency values set to #{motor_eff}%. Final year 0 capital costs for affected fans and pumps is $#{neat_numbers(
|
304
|
+
yr0_capital_totalCosts_proposed, 0
|
305
|
+
)}.")
|
331
306
|
|
332
|
-
|
307
|
+
true
|
333
308
|
end
|
334
309
|
end
|
335
310
|
|
@@ -3,8 +3,8 @@
|
|
3
3
|
<schema_version>3.1</schema_version>
|
4
4
|
<name>improve_motor_efficiency</name>
|
5
5
|
<uid>52013ba9-7b9b-4ffd-bc67-d4c0fa05d7ae</uid>
|
6
|
-
<version_id>
|
7
|
-
<version_modified>2025-
|
6
|
+
<version_id>b489d3b7-146d-4ef3-95b3-02fbed79c46b</version_id>
|
7
|
+
<version_modified>2025-09-25T15:33:44Z</version_modified>
|
8
8
|
<xml_checksum>F78494F2</xml_checksum>
|
9
9
|
<class_name>ImproveMotorEfficiency</class_name>
|
10
10
|
<display_name>Improve Motor Efficiency in Selected Fans and Pumps</display_name>
|
@@ -31,10 +31,10 @@ The cost arguments are user arguments that start with a default of $0. Operation
|
|
31
31
|
<type>Choice</type>
|
32
32
|
<required>true</required>
|
33
33
|
<model_dependent>false</model_dependent>
|
34
|
-
<default_value>{
|
34
|
+
<default_value>{477f3286-308d-43c0-8e7f-483284eb60d1}</default_value>
|
35
35
|
<choices>
|
36
36
|
<choice>
|
37
|
-
<value>{
|
37
|
+
<value>{477f3286-308d-43c0-8e7f-483284eb60d1}</value>
|
38
38
|
<display_name>*All Plant and Air Loops*</display_name>
|
39
39
|
</choice>
|
40
40
|
</choices>
|
@@ -177,7 +177,7 @@ The cost arguments are user arguments that start with a default of $0. Operation
|
|
177
177
|
<filename>measure.rb</filename>
|
178
178
|
<filetype>rb</filetype>
|
179
179
|
<usage_type>script</usage_type>
|
180
|
-
<checksum>
|
180
|
+
<checksum>09B3E503</checksum>
|
181
181
|
</file>
|
182
182
|
<file>
|
183
183
|
<filename>0320_ModelWithHVAC_01.osm</filename>
|
@@ -189,7 +189,7 @@ The cost arguments are user arguments that start with a default of $0. Operation
|
|
189
189
|
<filename>ImproveMotorEfficiency_Test.rb</filename>
|
190
190
|
<filetype>rb</filetype>
|
191
191
|
<usage_type>test</usage_type>
|
192
|
-
<checksum>
|
192
|
+
<checksum>E64A2125</checksum>
|
193
193
|
</file>
|
194
194
|
</files>
|
195
195
|
</measure>
|