openhab-scripting 2.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/workflow.yml +327 -0
  3. data/.gitignore +17 -0
  4. data/.java-version +1 -0
  5. data/.rspec +1 -0
  6. data/.yardopts +1 -0
  7. data/CHANGELOG.md +113 -0
  8. data/Gemfile +28 -0
  9. data/Gemfile.lock +245 -0
  10. data/Guardfile +35 -0
  11. data/LICENSE +277 -0
  12. data/README.md +23 -0
  13. data/Rakefile +406 -0
  14. data/bin/console +15 -0
  15. data/bin/setup +8 -0
  16. data/config/userdata/config/org/openhab/restauth.config +3 -0
  17. data/cucumber.yml +1 -0
  18. data/docs/_config.yml +135 -0
  19. data/docs/contributing/index.md +47 -0
  20. data/docs/examples/conversions.md +123 -0
  21. data/docs/examples/index.md +61 -0
  22. data/docs/index.md +19 -0
  23. data/docs/installation/index.md +26 -0
  24. data/docs/motivation/index.md +27 -0
  25. data/docs/usage/execution.md +9 -0
  26. data/docs/usage/execution/delay.md +48 -0
  27. data/docs/usage/execution/otherwise.md +30 -0
  28. data/docs/usage/execution/run.md +70 -0
  29. data/docs/usage/execution/triggered.md +48 -0
  30. data/docs/usage/guards.md +51 -0
  31. data/docs/usage/guards/between.md +30 -0
  32. data/docs/usage/guards/not_if.md +41 -0
  33. data/docs/usage/guards/only_if.md +40 -0
  34. data/docs/usage/index.md +11 -0
  35. data/docs/usage/items.md +66 -0
  36. data/docs/usage/items/contact.md +84 -0
  37. data/docs/usage/items/dimmer.md +147 -0
  38. data/docs/usage/items/groups.md +76 -0
  39. data/docs/usage/items/number.md +225 -0
  40. data/docs/usage/items/string.md +49 -0
  41. data/docs/usage/items/switch.md +85 -0
  42. data/docs/usage/misc.md +7 -0
  43. data/docs/usage/misc/actions.md +108 -0
  44. data/docs/usage/misc/duration.md +21 -0
  45. data/docs/usage/misc/gems.md +25 -0
  46. data/docs/usage/misc/logging.md +21 -0
  47. data/docs/usage/misc/metadata.md +128 -0
  48. data/docs/usage/misc/store_states.md +42 -0
  49. data/docs/usage/misc/time_of_day.md +69 -0
  50. data/docs/usage/misc/timers.md +67 -0
  51. data/docs/usage/rule.md +43 -0
  52. data/docs/usage/things.md +29 -0
  53. data/docs/usage/triggers.md +8 -0
  54. data/docs/usage/triggers/changed.md +57 -0
  55. data/docs/usage/triggers/channel.md +54 -0
  56. data/docs/usage/triggers/command.md +69 -0
  57. data/docs/usage/triggers/cron.md +19 -0
  58. data/docs/usage/triggers/every.md +76 -0
  59. data/docs/usage/triggers/updated.md +78 -0
  60. data/lib/openhab.rb +39 -0
  61. data/lib/openhab/configuration.rb +16 -0
  62. data/lib/openhab/core/cron.rb +27 -0
  63. data/lib/openhab/core/debug.rb +34 -0
  64. data/lib/openhab/core/dsl.rb +47 -0
  65. data/lib/openhab/core/dsl/actions.rb +107 -0
  66. data/lib/openhab/core/dsl/entities.rb +103 -0
  67. data/lib/openhab/core/dsl/gems.rb +29 -0
  68. data/lib/openhab/core/dsl/group.rb +91 -0
  69. data/lib/openhab/core/dsl/items/items.rb +39 -0
  70. data/lib/openhab/core/dsl/items/number_item.rb +217 -0
  71. data/lib/openhab/core/dsl/items/string_item.rb +102 -0
  72. data/lib/openhab/core/dsl/monkey_patch/actions/actions.rb +4 -0
  73. data/lib/openhab/core/dsl/monkey_patch/actions/script_thing_actions.rb +22 -0
  74. data/lib/openhab/core/dsl/monkey_patch/events.rb +5 -0
  75. data/lib/openhab/core/dsl/monkey_patch/events/item_command.rb +13 -0
  76. data/lib/openhab/core/dsl/monkey_patch/events/item_state_changed.rb +25 -0
  77. data/lib/openhab/core/dsl/monkey_patch/events/thing_status_info.rb +26 -0
  78. data/lib/openhab/core/dsl/monkey_patch/items/contact_item.rb +54 -0
  79. data/lib/openhab/core/dsl/monkey_patch/items/dimmer_item.rb +125 -0
  80. data/lib/openhab/core/dsl/monkey_patch/items/group_item.rb +27 -0
  81. data/lib/openhab/core/dsl/monkey_patch/items/items.rb +130 -0
  82. data/lib/openhab/core/dsl/monkey_patch/items/metadata.rb +259 -0
  83. data/lib/openhab/core/dsl/monkey_patch/items/switch_item.rb +86 -0
  84. data/lib/openhab/core/dsl/monkey_patch/ruby/number.rb +69 -0
  85. data/lib/openhab/core/dsl/monkey_patch/ruby/range.rb +46 -0
  86. data/lib/openhab/core/dsl/monkey_patch/ruby/ruby.rb +5 -0
  87. data/lib/openhab/core/dsl/monkey_patch/types/decimal_type.rb +24 -0
  88. data/lib/openhab/core/dsl/monkey_patch/types/on_off_type.rb +41 -0
  89. data/lib/openhab/core/dsl/monkey_patch/types/open_closed_type.rb +25 -0
  90. data/lib/openhab/core/dsl/monkey_patch/types/percent_type.rb +23 -0
  91. data/lib/openhab/core/dsl/monkey_patch/types/types.rb +7 -0
  92. data/lib/openhab/core/dsl/property.rb +85 -0
  93. data/lib/openhab/core/dsl/rule/channel.rb +41 -0
  94. data/lib/openhab/core/dsl/rule/cron.rb +115 -0
  95. data/lib/openhab/core/dsl/rule/guard.rb +99 -0
  96. data/lib/openhab/core/dsl/rule/item.rb +207 -0
  97. data/lib/openhab/core/dsl/rule/rule.rb +374 -0
  98. data/lib/openhab/core/dsl/rule/triggers.rb +77 -0
  99. data/lib/openhab/core/dsl/states.rb +63 -0
  100. data/lib/openhab/core/dsl/things.rb +93 -0
  101. data/lib/openhab/core/dsl/time_of_day.rb +203 -0
  102. data/lib/openhab/core/dsl/timers.rb +85 -0
  103. data/lib/openhab/core/dsl/types/quantity.rb +255 -0
  104. data/lib/openhab/core/dsl/units.rb +41 -0
  105. data/lib/openhab/core/duration.rb +69 -0
  106. data/lib/openhab/core/log.rb +175 -0
  107. data/lib/openhab/core/patch_load_path.rb +7 -0
  108. data/lib/openhab/core/startup_delay.rb +22 -0
  109. data/lib/openhab/osgi.rb +52 -0
  110. data/lib/openhab/version.rb +9 -0
  111. data/openhab-scripting.gemspec +30 -0
  112. data/openhab_rules/warmup.rb +5 -0
  113. metadata +157 -0
@@ -0,0 +1,255 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'java'
4
+ require 'forwardable'
5
+
6
+ module OpenHAB
7
+ module Core
8
+ module DSL
9
+ #
10
+ # Ruby implementation of OpenHAB Types
11
+ #
12
+ module Types
13
+ #
14
+ # Ruby implementation for OpenHAB quantities
15
+ #
16
+ class Quantity < Numeric
17
+ extend Forwardable
18
+ include Logging
19
+
20
+ def_delegator :@quantity, :to_s
21
+
22
+ java_import org.openhab.core.library.types.QuantityType
23
+ java_import 'tec.uom.se.format.SimpleUnitFormat'
24
+ java_import 'tec.uom.se.AbstractUnit'
25
+
26
+ OPERATIONS = {
27
+ '+' => 'add',
28
+ '-' => 'subtract',
29
+ '*' => 'multiply',
30
+ '/' => 'divide'
31
+ }.freeze
32
+
33
+ private_constant :OPERATIONS
34
+
35
+ attr_reader :quantity
36
+
37
+ #
38
+ # Create a new Quantity
39
+ #
40
+ # @param [Java::org::openhab::core::library::types::QuantityType] quantity OpenHAB quantity to delegate to
41
+ #
42
+ def initialize(quantity)
43
+ @quantity = case quantity
44
+ when String
45
+ QuantityType.new(quantity)
46
+ when QuantityType
47
+ quantity
48
+ when Numeric
49
+ QuantityType.new(BigDecimal(quantity).to_java, AbstractUnit::ONE)
50
+ else
51
+ raise "Unexpected type #{quantity.class} provided to Quantity initializer"
52
+ end
53
+ super()
54
+ end
55
+
56
+ #
57
+ # Convert this quantity into a another unit
58
+ #
59
+ # @param [Object] other String or Unit to convert to
60
+ #
61
+ # @return [Quantity] This quantity converted to another unit
62
+ #
63
+ def |(other)
64
+ other = SimpleUnitFormat.instance.unitFor(other) if other.is_a? String
65
+
66
+ Quantity.new(quantity.to_unit(other))
67
+ end
68
+
69
+ #
70
+ # Compare this quantity
71
+ #
72
+ # @param [Object] other object to compare to
73
+ #
74
+ # @return [Integer] -1,0,1 if this object is less than, equal to, or greater than the supplied object,
75
+ # nil if it cannot be compared
76
+ #
77
+ def <=>(other)
78
+ logger.trace("Comparing #{self} to #{other}")
79
+ case other
80
+ when Quantity
81
+ logger.trace("Comparing Quantity #{self} to Quantity #{other}")
82
+ convert_unit(quantity).compare_to(convert_unit(other.quantity))
83
+ when QuantityType
84
+ other = convert_unit(other)
85
+ quantity.compare_to(other)
86
+ when String
87
+ other = QuantityType.new(other)
88
+ other = convert_unit(other)
89
+ quantity.compare_to(other)
90
+ when Numeric
91
+ quantity.compare_to(QuantityType.new(other, unit)) if unit
92
+ end
93
+ end
94
+
95
+ #
96
+ # Coerce other object into a Quantity
97
+ #
98
+ # @param [Object] other object to convert to Quantity
99
+ #
100
+ # @return [Array] of self and other object as Quantity types, nil if object cannot be coerced
101
+ #
102
+ def coerce(other)
103
+ logger.trace("Coercing #{self} as a request from #{other.class}")
104
+ case other
105
+ when Quantity
106
+ [other.quantity, quantity]
107
+ when QuantityType
108
+ [other, quantity]
109
+ when Numeric
110
+ [Quantity.new(other), self]
111
+ end
112
+ end
113
+
114
+ #
115
+ # Forward missing methods to Openhab Quantity Item if they are defined
116
+ #
117
+ # @param [String] meth name of method invoked
118
+ # @param [Array] args arguments to invoked method
119
+ # @param [Proc] block block passed ot method
120
+ #
121
+ # @return [Object] result of delegation
122
+ #
123
+ def method_missing(meth, *args, &block)
124
+ if quantity.respond_to?(meth)
125
+ quantity.__send__(meth, *args, &block)
126
+ elsif ::Kernel.method_defined?(meth) || ::Kernel.private_method_defined?(meth)
127
+ ::Kernel.instance_method(meth).bind_call(self, *args, &block)
128
+ else
129
+ super(meth, *args, &block)
130
+ end
131
+ end
132
+
133
+ #
134
+ # Negate the quantity
135
+ #
136
+ # @return [Quantity] This quantity negated
137
+ #
138
+ def -@
139
+ Quantity.new(quantity.negate)
140
+ end
141
+
142
+ OPERATIONS.each do |operation, method|
143
+ define_method(operation) do |other|
144
+ logger.trace("Executing math operation '#{operation}' on quantity #{inspect} with other type #{other.class} and value #{other.inspect}")
145
+ a, b = case other
146
+ when Quantity
147
+ [quantity, other.quantity]
148
+ when String
149
+ [quantity, QuantityType.new(other)]
150
+ when NumberItem
151
+ a, b = other.coerce(self)
152
+ logger.trace("Number Item coerced result a(#{a.class})='#{a}' b(#{b.class})='#{b}'")
153
+ [a.quantity, b.quantity]
154
+ when Numeric
155
+ [quantity, QuantityType.new(BigDecimal(other).to_java, AbstractUnit::ONE)]
156
+ else
157
+ raise TypeError,
158
+ "Operation '#{operation}' cannot be performed between #{self} and #{other.class}"
159
+ end
160
+ logger.trace("Coerced a='#{a}' with b='#{b}'")
161
+ a, b = unitize(a, b, operation)
162
+ logger.trace("Unitized a='#{a}' b='#{b}'")
163
+ logger.trace("Performing operation '#{operation}' with method '#{method}' on a='#{a}' with b='#{b}'")
164
+ Quantity.new(a.public_send(method, b))
165
+ end
166
+ end
167
+
168
+ #
169
+ # Provide details about quantity object
170
+ #
171
+ # @return [String] Representing details about the quantity object
172
+ #
173
+ def inspect
174
+ if @quantity.unit == AbstractUnit::ONE
175
+ "unit=#{@quantity.unit}, value=#{@quantity.to_string}"
176
+ else
177
+ @quantity.to_string
178
+ end
179
+ end
180
+
181
+ private
182
+
183
+ DIMENSIONLESS_NON_UNITIZED_OPERATIONS = %w[* /].freeze
184
+
185
+ # Dimensionless numbers should only be unitzed for addition and subtraction
186
+
187
+ #
188
+ # Checks if an item should be unitized
189
+ #
190
+ # @param [Quantity] quantity to check
191
+ # @param [String] operation quantity is being used with
192
+ #
193
+ # @return [Boolean] True if the quantity should be unitzed based on the unit and operation, false otherwise
194
+ #
195
+ def unitize?(quantity, operation)
196
+ if quantity.unit == AbstractUnit::ONE && DIMENSIONLESS_NON_UNITIZED_OPERATIONS.include?(operation)
197
+ false
198
+ else
199
+ true
200
+ end
201
+ end
202
+
203
+ #
204
+ # Convert the unit for the quantity
205
+ #
206
+ # @param [Quantity] quantity being converted
207
+ #
208
+ # @return [Quantity] Quantity coverted to unit set by unit block
209
+ #
210
+ def convert_unit(quantity)
211
+ if unit
212
+ case quantity.unit
213
+ when AbstractUnit::ONE
214
+ logger.trace("Converting dimensionless #{quantity} to #{unit}")
215
+ QuantityType.new(quantity.to_big_decimal, unit)
216
+ when unit
217
+ quantity
218
+ else
219
+ logger.trace("Converting dimensioned item #{inspect} to #{unit}")
220
+ converted = quantity.to_unit(unit)
221
+ raise "Conversion from #{quantity.unit} to #{unit} failed" if converted.nil?
222
+
223
+ converted
224
+ end
225
+ else
226
+ quantity
227
+ end
228
+ end
229
+
230
+ #
231
+ # Convert quantities to appropriate units
232
+ #
233
+ # @param [Quantity] quantity_a Quantity on left side of operation
234
+ # @param [Quantity] quantity_b Quantity on right side of operation
235
+ # @param [String] operation Math operation
236
+ #
237
+ # @return [Array] of quantites in correct units for the supplied operation and set unit
238
+ #
239
+ def unitize(quantity_a, quantity_b, operation)
240
+ [quantity_a, quantity_b].map { |qt| unitize?(qt, operation) ? convert_unit(qt) : qt }
241
+ end
242
+
243
+ #
244
+ # Get the unit from the current thread local variable
245
+ #
246
+ # @return [Object] Unit or string representation of Unit, or nil if not set
247
+ #
248
+ def unit
249
+ Thread.current.thread_variable_get(:unit)
250
+ end
251
+ end
252
+ end
253
+ end
254
+ end
255
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'java'
4
+
5
+ # Import Imperial and SI Units overriding provided values
6
+ %i[ImperialUnits SIUnits].each do |type|
7
+ Object.send(:remove_const, type)
8
+ java_import "org.openhab.core.library.unit.#{type}"
9
+ end
10
+
11
+ Object.send(:remove_const, :QuantityType)
12
+ java_import org.openhab.core.library.types.QuantityType
13
+
14
+ module OpenHAB
15
+ module Core
16
+ module DSL
17
+ #
18
+ # Provides support for interacting with OpenHAB Units of Measurement
19
+ #
20
+ module Units
21
+ java_import 'tec.uom.se.format.SimpleUnitFormat'
22
+
23
+ #
24
+ # Sets a thread local variable to the supplied unit such that classes operating inside the block
25
+ # can perform automatic conversions to the supplied unit for NumberItems
26
+ #
27
+ # @param [Object] unit OpenHAB Unit or String representing unit
28
+ # @yield [] Block executed in context of the supplied unit
29
+ #
30
+ #
31
+ def unit(unit)
32
+ unit = SimpleUnitFormat.instance.unitFor(unit) if unit.is_a? String
33
+ Thread.current.thread_variable_set(:unit, unit)
34
+ yield
35
+ ensure
36
+ Thread.current.thread_variable_set(:unit, nil)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'openhab/core/cron'
4
+
5
+ module OpenHAB
6
+ module Core
7
+ #
8
+ # This class represents a duration of time
9
+ #
10
+ class Duration
11
+ include OpenHAB::Core::Cron
12
+
13
+ # @return [Array] of supported temperal units (milliseconds, seconds, minutes and hours)
14
+ TEMPORAL_UNITS = %i[MILLISECONDS SECONDS MINUTES HOURS].freeze
15
+
16
+ #
17
+ # Create a new Duration object
18
+ #
19
+ # @param [Symbol] temporal_unit Unit for duration
20
+ # @param [Integer] amount of that unit
21
+ #
22
+ def initialize(temporal_unit:, amount:)
23
+ unless TEMPORAL_UNITS.include? temporal_unit
24
+ raise ArgumentError,
25
+ "Unexpected Temporal Unit: #{temporal_unit}"
26
+ end
27
+
28
+ @temporal_unit = temporal_unit
29
+ @amount = amount
30
+ end
31
+
32
+ #
33
+ # Return a map
34
+ #
35
+ # @return [Map] Map with fields representing this duration @see OpenHAB::Core::Cron
36
+ #
37
+ def cron_map
38
+ case @temporal_unit
39
+ when :SECONDS
40
+ cron_expression_map.merge(second: "*/#{@amount}")
41
+ when :MINUTES
42
+ cron_expression_map.merge(minute: "*/#{@amount}")
43
+ when :HOURS
44
+ cron_expression_map.merge(hour: "*/#{@amount}")
45
+ else
46
+ raise ArgumentError, "Cron Expression not supported for temporal unit: #{temporal_unit}"
47
+ end
48
+ end
49
+
50
+ #
51
+ # Convert the duration to milliseconds
52
+ #
53
+ # @return [Integer] Duration in milliseconds
54
+ #
55
+ def to_ms
56
+ case @temporal_unit
57
+ when :MILLISECONDS
58
+ @amount
59
+ when :SECONDS
60
+ @amount * 1000
61
+ when :MINUTES
62
+ @amount * 1000 * 60
63
+ when :HOURS
64
+ @amount * 1000 * 60 * 60
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,175 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'openhab/configuration'
4
+ require 'java'
5
+ require 'pp'
6
+
7
+ #
8
+ # Provides access to the OpenHAB logging using a Ruby logging methods
9
+ #
10
+ module Logging
11
+ #
12
+ # Ruby Logger that forwards messages at appropriate levels to OpenHAB Logger
13
+ #
14
+ class Logger
15
+ java_import org.slf4j.LoggerFactory
16
+
17
+ # @return [Array] Supported logging levels
18
+ LEVELS = %i[TRACE DEBUG WARN INFO ERROR].freeze
19
+
20
+ #
21
+ # Create a new logger
22
+ #
23
+ # @param [String] name of the logger
24
+ #
25
+ def initialize(name)
26
+ @sl4fj_logger = LoggerFactory.getLogger(name)
27
+ end
28
+
29
+ # Dynamically define the methods for each level as identified by the levels constant
30
+ # This creates a method for each level that looks like this
31
+ # def <level>(msg=nil, &block)
32
+ # log(severity: <level>, msg: msg, &block)
33
+ # end
34
+ LEVELS.each do |level|
35
+ method = level.to_s.downcase
36
+ define_method(method.to_s) do |msg = nil, &block|
37
+ log(severity: level, msg: msg, &block)
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ #
44
+ # Log a message to the OpenHAB Logger
45
+ #
46
+ # @param [Symbol] severity Severity to log message at
47
+ # @param [Object] msg to log, if no msg supplied and a block is provided, the msg is taken from the result of the block
48
+ #
49
+ def log(severity:, msg: nil)
50
+ severity = severity.to_sym
51
+
52
+ raise ArgumentError, "Unknown Severity #{severity}" unless LEVELS.include? severity
53
+
54
+ # Dynamically check enablement of underlying logger, this expands to "is_<level>_enabled"
55
+ return unless @sl4fj_logger.send("is_#{severity.to_s.downcase}_enabled")
56
+
57
+ # Process block if no message provided
58
+ if msg.nil?
59
+ if block_given?
60
+ msg = yield
61
+ else
62
+ return
63
+ end
64
+ end
65
+
66
+ msg = message_to_string(msg: msg)
67
+
68
+ # Dynamically invoke underlying logger, this expands to "<level>(message)"
69
+ @sl4fj_logger.send(severity.to_s.downcase, msg)
70
+ end
71
+
72
+ #
73
+ # Conver the supplied message object to a String
74
+ #
75
+ # @param [object] msg object to convert
76
+ #
77
+ # @return [String] Msg object as a string
78
+ #
79
+ def message_to_string(msg:)
80
+ case msg
81
+ when ::String
82
+ msg
83
+ when ::Exception
84
+ "#{msg.message} (#{msg.class})\n#{msg.backtrace&.join("\n")}"
85
+ else
86
+ msg.inspect
87
+ end
88
+ end
89
+ end
90
+
91
+ @loggers = {}
92
+
93
+ # Return a logger with the configured log prefix plus the calling scripts name
94
+
95
+ #
96
+ # Create a logger for the current class
97
+ #
98
+ # @return [Logger] for the current class
99
+ #
100
+ def logger
101
+ Logging.logger(self.class.name)
102
+ end
103
+
104
+ class << self
105
+ #
106
+ # Injects a logger into the base class
107
+ #
108
+ # @param [String] name of the logger
109
+ #
110
+ # @return [Logger] for the supplied name
111
+ #
112
+ def logger(name)
113
+ name ||= self.class.name
114
+ @loggers[name] ||= Logging.logger_for(name)
115
+ end
116
+
117
+ #
118
+ # Configure a logger for the supplied class name
119
+ #
120
+ # @param [String] classname to configure logger for
121
+ #
122
+ # @return [Logger] for the supplied classname
123
+ #
124
+ def logger_for(classname)
125
+ configure_logger_for(classname)
126
+ end
127
+
128
+ private
129
+
130
+ #
131
+ # Configure a logger for the supplied classname
132
+ #
133
+ # @param [String] classname to create logger for
134
+ #
135
+ # @return [Logger] Logger for the supplied classname
136
+ #
137
+ def configure_logger_for(classname)
138
+ log_prefix = Configuration.log_prefix
139
+ log_prefix += if classname
140
+ ".#{classname}"
141
+ else
142
+ ".#{log_caller}"
143
+ end
144
+ Logger.new(log_prefix)
145
+ end
146
+
147
+ #
148
+ # Figure out the log prefix
149
+ #
150
+ # @return [String] Prefix for log messages
151
+ #
152
+ def log_caller
153
+ caller_locations.map(&:path)
154
+ .grep_v(%r{openhab/core/})
155
+ .grep_v(/rubygems/)
156
+ .grep_v(%r{lib/ruby})
157
+ .first
158
+ .yield_self { |caller| File.basename(caller, '.*') }
159
+ end
160
+ end
161
+
162
+ #
163
+ # Add logger method to the object that includes this module
164
+ #
165
+ # @param [Object] base Object to add method to
166
+ #
167
+ #
168
+ def self.included(base)
169
+ class << base
170
+ def logger
171
+ Logging.logger(self.class.name)
172
+ end
173
+ end
174
+ end
175
+ end