openstudio-workflow 1.2.1 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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