openstudio-ee 0.12.3 → 0.12.4

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.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.coverage +0 -0
  3. data/.github/workflows/test-with-openstudio.yml +109 -74
  4. data/.gitignore +21 -0
  5. data/.rubocop.yml +15 -2
  6. data/CHANGELOG.md +3 -0
  7. data/Gemfile +7 -8
  8. data/README.md +1 -0
  9. data/WORKFLOW_CHANGES.md +74 -0
  10. data/lib/measures/AddDaylightSensors/measure.rb +79 -79
  11. data/lib/measures/AddDaylightSensors/measure.xml +4 -4
  12. data/lib/measures/AddOverhangsByProjectionFactor/measure.rb +38 -41
  13. data/lib/measures/AddOverhangsByProjectionFactor/measure.xml +4 -4
  14. data/lib/measures/EnableDemandControlledVentilation/measure.rb +37 -40
  15. data/lib/measures/EnableDemandControlledVentilation/measure.xml +4 -4
  16. data/lib/measures/EnableEconomizerControl/measure.rb +36 -37
  17. data/lib/measures/EnableEconomizerControl/measure.xml +4 -4
  18. data/lib/measures/GLHEProExportLoadsforGroundHeatExchangerSizing/measure.rb +27 -41
  19. data/lib/measures/GLHEProExportLoadsforGroundHeatExchangerSizing/measure.xml +4 -4
  20. data/lib/measures/GLHEProGFunctionImport/measure.rb +11 -15
  21. data/lib/measures/GLHEProGFunctionImport/measure.xml +4 -4
  22. data/lib/measures/GLHEProSetupExportLoadsforGroundHeatExchangerSizing/measure.rb +5 -9
  23. data/lib/measures/GLHEProSetupExportLoadsforGroundHeatExchangerSizing/measure.xml +3 -3
  24. data/lib/measures/ImproveFanBeltEfficiency/measure.rb +78 -95
  25. data/lib/measures/ImproveFanBeltEfficiency/measure.xml +6 -6
  26. data/lib/measures/ImproveMotorEfficiency/measure.rb +75 -100
  27. data/lib/measures/ImproveMotorEfficiency/measure.xml +6 -6
  28. data/lib/measures/IncreaseInsulationRValueForExteriorWalls/measure.rb +137 -130
  29. data/lib/measures/IncreaseInsulationRValueForExteriorWalls/measure.xml +4 -4
  30. data/lib/measures/IncreaseInsulationRValueForExteriorWallsByPercentage/measure.rb +114 -115
  31. data/lib/measures/IncreaseInsulationRValueForExteriorWallsByPercentage/measure.xml +3 -3
  32. data/lib/measures/IncreaseInsulationRValueForRoofs/measure.rb +137 -130
  33. data/lib/measures/IncreaseInsulationRValueForRoofs/measure.xml +4 -4
  34. data/lib/measures/IncreaseInsulationRValueForRoofsByPercentage/measure.rb +114 -115
  35. data/lib/measures/IncreaseInsulationRValueForRoofsByPercentage/measure.xml +3 -3
  36. data/lib/measures/ReduceElectricEquipmentLoadsByPercentage/measure.rb +69 -63
  37. data/lib/measures/ReduceElectricEquipmentLoadsByPercentage/measure.xml +6 -6
  38. data/lib/measures/ReduceLightingLoadsByPercentage/measure.rb +77 -66
  39. data/lib/measures/ReduceLightingLoadsByPercentage/measure.xml +6 -6
  40. data/lib/measures/ReduceNightTimeElectricEquipmentLoads/measure.rb +45 -43
  41. data/lib/measures/ReduceNightTimeElectricEquipmentLoads/measure.xml +4 -4
  42. data/lib/measures/ReduceNightTimeLightingLoads/measure.rb +45 -43
  43. data/lib/measures/ReduceNightTimeLightingLoads/measure.xml +4 -4
  44. data/lib/measures/ReduceSpaceInfiltrationByPercentage/measure.rb +58 -52
  45. data/lib/measures/ReduceSpaceInfiltrationByPercentage/measure.xml +6 -6
  46. data/lib/measures/ReduceVentilationByPercentage/measure.rb +49 -46
  47. data/lib/measures/ReduceVentilationByPercentage/measure.xml +6 -6
  48. data/lib/measures/add_variable_speed_rtu_control_logic/measure.rb +31 -23
  49. data/lib/measures/add_variable_speed_rtu_control_logic/measure.xml +4 -4
  50. data/lib/measures/create_variable_speed_rtu/measure.rb +166 -174
  51. data/lib/measures/create_variable_speed_rtu/measure.xml +6 -6
  52. data/lib/measures/fan_assist_night_ventilation/measure.rb +33 -32
  53. data/lib/measures/fan_assist_night_ventilation/measure.xml +4 -4
  54. data/lib/measures/nze_hvac/measure.rb +72 -62
  55. data/lib/measures/nze_hvac/measure.xml +4 -4
  56. data/lib/measures/replace_water_heater_mixed_with_thermal_storage_chilled_water/measure.rb +16 -19
  57. data/lib/measures/replace_water_heater_mixed_with_thermal_storage_chilled_water/measure.xml +4 -4
  58. data/lib/measures/window_enhancement/LICENSE.md +14 -0
  59. data/lib/measures/window_enhancement/README.md +112 -0
  60. data/lib/measures/window_enhancement/docs/.gitkeep +0 -0
  61. data/lib/measures/window_enhancement/measure.py +386 -0
  62. data/lib/measures/window_enhancement/measure.xml +128 -0
  63. data/lib/measures/window_enhancement/resources/EC3_lookup.py +321 -0
  64. data/lib/measures/window_enhancement/resources/Test_API.py +32 -0
  65. data/lib/measures/window_enhancement/resources/__pycache__/EC3_lookup.cpython-39.pyc +0 -0
  66. data/lib/measures/window_enhancement/resources/__pycache__/Original_EC3_lookup.py +322 -0
  67. data/lib/measures/window_enhancement/resources/__pycache__/Test_API.cpython-39.pyc +0 -0
  68. data/lib/measures/window_enhancement/resources/calculate_perimeter.py +39 -0
  69. data/lib/measures/window_enhancement/test_output.log +39 -0
  70. data/lib/openstudio/ee_measures/version.rb +1 -1
  71. data/openstudio-ee.gemspec +10 -8
  72. data/test-workflow-locally.sh +152 -0
  73. metadata +64 -35
  74. data/Jenkinsfile +0 -11
@@ -9,11 +9,11 @@
9
9
  class IncreaseInsulationRValueForExteriorWalls < OpenStudio::Measure::ModelMeasure
10
10
  # define the name that a user will see
11
11
  def name
12
- return 'Increase R-value of Insulation for Exterior Walls to a Specific Value'
12
+ 'Increase R-value of Insulation for Exterior Walls to a Specific Value'
13
13
  end
14
14
 
15
15
  # define the arguments that the user will input
16
- def arguments(model)
16
+ def arguments(_model)
17
17
  args = OpenStudio::Measure::OSArgumentVector.new
18
18
 
19
19
  # make an argument insulation R-value
@@ -46,7 +46,7 @@ class IncreaseInsulationRValueForExteriorWalls < OpenStudio::Measure::ModelMeasu
46
46
  years_until_retrofit_cost.setDefaultValue(0)
47
47
  args << years_until_retrofit_cost
48
48
 
49
- return args
49
+ args
50
50
  end
51
51
 
52
52
  # define what happens when the measure is run
@@ -54,9 +54,7 @@ class IncreaseInsulationRValueForExteriorWalls < OpenStudio::Measure::ModelMeasu
54
54
  super(model, runner, user_arguments)
55
55
 
56
56
  # use the built-in error checking
57
- if !runner.validateUserArguments(arguments(model), user_arguments)
58
- return false
59
- end
57
+ return false unless runner.validateUserArguments(arguments(model), user_arguments)
60
58
 
61
59
  # assign the user inputs to variables
62
60
  r_value = runner.getDoubleArgumentValue('r_value', user_arguments)
@@ -85,18 +83,21 @@ class IncreaseInsulationRValueForExteriorWalls < OpenStudio::Measure::ModelMeasu
85
83
 
86
84
  # 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
87
85
  def neat_numbers(number, roundto = 2) # round to 0 or 2)
88
- if roundto == 2
89
- number = format '%.2f', number
90
- else
91
- number = number.round
92
- end
86
+ number = if roundto == 2
87
+ format '%.2f', number
88
+ else
89
+ number.round
90
+ end
93
91
  # regex to add commas
94
92
  number.to_s.reverse.gsub(/([0-9]{3}(?=([0-9])))/, '\\1,').reverse
95
93
  end
96
94
 
97
95
  # helper to make it easier to do unit conversions on the fly
98
96
  def unit_helper(number, from_unit_string, to_unit_string)
99
- converted_number = OpenStudio.convert(OpenStudio::Quantity.new(number, OpenStudio.createUnit(from_unit_string).get), OpenStudio.createUnit(to_unit_string).get).get.value
97
+ converted_number = OpenStudio.convert(
98
+ OpenStudio::Quantity.new(number,
99
+ OpenStudio.createUnit(from_unit_string).get), OpenStudio.createUnit(to_unit_string).get
100
+ ).get.value
100
101
  end
101
102
 
102
103
  # convert r_value and material_cost to si for future use
@@ -110,16 +111,16 @@ class IncreaseInsulationRValueForExteriorWalls < OpenStudio::Measure::ModelMeasu
110
111
  exterior_surface_construction_names = []
111
112
  ext_wall_resistance = []
112
113
  surfaces.each do |surface|
113
- if (surface.outsideBoundaryCondition == 'Outdoors') && (surface.surfaceType == 'Wall')
114
- exterior_surfaces << surface
115
- ext_wall_const = surface.construction.get
116
- # only add construction if it hasn't been added yet
117
- if !exterior_surface_construction_names.include?(ext_wall_const.name.to_s)
118
- exterior_surface_constructions << ext_wall_const.to_Construction.get
119
- end
120
- exterior_surface_construction_names << ext_wall_const.name.to_s
121
- ext_wall_resistance << 1 / ext_wall_const.thermalConductance.to_f
114
+ next unless (surface.outsideBoundaryCondition == 'Outdoors') && (surface.surfaceType == 'Wall')
115
+
116
+ exterior_surfaces << surface
117
+ ext_wall_const = surface.construction.get
118
+ # only add construction if it hasn't been added yet
119
+ unless exterior_surface_construction_names.include?(ext_wall_const.name.to_s)
120
+ exterior_surface_constructions << ext_wall_const.to_Construction.get
122
121
  end
122
+ exterior_surface_construction_names << ext_wall_const.name.to_s
123
+ ext_wall_resistance << (1 / ext_wall_const.thermalConductance.to_f)
123
124
  end
124
125
 
125
126
  # nothing will be done if there are no exterior surfaces
@@ -132,8 +133,9 @@ class IncreaseInsulationRValueForExteriorWalls < OpenStudio::Measure::ModelMeasu
132
133
  initial_string = []
133
134
  exterior_surface_constructions.uniq.each do |exterior_surface_construction|
134
135
  # unit conversion of wall insulation from SI units (M^2*K/W) to IP units (ft^2*h*R/Btu)
135
- initial_conductance_ip = unit_helper(1 / exterior_surface_construction.thermalConductance.to_f, 'm^2*K/W', 'ft^2*h*R/Btu')
136
- initial_string << "#{exterior_surface_construction.name} (R-#{(format '%.1f', initial_conductance_ip)})"
136
+ initial_conductance_ip = unit_helper(1 / exterior_surface_construction.thermalConductance.to_f, 'm^2*K/W',
137
+ 'ft^2*h*R/Btu')
138
+ initial_string << "#{exterior_surface_construction.name} (R-#{format '%.1f', initial_conductance_ip})"
137
139
  end
138
140
  runner.registerInitialCondition("The building had #{initial_string.size} exterior wall constructions: #{initial_string.sort.join(', ')}.")
139
141
 
@@ -161,14 +163,16 @@ class IncreaseInsulationRValueForExteriorWalls < OpenStudio::Measure::ModelMeasu
161
163
  no_mass_materials = materials_in_construction.select { |mat| mat['nomass'] == true }
162
164
  # measure will select the no mass material with the highest r-value as the insulation layer
163
165
  # if no mass materials are present, the measure will select the material with the highest r-value per inch
164
- if !no_mass_materials.empty?
165
- thermal_resistance_values = no_mass_materials.map { |mat| mat['r_value'] }
166
- max_mat_hash = no_mass_materials.select { |mat| mat['r_value'] >= thermal_resistance_values.max }
167
- else
168
- thermal_resistance_per_thickness_values = materials_in_construction.map { |mat| mat['r_value'] / mat['mat'].thickness }
166
+ if no_mass_materials.empty?
167
+ thermal_resistance_per_thickness_values = materials_in_construction.map do |mat|
168
+ mat['r_value'] / mat['mat'].thickness
169
+ end
169
170
  target_index = thermal_resistance_per_thickness_values.index(thermal_resistance_per_thickness_values.max)
170
171
  max_mat_hash = materials_in_construction.select { |mat| mat['index'] == target_index }
171
172
  thermal_resistance_values = materials_in_construction.map { |mat| mat['r_value'] }
173
+ else
174
+ thermal_resistance_values = no_mass_materials.map { |mat| mat['r_value'] }
175
+ max_mat_hash = no_mass_materials.select { |mat| mat['r_value'] >= thermal_resistance_values.max }
172
176
  end
173
177
  max_thermal_resistance_material = max_mat_hash[0]['mat']
174
178
  max_thermal_resistance_material_index = max_mat_hash[0]['index']
@@ -191,33 +195,39 @@ class IncreaseInsulationRValueForExteriorWalls < OpenStudio::Measure::ModelMeasu
191
195
  const_LCC_cat_const = false
192
196
  updated_cost_si = 0
193
197
  const_LCCs.each do |const_LCC|
194
- if (const_LCC.category == 'Construction') && (material_cost_increase_si != 0)
195
- const_LCC_cat_const = true # need this test to add proper lcc if it didn't exist to start with
196
- # if multiple LCC objects associated with construction only adjust the cost of one of them.
197
- if !cost_added
198
- const_LCC.setCost(const_LCC.cost + material_cost_increase_si)
199
- else
200
- runner.registerInfo("More than one LifeCycleCost object with a category of Construction was associated with #{final_construction.name}. Cost was only adjusted for one of the LifeCycleCost objects.")
201
- end
202
- updated_cost_si += const_LCC.cost
198
+ next unless (const_LCC.category == 'Construction') && (material_cost_increase_si != 0)
199
+
200
+ const_LCC_cat_const = true # need this test to add proper lcc if it didn't exist to start with
201
+ # if multiple LCC objects associated with construction only adjust the cost of one of them.
202
+ if cost_added
203
+ runner.registerInfo("More than one LifeCycleCost object with a category of Construction was associated with #{final_construction.name}. Cost was only adjusted for one of the LifeCycleCost objects.")
204
+ else
205
+ const_LCC.setCost(const_LCC.cost + material_cost_increase_si)
203
206
  end
207
+ updated_cost_si += const_LCC.cost
204
208
  end
205
209
 
206
210
  if cost_added
207
- runner.registerInfo("Adjusting material and installation cost for #{final_construction.name} to #{neat_numbers(unit_helper(updated_cost_si, '1/m^2', '1/ft^2'))} ($/ft^2).")
211
+ runner.registerInfo("Adjusting material and installation cost for #{final_construction.name} to #{neat_numbers(unit_helper(
212
+ updated_cost_si, '1/m^2', '1/ft^2'
213
+ ))} ($/ft^2).")
208
214
  end
209
215
 
210
216
  # add construction object if it didnt exist to start with and a cost increase was requested
211
217
  if (const_LCC_cat_const == false) && (material_cost_increase_si != 0)
212
- lcc_for_uncosted_const = OpenStudio::Model::LifeCycleCost.createLifeCycleCost('LCC_increase_insulation', final_construction, material_cost_increase_si, 'CostPerArea', 'Construction', 20, 0).get
213
- runner.registerInfo("No material or installation costs existed for #{final_construction.name}. Created a new LifeCycleCost object with a material and installation cost of #{neat_numbers(unit_helper(lcc_for_uncosted_const.cost, '1/m^2', '1/ft^2'))} ($/ft^2). Assumed capitol cost in first year, an expected life of 20 years, and no O & M costs.")
218
+ lcc_for_uncosted_const = OpenStudio::Model::LifeCycleCost.createLifeCycleCost('LCC_increase_insulation',
219
+ final_construction, material_cost_increase_si, 'CostPerArea', 'Construction', 20, 0).get
220
+ runner.registerInfo("No material or installation costs existed for #{final_construction.name}. Created a new LifeCycleCost object with a material and installation cost of #{neat_numbers(unit_helper(
221
+ lcc_for_uncosted_const.cost, '1/m^2', '1/ft^2'
222
+ ))} ($/ft^2). Assumed capitol cost in first year, an expected life of 20 years, and no O & M costs.")
214
223
  end
215
224
 
216
225
  # add one time cost if requested
217
226
  if one_time_retrofit_cost_ip > 0
218
227
  one_time_retrofit_cost_si = unit_helper(one_time_retrofit_cost_ip, '1/ft^2', '1/m^2')
219
228
  lcc_retrofit_specific = OpenStudio::Model::LifeCycleCost.createLifeCycleCost('LCC_retrofit_specific', final_construction, one_time_retrofit_cost_si, 'CostPerArea', 'Construction', 0, years_until_retrofit_cost).get # using 0 for repeat period since one time cost.
220
- runner.registerInfo("Adding one time cost of #{neat_numbers(unit_helper(lcc_retrofit_specific.cost, '1/m^2', '1/ft^2'))} ($/ft^2) related to retrofit of wall insulation.")
229
+ runner.registerInfo("Adding one time cost of #{neat_numbers(unit_helper(lcc_retrofit_specific.cost, '1/m^2',
230
+ '1/ft^2'))} ($/ft^2) related to retrofit of wall insulation.")
221
231
  end
222
232
 
223
233
  # push to hashes
@@ -228,13 +238,13 @@ class IncreaseInsulationRValueForExteriorWalls < OpenStudio::Measure::ModelMeasu
228
238
  target_material = max_thermal_resistance_material
229
239
  found_material = false
230
240
  materials_hash.each do |orig, new|
231
- if target_material.name.to_s == orig
232
- new_material = new
233
- materials_hash[max_thermal_resistance_material.name.to_s] = new_material
234
- final_construction.eraseLayer(max_thermal_resistance_material_index)
235
- final_construction.insertLayer(max_thermal_resistance_material_index, new_material)
236
- found_material = true
237
- end
241
+ next unless target_material.name.to_s == orig
242
+
243
+ new_material = new
244
+ materials_hash[max_thermal_resistance_material.name.to_s] = new_material
245
+ final_construction.eraseLayer(max_thermal_resistance_material_index)
246
+ final_construction.insertLayer(max_thermal_resistance_material_index, new_material)
247
+ found_material = true
238
248
  end
239
249
 
240
250
  # clone and edit insulation material and link to construction
@@ -249,17 +259,17 @@ class IncreaseInsulationRValueForExteriorWalls < OpenStudio::Measure::ModelMeasu
249
259
 
250
260
  # edit insulation material
251
261
  new_material_matt = new_material.to_Material
252
- if !new_material_matt.empty?
262
+ unless new_material_matt.empty?
253
263
  starting_thickness = new_material_matt.get.thickness
254
264
  target_thickness = starting_thickness * r_value_si / thermal_resistance_values.max
255
265
  final_thickness = new_material_matt.get.setThickness(target_thickness)
256
266
  end
257
267
  new_material_massless = new_material.to_MasslessOpaqueMaterial
258
- if !new_material_massless.empty?
268
+ unless new_material_massless.empty?
259
269
  final_thermal_resistance = new_material_massless.get.setThermalResistance(r_value_si)
260
270
  end
261
271
  new_material_airgap = new_material.to_AirGap
262
- if !new_material_airgap.empty?
272
+ unless new_material_airgap.empty?
263
273
  final_thermal_resistance = new_material_airgap.get.setThermalResistance(r_value_si)
264
274
  end
265
275
  end
@@ -269,85 +279,82 @@ class IncreaseInsulationRValueForExteriorWalls < OpenStudio::Measure::ModelMeasu
269
279
  # loop through construction sets used in the model
270
280
  default_construction_sets = model.getDefaultConstructionSets
271
281
  default_construction_sets.each do |default_construction_set|
272
- if default_construction_set.directUseCount > 0
273
- default_surface_const_set = default_construction_set.defaultExteriorSurfaceConstructions
274
- if !default_surface_const_set.empty?
275
- starting_construction = default_surface_const_set.get.wallConstruction
276
-
277
- # creating new default construction set
278
- new_default_construction_set = default_construction_set.clone(model)
279
- new_default_construction_set = new_default_construction_set.to_DefaultConstructionSet.get
280
- new_default_construction_set.setName("#{default_construction_set.name} adj ext wall insulation")
281
-
282
- # create new surface set and link to construction set
283
- new_default_surface_const_set = default_surface_const_set.get.clone(model)
284
- new_default_surface_const_set = new_default_surface_const_set.to_DefaultSurfaceConstructions.get
285
- new_default_surface_const_set.setName("#{default_surface_const_set.get.name} adj ext wall insulation")
286
- new_default_construction_set.setDefaultExteriorSurfaceConstructions(new_default_surface_const_set)
287
-
288
- # use the hash to find the proper construction and link to new_default_surface_const_set
289
- target_const = new_default_surface_const_set.wallConstruction
290
- if !target_const.empty?
291
- target_const = target_const.get.name.to_s
292
- found_const_flag = false
293
- constructions_hash_old_new.each do |orig, new|
294
- if target_const == orig
295
- final_construction = new
296
- new_default_surface_const_set.setWallConstruction(final_construction)
297
- found_const_flag = true
298
- end
299
- end
300
- if found_const_flag == false # this should never happen but is just an extra test in case something goes wrong with the measure code
301
- runner.registerWarning("Measure couldn't find the construction named '#{target_const}' in the exterior surface hash.")
302
- end
303
- end
304
-
305
- # swap all uses of the old construction set for the new
306
- construction_set_sources = default_construction_set.sources
307
- construction_set_sources.each do |construction_set_source|
308
- building_source = construction_set_source.to_Building
309
- # if statement for each type of object than can use a DefaultConstructionSet
310
- if !building_source.empty?
311
- building_source = building_source.get
312
- building_source.setDefaultConstructionSet(new_default_construction_set)
313
- end
314
- building_story_source = construction_set_source.to_BuildingStory
315
- if !building_story_source.empty?
316
- building_story_source = building_story_source.get
317
- building_story_source.setDefaultConstructionSet(new_default_construction_set)
318
- end
319
- space_type_source = construction_set_source.to_SpaceType
320
- if !space_type_source.empty?
321
- space_type_source = space_type_source.get
322
- space_type_source.setDefaultConstructionSet(new_default_construction_set)
323
- end
324
- space_source = construction_set_source.to_Space
325
- if !space_source.empty?
326
- space_source = space_source.get
327
- space_source.setDefaultConstructionSet(new_default_construction_set)
328
- end
329
- end
282
+ next unless default_construction_set.directUseCount > 0
283
+
284
+ default_surface_const_set = default_construction_set.defaultExteriorSurfaceConstructions
285
+ next if default_surface_const_set.empty?
286
+
287
+ starting_construction = default_surface_const_set.get.wallConstruction
288
+
289
+ # creating new default construction set
290
+ new_default_construction_set = default_construction_set.clone(model)
291
+ new_default_construction_set = new_default_construction_set.to_DefaultConstructionSet.get
292
+ new_default_construction_set.setName("#{default_construction_set.name} adj ext wall insulation")
293
+
294
+ # create new surface set and link to construction set
295
+ new_default_surface_const_set = default_surface_const_set.get.clone(model)
296
+ new_default_surface_const_set = new_default_surface_const_set.to_DefaultSurfaceConstructions.get
297
+ new_default_surface_const_set.setName("#{default_surface_const_set.get.name} adj ext wall insulation")
298
+ new_default_construction_set.setDefaultExteriorSurfaceConstructions(new_default_surface_const_set)
299
+
300
+ # use the hash to find the proper construction and link to new_default_surface_const_set
301
+ target_const = new_default_surface_const_set.wallConstruction
302
+ unless target_const.empty?
303
+ target_const = target_const.get.name.to_s
304
+ found_const_flag = false
305
+ constructions_hash_old_new.each do |orig, new|
306
+ next unless target_const == orig
307
+
308
+ final_construction = new
309
+ new_default_surface_const_set.setWallConstruction(final_construction)
310
+ found_const_flag = true
311
+ end
312
+ if found_const_flag == false # this should never happen but is just an extra test in case something goes wrong with the measure code
313
+ runner.registerWarning("Measure couldn't find the construction named '#{target_const}' in the exterior surface hash.")
314
+ end
315
+ end
330
316
 
317
+ # swap all uses of the old construction set for the new
318
+ construction_set_sources = default_construction_set.sources
319
+ construction_set_sources.each do |construction_set_source|
320
+ building_source = construction_set_source.to_Building
321
+ # if statement for each type of object than can use a DefaultConstructionSet
322
+ unless building_source.empty?
323
+ building_source = building_source.get
324
+ building_source.setDefaultConstructionSet(new_default_construction_set)
325
+ end
326
+ building_story_source = construction_set_source.to_BuildingStory
327
+ unless building_story_source.empty?
328
+ building_story_source = building_story_source.get
329
+ building_story_source.setDefaultConstructionSet(new_default_construction_set)
330
+ end
331
+ space_type_source = construction_set_source.to_SpaceType
332
+ unless space_type_source.empty?
333
+ space_type_source = space_type_source.get
334
+ space_type_source.setDefaultConstructionSet(new_default_construction_set)
335
+ end
336
+ space_source = construction_set_source.to_Space
337
+ unless space_source.empty?
338
+ space_source = space_source.get
339
+ space_source.setDefaultConstructionSet(new_default_construction_set)
331
340
  end
332
341
  end
333
342
  end
334
343
 
335
344
  # link cloned and edited constructions for surfaces with hard assigned constructions
336
345
  exterior_surfaces.each do |exterior_surface|
337
- if !exterior_surface.isConstructionDefaulted && !exterior_surface.construction.empty?
338
-
339
- # use the hash to find the proper construction and link to surface
340
- target_const = exterior_surface.construction
341
- if !target_const.empty?
342
- target_const = target_const.get.name.to_s
343
- constructions_hash_old_new.each do |orig, new|
344
- if target_const == orig
345
- final_construction = new
346
- exterior_surface.setConstruction(final_construction)
347
- end
348
- end
349
- end
346
+ next unless !exterior_surface.isConstructionDefaulted && !exterior_surface.construction.empty?
347
+
348
+ # use the hash to find the proper construction and link to surface
349
+ target_const = exterior_surface.construction
350
+ next if target_const.empty?
350
351
 
352
+ target_const = target_const.get.name.to_s
353
+ constructions_hash_old_new.each do |orig, new|
354
+ if target_const == orig
355
+ final_construction = new
356
+ exterior_surface.setConstruction(final_construction)
357
+ end
351
358
  end
352
359
  end
353
360
 
@@ -359,17 +366,15 @@ class IncreaseInsulationRValueForExteriorWalls < OpenStudio::Measure::ModelMeasu
359
366
  final_constructions_array.each do |final_construction|
360
367
  # unit conversion of wall insulation from SI units (M^2*K/W) to IP units (ft^2*h*R/Btu)
361
368
  final_conductance_ip = unit_helper(1 / final_construction.thermalConductance.to_f, 'm^2*K/W', 'ft^2*h*R/Btu')
362
- final_string << "#{final_construction.name} (R-#{(format '%.1f', final_conductance_ip)})"
369
+ final_string << "#{final_construction.name} (R-#{format '%.1f', final_conductance_ip})"
363
370
  affected_area_si += final_construction.getNetArea
364
371
 
365
372
  # loop through lifecycle costs getting total costs under "Construction" or "Salvage" category and add to counter if occurs during year 0
366
373
  const_LCCs = final_construction.lifeCycleCosts
367
374
  const_LCCs.each do |const_LCC|
368
- if (const_LCC.category == 'Construction') || (const_LCC.category == 'Salvage')
369
- if const_LCC.yearsFromStart == 0
370
- yr0_capital_totalCosts += const_LCC.totalCost
371
- end
372
- end
375
+ next unless (const_LCC.category == 'Construction') || (const_LCC.category == 'Salvage')
376
+
377
+ yr0_capital_totalCosts += const_LCC.totalCost if const_LCC.yearsFromStart == 0
373
378
  end
374
379
  end
375
380
 
@@ -384,9 +389,11 @@ class IncreaseInsulationRValueForExteriorWalls < OpenStudio::Measure::ModelMeasu
384
389
  end
385
390
 
386
391
  # report final condition
387
- runner.registerFinalCondition("The existing insulation for exterior walls was set to R-#{r_value}. This was accomplished for an initial cost of #{one_time_retrofit_cost_ip} ($/sf) and an increase of #{material_cost_increase_ip} ($/sf) for construction. This was applied to #{neat_numbers(affected_area_ip, 0)} (ft^2) across #{final_string.size} exterior wall constructions: #{final_string.sort.join(', ')}.")
392
+ runner.registerFinalCondition("The existing insulation for exterior walls was set to R-#{r_value}. This was accomplished for an initial cost of #{one_time_retrofit_cost_ip} ($/sf) and an increase of #{material_cost_increase_ip} ($/sf) for construction. This was applied to #{neat_numbers(
393
+ affected_area_ip, 0
394
+ )} (ft^2) across #{final_string.size} exterior wall constructions: #{final_string.sort.join(', ')}.")
388
395
 
389
- return true
396
+ true
390
397
  end
391
398
  end
392
399
 
@@ -3,8 +3,8 @@
3
3
  <schema_version>3.1</schema_version>
4
4
  <name>increase_insulation_r_value_for_exterior_walls</name>
5
5
  <uid>3fdf9c39-d305-449b-a4b5-077166af5a67</uid>
6
- <version_id>086d6259-1196-443e-abff-abad0805d999</version_id>
7
- <version_modified>2025-08-08T15:15:56Z</version_modified>
6
+ <version_id>e2c58f01-1f95-4c85-9f42-d1f97170fb49</version_id>
7
+ <version_modified>2025-09-25T15:33:42Z</version_modified>
8
8
  <xml_checksum>0F858D9E</xml_checksum>
9
9
  <class_name>IncreaseInsulationRValueForExteriorWalls</class_name>
10
10
  <display_name>Increase R-value of Insulation for Exterior Walls to a Specific Value</display_name>
@@ -135,7 +135,7 @@ The resulting construction will retain the cost data from the source constructio
135
135
  <filename>measure.rb</filename>
136
136
  <filetype>rb</filetype>
137
137
  <usage_type>script</usage_type>
138
- <checksum>EDD84D57</checksum>
138
+ <checksum>850115AF</checksum>
139
139
  </file>
140
140
  <file>
141
141
  <filename>EnvelopeAndLoadTestModel_01.osm</filename>
@@ -147,7 +147,7 @@ The resulting construction will retain the cost data from the source constructio
147
147
  <filename>IncreaseInsulationRValueForExteriorWalls_01_Test.rb</filename>
148
148
  <filetype>rb</filetype>
149
149
  <usage_type>test</usage_type>
150
- <checksum>308798DD</checksum>
150
+ <checksum>2D3B56DD</checksum>
151
151
  </file>
152
152
  <file>
153
153
  <filename>ReverseTranslatedModel.osm</filename>