openhab-scripting 5.13.0 → 5.15.0
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.
- checksums.yaml +4 -4
- data/lib/openhab/core/items/item.rb +67 -20
- data/lib/openhab/core/items/semantics/enumerable.rb +8 -0
- data/lib/openhab/core/sitemaps/provider.rb +24 -2
- data/lib/openhab/core/things/item_channel_link.rb +7 -0
- data/lib/openhab/dsl/sitemaps/builder.rb +55 -34
- data/lib/openhab/dsl/version.rb +1 -1
- data/lib/openhab/osgi.rb +35 -4
- data/lib/openhab/rspec/helpers.rb +60 -42
- data/lib/openhab/rspec/hooks.rb +4 -4
- data/lib/openhab/rspec/karaf.rb +4 -0
- data/lib/openhab/rspec/mocks/abstract_storage_based_type_provider_wrapped_storage_service.rb +24 -0
- data/lib/openhab/rspec/mocks/thing_handler.rb +7 -1
- data/lib/openhab/rspec/mocks/timer.rb +36 -0
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 11409728d3f0ecb384da9099355fea4728020aa1de1d494d3085dddea518e16c
|
|
4
|
+
data.tar.gz: d4daa321f0b779b0c9f47ccc405cdafd3a71f55666e173cb29315a7f948b2029
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b8eee772f02cf086af4db419ecaa5752b21393302533f6fea628a6e9bc50d7e986b1815e03c71de7acba63a13088f46d3e73e96d416a1869a7e2b9fe627764ea
|
|
7
|
+
data.tar.gz: 4ebdb8fb5d81c4429188163e4ced5aabf2ee8a33797b540a32e0e81024a67ac7143728b7679181ca26a4856f8e7e6ed291b5f4bb9427c1df2a744eb6fcb75dd1
|
|
@@ -252,10 +252,10 @@ module OpenHAB
|
|
|
252
252
|
end
|
|
253
253
|
|
|
254
254
|
# @!attribute thing [r]
|
|
255
|
-
# Return the item's thing if this item is linked with a thing. If an item is linked to more than one
|
|
255
|
+
# Return the item's thing if this item is linked with a thing. If an item is linked to more than one channel,
|
|
256
256
|
# this method only returns the first thing.
|
|
257
257
|
#
|
|
258
|
-
# @return [Thing
|
|
258
|
+
# @return [Things::Thing, nil]
|
|
259
259
|
def thing
|
|
260
260
|
all_linked_things.first
|
|
261
261
|
end
|
|
@@ -264,12 +264,46 @@ module OpenHAB
|
|
|
264
264
|
# @!attribute things [r]
|
|
265
265
|
# Returns all of the item's linked things.
|
|
266
266
|
#
|
|
267
|
-
# @return [Array<Thing>] An array of things or an empty array
|
|
267
|
+
# @return [Array<Things::Thing>] An array of things or an empty array
|
|
268
268
|
def things
|
|
269
269
|
Things::Links::Provider.registry.get_bound_things(name).map { |thing| Things::Proxy.new(thing) }
|
|
270
270
|
end
|
|
271
271
|
alias_method :all_linked_things, :things
|
|
272
272
|
|
|
273
|
+
# @!attribute channel_uid [r]
|
|
274
|
+
# Return the UID of the channel this item is linked to. If an item is linked to more than one channel,
|
|
275
|
+
# this method only returns the first channel.
|
|
276
|
+
#
|
|
277
|
+
# @return [Things::ChannelUID, nil]
|
|
278
|
+
def channel_uid
|
|
279
|
+
channel_uids.first
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
# @!attribute channel_uids [r]
|
|
283
|
+
# Return the UIDs of all of the channels this item is linked to.
|
|
284
|
+
#
|
|
285
|
+
# @return [Array<Things::ChannelUID>]
|
|
286
|
+
def channel_uids
|
|
287
|
+
Things::Links::Provider.registry.get_bound_channels(name)
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
# @!attribute channel [r]
|
|
291
|
+
# Return the the channel this item is linked to. If an item is linked to more than one channel,
|
|
292
|
+
# this method only returns the first channel.
|
|
293
|
+
#
|
|
294
|
+
# @return [Things::Channel, nil]
|
|
295
|
+
def channel
|
|
296
|
+
channel_uids.first&.channel
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
# @!attribute channels [r]
|
|
300
|
+
# Return all of the channels this item is linked to.
|
|
301
|
+
#
|
|
302
|
+
# @return [Array<Things::Channel>]
|
|
303
|
+
def channels
|
|
304
|
+
channel_uids.map(&:channel)
|
|
305
|
+
end
|
|
306
|
+
|
|
273
307
|
#
|
|
274
308
|
# @!attribute links [r]
|
|
275
309
|
# Returns all of the item's links (channels and link configurations).
|
|
@@ -290,30 +324,43 @@ module OpenHAB
|
|
|
290
324
|
end
|
|
291
325
|
|
|
292
326
|
#
|
|
293
|
-
#
|
|
327
|
+
# @return [Things::ItemChannelLink, nil]
|
|
294
328
|
#
|
|
295
|
-
# @
|
|
296
|
-
#
|
|
329
|
+
# @overload link
|
|
330
|
+
# Returns the item's link. If an item is linked to more than one channel,
|
|
331
|
+
# this method only returns the first link.
|
|
297
332
|
#
|
|
298
|
-
#
|
|
333
|
+
# @return [Things::ItemChannelLink, nil]
|
|
299
334
|
#
|
|
300
|
-
# @
|
|
301
|
-
# LivingRoom_Light_Power.link("mqtt:topic:livingroom-light:power")
|
|
335
|
+
# @overload link(channel, config = {})
|
|
302
336
|
#
|
|
303
|
-
#
|
|
304
|
-
# LivingRoom_Light_Power.link(things["mqtt:topic:livingroom-light"].channels["power"])
|
|
337
|
+
# Links the item to a channel.
|
|
305
338
|
#
|
|
306
|
-
#
|
|
307
|
-
#
|
|
308
|
-
# "mqtt:topic:outdoor-thermometer:temperature",
|
|
309
|
-
# profile: "system:hysteresis",
|
|
310
|
-
# lower: "29 °C",
|
|
311
|
-
# upper: "30 °C")
|
|
339
|
+
# @param [String, Things::Channel, Things::ChannelUID] channel The channel to link to.
|
|
340
|
+
# @param [Hash] config The configuration for the link.
|
|
312
341
|
#
|
|
313
|
-
#
|
|
314
|
-
#
|
|
342
|
+
# @return [Things::ItemChannelLink] The created link.
|
|
343
|
+
#
|
|
344
|
+
# @example Link an item to a channel
|
|
345
|
+
# LivingRoom_Light_Power.link("mqtt:topic:livingroom-light:power")
|
|
315
346
|
#
|
|
316
|
-
|
|
347
|
+
# @example Link to a Thing's channel
|
|
348
|
+
# LivingRoom_Light_Power.link(things["mqtt:topic:livingroom-light"].channels["power"])
|
|
349
|
+
#
|
|
350
|
+
# @example Specify a link configuration
|
|
351
|
+
# High_Temperature_Alert.link(
|
|
352
|
+
# "mqtt:topic:outdoor-thermometer:temperature",
|
|
353
|
+
# profile: "system:hysteresis",
|
|
354
|
+
# lower: "29 °C",
|
|
355
|
+
# upper: "30 °C")
|
|
356
|
+
#
|
|
357
|
+
# @see links
|
|
358
|
+
# @see unlink
|
|
359
|
+
#
|
|
360
|
+
def link(channel = nil, config = nil)
|
|
361
|
+
return Things::Links::Provider.registry.get_links(name).first if channel.nil? && config.nil?
|
|
362
|
+
|
|
363
|
+
config ||= {}
|
|
317
364
|
Core::Things::Links::Provider.create_link(self, channel, config).tap do |new_link|
|
|
318
365
|
provider = Core::Things::Links::Provider.current
|
|
319
366
|
if !(current_link = provider.get(new_link.uid))
|
|
@@ -63,7 +63,7 @@ module OpenHAB
|
|
|
63
63
|
#
|
|
64
64
|
# @example
|
|
65
65
|
# sitemaps.build do
|
|
66
|
-
# sitemap "default", "My Residence" do
|
|
66
|
+
# sitemap "default", label: "My Residence" do
|
|
67
67
|
# frame label: "Control" do
|
|
68
68
|
# text label: "Climate", icon: "if:mdi:home-thermometer-outline" do
|
|
69
69
|
# frame label: "Main Floor" do
|
|
@@ -112,8 +112,30 @@ module OpenHAB
|
|
|
112
112
|
# end
|
|
113
113
|
# end
|
|
114
114
|
#
|
|
115
|
+
# @example
|
|
116
|
+
# def add_tv(builder, tv)
|
|
117
|
+
# builder.frame label: tv.location.label do
|
|
118
|
+
# builder.switch item: tv.points(Semantics::Switch), label: "Power"
|
|
119
|
+
# end
|
|
120
|
+
# end
|
|
121
|
+
#
|
|
122
|
+
# sitemaps.build do |builder|
|
|
123
|
+
# builder.sitemap "tvs", label: "TVs" do
|
|
124
|
+
# items.equipments(Semantics::TV).each do |tv|
|
|
125
|
+
# add_tv(builder, tv)
|
|
126
|
+
# end
|
|
127
|
+
# end
|
|
128
|
+
# end
|
|
129
|
+
#
|
|
115
130
|
def build(update: true, &block)
|
|
116
|
-
|
|
131
|
+
builder_proxy = SimpleDelegator.new(nil) if block.arity == 1
|
|
132
|
+
builder = DSL::Sitemaps::Builder.new(self, builder_proxy, update: update)
|
|
133
|
+
if block.arity == 1
|
|
134
|
+
builder_proxy.__setobj__(builder)
|
|
135
|
+
yield builder_proxy
|
|
136
|
+
else
|
|
137
|
+
builder.instance_eval(&block)
|
|
138
|
+
end
|
|
117
139
|
end
|
|
118
140
|
|
|
119
141
|
# For use in specs
|
|
@@ -33,6 +33,13 @@ module OpenHAB
|
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
alias_method :channel_uid, :linked_uid
|
|
36
|
+
|
|
37
|
+
# @return [String]
|
|
38
|
+
def inspect
|
|
39
|
+
r = "#<OpenHAB::Core::Things::ItemChannelLink item_name=#{item_name} channel_uid=#{channel_uid}"
|
|
40
|
+
r += " configuration=#{configuration.properties.to_h}" unless configuration.properties.empty?
|
|
41
|
+
"#{r}>"
|
|
42
|
+
end
|
|
36
43
|
end
|
|
37
44
|
end
|
|
38
45
|
end
|
|
@@ -12,18 +12,19 @@ module OpenHAB
|
|
|
12
12
|
# Base sitemap builder DSL
|
|
13
13
|
class Builder
|
|
14
14
|
# @!visibility private
|
|
15
|
-
def initialize(provider, update:)
|
|
15
|
+
def initialize(provider, builder_proxy, update:)
|
|
16
16
|
@provider = provider
|
|
17
|
+
@builder_proxy = builder_proxy
|
|
17
18
|
@update = update
|
|
18
19
|
end
|
|
19
20
|
|
|
20
21
|
# (see SitemapBuilder#initialize)
|
|
22
|
+
# @!method sitemap(name, label: nil, icon: nil, &block)
|
|
21
23
|
# @yield Block executed in the context of a {SitemapBuilder}
|
|
22
24
|
# @return [SitemapBuilder]
|
|
23
25
|
# @!visibility public
|
|
24
|
-
def sitemap(name, label
|
|
25
|
-
sitemap = SitemapBuilder.new(name, label, icon: icon)
|
|
26
|
-
sitemap.instance_eval_with_dummy_items(&block) if block
|
|
26
|
+
def sitemap(name, label: nil, icon: nil, &block)
|
|
27
|
+
sitemap = SitemapBuilder.new(name, @builder_proxy, label: label, icon: icon, &block)
|
|
27
28
|
sitemap = sitemap.build
|
|
28
29
|
if @update && @provider.get(sitemap.uid)
|
|
29
30
|
@provider.update(sitemap)
|
|
@@ -105,6 +106,7 @@ module OpenHAB
|
|
|
105
106
|
# One or more visibility rules (see {#visibility})
|
|
106
107
|
# @!visibility private
|
|
107
108
|
def initialize(type,
|
|
109
|
+
builder_proxy,
|
|
108
110
|
item: nil,
|
|
109
111
|
label: nil,
|
|
110
112
|
icon: nil,
|
|
@@ -112,13 +114,15 @@ module OpenHAB
|
|
|
112
114
|
label_color: nil,
|
|
113
115
|
value_color: nil,
|
|
114
116
|
icon_color: nil,
|
|
115
|
-
visibility: nil
|
|
117
|
+
visibility: nil,
|
|
118
|
+
&block)
|
|
116
119
|
unless SitemapBuilder.factory.respond_to?("create_#{type}")
|
|
117
120
|
raise ArgumentError,
|
|
118
121
|
"#{type} is not a valid widget type"
|
|
119
122
|
end
|
|
120
123
|
|
|
121
124
|
@type = type
|
|
125
|
+
@builder_proxy = builder_proxy
|
|
122
126
|
@item = item
|
|
123
127
|
@label = label
|
|
124
128
|
@icon = icon
|
|
@@ -132,6 +136,20 @@ module OpenHAB
|
|
|
132
136
|
self.value_color(value_color) if value_color
|
|
133
137
|
self.icon_color(icon_color) if icon_color
|
|
134
138
|
self.visibility(*visibility) if visibility
|
|
139
|
+
|
|
140
|
+
return unless block
|
|
141
|
+
|
|
142
|
+
@builder_proxy ||= SimpleDelegator.new(nil) if block.arity == 1
|
|
143
|
+
|
|
144
|
+
if @builder_proxy
|
|
145
|
+
old_obj = @builder_proxy.__getobj__
|
|
146
|
+
@builder_proxy.__setobj__(self)
|
|
147
|
+
yield @builder_proxy
|
|
148
|
+
else
|
|
149
|
+
instance_eval_with_dummy_items(&block)
|
|
150
|
+
end
|
|
151
|
+
ensure
|
|
152
|
+
@builder_proxy&.__setobj__(old_obj)
|
|
135
153
|
end
|
|
136
154
|
|
|
137
155
|
# Adds one or more new rules for setting the label color
|
|
@@ -271,8 +289,8 @@ module OpenHAB
|
|
|
271
289
|
# @!method initialize(item: nil, label: nil, icon: nil, static_icon: nil, mappings: nil, label_color: nil, value_color: nil, icon_color: nil, visibility: nil)
|
|
272
290
|
# @param mappings [Hash, Array, nil] Mappings from command to label (see {SwitchBuilder#mappings})
|
|
273
291
|
# @!visibility private
|
|
274
|
-
def initialize(type, mappings: nil, **kwargs)
|
|
275
|
-
super(type, **kwargs)
|
|
292
|
+
def initialize(type, builder_proxy, mappings: nil, **kwargs, &block)
|
|
293
|
+
super(type, builder_proxy, **kwargs, &block)
|
|
276
294
|
|
|
277
295
|
@mappings = mappings
|
|
278
296
|
end
|
|
@@ -312,8 +330,8 @@ module OpenHAB
|
|
|
312
330
|
# @param range [Range, nil] Allowed range of the value (see {SetpointBuilder#range})
|
|
313
331
|
# @param step [Numeric,nil] How far the value will change with each button press (see {SetpointBuilder#step})
|
|
314
332
|
# @!visibility private
|
|
315
|
-
def initialize(type, range: nil, step: nil, **kwargs)
|
|
316
|
-
super(type, **kwargs)
|
|
333
|
+
def initialize(type, builder_proxy, range: nil, step: nil, **kwargs, &block)
|
|
334
|
+
super(type, builder_proxy, **kwargs, &block)
|
|
317
335
|
|
|
318
336
|
@range = range
|
|
319
337
|
@step = step
|
|
@@ -348,8 +366,8 @@ module OpenHAB
|
|
|
348
366
|
# @param frequency [Numeric, nil]
|
|
349
367
|
# How often to send requests (in seconds) (see {SliderBuilder#frequency})
|
|
350
368
|
# @!visibility private
|
|
351
|
-
def initialize(type, switch: nil, frequency: nil, **kwargs)
|
|
352
|
-
super(type, **kwargs)
|
|
369
|
+
def initialize(type, builder_proxy, switch: nil, frequency: nil, **kwargs, &block)
|
|
370
|
+
super(type, builder_proxy, **kwargs, &block)
|
|
353
371
|
|
|
354
372
|
@switch = switch
|
|
355
373
|
@frequency = frequency
|
|
@@ -387,8 +405,8 @@ module OpenHAB
|
|
|
387
405
|
# @param [String, nil] url (see {VideoBuilder#url})
|
|
388
406
|
# @param [:mjpeg, :hls, nil] encoding (see {VideoBuilder#encoding})
|
|
389
407
|
# @!visibility private
|
|
390
|
-
def initialize(type, url: nil, encoding: nil, **kwargs)
|
|
391
|
-
super(type, **kwargs)
|
|
408
|
+
def initialize(type, builder_proxy, url: nil, encoding: nil, **kwargs, &block)
|
|
409
|
+
super(type, builder_proxy, **kwargs, &block)
|
|
392
410
|
|
|
393
411
|
@url = url
|
|
394
412
|
self.encoding = encoding
|
|
@@ -456,14 +474,16 @@ module OpenHAB
|
|
|
456
474
|
# Formatting string for values on the y axis (see {ChartBuilder#y_axis_pattern})
|
|
457
475
|
# @!visibility private
|
|
458
476
|
def initialize(type,
|
|
477
|
+
builder_proxy,
|
|
459
478
|
service: nil,
|
|
460
479
|
refresh: nil,
|
|
461
480
|
period: nil,
|
|
462
481
|
legend: nil,
|
|
463
482
|
group: nil,
|
|
464
483
|
y_axis_pattern: nil,
|
|
465
|
-
**kwargs
|
|
466
|
-
|
|
484
|
+
**kwargs,
|
|
485
|
+
&block)
|
|
486
|
+
super(type, builder_proxy, **kwargs, &block)
|
|
467
487
|
|
|
468
488
|
@service = service
|
|
469
489
|
self.refresh = refresh
|
|
@@ -513,8 +533,8 @@ module OpenHAB
|
|
|
513
533
|
# @!method initialize(item: nil, label: nil, icon: nil, static_icon: nil, height: nil, label_color: nil, value_color: nil, icon_color: nil, visibility: nil)
|
|
514
534
|
# @param height [Integer] The number of element rows to fill (see {DefaultBuilder#height})
|
|
515
535
|
# @!visibility private
|
|
516
|
-
def initialize(type, height: nil, **kwargs)
|
|
517
|
-
super(type, **kwargs)
|
|
536
|
+
def initialize(type, builder_proxy, height: nil, **kwargs, &block)
|
|
537
|
+
super(type, builder_proxy, **kwargs, &block)
|
|
518
538
|
|
|
519
539
|
@height = height
|
|
520
540
|
end
|
|
@@ -538,8 +558,8 @@ module OpenHAB
|
|
|
538
558
|
# @!method initialize(item: nil, label: nil, icon: nil, static_icon: nil, url: nil, height: nil, label_color: nil, value_color: nil, icon_color: nil, visibility: nil)
|
|
539
559
|
# @param url [String, nil] (see {WebviewBuilder#url})
|
|
540
560
|
# @!visibility private
|
|
541
|
-
def initialize(type, url: nil, **kwargs)
|
|
542
|
-
super(type, **kwargs)
|
|
561
|
+
def initialize(type, builder_proxy, url: nil, **kwargs, &block)
|
|
562
|
+
super(type, builder_proxy, **kwargs, &block)
|
|
543
563
|
|
|
544
564
|
@url = url
|
|
545
565
|
end
|
|
@@ -564,8 +584,8 @@ module OpenHAB
|
|
|
564
584
|
# @!method initialize(item: nil, label: nil, icon: nil, static_icon: nil, frequency: nil, label_color: nil, value_color: nil, icon_color: nil, visibility: nil)
|
|
565
585
|
# @param frequency [Numeric, nil] How often to send requests (see {ColorpickerBuilder#frequency})
|
|
566
586
|
# @!visibility private
|
|
567
|
-
def initialize(type, frequency: nil, **kwargs)
|
|
568
|
-
super(type, **kwargs)
|
|
587
|
+
def initialize(type, builder_proxy, frequency: nil, **kwargs, &block)
|
|
588
|
+
super(type, builder_proxy, **kwargs, &block)
|
|
569
589
|
|
|
570
590
|
@frequency = frequency
|
|
571
591
|
end
|
|
@@ -600,8 +620,8 @@ module OpenHAB
|
|
|
600
620
|
# @param [:text, :number, :date, :time, :datetime, nil] hint
|
|
601
621
|
# Gives a hint to the user interface to use a widget adapted to a specific use (see {InputBuilder#hint})
|
|
602
622
|
# @!visibility private
|
|
603
|
-
def initialize(type, hint: nil, **kwargs)
|
|
604
|
-
super(type, **kwargs)
|
|
623
|
+
def initialize(type, builder_proxy, hint: nil, **kwargs, &block)
|
|
624
|
+
super(type, builder_proxy, **kwargs, &block)
|
|
605
625
|
|
|
606
626
|
self.hint = hint
|
|
607
627
|
end
|
|
@@ -657,10 +677,10 @@ module OpenHAB
|
|
|
657
677
|
#
|
|
658
678
|
# @see https://www.openhab.org/docs/ui/sitemaps.html#element-type-buttongrid
|
|
659
679
|
# @!visibility private
|
|
660
|
-
def initialize(type, buttons: [], **kwargs)
|
|
661
|
-
super(type, **kwargs)
|
|
662
|
-
buttons.each { |button| validate_button(button) }
|
|
680
|
+
def initialize(type, builder_proxy, buttons: [], **kwargs, &block)
|
|
663
681
|
@buttons = buttons
|
|
682
|
+
super(type, builder_proxy, **kwargs, &block)
|
|
683
|
+
buttons.each { |button| validate_button(button) }
|
|
664
684
|
end
|
|
665
685
|
|
|
666
686
|
#
|
|
@@ -997,9 +1017,10 @@ module OpenHAB
|
|
|
997
1017
|
class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
|
998
1018
|
def #{method}(*args, **kwargs, &block) # def frame(*args, **kwargs, &block)
|
|
999
1019
|
widget = #{method.capitalize}Builder.new(#{method.inspect}, # widget = FrameBuilder.new(:frame,
|
|
1020
|
+
@builder_proxy, # @builder_proxy,
|
|
1000
1021
|
*args, # *args,
|
|
1001
|
-
**kwargs
|
|
1002
|
-
|
|
1022
|
+
**kwargs, # **kwargs,
|
|
1023
|
+
&block) # &block)
|
|
1003
1024
|
children << widget # children << widget
|
|
1004
1025
|
widget # widget
|
|
1005
1026
|
end # end
|
|
@@ -1010,9 +1031,9 @@ module OpenHAB
|
|
|
1010
1031
|
# @!method initialize(item: nil, label: nil, icon: nil, static_icon: nil, label_color: nil, value_color: nil, icon_color: nil, visibility: nil)
|
|
1011
1032
|
# @!visibility private
|
|
1012
1033
|
def initialize(*, **)
|
|
1013
|
-
super
|
|
1014
|
-
|
|
1015
1034
|
@children = []
|
|
1035
|
+
|
|
1036
|
+
super
|
|
1016
1037
|
end
|
|
1017
1038
|
|
|
1018
1039
|
# @!visibility private
|
|
@@ -1061,8 +1082,8 @@ module OpenHAB
|
|
|
1061
1082
|
# @param url [String, nil] The URL for the image (see {ImageBuilder#url})
|
|
1062
1083
|
# @param refresh [Numeric, nil] How often to refresh the image (see {ImageBuilder#refresh})
|
|
1063
1084
|
# @!visibility private
|
|
1064
|
-
def initialize(type, url: nil, refresh: nil, **kwargs)
|
|
1065
|
-
super(type, **kwargs)
|
|
1085
|
+
def initialize(type, builder_proxy, url: nil, refresh: nil, **kwargs, &block)
|
|
1086
|
+
super(type, builder_proxy, **kwargs, &block)
|
|
1066
1087
|
|
|
1067
1088
|
@url = url
|
|
1068
1089
|
@refresh = refresh
|
|
@@ -1110,8 +1131,8 @@ module OpenHAB
|
|
|
1110
1131
|
# @param label [String, nil]
|
|
1111
1132
|
# @param icon [String, nil]
|
|
1112
1133
|
# @!visibility private
|
|
1113
|
-
def initialize(name, label
|
|
1114
|
-
super(:sitemap, label: label, icon: icon)
|
|
1134
|
+
def initialize(name, builder_proxy, label: nil, icon: nil)
|
|
1135
|
+
super(:sitemap, builder_proxy, label: label, icon: icon)
|
|
1115
1136
|
|
|
1116
1137
|
@name = name
|
|
1117
1138
|
end
|
data/lib/openhab/dsl/version.rb
CHANGED
data/lib/openhab/osgi.rb
CHANGED
|
@@ -33,20 +33,25 @@ module OpenHAB
|
|
|
33
33
|
# Register a new service instance with OSGi
|
|
34
34
|
#
|
|
35
35
|
# @param [Object] instance The service instance
|
|
36
|
-
# @param [Module] interfaces The interfaces to register this service for.
|
|
36
|
+
# @param [Module, String] interfaces The interfaces to register this service for.
|
|
37
37
|
# If not provided, it will default to all Java interfaces the instance
|
|
38
38
|
# implements.
|
|
39
|
+
# @param [org.osgi.framework.Bundle, nil] bundle The bundle to register
|
|
40
|
+
# the service from. If not provided, it will default to the bundle of the first
|
|
41
|
+
# interface.
|
|
39
42
|
# @param [Hash] properties The service registration properties.
|
|
40
43
|
# @return [org.osgi.framework.ServiceRegistration]
|
|
41
44
|
#
|
|
42
|
-
def register_service(instance, *interfaces, **properties)
|
|
45
|
+
def register_service(instance, *interfaces, bundle: nil, **properties)
|
|
43
46
|
if interfaces.empty?
|
|
44
47
|
interfaces = instance.class.ancestors.select { |k| k.respond_to?(:java_class) && k.java_class&.interface? }
|
|
45
48
|
end
|
|
46
49
|
|
|
47
|
-
|
|
50
|
+
bundle_class = interfaces.first.is_a?(Module) ? interfaces.first : instance
|
|
51
|
+
bundle ||= org.osgi.framework.FrameworkUtil.get_bundle(bundle_class.java_class)
|
|
52
|
+
interfaces.map! { |i| i.is_a?(String) ? i : i.java_class.name }
|
|
48
53
|
bundle.bundle_context.register_service(
|
|
49
|
-
interfaces.
|
|
54
|
+
interfaces.to_java(java.lang.String),
|
|
50
55
|
instance,
|
|
51
56
|
java.util.Hashtable.new(properties)
|
|
52
57
|
)
|
|
@@ -63,6 +68,32 @@ module OpenHAB
|
|
|
63
68
|
def bundle
|
|
64
69
|
@bundle ||= org.osgi.framework.FrameworkUtil.getBundle($scriptExtension.java_class)
|
|
65
70
|
end
|
|
71
|
+
|
|
72
|
+
# @!visibility private
|
|
73
|
+
SCR_NAMESPACE = "http://www.osgi.org/xmlns/scr/v1.4.0"
|
|
74
|
+
private_constant :SCR_NAMESPACE
|
|
75
|
+
|
|
76
|
+
# @!visibility private
|
|
77
|
+
def service_component_classes(bundle)
|
|
78
|
+
require "nokogiri"
|
|
79
|
+
|
|
80
|
+
component_paths = bundle.headers.get(
|
|
81
|
+
org.osgi.service.component.ComponentConstants::SERVICE_COMPONENT
|
|
82
|
+
)&.split(",") || []
|
|
83
|
+
component_paths.filter_map do |path|
|
|
84
|
+
stream = bundle.get_entry(path).open_stream
|
|
85
|
+
xml = Nokogiri::XML(String.from_java_bytes(stream.read_all_bytes))
|
|
86
|
+
|
|
87
|
+
class_name = xml.at_xpath("scr:component/implementation", scr: SCR_NAMESPACE)&.[]("class")
|
|
88
|
+
next unless class_name
|
|
89
|
+
|
|
90
|
+
services = xml.xpath("scr:component/service/provide", scr: SCR_NAMESPACE).map { |p| p["interface"] }
|
|
91
|
+
|
|
92
|
+
[bundle.load_class(class_name), services]
|
|
93
|
+
ensure
|
|
94
|
+
stream&.close
|
|
95
|
+
end.to_h
|
|
96
|
+
end
|
|
66
97
|
end
|
|
67
98
|
end
|
|
68
99
|
end
|
|
@@ -77,23 +77,37 @@ module OpenHAB
|
|
|
77
77
|
#
|
|
78
78
|
# @return [void]
|
|
79
79
|
#
|
|
80
|
+
# @deprecated
|
|
80
81
|
def autoupdate_all_items
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
@autoupdated_items = []
|
|
86
|
-
@spec_metadata_provider = Core::Items::Metadata::Provider.current
|
|
82
|
+
# no-op
|
|
83
|
+
end
|
|
87
84
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
85
|
+
#
|
|
86
|
+
# Force things to come online that are missing their thing type
|
|
87
|
+
#
|
|
88
|
+
# As of openHAB 4.0, things that are missing their thing type will not
|
|
89
|
+
# come online immediately. This especially impacts bindings that
|
|
90
|
+
# dynamically generate their thing types, but don't persist those
|
|
91
|
+
# thing types. You can use this method to force them to come online
|
|
92
|
+
# immediately.
|
|
93
|
+
#
|
|
94
|
+
# @return [void]
|
|
95
|
+
#
|
|
96
|
+
def initialize_missing_thing_types
|
|
97
|
+
thing_manager = OpenHAB::OSGi.service("org.openhab.core.thing.ThingManager")
|
|
98
|
+
thing_manager.class.field_reader :missingPrerequisites
|
|
99
|
+
first = true
|
|
100
|
+
thing_manager.missingPrerequisites.each_value do |prereq|
|
|
101
|
+
if first
|
|
102
|
+
prereq.class.field_accessor :timesChecked
|
|
103
|
+
first = false
|
|
96
104
|
end
|
|
105
|
+
prereq.timesChecked = 60
|
|
106
|
+
end
|
|
107
|
+
m = thing_manager.class.java_class.get_declared_method(:checkMissingPrerequisites)
|
|
108
|
+
m.accessible = true
|
|
109
|
+
suspend_rules do
|
|
110
|
+
m.invoke(thing_manager)
|
|
97
111
|
end
|
|
98
112
|
end
|
|
99
113
|
|
|
@@ -226,8 +240,11 @@ module OpenHAB
|
|
|
226
240
|
require_relative "openhab/core/actions"
|
|
227
241
|
|
|
228
242
|
ps = Mocks::PersistenceService.instance
|
|
229
|
-
|
|
230
|
-
|
|
243
|
+
persistence_bundle = org.osgi.framework.FrameworkUtil
|
|
244
|
+
.get_bundle(org.openhab.core.persistence.PersistenceService.java_class)
|
|
245
|
+
persistence_bundle.bundle_context.register_service(org.openhab.core.persistence.PersistenceService.java_class,
|
|
246
|
+
ps,
|
|
247
|
+
nil)
|
|
231
248
|
|
|
232
249
|
rs = OSGi.service("org.openhab.core.service.ReadyService")
|
|
233
250
|
|
|
@@ -240,6 +257,33 @@ module OpenHAB
|
|
|
240
257
|
rs.register_tracker(org.openhab.core.service.ReadyService::ReadyTracker.impl { continue.call }, filter)
|
|
241
258
|
end
|
|
242
259
|
|
|
260
|
+
begin
|
|
261
|
+
# load storage based type providers
|
|
262
|
+
ast = org.openhab.core.thing.binding.AbstractStorageBasedTypeProvider
|
|
263
|
+
ast_bundle = org.osgi.framework.FrameworkUtil.get_bundle(ast.java_class)
|
|
264
|
+
storage_service = OSGi.service("org.openhab.core.storage.StorageService")
|
|
265
|
+
require_relative "mocks/abstract_storage_based_type_provider_wrapped_storage_service"
|
|
266
|
+
|
|
267
|
+
OSGi.bundle_context.bundles.each do |bundle|
|
|
268
|
+
OSGi.service_component_classes(bundle)
|
|
269
|
+
.select { |klass, _services| klass.ancestors.include?(ast.java_class) }
|
|
270
|
+
.each do |klass, services|
|
|
271
|
+
new_ast_klass = Class.new(ast)
|
|
272
|
+
new_ast_klass.become_java!
|
|
273
|
+
wrapped_storage_service = Mocks::AbstractStorageBasedTypeProviderWrappedStorageService
|
|
274
|
+
.new(storage_service,
|
|
275
|
+
new_ast_klass.java_class,
|
|
276
|
+
klass)
|
|
277
|
+
new_ast = new_ast_klass.new(wrapped_storage_service)
|
|
278
|
+
|
|
279
|
+
services -= [klass.name]
|
|
280
|
+
OSGi.register_service(new_ast, *services, bundle: ast_bundle)
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
rescue NameError
|
|
284
|
+
# @deprecated OH 4.0
|
|
285
|
+
end
|
|
286
|
+
|
|
243
287
|
# RSpec additions
|
|
244
288
|
require_relative "suspend_rules"
|
|
245
289
|
|
|
@@ -422,32 +466,6 @@ module OpenHAB
|
|
|
422
466
|
.gsub(%r{(?:_|(/))([a-z\d]*)}) { "#{$1}#{$2.capitalize}" }
|
|
423
467
|
.split("/")
|
|
424
468
|
end
|
|
425
|
-
|
|
426
|
-
# need to transfer autoupdate metadata from GenericMetadataProvider to ManagedMetadataProvider
|
|
427
|
-
# so that we can mutate it in the future
|
|
428
|
-
def set_up_autoupdates
|
|
429
|
-
registry = Core::Items::Metadata::Provider.registry
|
|
430
|
-
registry.class.field_reader :identifierToElement
|
|
431
|
-
|
|
432
|
-
autoupdate_provider = Core::Items::Metadata::Provider.send(:new)
|
|
433
|
-
registry.all.each do |metadata|
|
|
434
|
-
next unless metadata.uid.namespace == "autoupdate"
|
|
435
|
-
|
|
436
|
-
# tweak the registry to allow us to overwrite this element
|
|
437
|
-
registry.identifierToElement.delete(metadata.uid)
|
|
438
|
-
autoupdate_provider.add(metadata)
|
|
439
|
-
end
|
|
440
|
-
end
|
|
441
|
-
|
|
442
|
-
def restore_autoupdate_items
|
|
443
|
-
return unless instance_variable_defined?(:@autoupdated_items)
|
|
444
|
-
|
|
445
|
-
@autoupdated_items.each do |(provider, hash)|
|
|
446
|
-
@spec_metadata_provider.remove(hash.uid)
|
|
447
|
-
provider.add(hash.instance_variable_get(:@metadata))
|
|
448
|
-
end
|
|
449
|
-
@autoupdated_items = nil
|
|
450
|
-
end
|
|
451
469
|
end
|
|
452
470
|
|
|
453
471
|
if defined?(::RSpec)
|
data/lib/openhab/rspec/hooks.rb
CHANGED
|
@@ -38,7 +38,6 @@ module OpenHAB
|
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
Helpers.autorequires unless Configuration.private_confdir
|
|
41
|
-
Helpers.send(:set_up_autoupdates)
|
|
42
41
|
Helpers.load_transforms
|
|
43
42
|
Helpers.load_rules
|
|
44
43
|
|
|
@@ -52,6 +51,10 @@ module OpenHAB
|
|
|
52
51
|
end
|
|
53
52
|
end
|
|
54
53
|
|
|
54
|
+
config.around do |example|
|
|
55
|
+
Mocks::Timer.mock_timers(self.class.mock_timers?, &example)
|
|
56
|
+
end
|
|
57
|
+
|
|
55
58
|
config.before do
|
|
56
59
|
suspend_rules do
|
|
57
60
|
$ir.for_each do |_provider, item|
|
|
@@ -88,8 +91,6 @@ module OpenHAB
|
|
|
88
91
|
@profile_factory = Core::ProfileFactory.send(:new)
|
|
89
92
|
allow(Core::ProfileFactory).to receive(:instance).and_return(@profile_factory)
|
|
90
93
|
|
|
91
|
-
stub_const("OpenHAB::Core::Timer", Mocks::Timer) if self.class.mock_timers?
|
|
92
|
-
|
|
93
94
|
log_line = "rspec #{example.location} # #{example.full_description}"
|
|
94
95
|
logger.info(log_line)
|
|
95
96
|
Logger.events.info(log_line)
|
|
@@ -103,7 +104,6 @@ module OpenHAB
|
|
|
103
104
|
# wipe this
|
|
104
105
|
DSL::Items::TimedCommand.timed_commands.clear
|
|
105
106
|
Timecop.return
|
|
106
|
-
restore_autoupdate_items
|
|
107
107
|
Mocks::PersistenceService.instance.reset
|
|
108
108
|
Hooks.cache_script_extension.sharedCache.clear if DSL.shared_cache
|
|
109
109
|
DSL.persistence!(nil)
|
data/lib/openhab/rspec/karaf.rb
CHANGED
|
@@ -537,6 +537,10 @@ module OpenHAB
|
|
|
537
537
|
|
|
538
538
|
def add_class_loader(bundle)
|
|
539
539
|
return if @class_loaders.include?(bundle.symbolic_name)
|
|
540
|
+
# this bundle sometimes has an invalid internal jar (geronimo-osgi-locator.jar) which will
|
|
541
|
+
# spam the logs with useless errors. it's doubtful we'll need to access a class from this
|
|
542
|
+
# bundle directly
|
|
543
|
+
return if bundle.symbolic_name == "org.apache.aries.javax.jax.rs-api"
|
|
540
544
|
|
|
541
545
|
@class_loaders << bundle.symbolic_name
|
|
542
546
|
::JRuby.runtime.instance_config.add_loader(JRuby::OSGiBundleClassLoader.new(bundle))
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "delegate"
|
|
4
|
+
|
|
5
|
+
module OpenHAB
|
|
6
|
+
module RSpec
|
|
7
|
+
# @!visibility private
|
|
8
|
+
module Mocks
|
|
9
|
+
class AbstractStorageBasedTypeProviderWrappedStorageService < SimpleDelegator
|
|
10
|
+
include org.openhab.core.storage.StorageService
|
|
11
|
+
|
|
12
|
+
def initialize(parent, ruby_klass, java_klass)
|
|
13
|
+
super(parent)
|
|
14
|
+
@ruby_klass = ruby_klass
|
|
15
|
+
@java_klass = java_klass
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def getStorage(name, _class_loader) # rubocop:disable Naming/MethodName
|
|
19
|
+
super(name.sub(@ruby_klass.name, @java_klass.name), @java_klass.class_loader)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -29,7 +29,13 @@ module OpenHAB
|
|
|
29
29
|
@thing = thing
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
def handle_command(
|
|
32
|
+
def handle_command(channel_uid, command)
|
|
33
|
+
channel = thing.get_channel(channel_uid)
|
|
34
|
+
return unless channel
|
|
35
|
+
return if channel.auto_update_policy == org.openhab.core.thing.type.AutoUpdatePolicy::VETO
|
|
36
|
+
|
|
37
|
+
callback&.state_updated(channel_uid, command) if command.is_a?(Core::Types::State)
|
|
38
|
+
end
|
|
33
39
|
|
|
34
40
|
def set_callback(callback)
|
|
35
41
|
@callback = callback
|
|
@@ -72,6 +72,42 @@ module OpenHAB
|
|
|
72
72
|
end
|
|
73
73
|
Timecop::TimeStackItem.prepend(TimeCopStackItem)
|
|
74
74
|
|
|
75
|
+
class << self
|
|
76
|
+
# If timers are currently mocked
|
|
77
|
+
# @return [true, false]
|
|
78
|
+
def mock_timers?
|
|
79
|
+
@mock_timers
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
#
|
|
83
|
+
# Temporarily mock or unmock timers
|
|
84
|
+
#
|
|
85
|
+
# @param [true, false] mock_timers if timers should be mocked
|
|
86
|
+
# @yield
|
|
87
|
+
# @return [Object] the block's return value
|
|
88
|
+
def mock_timers(mock_timers)
|
|
89
|
+
old_mock_timers = @mock_timers
|
|
90
|
+
@mock_timers = mock_timers
|
|
91
|
+
yield
|
|
92
|
+
ensure
|
|
93
|
+
@mock_timers = old_mock_timers
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
@mock_timers = true
|
|
98
|
+
|
|
99
|
+
# @!visibility private
|
|
100
|
+
module ClassMethods
|
|
101
|
+
# @!visibility private
|
|
102
|
+
def new(*args, **kwargs)
|
|
103
|
+
return super if self == Timer
|
|
104
|
+
return Timer.new(*args, **kwargs) if Timer.mock_timers?
|
|
105
|
+
|
|
106
|
+
super
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
Core::Timer.singleton_class.prepend(ClassMethods)
|
|
110
|
+
|
|
75
111
|
attr_reader :execution_time, :id, :block
|
|
76
112
|
|
|
77
113
|
def initialize(time, id:, thread_locals:, block:) # rubocop:disable Lint/MissingSuper
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: openhab-scripting
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.
|
|
4
|
+
version: 5.15.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brian O'Connell
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date: 2024-01-
|
|
13
|
+
date: 2024-01-06 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: bundler
|
|
@@ -546,6 +546,7 @@ files:
|
|
|
546
546
|
- lib/openhab/rspec/hooks.rb
|
|
547
547
|
- lib/openhab/rspec/jruby.rb
|
|
548
548
|
- lib/openhab/rspec/karaf.rb
|
|
549
|
+
- lib/openhab/rspec/mocks/abstract_storage_based_type_provider_wrapped_storage_service.rb
|
|
549
550
|
- lib/openhab/rspec/mocks/bundle_install_support.rb
|
|
550
551
|
- lib/openhab/rspec/mocks/bundle_resolver.rb
|
|
551
552
|
- lib/openhab/rspec/mocks/event_admin.rb
|
|
@@ -607,7 +608,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
607
608
|
- !ruby/object:Gem::Version
|
|
608
609
|
version: '0'
|
|
609
610
|
requirements: []
|
|
610
|
-
rubygems_version: 3.
|
|
611
|
+
rubygems_version: 3.5.4
|
|
611
612
|
signing_key:
|
|
612
613
|
specification_version: 4
|
|
613
614
|
summary: JRuby Helper Libraries for openHAB Scripting
|