openhab-jrubyscripting 5.0.0.rc1 → 5.0.0.rc3

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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/lib/openhab/core/entity_lookup.rb +1 -12
  3. data/lib/openhab/core/items/generic_item.rb +15 -7
  4. data/lib/openhab/core/items/metadata/hash.rb +81 -39
  5. data/lib/openhab/core/items/metadata/namespace_hash.rb +17 -19
  6. data/lib/openhab/core/items/metadata/provider.rb +48 -0
  7. data/lib/openhab/core/items/persistence.rb +2 -0
  8. data/lib/openhab/core/items/provider.rb +40 -0
  9. data/lib/openhab/core/items/proxy.rb +10 -0
  10. data/lib/openhab/core/items/registry.rb +16 -7
  11. data/lib/openhab/core/items/semantics/enumerable.rb +6 -4
  12. data/lib/openhab/core/items/state_storage.rb +3 -3
  13. data/lib/openhab/core/profile_factory.rb +3 -1
  14. data/lib/openhab/core/provider.rb +223 -0
  15. data/lib/openhab/core/registry.rb +30 -0
  16. data/lib/openhab/core/rules/provider.rb +25 -0
  17. data/lib/openhab/core/rules/registry.rb +76 -0
  18. data/lib/openhab/core/rules/rule.rb +150 -0
  19. data/lib/openhab/core/rules.rb +25 -0
  20. data/lib/openhab/core/script_handling.rb +50 -0
  21. data/lib/openhab/core/things/links/provider.rb +40 -0
  22. data/lib/openhab/core/things/provider.rb +25 -0
  23. data/lib/openhab/core/things/proxy.rb +10 -0
  24. data/lib/openhab/core/things/registry.rb +25 -2
  25. data/lib/openhab/core/timer.rb +17 -7
  26. data/lib/openhab/core/types/quantity_type.rb +5 -2
  27. data/lib/openhab/core/types.rb +1 -1
  28. data/lib/openhab/core.rb +3 -30
  29. data/lib/openhab/core_ext/java/class.rb +34 -0
  30. data/lib/openhab/core_ext/java/list.rb +436 -0
  31. data/lib/openhab/core_ext/java/local_time.rb +2 -1
  32. data/lib/openhab/core_ext/java/map.rb +66 -0
  33. data/lib/openhab/core_ext/java/month.rb +2 -1
  34. data/lib/openhab/core_ext/java/zoned_date_time.rb +1 -2
  35. data/lib/openhab/core_ext/ruby/date.rb +2 -0
  36. data/lib/openhab/core_ext/ruby/date_time.rb +53 -0
  37. data/lib/openhab/core_ext/ruby/time.rb +88 -86
  38. data/lib/openhab/dsl/events/watch_event.rb +1 -1
  39. data/lib/openhab/dsl/items/builder.rb +38 -100
  40. data/lib/openhab/dsl/items/ensure.rb +6 -2
  41. data/lib/openhab/dsl/items/timed_command.rb +10 -11
  42. data/lib/openhab/dsl/rules/automation_rule.rb +36 -13
  43. data/lib/openhab/dsl/rules/builder.rb +126 -8
  44. data/lib/openhab/dsl/rules/name_inference.rb +0 -5
  45. data/lib/openhab/dsl/rules/terse.rb +1 -2
  46. data/lib/openhab/dsl/rules/triggers/changed.rb +7 -4
  47. data/lib/openhab/dsl/rules/triggers/conditions/duration.rb +17 -53
  48. data/lib/openhab/dsl/rules/triggers/conditions/proc.rb +0 -3
  49. data/lib/openhab/dsl/rules/triggers/cron/cron.rb +1 -1
  50. data/lib/openhab/dsl/rules/triggers/trigger.rb +1 -1
  51. data/lib/openhab/dsl/rules/triggers/updated.rb +7 -3
  52. data/lib/openhab/dsl/rules/triggers/watch/watch_handler.rb +1 -1
  53. data/lib/openhab/dsl/rules.rb +0 -21
  54. data/lib/openhab/dsl/script_handling.rb +0 -49
  55. data/lib/openhab/dsl/things/builder.rb +8 -31
  56. data/lib/openhab/dsl/thread_local.rb +3 -2
  57. data/lib/openhab/dsl/timer_manager.rb +16 -8
  58. data/lib/openhab/dsl/version.rb +1 -1
  59. data/lib/openhab/dsl.rb +137 -120
  60. data/lib/openhab/log.rb +3 -3
  61. data/lib/openhab/rspec/example_group.rb +42 -0
  62. data/lib/openhab/rspec/helpers.rb +33 -27
  63. data/lib/openhab/rspec/hooks.rb +17 -23
  64. data/lib/openhab/rspec/karaf.rb +45 -27
  65. data/lib/openhab/rspec/mocks/synchronous_executor.rb +11 -4
  66. data/lib/openhab/rspec/mocks/timer.rb +7 -1
  67. data/lib/openhab/rspec/suspend_rules.rb +4 -2
  68. metadata +30 -3
  69. data/lib/openhab/rspec/mocks/metadata_provider.rb +0 -75
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cd7a4eed6a2398fd34734d9b3dc15a8f5e2bcc74f7309aede27be29501c21698
4
- data.tar.gz: a1f70554ada415e7de0325ea259ac9edcad48355ef6000a4877057fa06b343ce
3
+ metadata.gz: ce249607265a008aa969e2edbd56302edd70a67a01dfebaec9ad67b7e5f1ad27
4
+ data.tar.gz: ac0c8d25509a8be8374a3f15fecd2e575da8cb08b82268aef41414f64f7a3b38
5
5
  SHA512:
6
- metadata.gz: f27aa8940df9441a5318c32d1c0d84f15fdd70b2336cf95dd09383b73b97d14bbc7c924ba3e3df24f48d5f289d410ec1d6d0df9f99a40141ac34d88152e9a76a
7
- data.tar.gz: c369de38091c4486a492b88ef990537b5a4cc667becca6be5a99a56227a8a2b0339b14e9ce1e11e6e73b56d8b055d3876917916ee7ec52b66c5b23e85b33a95b
6
+ metadata.gz: 7c082f0949b6bc55ebf48b1489eade3f6bbcf25181d6741e29697dbb5ef5221abf583c78fb8ad46596b5ea10957e9d4b5d2d5dfe35097eea004f005d06683d48
7
+ data.tar.gz: ee7e740d0dd1233462521313c31145971bed68e2830c765bad27b8762d064bdf154993a2d733fc7743240bd55aec9e0eecd8cb4f2d569dbd0c599e765140cd06
@@ -72,7 +72,7 @@ module OpenHAB
72
72
  logger.trace("Looking up thing '#{uid}'")
73
73
  uid = uid.to_s if uid.is_a?(Symbol)
74
74
 
75
- uid = generate_thing_uid(uid) unless uid.is_a?(org.openhab.core.thing.ThingUID)
75
+ uid = Things::ThingUID.new(uid) unless uid.is_a?(Things::ThingUID)
76
76
  thing = $things.get(uid)
77
77
  return unless thing
78
78
 
@@ -117,17 +117,6 @@ module OpenHAB
117
117
  item = $ir.get(name)
118
118
  Items::Proxy.new(item) unless item.nil?
119
119
  end
120
-
121
- #
122
- # Returns a ThingUID given a string like object
123
- #
124
- # @!visibility private
125
- #
126
- # @return [Things::ThingUID]
127
- #
128
- def self.generate_thing_uid(uid)
129
- org.openhab.core.thing.ThingUID.new(*uid.split(":"))
130
- end
131
120
  end
132
121
  end
133
122
  end
@@ -65,16 +65,23 @@ module OpenHAB
65
65
  #
66
66
  # Send a command to this item
67
67
  #
68
+ # When this method is chained after the {OpenHAB::DSL::Items::Ensure::Ensurable#ensure ensure}
69
+ # method, or issued inside an {OpenHAB::DSL.ensure_states ensure_states} block,
70
+ # the command will only be sent if the item is not already in the same state.
71
+ #
68
72
  # @param [Command] command command to send to the item
69
- # @return [self]
73
+ # @return [self, nil] nil when `ensure` is in effect and the item was already in the same state,
74
+ # otherwise the item.
70
75
  #
71
- # @see DSL::Items::TimedCommand#command
76
+ # @see DSL::Items::TimedCommand#command Timed Command
77
+ # @see OpenHAB::DSL.ensure_states ensure_states
78
+ # @see DSL::Items::Ensure::Ensurable#ensure ensure
72
79
  #
73
80
  def command(command)
74
81
  command = format_command(command)
75
82
  logger.trace "Sending Command #{command} to #{name}"
76
- org.openhab.core.model.script.actions.BusEvent.sendCommand(self, command)
77
- self
83
+ $events.send_command(self, command)
84
+ Proxy.new(self)
78
85
  end
79
86
 
80
87
  # not an alias to allow easier stubbing and overriding
@@ -88,13 +95,14 @@ module OpenHAB
88
95
  # Send an update to this item
89
96
  #
90
97
  # @param [State] state
91
- # @return [self]
98
+ # @return [self, nil] nil when `ensure` is in effect and the item was already in the same state,
99
+ # otherwise the item.
92
100
  #
93
101
  def update(state)
94
102
  state = format_update(state)
95
103
  logger.trace "Sending Update #{state} to #{name}"
96
- org.openhab.core.model.script.actions.BusEvent.postUpdate(self, state)
97
- self
104
+ $events.post_update(self, state)
105
+ Proxy.new(self)
98
106
  end
99
107
 
100
108
  #
@@ -15,6 +15,8 @@ module OpenHAB
15
15
  #
16
16
  # @!attribute [rw] value
17
17
  # @return [String] The main value for the metadata namespace.
18
+ # @!attribute [r] namespace
19
+ # @return [String]
18
20
  #
19
21
  class Hash
20
22
  java_import org.openhab.core.items.Metadata
@@ -24,7 +26,7 @@ module OpenHAB
24
26
 
25
27
  extend Forwardable
26
28
  def_delegators :@metadata, :configuration, :hash, :to_s, :uid, :value
27
- protected :configuration
29
+ private :configuration
28
30
 
29
31
  # @!method to_hash
30
32
  # Implicit conversion to {::Hash}.
@@ -35,6 +37,9 @@ module OpenHAB
35
37
  # still others (mutators) must be manually implemented below.
36
38
  def_delegators :configuration,
37
39
  :any?,
40
+ :compact,
41
+ :compare_by_identity?,
42
+ :deconstruct_keys,
38
43
  :default,
39
44
  :default_proc,
40
45
  :each,
@@ -45,6 +50,8 @@ module OpenHAB
45
50
  :filter,
46
51
  :flatten,
47
52
  :has_value?,
53
+ :invert,
54
+ :key,
48
55
  :keys,
49
56
  :length,
50
57
  :rassoc,
@@ -55,8 +62,12 @@ module OpenHAB
55
62
  :to_a,
56
63
  :to_h,
57
64
  :to_hash,
65
+ :transform_keys,
66
+ :transform_values,
67
+ :values,
58
68
  :value?
59
- def_delegators :to_h, :invert, :merge, :transform_keys, :transform_values
69
+
70
+ def_delegator :uid, :namespace
60
71
 
61
72
  class << self
62
73
  # @!visibility private
@@ -72,7 +83,7 @@ module OpenHAB
72
83
 
73
84
  [value.first, (value.last || {}).transform_keys(&:to_s)]
74
85
  when ::Hash then ["", value.transform_keys(&:to_s)]
75
- else [value, {}]
86
+ else [value.to_s, {}]
76
87
  end
77
88
  new(Metadata.new(org.openhab.core.items.MetadataKey.new(namespace.to_s, item_name), *value))
78
89
  end
@@ -84,7 +95,7 @@ module OpenHAB
84
95
  end
85
96
 
86
97
  # @!visibility private
87
- def initialize(metadata)
98
+ def initialize(metadata = nil)
88
99
  @metadata = metadata
89
100
  end
90
101
 
@@ -108,13 +119,24 @@ module OpenHAB
108
119
  end
109
120
 
110
121
  # @!visibility private
111
- def create
112
- NamespaceHash.registry.add(@metadata) if attached?
122
+ def commit
123
+ return unless attached?
124
+
125
+ javaify
126
+ provider.update(@metadata)
113
127
  end
114
128
 
115
129
  # @!visibility private
116
- def commit
117
- NamespaceHash.registry.update(@metadata) if attached?
130
+ def create_or_update
131
+ return unless attached?
132
+
133
+ javaify
134
+ (p = provider).get(uid) ? p.update(@metadata) : p.add(@metadata)
135
+ end
136
+
137
+ # @!visibility private
138
+ def remove
139
+ provider.remove(uid)
118
140
  end
119
141
 
120
142
  # @!visibility private
@@ -141,7 +163,7 @@ module OpenHAB
141
163
  return false unless value == other.value
142
164
  end
143
165
 
144
- to_h < other
166
+ configuration < other
145
167
  end
146
168
 
147
169
  # @!visibility private
@@ -151,7 +173,7 @@ module OpenHAB
151
173
  return false unless value == other.value
152
174
  end
153
175
 
154
- to_h <= other
176
+ configuration <= other
155
177
  end
156
178
 
157
179
  # @!visibility private
@@ -161,7 +183,7 @@ module OpenHAB
161
183
 
162
184
  return configuration == other.configuration
163
185
  elsif value.empty? && other.respond_to?(:to_hash)
164
- return configuration.to_h == other.to_hash
186
+ return configuration == other.to_hash
165
187
  end
166
188
  false
167
189
  end
@@ -173,7 +195,7 @@ module OpenHAB
173
195
  return false unless value == other.value
174
196
  end
175
197
 
176
- to_h > other
198
+ configuration > other
177
199
  end
178
200
 
179
201
  # @!visibility private
@@ -183,7 +205,7 @@ module OpenHAB
183
205
  return false unless value == other.value
184
206
  end
185
207
 
186
- to_h >= other
208
+ configuration >= other
187
209
  end
188
210
 
189
211
  # @!visibility private
@@ -211,13 +233,9 @@ module OpenHAB
211
233
  replace({})
212
234
  end
213
235
 
214
- # @!visibility private
215
- alias_method :compact, :to_h
216
-
217
236
  # @!visibility private
218
237
  def compact!
219
- # no action; impossible to have nil keys
220
- self
238
+ replace(compact)
221
239
  end
222
240
 
223
241
  # @!visibility private
@@ -225,16 +243,6 @@ module OpenHAB
225
243
  raise NotImplementedError
226
244
  end
227
245
 
228
- # @!visibility private
229
- def compare_by_identity?
230
- false
231
- end
232
-
233
- # @!visibility private
234
- def deconstruct_keys
235
- self
236
- end
237
-
238
246
  # @!visibility private
239
247
  def default=(*)
240
248
  raise NotImplementedError
@@ -289,11 +297,6 @@ module OpenHAB
289
297
  self
290
298
  end
291
299
 
292
- # @!visibility private
293
- def key(value)
294
- rassoc(value)&.first
295
- end
296
-
297
300
  # @!visibility private
298
301
  def key?(key)
299
302
  configuration.key?(key.to_s)
@@ -345,7 +348,7 @@ module OpenHAB
345
348
 
346
349
  # @!visibility private
347
350
  def slice(*keys)
348
- to_h.slice(*keys.map(&:to_s))
351
+ configuration.slice(*keys.map(&:to_s))
349
352
  end
350
353
 
351
354
  # @!visibility private
@@ -365,11 +368,6 @@ module OpenHAB
365
368
  replace(transform_values(&block))
366
369
  end
367
370
 
368
- # @!visibility private
369
- def values
370
- configuration.values.to_a
371
- end
372
-
373
371
  # @!visibility private
374
372
  def values_at(*keys)
375
373
  configuration.values_at(*keys.map(&:to_s))
@@ -383,6 +381,50 @@ module OpenHAB
383
381
  [value, to_h].inspect
384
382
  end
385
383
  alias_method :to_s, :inspect
384
+
385
+ #
386
+ # @raise [RuntimeError] if the provider is not a
387
+ # {org.openhab.core.common.registry.ManagedProvider ManagedProvider} that can be updated.
388
+ # @return [org.openhab.core.common.registry.ManagedProvider]
389
+ #
390
+ def provider
391
+ preferred_provider = Provider.current(
392
+ Thread.current[:openhab_providers]&.dig(:metadata_items, uid.item_name) ||
393
+ Thread.current[:openhab_providers]&.dig(:metadata_namespaces, uid.namespace),
394
+ self
395
+ )
396
+
397
+ if attached?
398
+ provider = Provider.registry.provider_for(uid)
399
+ return preferred_provider unless provider
400
+
401
+ unless provider.is_a?(org.openhab.core.common.registry.ManagedProvider)
402
+ raise FrozenError, "Cannot modify metadata from provider #{provider.inspect}"
403
+ end
404
+
405
+ if preferred_provider != provider
406
+ logger.warn("Provider #{preferred_provider.inspect} cannot be used with #{uid}; " \
407
+ "reverting to provider #{provider.inspect}. " \
408
+ "This may cause unexpected issues, like metadata persisting that you did not expect to.")
409
+ preferred_provider = provider
410
+ end
411
+
412
+ end
413
+ preferred_provider
414
+ end
415
+
416
+ private
417
+
418
+ #
419
+ # @see https://github.com/openhab/openhab-core/issues/3169
420
+ #
421
+ # in the meantime, force the serialization round-trip right now
422
+ #
423
+ def javaify
424
+ mapper = Provider.registry.managed_provider.get.storage.entityMapper
425
+
426
+ @metadata = mapper.from_json(mapper.to_json_tree(@metadata), Metadata.java_class)
427
+ end
386
428
  end
387
429
  end
388
430
  end
@@ -96,12 +96,7 @@ module OpenHAB
96
96
  metadata = Hash.from_item(@item_name, namespace, value)
97
97
  return @hash[metadata.uid.namespace] = metadata unless attached? # rubocop:disable Lint/ReturnInVoidContext
98
98
 
99
- # registry.get can be omitted, but registry.update will log a warning for nonexistent metadata
100
- if self.class.registry.managed_provider.get.get(metadata.uid)
101
- metadata.commit
102
- else
103
- metadata.create
104
- end
99
+ metadata.create_or_update
105
100
  metadata # rubocop:disable Lint/Void
106
101
  end
107
102
  alias_method :store, :[]=
@@ -117,7 +112,11 @@ module OpenHAB
117
112
  # @!visibility private
118
113
  def clear
119
114
  if attached?
120
- self.class.registry.remove_item_metadata(@item_name)
115
+ provider = Provider.current(Thread.current[:openhab_providers]&.dig(:metadata_items, @item_name))
116
+ provider.remove_item_metadata(@item_name)
117
+ Thread.current[:openhab_providers]&.[](:metadata_namespaces)&.each_value do |namespace_provider|
118
+ Provider.current(namespace_provider).remove_item_metadata(@item_name)
119
+ end
121
120
  else
122
121
  @hash.clear
123
122
  end
@@ -171,11 +170,10 @@ module OpenHAB
171
170
 
172
171
  # @!visibility private
173
172
  def delete(namespace, &block)
174
- namespace = namespace.to_s
175
-
176
- return @hash.delete(namespace, &block) unless attached?
173
+ return @hash.delete(namespace.to_s, &block) unless attached?
177
174
 
178
- r = self.class.registry.remove(MetadataKey.new(namespace, @item_name))
175
+ metadata = Hash.from_item(@item_name, namespace, nil)
176
+ r = metadata.remove
179
177
  return yield(namespace) if block && !r
180
178
 
181
179
  Hash.new(r) if r
@@ -208,7 +206,7 @@ module OpenHAB
208
206
  return @hash.each(&block) unless attached?
209
207
  return to_enum(:each) unless block
210
208
 
211
- self.class.registry.all.each do |meta|
209
+ Provider.registry.all.each do |meta|
212
210
  yield meta.uid.namespace, Hash.new(meta) if meta.uid.item_name == @item_name
213
211
  end
214
212
  self
@@ -220,7 +218,7 @@ module OpenHAB
220
218
  return @hash.each_key(&block) unless attached?
221
219
  return to_enum(:each_key) unless block
222
220
 
223
- self.class.registry.all.each do |meta|
221
+ Provider.registry.all.each do |meta|
224
222
  yield meta.uid.namespace if meta.uid.item_name == @item_name
225
223
  end
226
224
  self
@@ -231,7 +229,7 @@ module OpenHAB
231
229
  return @hash.each_value(&block) unless attached?
232
230
  return to_enum(:each_value) unless block_given?
233
231
 
234
- self.class.registry.all.each do |meta|
232
+ Provider.registry.all.each do |meta|
235
233
  yield Hash.new(meta) if meta.uid.item_name == @item_name
236
234
  end
237
235
  self
@@ -241,7 +239,7 @@ module OpenHAB
241
239
  def empty?
242
240
  return @hash.empty? unless attached?
243
241
 
244
- self.class.registry.all.each do |meta|
242
+ Provider.registry.all.each do |meta|
245
243
  return false if meta.uid.item_name == @item_name
246
244
  end
247
245
  true
@@ -263,7 +261,7 @@ module OpenHAB
263
261
  end
264
262
 
265
263
  logger.trace("Getting metadata for item: #{@item_name}, namespace '#{key}'")
266
- if (m = self.class.registry.get(MetadataKey.new(key, @item_name)))
264
+ if (m = Provider.registry.get(MetadataKey.new(key, @item_name)))
267
265
  Hash.new(m)
268
266
  elsif block
269
267
  yield key
@@ -280,7 +278,7 @@ module OpenHAB
280
278
 
281
279
  keys.each_with_object([]) do |key, res|
282
280
  key = key.to_s
283
- if (m = self.class.registry.get(MetadataKey.new(key, @item_name)))
281
+ if (m = Provider.registry.get(MetadataKey.new(key, @item_name)))
284
282
  res << Hash.new(m)
285
283
  elsif block_given?
286
284
  res << yield(key)
@@ -307,7 +305,7 @@ module OpenHAB
307
305
  key = key.to_s
308
306
  return @hash.key?(key) unless attached?
309
307
 
310
- !self.class.registry.get(MetadataKey.new(key, @item_name)).nil?
308
+ !Provider.registry.get(MetadataKey.new(key, @item_name)).nil?
311
309
  end
312
310
  alias_method :has_key?, :key?
313
311
  alias_method :member?, :key?
@@ -373,7 +371,7 @@ module OpenHAB
373
371
 
374
372
  keys = keys.to_set
375
373
  r = {}
376
- self.class.registry.all.each do |meta|
374
+ Provider.registry.all.each do |meta|
377
375
  if meta.uid.item_name == @item_name && keys.include?(meta.uid.namespace)
378
376
  r[meta.uid.namespace] =
379
377
  Hash.new(meta)
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module Core
5
+ module Items
6
+ module Metadata
7
+ #
8
+ # Provides metadata created in Ruby to openHAB
9
+ #
10
+ class Provider < Core::Provider
11
+ include org.openhab.core.items.ManagedMetadataProvider
12
+
13
+ class << self
14
+ #
15
+ # The Metadata registry
16
+ #
17
+ # @return [org.openhab.core.items.MetadataRegistry]
18
+ #
19
+ def registry
20
+ @registry ||= OSGi.service("org.openhab.core.items.MetadataRegistry")
21
+ end
22
+ end
23
+
24
+ # see Hash#javaify
25
+ registry.managed_provider.get.class.field_reader :storage
26
+ registry.managed_provider.get.storage.class.field_reader :entityMapper
27
+
28
+ #
29
+ # Removes all metadata of a given item.
30
+ #
31
+ # @param [String] item_name
32
+ # @return [void]
33
+ #
34
+ def remove_item_metadata(item_name)
35
+ @elements.delete_if do |k, v|
36
+ next unless k.item_name == item_name
37
+
38
+ notify_listeners_about_removed_element(v)
39
+ true
40
+ end
41
+ nil
42
+ end
43
+ alias_method :removeItemMetadata, :remove_item_metadata
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "delegate"
4
+
3
5
  require_relative "generic_item"
4
6
 
5
7
  module OpenHAB
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module Core
5
+ module Items
6
+ #
7
+ # Provides {GenericItem Items} created in Ruby to openHAB
8
+ #
9
+ class Provider < Core::Provider
10
+ include org.openhab.core.items.ItemProvider
11
+
12
+ class << self
13
+ #
14
+ # The Item registry
15
+ #
16
+ # @return [org.openhab.core.items.ItemRegistry]
17
+ #
18
+ def registry
19
+ $ir
20
+ end
21
+ end
22
+
23
+ #
24
+ # Remove an item from this provider
25
+ #
26
+ # @param [String] item_name
27
+ # @param [true, false] recursive
28
+ # @return [GenericItem, nil] The removed item, if found.
29
+ #
30
+ def remove(item_name, recursive = false) # rubocop:disable Style/OptionalBooleanParameter matches Java method
31
+ return nil unless @elements.key?(item_name)
32
+
33
+ item = super(item_name)
34
+ item.members.each { |member| remove(member.name, true) } if recursive && item.is_a?(GroupItem)
35
+ item
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -53,6 +53,16 @@ module OpenHAB
53
53
 
54
54
  super
55
55
  end
56
+
57
+ #
58
+ # Non equality comparison
59
+ #
60
+ # @return [true, false]
61
+ #
62
+ # @!visibility private
63
+ def !=(other)
64
+ !(self == other) # rubocop:disable Style/InverseMethods
65
+ end
56
66
  end
57
67
  end
58
68
  end
@@ -32,6 +32,8 @@ module OpenHAB
32
32
  !$ir.getItems(name).empty?
33
33
  end
34
34
  alias_method :include?, :key?
35
+ # @deprecated
36
+ alias_method :has_key?, :key?
35
37
 
36
38
  # Explicit conversion to array
37
39
  # @return [Array]
@@ -39,26 +41,33 @@ module OpenHAB
39
41
  $ir.items.map { |item| Proxy.new(item) }
40
42
  end
41
43
 
44
+ #
42
45
  # Enter the Item Builder DSL.
46
+ #
47
+ # @param (see Core::Provider.current)
43
48
  # @yield Block executed in the context of a {DSL::Items::Builder}
44
49
  # @return [Object] The return value of the block.
45
- def build(&block)
46
- DSL::Items::BaseBuilderDSL.new.instance_eval(&block)
50
+ #
51
+ def build(preferred_provider = nil, &block)
52
+ DSL::Items::BaseBuilderDSL.new(preferred_provider).instance_eval(&block)
47
53
  end
48
54
 
55
+ #
49
56
  # Remove an item.
50
57
  #
51
- # The item must have either been created by this script, or be a
52
- # managed item (typically created in the UI).
58
+ # The item must be a managed item (typically created by Ruby or in the UI).
53
59
  #
60
+ # @param [String, GenericItem] item_name
54
61
  # @param recursive [true, false] Remove the item's members if it's a group
55
62
  # @return [GenericItem, nil] The removed item, if found.
56
63
  def remove(item_name, recursive: false)
57
64
  item_name = item_name.name if item_name.is_a?(GenericItem)
58
- result = DSL::Items::ItemProvider.instance.remove(item_name, recursive: recursive)
59
- return result if result
65
+ provider = Provider.registry.provider_for(item_name)
66
+ unless provider.is_a?(org.openhab.core.common.registry.ManagedProvider)
67
+ raise "Cannot remove item #{item_name} from non-managed provider #{provider.inspect}"
68
+ end
60
69
 
61
- $ir.remove(item_name, recursive)
70
+ provider.remove(item_name, recursive)
62
71
  end
63
72
  end
64
73
  end
@@ -72,15 +72,17 @@ module Enumerable
72
72
  # @!group Items State and Command Methods
73
73
 
74
74
  # Send a command to every item in the collection
75
- # @return [self]
75
+ # @return [self, nil] nil when `ensure` is in effect and all the items were already in the same state,
76
+ # otherwise self
76
77
  def command(command)
77
- each { |i| i.command(command) }
78
+ self if count { |i| i.command(command) }.positive?
78
79
  end
79
80
 
80
81
  # Update the state of every item in the collection
81
- # @return [self]
82
+ # @return [self, nil] nil when `ensure` is in effect and all the items were already in the same state,
83
+ # otherwise self
82
84
  def update(state)
83
- each { |i| i.update(state) }
85
+ self if count { |i| i.update(state) }.positive?
84
86
  end
85
87
 
86
88
  # @!method refresh
@@ -18,7 +18,7 @@ module OpenHAB
18
18
  #
19
19
  # @!visibility private
20
20
  def self.from_items(*items)
21
- StateStorage.new(org.openhab.core.model.script.actions.BusEvent.store_states(*items).to_h)
21
+ StateStorage.new($events.store_states(*items).to_h)
22
22
  end
23
23
 
24
24
  #
@@ -27,7 +27,7 @@ module OpenHAB
27
27
  # @return [void]
28
28
  #
29
29
  def restore
30
- org.openhab.core.model.script.actions.BusEvent.restore_states(to_h)
30
+ $events.restore_states(to_h)
31
31
  end
32
32
 
33
33
  #
@@ -36,7 +36,7 @@ module OpenHAB
36
36
  # @return [void]
37
37
  #
38
38
  def restore_changes
39
- org.openhab.core.model.script.actions.BusEvent.restore_states(select { |item, value| item.state != value })
39
+ $events.restore_states(select { |item, value| item.state != value })
40
40
  end
41
41
 
42
42
  #
@@ -87,6 +87,8 @@ module OpenHAB
87
87
  DSL::ThreadLocal.thread_local(**@thread_locals) do
88
88
  @block.call(event, **kwargs)
89
89
  rescue Exception => e
90
+ raise if defined?(::RSpec)
91
+
90
92
  @block.binding.eval("self").logger.log_exception(e)
91
93
  end
92
94
  end
@@ -113,6 +115,6 @@ module OpenHAB
113
115
  end
114
116
 
115
117
  registration = OSGi.register_service(ProfileFactory.instance)
116
- ScriptHandlingCallbacks.script_unloaded_hooks << -> { registration.unregister }
118
+ ScriptHandling.script_unloaded { registration.unregister }
117
119
  end
118
120
  end