openstudio-workflow 1.2.1 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +72 -72
  3. data/README.md +93 -48
  4. data/Rakefile +36 -36
  5. data/lib/openstudio-workflow.rb +49 -49
  6. data/lib/openstudio/workflow/adapters/input/local.rb +244 -240
  7. data/lib/openstudio/workflow/adapters/output/local.rb +95 -95
  8. data/lib/openstudio/workflow/adapters/output/socket.rb +91 -91
  9. data/lib/openstudio/workflow/adapters/output/web.rb +66 -66
  10. data/lib/openstudio/workflow/adapters/output_adapter.rb +147 -147
  11. data/lib/openstudio/workflow/job.rb +22 -22
  12. data/lib/openstudio/workflow/jobs/resources/monthly_report.idf +222 -222
  13. data/lib/openstudio/workflow/jobs/run_energyplus.rb +49 -49
  14. data/lib/openstudio/workflow/jobs/run_ep_measures.rb +55 -55
  15. data/lib/openstudio/workflow/jobs/run_initialization.rb +169 -167
  16. data/lib/openstudio/workflow/jobs/run_os_measures.rb +69 -69
  17. data/lib/openstudio/workflow/jobs/run_postprocess.rb +53 -53
  18. data/lib/openstudio/workflow/jobs/run_preprocess.rb +69 -69
  19. data/lib/openstudio/workflow/jobs/run_reporting_measures.rb +98 -98
  20. data/lib/openstudio/workflow/jobs/run_translation.rb +61 -61
  21. data/lib/openstudio/workflow/multi_delegator.rb +46 -46
  22. data/lib/openstudio/workflow/registry.rb +137 -137
  23. data/lib/openstudio/workflow/run.rb +299 -299
  24. data/lib/openstudio/workflow/time_logger.rb +53 -53
  25. data/lib/openstudio/workflow/util.rb +14 -14
  26. data/lib/openstudio/workflow/util/energyplus.rb +566 -564
  27. data/lib/openstudio/workflow/util/io.rb +33 -33
  28. data/lib/openstudio/workflow/util/measure.rb +588 -588
  29. data/lib/openstudio/workflow/util/model.rb +100 -100
  30. data/lib/openstudio/workflow/util/post_process.rb +187 -187
  31. data/lib/openstudio/workflow/util/weather_file.rb +108 -108
  32. data/lib/openstudio/workflow/version.rb +24 -24
  33. data/lib/openstudio/workflow_json.rb +426 -426
  34. data/lib/openstudio/workflow_runner.rb +233 -215
  35. metadata +3 -3
@@ -1,108 +1,108 @@
1
- module OpenStudio
2
- module Workflow
3
- module Util
4
- # The current precedence rules for weather files are defined in this module. Best practice is to only use the
5
- # #get_weather_file method, as it will be forward compatible
6
- #
7
- module WeatherFile
8
- # Returns the weather file with precedence
9
- #
10
- # @param [String] directory The directory to append all relative directories to, see #get_weather_file_from_fs
11
- # @param [String] wf The weather file being searched for. If not the name of the file this parameter should be
12
- # the absolute path specifying it's location
13
- # @param [Array] wf_search_array The set of precedence ordered relative directories to search for the wf in. A
14
- # typical entry might look like `['files', '../../files', '../../weather']`
15
- # @param [Object] model The OpenStudio::Model object to parse, see #get_weather_file_from_osm
16
- # @return [String, nil] The weather file with precedence if defined, nil if not, and a failure if the wf is
17
- # defined but not in the filesystem
18
- #
19
- def get_weather_file(directory, wf, wf_search_array, model, logger = nil)
20
- # TODO: this logic needs some updating, weather file should come from current model, found using search paths
21
- logger ||= ::Logger.new(STDOUT) unless logger
22
- if wf
23
- weather_file = get_weather_file_from_fs(directory, wf, wf_search_array, logger)
24
- raise 'Could not locate the weather file in the filesystem. Please see the log' if weather_file == false
25
- end
26
- weather_file = get_weather_file_from_osm(model, logger) if weather_file.nil?
27
- raise 'Could not locate the weather file in the filesystem. Please see the log' if weather_file == false
28
- logger.warn 'The weather file could not be determined. Please see the log for details' unless weather_file
29
- weather_file
30
- end
31
-
32
- private
33
-
34
- # Returns the weather file from the model. If the weather file is defined in the model, then
35
- # it checks the file paths to check if the model exists. This allows for a user to upload a
36
- # weather file in a measure and then have the measure's path be used for the weather file.
37
- #
38
- # @todo (rhorsey) verify the description of this method, as it seems suspect
39
- # @param [Object] model The OpenStudio::Model object to retrieve the weather file from
40
- # @return [nil,false, String] If the result is nil the weather file was not defined in the model, if the result
41
- # is false the weather file was set but could not be found on the filesystem, if a string the weather file was
42
- # defined and it's existence verified
43
- #
44
- def get_weather_file_from_osm(model, logger)
45
- wf = nil
46
- # grab the weather file out of the OSM if it exists
47
- if model.weatherFile.empty?
48
- logger.warn 'No weather file defined in the model'
49
- else
50
- p = model.weatherFile.get.path.get.to_s.gsub('file://', '')
51
- wf = if File.exist? p
52
- File.absolute_path(p)
53
- else
54
- # this is the weather file from the OSM model
55
- File.absolute_path(@model.weatherFile.get.path.get.to_s)
56
- end
57
- logger.info "The weather file path found in the model object: #{wf}"
58
- unless File.exist? wf
59
- logger.warn 'The weather file could not be found on the filesystem.'
60
- wf = false
61
- end
62
- end
63
- wf
64
- end
65
-
66
- # Returns the weather file defined in the OSW
67
- #
68
- # @param [String] directory The base directory to append all relative directories to
69
- # @param [String] wf The weather file being searched for. If not the name of the file this parameter should be
70
- # the absolute path specifying it's location
71
- # @param [Array] wf_search_array The set of precedence ordered relative directories to search for the wf in. A
72
- # typical entry might look like `['files', '../../files', '../../weather']`
73
- # @return [nil, false, String] If the result is nil the weather file was not defined in the workflow, if the
74
- # result is false the weather file was set but could not be found on the filesystem, if a string the weather
75
- # file was defined and it's existence verified. The order of precedence for paths is as follows: 1 - an
76
- # absolute path defined in wf, 2 - the wf_search_array, should it be defined, joined with the weather file and
77
- # appended to the directory, with each entry in the array searched until the wf is found
78
- #
79
- def get_weather_file_from_fs(directory, wf, wf_search_array, logger)
80
- raise "wf was defined as #{wf}. Please correct" unless wf
81
- weather_file = nil
82
- if Pathname.new(wf).absolute?
83
- weather_file = wf
84
- else
85
- wf_search_array.each do |wf_dir|
86
- logger.warn "The path #{wf_dir} does not exist" unless File.exist? File.join(directory, wf_dir)
87
- next unless File.exist? File.join(directory, wf_dir)
88
- if Dir.entries(File.join(directory, wf_dir)).include? File.basename(wf)
89
- weather_file = File.absolute_path(File.join(directory, wf_dir, wf))
90
- break
91
- end
92
- end
93
- end
94
- unless weather_file
95
- logger.warn 'The weather file was not found on the filesystem'
96
- return nil
97
- end
98
- logger.info "Weather file with precedence in the file system is #{weather_file}"
99
- unless File.exist? weather_file
100
- logger.warn 'The weather file could not be found on the filesystem'
101
- weather_file = false
102
- end
103
- weather_file
104
- end
105
- end
106
- end
107
- end
108
- end
1
+ module OpenStudio
2
+ module Workflow
3
+ module Util
4
+ # The current precedence rules for weather files are defined in this module. Best practice is to only use the
5
+ # #get_weather_file method, as it will be forward compatible
6
+ #
7
+ module WeatherFile
8
+ # Returns the weather file with precedence
9
+ #
10
+ # @param [String] directory The directory to append all relative directories to, see #get_weather_file_from_fs
11
+ # @param [String] wf The weather file being searched for. If not the name of the file this parameter should be
12
+ # the absolute path specifying it's location
13
+ # @param [Array] wf_search_array The set of precedence ordered relative directories to search for the wf in. A
14
+ # typical entry might look like `['files', '../../files', '../../weather']`
15
+ # @param [Object] model The OpenStudio::Model object to parse, see #get_weather_file_from_osm
16
+ # @return [String, nil] The weather file with precedence if defined, nil if not, and a failure if the wf is
17
+ # defined but not in the filesystem
18
+ #
19
+ def get_weather_file(directory, wf, wf_search_array, model, logger = nil)
20
+ # TODO: this logic needs some updating, weather file should come from current model, found using search paths
21
+ logger ||= ::Logger.new(STDOUT) unless logger
22
+ if wf
23
+ weather_file = get_weather_file_from_fs(directory, wf, wf_search_array, logger)
24
+ raise 'Could not locate the weather file in the filesystem. Please see the log' if weather_file == false
25
+ end
26
+ weather_file = get_weather_file_from_osm(model, logger) if weather_file.nil?
27
+ raise 'Could not locate the weather file in the filesystem. Please see the log' if weather_file == false
28
+ logger.warn 'The weather file could not be determined. Please see the log for details' unless weather_file
29
+ weather_file
30
+ end
31
+
32
+ private
33
+
34
+ # Returns the weather file from the model. If the weather file is defined in the model, then
35
+ # it checks the file paths to check if the model exists. This allows for a user to upload a
36
+ # weather file in a measure and then have the measure's path be used for the weather file.
37
+ #
38
+ # @todo (rhorsey) verify the description of this method, as it seems suspect
39
+ # @param [Object] model The OpenStudio::Model object to retrieve the weather file from
40
+ # @return [nil,false, String] If the result is nil the weather file was not defined in the model, if the result
41
+ # is false the weather file was set but could not be found on the filesystem, if a string the weather file was
42
+ # defined and it's existence verified
43
+ #
44
+ def get_weather_file_from_osm(model, logger)
45
+ wf = nil
46
+ # grab the weather file out of the OSM if it exists
47
+ if model.weatherFile.empty?
48
+ logger.warn 'No weather file defined in the model'
49
+ else
50
+ p = model.weatherFile.get.path.get.to_s.gsub('file://', '')
51
+ wf = if File.exist? p
52
+ File.absolute_path(p)
53
+ else
54
+ # this is the weather file from the OSM model
55
+ File.absolute_path(@model.weatherFile.get.path.get.to_s)
56
+ end
57
+ logger.info "The weather file path found in the model object: #{wf}"
58
+ unless File.exist? wf
59
+ logger.warn 'The weather file could not be found on the filesystem.'
60
+ wf = false
61
+ end
62
+ end
63
+ wf
64
+ end
65
+
66
+ # Returns the weather file defined in the OSW
67
+ #
68
+ # @param [String] directory The base directory to append all relative directories to
69
+ # @param [String] wf The weather file being searched for. If not the name of the file this parameter should be
70
+ # the absolute path specifying it's location
71
+ # @param [Array] wf_search_array The set of precedence ordered relative directories to search for the wf in. A
72
+ # typical entry might look like `['files', '../../files', '../../weather']`
73
+ # @return [nil, false, String] If the result is nil the weather file was not defined in the workflow, if the
74
+ # result is false the weather file was set but could not be found on the filesystem, if a string the weather
75
+ # file was defined and it's existence verified. The order of precedence for paths is as follows: 1 - an
76
+ # absolute path defined in wf, 2 - the wf_search_array, should it be defined, joined with the weather file and
77
+ # appended to the directory, with each entry in the array searched until the wf is found
78
+ #
79
+ def get_weather_file_from_fs(directory, wf, wf_search_array, logger)
80
+ raise "wf was defined as #{wf}. Please correct" unless wf
81
+ weather_file = nil
82
+ if Pathname.new(wf).absolute?
83
+ weather_file = wf
84
+ else
85
+ wf_search_array.each do |wf_dir|
86
+ logger.warn "The path #{wf_dir} does not exist" unless File.exist? File.join(directory, wf_dir)
87
+ next unless File.exist? File.join(directory, wf_dir)
88
+ if Dir.entries(File.join(directory, wf_dir)).include? File.basename(wf)
89
+ weather_file = File.absolute_path(File.join(directory, wf_dir, wf))
90
+ break
91
+ end
92
+ end
93
+ end
94
+ unless weather_file
95
+ logger.warn 'The weather file was not found on the filesystem'
96
+ return nil
97
+ end
98
+ logger.info "Weather file with precedence in the file system is #{weather_file}"
99
+ unless File.exist? weather_file
100
+ logger.warn 'The weather file could not be found on the filesystem'
101
+ weather_file = false
102
+ end
103
+ weather_file
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -1,24 +1,24 @@
1
- ######################################################################
2
- # Copyright (c) 2008-2014, Alliance for Sustainable Energy.
3
- # All rights reserved.
4
- #
5
- # This library is free software; you can redistribute it and/or
6
- # modify it under the terms of the GNU Lesser General Public
7
- # License as published by the Free Software Foundation; either
8
- # version 2.1 of the License, or (at your option) any later version.
9
- #
10
- # This library is distributed in the hope that it will be useful,
11
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
- # Lesser General Public License for more details.
14
- #
15
- # You should have received a copy of the GNU Lesser General Public
16
- # License along with this library; if not, write to the Free Software
17
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
- ######################################################################
19
-
20
- module OpenStudio
21
- module Workflow
22
- VERSION = '1.2.1'.freeze # Suffixes must have periods (not dashes)
23
- end
24
- end
1
+ ######################################################################
2
+ # Copyright (c) 2008-2014, Alliance for Sustainable Energy.
3
+ # All rights reserved.
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License as published by the Free Software Foundation; either
8
+ # version 2.1 of the License, or (at your option) any later version.
9
+ #
10
+ # This library is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ # Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public
16
+ # License along with this library; if not, write to the Free Software
17
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
+ ######################################################################
19
+
20
+ module OpenStudio
21
+ module Workflow
22
+ VERSION = '1.2.2'.freeze # Suffixes must have periods (not dashes)
23
+ end
24
+ end
@@ -1,426 +1,426 @@
1
- ######################################################################
2
- # Copyright (c) 2008-2014, Alliance for Sustainable Energy.
3
- # All rights reserved.
4
- #
5
- # This library is free software; you can redistribute it and/or
6
- # modify it under the terms of the GNU Lesser General Public
7
- # License as published by the Free Software Foundation; either
8
- # version 2.1 of the License, or (at your option) any later version.
9
- #
10
- # This library is distributed in the hope that it will be useful,
11
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
- # Lesser General Public License for more details.
14
- #
15
- # You should have received a copy of the GNU Lesser General Public
16
- # License along with this library; if not, write to the Free Software
17
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
- ######################################################################
19
-
20
- require 'pathname'
21
-
22
- # Optional_Shim provides a wrapper that looks like an OpenStudio Optional
23
- class Optional_Shim
24
- def initialize(obj)
25
- @obj = obj
26
- end
27
-
28
- def empty?
29
- @obj.nil?
30
- end
31
-
32
- def is_initialized
33
- !@obj.nil?
34
- end
35
-
36
- def get
37
- raise 'Uninitialized Optional_Shim' if @obj.nil?
38
- @obj
39
- end
40
- end
41
-
42
- s = ''
43
- unless s.respond_to?(:to_StepResult)
44
- class String
45
- def to_StepResult
46
- self
47
- end
48
- end
49
- end
50
- unless s.respond_to?(:to_VariantType)
51
- class String
52
- def to_VariantType
53
- self
54
- end
55
- end
56
- end
57
- unless s.respond_to?(:valueName)
58
- class String
59
- def valueName
60
- self
61
- end
62
- end
63
- end
64
-
65
- # WorkflowStepResultValue_Shim provides a shim interface to the WorkflowStepResultValue class in OpenStudio 2.X when running in OpenStudio 1.X
66
- class WorkflowStepResultValue_Shim
67
- def initialize(name, value, type)
68
- @name = name
69
- @value = value
70
- @type = type
71
- end
72
-
73
- attr_reader :name
74
-
75
- attr_reader :value
76
-
77
- def variantType
78
- @type
79
- end
80
-
81
- def valueAsString
82
- @value.to_s
83
- end
84
-
85
- def valueAsDouble
86
- @value.to_f
87
- end
88
-
89
- def valueAsInteger
90
- @value.to_i
91
- end
92
-
93
- def valueAsBoolean
94
- @value
95
- end
96
- end
97
-
98
- # WorkflowStepResult_Shim provides a shim interface to the WorkflowStepResult class in OpenStudio 2.X when running in OpenStudio 1.X
99
- class WorkflowStepResult_Shim
100
- def initialize(result)
101
- @result = result
102
- end
103
-
104
- def stepInitialCondition
105
- if @result[:initial_condition]
106
- return Optional_Shim.new(@result[:initial_condition])
107
- end
108
- return Optional_Shim.new(nil)
109
- end
110
-
111
- def stepFinalCondition
112
- if @result[:final_condition]
113
- return Optional_Shim.new(@result[:final_condition])
114
- end
115
- return Optional_Shim.new(nil)
116
- end
117
-
118
- def stepErrors
119
- return @result[:step_errors]
120
- end
121
-
122
- def stepWarnings
123
- return @result[:step_warnings]
124
- end
125
-
126
- def stepInfo
127
- return @result[:step_info]
128
- end
129
-
130
- def stepValues
131
- result = []
132
- @result[:step_values].each do |step_value|
133
- result << WorkflowStepResultValue_Shim.new(step_value[:name], step_value[:value], step_value[:type])
134
- end
135
- return result
136
- end
137
-
138
- def stepResult
139
- Optional_Shim.new(@result[:step_result])
140
- end
141
-
142
- def setStepResult(step_result)
143
- @result[:step_result] = step_result
144
- end
145
-
146
- end
147
-
148
- # WorkflowStep_Shim provides a shim interface to the WorkflowStep class in OpenStudio 2.X when running in OpenStudio 1.X
149
- class WorkflowStep_Shim
150
- def initialize(step)
151
- @step = step
152
- end
153
-
154
- attr_reader :step
155
-
156
- def result
157
- if @step[:result]
158
- Optional_Shim.new(WorkflowStepResult_Shim.new(@step[:result]))
159
- else
160
- Optional_Shim.new
161
- end
162
- end
163
-
164
- # std::string measureDirName() const;
165
- def measureDirName
166
- @step[:measure_dir_name]
167
- end
168
-
169
- # std::map<std::string, Variant> arguments() const;
170
- def arguments
171
- # TODO: match C++
172
- @step[:arguments]
173
- end
174
- end
175
-
176
- # WorkflowJSON_Shim provides a shim interface to the WorkflowJSON class in OpenStudio 2.X when running in OpenStudio 1.X
177
- class WorkflowJSON_Shim
178
- def initialize(workflow, osw_dir)
179
- @workflow = workflow
180
- @osw_dir = osw_dir
181
- @current_step_index = 0
182
- end
183
-
184
- # std::string string(bool includeHash=true) const;
185
- def string
186
- JSON.fast_generate(@workflow)
187
- end
188
-
189
- def timeString
190
- ::Time.now.utc.strftime("%Y%m%dT%H%M%SZ")
191
- end
192
-
193
- # Returns the absolute path to the directory this workflow was loaded from or saved to. Returns current working dir for new WorkflowJSON.
194
- # openstudio::path oswDir() const;
195
- def oswDir
196
- OpenStudio.toPath(@osw_dir)
197
- end
198
-
199
- def saveAs(path)
200
- File.open(path.to_s, 'w') do |file|
201
- file << JSON.pretty_generate(@workflow)
202
- end
203
- end
204
-
205
- # Sets the started at time.
206
- def start
207
- @workflow[:started_at] = timeString
208
- end
209
-
210
- # Get the current step index.
211
- def currentStepIndex
212
- @current_step_index
213
- end
214
-
215
- # Get the current step.
216
- # boost::optional<WorkflowStep> currentStep() const;
217
- def currentStep
218
- steps = @workflow[:steps]
219
-
220
- step = nil
221
- if @current_step_index < steps.size
222
- step = WorkflowStep_Shim.new(steps[@current_step_index])
223
- end
224
- return Optional_Shim.new(step)
225
- end
226
-
227
- # Increments current step, returns true if there is another step.
228
- # bool incrementStep();
229
- def incrementStep
230
- @current_step_index += 1
231
-
232
- if @current_step_index < @workflow[:steps].size
233
- return true
234
- end
235
-
236
- return false
237
- end
238
-
239
- # Returns the root directory, default value is '.'. Evaluated relative to oswDir if not absolute.
240
- # openstudio::path rootDir() const;
241
- # openstudio::path absoluteRootDir() const;
242
- def rootDir
243
- if @workflow[:root_dir]
244
- OpenStudio.toPath(@workflow[:root_dir])
245
- else
246
- OpenStudio.toPath(@osw_dir)
247
- end
248
- end
249
-
250
- def absoluteRootDir
251
- OpenStudio.toPath(File.absolute_path(rootDir.to_s, @osw_dir.to_s))
252
- end
253
-
254
- # Returns the run directory, default value is './run'. Evaluated relative to rootDir if not absolute.
255
- # openstudio::path runDir() const;
256
- # openstudio::path absoluteRunDir() const;
257
- def runDir
258
- if @workflow[:run_directory]
259
- OpenStudio.toPath(@workflow[:run_directory])
260
- else
261
- OpenStudio.toPath('./run')
262
- end
263
- end
264
-
265
- def absoluteRunDir
266
- OpenStudio.toPath(File.absolute_path(runDir.to_s, rootDir.to_s))
267
- end
268
-
269
- def outPath
270
- if @workflow[:out_name]
271
- OpenStudio.toPath(@workflow[:out_name])
272
- else
273
- OpenStudio.toPath('./out.osw')
274
- end
275
- end
276
-
277
- def absoluteOutPath
278
- OpenStudio.toPath(File.absolute_path(outPath.to_s, oswDir.to_s))
279
- end
280
-
281
- # Returns the paths that will be searched in order for files, default value is './files/'. Evaluated relative to rootDir if not absolute.
282
- # std::vector<openstudio::path> filePaths() const;
283
- # std::vector<openstudio::path> absoluteFilePaths() const;
284
- def filePaths
285
- result = OpenStudio::PathVector.new
286
- if @workflow[:file_paths]
287
- @workflow[:file_paths].each do |file_path|
288
- result << OpenStudio.toPath(file_path)
289
- end
290
- else
291
- result << OpenStudio.toPath('./files')
292
- result << OpenStudio.toPath('./weather')
293
- result << OpenStudio.toPath('../../files')
294
- result << OpenStudio.toPath('../../weather')
295
- result << OpenStudio.toPath('./')
296
- end
297
- result
298
- end
299
-
300
- def absoluteFilePaths
301
- result = OpenStudio::PathVector.new
302
- filePaths.each do |file_path|
303
- result << OpenStudio.toPath(File.absolute_path(file_path.to_s, rootDir.to_s))
304
- end
305
- result
306
- end
307
-
308
- # Attempts to find a file by name, searches through filePaths in order and returns first match.
309
- # boost::optional<openstudio::path> findFile(const openstudio::path& file);
310
- # boost::optional<openstudio::path> findFile(const std::string& fileName);
311
- def findFile(file)
312
- file = file.to_s
313
-
314
- # check if absolute and exists
315
- if Pathname.new(file).absolute?
316
- if File.exist?(file)
317
- return OpenStudio::OptionalPath.new(OpenStudio.toPath(file))
318
- end
319
-
320
- # absolute path does not exist
321
- return OpenStudio::OptionalPath.new
322
- end
323
-
324
- absoluteFilePaths.each do |file_path|
325
- result = File.join(file_path.to_s, file)
326
- if File.exist?(result)
327
- return OpenStudio::OptionalPath.new(OpenStudio.toPath(result))
328
- end
329
- end
330
- OpenStudio::OptionalPath.new
331
- end
332
-
333
- # Returns the paths that will be searched in order for measures, default value is './measures/'. Evaluated relative to rootDir if not absolute.
334
- # std::vector<openstudio::path> measurePaths() const;
335
- # std::vector<openstudio::path> absoluteMeasurePaths() const;
336
- def measurePaths
337
- result = OpenStudio::PathVector.new
338
- if @workflow[:measure_paths]
339
- @workflow[:measure_paths].each do |measure_path|
340
- result << OpenStudio.toPath(measure_path)
341
- end
342
- else
343
- result << OpenStudio.toPath('./measures')
344
- result << OpenStudio.toPath('../../measures')
345
- result << OpenStudio.toPath('./')
346
- end
347
- result
348
- end
349
-
350
- def absoluteMeasurePaths
351
- result = OpenStudio::PathVector.new
352
- measurePaths.each do |measure_path|
353
- result << OpenStudio.toPath(File.absolute_path(measure_path.to_s, rootDir.to_s))
354
- end
355
- result
356
- end
357
-
358
- # Attempts to find a measure by name, searches through measurePaths in order and returns first match. */
359
- # boost::optional<openstudio::path> findMeasure(const openstudio::path& measureDir);
360
- # boost::optional<openstudio::path> findMeasure(const std::string& measureDirName);
361
- def findMeasure(measureDir)
362
- measureDir = measureDir.to_s
363
-
364
- # check if absolute and exists
365
- if Pathname.new(measureDir).absolute?
366
- if File.exist?(measureDir)
367
- return OpenStudio::OptionalPath.new(OpenStudio.toPath(measureDir))
368
- end
369
-
370
- # absolute path does not exist
371
- return OpenStudio::OptionalPath.new
372
- end
373
-
374
- absoluteMeasurePaths.each do |measure_path|
375
- result = File.join(measure_path.to_s, measureDir)
376
- if File.exist?(result)
377
- return OpenStudio::OptionalPath.new(OpenStudio.toPath(result))
378
- end
379
- end
380
- OpenStudio::OptionalPath.new
381
- end
382
-
383
- # Returns the seed file path. Evaluated relative to filePaths if not absolute.
384
- # boost::optional<openstudio::path> seedFile() const;
385
- def seedFile
386
- result = OpenStudio::OptionalPath.new
387
- if @workflow[:seed_file]
388
- result = OpenStudio::OptionalPath.new(OpenStudio.toPath(@workflow[:seed_file]))
389
- end
390
- result
391
- end
392
-
393
- # Returns the weather file path. Evaluated relative to filePaths if not absolute.
394
- # boost::optional<openstudio::path> weatherFile() const;
395
- def weatherFile
396
- result = OpenStudio::OptionalPath.new
397
- if @workflow[:weather_file]
398
- result = OpenStudio::OptionalPath.new(OpenStudio.toPath(@workflow[:weather_file]))
399
- end
400
- result
401
- end
402
-
403
- # Returns the workflow steps. */
404
- # std::vector<WorkflowStep> workflowSteps() const;
405
- def workflowSteps
406
- result = []
407
- @workflow[:steps].each do |step|
408
- result << WorkflowStep_Shim.new(step)
409
- end
410
- result
411
- end
412
-
413
- def setCompletedStatus(status)
414
- @workflow[:completed_status] = status
415
- @workflow[:completed_at] = timeString
416
- end
417
-
418
- def setEplusoutErr(eplusout_err)
419
- @workflow[:eplusout_err] = eplusout_err
420
- end
421
-
422
- # return empty optional
423
- def runOptions
424
- return Optional_Shim.new(nil)
425
- end
426
- end
1
+ ######################################################################
2
+ # Copyright (c) 2008-2014, Alliance for Sustainable Energy.
3
+ # All rights reserved.
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License as published by the Free Software Foundation; either
8
+ # version 2.1 of the License, or (at your option) any later version.
9
+ #
10
+ # This library is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ # Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public
16
+ # License along with this library; if not, write to the Free Software
17
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
+ ######################################################################
19
+
20
+ require 'pathname'
21
+
22
+ # Optional_Shim provides a wrapper that looks like an OpenStudio Optional
23
+ class Optional_Shim
24
+ def initialize(obj)
25
+ @obj = obj
26
+ end
27
+
28
+ def empty?
29
+ @obj.nil?
30
+ end
31
+
32
+ def is_initialized
33
+ !@obj.nil?
34
+ end
35
+
36
+ def get
37
+ raise 'Uninitialized Optional_Shim' if @obj.nil?
38
+ @obj
39
+ end
40
+ end
41
+
42
+ s = ''
43
+ unless s.respond_to?(:to_StepResult)
44
+ class String
45
+ def to_StepResult
46
+ self
47
+ end
48
+ end
49
+ end
50
+ unless s.respond_to?(:to_VariantType)
51
+ class String
52
+ def to_VariantType
53
+ self
54
+ end
55
+ end
56
+ end
57
+ unless s.respond_to?(:valueName)
58
+ class String
59
+ def valueName
60
+ self
61
+ end
62
+ end
63
+ end
64
+
65
+ # WorkflowStepResultValue_Shim provides a shim interface to the WorkflowStepResultValue class in OpenStudio 2.X when running in OpenStudio 1.X
66
+ class WorkflowStepResultValue_Shim
67
+ def initialize(name, value, type)
68
+ @name = name
69
+ @value = value
70
+ @type = type
71
+ end
72
+
73
+ attr_reader :name
74
+
75
+ attr_reader :value
76
+
77
+ def variantType
78
+ @type
79
+ end
80
+
81
+ def valueAsString
82
+ @value.to_s
83
+ end
84
+
85
+ def valueAsDouble
86
+ @value.to_f
87
+ end
88
+
89
+ def valueAsInteger
90
+ @value.to_i
91
+ end
92
+
93
+ def valueAsBoolean
94
+ @value
95
+ end
96
+ end
97
+
98
+ # WorkflowStepResult_Shim provides a shim interface to the WorkflowStepResult class in OpenStudio 2.X when running in OpenStudio 1.X
99
+ class WorkflowStepResult_Shim
100
+ def initialize(result)
101
+ @result = result
102
+ end
103
+
104
+ def stepInitialCondition
105
+ if @result[:initial_condition]
106
+ return Optional_Shim.new(@result[:initial_condition])
107
+ end
108
+ return Optional_Shim.new(nil)
109
+ end
110
+
111
+ def stepFinalCondition
112
+ if @result[:final_condition]
113
+ return Optional_Shim.new(@result[:final_condition])
114
+ end
115
+ return Optional_Shim.new(nil)
116
+ end
117
+
118
+ def stepErrors
119
+ return @result[:step_errors]
120
+ end
121
+
122
+ def stepWarnings
123
+ return @result[:step_warnings]
124
+ end
125
+
126
+ def stepInfo
127
+ return @result[:step_info]
128
+ end
129
+
130
+ def stepValues
131
+ result = []
132
+ @result[:step_values].each do |step_value|
133
+ result << WorkflowStepResultValue_Shim.new(step_value[:name], step_value[:value], step_value[:type])
134
+ end
135
+ return result
136
+ end
137
+
138
+ def stepResult
139
+ Optional_Shim.new(@result[:step_result])
140
+ end
141
+
142
+ def setStepResult(step_result)
143
+ @result[:step_result] = step_result
144
+ end
145
+
146
+ end
147
+
148
+ # WorkflowStep_Shim provides a shim interface to the WorkflowStep class in OpenStudio 2.X when running in OpenStudio 1.X
149
+ class WorkflowStep_Shim
150
+ def initialize(step)
151
+ @step = step
152
+ end
153
+
154
+ attr_reader :step
155
+
156
+ def result
157
+ if @step[:result]
158
+ Optional_Shim.new(WorkflowStepResult_Shim.new(@step[:result]))
159
+ else
160
+ Optional_Shim.new
161
+ end
162
+ end
163
+
164
+ # std::string measureDirName() const;
165
+ def measureDirName
166
+ @step[:measure_dir_name]
167
+ end
168
+
169
+ # std::map<std::string, Variant> arguments() const;
170
+ def arguments
171
+ # TODO: match C++
172
+ @step[:arguments]
173
+ end
174
+ end
175
+
176
+ # WorkflowJSON_Shim provides a shim interface to the WorkflowJSON class in OpenStudio 2.X when running in OpenStudio 1.X
177
+ class WorkflowJSON_Shim
178
+ def initialize(workflow, osw_dir)
179
+ @workflow = workflow
180
+ @osw_dir = osw_dir
181
+ @current_step_index = 0
182
+ end
183
+
184
+ # std::string string(bool includeHash=true) const;
185
+ def string
186
+ JSON.fast_generate(@workflow)
187
+ end
188
+
189
+ def timeString
190
+ ::Time.now.utc.strftime("%Y%m%dT%H%M%SZ")
191
+ end
192
+
193
+ # Returns the absolute path to the directory this workflow was loaded from or saved to. Returns current working dir for new WorkflowJSON.
194
+ # openstudio::path oswDir() const;
195
+ def oswDir
196
+ OpenStudio.toPath(@osw_dir)
197
+ end
198
+
199
+ def saveAs(path)
200
+ File.open(path.to_s, 'w') do |file|
201
+ file << JSON.pretty_generate(@workflow)
202
+ end
203
+ end
204
+
205
+ # Sets the started at time.
206
+ def start
207
+ @workflow[:started_at] = timeString
208
+ end
209
+
210
+ # Get the current step index.
211
+ def currentStepIndex
212
+ @current_step_index
213
+ end
214
+
215
+ # Get the current step.
216
+ # boost::optional<WorkflowStep> currentStep() const;
217
+ def currentStep
218
+ steps = @workflow[:steps]
219
+
220
+ step = nil
221
+ if @current_step_index < steps.size
222
+ step = WorkflowStep_Shim.new(steps[@current_step_index])
223
+ end
224
+ return Optional_Shim.new(step)
225
+ end
226
+
227
+ # Increments current step, returns true if there is another step.
228
+ # bool incrementStep();
229
+ def incrementStep
230
+ @current_step_index += 1
231
+
232
+ if @current_step_index < @workflow[:steps].size
233
+ return true
234
+ end
235
+
236
+ return false
237
+ end
238
+
239
+ # Returns the root directory, default value is '.'. Evaluated relative to oswDir if not absolute.
240
+ # openstudio::path rootDir() const;
241
+ # openstudio::path absoluteRootDir() const;
242
+ def rootDir
243
+ if @workflow[:root_dir]
244
+ OpenStudio.toPath(@workflow[:root_dir])
245
+ else
246
+ OpenStudio.toPath(@osw_dir)
247
+ end
248
+ end
249
+
250
+ def absoluteRootDir
251
+ OpenStudio.toPath(File.absolute_path(rootDir.to_s, @osw_dir.to_s))
252
+ end
253
+
254
+ # Returns the run directory, default value is './run'. Evaluated relative to rootDir if not absolute.
255
+ # openstudio::path runDir() const;
256
+ # openstudio::path absoluteRunDir() const;
257
+ def runDir
258
+ if @workflow[:run_directory]
259
+ OpenStudio.toPath(@workflow[:run_directory])
260
+ else
261
+ OpenStudio.toPath('./run')
262
+ end
263
+ end
264
+
265
+ def absoluteRunDir
266
+ OpenStudio.toPath(File.absolute_path(runDir.to_s, rootDir.to_s))
267
+ end
268
+
269
+ def outPath
270
+ if @workflow[:out_name]
271
+ OpenStudio.toPath(@workflow[:out_name])
272
+ else
273
+ OpenStudio.toPath('./out.osw')
274
+ end
275
+ end
276
+
277
+ def absoluteOutPath
278
+ OpenStudio.toPath(File.absolute_path(outPath.to_s, oswDir.to_s))
279
+ end
280
+
281
+ # Returns the paths that will be searched in order for files, default value is './files/'. Evaluated relative to rootDir if not absolute.
282
+ # std::vector<openstudio::path> filePaths() const;
283
+ # std::vector<openstudio::path> absoluteFilePaths() const;
284
+ def filePaths
285
+ result = OpenStudio::PathVector.new
286
+ if @workflow[:file_paths]
287
+ @workflow[:file_paths].each do |file_path|
288
+ result << OpenStudio.toPath(file_path)
289
+ end
290
+ else
291
+ result << OpenStudio.toPath('./files')
292
+ result << OpenStudio.toPath('./weather')
293
+ result << OpenStudio.toPath('../../files')
294
+ result << OpenStudio.toPath('../../weather')
295
+ result << OpenStudio.toPath('./')
296
+ end
297
+ result
298
+ end
299
+
300
+ def absoluteFilePaths
301
+ result = OpenStudio::PathVector.new
302
+ filePaths.each do |file_path|
303
+ result << OpenStudio.toPath(File.absolute_path(file_path.to_s, rootDir.to_s))
304
+ end
305
+ result
306
+ end
307
+
308
+ # Attempts to find a file by name, searches through filePaths in order and returns first match.
309
+ # boost::optional<openstudio::path> findFile(const openstudio::path& file);
310
+ # boost::optional<openstudio::path> findFile(const std::string& fileName);
311
+ def findFile(file)
312
+ file = file.to_s
313
+
314
+ # check if absolute and exists
315
+ if Pathname.new(file).absolute?
316
+ if File.exist?(file)
317
+ return OpenStudio::OptionalPath.new(OpenStudio.toPath(file))
318
+ end
319
+
320
+ # absolute path does not exist
321
+ return OpenStudio::OptionalPath.new
322
+ end
323
+
324
+ absoluteFilePaths.each do |file_path|
325
+ result = File.join(file_path.to_s, file)
326
+ if File.exist?(result)
327
+ return OpenStudio::OptionalPath.new(OpenStudio.toPath(result))
328
+ end
329
+ end
330
+ OpenStudio::OptionalPath.new
331
+ end
332
+
333
+ # Returns the paths that will be searched in order for measures, default value is './measures/'. Evaluated relative to rootDir if not absolute.
334
+ # std::vector<openstudio::path> measurePaths() const;
335
+ # std::vector<openstudio::path> absoluteMeasurePaths() const;
336
+ def measurePaths
337
+ result = OpenStudio::PathVector.new
338
+ if @workflow[:measure_paths]
339
+ @workflow[:measure_paths].each do |measure_path|
340
+ result << OpenStudio.toPath(measure_path)
341
+ end
342
+ else
343
+ result << OpenStudio.toPath('./measures')
344
+ result << OpenStudio.toPath('../../measures')
345
+ result << OpenStudio.toPath('./')
346
+ end
347
+ result
348
+ end
349
+
350
+ def absoluteMeasurePaths
351
+ result = OpenStudio::PathVector.new
352
+ measurePaths.each do |measure_path|
353
+ result << OpenStudio.toPath(File.absolute_path(measure_path.to_s, rootDir.to_s))
354
+ end
355
+ result
356
+ end
357
+
358
+ # Attempts to find a measure by name, searches through measurePaths in order and returns first match. */
359
+ # boost::optional<openstudio::path> findMeasure(const openstudio::path& measureDir);
360
+ # boost::optional<openstudio::path> findMeasure(const std::string& measureDirName);
361
+ def findMeasure(measureDir)
362
+ measureDir = measureDir.to_s
363
+
364
+ # check if absolute and exists
365
+ if Pathname.new(measureDir).absolute?
366
+ if File.exist?(measureDir)
367
+ return OpenStudio::OptionalPath.new(OpenStudio.toPath(measureDir))
368
+ end
369
+
370
+ # absolute path does not exist
371
+ return OpenStudio::OptionalPath.new
372
+ end
373
+
374
+ absoluteMeasurePaths.each do |measure_path|
375
+ result = File.join(measure_path.to_s, measureDir)
376
+ if File.exist?(result)
377
+ return OpenStudio::OptionalPath.new(OpenStudio.toPath(result))
378
+ end
379
+ end
380
+ OpenStudio::OptionalPath.new
381
+ end
382
+
383
+ # Returns the seed file path. Evaluated relative to filePaths if not absolute.
384
+ # boost::optional<openstudio::path> seedFile() const;
385
+ def seedFile
386
+ result = OpenStudio::OptionalPath.new
387
+ if @workflow[:seed_file]
388
+ result = OpenStudio::OptionalPath.new(OpenStudio.toPath(@workflow[:seed_file]))
389
+ end
390
+ result
391
+ end
392
+
393
+ # Returns the weather file path. Evaluated relative to filePaths if not absolute.
394
+ # boost::optional<openstudio::path> weatherFile() const;
395
+ def weatherFile
396
+ result = OpenStudio::OptionalPath.new
397
+ if @workflow[:weather_file]
398
+ result = OpenStudio::OptionalPath.new(OpenStudio.toPath(@workflow[:weather_file]))
399
+ end
400
+ result
401
+ end
402
+
403
+ # Returns the workflow steps. */
404
+ # std::vector<WorkflowStep> workflowSteps() const;
405
+ def workflowSteps
406
+ result = []
407
+ @workflow[:steps].each do |step|
408
+ result << WorkflowStep_Shim.new(step)
409
+ end
410
+ result
411
+ end
412
+
413
+ def setCompletedStatus(status)
414
+ @workflow[:completed_status] = status
415
+ @workflow[:completed_at] = timeString
416
+ end
417
+
418
+ def setEplusoutErr(eplusout_err)
419
+ @workflow[:eplusout_err] = eplusout_err
420
+ end
421
+
422
+ # return empty optional
423
+ def runOptions
424
+ return Optional_Shim.new(nil)
425
+ end
426
+ end