openstudio-workflow 1.3.4 → 1.3.5

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 +89 -77
  3. data/README.md +67 -93
  4. data/Rakefile +36 -36
  5. data/lib/openstudio-workflow.rb +65 -65
  6. data/lib/openstudio/workflow/adapters/input/local.rb +311 -324
  7. data/lib/openstudio/workflow/adapters/output/local.rb +158 -161
  8. data/lib/openstudio/workflow/adapters/output/socket.rb +106 -107
  9. data/lib/openstudio/workflow/adapters/output/web.rb +82 -82
  10. data/lib/openstudio/workflow/adapters/output_adapter.rb +163 -163
  11. data/lib/openstudio/workflow/job.rb +57 -57
  12. data/lib/openstudio/workflow/jobs/resources/monthly_report.idf +222 -222
  13. data/lib/openstudio/workflow/jobs/run_energyplus.rb +70 -70
  14. data/lib/openstudio/workflow/jobs/run_ep_measures.rb +73 -73
  15. data/lib/openstudio/workflow/jobs/run_initialization.rb +203 -203
  16. data/lib/openstudio/workflow/jobs/run_os_measures.rb +89 -89
  17. data/lib/openstudio/workflow/jobs/run_postprocess.rb +73 -73
  18. data/lib/openstudio/workflow/jobs/run_preprocess.rb +104 -104
  19. data/lib/openstudio/workflow/jobs/run_reporting_measures.rb +118 -118
  20. data/lib/openstudio/workflow/jobs/run_translation.rb +84 -84
  21. data/lib/openstudio/workflow/multi_delegator.rb +62 -62
  22. data/lib/openstudio/workflow/registry.rb +172 -172
  23. data/lib/openstudio/workflow/run.rb +342 -328
  24. data/lib/openstudio/workflow/time_logger.rb +96 -96
  25. data/lib/openstudio/workflow/util.rb +49 -49
  26. data/lib/openstudio/workflow/util/energyplus.rb +575 -605
  27. data/lib/openstudio/workflow/util/io.rb +68 -68
  28. data/lib/openstudio/workflow/util/measure.rb +658 -650
  29. data/lib/openstudio/workflow/util/model.rb +151 -151
  30. data/lib/openstudio/workflow/util/post_process.rb +235 -238
  31. data/lib/openstudio/workflow/util/weather_file.rb +143 -143
  32. data/lib/openstudio/workflow/version.rb +40 -40
  33. data/lib/openstudio/workflow_json.rb +475 -476
  34. data/lib/openstudio/workflow_runner.rb +263 -268
  35. metadata +24 -24
@@ -1,96 +1,96 @@
1
- # *******************************************************************************
2
- # OpenStudio(R), Copyright (c) 2008-2018, Alliance for Sustainable Energy, LLC.
3
- # All rights reserved.
4
- # Redistribution and use in source and binary forms, with or without
5
- # modification, are permitted provided that the following conditions are met:
6
- #
7
- # (1) Redistributions of source code must retain the above copyright notice,
8
- # this list of conditions and the following disclaimer.
9
- #
10
- # (2) Redistributions in binary form must reproduce the above copyright notice,
11
- # this list of conditions and the following disclaimer in the documentation
12
- # and/or other materials provided with the distribution.
13
- #
14
- # (3) Neither the name of the copyright holder nor the names of any contributors
15
- # may be used to endorse or promote products derived from this software without
16
- # specific prior written permission from the respective party.
17
- #
18
- # (4) Other than as required in clauses (1) and (2), distributions in any form
19
- # of modifications or other derivative works may not use the "OpenStudio"
20
- # trademark, "OS", "os", or any other confusingly similar designation without
21
- # specific prior written permission from Alliance for Sustainable Energy, LLC.
22
- #
23
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24
- # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25
- # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26
- # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER, THE UNITED STATES
27
- # GOVERNMENT, OR ANY CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28
- # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29
- # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30
- # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31
- # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32
- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
33
- # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
- # *******************************************************************************
35
-
36
- # Class to store run times in a useful structure. Data are stored in a hash based on a the channel name
37
- # There is no concept of multi-levels. The onus is on the user to make sure that they don't add a value to the
38
- # logger that may be a level.
39
- class TimeLogger
40
- attr_reader :channels
41
-
42
- def initialize
43
- @logger = []
44
- @channels = {}
45
- end
46
-
47
- # name of the moniker that you are tracking. If the name is already in use, then it restarts the timer.
48
- def start(channel)
49
- # warning -- "will reset timer for #{moniker}" if @monikers.key? moniker
50
- s = ::Time.now
51
- @channels[channel] = { start_time_str: s.to_s, start_time: s.to_f }
52
- end
53
-
54
- def stop(channel)
55
- end_time = ::Time.now.to_f
56
- @logger << {
57
- channel: channel,
58
- start_time: @channels[channel][:start_time],
59
- start_time_str: @channels[channel][:start_time_str],
60
- end_time: end_time,
61
- delta: end_time - @channels[channel][:start_time]
62
- }
63
-
64
- # remove the channel
65
- @channels.delete(channel) if @channels.key? channel
66
- end
67
-
68
- def stop_all
69
- @channels.each_key do |channel|
70
- stop(channel)
71
- end
72
- end
73
-
74
- # return the entire report
75
- def report
76
- @logger
77
- end
78
-
79
- # this will report all the values for all the channels with this name.
80
- def delta(channel)
81
- @logger.map { |k| { channel.to_s => k[:delta] } if k[:channel] == channel }.compact
82
- end
83
-
84
- # save the data to a file. This will overwrite the file if it already exists
85
- def save(filename)
86
- File.open(filename, 'w') do |f|
87
- f << JSON.pretty_generate(@logger)
88
- # make sure data is written to the disk one way or the other
89
- begin
90
- f.fsync
91
- rescue
92
- f.flush
93
- end
94
- end
95
- end
96
- end
1
+ # *******************************************************************************
2
+ # OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC.
3
+ # All rights reserved.
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are met:
6
+ #
7
+ # (1) Redistributions of source code must retain the above copyright notice,
8
+ # this list of conditions and the following disclaimer.
9
+ #
10
+ # (2) Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ #
14
+ # (3) Neither the name of the copyright holder nor the names of any contributors
15
+ # may be used to endorse or promote products derived from this software without
16
+ # specific prior written permission from the respective party.
17
+ #
18
+ # (4) Other than as required in clauses (1) and (2), distributions in any form
19
+ # of modifications or other derivative works may not use the "OpenStudio"
20
+ # trademark, "OS", "os", or any other confusingly similar designation without
21
+ # specific prior written permission from Alliance for Sustainable Energy, LLC.
22
+ #
23
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER, THE UNITED STATES
27
+ # GOVERNMENT, OR ANY CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28
+ # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30
+ # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
33
+ # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
+ # *******************************************************************************
35
+
36
+ # Class to store run times in a useful structure. Data are stored in a hash based on a the channel name
37
+ # There is no concept of multi-levels. The onus is on the user to make sure that they don't add a value to the
38
+ # logger that may be a level.
39
+ class TimeLogger
40
+ attr_reader :channels
41
+
42
+ def initialize
43
+ @logger = []
44
+ @channels = {}
45
+ end
46
+
47
+ # name of the moniker that you are tracking. If the name is already in use, then it restarts the timer.
48
+ def start(channel)
49
+ # warning -- "will reset timer for #{moniker}" if @monikers.key? moniker
50
+ s = ::Time.now
51
+ @channels[channel] = { start_time_str: s.to_s, start_time: s.to_f }
52
+ end
53
+
54
+ def stop(channel)
55
+ end_time = ::Time.now.to_f
56
+ @logger << {
57
+ channel: channel,
58
+ start_time: @channels[channel][:start_time],
59
+ start_time_str: @channels[channel][:start_time_str],
60
+ end_time: end_time,
61
+ delta: end_time - @channels[channel][:start_time]
62
+ }
63
+
64
+ # remove the channel
65
+ @channels.delete(channel) if @channels.key? channel
66
+ end
67
+
68
+ def stop_all
69
+ @channels.each_key do |channel|
70
+ stop(channel)
71
+ end
72
+ end
73
+
74
+ # return the entire report
75
+ def report
76
+ @logger
77
+ end
78
+
79
+ # this will report all the values for all the channels with this name.
80
+ def delta(channel)
81
+ @logger.map { |k| { channel.to_s => k[:delta] } if k[:channel] == channel }.compact
82
+ end
83
+
84
+ # save the data to a file. This will overwrite the file if it already exists
85
+ def save(filename)
86
+ File.open(filename, 'w') do |f|
87
+ f << JSON.pretty_generate(@logger)
88
+ # make sure data is written to the disk one way or the other
89
+ begin
90
+ f.fsync
91
+ rescue StandardError
92
+ f.flush
93
+ end
94
+ end
95
+ end
96
+ end
@@ -1,49 +1,49 @@
1
- # *******************************************************************************
2
- # OpenStudio(R), Copyright (c) 2008-2018, Alliance for Sustainable Energy, LLC.
3
- # All rights reserved.
4
- # Redistribution and use in source and binary forms, with or without
5
- # modification, are permitted provided that the following conditions are met:
6
- #
7
- # (1) Redistributions of source code must retain the above copyright notice,
8
- # this list of conditions and the following disclaimer.
9
- #
10
- # (2) Redistributions in binary form must reproduce the above copyright notice,
11
- # this list of conditions and the following disclaimer in the documentation
12
- # and/or other materials provided with the distribution.
13
- #
14
- # (3) Neither the name of the copyright holder nor the names of any contributors
15
- # may be used to endorse or promote products derived from this software without
16
- # specific prior written permission from the respective party.
17
- #
18
- # (4) Other than as required in clauses (1) and (2), distributions in any form
19
- # of modifications or other derivative works may not use the "OpenStudio"
20
- # trademark, "OS", "os", or any other confusingly similar designation without
21
- # specific prior written permission from Alliance for Sustainable Energy, LLC.
22
- #
23
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24
- # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25
- # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26
- # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER, THE UNITED STATES
27
- # GOVERNMENT, OR ANY CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28
- # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29
- # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30
- # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31
- # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32
- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
33
- # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
- # *******************************************************************************
35
-
36
- module OpenStudio
37
- module Workflow
38
- # Hard load utils for the moment
39
- #
40
- module Util
41
- require 'openstudio/workflow/util/io'
42
- require 'openstudio/workflow/util/measure'
43
- require 'openstudio/workflow/util/weather_file'
44
- require 'openstudio/workflow/util/model'
45
- require 'openstudio/workflow/util/energyplus'
46
- require 'openstudio/workflow/util/post_process'
47
- end
48
- end
49
- end
1
+ # *******************************************************************************
2
+ # OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC.
3
+ # All rights reserved.
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are met:
6
+ #
7
+ # (1) Redistributions of source code must retain the above copyright notice,
8
+ # this list of conditions and the following disclaimer.
9
+ #
10
+ # (2) Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ #
14
+ # (3) Neither the name of the copyright holder nor the names of any contributors
15
+ # may be used to endorse or promote products derived from this software without
16
+ # specific prior written permission from the respective party.
17
+ #
18
+ # (4) Other than as required in clauses (1) and (2), distributions in any form
19
+ # of modifications or other derivative works may not use the "OpenStudio"
20
+ # trademark, "OS", "os", or any other confusingly similar designation without
21
+ # specific prior written permission from Alliance for Sustainable Energy, LLC.
22
+ #
23
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER, THE UNITED STATES
27
+ # GOVERNMENT, OR ANY CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28
+ # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30
+ # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
33
+ # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
+ # *******************************************************************************
35
+
36
+ module OpenStudio
37
+ module Workflow
38
+ # Hard load utils for the moment
39
+ #
40
+ module Util
41
+ require 'openstudio/workflow/util/io'
42
+ require 'openstudio/workflow/util/measure'
43
+ require 'openstudio/workflow/util/weather_file'
44
+ require 'openstudio/workflow/util/model'
45
+ require 'openstudio/workflow/util/energyplus'
46
+ require 'openstudio/workflow/util/post_process'
47
+ end
48
+ end
49
+ end
@@ -1,605 +1,575 @@
1
- # *******************************************************************************
2
- # OpenStudio(R), Copyright (c) 2008-2018, Alliance for Sustainable Energy, LLC.
3
- # All rights reserved.
4
- # Redistribution and use in source and binary forms, with or without
5
- # modification, are permitted provided that the following conditions are met:
6
- #
7
- # (1) Redistributions of source code must retain the above copyright notice,
8
- # this list of conditions and the following disclaimer.
9
- #
10
- # (2) Redistributions in binary form must reproduce the above copyright notice,
11
- # this list of conditions and the following disclaimer in the documentation
12
- # and/or other materials provided with the distribution.
13
- #
14
- # (3) Neither the name of the copyright holder nor the names of any contributors
15
- # may be used to endorse or promote products derived from this software without
16
- # specific prior written permission from the respective party.
17
- #
18
- # (4) Other than as required in clauses (1) and (2), distributions in any form
19
- # of modifications or other derivative works may not use the "OpenStudio"
20
- # trademark, "OS", "os", or any other confusingly similar designation without
21
- # specific prior written permission from Alliance for Sustainable Energy, LLC.
22
- #
23
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24
- # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25
- # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26
- # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER, THE UNITED STATES
27
- # GOVERNMENT, OR ANY CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28
- # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29
- # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30
- # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31
- # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32
- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
33
- # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
- # *******************************************************************************
35
-
36
- module OpenStudio
37
- module Workflow
38
- module Util
39
- # The methods needed to run simulations using EnergyPlus are stored here. See the run_simulation class for
40
- # implementation details.
41
- module EnergyPlus
42
- require 'openstudio/workflow/util/io'
43
- include OpenStudio::Workflow::Util::IO
44
- ENERGYPLUS_REGEX = /^energyplus\D{0,4}$/i
45
- EXPAND_OBJECTS_REGEX = /^expandobjects\D{0,4}$/i
46
-
47
- # Find the installation directory of EnergyPlus linked to the OpenStudio version being used
48
- #
49
- # @return [String] Returns the path to EnergyPlus
50
- #
51
- def find_energyplus
52
- path = OpenStudio.getEnergyPlusDirectory.to_s
53
- raise 'Unable to find the EnergyPlus executable' unless File.exist? path
54
- path
55
- end
56
-
57
- # Does something
58
- #
59
- # @param [String] run_directory Directory to run the EnergyPlus simulation in
60
- # @param [Array] energyplus_files Array of files containing the EnergyPlus and ExpandObjects EXEs
61
- # @return [Void]
62
- #
63
- def clean_directory(run_directory, energyplus_files, logger)
64
- logger.info 'Removing any copied EnergyPlus files'
65
- energyplus_files.each do |file|
66
- if File.exist? file
67
- FileUtils.rm_f file
68
- end
69
- end
70
-
71
- paths_to_rm = []
72
- paths_to_rm << "#{run_directory}/packaged_measures"
73
- paths_to_rm << "#{run_directory}/Energy+.ini"
74
- paths_to_rm.each { |p| FileUtils.rm_rf(p) if File.exist?(p) }
75
- end
76
-
77
- # Prepare the directory to run EnergyPlus
78
- #
79
- # @param [String] run_directory Directory to copy the required EnergyPlus files to
80
- # @param [Object] logger Logger object
81
- # @param [String] energyplus_path Path to the EnergyPlus EXE
82
- # @return [Array, file, file] Returns an array of strings of EnergyPlus files copied to the run_directory, the
83
- # ExpandObjects EXE file, and EnergyPlus EXE file
84
- #
85
- def prepare_energyplus_dir(run_directory, logger, energyplus_path = nil)
86
- logger.info "Copying EnergyPlus files to run directory: #{run_directory}"
87
- energyplus_path ||= find_energyplus
88
- logger.info "EnergyPlus path is #{energyplus_path}"
89
- energyplus_files = []
90
- energyplus_exe, expand_objects_exe = nil
91
- Dir["#{energyplus_path}/*"].each do |file|
92
- next if File.directory? file
93
-
94
- # copy idd and ini files
95
- if File.extname(file).downcase =~ /.idd|.ini/
96
- dest_file = "#{run_directory}/#{File.basename(file)}"
97
- energyplus_files << dest_file
98
- FileUtils.copy file, dest_file
99
- end
100
-
101
- energyplus_exe = file if File.basename(file) =~ ENERGYPLUS_REGEX
102
- expand_objects_exe = file if File.basename(file) =~ EXPAND_OBJECTS_REGEX
103
-
104
- end
105
-
106
- raise "Could not find EnergyPlus executable in #{energyplus_path}" unless energyplus_exe
107
- raise "Could not find ExpandObjects executable in #{energyplus_path}" unless expand_objects_exe
108
-
109
- logger.info "EnergyPlus executable path is #{energyplus_exe}"
110
- logger.info "ExpandObjects executable path is #{expand_objects_exe}"
111
-
112
- return energyplus_files, energyplus_exe, expand_objects_exe
113
- end
114
-
115
- # Configures and executes the EnergyPlus simulation and checks to see if the simulation was successful
116
- #
117
- # @param [String] run_directory Directory to execute the EnergyPlus simulation in. It is assumed that this
118
- # directory already has the IDF and weather file in it
119
- # @param [String] energyplus_path (nil) Optional path to override the default path associated with the
120
- # OpenStudio package being used
121
- # @param [Object] output_adapter (nil) Optional output adapter to update
122
- # @param [Object] logger (nil) Optional logger, will log to STDOUT if none provided
123
- # @return [Void]
124
- #
125
- def call_energyplus(run_directory, energyplus_path = nil, output_adapter = nil, logger = nil, workflow_json = nil)
126
- logger ||= ::Logger.new(STDOUT) unless logger
127
-
128
- current_dir = Dir.pwd
129
- energyplus_path ||= find_energyplus
130
- logger.info "EnergyPlus path is #{energyplus_path}"
131
- energyplus_files, energyplus_exe, expand_objects_exe = prepare_energyplus_dir(run_directory, logger, energyplus_path)
132
- Dir.chdir(run_directory)
133
- logger.info "Starting simulation in run directory: #{Dir.pwd}"
134
-
135
- if !@options[:skip_expand_objects]
136
- command = popen_command("\"#{expand_objects_exe}\"")
137
- logger.info "Running command '#{command}'"
138
- File.open('stdout-expandobject', 'w') do |file|
139
- ::IO.popen(command) do |io|
140
- while (line = io.gets)
141
- file << line
142
- end
143
- end
144
- end
145
-
146
- # Check if expand objects did anything
147
- if File.exist? 'expanded.idf'
148
- FileUtils.mv('in.idf', 'pre-expand.idf', force: true) if File.exist?('in.idf')
149
- FileUtils.mv('expanded.idf', 'in.idf', force: true)
150
- end
151
- end
152
-
153
- # create stdout
154
- command = popen_command("\"#{energyplus_exe}\" 2>&1")
155
- logger.info "Running command '#{command}'"
156
- File.open('stdout-energyplus', 'w') do |file|
157
- ::IO.popen(command) do |io|
158
- while (line = io.gets)
159
- file << line
160
- output_adapter.communicate_energyplus_stdout(line) if output_adapter
161
- end
162
- end
163
- end
164
- r = $?
165
-
166
- logger.info "EnergyPlus returned '#{r}'"
167
- unless r.to_i.zero?
168
- logger.warn 'EnergyPlus returned a non-zero exit code. Check the stdout-energyplus log.'
169
- end
170
-
171
- if File.exist? 'eplusout.err'
172
- eplus_err = File.read('eplusout.err').force_encoding('ISO-8859-1').encode('utf-8', replace: nil)
173
-
174
- if workflow_json
175
- begin
176
- if !@options[:fast]
177
- workflow_json.setEplusoutErr(eplus_err)
178
- end
179
- rescue => e
180
- # older versions of OpenStudio did not have the setEplusoutErr method
181
- end
182
- end
183
-
184
- if eplus_err =~ /EnergyPlus Terminated--Fatal Error Detected/
185
- raise 'EnergyPlus Terminated with a Fatal Error. Check eplusout.err log.'
186
- end
187
- end
188
-
189
- if File.exist? 'eplusout.end'
190
- f = File.read('eplusout.end').force_encoding('ISO-8859-1').encode('utf-8', replace: nil)
191
- warnings_count = f[/(\d*).Warning/, 1]
192
- error_count = f[/(\d*).Severe.Errors/, 1]
193
- logger.info "EnergyPlus finished with #{warnings_count} warnings and #{error_count} severe errors"
194
- if f =~ /EnergyPlus Terminated--Fatal Error Detected/
195
- raise 'EnergyPlus Terminated with a Fatal Error. Check eplusout.err log.'
196
- end
197
- else
198
- raise 'EnergyPlus failed and did not create an eplusout.end file. Check the stdout-energyplus log.'
199
- end
200
-
201
- rescue => e
202
- log_message = "#{__FILE__} failed with #{e.message}, #{e.backtrace.join("\n")}"
203
- logger.error log_message
204
- raise log_message
205
- ensure
206
- logger.info "Ensuring 'clean' directory"
207
- clean_directory(run_directory, energyplus_files, logger)
208
-
209
- Dir.chdir(current_dir)
210
- logger.info 'EnergyPlus Completed'
211
- end
212
-
213
- # Run this code before running EnergyPlus to make sure the reporting variables are setup correctly
214
- #
215
- # @param [Object] idf The IDF Workspace to be simulated
216
- # @return [Void]
217
- #
218
- def energyplus_preprocess(idf, logger)
219
- logger.info 'Running EnergyPlus Preprocess'
220
-
221
- new_objects = []
222
-
223
- needs_sqlobj = idf.getObjectsByType('Output:SQLite'.to_IddObjectType).empty?
224
-
225
- if needs_sqlobj
226
- # just add this, we don't allow this type in add_energyplus_output_request
227
- logger.info 'Adding SQL Output to IDF'
228
- object = OpenStudio::IdfObject.load('Output:SQLite,SimpleAndTabular;').get
229
- idf.addObjects(object)
230
- end
231
-
232
- # merge in monthly reports
233
- EnergyPlus.monthly_report_idf_text.split(/^[\s]*$/).each do |object|
234
- object = object.strip
235
- next if object.empty?
236
-
237
- new_objects << object
238
- end
239
-
240
- # These are needed for the calibration report
241
- new_objects << 'Output:Meter:MeterFileOnly,Gas:Facility,Daily;'
242
- new_objects << 'Output:Meter:MeterFileOnly,Electricity:Facility,Timestep;'
243
- new_objects << 'Output:Meter:MeterFileOnly,Electricity:Facility,Daily;'
244
-
245
- # Always add in the timestep facility meters
246
- new_objects << 'Output:Meter,Electricity:Facility,Timestep;'
247
- new_objects << 'Output:Meter,Gas:Facility,Timestep;'
248
- new_objects << 'Output:Meter,DistrictCooling:Facility,Timestep;'
249
- new_objects << 'Output:Meter,DistrictHeating:Facility,Timestep;'
250
-
251
- new_objects.each do |obj|
252
- object = OpenStudio::IdfObject.load(obj).get
253
- OpenStudio::Workflow::Util::EnergyPlus.add_energyplus_output_request(idf, object)
254
- end
255
-
256
- # this is a workaround for issue #1699 -- remove when 1699 is closed.
257
- needs_hourly = true
258
- needs_timestep = true
259
- needs_daily = true
260
- needs_monthy = true
261
- idf.getObjectsByType('Output:Variable'.to_IddObjectType).each do |object|
262
- timestep = object.getString(2, true).get
263
- if /Hourly/i =~ timestep
264
- needs_hourly = false
265
- elsif /Timestep/i =~ timestep
266
- needs_timestep = false
267
- elsif /Daily/i =~ timestep
268
- needs_daily = false
269
- elsif /Monthly/i =~ timestep
270
- needs_monthy = false
271
- end
272
- end
273
-
274
- new_objects = []
275
- new_objects << 'Output:Variable,*,Zone Air Temperature,Hourly;' if needs_hourly
276
- new_objects << 'Output:Variable,*,Site Outdoor Air Wetbulb Temperature,Timestep;' if needs_timestep
277
- new_objects << 'Output:Variable,*,Zone Air Relative Humidity,Daily;' if needs_daily
278
- new_objects << 'Output:Variable,*,Site Outdoor Air Drybulb Temperature,Monthly;' if needs_monthy
279
-
280
- new_objects.each do |obj|
281
- object = OpenStudio::IdfObject.load(obj).get
282
- OpenStudio::Workflow::Util::EnergyPlus.add_energyplus_output_request(idf, object)
283
- end
284
-
285
- logger.info 'Finished EnergyPlus Preprocess'
286
- end
287
-
288
- # examines object and determines whether or not to add it to the workspace
289
- def self.add_energyplus_output_request(workspace, idf_object)
290
- num_added = 0
291
- idd_object = idf_object.iddObject
292
-
293
- allowed_objects = []
294
- allowed_objects << 'Output:Surfaces:List'
295
- allowed_objects << 'Output:Surfaces:Drawing'
296
- allowed_objects << 'Output:Schedules'
297
- allowed_objects << 'Output:Constructions'
298
- allowed_objects << 'Output:Table:TimeBins'
299
- allowed_objects << 'Output:Table:Monthly'
300
- allowed_objects << 'Output:Variable'
301
- allowed_objects << 'Output:Meter'
302
- allowed_objects << 'Output:Meter:MeterFileOnly'
303
- allowed_objects << 'Output:Meter:Cumulative'
304
- allowed_objects << 'Output:Meter:Cumulative:MeterFileOnly'
305
- allowed_objects << 'Meter:Custom'
306
- allowed_objects << 'Meter:CustomDecrement'
307
-
308
- if allowed_objects.include?(idd_object.name)
309
- unless check_for_object(workspace, idf_object, idd_object.type)
310
- workspace.addObject(idf_object)
311
- num_added += 1
312
- end
313
- end
314
-
315
- allowed_unique_objects = []
316
- # allowed_unique_objects << "Output:EnergyManagementSystem" # TODO: have to merge
317
- # allowed_unique_objects << "OutputControl:SurfaceColorScheme" # TODO: have to merge
318
- allowed_unique_objects << 'Output:Table:SummaryReports' # TODO: have to merge
319
- # OutputControl:Table:Style # not allowed
320
- # OutputControl:ReportingTolerances # not allowed
321
- # Output:SQLite # not allowed
322
-
323
- if allowed_unique_objects.include?(idf_object.iddObject.name)
324
- if idf_object.iddObject.name == 'Output:Table:SummaryReports'
325
- summary_reports = workspace.getObjectsByType(idf_object.iddObject.type)
326
- if summary_reports.empty?
327
- workspace.addObject(idf_object)
328
- num_added += 1
329
- else
330
- merge_output_table_summary_reports(summary_reports[0], idf_object)
331
- end
332
- end
333
- end
334
-
335
- return num_added
336
- end
337
-
338
- # check to see if we have an exact match for this object already
339
- def self.check_for_object(workspace, idf_object, idd_object_type)
340
- workspace.getObjectsByType(idd_object_type).each do |object|
341
- # all of these objects fields are data fields
342
- if idf_object.dataFieldsEqual(object)
343
- return true
344
- end
345
- end
346
- return false
347
- end
348
-
349
- # merge all summary reports that are not in the current workspace
350
- def self.merge_output_table_summary_reports(current_object, new_object)
351
- current_fields = []
352
- current_object.extensibleGroups.each do |current_extensible_group|
353
- current_fields << current_extensible_group.getString(0).to_s
354
- end
355
-
356
- fields_to_add = []
357
- new_object.extensibleGroups.each do |new_extensible_group|
358
- field = new_extensible_group.getString(0).to_s
359
- unless current_fields.include?(field)
360
- current_fields << field
361
- fields_to_add << field
362
- end
363
- end
364
-
365
- unless fields_to_add.empty?
366
- fields_to_add.each do |field|
367
- values = OpenStudio::StringVector.new
368
- values << field
369
- current_object.pushExtensibleGroup(values)
370
- end
371
- return true
372
- end
373
-
374
- return false
375
- end
376
-
377
- def self.monthly_report_idf_text
378
- <<-HEREDOC
379
- Output:Table:Monthly,
380
- Building Energy Performance - Electricity, !- Name
381
- 2, !- Digits After Decimal
382
- InteriorLights:Electricity, !- Variable or Meter 1 Name
383
- SumOrAverage, !- Aggregation Type for Variable or Meter 1
384
- ExteriorLights:Electricity, !- Variable or Meter 2 Name
385
- SumOrAverage, !- Aggregation Type for Variable or Meter 2
386
- InteriorEquipment:Electricity, !- Variable or Meter 3 Name
387
- SumOrAverage, !- Aggregation Type for Variable or Meter 3
388
- ExteriorEquipment:Electricity, !- Variable or Meter 4 Name
389
- SumOrAverage, !- Aggregation Type for Variable or Meter 4
390
- Fans:Electricity, !- Variable or Meter 5 Name
391
- SumOrAverage, !- Aggregation Type for Variable or Meter 5
392
- Pumps:Electricity, !- Variable or Meter 6 Name
393
- SumOrAverage, !- Aggregation Type for Variable or Meter 6
394
- Heating:Electricity, !- Variable or Meter 7 Name
395
- SumOrAverage, !- Aggregation Type for Variable or Meter 7
396
- Cooling:Electricity, !- Variable or Meter 8 Name
397
- SumOrAverage, !- Aggregation Type for Variable or Meter 8
398
- HeatRejection:Electricity, !- Variable or Meter 9 Name
399
- SumOrAverage, !- Aggregation Type for Variable or Meter 9
400
- Humidifier:Electricity, !- Variable or Meter 10 Name
401
- SumOrAverage, !- Aggregation Type for Variable or Meter 10
402
- HeatRecovery:Electricity,!- Variable or Meter 11 Name
403
- SumOrAverage, !- Aggregation Type for Variable or Meter 11
404
- WaterSystems:Electricity,!- Variable or Meter 12 Name
405
- SumOrAverage, !- Aggregation Type for Variable or Meter 12
406
- Cogeneration:Electricity,!- Variable or Meter 13 Name
407
- SumOrAverage, !- Aggregation Type for Variable or Meter 13
408
- Refrigeration:Electricity,!- Variable or Meter 14 Name
409
- SumOrAverage; !- Aggregation Type for Variable or Meter 14
410
-
411
- Output:Table:Monthly,
412
- Building Energy Performance - Natural Gas, !- Name
413
- 2, !- Digits After Decimal
414
- InteriorEquipment:Gas, !- Variable or Meter 1 Name
415
- SumOrAverage, !- Aggregation Type for Variable or Meter 1
416
- ExteriorEquipment:Gas, !- Variable or Meter 2 Name
417
- SumOrAverage, !- Aggregation Type for Variable or Meter 2
418
- Heating:Gas, !- Variable or Meter 3 Name
419
- SumOrAverage, !- Aggregation Type for Variable or Meter 3
420
- Cooling:Gas, !- Variable or Meter 4 Name
421
- SumOrAverage, !- Aggregation Type for Variable or Meter 4
422
- WaterSystems:Gas, !- Variable or Meter 5 Name
423
- SumOrAverage, !- Aggregation Type for Variable or Meter 5
424
- Cogeneration:Gas, !- Variable or Meter 6 Name
425
- SumOrAverage; !- Aggregation Type for Variable or Meter 6
426
-
427
- Output:Table:Monthly,
428
- Building Energy Performance - District Heating, !- Name
429
- 2, !- Digits After Decimal
430
- InteriorLights:DistrictHeating, !- Variable or Meter 1 Name
431
- SumOrAverage, !- Aggregation Type for Variable or Meter 1
432
- ExteriorLights:DistrictHeating, !- Variable or Meter 2 Name
433
- SumOrAverage, !- Aggregation Type for Variable or Meter 2
434
- InteriorEquipment:DistrictHeating, !- Variable or Meter 3 Name
435
- SumOrAverage, !- Aggregation Type for Variable or Meter 3
436
- ExteriorEquipment:DistrictHeating, !- Variable or Meter 4 Name
437
- SumOrAverage, !- Aggregation Type for Variable or Meter 4
438
- Fans:DistrictHeating, !- Variable or Meter 5 Name
439
- SumOrAverage, !- Aggregation Type for Variable or Meter 5
440
- Pumps:DistrictHeating, !- Variable or Meter 6 Name
441
- SumOrAverage, !- Aggregation Type for Variable or Meter 6
442
- Heating:DistrictHeating, !- Variable or Meter 7 Name
443
- SumOrAverage, !- Aggregation Type for Variable or Meter 7
444
- Cooling:DistrictHeating, !- Variable or Meter 8 Name
445
- SumOrAverage, !- Aggregation Type for Variable or Meter 8
446
- HeatRejection:DistrictHeating, !- Variable or Meter 9 Name
447
- SumOrAverage, !- Aggregation Type for Variable or Meter 9
448
- Humidifier:DistrictHeating, !- Variable or Meter 10 Name
449
- SumOrAverage, !- Aggregation Type for Variable or Meter 10
450
- HeatRecovery:DistrictHeating,!- Variable or Meter 11 Name
451
- SumOrAverage, !- Aggregation Type for Variable or Meter 11
452
- WaterSystems:DistrictHeating,!- Variable or Meter 12 Name
453
- SumOrAverage, !- Aggregation Type for Variable or Meter 12
454
- Cogeneration:DistrictHeating,!- Variable or Meter 13 Name
455
- SumOrAverage; !- Aggregation Type for Variable or Meter 13
456
-
457
- Output:Table:Monthly,
458
- Building Energy Performance - District Cooling, !- Name
459
- 2, !- Digits After Decimal
460
- InteriorLights:DistrictCooling, !- Variable or Meter 1 Name
461
- SumOrAverage, !- Aggregation Type for Variable or Meter 1
462
- ExteriorLights:DistrictCooling, !- Variable or Meter 2 Name
463
- SumOrAverage, !- Aggregation Type for Variable or Meter 2
464
- InteriorEquipment:DistrictCooling, !- Variable or Meter 3 Name
465
- SumOrAverage, !- Aggregation Type for Variable or Meter 3
466
- ExteriorEquipment:DistrictCooling, !- Variable or Meter 4 Name
467
- SumOrAverage, !- Aggregation Type for Variable or Meter 4
468
- Fans:DistrictCooling, !- Variable or Meter 5 Name
469
- SumOrAverage, !- Aggregation Type for Variable or Meter 5
470
- Pumps:DistrictCooling, !- Variable or Meter 6 Name
471
- SumOrAverage, !- Aggregation Type for Variable or Meter 6
472
- Heating:DistrictCooling, !- Variable or Meter 7 Name
473
- SumOrAverage, !- Aggregation Type for Variable or Meter 7
474
- Cooling:DistrictCooling, !- Variable or Meter 8 Name
475
- SumOrAverage, !- Aggregation Type for Variable or Meter 8
476
- HeatRejection:DistrictCooling, !- Variable or Meter 9 Name
477
- SumOrAverage, !- Aggregation Type for Variable or Meter 9
478
- Humidifier:DistrictCooling, !- Variable or Meter 10 Name
479
- SumOrAverage, !- Aggregation Type for Variable or Meter 10
480
- HeatRecovery:DistrictCooling,!- Variable or Meter 11 Name
481
- SumOrAverage, !- Aggregation Type for Variable or Meter 11
482
- WaterSystems:DistrictCooling,!- Variable or Meter 12 Name
483
- SumOrAverage, !- Aggregation Type for Variable or Meter 12
484
- Cogeneration:DistrictCooling,!- Variable or Meter 13 Name
485
- SumOrAverage; !- Aggregation Type for Variable or Meter 13
486
-
487
- Output:Table:Monthly,
488
- Building Energy Performance - Electricity Peak Demand, !- Name
489
- 2, !- Digits After Decimal
490
- Electricity:Facility, !- Variable or Meter 1 Name
491
- Maximum, !- Aggregation Type for Variable or Meter 1
492
- InteriorLights:Electricity, !- Variable or Meter 1 Name
493
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 1
494
- ExteriorLights:Electricity, !- Variable or Meter 2 Name
495
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 2
496
- InteriorEquipment:Electricity, !- Variable or Meter 3 Name
497
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 3
498
- ExteriorEquipment:Electricity, !- Variable or Meter 4 Name
499
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 4
500
- Fans:Electricity, !- Variable or Meter 5 Name
501
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 5
502
- Pumps:Electricity, !- Variable or Meter 6 Name
503
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 6
504
- Heating:Electricity, !- Variable or Meter 7 Name
505
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 7
506
- Cooling:Electricity, !- Variable or Meter 8 Name
507
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 8
508
- HeatRejection:Electricity, !- Variable or Meter 9 Name
509
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 9
510
- Humidifier:Electricity, !- Variable or Meter 10 Name
511
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 10
512
- HeatRecovery:Electricity,!- Variable or Meter 11 Name
513
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 11
514
- WaterSystems:Electricity,!- Variable or Meter 12 Name
515
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 12
516
- Cogeneration:Electricity,!- Variable or Meter 13 Name
517
- ValueWhenMaximumOrMinimum; !- Aggregation Type for Variable or Meter 13
518
-
519
- Output:Table:Monthly,
520
- Building Energy Performance - Natural Gas Peak Demand, !- Name
521
- 2, !- Digits After Decimal
522
- Gas:Facility, !- Variable or Meter 1 Name
523
- Maximum, !- Aggregation Type for Variable or Meter 1
524
- InteriorEquipment:Gas, !- Variable or Meter 1 Name
525
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 1
526
- ExteriorEquipment:Gas, !- Variable or Meter 2 Name
527
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 2
528
- Heating:Gas, !- Variable or Meter 3 Name
529
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 3
530
- Cooling:Gas, !- Variable or Meter 4 Name
531
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 4
532
- WaterSystems:Gas, !- Variable or Meter 5 Name
533
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 5
534
- Cogeneration:Gas, !- Variable or Meter 6 Name
535
- ValueWhenMaximumOrMinimum; !- Aggregation Type for Variable or Meter 6
536
-
537
- Output:Table:Monthly,
538
- Building Energy Performance - District Heating Peak Demand, !- Name
539
- 2, !- Digits After Decimal
540
- DistrictHeating:Facility, !- Variable or Meter 1 Name
541
- Maximum, !- Aggregation Type for Variable or Meter 1
542
- InteriorLights:DistrictHeating, !- Variable or Meter 1 Name
543
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 1
544
- ExteriorLights:DistrictHeating, !- Variable or Meter 2 Name
545
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 2
546
- InteriorEquipment:DistrictHeating, !- Variable or Meter 3 Name
547
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 3
548
- ExteriorEquipment:DistrictHeating, !- Variable or Meter 4 Name
549
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 4
550
- Fans:DistrictHeating, !- Variable or Meter 5 Name
551
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 5
552
- Pumps:DistrictHeating, !- Variable or Meter 6 Name
553
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 6
554
- Heating:DistrictHeating, !- Variable or Meter 7 Name
555
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 7
556
- Cooling:DistrictHeating, !- Variable or Meter 8 Name
557
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 8
558
- HeatRejection:DistrictHeating, !- Variable or Meter 9 Name
559
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 9
560
- Humidifier:DistrictHeating, !- Variable or Meter 10 Name
561
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 10
562
- HeatRecovery:DistrictHeating,!- Variable or Meter 11 Name
563
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 11
564
- WaterSystems:DistrictHeating,!- Variable or Meter 12 Name
565
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 12
566
- Cogeneration:DistrictHeating,!- Variable or Meter 13 Name
567
- ValueWhenMaximumOrMinimum; !- Aggregation Type for Variable or Meter 13
568
-
569
- Output:Table:Monthly,
570
- Building Energy Performance - District Cooling Peak Demand, !- Name
571
- 2, !- Digits After Decimal
572
- DistrictCooling:Facility, !- Variable or Meter 1 Name
573
- Maximum, !- Aggregation Type for Variable or Meter 1
574
- InteriorLights:DistrictCooling, !- Variable or Meter 1 Name
575
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 1
576
- ExteriorLights:DistrictCooling, !- Variable or Meter 2 Name
577
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 2
578
- InteriorEquipment:DistrictCooling, !- Variable or Meter 3 Name
579
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 3
580
- ExteriorEquipment:DistrictCooling, !- Variable or Meter 4 Name
581
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 4
582
- Fans:DistrictCooling, !- Variable or Meter 5 Name
583
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 5
584
- Pumps:DistrictCooling, !- Variable or Meter 6 Name
585
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 6
586
- Heating:DistrictCooling, !- Variable or Meter 7 Name
587
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 7
588
- Cooling:DistrictCooling, !- Variable or Meter 8 Name
589
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 8
590
- HeatRejection:DistrictCooling, !- Variable or Meter 9 Name
591
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 9
592
- Humidifier:DistrictCooling, !- Variable or Meter 10 Name
593
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 10
594
- HeatRecovery:DistrictCooling,!- Variable or Meter 11 Name
595
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 11
596
- WaterSystems:DistrictCooling,!- Variable or Meter 12 Name
597
- ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 12
598
- Cogeneration:DistrictCooling,!- Variable or Meter 13 Name
599
- ValueWhenMaximumOrMinimum; !- Aggregation Type for Variable or Meter 13
600
- HEREDOC
601
- end
602
- end
603
- end
604
- end
605
- end
1
+ # *******************************************************************************
2
+ # OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC.
3
+ # All rights reserved.
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are met:
6
+ #
7
+ # (1) Redistributions of source code must retain the above copyright notice,
8
+ # this list of conditions and the following disclaimer.
9
+ #
10
+ # (2) Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ #
14
+ # (3) Neither the name of the copyright holder nor the names of any contributors
15
+ # may be used to endorse or promote products derived from this software without
16
+ # specific prior written permission from the respective party.
17
+ #
18
+ # (4) Other than as required in clauses (1) and (2), distributions in any form
19
+ # of modifications or other derivative works may not use the "OpenStudio"
20
+ # trademark, "OS", "os", or any other confusingly similar designation without
21
+ # specific prior written permission from Alliance for Sustainable Energy, LLC.
22
+ #
23
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER, THE UNITED STATES
27
+ # GOVERNMENT, OR ANY CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28
+ # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30
+ # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
33
+ # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
+ # *******************************************************************************
35
+
36
+ module OpenStudio
37
+ module Workflow
38
+ module Util
39
+ # The methods needed to run simulations using EnergyPlus are stored here. See the run_simulation class for
40
+ # implementation details.
41
+ module EnergyPlus
42
+ require 'openstudio/workflow/util/io'
43
+ include OpenStudio::Workflow::Util::IO
44
+ ENERGYPLUS_REGEX = /^energyplus\D{0,4}$/i
45
+ EXPAND_OBJECTS_REGEX = /^expandobjects\D{0,4}$/i
46
+
47
+ # Find the installation directory of EnergyPlus linked to the OpenStudio version being used
48
+ #
49
+ # @return [String] Returns the path to EnergyPlus
50
+ #
51
+ def find_energyplus
52
+ path = OpenStudio.getEnergyPlusDirectory.to_s
53
+ raise 'Unable to find the EnergyPlus executable' unless File.exist? path
54
+ path
55
+ end
56
+
57
+ # Does something
58
+ #
59
+ # @param [String] run_directory Directory to run the EnergyPlus simulation in
60
+ # @param [Array] energyplus_files Array of files containing the EnergyPlus and ExpandObjects EXEs
61
+ # @return [Void]
62
+ #
63
+ def clean_directory(run_directory, energyplus_files, logger)
64
+ logger.info 'Removing any copied EnergyPlus files'
65
+ energyplus_files.each do |file|
66
+ if File.exist? file
67
+ FileUtils.rm_f file
68
+ end
69
+ end
70
+
71
+ paths_to_rm = []
72
+ paths_to_rm << "#{run_directory}/packaged_measures"
73
+ paths_to_rm << "#{run_directory}/Energy+.ini"
74
+ paths_to_rm.each { |p| FileUtils.rm_rf(p) if File.exist?(p) }
75
+ end
76
+
77
+ # Prepare the directory to run EnergyPlus
78
+ #
79
+ # @param [String] run_directory Directory to copy the required EnergyPlus files to
80
+ # @param [Object] logger Logger object
81
+ # @param [String] energyplus_path Path to the EnergyPlus EXE
82
+ # @return [Array, file, file] Returns an array of strings of EnergyPlus files copied to the run_directory, the
83
+ # ExpandObjects EXE file, and EnergyPlus EXE file
84
+ #
85
+ def prepare_energyplus_dir(run_directory, logger, energyplus_path = nil)
86
+ logger.info "Copying EnergyPlus files to run directory: #{run_directory}"
87
+ energyplus_path ||= find_energyplus
88
+ logger.info "EnergyPlus path is #{energyplus_path}"
89
+ energyplus_files = []
90
+ energyplus_exe, expand_objects_exe = nil
91
+ Dir["#{energyplus_path}/*"].each do |file|
92
+ next if File.directory? file
93
+
94
+ # copy idd and ini files
95
+ if File.extname(file).downcase =~ /.idd|.ini/
96
+ dest_file = "#{run_directory}/#{File.basename(file)}"
97
+ energyplus_files << dest_file
98
+ FileUtils.copy file, dest_file
99
+ end
100
+
101
+ energyplus_exe = file if File.basename(file) =~ ENERGYPLUS_REGEX
102
+ expand_objects_exe = file if File.basename(file) =~ EXPAND_OBJECTS_REGEX
103
+ end
104
+
105
+ raise "Could not find EnergyPlus executable in #{energyplus_path}" unless energyplus_exe
106
+ raise "Could not find ExpandObjects executable in #{energyplus_path}" unless expand_objects_exe
107
+
108
+ logger.info "EnergyPlus executable path is #{energyplus_exe}"
109
+ logger.info "ExpandObjects executable path is #{expand_objects_exe}"
110
+
111
+ return energyplus_files, energyplus_exe, expand_objects_exe
112
+ end
113
+
114
+ # Configures and executes the EnergyPlus simulation and checks to see if the simulation was successful
115
+ #
116
+ # @param [String] run_directory Directory to execute the EnergyPlus simulation in. It is assumed that this
117
+ # directory already has the IDF and weather file in it
118
+ # @param [String] energyplus_path (nil) Optional path to override the default path associated with the
119
+ # OpenStudio package being used
120
+ # @param [Object] output_adapter (nil) Optional output adapter to update
121
+ # @param [Object] logger (nil) Optional logger, will log to STDOUT if none provided
122
+ # @return [Void]
123
+ #
124
+ def call_energyplus(run_directory, energyplus_path = nil, output_adapter = nil, logger = nil, workflow_json = nil)
125
+ logger ||= ::Logger.new(STDOUT) unless logger
126
+
127
+ current_dir = Dir.pwd
128
+ energyplus_path ||= find_energyplus
129
+ logger.info "EnergyPlus path is #{energyplus_path}"
130
+ energyplus_files, energyplus_exe, expand_objects_exe = prepare_energyplus_dir(run_directory, logger, energyplus_path)
131
+ Dir.chdir(run_directory)
132
+ logger.info "Starting simulation in run directory: #{Dir.pwd}"
133
+
134
+ if !@options[:skip_expand_objects]
135
+ command = popen_command("\"#{expand_objects_exe}\"")
136
+ logger.info "Running command '#{command}'"
137
+ File.open('stdout-expandobject', 'w') do |file|
138
+ ::IO.popen(command) do |io|
139
+ while (line = io.gets)
140
+ file << line
141
+ end
142
+ end
143
+ end
144
+
145
+ # Check if expand objects did anything
146
+ if File.exist? 'expanded.idf'
147
+ FileUtils.mv('in.idf', 'pre-expand.idf', force: true) if File.exist?('in.idf')
148
+ FileUtils.mv('expanded.idf', 'in.idf', force: true)
149
+ end
150
+ end
151
+
152
+ # create stdout
153
+ command = popen_command("\"#{energyplus_exe}\" 2>&1")
154
+ logger.info "Running command '#{command}'"
155
+ File.open('stdout-energyplus', 'w') do |file|
156
+ ::IO.popen(command) do |io|
157
+ while (line = io.gets)
158
+ file << line
159
+ output_adapter.communicate_energyplus_stdout(line) if output_adapter
160
+ end
161
+ end
162
+ end
163
+ r = $?
164
+
165
+ logger.info "EnergyPlus returned '#{r}'"
166
+ unless r.to_i.zero?
167
+ logger.warn 'EnergyPlus returned a non-zero exit code. Check the stdout-energyplus log.'
168
+ end
169
+
170
+ if File.exist? 'eplusout.err'
171
+ eplus_err = File.read('eplusout.err').force_encoding('ISO-8859-1').encode('utf-8', replace: nil)
172
+
173
+ if workflow_json
174
+ begin
175
+ if !@options[:fast]
176
+ workflow_json.setEplusoutErr(eplus_err)
177
+ end
178
+ rescue StandardError => e
179
+ # older versions of OpenStudio did not have the setEplusoutErr method
180
+ end
181
+ end
182
+
183
+ if eplus_err =~ /EnergyPlus Terminated--Fatal Error Detected/
184
+ raise 'EnergyPlus Terminated with a Fatal Error. Check eplusout.err log.'
185
+ end
186
+ end
187
+
188
+ if File.exist? 'eplusout.end'
189
+ f = File.read('eplusout.end').force_encoding('ISO-8859-1').encode('utf-8', replace: nil)
190
+ warnings_count = f[/(\d*).Warning/, 1]
191
+ error_count = f[/(\d*).Severe.Errors/, 1]
192
+ logger.info "EnergyPlus finished with #{warnings_count} warnings and #{error_count} severe errors"
193
+ if f =~ /EnergyPlus Terminated--Fatal Error Detected/
194
+ raise 'EnergyPlus Terminated with a Fatal Error. Check eplusout.err log.'
195
+ end
196
+ else
197
+ raise 'EnergyPlus failed and did not create an eplusout.end file. Check the stdout-energyplus log.'
198
+ end
199
+ rescue StandardError => e
200
+ log_message = "#{__FILE__} failed with #{e.message}, #{e.backtrace.join("\n")}"
201
+ logger.error log_message
202
+ raise log_message
203
+ ensure
204
+ logger.info "Ensuring 'clean' directory"
205
+ clean_directory(run_directory, energyplus_files, logger)
206
+
207
+ Dir.chdir(current_dir)
208
+ logger.info 'EnergyPlus Completed'
209
+ end
210
+
211
+ # Run this code before running EnergyPlus to make sure the reporting variables are setup correctly
212
+ #
213
+ # @param [Object] idf The IDF Workspace to be simulated
214
+ # @return [Void]
215
+ #
216
+ def energyplus_preprocess(idf, logger)
217
+ logger.info 'Running EnergyPlus Preprocess'
218
+
219
+ new_objects = []
220
+
221
+ needs_sqlobj = idf.getObjectsByType('Output:SQLite'.to_IddObjectType).empty?
222
+
223
+ if needs_sqlobj
224
+ # just add this, we don't allow this type in add_energyplus_output_request
225
+ logger.info 'Adding SQL Output to IDF'
226
+ object = OpenStudio::IdfObject.load('Output:SQLite,SimpleAndTabular;').get
227
+ idf.addObjects(object)
228
+ end
229
+
230
+ # merge in monthly reports
231
+ EnergyPlus.monthly_report_idf_text.split(/^[\s]*$/).each do |object|
232
+ object = object.strip
233
+ next if object.empty?
234
+
235
+ new_objects << object
236
+ end
237
+
238
+ # These are needed for the calibration report
239
+ new_objects << 'Output:Meter:MeterFileOnly,Gas:Facility,Daily;'
240
+ new_objects << 'Output:Meter:MeterFileOnly,Electricity:Facility,Timestep;'
241
+ new_objects << 'Output:Meter:MeterFileOnly,Electricity:Facility,Daily;'
242
+
243
+ # Always add in the timestep facility meters
244
+ new_objects << 'Output:Meter,Electricity:Facility,Timestep;'
245
+ new_objects << 'Output:Meter,Gas:Facility,Timestep;'
246
+ new_objects << 'Output:Meter,DistrictCooling:Facility,Timestep;'
247
+ new_objects << 'Output:Meter,DistrictHeating:Facility,Timestep;'
248
+
249
+ new_objects.each do |obj|
250
+ object = OpenStudio::IdfObject.load(obj).get
251
+ OpenStudio::Workflow::Util::EnergyPlus.add_energyplus_output_request(idf, object)
252
+ end
253
+
254
+ logger.info 'Finished EnergyPlus Preprocess'
255
+ end
256
+
257
+ # examines object and determines whether or not to add it to the workspace
258
+ def self.add_energyplus_output_request(workspace, idf_object)
259
+ num_added = 0
260
+ idd_object = idf_object.iddObject
261
+
262
+ allowed_objects = []
263
+ allowed_objects << 'Output:Surfaces:List'
264
+ allowed_objects << 'Output:Surfaces:Drawing'
265
+ allowed_objects << 'Output:Schedules'
266
+ allowed_objects << 'Output:Constructions'
267
+ allowed_objects << 'Output:Table:TimeBins'
268
+ allowed_objects << 'Output:Table:Monthly'
269
+ allowed_objects << 'Output:Variable'
270
+ allowed_objects << 'Output:Meter'
271
+ allowed_objects << 'Output:Meter:MeterFileOnly'
272
+ allowed_objects << 'Output:Meter:Cumulative'
273
+ allowed_objects << 'Output:Meter:Cumulative:MeterFileOnly'
274
+ allowed_objects << 'Meter:Custom'
275
+ allowed_objects << 'Meter:CustomDecrement'
276
+ allowed_objects << 'EnergyManagementSystem:OutputVariable'
277
+
278
+ if allowed_objects.include?(idd_object.name)
279
+ unless check_for_object(workspace, idf_object, idd_object.type)
280
+ workspace.addObject(idf_object)
281
+ num_added += 1
282
+ end
283
+ end
284
+
285
+ allowed_unique_objects = []
286
+ # allowed_unique_objects << "Output:EnergyManagementSystem" # TODO: have to merge
287
+ # allowed_unique_objects << "OutputControl:SurfaceColorScheme" # TODO: have to merge
288
+ allowed_unique_objects << 'Output:Table:SummaryReports' # TODO: have to merge
289
+ # OutputControl:Table:Style # not allowed
290
+ # OutputControl:ReportingTolerances # not allowed
291
+ # Output:SQLite # not allowed
292
+
293
+ if allowed_unique_objects.include?(idf_object.iddObject.name)
294
+ if idf_object.iddObject.name == 'Output:Table:SummaryReports'
295
+ summary_reports = workspace.getObjectsByType(idf_object.iddObject.type)
296
+ if summary_reports.empty?
297
+ workspace.addObject(idf_object)
298
+ num_added += 1
299
+ else
300
+ merge_output_table_summary_reports(summary_reports[0], idf_object)
301
+ end
302
+ end
303
+ end
304
+
305
+ return num_added
306
+ end
307
+
308
+ # check to see if we have an exact match for this object already
309
+ def self.check_for_object(workspace, idf_object, idd_object_type)
310
+ workspace.getObjectsByType(idd_object_type).each do |object|
311
+ # all of these objects fields are data fields
312
+ if idf_object.dataFieldsEqual(object)
313
+ return true
314
+ end
315
+ end
316
+ return false
317
+ end
318
+
319
+ # merge all summary reports that are not in the current workspace
320
+ def self.merge_output_table_summary_reports(current_object, new_object)
321
+ current_fields = []
322
+ current_object.extensibleGroups.each do |current_extensible_group|
323
+ current_fields << current_extensible_group.getString(0).to_s
324
+ end
325
+
326
+ fields_to_add = []
327
+ new_object.extensibleGroups.each do |new_extensible_group|
328
+ field = new_extensible_group.getString(0).to_s
329
+ unless current_fields.include?(field)
330
+ current_fields << field
331
+ fields_to_add << field
332
+ end
333
+ end
334
+
335
+ unless fields_to_add.empty?
336
+ fields_to_add.each do |field|
337
+ values = OpenStudio::StringVector.new
338
+ values << field
339
+ current_object.pushExtensibleGroup(values)
340
+ end
341
+ return true
342
+ end
343
+
344
+ return false
345
+ end
346
+
347
+ def self.monthly_report_idf_text
348
+ <<-HEREDOC
349
+ Output:Table:Monthly,
350
+ Building Energy Performance - Electricity, !- Name
351
+ 2, !- Digits After Decimal
352
+ InteriorLights:Electricity, !- Variable or Meter 1 Name
353
+ SumOrAverage, !- Aggregation Type for Variable or Meter 1
354
+ ExteriorLights:Electricity, !- Variable or Meter 2 Name
355
+ SumOrAverage, !- Aggregation Type for Variable or Meter 2
356
+ InteriorEquipment:Electricity, !- Variable or Meter 3 Name
357
+ SumOrAverage, !- Aggregation Type for Variable or Meter 3
358
+ ExteriorEquipment:Electricity, !- Variable or Meter 4 Name
359
+ SumOrAverage, !- Aggregation Type for Variable or Meter 4
360
+ Fans:Electricity, !- Variable or Meter 5 Name
361
+ SumOrAverage, !- Aggregation Type for Variable or Meter 5
362
+ Pumps:Electricity, !- Variable or Meter 6 Name
363
+ SumOrAverage, !- Aggregation Type for Variable or Meter 6
364
+ Heating:Electricity, !- Variable or Meter 7 Name
365
+ SumOrAverage, !- Aggregation Type for Variable or Meter 7
366
+ Cooling:Electricity, !- Variable or Meter 8 Name
367
+ SumOrAverage, !- Aggregation Type for Variable or Meter 8
368
+ HeatRejection:Electricity, !- Variable or Meter 9 Name
369
+ SumOrAverage, !- Aggregation Type for Variable or Meter 9
370
+ Humidifier:Electricity, !- Variable or Meter 10 Name
371
+ SumOrAverage, !- Aggregation Type for Variable or Meter 10
372
+ HeatRecovery:Electricity,!- Variable or Meter 11 Name
373
+ SumOrAverage, !- Aggregation Type for Variable or Meter 11
374
+ WaterSystems:Electricity,!- Variable or Meter 12 Name
375
+ SumOrAverage, !- Aggregation Type for Variable or Meter 12
376
+ Cogeneration:Electricity,!- Variable or Meter 13 Name
377
+ SumOrAverage, !- Aggregation Type for Variable or Meter 13
378
+ Refrigeration:Electricity,!- Variable or Meter 14 Name
379
+ SumOrAverage; !- Aggregation Type for Variable or Meter 14
380
+
381
+ Output:Table:Monthly,
382
+ Building Energy Performance - Natural Gas, !- Name
383
+ 2, !- Digits After Decimal
384
+ InteriorEquipment:Gas, !- Variable or Meter 1 Name
385
+ SumOrAverage, !- Aggregation Type for Variable or Meter 1
386
+ ExteriorEquipment:Gas, !- Variable or Meter 2 Name
387
+ SumOrAverage, !- Aggregation Type for Variable or Meter 2
388
+ Heating:Gas, !- Variable or Meter 3 Name
389
+ SumOrAverage, !- Aggregation Type for Variable or Meter 3
390
+ Cooling:Gas, !- Variable or Meter 4 Name
391
+ SumOrAverage, !- Aggregation Type for Variable or Meter 4
392
+ WaterSystems:Gas, !- Variable or Meter 5 Name
393
+ SumOrAverage, !- Aggregation Type for Variable or Meter 5
394
+ Cogeneration:Gas, !- Variable or Meter 6 Name
395
+ SumOrAverage; !- Aggregation Type for Variable or Meter 6
396
+
397
+ Output:Table:Monthly,
398
+ Building Energy Performance - District Heating, !- Name
399
+ 2, !- Digits After Decimal
400
+ InteriorLights:DistrictHeating, !- Variable or Meter 1 Name
401
+ SumOrAverage, !- Aggregation Type for Variable or Meter 1
402
+ ExteriorLights:DistrictHeating, !- Variable or Meter 2 Name
403
+ SumOrAverage, !- Aggregation Type for Variable or Meter 2
404
+ InteriorEquipment:DistrictHeating, !- Variable or Meter 3 Name
405
+ SumOrAverage, !- Aggregation Type for Variable or Meter 3
406
+ ExteriorEquipment:DistrictHeating, !- Variable or Meter 4 Name
407
+ SumOrAverage, !- Aggregation Type for Variable or Meter 4
408
+ Fans:DistrictHeating, !- Variable or Meter 5 Name
409
+ SumOrAverage, !- Aggregation Type for Variable or Meter 5
410
+ Pumps:DistrictHeating, !- Variable or Meter 6 Name
411
+ SumOrAverage, !- Aggregation Type for Variable or Meter 6
412
+ Heating:DistrictHeating, !- Variable or Meter 7 Name
413
+ SumOrAverage, !- Aggregation Type for Variable or Meter 7
414
+ Cooling:DistrictHeating, !- Variable or Meter 8 Name
415
+ SumOrAverage, !- Aggregation Type for Variable or Meter 8
416
+ HeatRejection:DistrictHeating, !- Variable or Meter 9 Name
417
+ SumOrAverage, !- Aggregation Type for Variable or Meter 9
418
+ Humidifier:DistrictHeating, !- Variable or Meter 10 Name
419
+ SumOrAverage, !- Aggregation Type for Variable or Meter 10
420
+ HeatRecovery:DistrictHeating,!- Variable or Meter 11 Name
421
+ SumOrAverage, !- Aggregation Type for Variable or Meter 11
422
+ WaterSystems:DistrictHeating,!- Variable or Meter 12 Name
423
+ SumOrAverage, !- Aggregation Type for Variable or Meter 12
424
+ Cogeneration:DistrictHeating,!- Variable or Meter 13 Name
425
+ SumOrAverage; !- Aggregation Type for Variable or Meter 13
426
+
427
+ Output:Table:Monthly,
428
+ Building Energy Performance - District Cooling, !- Name
429
+ 2, !- Digits After Decimal
430
+ InteriorLights:DistrictCooling, !- Variable or Meter 1 Name
431
+ SumOrAverage, !- Aggregation Type for Variable or Meter 1
432
+ ExteriorLights:DistrictCooling, !- Variable or Meter 2 Name
433
+ SumOrAverage, !- Aggregation Type for Variable or Meter 2
434
+ InteriorEquipment:DistrictCooling, !- Variable or Meter 3 Name
435
+ SumOrAverage, !- Aggregation Type for Variable or Meter 3
436
+ ExteriorEquipment:DistrictCooling, !- Variable or Meter 4 Name
437
+ SumOrAverage, !- Aggregation Type for Variable or Meter 4
438
+ Fans:DistrictCooling, !- Variable or Meter 5 Name
439
+ SumOrAverage, !- Aggregation Type for Variable or Meter 5
440
+ Pumps:DistrictCooling, !- Variable or Meter 6 Name
441
+ SumOrAverage, !- Aggregation Type for Variable or Meter 6
442
+ Heating:DistrictCooling, !- Variable or Meter 7 Name
443
+ SumOrAverage, !- Aggregation Type for Variable or Meter 7
444
+ Cooling:DistrictCooling, !- Variable or Meter 8 Name
445
+ SumOrAverage, !- Aggregation Type for Variable or Meter 8
446
+ HeatRejection:DistrictCooling, !- Variable or Meter 9 Name
447
+ SumOrAverage, !- Aggregation Type for Variable or Meter 9
448
+ Humidifier:DistrictCooling, !- Variable or Meter 10 Name
449
+ SumOrAverage, !- Aggregation Type for Variable or Meter 10
450
+ HeatRecovery:DistrictCooling,!- Variable or Meter 11 Name
451
+ SumOrAverage, !- Aggregation Type for Variable or Meter 11
452
+ WaterSystems:DistrictCooling,!- Variable or Meter 12 Name
453
+ SumOrAverage, !- Aggregation Type for Variable or Meter 12
454
+ Cogeneration:DistrictCooling,!- Variable or Meter 13 Name
455
+ SumOrAverage; !- Aggregation Type for Variable or Meter 13
456
+
457
+ Output:Table:Monthly,
458
+ Building Energy Performance - Electricity Peak Demand, !- Name
459
+ 2, !- Digits After Decimal
460
+ Electricity:Facility, !- Variable or Meter 1 Name
461
+ Maximum, !- Aggregation Type for Variable or Meter 1
462
+ InteriorLights:Electricity, !- Variable or Meter 1 Name
463
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 1
464
+ ExteriorLights:Electricity, !- Variable or Meter 2 Name
465
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 2
466
+ InteriorEquipment:Electricity, !- Variable or Meter 3 Name
467
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 3
468
+ ExteriorEquipment:Electricity, !- Variable or Meter 4 Name
469
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 4
470
+ Fans:Electricity, !- Variable or Meter 5 Name
471
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 5
472
+ Pumps:Electricity, !- Variable or Meter 6 Name
473
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 6
474
+ Heating:Electricity, !- Variable or Meter 7 Name
475
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 7
476
+ Cooling:Electricity, !- Variable or Meter 8 Name
477
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 8
478
+ HeatRejection:Electricity, !- Variable or Meter 9 Name
479
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 9
480
+ Humidifier:Electricity, !- Variable or Meter 10 Name
481
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 10
482
+ HeatRecovery:Electricity,!- Variable or Meter 11 Name
483
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 11
484
+ WaterSystems:Electricity,!- Variable or Meter 12 Name
485
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 12
486
+ Cogeneration:Electricity,!- Variable or Meter 13 Name
487
+ ValueWhenMaximumOrMinimum; !- Aggregation Type for Variable or Meter 13
488
+
489
+ Output:Table:Monthly,
490
+ Building Energy Performance - Natural Gas Peak Demand, !- Name
491
+ 2, !- Digits After Decimal
492
+ Gas:Facility, !- Variable or Meter 1 Name
493
+ Maximum, !- Aggregation Type for Variable or Meter 1
494
+ InteriorEquipment:Gas, !- Variable or Meter 1 Name
495
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 1
496
+ ExteriorEquipment:Gas, !- Variable or Meter 2 Name
497
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 2
498
+ Heating:Gas, !- Variable or Meter 3 Name
499
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 3
500
+ Cooling:Gas, !- Variable or Meter 4 Name
501
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 4
502
+ WaterSystems:Gas, !- Variable or Meter 5 Name
503
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 5
504
+ Cogeneration:Gas, !- Variable or Meter 6 Name
505
+ ValueWhenMaximumOrMinimum; !- Aggregation Type for Variable or Meter 6
506
+
507
+ Output:Table:Monthly,
508
+ Building Energy Performance - District Heating Peak Demand, !- Name
509
+ 2, !- Digits After Decimal
510
+ DistrictHeating:Facility, !- Variable or Meter 1 Name
511
+ Maximum, !- Aggregation Type for Variable or Meter 1
512
+ InteriorLights:DistrictHeating, !- Variable or Meter 1 Name
513
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 1
514
+ ExteriorLights:DistrictHeating, !- Variable or Meter 2 Name
515
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 2
516
+ InteriorEquipment:DistrictHeating, !- Variable or Meter 3 Name
517
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 3
518
+ ExteriorEquipment:DistrictHeating, !- Variable or Meter 4 Name
519
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 4
520
+ Fans:DistrictHeating, !- Variable or Meter 5 Name
521
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 5
522
+ Pumps:DistrictHeating, !- Variable or Meter 6 Name
523
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 6
524
+ Heating:DistrictHeating, !- Variable or Meter 7 Name
525
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 7
526
+ Cooling:DistrictHeating, !- Variable or Meter 8 Name
527
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 8
528
+ HeatRejection:DistrictHeating, !- Variable or Meter 9 Name
529
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 9
530
+ Humidifier:DistrictHeating, !- Variable or Meter 10 Name
531
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 10
532
+ HeatRecovery:DistrictHeating,!- Variable or Meter 11 Name
533
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 11
534
+ WaterSystems:DistrictHeating,!- Variable or Meter 12 Name
535
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 12
536
+ Cogeneration:DistrictHeating,!- Variable or Meter 13 Name
537
+ ValueWhenMaximumOrMinimum; !- Aggregation Type for Variable or Meter 13
538
+
539
+ Output:Table:Monthly,
540
+ Building Energy Performance - District Cooling Peak Demand, !- Name
541
+ 2, !- Digits After Decimal
542
+ DistrictCooling:Facility, !- Variable or Meter 1 Name
543
+ Maximum, !- Aggregation Type for Variable or Meter 1
544
+ InteriorLights:DistrictCooling, !- Variable or Meter 1 Name
545
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 1
546
+ ExteriorLights:DistrictCooling, !- Variable or Meter 2 Name
547
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 2
548
+ InteriorEquipment:DistrictCooling, !- Variable or Meter 3 Name
549
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 3
550
+ ExteriorEquipment:DistrictCooling, !- Variable or Meter 4 Name
551
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 4
552
+ Fans:DistrictCooling, !- Variable or Meter 5 Name
553
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 5
554
+ Pumps:DistrictCooling, !- Variable or Meter 6 Name
555
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 6
556
+ Heating:DistrictCooling, !- Variable or Meter 7 Name
557
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 7
558
+ Cooling:DistrictCooling, !- Variable or Meter 8 Name
559
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 8
560
+ HeatRejection:DistrictCooling, !- Variable or Meter 9 Name
561
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 9
562
+ Humidifier:DistrictCooling, !- Variable or Meter 10 Name
563
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 10
564
+ HeatRecovery:DistrictCooling,!- Variable or Meter 11 Name
565
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 11
566
+ WaterSystems:DistrictCooling,!- Variable or Meter 12 Name
567
+ ValueWhenMaximumOrMinimum, !- Aggregation Type for Variable or Meter 12
568
+ Cogeneration:DistrictCooling,!- Variable or Meter 13 Name
569
+ ValueWhenMaximumOrMinimum; !- Aggregation Type for Variable or Meter 13
570
+ HEREDOC
571
+ end
572
+ end
573
+ end
574
+ end
575
+ end