Class: SwapLightsDefinition

Inherits:
OpenStudio::Measure::ModelMeasure
  • Object
show all
Defined in:
lib/measures/SwapLightsDefinition/measure.rb

Overview

start the measure

Instance Method Summary collapse

Instance Method Details

#add_to_baseline_demo_cost_counter(baseline_object, demo_cost_initial_const) ⇒ Object



146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/measures/SwapLightsDefinition/measure.rb', line 146

def add_to_baseline_demo_cost_counter(baseline_object, demo_cost_initial_const)
  counter = 0
  if demo_cost_initial_const == true
    baseline_object_LCCs = baseline_object.lifeCycleCosts
    baseline_object_LCCs.each do |baseline_object_LCC|
      if baseline_object_LCC.category == 'Salvage'
        counter += baseline_object_LCC.totalCost
      end
    end
  end
  return counter
end

#arguments(model) ⇒ Object

define the arguments that the user will input



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/measures/SwapLightsDefinition/measure.rb', line 21

def arguments(model)
  args = OpenStudio::Measure::OSArgumentVector.new

  # populate choice argument for lights_defs that are applied to surfaces in the model
  old_lights_def_handles = OpenStudio::StringVector.new
  old_lights_def_display_names = OpenStudio::StringVector.new

  # putting space types and names into hash
  old_lights_def_args = model.getLightsDefinitions
  old_lights_def_args_hash = {}
  old_lights_def_args.each do |old_lights_def_arg|
    old_lights_def_args_hash[old_lights_def_arg.name.to_s] = old_lights_def_arg
  end

  # looping through sorted hash of old_lights_defs
  old_lights_def_args_hash.sort.map do |key, value|
    # only include if old_lights_def is an old_lights_def, if it is used in a space
    if value.quantity > 0
      old_lights_def_handles << value.handle.to_s
      old_lights_def_display_names << key
    end
  end

  # make an argument for old_lights_def
  old_lights_def = OpenStudio::Measure::OSArgument.makeChoiceArgument('old_lights_def', old_lights_def_handles, old_lights_def_display_names, true)
  old_lights_def.setDisplayName('Choose the Lights Definition you Want to Replace.')
  args << old_lights_def

  # populate choice argument for new_lights_defs that are applied to surfaces in the model
  new_lights_def_handles = OpenStudio::StringVector.new
  new_lights_def_display_names = OpenStudio::StringVector.new

  # putting space types and names into hash
  new_lights_def_args = model.getLightsDefinitions
  new_lights_def_args_hash = {}
  new_lights_def_args.each do |new_lights_def_arg|
    new_lights_def_args_hash[new_lights_def_arg.name.to_s] = new_lights_def_arg
  end

  # looping through sorted hash of new_lights_defs
  new_lights_def_args_hash.sort.map do |key, value|
    # include ANY new_lights_def
    new_lights_def_handles << value.handle.to_s
    new_lights_def_display_names << key
  end

  # make an argument for new_lights_def
  new_lights_def = OpenStudio::Measure::OSArgument.makeChoiceArgument('new_lights_def', new_lights_def_handles, new_lights_def_display_names, true)
  new_lights_def.setDisplayName('Choose the Lights Definition to Use in Place of Removed Definition.')
  args << new_lights_def

  # make an argument to determine if demolition costs should be included in initial Definition
  demo_cost_initial_const = OpenStudio::Measure::OSArgument.makeBoolArgument('demo_cost_initial_const', true)
  demo_cost_initial_const.setDisplayName('Demolition Costs Occur During Initial Definition?')
  demo_cost_initial_const.setDefaultValue(false)
  args << demo_cost_initial_const

  return args
end

#nameObject

define the name that a user will see, this method may be deprecated as the display name in PAT comes from the name field in measure.xml



16
17
18
# File 'lib/measures/SwapLightsDefinition/measure.rb', line 16

def name
  return 'SwapLightsDefinition'
end

#neat_numbers(number, roundto = 2) ⇒ Object

helper to make numbers pretty (converts 4125001.25641 to 4,125,001.26 or 4,125,001). The definition be called through this measure.



136
137
138
139
140
141
142
143
144
# File 'lib/measures/SwapLightsDefinition/measure.rb', line 136

def neat_numbers(number, roundto = 2) # round to 0 or 2)
  if roundto == 2
    number = format '%.2f', number
  else
    number = number.round
  end
  # regex to add commas
  number.to_s.reverse.gsub(/([0-9]{3}(?=([0-9])))/, '\\1,').reverse
end

#run(model, runner, user_arguments) ⇒ Object

define what happens when the measure is run



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/measures/SwapLightsDefinition/measure.rb', line 82

def run(model, runner, user_arguments)
  super(model, runner, user_arguments)

  # use the built-in error checking
  if !runner.validateUserArguments(arguments(model), user_arguments)
    return false
  end

  # assign the user inputs to variables
  old_lights_def = runner.getOptionalWorkspaceObjectChoiceValue('old_lights_def', user_arguments, model) # model is passed in because of argument type
  new_lights_def = runner.getOptionalWorkspaceObjectChoiceValue('new_lights_def', user_arguments, model) # model is passed in because of argument type
  demo_cost_initial_const = runner.getBoolArgumentValue('demo_cost_initial_const', user_arguments)

  # check the Definition for reasonableness
  if old_lights_def.empty?
    handle = runner.getStringArgumentValue('old_lights_def', user_arguments)
    if handle.empty?
      runner.registerError('No Lights Definition was chosen.')
    else
      runner.registerError("The selected Lights Definition with handle '#{handle}' was not found in the model. It may have been removed by another measure.")
    end
    return false
  else
    if !old_lights_def.get.to_LightsDefinition.empty?
      old_lights_def = old_lights_def.get.to_LightsDefinition.get
    else
      runner.registerError('Script Error - argument not showing up as Lights Definition.')
      return false
    end
  end

  if new_lights_def.empty?
    handle = runner.getStringArgumentValue('new_lights_def', user_arguments)
    if handle.empty?
      runner.registerError('No Lights Definition was chosen.')
    else
      runner.registerError("The selected Lights Definition with handle '#{handle}' was not found in the model. It may have been removed by another measure.")
    end
    return false
  else
    if !new_lights_def.get.to_LightsDefinition.empty?
      new_lights_def = new_lights_def.get.to_LightsDefinition.get
    else
      runner.registerError('Script Error - argument not showing up as Lights Definition.')
      return false
    end
  end

  # warn user if selected definitions have different load methods (e.g. lpd and lighting power)
  if old_lights_def.designLevelCalculationMethod != new_lights_def.designLevelCalculationMethod
    runner.registerWarning("#{old_lights_def.name} and #{new_lights_def.name} have different design level calculation methods.")
  end

  # helper to make numbers pretty (converts 4125001.25641 to 4,125,001.26 or 4,125,001). The definition be called through this measure.
  def neat_numbers(number, roundto = 2) # round to 0 or 2)
    if roundto == 2
      number = format '%.2f', number
    else
      number = number.round
    end
    # regex to add commas
    number.to_s.reverse.gsub(/([0-9]{3}(?=([0-9])))/, '\\1,').reverse
  end

  def add_to_baseline_demo_cost_counter(baseline_object, demo_cost_initial_const)
    counter = 0
    if demo_cost_initial_const == true
      baseline_object_LCCs = baseline_object.lifeCycleCosts
      baseline_object_LCCs.each do |baseline_object_LCC|
        if baseline_object_LCC.category == 'Salvage'
          counter += baseline_object_LCC.totalCost
        end
      end
    end
    return counter
  end

  # reporting initial condition of model
  runner.registerInitialCondition("#{old_lights_def.name} is used #{old_lights_def.quantity} times in the model.")

  # add one time demo cost of removed lights
  if demo_cost_initial_const == true
    building = model.getBuilding
    lcc_baseline_demo = OpenStudio::Model::LifeCycleCost.createLifeCycleCost('LCC_baseline_demo', building, add_to_baseline_demo_cost_counter(old_lights_def, demo_cost_initial_const), 'CostPerEach', 'Salvage', 0, 0).get # using 0 for repeat period since one time cost.
    runner.registerInfo("Adding one time cost of $#{neat_numbers(lcc_baseline_demo.totalCost, 0)} related to demolition of baseline objects.")
  end

  # array for lights to alter
  lights_to_swap = []

  # push space_type instances to the array
  space_types = model.getSpaceTypes
  space_types.each do |space_type|
    space_type_lights = space_type.lights
    space_type_spaces = space_type.spaces
    if !space_type_spaces.empty?
      space_type_lights.each do |space_type_light|
        if space_type_light.definition == old_lights_def
          lights_to_swap << space_type_light
        end
      end
    end
  end

  # push space_type instances to the array
  spaces = model.getSpaceTypes
  spaces.each do |space|
    space_lights = space.lights
    space_lights.each do |space_light|
      if space_light.definition == old_lights_def
        lights_to_swap << space_light
      end
    end
  end

  # flag for non-1 instance multiplier
  non_1_multiplier = false

  # swap definitions
  lights_to_swap.each do |light|
    # apply requested definition
    light.setLightsDefinition(new_lights_def)
    # set flag for non-1 multiplier in instance
    non_1_multiplier = true
  end

  # warn if non-1 multiplier in instance
  if non_1_multiplier == true
    runner.registerInfo('One or more light instances have a non 1 multiplier.')
  end

  # reporting final condition of model
  runner.registerFinalCondition("#{old_lights_def.name} is used #{old_lights_def.instances.size} times in the model.")

  return true
end