openstudio-workflow 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -13,10 +13,10 @@ module OpenStudio
13
13
  # @param [Hash] options ({}) User-specified options used to override defaults
14
14
  # @option options [Object] :time_logger A special logger used to debug performance issues
15
15
  # @option options [Object] :output_adapter An output adapter to register measure transitions to
16
- # @option options [Object] :energyplus_output_requests If true then the energyPlusOutputRequests is called instead of the run method
16
+ # @param [Boolean] energyplus_output_requests If true then the energyPlusOutputRequests is called instead of the run method
17
17
  # @return [Void]
18
18
  #
19
- def apply_measures(measure_type, registry, options = {})
19
+ def apply_measures(measure_type, registry, options = {}, energyplus_output_requests = false)
20
20
 
21
21
  # DLM: time_logger is in the registry but docs say it is in options?
22
22
  registry[:time_logger].start "#{measure_type.valueName}:apply_measures" if registry[:time_logger]
@@ -49,9 +49,9 @@ module OpenStudio
49
49
  class_name = measure.className
50
50
  measure_instance_type = measure.measureType
51
51
  if measure_instance_type == measure_type
52
- if options[:energyplus_output_requests]
52
+ if energyplus_output_requests
53
53
  logger.info "Found measure #{class_name} of type #{measure_type.valueName}. Collecting EnergyPlus Output Requests now."
54
- apply_measure(registry, step, options)
54
+ apply_measure(registry, step, options, energyplus_output_requests)
55
55
  else
56
56
  logger.info "Found measure #{class_name} of type #{measure_type.valueName}. Applying now."
57
57
 
@@ -193,11 +193,11 @@ module OpenStudio
193
193
  # @option options [Array] :measure_search_array Ordered set of measure directories used to search for
194
194
  # step[:measure_dir_name], e.g. ['measures', '../../measures']
195
195
  # @option options [Object] :time_logger Special logger used to debug performance issues
196
- # @option options [Object] :energyplus_output_requests If true then the energyPlusOutputRequests is called instead of the run method
196
+ # @param [Boolean] energyplus_output_requests If true then the energyPlusOutputRequests is called instead of the run method
197
197
  # @return [Hash, String] Returns two objects. The first is the (potentially) updated output_attributes hash, and
198
198
  # the second is the (potentially) updated current_weather_filepath
199
199
  #
200
- def apply_measure(registry, step, options = {})
200
+ def apply_measure(registry, step, options = {}, energyplus_output_requests = false)
201
201
 
202
202
  logger = registry[:logger]
203
203
  runner = registry[:runner]
@@ -214,7 +214,7 @@ module OpenStudio
214
214
  @model = registry[:model]
215
215
  @model_idf = registry[:model_idf]
216
216
  @sql_filename = registry[:sql]
217
-
217
+
218
218
  runner.setLastOpenStudioModel(@model) if @model
219
219
  #runner.setLastOpenStudioModelPath(const openstudio::path& lastOpenStudioModelPath); #DLM - deprecate?
220
220
  runner.setLastEnergyPlusWorkspace(@model_idf) if @model_idf
@@ -244,7 +244,7 @@ module OpenStudio
244
244
  FileUtils.mkdir_p measure_run_dir
245
245
  Dir.chdir measure_run_dir
246
246
 
247
- if options[:energyplus_output_requests]
247
+ if energyplus_output_requests
248
248
  logger.debug "energyPlusOutputRequests running in #{Dir.pwd}"
249
249
  else
250
250
  logger.debug "Apply measure running in #{Dir.pwd}"
@@ -375,7 +375,7 @@ module OpenStudio
375
375
  end
376
376
 
377
377
  if skip_measure
378
- if !options[:energyplus_output_requests]
378
+ if !energyplus_output_requests
379
379
  # just increment
380
380
  logger.debug "Skipping measure '#{measure_dir_name}'"
381
381
  runner.prepareForUserScriptRun(measure_object)
@@ -387,7 +387,7 @@ module OpenStudio
387
387
  else
388
388
 
389
389
  begin
390
- if options[:energyplus_output_requests]
390
+ if energyplus_output_requests
391
391
  logger.debug "Calling measure.energyPlusOutputRequests for '#{measure_dir_name}'"
392
392
  idf_objects = measure_object.energyPlusOutputRequests(runner, argument_map)
393
393
  num_added = 0
@@ -414,7 +414,7 @@ module OpenStudio
414
414
  # add the error to the osw.out
415
415
  runner.registerError("#{e.message}\n\t#{e.backtrace.join("\n\t")}")
416
416
 
417
- if !options[:energyplus_output_requests]
417
+ if !energyplus_output_requests
418
418
  # incrementStep must be called after run
419
419
  runner.incrementStep
420
420
  end
@@ -424,7 +424,7 @@ module OpenStudio
424
424
  end
425
425
 
426
426
  # if doing output requests we are done now
427
- if options[:energyplus_output_requests]
427
+ if energyplus_output_requests
428
428
  registry.register(:model_idf) { @model_idf }
429
429
  return
430
430
  end
@@ -451,6 +451,28 @@ module OpenStudio
451
451
  registry.register(:model) { @model }
452
452
  registry.register(:model_idf) { @model_idf }
453
453
  registry.register(:sql) { @sql_filename }
454
+
455
+ if measure_type == 'ModelMeasure'.to_MeasureType
456
+ # check if weather file has changed
457
+ weather_file = @model.getOptionalWeatherFile
458
+ if !weather_file.empty?
459
+ weather_file_path = weather_file.get.path
460
+ if weather_file_path.empty?
461
+ logger.debug "Weather file object found in model but no path is given"
462
+ else
463
+ weather_file_path2 = workflow_json.findFile(weather_file_path.get)
464
+ if weather_file_path2.empty?
465
+ logger.warn "Could not find weather file '#{weather_file_path}' referenced in model"
466
+ else
467
+ if weather_file_path2.get.to_s != @wf
468
+ logger.debug "Updating weather file path to '#{weather_file_path2.get.to_s}'"
469
+ @wf = weather_file_path2.get.to_s
470
+ registry.register(:wf) { @wf }
471
+ end
472
+ end
473
+ end
474
+ end
475
+ end
454
476
 
455
477
  rescue => e
456
478
  log_message = "Runner error #{__FILE__} failed with #{e.message}, #{e.backtrace.join("\n")}"
@@ -511,7 +533,7 @@ module OpenStudio
511
533
  Dir.chdir current_dir
512
534
  registry[:time_logger].stop("Measure:#{measure_dir_name}") if registry[:time_logger]
513
535
 
514
- logger.info "Finished #{__method__} for #{measure_dir_name} in #{@registry[:time_logger].delta("Measure:#{measure_dir_name}")} s"
536
+ logger.info "Finished #{__method__} for #{measure_dir_name} in #{@registry[:time_logger].delta("Measure:#{measure_dir_name}")} s" if registry[:time_logger]
515
537
  end
516
538
  end
517
539
  end
@@ -19,6 +19,6 @@
19
19
 
20
20
  module OpenStudio
21
21
  module Workflow
22
- VERSION = '1.0.0'.freeze # Suffixes must have periods (not dashes)
22
+ VERSION = '1.1.0'.freeze # Suffixes must have periods (not dashes)
23
23
  end
24
24
  end
@@ -396,4 +396,9 @@ class WorkflowJSON_Shim
396
396
  def setEplusoutErr(eplusout_err)
397
397
  @workflow[:eplusout_err] = eplusout_err
398
398
  end
399
+
400
+ # return empty optional
401
+ def runOptions
402
+ return Optional_Shim.new(nil)
403
+ end
399
404
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openstudio-workflow
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nicholas Long
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-01-06 00:00:00.000000000 Z
12
+ date: 2017-02-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -43,15 +43,13 @@ description: Run OpenStudio based measures and simulations using EnergyPlus
43
43
  email:
44
44
  - nicholas.long@nrel.gov
45
45
  - henry.horsey@nrel.gov
46
- executables:
47
- - openstudio_cli
46
+ executables: []
48
47
  extensions: []
49
48
  extra_rdoc_files: []
50
49
  files:
51
50
  - CHANGELOG.md
52
51
  - README.md
53
52
  - Rakefile
54
- - bin/openstudio_cli
55
53
  - lib/openstudio-workflow.rb
56
54
  - lib/openstudio/workflow/adapters/input/local.rb
57
55
  - lib/openstudio/workflow/adapters/output/local.rb
data/bin/openstudio_cli DELETED
@@ -1,786 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- ######################################################################
4
- # Copyright (c) 2008-2016, Alliance for Sustainable Energy.
5
- # All rights reserved.
6
- #
7
- # This library is free software; you can redistribute it and/or
8
- # modify it under the terms of the GNU Lesser General Public
9
- # License as published by the Free Software Foundation; either
10
- # version 2.1 of the License, or (at your option) any later version.
11
- #
12
- # This library is distributed in the hope that it will be useful,
13
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
- # Lesser General Public License for more details.
16
- #
17
- # You should have received a copy of the GNU Lesser General Public
18
- # License along with this library; if not, write to the Free Software
19
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
- ######################################################################
21
-
22
- Signal.trap('INT') { abort }
23
-
24
- require 'openstudio-workflow'
25
- require 'optparse'
26
- require 'irb'
27
- require 'json'
28
- include OpenStudio::Workflow::Util::IO
29
- include OpenStudio::Workflow::Util::Directory
30
-
31
- $logger = Logger.new(STDOUT)
32
- $logger.level = Logger::WARN
33
-
34
- # This is the code chunk to allow for an embedded IRB shell. From Jason Roelofs, found on StackOverflow
35
- module IRB # :nodoc:
36
- def self.start_session(binding)
37
- unless @__initialized
38
- args = ARGV
39
- ARGV.replace(ARGV.dup)
40
- IRB.setup(nil)
41
- ARGV.replace(args)
42
- @__initialized = true
43
- end
44
-
45
- workspace = WorkSpace.new(binding)
46
-
47
- irb = Irb.new(workspace)
48
-
49
- @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
50
- @CONF[:MAIN_CONTEXT] = irb.context
51
-
52
- catch(:IRB_EXIT) do
53
- irb.eval_input
54
- end
55
- end
56
- end
57
-
58
- # This is the save puts to use to catch EPIPE. Uses `puts` on the given IO object and safely ignores any Errno::EPIPE
59
- #
60
- # @param [String] message Message to output
61
- # @param [Hash] opts Options hash
62
- #
63
- def safe_puts(message = nil, opts = nil)
64
- message ||= ''
65
- opts = {
66
- io: $stdout,
67
- printer: :puts
68
- }.merge(opts || {})
69
-
70
- begin
71
- opts[:io].send(opts[:printer], message)
72
- rescue Errno::EPIPE
73
- # This is what makes this a `safe` puts
74
- return
75
- end
76
- end
77
-
78
- # This is a convenience method that properly handles duping the originally argv array so that it is not destroyed. This
79
- # method will also automatically detect "-h" and "--help" and print help. And if any invalid options are detected, the
80
- # help will be printed, as well
81
- #
82
- # @param [Object, nil] opts An instance of OptionParse to parse against, defaults to a new OptionParse instance
83
- # @param [Array, nil] argv The argv input to be parsed, defaults to $argv
84
- # @return[Array, nil] If this method returns `nil`, then you should assume that help was printed and parsing failed
85
- #
86
- def parse_options(opts = nil, argv = nil)
87
- # Creating a shallow copy of the arguments so the OptionParser
88
- # doesn't destroy the originals.
89
- argv ||= $argv.dup
90
-
91
- # Default opts to a blank optionparser if none is given
92
- opts ||= OptionParser.new
93
-
94
- # Add the help option, which must be on every command.
95
- opts.on_tail('-h', '--help', 'Print this help') do
96
- safe_puts(opts.help)
97
- return nil
98
- end
99
-
100
- opts.parse!(argv)
101
- return argv
102
- rescue OptionParser::InvalidOption, OptionParser::MissingArgument
103
- raise "Error: Invalid CLI option, #{opts.help.chomp}"
104
- end
105
-
106
- # This method will split the argv given into three parts: the flags to this command, the subcommand, and the flags to
107
- # the subcommand. For example:
108
- # -v status -h -v
109
- # The above would yield 3 parts:
110
- # ["-v"]
111
- # "status"
112
- # ["-h", "-v"]
113
- # These parts are useful because the first is a list of arguments given to the current command, the second is a
114
- # subcommand, and the third are the commands given to the subcommand
115
- #
116
- # @param [Array] argv The input to be split
117
- # @return [Array] The split command as [main arguments, sub command, sub command arguments]
118
- #
119
- def split_main_and_subcommand(argv)
120
- # Initialize return variables
121
- main_args = nil
122
- sub_command = nil
123
- sub_args = []
124
-
125
- # We split the arguments into two: One set containing any flags before a word, and then the rest. The rest are what
126
- # get actually sent on to the subcommand
127
- argv.each_index do |i|
128
- unless argv[i].start_with?('-')
129
- # We found the beginning of the sub command. Split the
130
- # args up.
131
- main_args = argv[0, i]
132
- sub_command = argv[i]
133
- sub_args = argv[i + 1, argv.length - i + 1]
134
-
135
- # Break so we don't find the next non flag and shift our main args
136
- break
137
- end
138
- end
139
-
140
- # Handle the case that argv was empty or didn't contain any subcommand
141
- main_args = argv.dup if main_args.nil?
142
-
143
- [main_args, sub_command, sub_args]
144
- end
145
-
146
- # This CLI class processes the input args and invokes the proper command class
147
- class CLI
148
- # This constant maps subcommands to classes in this CLI and stores meta-data on them
149
- COMMAND_LIST = {
150
- run: [proc { ::Run }, { primary: true, working: true }],
151
- apply_measure: [proc { ::ApplyMeasure }, { primary: true, working: false }],
152
- gem_list: [proc { ::GemList }, { primary: true, working: true }],
153
- gem_install: [proc { ::InstallGem }, { primary: false, working: true }],
154
- measure: [proc { ::Measure }, { primary: true, working: false }],
155
- e: [proc { ::ExecuteRubyScript }, { primary: false, working: true }],
156
- i: [proc { ::InteractiveRubyShell }, { primary: false, working: true }],
157
- openstudio_version: [proc { ::OpenStudioVersion }, { primary: true, working: true }],
158
- energyplus_version: [proc { ::EnergyPlusVersion }, { primary: true, working: true }],
159
- ruby_version: [proc { ::RubyVersion }, { primary: false, working: true }],
160
- list_commands: [proc { ::ListCommands }, { primary: true, working: true }]
161
- }.freeze
162
-
163
- # This method instantiates the global variables $main_args, $sub_command, and $sub_args
164
- #
165
- # @param [Array] argv The arguments passed through the CLI
166
- # @return [Object] An instance of the CLI class with initialized globals
167
- #
168
- def initialize(argv)
169
- $main_args, $sub_command, $sub_args = split_main_and_subcommand(argv)
170
-
171
- $logger.info("CLI Parsed Inputs: #{$main_args.inspect} #{$sub_command.inspect} #{$sub_args.inspect}")
172
- end
173
-
174
- # Checks to see if it should print the main help, and if not parses the subcommand into a class and executes it
175
- def execute
176
- $logger.debug "Main arguments are #{$main_args}"
177
- $logger.debug "Sub-command is #{$sub_command}"
178
- $logger.debug "Sub-arguments are #{$sub_args}"
179
- if $main_args.include?('-h') || $main_args.include?('--help')
180
- # Help is next in short-circuiting everything. Print
181
- # the help and exit.
182
- help
183
- return 0
184
- end
185
-
186
- # If we reached this far then we must have a subcommand. If not,
187
- # then we also just print the help and exit.
188
- command_plugin = nil
189
- if $sub_command
190
- command_plugin = COMMAND_LIST[$sub_command.to_sym]
191
- end
192
-
193
- if !command_plugin || !$sub_command
194
- help
195
- return 1
196
- end
197
-
198
- command_class = command_plugin[0].call
199
- $logger.debug("Invoking command class: #{command_class} #{$sub_args.inspect}")
200
-
201
- # Initialize and execute the command class, returning the exit status.
202
- result = 0
203
- begin
204
- result = command_class.new.execute($sub_args)
205
- rescue Interrupt
206
- $logger.error '?'
207
- result = 1
208
- end
209
-
210
- result = 0 unless result.is_a?(Fixnum)
211
- result
212
- end
213
-
214
- # Prints out the help text for the CLI
215
- #
216
- # @param [Boolean] list_all If set to true, the help prints all commands, however it otherwise only prints those
217
- # marked as primary in #COMMAND_LIST
218
- # @return [void]
219
- # @see #COMMAND_LIST #::ListCommands
220
- #
221
- def help(list_all = false)
222
- opts = OptionParser.new do |o|
223
- o.banner = 'Usage: openstudio_cli [options] <command> [<args>]'
224
- o.separator ''
225
- o.on('-h', '--help', 'Print this help.')
226
- o.on('--verbose', 'Print the full log to STDOUT')
227
- o.on('--gem_path PATH', 'Path to use for installing gems to and loading gems from')
228
- o.separator ''
229
- o.separator 'Common commands:'
230
-
231
- # Add the available subcommands as separators in order to print them
232
- # out as well.
233
- commands = {}
234
- longest = 0
235
- COMMAND_LIST.each do |key, data|
236
- # Skip non-primary commands. These only show up in extended
237
- # help output.
238
- next unless list_all || data[1][:primary]
239
-
240
- key = key.to_s
241
- klass = data[0].call
242
- commands[key] = klass.synopsis
243
- longest = key.length if key.length > longest
244
- end
245
-
246
- commands.keys.sort.each do |key|
247
- o.separator " #{key.ljust(longest + 2)} #{commands[key]}"
248
- end
249
-
250
- o.separator ''
251
- o.separator 'For help on any individual command run `openstudio_cli COMMAND -h`'
252
- unless list_all
253
- o.separator ''
254
- o.separator 'Additional subcommands are available, but are either more advanced'
255
- o.separator 'or not commonly used. To see all subcommands, run the command'
256
- o.separator '`openstudio_cli list_commands`.'
257
- end
258
- end
259
-
260
- safe_puts opts.help
261
- end
262
- end
263
-
264
- # Class to execute part or all of an OSW workflow
265
- class Run
266
- # Provides text for the main help functionality
267
- def self.synopsis
268
- 'Executes an OpenStudio Workflow file'
269
- end
270
-
271
- # Executes the standard, or one of two custom, workflows using the workflow-gem
272
- #
273
- # @param [Array] sub_argv Options passed to the run subcommand from the user input
274
- # @return [Fixnum] Return status
275
- #
276
- def execute(sub_argv)
277
- options = {}
278
- options[:debug] = false
279
- options[:no_simulation] = false
280
- options[:workflow] = './workflow.osw'
281
- options[:post_process] = false
282
-
283
- opts = OptionParser.new do |o|
284
- o.banner = 'Usage: openstudio_cli run [options]'
285
- o.separator ''
286
- o.separator 'Options:'
287
- o.separator ''
288
-
289
- o.on('-w', '--workflow [FILE]', 'Specify the FILE path to the workflow to run') do |workflow|
290
- options[:workflow] = workflow
291
- end
292
- o.on('-m', '--measures_only', 'Only run the OpenStudio and EnergyPlus measures') do
293
- options[:no_simulation] = true
294
- end
295
- o.on('-p', '--postprocess_only', 'Only run the reporting measures') do
296
- options[:post_process] = true
297
- end
298
- o.on('--debug', 'Includes additional outputs for debugging failing workflows and does not clean up the run directory') do |f|
299
- options[:debug] = f
300
- end
301
- end
302
-
303
- # Parse the options
304
- argv = parse_options(opts, sub_argv)
305
- return 0 if argv.nil?
306
- unless argv == []
307
- $logger.error 'Extra arguments passed to the run command. Please refer to the help documentation.'
308
- return 1
309
- end
310
- $logger.debug("Run command: #{argv.inspect} #{options.inspect}")
311
-
312
- if options[:post_process] && options[:no_simulation]
313
- $logger.error 'Both the -m and -p flags were set, which is an invalid combination.'
314
- return 1
315
- end
316
-
317
- osw_path = options[:workflow]
318
- osw_path = File.absolute_path(File.join(Dir.pwd, osw_path)) unless Pathname.new(osw_path).absolute?
319
- $logger.debug "Path for the OSW: #{osw_path}"
320
-
321
- adapter_options = { workflow_filename: File.basename(osw_path) }
322
- input_adapter = OpenStudio::Workflow.load_input_adapter 'local', adapter_options
323
- adapter_options[:output_directory] = input_adapter.run_directory File.dirname(osw_path)
324
- output_adapter = OpenStudio::Workflow.load_output_adapter 'local', adapter_options
325
- run_options = options[:debug] ? { debug: true, cleanup: false } : {}
326
- if options[:no_simulation]
327
- run_options[:jobs] = [
328
- { state: :queued, next_state: :initialization, options: { initial: true } },
329
- { state: :initialization, next_state: :os_measures, job: :RunInitialization,
330
- file: 'openstudio/workflow/jobs/run_initialization.rb', options: {} },
331
- { state: :os_measures, next_state: :translator, job: :RunOpenStudioMeasures,
332
- file: 'openstudio/workflow/jobs/run_os_measures.rb', options: {} },
333
- { state: :translator, next_state: :ep_measures, job: :RunTranslation,
334
- file: 'openstudio/workflow/jobs/run_translation.rb', options: {} },
335
- { state: :ep_measures, next_state: :finished, job: :RunEnergyPlusMeasures,
336
- file: 'openstudio/workflow/jobs/run_ep_measures.rb', options: {} },
337
- { state: :finished },
338
- { state: :errored }
339
- ]
340
- elsif options[:post_process]
341
- run_options[:jobs] = [
342
- { state: :queued, next_state: :initialization, options: { initial: true } },
343
- { state: :initialization, next_state: :reporting_measures, job: :RunInitialization,
344
- file: 'openstudio/workflow/jobs/run_initialization.rb', options: {} },
345
- { state: :reporting_measures, next_state: :postprocess, job: :RunReportingMeasures,
346
- file: 'openstudio/workflow/jobs/run_reporting_measures.rb', options: {} },
347
- { state: :postprocess, next_state: :finished, job: :RunPostprocess,
348
- file: 'openstudio/workflow/jobs/run_postprocess.rb', options: {} },
349
- { state: :finished },
350
- { state: :errored }
351
- ]
352
- run_options[:load_simulation_osm] = true
353
- run_options[:load_simulation_idf] = true
354
- run_options[:load_simulation_sql] = true
355
- run_options[:preserve_run_dir] = true
356
- end
357
- k = OpenStudio::Workflow::Run.new input_adapter, output_adapter, File.dirname(osw_path), run_options
358
- k.run
359
-
360
- 0
361
- end
362
- end
363
-
364
- # Class to apply an OpenStudio, EnergyPlus, or Reporting measure
365
- # @abstract
366
- class ApplyMeasure
367
- # Provides text for the main help functionality
368
- def self.synopsis
369
- 'Applies an OpenStudio, EnergyPlus, or Reporting measure'
370
- end
371
-
372
- # Executes a single measure using an undefined interface
373
- #
374
- # @param [Array] sub_argv Options passed to the apply_measures subcommand from the user input
375
- # @return [Fixnum] Return status
376
- # @abstract
377
- #
378
- def execute(sub_argv)
379
- # options = {}
380
- # options[:debug] = false
381
-
382
- # opts = OptionParser.new do |o|
383
- # o.banner = 'Usage: openstudio_cli apply_measure'
384
- # o.separator ''
385
- # o.separator 'Options:'
386
- # o.separator ''
387
- # end
388
-
389
- $logger.error 'This interface has yet to be defined.'
390
-
391
- # Parse the options
392
- argv = parse_options(opts, sub_argv)
393
- return 1 unless argv
394
- # $logger.debug("ApplyMeasure command: #{argv.inspect} #{options.inspect}")
395
-
396
- 1
397
- end
398
- end
399
-
400
- # Class to list the gems used by the CLI
401
- class GemList
402
- # Provides text for the main help functionality
403
- def self.synopsis
404
- 'Lists the set gems available to openstudio_cli'
405
- end
406
-
407
- # Alters the environment variable used to define the gem install location
408
- #
409
- # @param [Array] sub_argv Options passed to the gem_install subcommand from the user input
410
- # @return [Fixnum] Return status
411
- #
412
- def execute(sub_argv)
413
- require 'rubygems'
414
- require 'rubygems/gem_runner'
415
-
416
- # Parse the options
417
- opts = OptionParser.new do |o|
418
- o.banner = 'Usage: openstudio_cli gem_list'
419
- end
420
- argv = parse_options(opts, sub_argv)
421
- unless argv == []
422
- $logger.error 'Extra arguments passed to the gem_list command. Please refer to the help documentation.'
423
- return 1
424
- end
425
-
426
- begin
427
- Gem::GemRunner.new.run ['list']
428
- rescue => e
429
- $logger.error "Error listing gems: #{e.message} in #{e.backtrace.join("\n")}"
430
- exit e.exit_code
431
- end
432
-
433
- 0
434
- end
435
- end
436
-
437
- # Class to install gems using the RubyGems functionality
438
- class InstallGem
439
- # Provides text for the main help functionality
440
- def self.synopsis
441
- 'Installs a Gem using the embedded ruby'
442
- end
443
-
444
- # Executes the RubyGems gem install process, using the RubyGems options
445
- #
446
- # @param [Array] sub_argv Options passed to the gem_install subcommand from the user input
447
- # @return [Fixnum] Return status
448
- #
449
- def execute(sub_argv)
450
- require 'rubygems'
451
- require 'rubygems/gem_runner'
452
-
453
- # Parse the options
454
- argv = sub_argv.unshift('install')
455
- if argv.include? '--install-dir'
456
- $logger.error 'The rubygems option --install-dir is not supported. Please use the --gem_path option'
457
- return 1
458
- else
459
- argv.push '--install-dir'
460
- argv.push ENV['GEM_PATH']
461
- end
462
- $logger.debug "GemInstall command: #{argv.inspect}"
463
- $logger.debug "Invoking the GemRunner with argv: #{argv}"
464
-
465
- begin
466
- Gem::GemRunner.new.run argv
467
- rescue => e
468
- $logger.error "Error installing gem: #{e.message} in #{e.backtrace.join("\n")}"
469
- exit e.exit_code
470
- end
471
-
472
- $logger.info 'The gem was successfully installed'
473
-
474
- 0
475
- end
476
- end
477
-
478
- # Class to update measures and compute arguments
479
- class Measure
480
- # Provides text for the main help functionality
481
- def self.synopsis
482
- 'Updates measures and compute arguments'
483
- end
484
-
485
- # Executes code to update and compute arguments for measures
486
- #
487
- # @param [Array] sub_argv Options passed to the e subcommand from the user input
488
- # @return [Fixnum] Return status
489
- # @todo (macumber) Add in the OpenStudio code to execute on measures
490
- #
491
- def execute(sub_argv)
492
- options = {}
493
- options[:check_for_update] = false
494
- options[:update] = false
495
- options[:compute_arguments] = nil
496
-
497
- opts = OptionParser.new do |o|
498
- o.banner = 'Usage: openstudio_cli measure [options] DIRECTORY'
499
- o.separator ''
500
- o.separator 'Options:'
501
- o.separator ''
502
-
503
- o.on('-c', '--check_for_updates', 'Check to see if the measure needs to be updated') do
504
- options[:check_for_update] = workflow
505
- end
506
- o.on('-u', '--update', 'Update the measure.xml') do
507
- options[:update] = true
508
- end
509
- o.on('-a', '--compute_arguments [MODEL]', 'Compute arguments for the given model') do |model_file|
510
- options[:compute_arguments] = model_file
511
- end
512
- end
513
-
514
- # Parse the options
515
- argv = parse_options(opts, sub_argv)
516
- $logger.error 'No directory provided' if argv == []
517
- return 1 if argv == []
518
- directory = argv[0]
519
-
520
- $logger.debug("Measure command: #{argv.inspect} #{options.inspect}")
521
- $logger.debug("Directory to examine is #{directory}")
522
-
523
- $logger.error 'Code to be added here to operate on measures'
524
-
525
- 1
526
- end
527
- end
528
-
529
- # Class to execute a ruby script
530
- class ExecuteRubyScript
531
- # Provides text for the main help functionality
532
- def self.synopsis
533
- 'Executes a ruby file'
534
- end
535
-
536
- # Executes an arbitrary ruby script
537
- #
538
- # @param [Array] sub_argv Options passed to the e subcommand from the user input
539
- # @return [Fixnum] Return status
540
- #
541
- def execute(sub_argv)
542
- options = {}
543
-
544
- opts = OptionParser.new do |o|
545
- o.banner = 'Usage: openstudio_cli e [file]'
546
- end
547
-
548
- # Parse the options
549
- argv = parse_options(opts, sub_argv)
550
- return 0 if argv.nil?
551
- return 1 unless argv
552
- $logger.debug("ExecuteRubyScript command: #{argv.inspect} #{options.inspect}")
553
- file_path = argv.shift.to_s
554
- file_path = File.absolute_path(File.join(Dir.pwd, file_path)) unless Pathname.new(file_path).absolute?
555
- $logger.debug "Path for the file to run: #{file_path}"
556
-
557
- unless argv == []
558
- $logger.error 'Extra arguments passed to the e command. Please refer to the help documentation.'
559
- return 1
560
- end
561
-
562
- unless File.exist? file_path
563
- $logger.error "Unable to find the file #{file_path} on the filesystem"
564
- return 1
565
- end
566
-
567
- require file_path
568
-
569
- 0
570
- end
571
- end
572
-
573
- # Class to put the user into an irb shell
574
- class InteractiveRubyShell
575
- # Provides text for the main help functionality
576
- def self.synopsis
577
- 'Provides an interactive ruby shell'
578
- end
579
-
580
- # Executes the commands to get into an IRB prompt
581
- #
582
- # @param [Array] sub_argv Options passed to the i subcommand from the user input
583
- # @return [Fixnum] Return status
584
- #
585
- def execute(sub_argv)
586
- options = {}
587
-
588
- opts = OptionParser.new do |o|
589
- o.banner = 'Usage: openstudio_cli i'
590
- end
591
-
592
- # Parse the options
593
- argv = parse_options(opts, sub_argv)
594
- $logger.debug("InteractiveRubyShell command: #{argv.inspect} #{options.inspect}")
595
- return 0 if argv.nil?
596
-
597
- unless argv == []
598
- $logger.error 'Extra arguments passed to the i command.'
599
- return 1
600
- end
601
-
602
- IRB.start_session(binding)
603
-
604
- 0
605
- end
606
- end
607
-
608
- # Class to return the packaged OpenStudio version
609
- class OpenStudioVersion
610
- # Provides text for the main help functionality
611
- def self.synopsis
612
- 'Returns the OpenStudio version used by the CLI'
613
- end
614
-
615
- # Executes the OpenStudio commands to return the OpenStudio version
616
- #
617
- # @param [Array] sub_argv Options passed to the energyplus_version subcommand from the user input
618
- # @return [Fixnum] Return status
619
- #
620
- def execute(sub_argv)
621
- options = {}
622
-
623
- opts = OptionParser.new do |o|
624
- o.banner = 'Usage: openstudio_cli openstudio_version'
625
- end
626
-
627
- # Parse the options
628
- argv = parse_options(opts, sub_argv)
629
- $logger.debug("OpenStudioVersion command: #{argv.inspect} #{options.inspect}")
630
- return 0 if argv.nil?
631
-
632
- unless argv == []
633
- $logger.error 'Extra arguments passed to the openstudio_version command.'
634
- return 1
635
- end
636
-
637
- safe_puts OpenStudio.openStudioLongVersion
638
-
639
- 0
640
- end
641
- end
642
-
643
- # Class to return the EnergyPlus version
644
- class EnergyPlusVersion
645
- # Provides text for the main help functionality
646
- def self.synopsis
647
- 'Returns the EnergyPlus version used by the CLI'
648
- end
649
-
650
- # Executes the OpenStudio command to return the EnergyPlus version
651
- #
652
- # @param [Array] sub_argv Options passed to the openstudio_version subcommand from the user input
653
- # @return [Fixnum] Return status
654
- #
655
- def execute(sub_argv)
656
- options = {}
657
-
658
- opts = OptionParser.new do |o|
659
- o.banner = 'Usage: openstudio_cli energyplus_version'
660
- end
661
-
662
- # Parse the options
663
- argv = parse_options(opts, sub_argv)
664
- $logger.debug("EnergyPlusVersion command: #{argv.inspect} #{options.inspect}")
665
- return 0 if argv.nil?
666
-
667
- unless argv == []
668
- $logger.error 'Arguments passed to the energyplus_version command.'
669
- return 1
670
- end
671
-
672
- safe_puts OpenStudio.energyPlusVersion
673
-
674
- 0
675
- end
676
- end
677
-
678
- # Class to return the ruby version used by the packaged CLI
679
- class RubyVersion
680
- # Provides text for the main help functionality
681
- def self.synopsis
682
- 'Returns the Ruby version used by the CLI'
683
- end
684
-
685
- # Evaluates the RUBY_VERSION constant and returns it
686
- #
687
- # @param [Array] sub_argv Options passed to the ruby_version subcommand from the user input
688
- # @return [Fixnum] Return status
689
- #
690
- def execute(sub_argv)
691
- options = {}
692
-
693
- opts = OptionParser.new do |o|
694
- o.banner = 'Usage: openstudio_cli ruby_version'
695
- end
696
-
697
- # Parse the options
698
- argv = parse_options(opts, sub_argv)
699
- $logger.debug("RubyVersion command: #{argv.inspect} #{options.inspect}")
700
- return 0 if argv.nil?
701
-
702
- unless argv == []
703
- $logger.error 'Arguments passed to the ruby_version command.'
704
- return 1
705
- end
706
-
707
- safe_puts RUBY_VERSION
708
-
709
- 0
710
- end
711
- end
712
-
713
- # Class to return the full set of possible commands for the CLI
714
- class ListCommands
715
- # Provides text for the main help functionality
716
- def self.synopsis
717
- 'Lists the entire set of available commands for openstudio_cli'
718
- end
719
-
720
- # Executes the standard help method with the list_all attribute set to true
721
- #
722
- # @param [Array] sub_argv Options passed to the list_all subcommand from the user input
723
- # @return [Fixnum] Return status
724
- # @see #::CLI.help
725
- #
726
- def execute(sub_argv)
727
- options = {}
728
-
729
- opts = OptionParser.new do |o|
730
- o.banner = 'Usage: openstudio_cli list_commands'
731
- end
732
-
733
- # Parse the options
734
- argv = parse_options(opts, sub_argv)
735
- $logger.debug("ListCommands command: #{argv.inspect} #{options.inspect}")
736
- return 0 if argv.nil?
737
-
738
- unless argv == []
739
- $logger.error 'Arguments passed to the list_commands command.'
740
- return 1
741
- end
742
-
743
- $logger.debug 'Creating a new CLI instance and calling help with list_all enabled'
744
- ::CLI.new([]).help(true)
745
-
746
- 0
747
- end
748
- end
749
-
750
- # Set the logger level to DEBUG if the arguments include --verbose
751
- $argv = ARGV.dup
752
- if $argv.include? '--verbose'
753
- $logger.level = Logger::DEBUG
754
- $argv.delete '--verbose'
755
- $logger.debug 'Set Logger log level to DEBUG'
756
- end
757
- $logger.debug "Input ARGV is #{$argv}"
758
-
759
- # Operate on the gem_path option to set the gem search path
760
- if $argv.include? '--gem_path'
761
- $logger.info 'Setting gem path'
762
- option_index = $argv.index '--gem_path'
763
- path_index = option_index + 1
764
- new_home = $argv[path_index]
765
- $argv.slice! path_index
766
- $argv.slice! $argv.index '--gem_path'
767
- current_home = ENV['OPENSTUDIO_GEM_PATH']
768
- $logger.warn "Overwriting previous OPENSTUDIO_GEM_PATH of #{current_home} to #{new_home} for this command" if current_home
769
- $logger.info "No current gem path set in OPENSTUDIO_GEM_PATH, setting to #{new_home}" unless current_home
770
- ENV['OPENSTUDIO_GEM_PATH'] = new_home
771
- end
772
-
773
- # Configure Gems to load the correct Gem files
774
- # @see http://rubygems.rubyforge.org/rubygems-update/Gem.html
775
- local_dir = ENV['OPENSTUDIO_GEM_PATH'] ? ENV['OPENSTUDIO_GEM_PATH'] : "~/OpenStudio/v#{OpenStudio.openStudioVersion}"
776
- local_dir = File.absolute_path(local_dir)
777
- ENV['GEM_PATH'] = OpenStudio::Workflow::Util::IO.is_windows? ? local_dir.tr('/', '\\') : local_dir
778
- $logger.debug "Set environment variable GEM_PATH to #{ENV['GEM_PATH']}"
779
- ENV['GEM_HOME'] = OpenStudio::Workflow::Util::IO.is_windows? ? '\\' : '/'
780
- $logger.debug "Set environment variable GEM_HOME to #{ENV['GEM_HOME']}"
781
- Gem.clear_paths
782
- $logger.debug 'Reset Gem paths; openstudio_cli associated gems should load correctly'
783
-
784
- # Execute the CLI interface, and exit with the proper error code
785
- $logger.info "Executing argv: #{$argv}"
786
- CLI.new($argv).execute