openhab-scripting 4.5.0 → 4.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 13732b675b80ad3a92e2346e56da3e7d63b6a4845f8409c5a545d1b5006ab999
4
- data.tar.gz: a5b9d54c25a47857256805d849344cfde4602ad23408228cc595bfc574a04587
3
+ metadata.gz: c0e7aabfc4cdcd9a89787c861b639e087f903e9f499db1e24d1b67b0baea71eb
4
+ data.tar.gz: d590f67786a6499e17afc791fe18564223d13a0792d649494b197daf2c688536
5
5
  SHA512:
6
- metadata.gz: 9d8715ab0e0e84315b02a67aeb28f47ebcddb8b58ea5ea1043b53ef329f5f5017329fdae23961530cd1f0ac184e38acf8ad11fd9b1a7a41f77f486cf3d53f01c
7
- data.tar.gz: 15a9babdc9a9d7179dda57fcad46356175c25933f534cc4ed1dad9566a56bdde08677b6ef0224c2761fdeb1dd9253f4d6a50cec5a5804bd703b6c843e438a66b
6
+ metadata.gz: 91b26707cfa19145ad2d38587e476057a9ae7f8ac3c77a7a3c237f119c257ccbec79419fd77cd9b61656da8c6c18ff35be4ad14a1ea1d674ee3f28e26cc412aa
7
+ data.tar.gz: d168357490983f4ce8a5d3152394cf5c982270ae110d829096a32d9637dfc2c99a453a82783b4e5ba9300f5832632bedb88a077654623a43b8a0228bfe07cf40
@@ -4,6 +4,8 @@ require 'pp'
4
4
  require 'java'
5
5
  require 'set'
6
6
 
7
+ require 'openhab/log/logger'
8
+
7
9
  # Automation lookup and injection of OpenHab entities
8
10
 
9
11
  module OpenHAB
@@ -24,9 +26,6 @@ module OpenHAB
24
26
  # @return [Object] Item or Thing if found in registry
25
27
  #
26
28
  def method_missing(method, *args, &block)
27
- return if method.to_s == 'scriptLoaded'
28
- return if method.to_s == 'scriptUnloaded'
29
-
30
29
  logger.trace("method missing, performing OpenHab Lookup for: #{method}")
31
30
  EntityLookup.lookup_entity(method) || super
32
31
  end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'openhab/log/logger'
4
+ require 'openhab/dsl/rules/rule'
5
+ require 'openhab/dsl/timers'
6
+
7
+ # OpenHAB main module
8
+ module OpenHAB
9
+ module Core
10
+ #
11
+ # Manages script loading and unloading
12
+ #
13
+ module ScriptHandling
14
+ include OpenHAB::Log
15
+
16
+ #
17
+ # Executed when OpenHAB unloads a script file
18
+ #
19
+ # rubocop:disable Naming/MethodName
20
+ # method name dictacted by OpenHAB
21
+ def scriptUnloaded
22
+ logger.trace('Script unloaded')
23
+ OpenHAB::DSL::Rules.cleanup_rules
24
+ OpenHAB::DSL::Timers.cancel_all
25
+ end
26
+ # rubocop:enable Naming/MethodName
27
+
28
+ #
29
+ # Executed when OpenHAB loads a script file
30
+ #
31
+ # rubocop:disable Naming/MethodName
32
+ # method name dictacted by OpenHAB
33
+ def scriptLoaded(filename)
34
+ logger.trace("Script loaded: #{filename}")
35
+ end
36
+ # rubocop:enable Naming/MethodName
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ # OpenHAB main module
4
+ module OpenHAB
5
+ module Core
6
+ #
7
+ # Manages thread local varaibles for access inside of blocks
8
+ #
9
+ module ThreadLocal
10
+ #
11
+ # Execute the supplied block with the supplied values set for the currently running thread
12
+ # The previous values for each key are restored after the block is executed
13
+ #
14
+ # @param [Hash] Keys and values to set for running thread
15
+ #
16
+ def thread_local(**values)
17
+ old_values = values.map { |key, _value| [key, Thread.current[key]] }.to_h
18
+ values.each { |key, value| Thread.current[key] = value }
19
+ yield
20
+ ensure
21
+ old_values.each { |key, value| Thread.current[key] = value }
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'openhab/dsl/monkey_patch/events/item_command'
4
+ require 'openhab/dsl/types/types'
4
5
 
5
6
  require_relative 'item_registry'
6
7
 
@@ -14,6 +15,7 @@ require_relative 'color_item'
14
15
  require_relative 'contact_item'
15
16
  require_relative 'group_item'
16
17
  require_relative 'image_item'
18
+ require_relative 'location_item'
17
19
  require_relative 'number_item'
18
20
  require_relative 'player_item'
19
21
  require_relative 'rollershutter_item'
@@ -26,6 +28,8 @@ module OpenHAB
26
28
  # Contains all OpenHAB *Item classes, as well as associated support
27
29
  # modules
28
30
  module Items
31
+ include OpenHAB::Log
32
+
29
33
  class << self
30
34
  private
31
35
 
@@ -43,7 +47,7 @@ module OpenHAB
43
47
  _command_predicate, state_predicate = Types::PREDICATE_ALIASES[state.to_s]
44
48
  next if klass.instance_methods.include?(state_predicate)
45
49
 
46
- OpenHAB::Core.logger.trace("Defining #{klass}##{state_predicate} for #{state}")
50
+ logger.trace("Defining #{klass}##{state_predicate} for #{state}")
47
51
  klass.class_eval <<~RUBY, __FILE__, __LINE__ + 1
48
52
  def #{state_predicate} # def on?
49
53
  raw_state == #{state} # raw_state == ON
@@ -59,21 +63,21 @@ module OpenHAB
59
63
  command = Types::COMMAND_ALIASES[value.to_s]
60
64
  next if klass.instance_methods.include?(command)
61
65
 
62
- OpenHAB::Core.logger.trace("Defining #{klass}##{command} for #{value}")
66
+ logger.trace("Defining #{klass}##{command} for #{value}")
63
67
  klass.class_eval <<~RUBY, __FILE__, __LINE__ + 1
64
68
  def #{command} # def on
65
69
  command(#{value}) # command(ON)
66
70
  end # end
67
71
  RUBY
68
72
 
69
- OpenHAB::Core.logger.trace("Defining GroupItem::GroupMembers##{command} for #{value}")
73
+ logger.trace("Defining GroupItem::GroupMembers##{command} for #{value}")
70
74
  GroupItem::GroupMembers.class_eval <<~RUBY, __FILE__, __LINE__ + 1
71
75
  def #{command} # def on
72
76
  each(&:#{command}) # each(&:on)
73
77
  end # end
74
78
  RUBY
75
79
 
76
- OpenHAB::Core.logger.trace("Defining ItemCommandEvent##{command}? for #{value}")
80
+ logger.trace("Defining ItemCommandEvent##{command}? for #{value}")
77
81
  MonkeyPatch::Events::ItemCommandEvent.class_eval <<~RUBY, __FILE__, __LINE__ + 1
78
82
  def #{command}? # def refresh?
79
83
  command == #{value} # command == REFRESH
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+
5
+ require_relative 'comparable_item'
6
+ require 'openhab/dsl/types/point_type'
7
+
8
+ module OpenHAB
9
+ module DSL
10
+ module Items
11
+ java_import org.openhab.core.library.items.LocationItem
12
+
13
+ # Adds methods to core OpenHAB NumberItem type to make it more natural in
14
+ # Ruby
15
+ class LocationItem < GenericItem
16
+ extend Forwardable
17
+ include ComparableItem
18
+
19
+ # !@visibility private
20
+ def ==(other)
21
+ # need to check if we're referring to the same item before
22
+ # forwarding to <=> (and thus checking equality with state)
23
+ return true if equal?(other) || eql?(other)
24
+
25
+ super
26
+ end
27
+
28
+ #
29
+ # Type Coercion
30
+ #
31
+ # Coerce object to a PointType
32
+ #
33
+ # @param [Types::PointType, String] other object to coerce to a
34
+ # PointType
35
+ #
36
+ # @return [[Types::PointType, Types::PointType]]
37
+ #
38
+ def coerce(other)
39
+ logger.trace("Coercing #{self} as a request from #{other.class}")
40
+ return [other, nil] unless state?
41
+ return [other, state] if other.is_a?(Types::PointType) || other.respond_to?(:to_str)
42
+
43
+ raise TypeError, "can't convert #{other.class} into #{self.class}"
44
+ end
45
+
46
+ # OpenHAB has this method, but it _only_ accepts PointType, so remove it and delegate
47
+ remove_method :distance_from
48
+
49
+ # any method that exists on {Types::PointType} gets forwarded to +state+
50
+ delegate (Types::PointType.instance_methods - instance_methods) => :state
51
+ end
52
+ end
53
+ end
54
+ end
@@ -25,6 +25,7 @@ module OpenHAB
25
25
  extend Forwardable
26
26
 
27
27
  def_delegator :@metadata, :value
28
+ def_delegator :__getobj__, :to_h, :to_hash
28
29
 
29
30
  def initialize(metadata: nil, key: nil, value: nil, config: nil)
30
31
  @metadata = metadata || Metadata.new(key || MetadataKey.new('', ''), value&.to_s, config)
@@ -68,6 +69,7 @@ module OpenHAB
68
69
  # @return [Java::Org::openhab::core::items::Metadata] the old metadata
69
70
  #
70
71
  def config=(config)
72
+ config = config.to_hash if config.respond_to?(:to_hash)
71
73
  raise ArgumentError, 'Configuration must be a hash' unless config.is_a? Hash
72
74
 
73
75
  metadata = Metadata.new(@metadata&.uID, @metadata&.value, config)
@@ -158,7 +160,7 @@ module OpenHAB
158
160
  meta_value, configuration = update_from_value(value)
159
161
 
160
162
  key = MetadataKey.new(namespace, @item_name)
161
- metadata = Metadata.new(key, meta_value&.to_s, configuration)
163
+ metadata = Metadata.new(key, meta_value&.to_s, configuration.to_h)
162
164
  # registry.get can be omitted, but registry.update will log a warning for nonexistent metadata
163
165
  if NamespaceAccessor.registry.get(key)
164
166
  NamespaceAccessor.registry.update(metadata)
@@ -15,10 +15,11 @@ module OpenHAB
15
15
  include ComparableItem
16
16
 
17
17
  # apply meta-programming methods to including class
18
+ # @!visibility private
18
19
  def self.included(klass)
19
20
  klass.prepend ItemEquality # make sure this is first
20
21
  klass.extend Forwardable
21
- klass.delegate %i[+ - * / % | positive? negative? to_d to_f to_i to_int zero?] => :state
22
+ klass.delegate %i[+ - * / % | to_d to_f to_i to_int] => :state
22
23
  # remove the JRuby default == so that we can inherit the Ruby method
23
24
  klass.remove_method :==
24
25
  end
@@ -62,6 +63,16 @@ module OpenHAB
62
63
 
63
64
  super
64
65
  end
66
+
67
+ %i[positive? negative? zero?].each do |predicate|
68
+ class_eval <<~RUBY, __FILE__, __LINE__ + 1
69
+ def #{predicate} # def positive?
70
+ return false unless state? # return false unless state?
71
+ #
72
+ state.#{predicate} # state.positive?
73
+ end # end
74
+ RUBY
75
+ end
65
76
  end
66
77
  end
67
78
  end
@@ -91,7 +91,7 @@ module OpenHAB
91
91
 
92
92
  return super unless other.is_a?(javax.measure.Unit)
93
93
 
94
- QuantityType.new(to_d.to_java, other)
94
+ Types::QuantityType.new(to_d.to_java, other)
95
95
  end
96
96
  end
97
97
  end
@@ -1,6 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'java'
4
+ require 'set'
5
+ require 'openhab/core/thread_local'
6
+ require 'openhab/log/logger'
4
7
 
5
8
  module OpenHAB
6
9
  module DSL
@@ -16,6 +19,7 @@ module OpenHAB
16
19
  # way of breaking it up into multiple classes
17
20
  class AutomationRule < Java::OrgOpenhabCoreAutomationModuleScriptRulesupportSharedSimple::SimpleRule
18
21
  include OpenHAB::Log
22
+ include OpenHAB::Core::ThreadLocal
19
23
  include OpenHAB::DSL::TimeOfDay
20
24
  java_import java.time.ZonedDateTime
21
25
 
@@ -24,6 +28,7 @@ module OpenHAB
24
28
  #
25
29
  # @param [Config] config Rule configuration
26
30
  #
31
+ # Constructor sets a number of variables, no further decomposition necessary
27
32
  def initialize(config:)
28
33
  super()
29
34
  set_name(config.name)
@@ -59,6 +64,14 @@ module OpenHAB
59
64
  end
60
65
  end
61
66
 
67
+ #
68
+ # Cleanup any resources associated with automation rule
69
+ #
70
+ def cleanup
71
+ logger.trace "Cancelling #{@trigger_delays.length} Trigger Delays(s) for rule '#{name}'"
72
+ @trigger_delays.each_value { |trigger_delay| trigger_delay.timer&.cancel }
73
+ end
74
+
62
75
  private
63
76
 
64
77
  #
@@ -13,6 +13,12 @@ module OpenHAB
13
13
  # Creates and manages OpenHAB Rules
14
14
  #
15
15
  module Rules
16
+ @script_rules = []
17
+
18
+ class << self
19
+ attr_reader :script_rules
20
+ end
21
+
16
22
  #
17
23
  # Create a new rule
18
24
  #
@@ -39,12 +45,19 @@ module OpenHAB
39
45
  #
40
46
  def logger
41
47
  if @rule_name
42
- Log.logger(@rule_name.chomp.gsub(/\s+/, '_'))
48
+ Log.logger_for(@rule_name.chomp.gsub(/\s+/, '_'))
43
49
  else
44
50
  super
45
51
  end
46
52
  end
47
53
 
54
+ #
55
+ # Cleanup rules in this script file
56
+ #
57
+ def self.cleanup_rules
58
+ @script_rules.each(&:cleanup)
59
+ end
60
+
48
61
  private
49
62
 
50
63
  #
@@ -67,6 +80,7 @@ module OpenHAB
67
80
  return unless create_rule?(config)
68
81
 
69
82
  rule = AutomationRule.new(config: config)
83
+ Rules.script_rules << rule
70
84
  add_rule(rule)
71
85
  rule.execute if config.on_start?
72
86
  end
@@ -26,7 +26,7 @@ module OpenHAB
26
26
  class RuleConfig
27
27
  include OpenHAB::Log
28
28
  include OpenHAB::Core::EntityLookup
29
- include OpenHAB::DSL::Rules::Triggers
29
+ prepend OpenHAB::DSL::Rules::Triggers
30
30
  include OpenHAB::DSL::Rules::Guard
31
31
  include OpenHAB::DSL::Rules::Property
32
32
  extend OpenHAB::DSL
@@ -127,7 +127,7 @@ module OpenHAB
127
127
  #
128
128
  def logger
129
129
  if name
130
- Log.logger(name.chomp.gsub(/\s+/, '_'))
130
+ Log.logger_for(name.chomp.gsub(/\s+/, '_'))
131
131
  else
132
132
  super
133
133
  end
@@ -39,7 +39,7 @@ module OpenHAB
39
39
  else
40
40
  # Place in array and flatten to support multiple to elements or single or nil
41
41
  [to].flatten.each do |to_state|
42
- create_changed_trigger(item, from, to_state)
42
+ [from].flatten.each { |from_state| create_changed_trigger(item, from_state, to_state) }
43
43
  end
44
44
  end
45
45
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'openhab/log/logger'
4
4
  require 'openhab/dsl/types/date_time_type'
5
+ require 'openhab/dsl/items/items'
5
6
  require 'time'
6
7
 
7
8
  module OpenHAB
@@ -3,6 +3,7 @@
3
3
  require 'java'
4
4
  require 'delegate'
5
5
  require 'forwardable'
6
+ require 'openhab/log/logger'
6
7
 
7
8
  module OpenHAB
8
9
  module DSL
@@ -10,15 +11,23 @@ module OpenHAB
10
11
  # Provides access to and ruby wrappers around OpenHAB timers
11
12
  #
12
13
  module Timers
14
+ include OpenHAB::Log
13
15
  java_import org.openhab.core.model.script.actions.ScriptExecution
14
16
  java_import java.time.ZonedDateTime
15
17
 
18
+ # Tracks active timers
19
+ @timers = Set.new
20
+ class << self
21
+ attr_accessor :timers
22
+ end
23
+
16
24
  # Ruby wrapper for OpenHAB Timer
17
25
  # This class implements delegator to delegate methods to the OpenHAB timer
18
26
  #
19
27
  # @author Brian O'Connell
20
28
  # @since 2.0.0
21
29
  class Timer < SimpleDelegator
30
+ include OpenHAB::Log
22
31
  extend Forwardable
23
32
 
24
33
  def_delegator :@timer, :is_active, :active?
@@ -31,20 +40,19 @@ module OpenHAB
31
40
  # @param [Duration] duration Duration until timer should fire
32
41
  # @param [Block] block Block to execute when timer fires
33
42
  #
34
- def initialize(duration:)
43
+ def initialize(duration:, &block)
35
44
  @duration = duration
36
45
 
37
46
  # A semaphore is used to prevent a race condition in which calling the block from the timer thread
38
47
  # occurs before the @timer variable can be set resulting in @timer being nil
39
48
  semaphore = Mutex.new
40
49
 
41
- timer_block = proc { semaphore.synchronize { yield(self) } }
42
-
43
50
  semaphore.synchronize do
44
51
  @timer = ScriptExecution.createTimer(
45
- ZonedDateTime.now.plus(@duration), timer_block
52
+ ZonedDateTime.now.plus(@duration), timer_block(semaphore, &block)
46
53
  )
47
54
  super(@timer)
55
+ Timers.timers << self
48
56
  end
49
57
  end
50
58
 
@@ -53,12 +61,40 @@ module OpenHAB
53
61
  #
54
62
  # @param [Duration] duration
55
63
  #
56
- # @return [<Type>] <description>
64
+ # @return [Timer] Rescheduled timer instances
57
65
  #
58
66
  def reschedule(duration = nil)
59
67
  duration ||= @duration
68
+ Timers.timers << self
60
69
  @timer.reschedule(ZonedDateTime.now.plus(duration))
61
70
  end
71
+
72
+ # Cancel timer
73
+ #
74
+ # @return [Boolean] True if cancel was successful, false otherwise
75
+ #
76
+ def cancel
77
+ Timers.timers.delete(self)
78
+ @timer.cancel
79
+ end
80
+
81
+ private
82
+
83
+ #
84
+ # Constructs a block to execute timer within
85
+ #
86
+ # @param [Semaphore] Semaphore to obtain before executing
87
+ #
88
+ # @return [Proc] Block for timer to execute
89
+ #
90
+ def timer_block(semaphore)
91
+ proc {
92
+ semaphore.synchronize do
93
+ Timers.timers.delete(self)
94
+ yield(self)
95
+ end
96
+ }
97
+ end
62
98
  end
63
99
 
64
100
  #
@@ -72,6 +108,14 @@ module OpenHAB
72
108
  def after(duration, &block)
73
109
  Timer.new(duration: duration, &block)
74
110
  end
111
+
112
+ #
113
+ # Cancels all active timers
114
+ #
115
+ def self.cancel_all
116
+ logger.trace("Cancelling #{@timers.length} timers")
117
+ @timers.each(&:cancel)
118
+ end
75
119
  end
76
120
  end
77
121
  end
@@ -0,0 +1,151 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module DSL
5
+ module Types
6
+ java_import org.openhab.core.library.types.PointType
7
+
8
+ # global scope
9
+ # @!visibility private
10
+ ::PointType = PointType
11
+
12
+ # Adds methods to core OpenHAB PointType to make it more natural in Ruby
13
+ class PointType
14
+ # @!parse include PrimitiveType
15
+
16
+ # @param latitude [DecimalType, QuantityType, StringType, Numeric]
17
+ # @param longitude [DecimalType, QuantityType, StringType, Numeric]
18
+ # @param altitude [DecimalType, QuantityType, StringType, Numeric]
19
+ def initialize(*args) # rubocop:disable Metrics
20
+ if (2..3).cover?(args.length)
21
+ args = args.each_with_index.map do |value, index|
22
+ if value.is_a?(DecimalType) || value.is_a?(StringType)
23
+ value
24
+ elsif value.is_a?(QuantityType)
25
+ unit = index == 2 ? Units.unit || SIUnits::METRE : Units::DEGREE_ANGLE
26
+ DecimalType.new(value.to_unit(unit).to_big_decimal)
27
+ elsif value.respond_to?(:to_str)
28
+ StringType.new(value.to_str)
29
+ elsif value.respond_to?(:to_d)
30
+ DecimalType.new(value)
31
+ end
32
+ end
33
+ end
34
+
35
+ super(*args)
36
+ end
37
+
38
+ #
39
+ # Check equality without type conversion
40
+ #
41
+ # @return [Boolean] if the same value is represented, without type
42
+ # conversion
43
+ def eql?(other)
44
+ return false unless other.instance_of?(self.class)
45
+
46
+ equals(other.to_s).zero?
47
+ end
48
+
49
+ #
50
+ # Check equality with type conversion
51
+ #
52
+ # @param [PointType, Items::LocationItem, String]
53
+ # other object to compare to
54
+ #
55
+ # @return [Boolean]
56
+ #
57
+ def ==(other) # rubocop:disable Metrics
58
+ logger.trace("(#{self.class}) #{self} == #{other} (#{other.class})")
59
+ if other.is_a?(Items::LocationItem) ||
60
+ (other.is_a?(Items::GroupItem) && other.base_item.is_a?(LocationItem))
61
+ return false unless other.state?
62
+
63
+ self == other.state
64
+ elsif other.respond_to?(:to_str)
65
+ self == PointType.new(other)
66
+ elsif other.respond_to?(:coerce)
67
+ lhs, rhs = other.coerce(self)
68
+ lhs == rhs
69
+ end
70
+ end
71
+
72
+ #
73
+ # Type Coercion
74
+ #
75
+ # Coerce object to a PointType
76
+ #
77
+ # @param [Items::LocationItem, String] other object to coerce to a
78
+ # PointType
79
+ #
80
+ # @return [[PointType, PointType]]
81
+ #
82
+ def coerce(other)
83
+ [coerce_single(other), self]
84
+ end
85
+
86
+ # rename raw methods so we can overwrite them
87
+ # @!visibility private
88
+ alias raw_latitude latitude
89
+ # .
90
+ # @!visibility private
91
+ alias raw_longitude longitude
92
+ # .
93
+ # @!visibility private
94
+ alias raw_altitude altitude
95
+ # .
96
+ # @!visibility private
97
+ alias raw_distance_from distance_from
98
+
99
+ # @!attribute [r] latitude
100
+ # @return [QuantityType]
101
+ def latitude
102
+ QuantityType.new(raw_latitude.to_big_decimal, SIUnits::DEGREE_ANGLE)
103
+ end
104
+
105
+ # @!attribute [r] longitude
106
+ # @return [QuantityType]
107
+ def longitude
108
+ QuantityType.new(raw_longitude.to_big_decimal, SIUnits::DEGREE_ANGLE)
109
+ end
110
+
111
+ # @!attribute [r] altitude
112
+ # @return [QuantityType]
113
+ def altitude
114
+ QuantityType.new(raw_altitude.to_big_decimal, Units::METRE)
115
+ end
116
+
117
+ #
118
+ # Calculate the distance in meters from other, ignoring altitude.
119
+ #
120
+ # This algorithm also ignores the oblate spheroid shape of Earth and
121
+ # assumes a perfect sphere, so results are inexact.
122
+ #
123
+ # @return [QuantityType]
124
+ def distance_from(other)
125
+ logger.trace("(#{self}).distance_from(#{other} (#{other.class})")
126
+ QuantityType.new(raw_distance_from(coerce_single(other)), SIUnits::METRE)
127
+ end
128
+ alias - distance_from
129
+
130
+ private
131
+
132
+ # coerce an object to a PointType
133
+ # @return [PointType]
134
+ def coerce_single(other) # rubocop:disable Metrics/MethodLength
135
+ logger.trace("Coercing #{self} as a request from #{other.class}")
136
+ if other.is_a?(PointType)
137
+ other
138
+ elsif other.is_a?(Items::LocationItem)
139
+ raise TypeError, "can't convert #{other.raw_state} into #{self.class}" unless other.state?
140
+
141
+ other.state
142
+ elsif other.respond_to?(:to_str)
143
+ PointType.new(other.to_str)
144
+ else
145
+ raise TypeError, "can't convert #{other.class} into #{self.class}"
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'openhab/log/logger'
4
+
3
5
  require_relative 'type'
4
6
 
5
7
  require_relative 'date_time_type'
@@ -11,6 +13,7 @@ require_relative 'open_closed_type'
11
13
  require_relative 'on_off_type'
12
14
  require_relative 'percent_type'
13
15
  require_relative 'play_pause_type'
16
+ require_relative 'point_type'
14
17
  require_relative 'quantity_type'
15
18
  require_relative 'refresh_type'
16
19
  require_relative 'rewind_fastforward_type'
@@ -26,6 +29,8 @@ module OpenHAB
26
29
  # modules
27
30
  #
28
31
  module Types
32
+ include OpenHAB::Log
33
+
29
34
  # Hash taking a Enum value, and returning two symbols of
30
35
  # predicates to be defined for it. the first is the "command" form,
31
36
  # which should be defined on ItemCommandEvent, and on the Type itself.
@@ -64,7 +69,7 @@ module OpenHAB
64
69
  states = PREDICATE_ALIASES[value.to_s]
65
70
 
66
71
  ([command] | states).each do |method|
67
- OpenHAB::Core.logger.trace("Defining #{klass}##{method} for #{value}")
72
+ logger.trace("Defining #{klass}##{method} for #{value}")
68
73
  klass.class_eval <<~RUBY, __FILE__, __LINE__ + 1
69
74
  def #{method} # def on?
70
75
  self == #{value} # self == ON
@@ -137,31 +137,36 @@ module OpenHAB
137
137
  # @return [Logger] for the current class
138
138
  #
139
139
  def logger
140
- Log.logger(self.class.name)
140
+ Log.logger(self.class)
141
141
  end
142
142
 
143
143
  class << self
144
144
  #
145
145
  # Injects a logger into the base class
146
146
  #
147
- # @param [String] name of the logger
147
+ # @param [Class] class the logger is for
148
148
  #
149
149
  # @return [Logger] for the supplied name
150
150
  #
151
- def logger(name)
152
- name ||= self.class.name
151
+ def logger(klass)
152
+ if klass.respond_to?(:java_class) &&
153
+ klass.java_class &&
154
+ !klass.java_class.name.start_with?('org.jruby.Ruby')
155
+ klass = klass.java_class
156
+ end
157
+ name = klass.name
153
158
  @loggers[name] ||= Log.logger_for(name)
154
159
  end
155
160
 
156
161
  #
157
162
  # Configure a logger for the supplied class name
158
163
  #
159
- # @param [String] classname to configure logger for
164
+ # @param [String] name to configure logger for
160
165
  #
161
166
  # @return [Logger] for the supplied classname
162
167
  #
163
- def logger_for(classname)
164
- configure_logger_for(classname)
168
+ def logger_for(name)
169
+ configure_logger_for(name)
165
170
  end
166
171
 
167
172
  private
@@ -173,10 +178,10 @@ module OpenHAB
173
178
  #
174
179
  # @return [Logger] Logger for the supplied classname
175
180
  #
176
- def configure_logger_for(classname)
181
+ def configure_logger_for(name)
177
182
  log_prefix = Configuration.log_prefix
178
- log_prefix += if classname
179
- ".#{classname}"
183
+ log_prefix += if name
184
+ ".#{name}"
180
185
  else
181
186
  ".#{log_caller}"
182
187
  end
@@ -207,7 +212,7 @@ module OpenHAB
207
212
  def self.included(base)
208
213
  class << base
209
214
  def logger
210
- Log.logger(self.class.name)
215
+ Log.logger(self)
211
216
  end
212
217
  end
213
218
  end
@@ -5,5 +5,5 @@
5
5
  #
6
6
  module OpenHAB
7
7
  # @return [String] Version of OpenHAB helper libraries
8
- VERSION = '4.5.0'
8
+ VERSION = '4.7.0'
9
9
  end
data/lib/openhab.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'openhab/core/load_path'
4
+ require 'openhab/core/entity_lookup'
5
+ require 'openhab/core/script_handling'
4
6
  require 'openhab/core/openhab_setup'
5
7
  require 'openhab/log/logger'
6
8
  require 'openhab/dsl/dsl'
@@ -17,9 +19,12 @@ module OpenHAB
17
19
  # @param [Object] base Object to decorate with DSL and helper methods
18
20
  #
19
21
  #
22
+ # rubocop:disable Metrics/MethodLength
23
+ # Number of extensions and includes requires more lines
20
24
  def self.extended(base)
21
25
  OpenHAB::Core.wait_till_openhab_ready
22
26
  base.extend Log
27
+ base.extend OpenHAB::Core::ScriptHandling
23
28
  base.extend OpenHAB::Core::EntityLookup
24
29
  base.extend OpenHAB::DSL
25
30
  base.extend OpenHAB::DSL::TimeOfDay
@@ -31,6 +36,7 @@ module OpenHAB
31
36
 
32
37
  OpenHAB::Core.add_rubylib_to_load_path
33
38
  end
39
+ # rubocop:enable Metrics/MethodLength
34
40
  end
35
41
 
36
42
  # Extend caller with OpenHAB methods
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openhab-scripting
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.5.0
4
+ version: 4.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian O'Connell
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-10-19 00:00:00.000000000 Z
11
+ date: 2021-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -50,6 +50,8 @@ files:
50
50
  - lib/openhab/core/load_path.rb
51
51
  - lib/openhab/core/openhab_setup.rb
52
52
  - lib/openhab/core/osgi.rb
53
+ - lib/openhab/core/script_handling.rb
54
+ - lib/openhab/core/thread_local.rb
53
55
  - lib/openhab/dsl/actions.rb
54
56
  - lib/openhab/dsl/dsl.rb
55
57
  - lib/openhab/dsl/gems.rb
@@ -66,6 +68,7 @@ files:
66
68
  - lib/openhab/dsl/items/item_equality.rb
67
69
  - lib/openhab/dsl/items/item_registry.rb
68
70
  - lib/openhab/dsl/items/items.rb
71
+ - lib/openhab/dsl/items/location_item.rb
69
72
  - lib/openhab/dsl/items/metadata.rb
70
73
  - lib/openhab/dsl/items/number_item.rb
71
74
  - lib/openhab/dsl/items/numeric_item.rb
@@ -114,6 +117,7 @@ files:
114
117
  - lib/openhab/dsl/types/open_closed_type.rb
115
118
  - lib/openhab/dsl/types/percent_type.rb
116
119
  - lib/openhab/dsl/types/play_pause_type.rb
120
+ - lib/openhab/dsl/types/point_type.rb
117
121
  - lib/openhab/dsl/types/quantity_type.rb
118
122
  - lib/openhab/dsl/types/refresh_type.rb
119
123
  - lib/openhab/dsl/types/rewind_fastforward_type.rb