openhab-scripting 4.8.5 → 4.10.2

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: 19b14c62e681500abaa99858522f7592e0a4d93f6966a5cf8e99157b0944cbe6
4
- data.tar.gz: 071556f83604d539af3620a0796eef993edfc0bb224ad3dd08cf7d5a71e9d593
3
+ metadata.gz: 2363b08b3ff2cf49420f2083bad82d1c20fcc927104641bbcc824495bd0ba520
4
+ data.tar.gz: a589c5a4e5a92a8c4899784a70a1a2bd5c352ae46d0ccd446516369fb1ce39ad
5
5
  SHA512:
6
- metadata.gz: '01429a840f1af1e81886988f00ad628fa01dd7a7423ef2e20c59eb1d40822b573115d12a0c8c6fc093012ad29a70666bf280de52a789a8dc8cf6b0c7d2eb1867'
7
- data.tar.gz: 28aab00e8742851f08fee9535b39c913f78f4c7200f2bdbd8788e4d6c8ac8ae6f202a7f3e4675e0e02af2bbc953b6a10114b93987eff5c6ec37e1d6ad0f8ddeb
6
+ metadata.gz: dfe40bd0793be059b2196d18ea6e68fba9415b92326cb9e55b6a1bcbf68bc778ed96cb5f1a97ce2f6a61f6164452dea25e0c6f905bdd88c206cafc19194e850e
7
+ data.tar.gz: cdb36b59bd35ab74fa08cbfa1e011c73c3111f04702451e16698c8f701fadedfb6f68af514149dc6bac6a9808ad206ea5eba738a1cd78f5e2efee2b6fb52cd16
@@ -39,8 +39,6 @@ module OpenHAB
39
39
  logger.trace("Coercing #{self} as a request from #{other.class}")
40
40
  return [other, nil] unless state?
41
41
  return [other, state] if other.is_a?(Types::HSBType) || other.respond_to?(:to_str)
42
-
43
- raise TypeError, "can't convert #{other.class} into #{self.class}"
44
42
  end
45
43
 
46
44
  # any method that exists on {Types::HSBType} gets forwarded to +state+
@@ -40,8 +40,6 @@ module OpenHAB
40
40
  logger.trace("Coercing #{self} as a request from #{other.class}")
41
41
  return [other, nil] unless state?
42
42
  return [other, state] if other.is_a?(Types::DateTimeType) || other.respond_to?(:to_time)
43
-
44
- raise TypeError, "can't convert #{other.class} into #{self.class}"
45
43
  end
46
44
 
47
45
  # any method that exists on DateTimeType, Java's ZonedDateTime, or
@@ -39,8 +39,6 @@ module OpenHAB
39
39
  logger.trace("Coercing #{self} as a request from #{other.class}")
40
40
  return [other, nil] unless state?
41
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
42
  end
45
43
 
46
44
  # OpenHAB has this method, but it _only_ accepts PointType, so remove it and delegate
@@ -47,8 +47,6 @@ module OpenHAB
47
47
  logger.trace("Coercing #{self} as a request from #{other.class}")
48
48
  return [other, nil] unless state?
49
49
  return [other, state] if other.is_a?(Types::NumericType) || other.respond_to?(:to_d)
50
-
51
- raise TypeError, "can't convert #{other.class} into #{self.class}"
52
50
  end
53
51
 
54
52
  # strip trailing zeros from commands
@@ -5,6 +5,8 @@ require 'set'
5
5
  require 'openhab/core/thread_local'
6
6
  require 'openhab/log/logger'
7
7
 
8
+ require_relative 'item_event'
9
+
8
10
  module OpenHAB
9
11
  module DSL
10
12
  #
@@ -29,6 +31,8 @@ module OpenHAB
29
31
  # @param [Config] config Rule configuration
30
32
  #
31
33
  # Constructor sets a number of variables, no further decomposition necessary
34
+ # rubocop:disable Metrics/MethodLength
35
+ # Metrics disabled because only setters are called or defaults set.
32
36
  def initialize(config:)
33
37
  super()
34
38
  set_name(config.name)
@@ -41,7 +45,9 @@ module OpenHAB
41
45
  @between = between || OpenHAB::DSL::TimeOfDay::ALL_DAY
42
46
  # Convert between to correct range or nil if not set
43
47
  @trigger_delays = config.trigger_delays
48
+ @attachments = config.attachments
44
49
  end
50
+ # rubocop:enable Metrics/MethodLength
45
51
 
46
52
  #
47
53
  # Execute the rule
@@ -51,7 +57,7 @@ module OpenHAB
51
57
  #
52
58
  #
53
59
  def execute(mod = nil, inputs = nil)
54
- logger.trace { "Execute called with mod (#{mod&.to_string}) and inputs (#{inputs&.pretty_inspect}" }
60
+ logger.trace { "Execute called with mod (#{mod&.to_string}) and inputs (#{inputs&.pretty_inspect})" }
55
61
  logger.trace { "Event details #{inputs['event'].pretty_inspect}" } if inputs&.key?('event')
56
62
  if trigger_delay inputs
57
63
  trigger_delay = trigger_delay(inputs)
@@ -88,6 +94,15 @@ module OpenHAB
88
94
  end
89
95
  end
90
96
 
97
+ #
98
+ # Get the trigger_id for the trigger that caused the rule creation
99
+ #
100
+ # @return [Hash] Input hash potentially containing trigger id
101
+ #
102
+ def trigger_id(inputs)
103
+ inputs&.keys&.grep(/\.event$/)&.first&.chomp('.event')
104
+ end
105
+
91
106
  #
92
107
  # Returns trigger delay from inputs if it exists
93
108
  #
@@ -100,7 +115,24 @@ module OpenHAB
100
115
  # ["72698819-83cb-498a-8e61-5aab8b812623.event", "oldState", "module", \
101
116
  # "72698819-83cb-498a-8e61-5aab8b812623.oldState", "event", "newState",\
102
117
  # "72698819-83cb-498a-8e61-5aab8b812623.newState"]
103
- @trigger_delays[inputs&.keys&.grep(/\.event$/)&.first&.chomp('.event')]
118
+ @trigger_delays[trigger_id(inputs)]
119
+ end
120
+
121
+ # If an attachment exists for the trigger for this event add it to the event object
122
+ # @param [Object] Event
123
+ # @param [Hash] Inputs into event
124
+ # @return [Object] Event with attachment added
125
+ #
126
+ def add_attachment(event, inputs)
127
+ attachment = @attachments[trigger_id(inputs)]
128
+ return event unless attachment
129
+
130
+ # Some events, like those from cron triggers don't have an event
131
+ # so an event is created
132
+ event ||= Struct.new(:event).new
133
+
134
+ event.attachment = attachment
135
+ event
104
136
  end
105
137
 
106
138
  #
@@ -268,8 +300,11 @@ module OpenHAB
268
300
  # @param [Map] inputs OpenHAB map object describing rule trigge
269
301
  #
270
302
  #
303
+ # rubocop:disable Metrics/MethodLength
304
+ # No logical way to break this method up
271
305
  def process_queue(run_queue, mod, inputs)
272
306
  event = inputs&.dig('event')
307
+ event = add_attachment(event, inputs)
273
308
 
274
309
  while (task = run_queue.shift)
275
310
  if task.is_a? RuleConfig::Delay
@@ -281,6 +316,7 @@ module OpenHAB
281
316
  rescue StandardError => e
282
317
  print_backtrace(e)
283
318
  end
319
+ # rubocop:enable Metrics/MethodLength
284
320
 
285
321
  #
286
322
  # Dispatch execution block tasks to different methods
@@ -13,13 +13,13 @@ module OpenHAB
13
13
  include OpenHAB::DSL::Rules::Property
14
14
 
15
15
  prop_array(:only_if) do |item|
16
- unless item.is_a?(Proc) || item.respond_to?(:truthy?)
16
+ unless item.is_a?(Proc) || [item].flatten.all? { |it| it.respond_to?(:truthy?) }
17
17
  raise ArgumentError, "Object passed to only_if must respond_to 'truthy?'"
18
18
  end
19
19
  end
20
20
 
21
21
  prop_array(:not_if) do |item|
22
- unless item.is_a?(Proc) || item.respond_to?(:truthy?)
22
+ unless item.is_a?(Proc) || [item].flatten.all? { |it| it.respond_to?(:truthy?) }
23
23
  raise ArgumentError, "Object passed to not_if must respond_to 'truthy?'"
24
24
  end
25
25
  end
@@ -113,7 +113,7 @@ module OpenHAB
113
113
  # @return [Boolean] True if criteria are satisfied, false otherwise
114
114
  #
115
115
  def process_not_if(event, items, procs)
116
- items.none?(&:truthy?) && procs.none? { |proc| proc.call(event) }
116
+ items.flatten.none?(&:truthy?) && procs.none? { |proc| proc.call(event) }
117
117
  end
118
118
 
119
119
  #
@@ -126,7 +126,7 @@ module OpenHAB
126
126
  # @return [Boolean] True if criteria are satisfied, false otherwise
127
127
  #
128
128
  def process_only_if(event, items, procs)
129
- items.all?(&:truthy?) && procs.all? { |proc| proc.call(event) }
129
+ items.flatten.all?(&:truthy?) && procs.all? { |proc| proc.call(event) }
130
130
  end
131
131
  end
132
132
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module DSL
5
+ module Rules
6
+ #
7
+ # Extends OpenHAB events
8
+ #
9
+ module Events
10
+ java_import org.openhab.core.events.AbstractEvent
11
+
12
+ # Add attachments to ItemEvent
13
+ class AbstractEvent
14
+ attr_accessor :attachment
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -87,7 +87,7 @@ module OpenHAB
87
87
  rule = AutomationRule.new(config: config)
88
88
  Rules.script_rules << rule
89
89
  add_rule(rule)
90
- rule.execute if config.on_start?
90
+ rule.execute(nil, { 'event' => Struct.new(:attachment).new(config.start_attachment) }) if config.on_start?
91
91
  end
92
92
 
93
93
  #
@@ -37,6 +37,9 @@ module OpenHAB
37
37
  # @return [Array] Of trigger delays
38
38
  attr_reader :trigger_delays
39
39
 
40
+ # @return [Hash] Hash of trigger UIDs to attachments
41
+ attr_reader :attachments
42
+
40
43
  # @return [Array] Of trigger guards
41
44
  attr_accessor :guard
42
45
 
@@ -82,6 +85,7 @@ module OpenHAB
82
85
  def initialize(rule_name, caller_binding)
83
86
  @triggers = []
84
87
  @trigger_delays = {}
88
+ @attachments = {}
85
89
  @caller = caller_binding.eval 'self'
86
90
  enabled(true)
87
91
  on_start(false)
@@ -96,8 +100,8 @@ module OpenHAB
96
100
  #
97
101
  # rubocop: disable Style/OptionalBooleanParameter
98
102
  # Disabled cop due to use in a DSL
99
- def on_start(run_on_start = true)
100
- @on_start = run_on_start
103
+ def on_start(run_on_start = true, attach: nil)
104
+ @on_start = Struct.new(:enabled, :attach).new(run_on_start, attach)
101
105
  end
102
106
  # rubocop: enable Style/OptionalBooleanParameter
103
107
 
@@ -107,7 +111,16 @@ module OpenHAB
107
111
  # @return [Boolean] True if rule should run on start, false otherwise.
108
112
  #
109
113
  def on_start?
110
- @on_start
114
+ @on_start.enabled
115
+ end
116
+
117
+ #
118
+ # Get the optional start attachment
119
+ #
120
+ # @return [Object] optional user provided attachment to the on_start method
121
+ #
122
+ def start_attachment
123
+ @on_start.attach
111
124
  end
112
125
 
113
126
  #
@@ -144,7 +157,8 @@ module OpenHAB
144
157
  "Run blocks: (#{run}) " \
145
158
  "on_start: (#{on_start?}) " \
146
159
  "Trigger Waits: #{trigger_delays} " \
147
- "Trigger UIDs: #{triggers.map(&:id).join(', ')}"
160
+ "Trigger UIDs: #{triggers.map(&:id).join(', ')}" \
161
+ "Attachments: #{attachments} "
148
162
  end
149
163
  end
150
164
  end
@@ -30,16 +30,16 @@ module OpenHAB
30
30
  #
31
31
  # @return [Trigger] OpenHAB trigger
32
32
  #
33
- def changed(*items, to: nil, from: nil, for: nil)
33
+ def changed(*items, to: nil, from: nil, for: nil, attach: nil)
34
34
  separate_groups(items).map do |item|
35
35
  logger.trace("Creating changed trigger for entity(#{item}), to(#{to}), from(#{from})")
36
36
  # for is a reserved word in ruby, so use local_variable_get :for
37
37
  if (wait_duration = binding.local_variable_get(:for))
38
- changed_wait(item, to: to, from: from, duration: wait_duration)
38
+ changed_wait(item, to: to, from: from, duration: wait_duration, attach: attach)
39
39
  else
40
40
  # Place in array and flatten to support multiple to elements or single or nil
41
41
  [to].flatten.map do |to_state|
42
- [from].flatten.map { |from_state| create_changed_trigger(item, from_state, to_state) }
42
+ [from].flatten.map { |from_state| create_changed_trigger(item, from_state, to_state, attach) }
43
43
  end
44
44
  end
45
45
  end.flatten
@@ -57,8 +57,8 @@ module OpenHAB
57
57
  #
58
58
  # @return [Trigger] OpenHAB trigger
59
59
  #
60
- def changed_wait(item, duration:, to: nil, from: nil)
61
- trigger = create_changed_trigger(item, nil, nil)
60
+ def changed_wait(item, duration:, to: nil, from: nil, attach: nil)
61
+ trigger = create_changed_trigger(item, nil, nil, attach)
62
62
  logger.trace("Creating Changed Wait Change Trigger for #{item}")
63
63
  @trigger_delays[trigger.id] = TriggerDelay.new(to: to, from: from, duration: duration)
64
64
  trigger
@@ -72,14 +72,14 @@ module OpenHAB
72
72
  # @param [String] to state restrict trigger to
73
73
  #
74
74
  #
75
- def create_changed_trigger(item, from, to)
75
+ def create_changed_trigger(item, from, to, attach)
76
76
  trigger, config = case item
77
77
  when OpenHAB::DSL::Items::GroupItem::GroupMembers
78
78
  create_group_changed_trigger(item, from, to)
79
79
  when Thing then create_thing_changed_trigger(item, from, to)
80
80
  else create_item_changed_trigger(item, from, to)
81
81
  end
82
- append_trigger(trigger, config)
82
+ append_trigger(trigger, config, attach: attach)
83
83
  end
84
84
 
85
85
  #
@@ -21,12 +21,12 @@ module OpenHAB
21
21
  # @param [String] triggered specific triggering condition to match for trigger
22
22
  #
23
23
  #
24
- def channel(*channels, thing: nil, triggered: nil)
24
+ def channel(*channels, thing: nil, triggered: nil, attach: nil)
25
25
  channels.flatten.each do |channel|
26
26
  channel = [thing, channel].join(':') if thing
27
27
  logger.trace("Creating channel trigger for channel(#{channel}), thing(#{thing}), trigger(#{triggered})")
28
28
  [triggered].flatten.each do |trigger|
29
- create_channel_trigger(channel, trigger)
29
+ create_channel_trigger(channel, trigger, attach)
30
30
  end
31
31
  end
32
32
  end
@@ -40,12 +40,12 @@ module OpenHAB
40
40
  # @param [Trigger] trigger specific channel trigger to match
41
41
  #
42
42
  #
43
- def create_channel_trigger(channel, trigger)
43
+ def create_channel_trigger(channel, trigger, attach)
44
44
  config = { 'channelUID' => channel }
45
45
  config['event'] = trigger.to_s unless trigger.nil?
46
46
  config['channelUID'] = channel
47
47
  logger.trace("Creating Change Trigger for #{config}")
48
- @triggers << Trigger.trigger(type: Trigger::CHANNEL_EVENT, config: config)
48
+ append_trigger(Trigger::CHANNEL_EVENT, config, attach: attach)
49
49
  end
50
50
  end
51
51
  end
@@ -21,14 +21,14 @@ module OpenHAB
21
21
  # @param [Array] commands commands to match for trigger
22
22
  #
23
23
  #
24
- def received_command(*items, command: nil, commands: nil)
24
+ def received_command(*items, command: nil, commands: nil, attach: nil)
25
25
  separate_groups(items).map do |item|
26
26
  logger.trace("Creating received command trigger for item(#{item})"\
27
27
  "command(#{command}) commands(#{commands})")
28
28
 
29
29
  # Combine command and commands, doing union so only a single nil will be in the combined array.
30
30
  combined_commands = combine_commands(command, commands)
31
- create_received_trigger(combined_commands, item)
31
+ create_received_trigger(combined_commands, item, attach)
32
32
  end.flatten
33
33
  end
34
34
 
@@ -41,7 +41,7 @@ module OpenHAB
41
41
  # @param [Object] item to create trigger for
42
42
  #
43
43
  #
44
- def create_received_trigger(commands, item)
44
+ def create_received_trigger(commands, item, attach)
45
45
  commands.map do |command|
46
46
  if item.is_a? OpenHAB::DSL::Items::GroupItem::GroupMembers
47
47
  config, trigger = create_group_command_trigger(item)
@@ -49,7 +49,7 @@ module OpenHAB
49
49
  config, trigger = create_item_command_trigger(item)
50
50
  end
51
51
  config['command'] = command.to_s unless command.nil?
52
- append_trigger(trigger, config)
52
+ append_trigger(trigger, config, attach: attach)
53
53
  end
54
54
  end
55
55
 
@@ -46,9 +46,10 @@ module OpenHAB
46
46
  #
47
47
  # @return [Trigger] OpenHAB trigger
48
48
  #
49
- def append_trigger(type, config)
49
+ def append_trigger(type, config, attach: nil)
50
50
  logger.trace("Creating trigger of type #{type} for #{config}")
51
51
  trigger = Trigger.trigger(type: type, config: config)
52
+ @attachments[trigger.id] = attach if attach
52
53
  @triggers << trigger
53
54
  trigger
54
55
  end
@@ -19,12 +19,12 @@ module OpenHAB
19
19
  #
20
20
  # @return [Trigger] Trigger for updated entity
21
21
  #
22
- def updated(*items, to: nil)
22
+ def updated(*items, to: nil, attach: nil)
23
23
  separate_groups(items).map do |item|
24
24
  logger.trace("Creating updated trigger for item(#{item}) to(#{to})")
25
25
  [to].flatten.map do |to_state|
26
26
  trigger, config = create_update_trigger(item, to_state)
27
- append_trigger(trigger, config)
27
+ append_trigger(trigger, config, attach: attach)
28
28
  end
29
29
  end.flatten
30
30
  end
@@ -161,7 +161,8 @@ module OpenHAB
161
161
  time_string = "#{time_string}T00:00:00#{zone}" if DATE_ONLY_REGEX.match?(time_string)
162
162
  self <=> DateTimeType.parse(time_string)
163
163
  elsif other.respond_to?(:coerce)
164
- lhs, rhs = other.coerce(self)
164
+ return nil unless (lhs, rhs = other.coerce(self))
165
+
165
166
  lhs <=> rhs
166
167
  end
167
168
  end
@@ -179,13 +180,11 @@ module OpenHAB
179
180
  def coerce(other)
180
181
  logger.trace("Coercing #{self} as a request from #{other.class}")
181
182
  if other.is_a?(Items::DateTimeItem)
182
- raise TypeError, "can't convert #{UnDefType} into #{self.class}" unless other.state?
183
+ return unless other.state?
183
184
 
184
185
  [other.state, self]
185
186
  elsif other.respond_to?(:to_time)
186
187
  [DateTimeType.new(other), self]
187
- else
188
- raise TypeError, "can't convert #{other.class} into #{self.class}"
189
188
  end
190
189
  end
191
190
 
@@ -286,8 +285,7 @@ module OpenHAB
286
285
  self + other
287
286
  elsif other.respond_to?(:to_d)
288
287
  DateTimeType.new(zoned_date_time.plusNanos((other.to_d * 1_000_000_000).to_i))
289
- elsif other.respond_to?(:coerce)
290
- lhs, rhs = other.coerce(to_d)
288
+ elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
291
289
  lhs + rhs
292
290
  else
293
291
  raise TypeError, "\#{other.class} can't be coerced into \#{self.class}"
@@ -320,8 +318,7 @@ module OpenHAB
320
318
  self - other
321
319
  elsif other.respond_to?(:to_d)
322
320
  DateTimeType.new(zoned_date_time.minusNanos((other.to_d * 1_000_000_000).to_i))
323
- elsif other.respond_to?(:coerce)
324
- lhs, rhs = other.coerce(to_d)
321
+ elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
325
322
  lhs - rhs
326
323
  else
327
324
  raise TypeError, "\#{other.class} can't be coerced into \#{self.class}"
@@ -87,7 +87,8 @@ module OpenHAB
87
87
  elsif other.respond_to?(:to_d)
88
88
  to_d <=> other.to_d
89
89
  elsif other.respond_to?(:coerce)
90
- lhs, rhs = other.coerce(self)
90
+ return nil unless (lhs, rhs = other.coerce(self))
91
+
91
92
  lhs <=> rhs
92
93
  end
93
94
  end
@@ -109,15 +110,13 @@ module OpenHAB
109
110
  logger.trace("Coercing #{self} as a request from #{other.class}")
110
111
  if other.is_a?(Items::NumericItem) ||
111
112
  (other.is_a?(Items::GroupItem) && other.base_item.is_a?(Items::NumericItem))
112
- raise TypeError, "can't convert #{UnDefType} into #{self.class}" unless other.state?
113
+ return unless other.state?
113
114
 
114
115
  [other.state, self]
115
116
  elsif other.is_a?(Type)
116
117
  [other, as(other.class)]
117
118
  elsif other.respond_to?(:to_d)
118
119
  [self.class.new(other.to_d), self]
119
- else
120
- raise TypeError, "can't convert #{other.class} into #{self.class}"
121
120
  end
122
121
  end
123
122
 
@@ -150,8 +149,7 @@ module OpenHAB
150
149
  # # result could already be a QuantityType
151
150
  # result = self.class.new(result) unless result.is_a?(NumericType)
152
151
  # result
153
- # elsif other.respond_to?(:coerce)
154
- # lhs, rhs = other.coerce(to_d)
152
+ # elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
155
153
  # lhs + rhs
156
154
  # else
157
155
  # raise TypeError, "#{other.class} can't be coerced into #{self.class}"
@@ -168,8 +166,7 @@ module OpenHAB
168
166
  # result could already be a QuantityType
169
167
  result = self.class.new(result) unless result.is_a?(NumericType)
170
168
  result
171
- elsif other.respond_to?(:coerce)
172
- lhs, rhs = other.coerce(to_d)
169
+ elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
173
170
  lhs #{ruby_op} rhs
174
171
  else
175
172
  raise TypeError, "\#{other.class} can't be coerced into \#{self.class}"
@@ -133,7 +133,7 @@ module OpenHAB
133
133
  logger.trace("Coercing #{self} as a request from #{other.class}")
134
134
  if other.is_a?(Items::NumericItem) ||
135
135
  (other.is_a?(Items::GroupItem) && other.base_item.is_a?(Items::NumericItem))
136
- raise TypeError, "can't convert #{UnDefType} into #{self.class}" unless other.state?
136
+ return unless other.state?
137
137
 
138
138
  [other.state, self]
139
139
  elsif other.respond_to?(:to_str)
@@ -64,7 +64,8 @@ module OpenHAB
64
64
  elsif other.respond_to?(:to_str)
65
65
  self == PointType.new(other)
66
66
  elsif other.respond_to?(:coerce)
67
- lhs, rhs = other.coerce(self)
67
+ return false unless (lhs, rhs = other.coerce(self))
68
+
68
69
  lhs == rhs
69
70
  end
70
71
  end
@@ -80,7 +81,10 @@ module OpenHAB
80
81
  # @return [[PointType, PointType]]
81
82
  #
82
83
  def coerce(other)
83
- [coerce_single(other), self]
84
+ lhs = coerce_single(other)
85
+ return unless lhs
86
+
87
+ [lhs, self]
84
88
  end
85
89
 
86
90
  # rename raw methods so we can overwrite them
@@ -123,7 +127,10 @@ module OpenHAB
123
127
  # @return [QuantityType]
124
128
  def distance_from(other)
125
129
  logger.trace("(#{self}).distance_from(#{other} (#{other.class})")
126
- QuantityType.new(raw_distance_from(coerce_single(other)), SIUnits::METRE)
130
+ other = coerce_single(other)
131
+ raise TypeError, "#{other.class} can't be coerced into #{self.class}" unless other
132
+
133
+ QuantityType.new(raw_distance_from(other), SIUnits::METRE)
127
134
  end
128
135
  alias - distance_from
129
136
 
@@ -131,18 +138,16 @@ module OpenHAB
131
138
 
132
139
  # coerce an object to a PointType
133
140
  # @return [PointType]
134
- def coerce_single(other) # rubocop:disable Metrics/MethodLength
141
+ def coerce_single(other)
135
142
  logger.trace("Coercing #{self} as a request from #{other.class}")
136
143
  if other.is_a?(PointType)
137
144
  other
138
145
  elsif other.is_a?(Items::LocationItem)
139
- raise TypeError, "can't convert #{other.raw_state} into #{self.class}" unless other.state?
146
+ return unless other.state?
140
147
 
141
148
  other.state
142
149
  elsif other.respond_to?(:to_str)
143
150
  PointType.new(other.to_str)
144
- else
145
- raise TypeError, "can't convert #{other.class} into #{self.class}"
146
151
  end
147
152
  end
148
153
  end
@@ -61,7 +61,8 @@ module OpenHAB
61
61
  elsif other.respond_to?(:to_d)
62
62
  compare_to(QuantityType.new(other.to_d.to_java, Units.unit || unit))
63
63
  elsif other.respond_to?(:coerce)
64
- lhs, rhs = other.coerce(self)
64
+ return nil unless (lhs, rhs = other.coerce(self))
65
+
65
66
  lhs <=> rhs
66
67
  end
67
68
  end
@@ -82,7 +83,7 @@ module OpenHAB
82
83
  logger.trace("Coercing #{self} as a request from #{other.class}")
83
84
  if other.is_a?(Items::NumericItem) ||
84
85
  (other.is_a?(Items::GroupItem) && other.base_item.is_a?(Items::NumericItem))
85
- raise TypeError, "can't convert #{UnDefType} into #{self.class}" unless other.state?
86
+ return unless other.state?
86
87
 
87
88
  [other.state, self]
88
89
  elsif other.is_a?(Type)
@@ -91,8 +92,6 @@ module OpenHAB
91
92
  [QuantityType.new(other.to_d.to_java, ONE), self]
92
93
  elsif other.is_a?(String)
93
94
  [QuantityType.new(other), self]
94
- else
95
- raise TypeError, "can't convert #{other.class} into #{self.class}"
96
95
  end
97
96
  end
98
97
 
@@ -123,9 +122,8 @@ module OpenHAB
123
122
  # elsif other.respond_to?(:to_d)
124
123
  # other = other.to_d.to_java
125
124
  # add_quantity(self.class.new(other, Units.unit || unit))
126
- # elsif other.respond_to?(:coerce)
127
- # lhs, rhs = other.coerce(to_d)
128
- # lhs = rhs
125
+ # elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
126
+ # lhs + rhs
129
127
  # else
130
128
  # raise TypeError, "#{other.class} can't be coerced into #{self.class}"
131
129
  # end
@@ -148,8 +146,7 @@ module OpenHAB
148
146
  elsif other.respond_to?(:to_d)
149
147
  other = other.to_d.to_java
150
148
  #{java_op}_quantity(#{convert})
151
- elsif other.respond_to?(:coerce)
152
- lhs, rhs = other.coerce(to_d)
149
+ elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
153
150
  lhs #{ruby_op} rhs
154
151
  else
155
152
  raise TypeError, "\#{other.class} can't be coerced into \#{self.class}"
@@ -179,8 +176,7 @@ module OpenHAB
179
176
  # self * self.class.new(other)
180
177
  # elsif other.respond_to?(:to_d)
181
178
  # multiply(other.to_d.to_java)
182
- # elsif other.respond_to?(:coerce)
183
- # lhs, rhs = other.coerce(to_d)
179
+ # elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
184
180
  # lhs * rhs
185
181
  # else
186
182
  # raise TypeError, "#{other.class} can't be coerced into #{self.class}"
@@ -202,8 +198,7 @@ module OpenHAB
202
198
  self #{ruby_op} self.class.new(other)
203
199
  elsif other.respond_to?(:to_d)
204
200
  #{java_op}(other.to_d.to_java)
205
- elsif other.respond_to?(:coerce)
206
- lhs, rhs = other.coerce(to_d)
201
+ elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
207
202
  lhs #{ruby_op} rhs
208
203
  else
209
204
  raise TypeError, "\#{other.class} can't be coerced into \#{self.class}"
@@ -52,7 +52,8 @@ module OpenHAB
52
52
  elsif other.respond_to?(:to_str)
53
53
  to_str <=> other.to_str
54
54
  elsif other.respond_to?(:coerce)
55
- lhs, rhs = other.coerce(self)
55
+ return nil unless (lhs, rhs = other.coerce(self))
56
+
56
57
  lhs <=> rhs
57
58
  end
58
59
  end
@@ -70,13 +71,11 @@ module OpenHAB
70
71
  def coerce(other)
71
72
  logger.trace("Coercing #{self} as a request from #{other.class}")
72
73
  if other.is_a?(Items::StringItem)
73
- raise TypeError, "can't convert #{other.raw_state} into #{self.class}" unless other.state?
74
+ return unless other.state?
74
75
 
75
76
  [other.state, self]
76
77
  elsif other.respond_to?(:to_str)
77
78
  [String.new(other.to_str), self]
78
- else
79
- raise TypeError, "can't convert #{other.class} into #{self.class}"
80
79
  end
81
80
  end
82
81
 
@@ -28,8 +28,6 @@ module OpenHAB
28
28
  def coerce(other)
29
29
  logger.trace("Coercing #{self} (#{self.class}) as a request from #{other.class}")
30
30
  return [other.as(self.class), self] if other.is_a?(Type)
31
-
32
- raise TypeError, "can't convert #{other.class} into #{self.class}"
33
31
  end
34
32
 
35
33
  #
@@ -49,7 +47,8 @@ module OpenHAB
49
47
  # @return [Boolean] if the same value is represented, including
50
48
  # type conversions
51
49
  #
52
- def ==(other)
50
+ def ==(other) # rubocop:disable Metrics
51
+ logger.trace("(#{self.class}) #{self} == #{other} (#{other.class})")
53
52
  return true if equal?(other)
54
53
 
55
54
  # i.e. ON == OFF, REFRESH == ON, ON == REFRESH
@@ -60,7 +59,17 @@ module OpenHAB
60
59
  return self == other.raw_state if other.is_a?(Items::GenericItem)
61
60
 
62
61
  if other.respond_to?(:coerce)
63
- lhs, rhs = other.coerce(self)
62
+ begin
63
+ return false unless (lhs, rhs = other.coerce(self))
64
+ rescue TypeError
65
+ # this one is a bit odd. 50 (Integer) == ON is internally
66
+ # flipping the argument and calling this method. but it responds
67
+ # to coerce, and then raises a TypeError (from Float???) that
68
+ # it couldn't convert to OnOffType. it probably should have
69
+ # returned nil. catch it and return false instead
70
+ return false
71
+ end
72
+
64
73
  return lhs == rhs
65
74
  end
66
75
 
@@ -5,5 +5,5 @@
5
5
  #
6
6
  module OpenHAB
7
7
  # @return [String] Version of OpenHAB helper libraries
8
- VERSION = '4.8.5'
8
+ VERSION = '4.10.2'
9
9
  end
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.8.5
4
+ version: 4.10.2
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-11-01 00:00:00.000000000 Z
11
+ date: 2021-11-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -93,6 +93,7 @@ files:
93
93
  - lib/openhab/dsl/persistence.rb
94
94
  - lib/openhab/dsl/rules/automation_rule.rb
95
95
  - lib/openhab/dsl/rules/guard.rb
96
+ - lib/openhab/dsl/rules/item_event.rb
96
97
  - lib/openhab/dsl/rules/property.rb
97
98
  - lib/openhab/dsl/rules/rule.rb
98
99
  - lib/openhab/dsl/rules/rule_config.rb