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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +72 -72
- data/README.md +93 -48
- data/Rakefile +36 -36
- data/lib/openstudio-workflow.rb +49 -49
- data/lib/openstudio/workflow/adapters/input/local.rb +244 -240
- data/lib/openstudio/workflow/adapters/output/local.rb +95 -95
- data/lib/openstudio/workflow/adapters/output/socket.rb +91 -91
- data/lib/openstudio/workflow/adapters/output/web.rb +66 -66
- data/lib/openstudio/workflow/adapters/output_adapter.rb +147 -147
- data/lib/openstudio/workflow/job.rb +22 -22
- data/lib/openstudio/workflow/jobs/resources/monthly_report.idf +222 -222
- data/lib/openstudio/workflow/jobs/run_energyplus.rb +49 -49
- data/lib/openstudio/workflow/jobs/run_ep_measures.rb +55 -55
- data/lib/openstudio/workflow/jobs/run_initialization.rb +169 -167
- data/lib/openstudio/workflow/jobs/run_os_measures.rb +69 -69
- data/lib/openstudio/workflow/jobs/run_postprocess.rb +53 -53
- data/lib/openstudio/workflow/jobs/run_preprocess.rb +69 -69
- data/lib/openstudio/workflow/jobs/run_reporting_measures.rb +98 -98
- data/lib/openstudio/workflow/jobs/run_translation.rb +61 -61
- data/lib/openstudio/workflow/multi_delegator.rb +46 -46
- data/lib/openstudio/workflow/registry.rb +137 -137
- data/lib/openstudio/workflow/run.rb +299 -299
- data/lib/openstudio/workflow/time_logger.rb +53 -53
- data/lib/openstudio/workflow/util.rb +14 -14
- data/lib/openstudio/workflow/util/energyplus.rb +566 -564
- data/lib/openstudio/workflow/util/io.rb +33 -33
- data/lib/openstudio/workflow/util/measure.rb +588 -588
- data/lib/openstudio/workflow/util/model.rb +100 -100
- data/lib/openstudio/workflow/util/post_process.rb +187 -187
- data/lib/openstudio/workflow/util/weather_file.rb +108 -108
- data/lib/openstudio/workflow/version.rb +24 -24
- data/lib/openstudio/workflow_json.rb +426 -426
- data/lib/openstudio/workflow_runner.rb +233 -215
- metadata +3 -3
@@ -1,240 +1,244 @@
|
|
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 'openstudio/workflow_json'
|
21
|
-
|
22
|
-
# Local file based workflow
|
23
|
-
module OpenStudio
|
24
|
-
module Workflow
|
25
|
-
module InputAdapter
|
26
|
-
class Local
|
27
|
-
def initialize(osw_path = './workflow.osw')
|
28
|
-
@osw_abs_path = File.absolute_path(osw_path, Dir.pwd)
|
29
|
-
|
30
|
-
@workflow = nil
|
31
|
-
if File.exist? @osw_abs_path
|
32
|
-
@workflow = ::JSON.parse(File.read(@osw_abs_path), symbolize_names: true)
|
33
|
-
end
|
34
|
-
|
35
|
-
@workflow_json = nil
|
36
|
-
@run_options = nil
|
37
|
-
if @workflow
|
38
|
-
begin
|
39
|
-
# Create a temporary WorkflowJSON, will not be same one used in registry during simulation
|
40
|
-
@workflow_json = OpenStudio::WorkflowJSON.new(JSON.fast_generate(workflow))
|
41
|
-
@workflow_json.setOswDir(osw_dir)
|
42
|
-
rescue NameError => e
|
43
|
-
@workflow_json = WorkflowJSON_Shim.new(workflow, osw_dir)
|
44
|
-
end
|
45
|
-
|
46
|
-
begin
|
47
|
-
@run_options = @workflow_json.runOptions
|
48
|
-
rescue
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
# Get the OSW file from the local filesystem
|
54
|
-
#
|
55
|
-
def workflow
|
56
|
-
raise "Could not read workflow from #{@osw_abs_path}" if @workflow.nil?
|
57
|
-
@workflow
|
58
|
-
end
|
59
|
-
|
60
|
-
# Get the OSW path
|
61
|
-
#
|
62
|
-
def osw_path
|
63
|
-
@osw_abs_path
|
64
|
-
end
|
65
|
-
|
66
|
-
# Get the OSW dir
|
67
|
-
#
|
68
|
-
def osw_dir
|
69
|
-
File.dirname(@osw_abs_path)
|
70
|
-
end
|
71
|
-
|
72
|
-
# Get the run dir
|
73
|
-
#
|
74
|
-
def run_dir
|
75
|
-
result = File.join(osw_dir, 'run')
|
76
|
-
if @workflow_json
|
77
|
-
begin
|
78
|
-
result = @workflow_json.absoluteRunDir.to_s
|
79
|
-
rescue
|
80
|
-
end
|
81
|
-
end
|
82
|
-
result
|
83
|
-
end
|
84
|
-
|
85
|
-
def output_adapter(user_options, default, logger)
|
86
|
-
|
87
|
-
# user option trumps all others
|
88
|
-
return user_options[:output_adapter] if user_options[:output_adapter]
|
89
|
-
|
90
|
-
# try to read from OSW
|
91
|
-
if @run_options && !@run_options.empty?
|
92
|
-
custom_adapter = @run_options.get.customOutputAdapter
|
93
|
-
if !custom_adapter.empty?
|
94
|
-
begin
|
95
|
-
custom_file_name = custom_adapter.get.customFileName
|
96
|
-
class_name = custom_adapter.get.className
|
97
|
-
options = ::JSON.parse(custom_adapter.get.options, :symbolize_names => true)
|
98
|
-
|
99
|
-
# merge with user options, user options will replace options loaded from OSW
|
100
|
-
options.merge!(user_options)
|
101
|
-
|
102
|
-
# stick output_directory in options
|
103
|
-
options[:output_directory] = run_dir
|
104
|
-
|
105
|
-
p = @workflow_json.findFile(custom_file_name)
|
106
|
-
if !p.empty?
|
107
|
-
load(p.get.to_s)
|
108
|
-
output_adapter = eval("#{class_name}.new(options)")
|
109
|
-
return output_adapter
|
110
|
-
else
|
111
|
-
log_message = "Failed to load custom adapter file '#{custom_file_name}'"
|
112
|
-
logger.error log_message
|
113
|
-
raise log_message
|
114
|
-
end
|
115
|
-
rescue
|
116
|
-
log_message = "Failed to load custom adapter '#{class_name}' from file '#{custom_file_name}'"
|
117
|
-
logger.error log_message
|
118
|
-
raise log_message
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
return default
|
124
|
-
end
|
125
|
-
|
126
|
-
def jobs(user_options, default, logger)
|
127
|
-
|
128
|
-
# user option trumps all others
|
129
|
-
return user_options[:jobs] if user_options[:jobs]
|
130
|
-
|
131
|
-
# try to read from OSW
|
132
|
-
begin
|
133
|
-
#log_message = "Reading custom job states from OSW is not currently supported'"
|
134
|
-
#logger.info log_message
|
135
|
-
rescue
|
136
|
-
end
|
137
|
-
|
138
|
-
return default
|
139
|
-
end
|
140
|
-
|
141
|
-
def debug(user_options, default)
|
142
|
-
|
143
|
-
# user option trumps all others
|
144
|
-
return user_options[:debug] if user_options[:debug]
|
145
|
-
|
146
|
-
# try to read from OSW
|
147
|
-
if @run_options && !@run_options.empty?
|
148
|
-
return @run_options.get.debug
|
149
|
-
end
|
150
|
-
|
151
|
-
return default
|
152
|
-
end
|
153
|
-
|
154
|
-
def preserve_run_dir(user_options, default)
|
155
|
-
|
156
|
-
# user option trumps all others
|
157
|
-
return user_options[:preserve_run_dir] if user_options[:preserve_run_dir]
|
158
|
-
|
159
|
-
# try to read from OSW
|
160
|
-
if @run_options && !@run_options.empty?
|
161
|
-
return @run_options.get.preserveRunDir
|
162
|
-
end
|
163
|
-
|
164
|
-
return default
|
165
|
-
end
|
166
|
-
|
167
|
-
def cleanup(user_options, default)
|
168
|
-
|
169
|
-
# user option trumps all others
|
170
|
-
return user_options[:cleanup] if user_options[:cleanup]
|
171
|
-
|
172
|
-
# try to read from OSW
|
173
|
-
if @run_options && !@run_options.empty?
|
174
|
-
return @run_options.get.cleanup
|
175
|
-
end
|
176
|
-
|
177
|
-
return default
|
178
|
-
end
|
179
|
-
|
180
|
-
def energyplus_path(user_options, default)
|
181
|
-
|
182
|
-
# user option trumps all others
|
183
|
-
return user_options[:energyplus_path] if user_options[:energyplus_path]
|
184
|
-
|
185
|
-
return default
|
186
|
-
end
|
187
|
-
|
188
|
-
def profile(user_options, default)
|
189
|
-
|
190
|
-
# user option trumps all others
|
191
|
-
return user_options[:profile] if user_options[:profile]
|
192
|
-
|
193
|
-
return default
|
194
|
-
end
|
195
|
-
|
196
|
-
def verify_osw(user_options, default)
|
197
|
-
|
198
|
-
# user option trumps all others
|
199
|
-
return user_options[:verify_osw] if user_options[:verify_osw]
|
200
|
-
|
201
|
-
return default
|
202
|
-
end
|
203
|
-
|
204
|
-
def weather_file(user_options, default)
|
205
|
-
|
206
|
-
# user option trumps all others
|
207
|
-
return user_options[:weather_file] if user_options[:weather_file]
|
208
|
-
|
209
|
-
# try to read from OSW
|
210
|
-
if !@workflow_json.weatherFile.empty?
|
211
|
-
return @workflow_json.weatherFile.get.to_s
|
212
|
-
end
|
213
|
-
|
214
|
-
return default
|
215
|
-
end
|
216
|
-
|
217
|
-
# Get the associated OSD (datapoint) file from the local filesystem
|
218
|
-
#
|
219
|
-
def datapoint
|
220
|
-
# DLM: should this come from the OSW? the osd id and checksum are specified there.
|
221
|
-
osd_abs_path = File.join(osw_dir, 'datapoint.osd')
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
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 'openstudio/workflow_json'
|
21
|
+
|
22
|
+
# Local file based workflow
|
23
|
+
module OpenStudio
|
24
|
+
module Workflow
|
25
|
+
module InputAdapter
|
26
|
+
class Local
|
27
|
+
def initialize(osw_path = './workflow.osw')
|
28
|
+
@osw_abs_path = File.absolute_path(osw_path, Dir.pwd)
|
29
|
+
|
30
|
+
@workflow = nil
|
31
|
+
if File.exist? @osw_abs_path
|
32
|
+
@workflow = ::JSON.parse(File.read(@osw_abs_path), symbolize_names: true)
|
33
|
+
end
|
34
|
+
|
35
|
+
@workflow_json = nil
|
36
|
+
@run_options = nil
|
37
|
+
if @workflow
|
38
|
+
begin
|
39
|
+
# Create a temporary WorkflowJSON, will not be same one used in registry during simulation
|
40
|
+
@workflow_json = OpenStudio::WorkflowJSON.new(JSON.fast_generate(workflow))
|
41
|
+
@workflow_json.setOswDir(osw_dir)
|
42
|
+
rescue NameError => e
|
43
|
+
@workflow_json = WorkflowJSON_Shim.new(workflow, osw_dir)
|
44
|
+
end
|
45
|
+
|
46
|
+
begin
|
47
|
+
@run_options = @workflow_json.runOptions
|
48
|
+
rescue
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Get the OSW file from the local filesystem
|
54
|
+
#
|
55
|
+
def workflow
|
56
|
+
raise "Could not read workflow from #{@osw_abs_path}" if @workflow.nil?
|
57
|
+
@workflow
|
58
|
+
end
|
59
|
+
|
60
|
+
# Get the OSW path
|
61
|
+
#
|
62
|
+
def osw_path
|
63
|
+
@osw_abs_path
|
64
|
+
end
|
65
|
+
|
66
|
+
# Get the OSW dir
|
67
|
+
#
|
68
|
+
def osw_dir
|
69
|
+
File.dirname(@osw_abs_path)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Get the run dir
|
73
|
+
#
|
74
|
+
def run_dir
|
75
|
+
result = File.join(osw_dir, 'run')
|
76
|
+
if @workflow_json
|
77
|
+
begin
|
78
|
+
result = @workflow_json.absoluteRunDir.to_s
|
79
|
+
rescue
|
80
|
+
end
|
81
|
+
end
|
82
|
+
result
|
83
|
+
end
|
84
|
+
|
85
|
+
def output_adapter(user_options, default, logger)
|
86
|
+
|
87
|
+
# user option trumps all others
|
88
|
+
return user_options[:output_adapter] if user_options[:output_adapter]
|
89
|
+
|
90
|
+
# try to read from OSW
|
91
|
+
if @run_options && !@run_options.empty?
|
92
|
+
custom_adapter = @run_options.get.customOutputAdapter
|
93
|
+
if !custom_adapter.empty?
|
94
|
+
begin
|
95
|
+
custom_file_name = custom_adapter.get.customFileName
|
96
|
+
class_name = custom_adapter.get.className
|
97
|
+
options = ::JSON.parse(custom_adapter.get.options, :symbolize_names => true)
|
98
|
+
|
99
|
+
# merge with user options, user options will replace options loaded from OSW
|
100
|
+
options.merge!(user_options)
|
101
|
+
|
102
|
+
# stick output_directory in options
|
103
|
+
options[:output_directory] = run_dir
|
104
|
+
|
105
|
+
p = @workflow_json.findFile(custom_file_name)
|
106
|
+
if !p.empty?
|
107
|
+
load(p.get.to_s)
|
108
|
+
output_adapter = eval("#{class_name}.new(options)")
|
109
|
+
return output_adapter
|
110
|
+
else
|
111
|
+
log_message = "Failed to load custom adapter file '#{custom_file_name}'"
|
112
|
+
logger.error log_message
|
113
|
+
raise log_message
|
114
|
+
end
|
115
|
+
rescue
|
116
|
+
log_message = "Failed to load custom adapter '#{class_name}' from file '#{custom_file_name}'"
|
117
|
+
logger.error log_message
|
118
|
+
raise log_message
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
return default
|
124
|
+
end
|
125
|
+
|
126
|
+
def jobs(user_options, default, logger)
|
127
|
+
|
128
|
+
# user option trumps all others
|
129
|
+
return user_options[:jobs] if user_options[:jobs]
|
130
|
+
|
131
|
+
# try to read from OSW
|
132
|
+
begin
|
133
|
+
#log_message = "Reading custom job states from OSW is not currently supported'"
|
134
|
+
#logger.info log_message
|
135
|
+
rescue
|
136
|
+
end
|
137
|
+
|
138
|
+
return default
|
139
|
+
end
|
140
|
+
|
141
|
+
def debug(user_options, default)
|
142
|
+
|
143
|
+
# user option trumps all others
|
144
|
+
return user_options[:debug] if user_options[:debug]
|
145
|
+
|
146
|
+
# try to read from OSW
|
147
|
+
if @run_options && !@run_options.empty?
|
148
|
+
return @run_options.get.debug
|
149
|
+
end
|
150
|
+
|
151
|
+
return default
|
152
|
+
end
|
153
|
+
|
154
|
+
def preserve_run_dir(user_options, default)
|
155
|
+
|
156
|
+
# user option trumps all others
|
157
|
+
return user_options[:preserve_run_dir] if user_options[:preserve_run_dir]
|
158
|
+
|
159
|
+
# try to read from OSW
|
160
|
+
if @run_options && !@run_options.empty?
|
161
|
+
return @run_options.get.preserveRunDir
|
162
|
+
end
|
163
|
+
|
164
|
+
return default
|
165
|
+
end
|
166
|
+
|
167
|
+
def cleanup(user_options, default)
|
168
|
+
|
169
|
+
# user option trumps all others
|
170
|
+
return user_options[:cleanup] if user_options[:cleanup]
|
171
|
+
|
172
|
+
# try to read from OSW
|
173
|
+
if @run_options && !@run_options.empty?
|
174
|
+
return @run_options.get.cleanup
|
175
|
+
end
|
176
|
+
|
177
|
+
return default
|
178
|
+
end
|
179
|
+
|
180
|
+
def energyplus_path(user_options, default)
|
181
|
+
|
182
|
+
# user option trumps all others
|
183
|
+
return user_options[:energyplus_path] if user_options[:energyplus_path]
|
184
|
+
|
185
|
+
return default
|
186
|
+
end
|
187
|
+
|
188
|
+
def profile(user_options, default)
|
189
|
+
|
190
|
+
# user option trumps all others
|
191
|
+
return user_options[:profile] if user_options[:profile]
|
192
|
+
|
193
|
+
return default
|
194
|
+
end
|
195
|
+
|
196
|
+
def verify_osw(user_options, default)
|
197
|
+
|
198
|
+
# user option trumps all others
|
199
|
+
return user_options[:verify_osw] if user_options[:verify_osw]
|
200
|
+
|
201
|
+
return default
|
202
|
+
end
|
203
|
+
|
204
|
+
def weather_file(user_options, default)
|
205
|
+
|
206
|
+
# user option trumps all others
|
207
|
+
return user_options[:weather_file] if user_options[:weather_file]
|
208
|
+
|
209
|
+
# try to read from OSW
|
210
|
+
if !@workflow_json.weatherFile.empty?
|
211
|
+
return @workflow_json.weatherFile.get.to_s
|
212
|
+
end
|
213
|
+
|
214
|
+
return default
|
215
|
+
end
|
216
|
+
|
217
|
+
# Get the associated OSD (datapoint) file from the local filesystem
|
218
|
+
#
|
219
|
+
def datapoint
|
220
|
+
# DLM: should this come from the OSW? the osd id and checksum are specified there.
|
221
|
+
osd_abs_path = File.join(osw_dir, 'datapoint.osd')
|
222
|
+
result = nil
|
223
|
+
if File.exist? osd_abs_path
|
224
|
+
result = ::JSON.parse(File.read(osd_abs_path), symbolize_names: true)
|
225
|
+
end
|
226
|
+
return result
|
227
|
+
end
|
228
|
+
|
229
|
+
# Get the associated OSA (analysis) definition from the local filesystem
|
230
|
+
#
|
231
|
+
def analysis
|
232
|
+
# DLM: should this come from the OSW? the osd id and checksum are specified there.
|
233
|
+
osa_abs_path = File.join(osw_dir, '../analysis.json')
|
234
|
+
result = nil
|
235
|
+
if File.exist? osa_abs_path
|
236
|
+
result = ::JSON.parse(File.read(osa_abs_path), symbolize_names: true)
|
237
|
+
end
|
238
|
+
return result
|
239
|
+
end
|
240
|
+
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|