openstudio-workflow 1.0.0 → 1.1.0

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.
@@ -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