openstudio-workflow 1.0.0.pat1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/README.md +16 -68
  4. data/Rakefile +9 -9
  5. data/bin/openstudio_cli +786 -0
  6. data/lib/openstudio/workflow/adapters/input/local.rb +97 -0
  7. data/lib/openstudio/workflow/adapters/output/local.rb +90 -0
  8. data/lib/openstudio/workflow/adapters/output/socket.rb +70 -0
  9. data/lib/openstudio/workflow/{jobs/run_preflight/run_preflight.rb → adapters/output/web.rb} +37 -19
  10. data/lib/openstudio/workflow/{adapter.rb → adapters/output_adapter.rb} +53 -51
  11. data/lib/openstudio/workflow/job.rb +22 -0
  12. data/lib/openstudio/workflow/jobs/{run_energyplus → resources}/monthly_report.idf +0 -0
  13. data/lib/openstudio/workflow/jobs/run_energyplus.rb +49 -0
  14. data/lib/openstudio/workflow/jobs/run_ep_measures.rb +55 -0
  15. data/lib/openstudio/workflow/jobs/run_initialization.rb +136 -0
  16. data/lib/openstudio/workflow/jobs/run_os_measures.rb +59 -0
  17. data/lib/openstudio/workflow/jobs/run_postprocess.rb +53 -0
  18. data/lib/openstudio/workflow/jobs/run_preprocess.rb +81 -0
  19. data/lib/openstudio/workflow/jobs/run_reporting_measures.rb +86 -0
  20. data/lib/openstudio/workflow/jobs/run_translation.rb +49 -0
  21. data/lib/openstudio/workflow/multi_delegator.rb +1 -3
  22. data/lib/openstudio/workflow/registry.rb +137 -0
  23. data/lib/openstudio/workflow/run.rb +182 -221
  24. data/lib/openstudio/workflow/time_logger.rb +1 -1
  25. data/lib/openstudio/workflow/util/energyplus.rb +564 -0
  26. data/lib/openstudio/workflow/util/io.rb +33 -0
  27. data/lib/openstudio/workflow/util/measure.rb +520 -0
  28. data/lib/openstudio/workflow/util/model.rb +100 -0
  29. data/lib/openstudio/workflow/util/post_process.rb +177 -0
  30. data/lib/openstudio/workflow/util/weather_file.rb +108 -0
  31. data/lib/openstudio/workflow/util.rb +14 -0
  32. data/lib/openstudio/workflow/version.rb +1 -1
  33. data/lib/openstudio/workflow_json.rb +399 -0
  34. data/lib/openstudio/workflow_runner.rb +213 -0
  35. data/lib/openstudio-workflow.rb +13 -118
  36. metadata +45 -85
  37. data/lib/openstudio/extended_runner.rb +0 -105
  38. data/lib/openstudio/workflow/adapters/local.rb +0 -101
  39. data/lib/openstudio/workflow/adapters/mongo.rb +0 -227
  40. data/lib/openstudio/workflow/jobs/lib/apply_measures.rb +0 -253
  41. data/lib/openstudio/workflow/jobs/run_energyplus/run_energyplus.rb +0 -314
  42. data/lib/openstudio/workflow/jobs/run_openstudio/run_openstudio.rb +0 -230
  43. data/lib/openstudio/workflow/jobs/run_postprocess/run_postprocess.rb +0 -110
  44. data/lib/openstudio/workflow/jobs/run_reporting_measures/run_reporting_measures.rb +0 -471
  45. data/lib/openstudio/workflow/jobs/run_runmanager/run_runmanager.rb +0 -247
  46. data/lib/openstudio/workflow/jobs/run_xml/run_xml.rb +0 -279
@@ -0,0 +1,564 @@
1
+ module OpenStudio
2
+ module Workflow
3
+ module Util
4
+ # The methods needed to run simulations using EnergyPlus are stored here. See the run_simulation class for
5
+ # implementation details.
6
+ module EnergyPlus
7
+ require 'openstudio/workflow/util/io'
8
+ include OpenStudio::Workflow::Util::IO
9
+ ENERGYPLUS_REGEX = /^energyplus\D{0,4}$/i
10
+ EXPAND_OBJECTS_REGEX = /^expandobjects\D{0,4}$/i
11
+
12
+ # Find the installation directory of EnergyPlus linked to the OpenStudio version being used
13
+ #
14
+ # @return [String] Returns the path to EnergyPlus
15
+ #
16
+ def find_energyplus
17
+ path = OpenStudio.getEnergyPlusDirectory.to_s
18
+ raise 'Unable to find the EnergyPlus executable' unless File.exist? path
19
+ path
20
+ end
21
+
22
+ # Does something
23
+ #
24
+ # @param [String] run_directory Directory to run the EnergyPlus simulation in
25
+ # @param [Array] energyplus_files Array of files containing the EnergyPlus and ExpandObjects EXEs
26
+ # @return [Void]
27
+ #
28
+ def clean_directory(run_directory, energyplus_files, logger)
29
+ logger.info 'Removing any copied EnergyPlus files'
30
+ energyplus_files.each do |file|
31
+ if File.exist? file
32
+ FileUtils.rm_f file
33
+ end
34
+ end
35
+
36
+ paths_to_rm = []
37
+ paths_to_rm << "#{run_directory}/packaged_measures"
38
+ paths_to_rm << "#{run_directory}/Energy+.ini"
39
+ paths_to_rm.each { |p| FileUtils.rm_rf(p) if File.exist?(p) }
40
+ end
41
+
42
+ # Prepare the directory to run EnergyPlus
43
+ #
44
+ # @param [String] run_directory Directory to copy the required EnergyPlus files to
45
+ # @param [Object] logger Logger object
46
+ # @param [String] energyplus_path Path to the EnergyPlus EXE
47
+ # @return [Array, file, file] Returns an array of strings of EnergyPlus files copied to the run_directory, the
48
+ # ExpandObjects EXE file, and EnergyPlus EXE file
49
+ #
50
+ def prepare_energyplus_dir(run_directory, logger, energyplus_path = nil)
51
+ logger.info "Copying EnergyPlus files to run directory: #{run_directory}"
52
+ energyplus_path ||= find_energyplus
53
+ logger.info "EnergyPlus path is #{energyplus_path}"
54
+ energyplus_files = []
55
+ energyplus_exe, expand_objects_exe = nil
56
+ Dir["#{energyplus_path}/*"].each do |file|
57
+ next if File.directory? file
58
+ next if File.extname(file).downcase =~ /.pdf|.app|.html|.gif|.txt|.xlsx/
59
+
60
+ dest_file = "#{run_directory}/#{File.basename(file)}"
61
+ energyplus_files << dest_file
62
+
63
+ # @todo (rhorsey) don't need to do this copy - DLM
64
+ energyplus_exe = File.basename(dest_file) if File.basename(dest_file) =~ ENERGYPLUS_REGEX
65
+ expand_objects_exe = File.basename(dest_file) if File.basename(dest_file) =~ EXPAND_OBJECTS_REGEX
66
+ FileUtils.copy file, dest_file
67
+ end
68
+
69
+ raise "Could not find EnergyPlus executable in #{energyplus_path}" unless energyplus_exe
70
+ raise "Could not find ExpandObjects executable in #{energyplus_path}" unless expand_objects_exe
71
+
72
+ logger.info "EnergyPlus executable path is #{energyplus_exe}"
73
+ logger.info "ExpandObjects executable path is #{expand_objects_exe}"
74
+
75
+ return energyplus_files, energyplus_exe, expand_objects_exe
76
+ end
77
+
78
+ # Configures and executes the EnergyPlus simulation and checks to see if the simulation was successful
79
+ #
80
+ # @param [String] run_directory Directory to execute the EnergyPlus simulation in. It is assumed that this
81
+ # directory already has the IDF and weather file in it
82
+ # @param [String] energyplus_path (nil) Optional path to override the default path associated with the
83
+ # OpenStudio package being used
84
+ # @param [Object] output_adapter (nil) Optional output adapter to update
85
+ # @param [Object] logger (nil) Optional logger, will log to STDOUT if none provided
86
+ # @return [Void]
87
+ #
88
+ def call_energyplus(run_directory, energyplus_path = nil, output_adapter = nil, logger = nil, workflow_json = nil)
89
+ logger ||= ::Logger.new(STDOUT) unless logger
90
+
91
+ current_dir = Dir.pwd
92
+ energyplus_path ||= find_energyplus
93
+ logger.info "EnergyPlus path is #{energyplus_path}"
94
+ energyplus_files, energyplus_exe, expand_objects_exe = prepare_energyplus_dir(run_directory, logger, energyplus_path)
95
+ Dir.chdir(run_directory)
96
+ logger.info "Starting simulation in run directory: #{Dir.pwd}"
97
+
98
+ command = popen_command("./#{expand_objects_exe}")
99
+ logger.info "Running command '#{command}'"
100
+ File.open('stdout-expandobject', 'w') do |file|
101
+ ::IO.popen(command) do |io|
102
+ while (line = io.gets)
103
+ file << line
104
+ end
105
+ end
106
+ end
107
+
108
+ # Check if expand objects did anything
109
+ if File.exist? 'expanded.idf'
110
+ FileUtils.mv('in.idf', 'pre-expand.idf', force: true) if File.exist?('in.idf')
111
+ FileUtils.mv('expanded.idf', 'in.idf', force: true)
112
+ end
113
+
114
+ # create stdout
115
+ command = popen_command("./#{energyplus_exe} 2>&1")
116
+ logger.info "Running command '#{command}'"
117
+ File.open('stdout-energyplus', 'w') do |file|
118
+ ::IO.popen(command) do |io|
119
+ while (line = io.gets)
120
+ file << line
121
+ output_adapter.communicate_energyplus_stdout(line) if output_adapter
122
+ end
123
+ end
124
+ end
125
+ r = $?
126
+
127
+ logger.info "EnergyPlus returned '#{r}'"
128
+ unless r.to_i.zero?
129
+ logger.warn 'EnergyPlus returned a non-zero exit code. Check the stdout-energyplus log.'
130
+ end
131
+
132
+ if File.exist? 'eplusout.err'
133
+ eplus_err = File.read('eplusout.err').force_encoding('ISO-8859-1').encode('utf-8', replace: nil)
134
+
135
+ if workflow_json
136
+ begin
137
+ workflow_json.setEplusoutErr(eplus_err)
138
+ rescue => e
139
+ # older versions of OpenStudio did not have the setEplusoutErr method
140
+ end
141
+ end
142
+
143
+ if eplus_err =~ /EnergyPlus Terminated--Fatal Error Detected/
144
+ raise 'EnergyPlus Terminated with a Fatal Error. Check eplusout.err log.'
145
+ end
146
+ end
147
+
148
+ if File.exist? 'eplusout.end'
149
+ f = File.read('eplusout.end').force_encoding('ISO-8859-1').encode('utf-8', replace: nil)
150
+ warnings_count = f[/(\d*).Warning/, 1]
151
+ error_count = f[/(\d*).Severe.Errors/, 1]
152
+ logger.info "EnergyPlus finished with #{warnings_count} warnings and #{error_count} severe errors"
153
+ if f =~ /EnergyPlus Terminated--Fatal Error Detected/
154
+ raise 'EnergyPlus Terminated with a Fatal Error. Check eplusout.err log.'
155
+ end
156
+ else
157
+ raise 'EnergyPlus failed and did not create an eplusout.end file. Check the stdout-energyplus log.'
158
+ end
159
+
160
+ rescue => e
161
+ log_message = "#{__FILE__} failed with #{e.message}, #{e.backtrace.join("\n")}"
162
+ logger.error log_message
163
+ raise log_message
164
+ ensure
165
+ logger.info "Ensuring 'clean' directory"
166
+ clean_directory(run_directory, energyplus_files, logger)
167
+
168
+ Dir.chdir(current_dir)
169
+ logger.info 'EnergyPlus Completed'
170
+ end
171
+
172
+ # Run this code before running EnergyPlus to make sure the reporting variables are setup correctly
173
+ #
174
+ # @param [Object] idf The IDF Workspace to be simulated
175
+ # @return [Void]
176
+ #
177
+ def energyplus_preprocess(idf, logger)
178
+ logger.info 'Running EnergyPlus Preprocess'
179
+
180
+ new_objects = []
181
+
182
+ needs_sqlobj = idf.getObjectsByType('Output:SQLite'.to_IddObjectType).empty?
183
+
184
+ if needs_sqlobj
185
+ # just add this, we don't allow this type in add_energyplus_output_request
186
+ logger.info 'Adding SQL Output to IDF'
187
+ object = OpenStudio::IdfObject.load('Output:SQLite,SimpleAndTabular;').get
188
+ idf.addObjects(object)
189
+ end
190
+
191
+ # merge in monthly reports
192
+ EnergyPlus.monthly_report_idf_text.split(/^[\s]*$/).each do |object|
193
+ object = object.strip
194
+ next if object.empty?
195
+
196
+ new_objects << object
197
+ end
198
+
199
+ # These are needed for the calibration report
200
+ new_objects << 'Output:Meter:MeterFileOnly,Gas:Facility,Daily;'
201
+ new_objects << 'Output:Meter:MeterFileOnly,Electricity:Facility,Timestep;'
202
+ new_objects << 'Output:Meter:MeterFileOnly,Electricity:Facility,Daily;'
203
+
204
+ # Always add in the timestep facility meters
205
+ new_objects << 'Output:Meter,Electricity:Facility,Timestep;'
206
+ new_objects << 'Output:Meter,Gas:Facility,Timestep;'
207
+ new_objects << 'Output:Meter,DistrictCooling:Facility,Timestep;'
208
+ new_objects << 'Output:Meter,DistrictHeating:Facility,Timestep;'
209
+
210
+ new_objects.each do |obj|
211
+ object = OpenStudio::IdfObject.load(obj).get
212
+ OpenStudio::Workflow::Util::EnergyPlus.add_energyplus_output_request(idf, object)
213
+ end
214
+
215
+ # this is a workaround for issue #1699 -- remove when 1699 is closed.
216
+ needs_hourly = true
217
+ needs_timestep = true
218
+ needs_daily = true
219
+ needs_monthy = true
220
+ idf.getObjectsByType('Output:Variable'.to_IddObjectType).each do |object|
221
+ timestep = object.getString(2, true).get
222
+ if /Hourly/i =~ timestep
223
+ needs_hourly = false
224
+ elsif /Timestep/i =~ timestep
225
+ needs_timestep = false
226
+ elsif /Daily/i =~ timestep
227
+ needs_daily = false
228
+ elsif /Monthly/i =~ timestep
229
+ needs_monthy = false
230
+ end
231
+ end
232
+
233
+ new_objects = []
234
+ new_objects << 'Output:Variable,*,Zone Air Temperature,Hourly;' if needs_hourly
235
+ new_objects << 'Output:Variable,*,Site Outdoor Air Wetbulb Temperature,Timestep;' if needs_timestep
236
+ new_objects << 'Output:Variable,*,Zone Air Relative Humidity,Daily;' if needs_daily
237
+ new_objects << 'Output:Variable,*,Site Outdoor Air Drybulb Temperature,Monthly;' if needs_monthy
238
+
239
+ new_objects.each do |obj|
240
+ object = OpenStudio::IdfObject.load(obj).get
241
+ OpenStudio::Workflow::Util::EnergyPlus.add_energyplus_output_request(idf, object)
242
+ end
243
+
244
+ logger.info 'Finished EnergyPlus Preprocess'
245
+ end
246
+
247
+ # examines object and determines whether or not to add it to the workspace
248
+ def self.add_energyplus_output_request(workspace, idf_object)
249
+ num_added = 0
250
+ idd_object = idf_object.iddObject
251
+
252
+ allowed_objects = []
253
+ allowed_objects << 'Output:Surfaces:List'
254
+ allowed_objects << 'Output:Surfaces:Drawing'
255
+ allowed_objects << 'Output:Schedules'
256
+ allowed_objects << 'Output:Constructions'
257
+ allowed_objects << 'Output:Table:TimeBins'
258
+ allowed_objects << 'Output:Table:Monthly'
259
+ allowed_objects << 'Output:Variable'
260
+ allowed_objects << 'Output:Meter'
261
+ allowed_objects << 'Output:Meter:MeterFileOnly'
262
+ allowed_objects << 'Output:Meter:Cumulative'
263
+ allowed_objects << 'Output:Meter:Cumulative:MeterFileOnly'
264
+ allowed_objects << 'Meter:Custom'
265
+ allowed_objects << 'Meter:CustomDecrement'
266
+
267
+ if allowed_objects.include?(idd_object.name)
268
+ unless check_for_object(workspace, idf_object, idd_object.type)
269
+ workspace.addObject(idf_object)
270
+ num_added += 1
271
+ end
272
+ end
273
+
274
+ allowed_unique_objects = []
275
+ # allowed_unique_objects << "Output:EnergyManagementSystem" # TODO: have to merge
276
+ # allowed_unique_objects << "OutputControl:SurfaceColorScheme" # TODO: have to merge
277
+ allowed_unique_objects << 'Output:Table:SummaryReports' # TODO: have to merge
278
+ # OutputControl:Table:Style # not allowed
279
+ # OutputControl:ReportingTolerances # not allowed
280
+ # Output:SQLite # not allowed
281
+
282
+ if allowed_unique_objects.include?(idf_object.iddObject.name)
283
+ if idf_object.iddObject.name == 'Output:Table:SummaryReports'
284
+ summary_reports = workspace.getObjectsByType(idf_object.iddObject.type)
285
+ if summary_reports.empty?
286
+ workspace.addObject(idf_object)
287
+ num_added += 1
288
+ else
289
+ merge_output_table_summary_reports(summary_reports[0], idf_object)
290
+ end
291
+ end
292
+ end
293
+
294
+ return num_added
295
+ end
296
+
297
+ # check to see if we have an exact match for this object already
298
+ def self.check_for_object(workspace, idf_object, idd_object_type)
299
+ workspace.getObjectsByType(idd_object_type).each do |object|
300
+ # all of these objects fields are data fields
301
+ if idf_object.dataFieldsEqual(object)
302
+ return true
303
+ end
304
+ end
305
+ return false
306
+ end
307
+
308
+ # merge all summary reports that are not in the current workspace
309
+ def self.merge_output_table_summary_reports(current_object, new_object)
310
+ current_fields = []
311
+ current_object.extensibleGroups.each do |current_extensible_group|
312
+ current_fields << current_extensible_group.getString(0).to_s
313
+ end
314
+
315
+ fields_to_add = []
316
+ new_object.extensibleGroups.each do |new_extensible_group|
317
+ field = new_extensible_group.getString(0).to_s
318
+ unless current_fields.include?(field)
319
+ current_fields << field
320
+ fields_to_add << field
321
+ end
322
+ end
323
+
324
+ unless fields_to_add.empty?
325
+ fields_to_add.each do |field|
326
+ values = OpenStudio::StringVector.new
327
+ values << field
328
+ current_object.pushExtensibleGroup(values)
329
+ end
330
+ return true
331
+ end
332
+
333
+ return false
334
+ end
335
+
336
+ def self.monthly_report_idf_text
337
+ <<-HEREDOC
338
+ Output:Table:Monthly,
339
+ Building Energy Performance - Electricity, !- Name
340
+ 2, !- Digits After Decimal
341
+ InteriorLights:Electricity, !- Variable or Meter 1 Name
342
+ SumOrAverage, !- Aggregation Type for Variable or Meter 1
343
+ ExteriorLights:Electricity, !- Variable or Meter 2 Name
344
+ SumOrAverage, !- Aggregation Type for Variable or Meter 2
345
+ InteriorEquipment:Electricity, !- Variable or Meter 3 Name
346
+ SumOrAverage, !- Aggregation Type for Variable or Meter 3
347
+ ExteriorEquipment:Electricity, !- Variable or Meter 4 Name
348
+ SumOrAverage, !- Aggregation Type for Variable or Meter 4
349
+ Fans:Electricity, !- Variable or Meter 5 Name
350
+ SumOrAverage, !- Aggregation Type for Variable or Meter 5
351
+ Pumps:Electricity, !- Variable or Meter 6 Name
352
+ SumOrAverage, !- Aggregation Type for Variable or Meter 6
353
+ Heating:Electricity, !- Variable or Meter 7 Name
354
+ SumOrAverage, !- Aggregation Type for Variable or Meter 7
355
+ Cooling:Electricity, !- Variable or Meter 8 Name
356
+ SumOrAverage, !- Aggregation Type for Variable or Meter 8
357
+ HeatRejection:Electricity, !- Variable or Meter 9 Name
358
+ SumOrAverage, !- Aggregation Type for Variable or Meter 9
359
+ Humidifier:Electricity, !- Variable or Meter 10 Name
360
+ SumOrAverage, !- Aggregation Type for Variable or Meter 10
361
+ HeatRecovery:Electricity,!- Variable or Meter 11 Name
362
+ SumOrAverage, !- Aggregation Type for Variable or Meter 11
363
+ WaterSystems:Electricity,!- Variable or Meter 12 Name
364
+ SumOrAverage, !- Aggregation Type for Variable or Meter 12
365
+ Cogeneration:Electricity,!- Variable or Meter 13 Name
366
+ SumOrAverage, !- Aggregation Type for Variable or Meter 13
367
+ Refrigeration:Electricity,!- Variable or Meter 14 Name
368
+ SumOrAverage; !- Aggregation Type for Variable or Meter 14
369
+
370
+ Output:Table:Monthly,
371
+ Building Energy Performance - Natural Gas, !- Name
372
+ 2, !- Digits After Decimal
373
+ InteriorEquipment:Gas, !- Variable or Meter 1 Name
374
+ SumOrAverage, !- Aggregation Type for Variable or Meter 1
375
+ ExteriorEquipment:Gas, !- Variable or Meter 2 Name
376
+ SumOrAverage, !- Aggregation Type for Variable or Meter 2
377
+ Heating:Gas, !- Variable or Meter 3 Name
378
+ SumOrAverage, !- Aggregation Type for Variable or Meter 3
379
+ Cooling:Gas, !- Variable or Meter 4 Name
380
+ SumOrAverage, !- Aggregation Type for Variable or Meter 4
381
+ WaterSystems:Gas, !- Variable or Meter 5 Name
382
+ SumOrAverage, !- Aggregation Type for Variable or Meter 5
383
+ Cogeneration:Gas, !- Variable or Meter 6 Name
384
+ SumOrAverage; !- Aggregation Type for Variable or Meter 6
385
+
386
+ Output:Table:Monthly,
387
+ Building Energy Performance - District Heating, !- Name
388
+ 2, !- Digits After Decimal
389
+ InteriorLights:DistrictHeating, !- Variable or Meter 1 Name
390
+ SumOrAverage, !- Aggregation Type for Variable or Meter 1
391
+ ExteriorLights:DistrictHeating, !- Variable or Meter 2 Name
392
+ SumOrAverage, !- Aggregation Type for Variable or Meter 2
393
+ InteriorEquipment:DistrictHeating, !- Variable or Meter 3 Name
394
+ SumOrAverage, !- Aggregation Type for Variable or Meter 3
395
+ ExteriorEquipment:DistrictHeating, !- Variable or Meter 4 Name
396
+ SumOrAverage, !- Aggregation Type for Variable or Meter 4
397
+ Fans:DistrictHeating, !- Variable or Meter 5 Name
398
+ SumOrAverage, !- Aggregation Type for Variable or Meter 5
399
+ Pumps:DistrictHeating, !- Variable or Meter 6 Name
400
+ SumOrAverage, !- Aggregation Type for Variable or Meter 6
401
+ Heating:DistrictHeating, !- Variable or Meter 7 Name
402
+ SumOrAverage, !- Aggregation Type for Variable or Meter 7
403
+ Cooling:DistrictHeating, !- Variable or Meter 8 Name
404
+ SumOrAverage, !- Aggregation Type for Variable or Meter 8
405
+ HeatRejection:DistrictHeating, !- Variable or Meter 9 Name
406
+ SumOrAverage, !- Aggregation Type for Variable or Meter 9
407
+ Humidifier:DistrictHeating, !- Variable or Meter 10 Name
408
+ SumOrAverage, !- Aggregation Type for Variable or Meter 10
409
+ HeatRecovery:DistrictHeating,!- Variable or Meter 11 Name
410
+ SumOrAverage, !- Aggregation Type for Variable or Meter 11
411
+ WaterSystems:DistrictHeating,!- Variable or Meter 12 Name
412
+ SumOrAverage, !- Aggregation Type for Variable or Meter 12
413
+ Cogeneration:DistrictHeating,!- Variable or Meter 13 Name
414
+ SumOrAverage; !- Aggregation Type for Variable or Meter 13
415
+
416
+ Output:Table:Monthly,
417
+ Building Energy Performance - District Cooling, !- Name
418
+ 2, !- Digits After Decimal
419
+ InteriorLights:DistrictCooling, !- Variable or Meter 1 Name
420
+ SumOrAverage, !- Aggregation Type for Variable or Meter 1
421
+ ExteriorLights:DistrictCooling, !- Variable or Meter 2 Name
422
+ SumOrAverage, !- Aggregation Type for Variable or Meter 2
423
+ InteriorEquipment:DistrictCooling, !- Variable or Meter 3 Name
424
+ SumOrAverage, !- Aggregation Type for Variable or Meter 3
425
+ ExteriorEquipment:DistrictCooling, !- Variable or Meter 4 Name
426
+ SumOrAverage, !- Aggregation Type for Variable or Meter 4
427
+ Fans:DistrictCooling, !- Variable or Meter 5 Name
428
+ SumOrAverage, !- Aggregation Type for Variable or Meter 5
429
+ Pumps:DistrictCooling, !- Variable or Meter 6 Name
430
+ SumOrAverage, !- Aggregation Type for Variable or Meter 6
431
+ Heating:DistrictCooling, !- Variable or Meter 7 Name
432
+ SumOrAverage, !- Aggregation Type for Variable or Meter 7
433
+ Cooling:DistrictCooling, !- Variable or Meter 8 Name
434
+ SumOrAverage, !- Aggregation Type for Variable or Meter 8
435
+ HeatRejection:DistrictCooling, !- Variable or Meter 9 Name
436
+ SumOrAverage, !- Aggregation Type for Variable or Meter 9
437
+ Humidifier:DistrictCooling, !- Variable or Meter 10 Name
438
+ SumOrAverage, !- Aggregation Type for Variable or Meter 10
439
+ HeatRecovery:DistrictCooling,!- Variable or Meter 11 Name
440
+ SumOrAverage, !- Aggregation Type for Variable or Meter 11
441
+ WaterSystems:DistrictCooling,!- Variable or Meter 12 Name
442
+ SumOrAverage, !- Aggregation Type for Variable or Meter 12
443
+ Cogeneration:DistrictCooling,!- Variable or Meter 13 Name
444
+ SumOrAverage; !- Aggregation Type for Variable or Meter 13
445
+
446
+ Output:Table:Monthly,
447
+ Building Energy Performance - Electricity Peak Demand, !- Name
448
+ 2, !- Digits After Decimal
449
+ Electricity:Facility, !- Variable or Meter 1 Name
450
+ Maximum, !- Aggregation Type for Variable or Meter 1
451
+ InteriorLights:Electricity, !- Variable or Meter 1 Name
452
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 1
453
+ ExteriorLights:Electricity, !- Variable or Meter 2 Name
454
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 2
455
+ InteriorEquipment:Electricity, !- Variable or Meter 3 Name
456
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 3
457
+ ExteriorEquipment:Electricity, !- Variable or Meter 4 Name
458
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 4
459
+ Fans:Electricity, !- Variable or Meter 5 Name
460
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 5
461
+ Pumps:Electricity, !- Variable or Meter 6 Name
462
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 6
463
+ Heating:Electricity, !- Variable or Meter 7 Name
464
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 7
465
+ Cooling:Electricity, !- Variable or Meter 8 Name
466
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 8
467
+ HeatRejection:Electricity, !- Variable or Meter 9 Name
468
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 9
469
+ Humidifier:Electricity, !- Variable or Meter 10 Name
470
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 10
471
+ HeatRecovery:Electricity,!- Variable or Meter 11 Name
472
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 11
473
+ WaterSystems:Electricity,!- Variable or Meter 12 Name
474
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 12
475
+ Cogeneration:Electricity,!- Variable or Meter 13 Name
476
+ ValueWhenMaximumOrMinimum; !- Aggregation Type for Variable or Meter 13
477
+
478
+ Output:Table:Monthly,
479
+ Building Energy Performance - Natural Gas Peak Demand, !- Name
480
+ 2, !- Digits After Decimal
481
+ Gas:Facility, !- Variable or Meter 1 Name
482
+ Maximum, !- Aggregation Type for Variable or Meter 1
483
+ InteriorEquipment:Gas, !- Variable or Meter 1 Name
484
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 1
485
+ ExteriorEquipment:Gas, !- Variable or Meter 2 Name
486
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 2
487
+ Heating:Gas, !- Variable or Meter 3 Name
488
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 3
489
+ Cooling:Gas, !- Variable or Meter 4 Name
490
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 4
491
+ WaterSystems:Gas, !- Variable or Meter 5 Name
492
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 5
493
+ Cogeneration:Gas, !- Variable or Meter 6 Name
494
+ ValueWhenMaximumOrMinimum; !- Aggregation Type for Variable or Meter 6
495
+
496
+ Output:Table:Monthly,
497
+ Building Energy Performance - District Heating Peak Demand, !- Name
498
+ 2, !- Digits After Decimal
499
+ DistrictHeating:Facility, !- Variable or Meter 1 Name
500
+ Maximum, !- Aggregation Type for Variable or Meter 1
501
+ InteriorLights:DistrictHeating, !- Variable or Meter 1 Name
502
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 1
503
+ ExteriorLights:DistrictHeating, !- Variable or Meter 2 Name
504
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 2
505
+ InteriorEquipment:DistrictHeating, !- Variable or Meter 3 Name
506
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 3
507
+ ExteriorEquipment:DistrictHeating, !- Variable or Meter 4 Name
508
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 4
509
+ Fans:DistrictHeating, !- Variable or Meter 5 Name
510
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 5
511
+ Pumps:DistrictHeating, !- Variable or Meter 6 Name
512
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 6
513
+ Heating:DistrictHeating, !- Variable or Meter 7 Name
514
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 7
515
+ Cooling:DistrictHeating, !- Variable or Meter 8 Name
516
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 8
517
+ HeatRejection:DistrictHeating, !- Variable or Meter 9 Name
518
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 9
519
+ Humidifier:DistrictHeating, !- Variable or Meter 10 Name
520
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 10
521
+ HeatRecovery:DistrictHeating,!- Variable or Meter 11 Name
522
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 11
523
+ WaterSystems:DistrictHeating,!- Variable or Meter 12 Name
524
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 12
525
+ Cogeneration:DistrictHeating,!- Variable or Meter 13 Name
526
+ ValueWhenMaximumOrMinimum; !- Aggregation Type for Variable or Meter 13
527
+
528
+ Output:Table:Monthly,
529
+ Building Energy Performance - District Cooling Peak Demand, !- Name
530
+ 2, !- Digits After Decimal
531
+ DistrictCooling:Facility, !- Variable or Meter 1 Name
532
+ Maximum, !- Aggregation Type for Variable or Meter 1
533
+ InteriorLights:DistrictCooling, !- Variable or Meter 1 Name
534
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 1
535
+ ExteriorLights:DistrictCooling, !- Variable or Meter 2 Name
536
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 2
537
+ InteriorEquipment:DistrictCooling, !- Variable or Meter 3 Name
538
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 3
539
+ ExteriorEquipment:DistrictCooling, !- Variable or Meter 4 Name
540
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 4
541
+ Fans:DistrictCooling, !- Variable or Meter 5 Name
542
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 5
543
+ Pumps:DistrictCooling, !- Variable or Meter 6 Name
544
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 6
545
+ Heating:DistrictCooling, !- Variable or Meter 7 Name
546
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 7
547
+ Cooling:DistrictCooling, !- Variable or Meter 8 Name
548
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 8
549
+ HeatRejection:DistrictCooling, !- Variable or Meter 9 Name
550
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 9
551
+ Humidifier:DistrictCooling, !- Variable or Meter 10 Name
552
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 10
553
+ HeatRecovery:DistrictCooling,!- Variable or Meter 11 Name
554
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 11
555
+ WaterSystems:DistrictCooling,!- Variable or Meter 12 Name
556
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 12
557
+ Cogeneration:DistrictCooling,!- Variable or Meter 13 Name
558
+ ValueWhenMaximumOrMinimum; !- Aggregation Type for Variable or Meter 13
559
+ HEREDOC
560
+ end
561
+ end
562
+ end
563
+ end
564
+ end
@@ -0,0 +1,33 @@
1
+ module OpenStudio
2
+ module Workflow
3
+ module Util
4
+ module IO
5
+ def is_windows?
6
+ win_patterns = [
7
+ /bccwin/i,
8
+ /cygwin/i,
9
+ /djgpp/i,
10
+ /mingw/i,
11
+ /mswin/i,
12
+ /wince/i
13
+ ]
14
+
15
+ case RUBY_PLATFORM
16
+ when *win_patterns
17
+ return true
18
+ else
19
+ return false
20
+ end
21
+ end
22
+
23
+ def popen_command(command)
24
+ result = command
25
+ if is_windows?
26
+ result = command.tr('/', '\\')
27
+ end
28
+ return result
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end