openstudio-workflow 1.3.3 → 1.3.4

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 +77 -72
  3. data/README.md +93 -93
  4. data/Rakefile +36 -36
  5. data/lib/openstudio-workflow.rb +65 -49
  6. data/lib/openstudio/workflow/adapters/input/local.rb +324 -301
  7. data/lib/openstudio/workflow/adapters/output/local.rb +161 -97
  8. data/lib/openstudio/workflow/adapters/output/socket.rb +107 -91
  9. data/lib/openstudio/workflow/adapters/output/web.rb +82 -66
  10. data/lib/openstudio/workflow/adapters/output_adapter.rb +163 -147
  11. data/lib/openstudio/workflow/job.rb +57 -22
  12. data/lib/openstudio/workflow/jobs/resources/monthly_report.idf +222 -222
  13. data/lib/openstudio/workflow/jobs/run_energyplus.rb +70 -54
  14. data/lib/openstudio/workflow/jobs/run_ep_measures.rb +73 -57
  15. data/lib/openstudio/workflow/jobs/run_initialization.rb +203 -171
  16. data/lib/openstudio/workflow/jobs/run_os_measures.rb +89 -73
  17. data/lib/openstudio/workflow/jobs/run_postprocess.rb +73 -57
  18. data/lib/openstudio/workflow/jobs/run_preprocess.rb +104 -80
  19. data/lib/openstudio/workflow/jobs/run_reporting_measures.rb +118 -102
  20. data/lib/openstudio/workflow/jobs/run_translation.rb +84 -68
  21. data/lib/openstudio/workflow/multi_delegator.rb +62 -46
  22. data/lib/openstudio/workflow/registry.rb +172 -137
  23. data/lib/openstudio/workflow/run.rb +328 -312
  24. data/lib/openstudio/workflow/time_logger.rb +96 -53
  25. data/lib/openstudio/workflow/util.rb +49 -14
  26. data/lib/openstudio/workflow/util/energyplus.rb +605 -570
  27. data/lib/openstudio/workflow/util/io.rb +68 -33
  28. data/lib/openstudio/workflow/util/measure.rb +650 -615
  29. data/lib/openstudio/workflow/util/model.rb +151 -100
  30. data/lib/openstudio/workflow/util/post_process.rb +238 -187
  31. data/lib/openstudio/workflow/util/weather_file.rb +143 -108
  32. data/lib/openstudio/workflow/version.rb +40 -24
  33. data/lib/openstudio/workflow_json.rb +476 -443
  34. data/lib/openstudio/workflow_runner.rb +268 -252
  35. metadata +23 -23
@@ -1,102 +1,118 @@
1
- ######################################################################
2
- # Copyright (c) 2008-2014, Alliance for Sustainable Energy.
3
- # All rights reserved.
4
- #
5
- # This library is free software; you can redistribute it and/or
6
- # modify it under the terms of the GNU Lesser General Public
7
- # License as published by the Free Software Foundation; either
8
- # version 2.1 of the License, or (at your option) any later version.
9
- #
10
- # This library is distributed in the hope that it will be useful,
11
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
- # Lesser General Public License for more details.
14
- #
15
- # You should have received a copy of the GNU Lesser General Public
16
- # License along with this library; if not, write to the Free Software
17
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
- ######################################################################
19
-
20
- # Run reporting measures and execute scripts to post-process objective functions and results on the filesystem
21
- class RunReportingMeasures < OpenStudio::Workflow::Job
22
- require 'csv'
23
- require 'ostruct'
24
- require 'openstudio/workflow/util'
25
- include OpenStudio::Workflow::Util::Model
26
- include OpenStudio::Workflow::Util::Measure
27
- include OpenStudio::Workflow::Util::PostProcess
28
-
29
- def initialize(input_adapter, output_adapter, registry, options = {})
30
- defaults = {
31
- load_simulation_osm: false,
32
- load_simulation_idf: false,
33
- load_simulation_sql: false
34
- }
35
- options = defaults.merge(options)
36
- super
37
- end
38
-
39
- def perform
40
- @logger.debug "Calling #{__method__} in the #{self.class} class"
41
- @logger.debug 'RunPostProcess Retrieving datapoint and problem'
42
-
43
- # halted workflow is handled in apply_measures
44
-
45
- # Ensure output_attributes is initialized in the registry
46
- @registry.register(:output_attributes) { {} } unless @registry[:output_attributes]
47
-
48
- # Load simulation files as required
49
- unless @registry[:runner].halted
50
- if @registry[:model].nil?
51
- osm_path = File.absolute_path(File.join(@registry[:run_dir], 'in.osm'))
52
- @logger.debug "Attempting to load #{osm_path}"
53
- @registry.register(:model) { load_osm('.', osm_path) }
54
- raise "Unable to load #{osm_path}" unless @registry[:model]
55
- @logger.debug "Successfully loaded #{osm_path}"
56
- end
57
- if @registry[:model_idf].nil?
58
- idf_path = File.absolute_path(File.join(@registry[:run_dir], 'in.idf'))
59
- @logger.debug "Attempting to load #{idf_path}"
60
- @registry.register(:model_idf) { load_idf(idf_path, @logger) }
61
- raise "Unable to load #{idf_path}" unless @registry[:model_idf]
62
- @logger.debug "Successfully loaded #{idf_path}"
63
- end
64
- if @registry[:sql].nil?
65
- sql_path = File.absolute_path(File.join(@registry[:run_dir], 'eplusout.sql'))
66
- if File.exists?(sql_path)
67
- @registry.register(:sql) { sql_path }
68
- @logger.debug "Registered the sql filepath as #{@registry[:sql]}"
69
- end
70
- #raise "Unable to load #{sql_path}" unless @registry[:sql]
71
- end
72
- if @registry[:wf].nil?
73
- epw_path = File.absolute_path(File.join(@registry[:run_dir], 'in.epw'))
74
- if File.exists?(epw_path)
75
- @registry.register(:wf) { epw_path }
76
- @logger.debug "Registered the wf filepath as #{@registry[:wf]}"
77
- end
78
- #raise "Unable to load #{epw_path}" unless @registry[:wf]
79
- end
80
- end
81
-
82
- # Apply reporting measures
83
- @options[:output_adapter] = @output_adapter
84
- @logger.info 'Beginning to execute Reporting measures.'
85
- apply_measures('ReportingMeasure'.to_MeasureType, @registry, @options)
86
- @logger.info('Finished applying Reporting measures.')
87
-
88
- # Send the updated measure_attributes to the output adapter
89
- @logger.debug 'Communicating measures output attributes to the output adapter'
90
- @output_adapter.communicate_measure_attributes @registry[:output_attributes]
91
-
92
- # Parse the files generated by the local output adapter
93
- results, objective_functions = run_extract_inputs_and_outputs @registry[:run_dir], @logger
94
- @registry.register(:results) { results }
95
-
96
- # Send the objective function results to the output adapter
97
- @logger.debug "Objective Function JSON is #{objective_functions}"
98
- @output_adapter.communicate_objective_function objective_functions
99
-
100
- nil
101
- end
102
- end
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
+ # Run reporting measures and execute scripts to post-process objective functions and results on the filesystem
37
+ class RunReportingMeasures < OpenStudio::Workflow::Job
38
+ require 'csv'
39
+ require 'ostruct'
40
+ require 'openstudio/workflow/util'
41
+ include OpenStudio::Workflow::Util::Model
42
+ include OpenStudio::Workflow::Util::Measure
43
+ include OpenStudio::Workflow::Util::PostProcess
44
+
45
+ def initialize(input_adapter, output_adapter, registry, options = {})
46
+ defaults = {
47
+ load_simulation_osm: false,
48
+ load_simulation_idf: false,
49
+ load_simulation_sql: false
50
+ }
51
+ options = defaults.merge(options)
52
+ super
53
+ end
54
+
55
+ def perform
56
+ @logger.debug "Calling #{__method__} in the #{self.class} class"
57
+ @logger.debug 'RunPostProcess Retrieving datapoint and problem'
58
+
59
+ # halted workflow is handled in apply_measures
60
+
61
+ # Ensure output_attributes is initialized in the registry
62
+ @registry.register(:output_attributes) { {} } unless @registry[:output_attributes]
63
+
64
+ # Load simulation files as required
65
+ unless @registry[:runner].halted
66
+ if @registry[:model].nil?
67
+ osm_path = File.absolute_path(File.join(@registry[:run_dir], 'in.osm'))
68
+ @logger.debug "Attempting to load #{osm_path}"
69
+ @registry.register(:model) { load_osm('.', osm_path) }
70
+ raise "Unable to load #{osm_path}" unless @registry[:model]
71
+ @logger.debug "Successfully loaded #{osm_path}"
72
+ end
73
+ if @registry[:model_idf].nil?
74
+ idf_path = File.absolute_path(File.join(@registry[:run_dir], 'in.idf'))
75
+ @logger.debug "Attempting to load #{idf_path}"
76
+ @registry.register(:model_idf) { load_idf(idf_path, @logger) }
77
+ raise "Unable to load #{idf_path}" unless @registry[:model_idf]
78
+ @logger.debug "Successfully loaded #{idf_path}"
79
+ end
80
+ if @registry[:sql].nil?
81
+ sql_path = File.absolute_path(File.join(@registry[:run_dir], 'eplusout.sql'))
82
+ if File.exists?(sql_path)
83
+ @registry.register(:sql) { sql_path }
84
+ @logger.debug "Registered the sql filepath as #{@registry[:sql]}"
85
+ end
86
+ #raise "Unable to load #{sql_path}" unless @registry[:sql]
87
+ end
88
+ if @registry[:wf].nil?
89
+ epw_path = File.absolute_path(File.join(@registry[:run_dir], 'in.epw'))
90
+ if File.exists?(epw_path)
91
+ @registry.register(:wf) { epw_path }
92
+ @logger.debug "Registered the wf filepath as #{@registry[:wf]}"
93
+ end
94
+ #raise "Unable to load #{epw_path}" unless @registry[:wf]
95
+ end
96
+ end
97
+
98
+ # Apply reporting measures
99
+ @options[:output_adapter] = @output_adapter
100
+ @logger.info 'Beginning to execute Reporting measures.'
101
+ apply_measures('ReportingMeasure'.to_MeasureType, @registry, @options)
102
+ @logger.info('Finished applying Reporting measures.')
103
+
104
+ # Send the updated measure_attributes to the output adapter
105
+ @logger.debug 'Communicating measures output attributes to the output adapter'
106
+ @output_adapter.communicate_measure_attributes @registry[:output_attributes]
107
+
108
+ # Parse the files generated by the local output adapter
109
+ results, objective_functions = run_extract_inputs_and_outputs @registry[:run_dir], @logger
110
+ @registry.register(:results) { results }
111
+
112
+ # Send the objective function results to the output adapter
113
+ @logger.debug "Objective Function JSON is #{objective_functions}"
114
+ @output_adapter.communicate_objective_function objective_functions
115
+
116
+ nil
117
+ end
118
+ end
@@ -1,68 +1,84 @@
1
- ######################################################################
2
- # Copyright (c) 2008-2014, Alliance for Sustainable Energy.
3
- # All rights reserved.
4
- #
5
- # This library is free software; you can redistribute it and/or
6
- # modify it under the terms of the GNU Lesser General Public
7
- # License as published by the Free Software Foundation; either
8
- # version 2.1 of the License, or (at your option) any later version.
9
- #
10
- # This library is distributed in the hope that it will be useful,
11
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
- # Lesser General Public License for more details.
14
- #
15
- # You should have received a copy of the GNU Lesser General Public
16
- # License along with this library; if not, write to the Free Software
17
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
- ######################################################################
19
-
20
- # Run the initialization job to validate the directory and initialize the adapters.
21
- class RunTranslation < OpenStudio::Workflow::Job
22
- require 'openstudio/workflow/util/model'
23
- include OpenStudio::Workflow::Util::Model
24
-
25
- def initialize(input_adapter, output_adapter, registry, options = {})
26
- super
27
- end
28
-
29
- def perform
30
- @logger.debug "Calling #{__method__} in the #{self.class} class"
31
-
32
- # skip if halted
33
- if @registry[:runner].halted
34
- @logger.info 'Workflow halted, skipping OSM to IDF translation'
35
- @registry.register(:model_idf) { OpenStudio::Workspace.new } # This allows model arguments to still be calculated
36
- return nil
37
- end
38
-
39
- # Ensure that the run directory is created
40
- FileUtils.mkdir_p(@registry[:run_dir])
41
-
42
- # Copy in the weather file defined in the registry, or alternately in the options
43
- if @registry[:wf]
44
- @logger.info "Weather file for EnergyPlus simulation is #{@registry[:wf]}"
45
- FileUtils.copy(@registry[:wf], "#{@registry[:run_dir]}/in.epw")
46
- @registry.register(:wf) { "#{@registry[:run_dir]}/in.epw" }
47
- else
48
- @logger.warn "EPW file not found or not sent to #{self.class}"
49
- end
50
-
51
- # Translate the OSM to an IDF
52
- @logger.info 'Beginning the translation to IDF'
53
- @registry[:time_logger].start('Translating to EnergyPlus') if @registry[:time_logger]
54
- model_idf = translate_to_energyplus @registry[:model], @logger
55
- @registry[:time_logger].stop('Translating to EnergyPlus') if @registry[:time_logger]
56
- @registry.register(:model_idf) { model_idf }
57
- @logger.info 'Successfully translated to IDF'
58
-
59
- # Save the generated IDF file if the :debug option is true
60
- return nil unless @options[:debug]
61
- @registry[:time_logger].start('Saving IDF') if @registry[:time_logger]
62
- idf_name = save_idf(@registry[:model_idf], @registry[:root_dir])
63
- @registry[:time_logger].stop('Saving IDF') if @registry[:time_logger]
64
- @logger.debug "Saved IDF as #{idf_name}"
65
-
66
- nil
67
- end
68
- end
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
+ # Run the initialization job to validate the directory and initialize the adapters.
37
+ class RunTranslation < OpenStudio::Workflow::Job
38
+ require 'openstudio/workflow/util/model'
39
+ include OpenStudio::Workflow::Util::Model
40
+
41
+ def initialize(input_adapter, output_adapter, registry, options = {})
42
+ super
43
+ end
44
+
45
+ def perform
46
+ @logger.debug "Calling #{__method__} in the #{self.class} class"
47
+
48
+ # skip if halted
49
+ if @registry[:runner].halted
50
+ @logger.info 'Workflow halted, skipping OSM to IDF translation'
51
+ @registry.register(:model_idf) { OpenStudio::Workspace.new } # This allows model arguments to still be calculated
52
+ return nil
53
+ end
54
+
55
+ # Ensure that the run directory is created
56
+ FileUtils.mkdir_p(@registry[:run_dir])
57
+
58
+ # Copy in the weather file defined in the registry, or alternately in the options
59
+ if @registry[:wf]
60
+ @logger.info "Weather file for EnergyPlus simulation is #{@registry[:wf]}"
61
+ FileUtils.copy(@registry[:wf], "#{@registry[:run_dir]}/in.epw")
62
+ @registry.register(:wf) { "#{@registry[:run_dir]}/in.epw" }
63
+ else
64
+ @logger.warn "EPW file not found or not sent to #{self.class}"
65
+ end
66
+
67
+ # Translate the OSM to an IDF
68
+ @logger.info 'Beginning the translation to IDF'
69
+ @registry[:time_logger].start('Translating to EnergyPlus') if @registry[:time_logger]
70
+ model_idf = translate_to_energyplus @registry[:model], @logger
71
+ @registry[:time_logger].stop('Translating to EnergyPlus') if @registry[:time_logger]
72
+ @registry.register(:model_idf) { model_idf }
73
+ @logger.info 'Successfully translated to IDF'
74
+
75
+ # Save the generated IDF file if the :debug option is true
76
+ return nil unless @options[:debug]
77
+ @registry[:time_logger].start('Saving IDF') if @registry[:time_logger]
78
+ idf_name = save_idf(@registry[:model_idf], @registry[:root_dir])
79
+ @registry[:time_logger].stop('Saving IDF') if @registry[:time_logger]
80
+ @logger.debug "Saved IDF as #{idf_name}"
81
+
82
+ nil
83
+ end
84
+ end
@@ -1,46 +1,62 @@
1
- ######################################################################
2
- # Copyright (c) 2008-2014, Alliance for Sustainable Energy.
3
- # All rights reserved.
4
- #
5
- # This library is free software; you can redistribute it and/or
6
- # modify it under the terms of the GNU Lesser General Public
7
- # License as published by the Free Software Foundation; either
8
- # version 2.1 of the License, or (at your option) any later version.
9
- #
10
- # This library is distributed in the hope that it will be useful,
11
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
- # Lesser General Public License for more details.
14
- #
15
- # You should have received a copy of the GNU Lesser General Public
16
- # License along with this library; if not, write to the Free Software
17
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
- ######################################################################
19
-
20
- require 'logger'
21
-
22
- class Logger
23
- def format_message(severity, datetime, _progname, msg)
24
- "[%s %s] %s\n" % [datetime.strftime('%H:%M:%S.%6N'), severity, msg]
25
- end
26
- end
27
-
28
- # Class to allow multiple logging paths
29
- class MultiDelegator
30
- def initialize(*targets)
31
- @targets = targets
32
- end
33
-
34
- def self.delegate(*methods)
35
- methods.each do |m|
36
- define_method(m) do |*args|
37
- @targets.map { |t| t.send(m, *args) }
38
- end
39
- end
40
- self
41
- end
42
-
43
- class <<self
44
- alias to new
45
- end
46
- end
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
+ require 'logger'
37
+
38
+ class Logger
39
+ def format_message(severity, datetime, _progname, msg)
40
+ "[%s %s] %s\n" % [datetime.strftime('%H:%M:%S.%6N'), severity, msg]
41
+ end
42
+ end
43
+
44
+ # Class to allow multiple logging paths
45
+ class MultiDelegator
46
+ def initialize(*targets)
47
+ @targets = targets
48
+ end
49
+
50
+ def self.delegate(*methods)
51
+ methods.each do |m|
52
+ define_method(m) do |*args|
53
+ @targets.map { |t| t.send(m, *args) }
54
+ end
55
+ end
56
+ self
57
+ end
58
+
59
+ class <<self
60
+ alias to new
61
+ end
62
+ end