openhab-scripting 5.36.2 → 5.38.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/events/item_state_changed_event.rb +11 -0
- data/lib/openhab/core/events/item_state_updated_event.rb +13 -0
- data/lib/openhab/core/items/call_item.rb +4 -0
- data/lib/openhab/core/items/color_item.rb +4 -0
- data/lib/openhab/core/items/contact_item.rb +27 -14
- data/lib/openhab/core/items/date_time_item.rb +4 -0
- data/lib/openhab/core/items/dimmer_item.rb +4 -0
- data/lib/openhab/core/items/generic_item.rb +35 -0
- data/lib/openhab/core/items/image_item.rb +5 -1
- data/lib/openhab/core/items/item.rb +18 -0
- data/lib/openhab/core/items/location_item.rb +4 -0
- data/lib/openhab/core/items/number_item.rb +3 -0
- data/lib/openhab/core/items/persistence.rb +141 -43
- data/lib/openhab/core/items/player_item.rb +80 -59
- data/lib/openhab/core/items/rollershutter_item.rb +12 -0
- data/lib/openhab/core/items/semantics.rb +51 -14
- data/lib/openhab/core/items/string_item.rb +4 -0
- data/lib/openhab/core/items/switch_item.rb +11 -0
- data/lib/openhab/core/items.rb +4 -0
- data/lib/openhab/core/timer.rb +75 -1
- data/lib/openhab/core/value_cache.rb +43 -5
- data/lib/openhab/core.rb +17 -0
- data/lib/openhab/dsl/rules/builder.rb +55 -9
- data/lib/openhab/dsl/rules/triggers/changed.rb +10 -2
- data/lib/openhab/dsl/rules/triggers/command.rb +5 -2
- data/lib/openhab/dsl/rules/triggers/updated.rb +9 -4
- data/lib/openhab/dsl/version.rb +1 -1
- data/lib/openhab/dsl.rb +26 -0
- data/lib/openhab/scripting.rb +7 -0
- data/lib/openhab/yard/markdown_helper.rb +3 -0
- metadata +4 -3
@@ -10,71 +10,92 @@ module OpenHAB
|
|
10
10
|
#
|
11
11
|
# A {PlayerItem} allows control of a player, e.g. an audio player.
|
12
12
|
#
|
13
|
-
# @!attribute [r] state
|
14
|
-
# @return [PlayPauseType, RewindFastforwardType, nil]
|
15
|
-
#
|
16
13
|
# @example Start playing on a player item
|
17
14
|
# Chromecast.play
|
18
15
|
# @example Check if a player is paused
|
19
16
|
# logger.warn("#{item.name} is paused") if Chromecast.paused?
|
20
17
|
#
|
18
|
+
# @!attribute [r] state
|
19
|
+
# @return [PlayPauseType, RewindFastforwardType, nil]
|
20
|
+
#
|
21
|
+
# @!attribute [r] was
|
22
|
+
# @return [PlayPauseType, RewindFastforwardType, nil]
|
23
|
+
# @since openHAB 5.0
|
24
|
+
#
|
25
|
+
# @!method play?
|
26
|
+
# Check if the item state == {PLAY}
|
27
|
+
# @return [true,false]
|
28
|
+
#
|
29
|
+
# @!method paused?
|
30
|
+
# Check if the item state == {PAUSE}
|
31
|
+
# @return [true,false]
|
32
|
+
#
|
33
|
+
# @!method rewinding?
|
34
|
+
# Check if the item state == {REWIND}
|
35
|
+
# @return [true,false]
|
36
|
+
#
|
37
|
+
# @!method fast_forwarding?
|
38
|
+
# Check if the item state == {FASTFORWARD}
|
39
|
+
# @return [true,false]
|
40
|
+
#
|
41
|
+
# @!method was_playing?
|
42
|
+
# Check if {#was} is {PLAY}
|
43
|
+
# @return [true, false]
|
44
|
+
#
|
45
|
+
# @!method was_paused?
|
46
|
+
# Check if {#was} is {PAUSE}
|
47
|
+
# @return [true, false]
|
48
|
+
#
|
49
|
+
# @!method was_rewinding?
|
50
|
+
# Check if {#was} is {REWIND}
|
51
|
+
# @return [true, false]
|
52
|
+
#
|
53
|
+
# @!method was_fast_forwarding?
|
54
|
+
# Check if {#was} is {FASTFORWARD}
|
55
|
+
# @return [true, false]
|
56
|
+
#
|
57
|
+
# @!method play
|
58
|
+
# Send the {PLAY} command to the item
|
59
|
+
# @return [PlayerItem] `self`
|
60
|
+
#
|
61
|
+
# @!method play!
|
62
|
+
# Send the {PLAY} command to the item, even when {OpenHAB::DSL.ensure_states! ensure_states!} is in effect.
|
63
|
+
# @return [PlayerItem] `self`
|
64
|
+
#
|
65
|
+
# @!method pause
|
66
|
+
# Send the {PAUSE} command to the item
|
67
|
+
# @return [PlayerItem] `self`
|
68
|
+
#
|
69
|
+
# @!method pause!
|
70
|
+
# Send the {PAUSE} command to the item, even when {OpenHAB::DSL.ensure_states! ensure_states!} is in effect.
|
71
|
+
# @return [PlayerItem] `self`
|
72
|
+
#
|
73
|
+
# @!method rewind
|
74
|
+
# Send the {REWIND} command to the item
|
75
|
+
# @return [PlayerItem] `self`
|
76
|
+
#
|
77
|
+
# @!method rewind!
|
78
|
+
# Send the {REWIND} command to the item, even when {OpenHAB::DSL.ensure_states! ensure_states!} is in effect.
|
79
|
+
# @return [PlayerItem] `self`
|
80
|
+
#
|
81
|
+
# @!method fast_forward
|
82
|
+
# Send the {FASTFORWARD} command to the item
|
83
|
+
# @return [PlayerItem] `self`
|
84
|
+
#
|
85
|
+
# @!method fast_forward!
|
86
|
+
# Send the {FASTFORWARD} command to the item, even when
|
87
|
+
# {OpenHAB::DSL.ensure_states! ensure_states!} is in effect.
|
88
|
+
# @return [PlayerItem] `self`
|
89
|
+
#
|
90
|
+
# @!method next
|
91
|
+
# Send the {NEXT} command to the item
|
92
|
+
# @return [PlayerItem] `self`
|
93
|
+
#
|
94
|
+
# @!method previous
|
95
|
+
# Send the {PREVIOUS} command to the item
|
96
|
+
# @return [PlayerItem] `self`
|
97
|
+
#
|
21
98
|
class PlayerItem < GenericItem
|
22
|
-
# @!method play?
|
23
|
-
# Check if the item state == {PLAY}
|
24
|
-
# @return [true,false]
|
25
|
-
|
26
|
-
# @!method paused?
|
27
|
-
# Check if the item state == {PAUSE}
|
28
|
-
# @return [true,false]
|
29
|
-
|
30
|
-
# @!method rewinding?
|
31
|
-
# Check if the item state == {REWIND}
|
32
|
-
# @return [true,false]
|
33
|
-
|
34
|
-
# @!method fast_forwarding?
|
35
|
-
# Check if the item state == {FASTFORWARD}
|
36
|
-
# @return [true,false]
|
37
|
-
|
38
|
-
# @!method play
|
39
|
-
# Send the {PLAY} command to the item
|
40
|
-
# @return [PlayerItem] `self`
|
41
|
-
|
42
|
-
# @!method play!
|
43
|
-
# Send the {PLAY} command to the item, even when {OpenHAB::DSL.ensure_states! ensure_states!} is in effect.
|
44
|
-
# @return [PlayerItem] `self`
|
45
|
-
|
46
|
-
# @!method pause
|
47
|
-
# Send the {PAUSE} command to the item
|
48
|
-
# @return [PlayerItem] `self`
|
49
|
-
|
50
|
-
# @!method pause!
|
51
|
-
# Send the {PAUSE} command to the item, even when {OpenHAB::DSL.ensure_states! ensure_states!} is in effect.
|
52
|
-
# @return [PlayerItem] `self`
|
53
|
-
|
54
|
-
# @!method rewind
|
55
|
-
# Send the {REWIND} command to the item
|
56
|
-
# @return [PlayerItem] `self`
|
57
|
-
|
58
|
-
# @!method rewind!
|
59
|
-
# Send the {REWIND} command to the item, even when {OpenHAB::DSL.ensure_states! ensure_states!} is in effect.
|
60
|
-
# @return [PlayerItem] `self`
|
61
|
-
|
62
|
-
# @!method fast_forward
|
63
|
-
# Send the {FASTFORWARD} command to the item
|
64
|
-
# @return [PlayerItem] `self`
|
65
|
-
|
66
|
-
# @!method fast_forward!
|
67
|
-
# Send the {FASTFORWARD} command to the item, even when
|
68
|
-
# {OpenHAB::DSL.ensure_states! ensure_states!} is in effect.
|
69
|
-
# @return [PlayerItem] `self`
|
70
|
-
|
71
|
-
# @!method next
|
72
|
-
# Send the {NEXT} command to the item
|
73
|
-
# @return [PlayerItem] `self`
|
74
|
-
|
75
|
-
# @!method previous
|
76
|
-
# Send the {PREVIOUS} command to the item
|
77
|
-
# @return [PlayerItem] `self`
|
78
99
|
end
|
79
100
|
end
|
80
101
|
end
|
@@ -16,6 +16,10 @@ module OpenHAB
|
|
16
16
|
# @!attribute [r] state
|
17
17
|
# @return [PercentType, UpDownType, nil]
|
18
18
|
#
|
19
|
+
# @!attribute [r] was
|
20
|
+
# @return [PercentType, UpDownType, nil]
|
21
|
+
# @since openHAB 5.0
|
22
|
+
#
|
19
23
|
# @example Roll up all Rollershutters in a group
|
20
24
|
# Shutters.up
|
21
25
|
#
|
@@ -37,6 +41,14 @@ module OpenHAB
|
|
37
41
|
# Check if the item state == {DOWN}
|
38
42
|
# @return [true,false]
|
39
43
|
|
44
|
+
# @!method was_up?
|
45
|
+
# Check if {#was} is {UP}
|
46
|
+
# @return [true, false]
|
47
|
+
|
48
|
+
# @!method was_down?
|
49
|
+
# Check if {#was} is {DOWN}
|
50
|
+
# @return [true, false]
|
51
|
+
|
40
52
|
# @!method up
|
41
53
|
# Send the {UP} command to the item
|
42
54
|
# @return [RollershutterItem] `self`
|
@@ -543,17 +543,14 @@ module OpenHAB
|
|
543
543
|
# @example Given a A/V receiver's input item, search for its power item
|
544
544
|
# FamilyReceiver_Input.points(Semantics::Switch) # => [FamilyReceiver_Switch]
|
545
545
|
#
|
546
|
-
# @param
|
547
|
-
# Pass 1 or 2 classes that are sub-classes of {Point} or {Property}.
|
548
|
-
# Note that when comparing against semantic tags, it does a sub-class check.
|
549
|
-
# So if you search for [Control], you'll get items tagged with [Switch].
|
546
|
+
# @param (see Enumerable#points)
|
550
547
|
# @return [Array<Item>]
|
551
548
|
#
|
552
|
-
def points(
|
553
|
-
return members.points(
|
549
|
+
def points(...)
|
550
|
+
return members.points(...) if equipment? || location?
|
554
551
|
|
555
552
|
# automatically search the parent equipment (or location?!) for sibling points
|
556
|
-
result = (equipment || location)&.points(
|
553
|
+
result = (equipment || location)&.points(...) || []
|
557
554
|
result.delete(self)
|
558
555
|
result
|
559
556
|
end
|
@@ -572,6 +569,14 @@ module Enumerable
|
|
572
569
|
|
573
570
|
#
|
574
571
|
# Returns a new array of items that are a semantics Location (optionally of one of the given types)
|
572
|
+
#
|
573
|
+
# @param [SemanticTag] types
|
574
|
+
# Pass 1 or more classes that are sub-classes of {Semantics::Location Semantics::Location}.
|
575
|
+
# Note that when comparing against semantic tags, it does a sub-class check by default.
|
576
|
+
# So if you search for [Room], you'll get items tagged with [LivingRoom], [Kitchen], etc.
|
577
|
+
# @param [true, false] subclasses
|
578
|
+
# If true, match all subclasses of the given types.
|
579
|
+
# If false, only match the exact type.
|
575
580
|
# @return [Array<Item>]
|
576
581
|
#
|
577
582
|
# @example Get all rooms
|
@@ -580,7 +585,7 @@ module Enumerable
|
|
580
585
|
# @example Get all bedrooms and bathrooms
|
581
586
|
# items.locations(Semantics::Bedroom, Semantics::Bathroom)
|
582
587
|
#
|
583
|
-
def locations(*types)
|
588
|
+
def locations(*types, subclasses: true)
|
584
589
|
begin
|
585
590
|
raise ArgumentError unless types.all? { |type| type < Semantics::Location }
|
586
591
|
rescue ArgumentError, TypeError
|
@@ -588,7 +593,13 @@ module Enumerable
|
|
588
593
|
end
|
589
594
|
|
590
595
|
result = select(&:location?)
|
591
|
-
|
596
|
+
unless types.empty?
|
597
|
+
if subclasses
|
598
|
+
result.select! { |i| types.any? { |type| i.location_type <= type } }
|
599
|
+
else
|
600
|
+
result.select! { |i| types.include?(i.location_type) }
|
601
|
+
end
|
602
|
+
end
|
592
603
|
|
593
604
|
result
|
594
605
|
end
|
@@ -602,6 +613,13 @@ module Enumerable
|
|
602
613
|
# that belong to the {Semantics::Equipment equipments}, use {#members}
|
603
614
|
# before calling {#points}. See the example with {#points}.
|
604
615
|
#
|
616
|
+
# @param [SemanticTag] types
|
617
|
+
# Pass 1 or more classes that are sub-classes of {Semantics::Equipment Semantics::Equipment}.
|
618
|
+
# Note that when comparing against semantic tags, it does a sub-class check by default.
|
619
|
+
# So if you search for [Fan], you'll get items tagged with [CeilingFan], [KitchenHood], etc.
|
620
|
+
# @param [true, false] subclasses
|
621
|
+
# If true, match all subclasses of the given types.
|
622
|
+
# If false, only match the exact type.
|
605
623
|
# @return [Array<Item>]
|
606
624
|
#
|
607
625
|
# @example Get all TVs in a room
|
@@ -610,7 +628,7 @@ module Enumerable
|
|
610
628
|
# @example Get all TVs and Speakers in a room
|
611
629
|
# lGreatRoom.equipments(Semantics::Television, Semantics::Speaker)
|
612
630
|
#
|
613
|
-
def equipments(*types)
|
631
|
+
def equipments(*types, subclasses: true)
|
614
632
|
begin
|
615
633
|
raise ArgumentError unless types.all? { |type| type < Semantics::Equipment }
|
616
634
|
rescue ArgumentError, TypeError
|
@@ -618,13 +636,27 @@ module Enumerable
|
|
618
636
|
end
|
619
637
|
|
620
638
|
result = select(&:equipment?)
|
621
|
-
|
639
|
+
unless types.empty?
|
640
|
+
if subclasses
|
641
|
+
result.select! { |i| types.any? { |type| i.equipment_type <= type } }
|
642
|
+
else
|
643
|
+
result.select! { |i| types.include?(i.equipment_type) }
|
644
|
+
end
|
645
|
+
end
|
622
646
|
|
623
647
|
result
|
624
648
|
end
|
625
649
|
|
626
650
|
# Returns a new array of items that are semantics points (optionally of a given type)
|
627
651
|
#
|
652
|
+
# @param [SemanticTag] point_or_property_types
|
653
|
+
# Pass 1 or 2 classes that are sub-classes of {Semantics::Point Semantics::Point} or
|
654
|
+
# {Semantics::Property Semantics::Property}.
|
655
|
+
# Note that when comparing against semantic tags, it does a sub-class check by default.
|
656
|
+
# So if you search for [Control], you'll get items tagged with [Switch].
|
657
|
+
# @param [true, false] subclasses
|
658
|
+
# If true, match all subclasses of the given types.
|
659
|
+
# If false, only match the exact type.
|
628
660
|
# @return [Array<Item>]
|
629
661
|
#
|
630
662
|
# @example Get all the power switch items for every equipment in a room
|
@@ -632,7 +664,7 @@ module Enumerable
|
|
632
664
|
#
|
633
665
|
# @see #members
|
634
666
|
#
|
635
|
-
def points(*point_or_property_types)
|
667
|
+
def points(*point_or_property_types, subclasses: true)
|
636
668
|
unless (0..2).cover?(point_or_property_types.length)
|
637
669
|
raise ArgumentError, "wrong number of arguments (given #{point_or_property_types.length}, expected 0..2)"
|
638
670
|
end
|
@@ -652,8 +684,13 @@ module Enumerable
|
|
652
684
|
|
653
685
|
select do |point|
|
654
686
|
point.point? && point_or_property_types.all? do |tag|
|
655
|
-
|
656
|
-
(tag < Semantics::
|
687
|
+
if subclasses
|
688
|
+
(tag < Semantics::Point && point.point_type&.<=(tag)) ||
|
689
|
+
(tag < Semantics::Property && point.property_type&.<=(tag))
|
690
|
+
else
|
691
|
+
(tag < Semantics::Point && point.point_type == tag) ||
|
692
|
+
(tag < Semantics::Property && point.property_type == tag)
|
693
|
+
end
|
657
694
|
end
|
658
695
|
end
|
659
696
|
end
|
@@ -14,6 +14,10 @@ module OpenHAB
|
|
14
14
|
# @!attribute [r] state
|
15
15
|
# @return [StringType, nil]
|
16
16
|
#
|
17
|
+
# @!attribute [r] was
|
18
|
+
# @return [StringType, nil]
|
19
|
+
# @since openHAB 5.0
|
20
|
+
#
|
17
21
|
# @example
|
18
22
|
# # StringOne has a current state of "Hello"
|
19
23
|
# StringOne << StringOne + " World!"
|
@@ -14,6 +14,9 @@ module OpenHAB
|
|
14
14
|
# @!attribute [r] state
|
15
15
|
# @return [OnOffType, nil]
|
16
16
|
#
|
17
|
+
# @!attribute [r] was
|
18
|
+
# @return [OnOffType, nil]
|
19
|
+
# @since openHAB 5.0
|
17
20
|
#
|
18
21
|
# @example Turn on all switches in a `Group:Switch` called Switches
|
19
22
|
# Switches.on
|
@@ -76,6 +79,14 @@ module OpenHAB
|
|
76
79
|
# @!method off!
|
77
80
|
# Send the {OFF} command to the item, even when {OpenHAB::DSL.ensure_states! ensure_states!} is in effect.
|
78
81
|
# @return [SwitchItem] `self`
|
82
|
+
|
83
|
+
# @!method was_on?
|
84
|
+
# Check if {#was} is (implicitly convertible to) {ON}
|
85
|
+
# @return [true, false]
|
86
|
+
|
87
|
+
# @!method was_off?
|
88
|
+
# Check if {#was} is (implicitly convertible to) {OFF}
|
89
|
+
# @return [true, false]
|
79
90
|
end
|
80
91
|
end
|
81
92
|
end
|
data/lib/openhab/core/items.rb
CHANGED
@@ -49,6 +49,10 @@ module OpenHAB
|
|
49
49
|
def #{state_predicate} # def on?
|
50
50
|
raw_state.as(#{state.class.java_class.simple_name}).equal?(#{state}) # raw_state.as(OnOffType) == ON
|
51
51
|
end # end
|
52
|
+
|
53
|
+
def was_#{state_predicate} # def was_on?
|
54
|
+
last_state.as(#{state.class.java_class.simple_name}).equal?(#{state}) # last_state.as(OnOffType) == ON
|
55
|
+
end # end
|
52
56
|
RUBY
|
53
57
|
end
|
54
58
|
end
|
data/lib/openhab/core/timer.rb
CHANGED
@@ -45,6 +45,7 @@ module OpenHAB
|
|
45
45
|
#
|
46
46
|
# @!visibility private
|
47
47
|
def initialize(time, id:, thread_locals:, block:)
|
48
|
+
@managed = true
|
48
49
|
@time = time
|
49
50
|
@id = id
|
50
51
|
@thread_locals = thread_locals
|
@@ -95,7 +96,7 @@ module OpenHAB
|
|
95
96
|
# @!visibility private
|
96
97
|
def reschedule!(time = nil)
|
97
98
|
Thread.current[:openhab_rescheduled_timer] = true if Thread.current[:openhab_rescheduled_timer] == self
|
98
|
-
DSL.timers.add(self)
|
99
|
+
DSL.timers.add(self) if managed?
|
99
100
|
@timer.reschedule(new_execution_time(time || @time))
|
100
101
|
self
|
101
102
|
end
|
@@ -122,6 +123,79 @@ module OpenHAB
|
|
122
123
|
@timer.cancel
|
123
124
|
end
|
124
125
|
|
126
|
+
#
|
127
|
+
# Returns the openHAB Timer object.
|
128
|
+
#
|
129
|
+
# This can be used to share the timer with other scripts via {OpenHAB::DSL.shared_cache shared_cache}.
|
130
|
+
# The other scripts can be other JRuby scripts or scripts written in a different language
|
131
|
+
# such as JSScripting, Python, etc. which can either be file-based or UI based scripts.
|
132
|
+
#
|
133
|
+
# Timers are normally managed by TimerManager, and are normally automatically cancelled
|
134
|
+
# when the script unloads/reloads.
|
135
|
+
#
|
136
|
+
# To disable this automatic timer cancellation at script unload, call {unmanage}.
|
137
|
+
#
|
138
|
+
# openHAB will cancel the timer stored in the {OpenHAB::DSL.shared_cache shared_cache}
|
139
|
+
# and remove the cache entry when all the scripts that _had accessed_ it have been unloaded.
|
140
|
+
#
|
141
|
+
# @return [org.openhab.core.automation.module.script.action.Timer]
|
142
|
+
#
|
143
|
+
# @see unmanage
|
144
|
+
#
|
145
|
+
# @example
|
146
|
+
# # script1.rb:
|
147
|
+
# timer = after(10.hours) { logger.warn "Timer created in script1.rb fired" }
|
148
|
+
# shared_cache[:script1_timer] = timer.to_java
|
149
|
+
#
|
150
|
+
# # script2.js: (JavaScript!)
|
151
|
+
# rules.when().item("TestSwitch1").receivedCommand().then(event => {
|
152
|
+
# cache.shared.get("script1_timer")?.cancel()
|
153
|
+
# })
|
154
|
+
#
|
155
|
+
# # or in Ruby script2.rb
|
156
|
+
# received_command(TestSwitch2, command: ON) do
|
157
|
+
# # This is an openHAB timer object, not a JRuby timer object
|
158
|
+
# # the reschedule method expects a ZonedDateTime
|
159
|
+
# shared_cache[:script1_timer]&.reschedule(3.seconds.from_now)
|
160
|
+
# end
|
161
|
+
#
|
162
|
+
# @!visibility private
|
163
|
+
def to_java
|
164
|
+
@timer
|
165
|
+
end
|
166
|
+
|
167
|
+
#
|
168
|
+
# Removes the timer from the {TimerManager TimerManager}
|
169
|
+
#
|
170
|
+
# The effects of calling this method are:
|
171
|
+
# - The timer will no longer be automatically cancelled when the script unloads.
|
172
|
+
# It will still execute as scheduled even if the script is unloaded/removed.
|
173
|
+
# - It can no longer be referenced by its `id`.
|
174
|
+
# - Subsequent calls to {OpenHAB::DSL.after after} with the same `id` will create a separate new timer.
|
175
|
+
# - Normal timer operations such as {reschedule}, {cancel}, etc. will still work.
|
176
|
+
#
|
177
|
+
# @return [org.openhab.core.automation.module.script.action.Timer] The openHAB Timer object
|
178
|
+
#
|
179
|
+
# @example
|
180
|
+
# timer = after(10.hours) { logger.warn "Timer created in script1.rb fired" }
|
181
|
+
# shared_cache[:script1_timer] = timer
|
182
|
+
# # Don't cancel the timer when this script unloads,
|
183
|
+
# # but openHAB will do it if all scripts that had referenced the shared cache are unloaded.
|
184
|
+
# timer.unmanage
|
185
|
+
#
|
186
|
+
def unmanage
|
187
|
+
@managed = false
|
188
|
+
DSL.timers.delete(self)
|
189
|
+
@id = nil
|
190
|
+
@timer
|
191
|
+
end
|
192
|
+
|
193
|
+
# @return [true,false] True if the timer is managed by TimerManager, false otherwise.
|
194
|
+
# A timer is managed by default, and becomes un-managed when {unmanage} is called.
|
195
|
+
def managed?
|
196
|
+
@managed
|
197
|
+
end
|
198
|
+
|
125
199
|
private
|
126
200
|
|
127
201
|
#
|
@@ -47,7 +47,7 @@ module OpenHAB
|
|
47
47
|
module ValueCache
|
48
48
|
# @see https://docs.ruby-lang.org/en/master/Hash.html#method-i-5B-5D Hash#[]
|
49
49
|
def [](key)
|
50
|
-
get(key
|
50
|
+
get(key)
|
51
51
|
end
|
52
52
|
|
53
53
|
#
|
@@ -58,18 +58,18 @@ module OpenHAB
|
|
58
58
|
# @return [Object] new value or current value
|
59
59
|
#
|
60
60
|
def compute_if_absent(key, &)
|
61
|
-
get(key
|
61
|
+
get(key, &)
|
62
62
|
end
|
63
63
|
|
64
64
|
# @see https://docs.ruby-lang.org/en/master/Hash.html#method-i-5B-5D-3D Hash#[]=
|
65
65
|
def []=(key, value)
|
66
|
-
put(key
|
66
|
+
put(key, value)
|
67
67
|
end
|
68
68
|
alias_method :store, :[]
|
69
69
|
|
70
70
|
# @see https://docs.ruby-lang.org/en/master/Hash.html#method-i-delete Hash#delete
|
71
71
|
def delete(key)
|
72
|
-
key = key.to_s
|
72
|
+
key = key.to_s # needed for remove below
|
73
73
|
if block_given?
|
74
74
|
fetch(key) do
|
75
75
|
return yield(key)
|
@@ -89,8 +89,8 @@ module OpenHAB
|
|
89
89
|
"wrong number of arguments (given #{default_value.length + 1}, expected 0..1)"
|
90
90
|
end
|
91
91
|
|
92
|
-
key = key.to_s
|
93
92
|
if default_value.empty?
|
93
|
+
key = key.to_s
|
94
94
|
if block_given?
|
95
95
|
get(key) do
|
96
96
|
return yield(key)
|
@@ -184,6 +184,44 @@ module OpenHAB
|
|
184
184
|
self[k]
|
185
185
|
end
|
186
186
|
end
|
187
|
+
|
188
|
+
#
|
189
|
+
# Converts values before storing them in the cache.
|
190
|
+
#
|
191
|
+
# This is used to convert JRuby timers created with {OpenHAB::DSL.after} to openHAB timers.
|
192
|
+
#
|
193
|
+
# Because we generally can't store JRuby objects in the shared cache,
|
194
|
+
# we can convert other things to Java objects here too as necessary.
|
195
|
+
#
|
196
|
+
# @!visibility private
|
197
|
+
module ValueConverter
|
198
|
+
# @!visibility private
|
199
|
+
def get(key, &)
|
200
|
+
key = key.to_s
|
201
|
+
return super(key) unless block_given?
|
202
|
+
|
203
|
+
super do
|
204
|
+
convert(yield(key))
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
# @!visibility private
|
209
|
+
def put(key, value)
|
210
|
+
key = key.to_s
|
211
|
+
value = convert(value)
|
212
|
+
super
|
213
|
+
end
|
214
|
+
|
215
|
+
private
|
216
|
+
|
217
|
+
def convert(value)
|
218
|
+
value.respond_to?(:to_java) ? value.to_java : value
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
# We use prepend here instead of overriding the methods inside ValueCache module/interface
|
223
|
+
# because the methods are defined in the implementation class
|
224
|
+
$sharedCache.class.prepend(ValueConverter)
|
187
225
|
end
|
188
226
|
end
|
189
227
|
end
|
data/lib/openhab/core.rb
CHANGED
@@ -13,6 +13,8 @@ module OpenHAB
|
|
13
13
|
V4_2 = Gem::Version.new("4.2.0").freeze
|
14
14
|
# @!visibility private
|
15
15
|
V4_3 = Gem::Version.new("4.3.0").freeze
|
16
|
+
# @!visibility private
|
17
|
+
V5_0 = Gem::Version.new("5.0.0").freeze
|
16
18
|
|
17
19
|
# @return [Gem::Version] Returns the current openHAB version as a Gem::Version object
|
18
20
|
# Note, this strips off snapshots, milestones and RC versions and returns the release version.
|
@@ -21,6 +23,21 @@ module OpenHAB
|
|
21
23
|
@version ||= Gem::Version.new(VERSION).release.freeze
|
22
24
|
end
|
23
25
|
|
26
|
+
#
|
27
|
+
# Returns the full version of openHAB
|
28
|
+
#
|
29
|
+
# The {version} method returns the release version, stripping off any
|
30
|
+
# additional qualifiers such as M1, or snapshots.
|
31
|
+
# This method returns the full version string, including the qualifiers.
|
32
|
+
#
|
33
|
+
# @return [Gem::Version] Returns the full version of openHAB
|
34
|
+
#
|
35
|
+
# @!visibility private
|
36
|
+
#
|
37
|
+
def self.full_version
|
38
|
+
@full_version ||= Gem::Version.new(VERSION).freeze
|
39
|
+
end
|
40
|
+
|
24
41
|
raise "`openhab-scripting` requires openHAB >= 4.1.0" unless version >= V4_1
|
25
42
|
|
26
43
|
# @return [Integer] Number of seconds to wait between checks for automation manager
|