openhab-scripting 5.37.0 → 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 +4 -0
- 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
- 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: dcf7591d994378fb216137014e04dae3321ba891e11f201336e1afc6f1b7226b
|
4
|
+
data.tar.gz: d9917f8c8f5ead81623e39b3c606ab0f4efe7da519f654b081498bd743ebc721
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 78aa38c7c90b81ead46d438543077abb55bf06db1476f6e73cf36577f4df10c3b305e5169de2df2580f7d1d963fd8e5a998521764d9377305f87717ff216fff5
|
7
|
+
data.tar.gz: 9a410509dc518a5019c3885d5123c8a1840a0a70c6abb99df85cdbc11897eb7d5367d6014c71ff16759baebe03083a409f8f254606f0fab22a51ef50f2cdcdc6
|
@@ -13,6 +13,14 @@ module OpenHAB
|
|
13
13
|
class ItemStateChangedEvent < ItemEvent
|
14
14
|
include ItemState
|
15
15
|
|
16
|
+
# @!attribute [r] last_state_update
|
17
|
+
# @return [ZonedDateTime] the time the previous state update occurred
|
18
|
+
# @since openHAB 5.0
|
19
|
+
|
20
|
+
# @!attribute [r] last_state_change
|
21
|
+
# @return [ZonedDateTime] the time the previous state change occurred
|
22
|
+
# @since openHAB 5.0
|
23
|
+
|
16
24
|
# @!method was_undef?
|
17
25
|
# Check if {#was} is {UNDEF}
|
18
26
|
# @return [true, false]
|
@@ -74,6 +82,9 @@ module OpenHAB
|
|
74
82
|
def inspect
|
75
83
|
s = "#<OpenHAB::Core::Events::ItemStateChangedEvent item=#{item_name} " \
|
76
84
|
"state=#{item_state.inspect} was=#{old_item_state.inspect}"
|
85
|
+
# @deprecated OH4.3 remove respond_to? checks in the next two lines when dropping OH 4.3
|
86
|
+
s += " last_state_update=#{last_state_update}" if respond_to?(:last_state_update) && last_state_update
|
87
|
+
s += " last_state_change=#{last_state_change}" if respond_to?(:last_state_change) && last_state_change
|
77
88
|
s += " source=#{source.inspect}" if source
|
78
89
|
"#{s}>"
|
79
90
|
end
|
@@ -14,6 +14,19 @@ module OpenHAB
|
|
14
14
|
#
|
15
15
|
class ItemStateUpdatedEvent < ItemEvent
|
16
16
|
include ItemState
|
17
|
+
|
18
|
+
# @!attribute [r] last_state_update
|
19
|
+
# @return [ZonedDateTime] the time the previous state update occurred
|
20
|
+
# @since openHAB 5.0
|
21
|
+
|
22
|
+
# @return [String]
|
23
|
+
def inspect
|
24
|
+
s = "#<OpenHAB::Core::Events::ItemStateUpdatedEvent item=#{item_name} state=#{item_state.inspect}"
|
25
|
+
# @deprecated OH4.3 remove respond_to? check when dropping OH 4.3
|
26
|
+
s += " last_state_update=#{last_state_update}" if respond_to?(:last_state_update) && last_state_update
|
27
|
+
s += " source=#{source.inspect}" if source
|
28
|
+
"#{s}>"
|
29
|
+
end
|
17
30
|
end
|
18
31
|
end
|
19
32
|
end
|
@@ -13,6 +13,10 @@ module OpenHAB
|
|
13
13
|
# @!attribute [r] state
|
14
14
|
# @return [StringListType, nil]
|
15
15
|
#
|
16
|
+
# @!attribute [r] was
|
17
|
+
# @return [StringListType, nil]
|
18
|
+
# @since openHAB 5.0
|
19
|
+
#
|
16
20
|
class CallItem < GenericItem
|
17
21
|
# @!visibility private
|
18
22
|
def format_type(command)
|
@@ -35,6 +35,10 @@ module OpenHAB
|
|
35
35
|
# @!attribute [r] state
|
36
36
|
# @return [HSBType, nil]
|
37
37
|
#
|
38
|
+
# @!attribute [r] was
|
39
|
+
# @return [HSBType, nil]
|
40
|
+
# @since openHAB 5.0
|
41
|
+
#
|
38
42
|
class ColorItem < DimmerItem
|
39
43
|
# Make sure to do the String => HSBType conversion in Ruby,
|
40
44
|
# where we add support for hex
|
@@ -8,7 +8,7 @@ module OpenHAB
|
|
8
8
|
java_import org.openhab.core.library.items.ContactItem
|
9
9
|
|
10
10
|
#
|
11
|
-
#
|
11
|
+
# A {ContactItem} can be used for sensors that return an "open" or
|
12
12
|
# "closed" as a state.
|
13
13
|
#
|
14
14
|
# This is useful for doors, windows, etc.
|
@@ -16,6 +16,10 @@ module OpenHAB
|
|
16
16
|
# @!attribute [r] state
|
17
17
|
# @return [OpenClosedType, nil]
|
18
18
|
#
|
19
|
+
# @!attribute [r] was
|
20
|
+
# @return [OpenClosedType, nil]
|
21
|
+
# @since openHAB 5.0
|
22
|
+
#
|
19
23
|
# @example
|
20
24
|
# rule 'Log state of all doors on system startup' do
|
21
25
|
# on_load
|
@@ -30,20 +34,29 @@ module OpenHAB
|
|
30
34
|
# end
|
31
35
|
# end
|
32
36
|
#
|
37
|
+
# @!method open?
|
38
|
+
# Check if the item state == {OPEN}
|
39
|
+
# @return [true,false]
|
40
|
+
#
|
41
|
+
# @example Log open contacts
|
42
|
+
# Contacts.select(&:open?).each { |contact| logger.info("Contact #{contact.name} is open")}
|
43
|
+
#
|
44
|
+
# @!method closed?
|
45
|
+
# Check if the item state == {CLOSED}
|
46
|
+
# @return [true,false]
|
47
|
+
#
|
48
|
+
# @example Log closed contacts
|
49
|
+
# Contacts.select(&:closed?).each { |contact| logger.info("Contact #{contact.name} is closed")}
|
50
|
+
#
|
51
|
+
# @!method was_open?
|
52
|
+
# Check if {#was} is {OPEN}
|
53
|
+
# @return [true, false]
|
54
|
+
#
|
55
|
+
# @!method was_closed?
|
56
|
+
# Check if {#was} is {CLOSED}
|
57
|
+
# @return [true, false]
|
58
|
+
#
|
33
59
|
class ContactItem < GenericItem
|
34
|
-
# @!method open?
|
35
|
-
# Check if the item state == {OPEN}
|
36
|
-
# @return [true,false]
|
37
|
-
#
|
38
|
-
# @example Log open contacts
|
39
|
-
# Contacts.select(&:open?).each { |contact| logger.info("Contact #{contact.name} is open")}
|
40
|
-
|
41
|
-
# @!method closed?
|
42
|
-
# Check if the item state == {CLOSED}
|
43
|
-
# @return [true,false]
|
44
|
-
#
|
45
|
-
# @example Log closed contacts
|
46
|
-
# Contacts.select(&:closed?).each { |contact| logger.info("Contact #{contact.name} is closed")}
|
47
60
|
end
|
48
61
|
end
|
49
62
|
end
|
@@ -13,6 +13,10 @@ module OpenHAB
|
|
13
13
|
# @!attribute [r] state
|
14
14
|
# @return [DateTimeType, nil]
|
15
15
|
#
|
16
|
+
# @!attribute [r] was
|
17
|
+
# @return [DateTimeType, nil]
|
18
|
+
# @since openHAB 5.0
|
19
|
+
#
|
16
20
|
# @example DateTime items can be updated and commanded with Ruby Time objects or Java ZonedDateTime objects
|
17
21
|
# Example_DateTimeItem << Time.now
|
18
22
|
# Example_DateTimeItem << ZonedDateTime.now
|
@@ -15,6 +15,10 @@ module OpenHAB
|
|
15
15
|
# @!attribute [r] state
|
16
16
|
# @return [PercentType, nil]
|
17
17
|
#
|
18
|
+
# @!attribute [r] was
|
19
|
+
# @return [PercentType, nil]
|
20
|
+
# @since openHAB 5.0
|
21
|
+
#
|
18
22
|
# @example
|
19
23
|
# DimmerOne << DimmerOne.state - 5
|
20
24
|
# DimmerOne << 100 - DimmerOne.state
|
@@ -79,10 +79,45 @@ module OpenHAB
|
|
79
79
|
# [Ruby safe navigation operator `&.`](https://docs.ruby-lang.org/en/master/syntax/calling_methods_rdoc.html#label-Safe+Navigation+Operator)
|
80
80
|
# Use {#undef?} or {#null?} to check for those states.
|
81
81
|
#
|
82
|
+
# @see was
|
83
|
+
#
|
82
84
|
def state
|
83
85
|
raw_state if state?
|
84
86
|
end
|
85
87
|
|
88
|
+
# @!method was_undef?
|
89
|
+
# Check if {#was} is {UNDEF}
|
90
|
+
# @return [true, false]
|
91
|
+
|
92
|
+
# @!method was_null?
|
93
|
+
# Check if {#was} is {NULL}
|
94
|
+
# @return [true, false]
|
95
|
+
|
96
|
+
#
|
97
|
+
# Check if the item's previous state was not `nil`, {UNDEF} or {NULL}
|
98
|
+
#
|
99
|
+
# @return [true, false]
|
100
|
+
#
|
101
|
+
# @since openHAB 5.0
|
102
|
+
#
|
103
|
+
def was?
|
104
|
+
!last_state.nil? && !last_state.is_a?(Types::UnDefType)
|
105
|
+
end
|
106
|
+
|
107
|
+
#
|
108
|
+
# @!attribute [r] was
|
109
|
+
#
|
110
|
+
# @return [State] The previous state of the item. nil if the item was never updated, or
|
111
|
+
# if the item was updated to {NULL} or {UNDEF}.
|
112
|
+
# @since openHAB 5.0
|
113
|
+
#
|
114
|
+
# @see state
|
115
|
+
# @see Item#last_state
|
116
|
+
#
|
117
|
+
def was
|
118
|
+
last_state if was?
|
119
|
+
end
|
120
|
+
|
86
121
|
# @!method null?
|
87
122
|
# Check if the item state == {NULL}
|
88
123
|
# @return [true,false]
|
@@ -18,7 +18,11 @@ module OpenHAB
|
|
18
18
|
# @!attribute [r] state
|
19
19
|
# @return [RawType, nil]
|
20
20
|
#
|
21
|
-
#
|
21
|
+
# @!attribute [r] was
|
22
|
+
# @return [RawType, nil]
|
23
|
+
# @since openHAB 5.0
|
24
|
+
#
|
25
|
+
# @example Update from a base 64 encoded image string
|
22
26
|
# Image.update("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=")
|
23
27
|
#
|
24
28
|
# @example Update from image bytes and mime type
|
@@ -70,6 +70,18 @@ module OpenHAB
|
|
70
70
|
# @!attribute [r] command_description
|
71
71
|
# @return [Types::CommandDescription, nil]
|
72
72
|
|
73
|
+
# @!attribute [r] last_state
|
74
|
+
# @return [State] The previous state of the item.
|
75
|
+
# @since openHAB 5.0
|
76
|
+
|
77
|
+
# @!attribute [r] last_state_change
|
78
|
+
# @return [ZonedDateTime] The time of the last state change.
|
79
|
+
# @since openHAB 5.0
|
80
|
+
|
81
|
+
# @!attribute [r] last_state_update
|
82
|
+
# @return [ZonedDateTime] The time of the last state update.
|
83
|
+
# @since openHAB 5.0
|
84
|
+
|
73
85
|
#
|
74
86
|
# The item's {GenericItem#label label} if one is defined, otherwise its {#name}.
|
75
87
|
#
|
@@ -550,6 +562,12 @@ module OpenHAB
|
|
550
562
|
# @return [String]
|
551
563
|
def inspect
|
552
564
|
s = "#<OpenHAB::Core::Items::#{type}Item#{type_details} #{name} #{label.inspect} state=#{raw_state.inspect}"
|
565
|
+
# @deprecated OH 4.3 Remove if guard when dropping support for OH 4.3
|
566
|
+
if respond_to?(:last_state)
|
567
|
+
s += " last_state=#{last_state.inspect}" if last_state
|
568
|
+
s += " last_state_update=#{last_state_update}" if last_state_update
|
569
|
+
s += " last_state_change=#{last_state_change}" if last_state_change
|
570
|
+
end
|
553
571
|
s += " category=#{category.inspect}" if category
|
554
572
|
s += " tags=#{tags.to_a.inspect}" unless tags.empty?
|
555
573
|
s += " groups=#{group_names}" unless group_names.empty?
|
@@ -16,6 +16,10 @@ module OpenHAB
|
|
16
16
|
# @!attribute [r] state
|
17
17
|
# @return [PointType, nil]
|
18
18
|
#
|
19
|
+
# @!attribute [r] was
|
20
|
+
# @return [PointType, nil]
|
21
|
+
# @since openHAB 5.0
|
22
|
+
#
|
19
23
|
# @example Send point commands
|
20
24
|
# Location << '30,20' # latitude of 30, longitude of 20
|
21
25
|
# Location << '30,20,80' # latitude of 30, longitude of 20, altitude of 80
|
@@ -25,6 +25,9 @@ module OpenHAB
|
|
25
25
|
# @return [javax.measure.Unit, nil]
|
26
26
|
# @!attribute [r] state
|
27
27
|
# @return [DecimalType, QuantityType, nil]
|
28
|
+
# @!attribute [r] was
|
29
|
+
# @return [DecimalType, QuantityType, nil]
|
30
|
+
# @since openHAB 5.0
|
28
31
|
#
|
29
32
|
# @example Number Items can be selected in an enumerable with grep.
|
30
33
|
# # Get all NumberItems
|
@@ -623,6 +623,7 @@ module OpenHAB
|
|
623
623
|
# Returns the time the item was last updated.
|
624
624
|
# @param [Symbol, String] service An optional persistence id instead of the default persistence service.
|
625
625
|
# @return [ZonedDateTime, nil] The timestamp of the last update
|
626
|
+
# @see Item#last_state_update
|
626
627
|
|
627
628
|
# @!method next_update(service = nil)
|
628
629
|
# Returns the first future update time of the item.
|
@@ -636,6 +637,7 @@ module OpenHAB
|
|
636
637
|
# @param [Symbol, String] service An optional persistence id instead of the default persistence service.
|
637
638
|
# @return [ZonedDateTime, nil] The timestamp of the last update
|
638
639
|
# @since openHAB 4.2
|
640
|
+
# @see Item#last_state_change
|
639
641
|
|
640
642
|
# @!method next_change(service = nil)
|
641
643
|
# Returns the first future change time of the item.
|
@@ -670,6 +672,8 @@ module OpenHAB
|
|
670
672
|
# @return [PersistedState, nil] the previous state or nil if no previous state could be found,
|
671
673
|
# or if the default persistence service is not configured or
|
672
674
|
# does not refer to a valid service
|
675
|
+
#
|
676
|
+
# @see Item#last_state
|
673
677
|
|
674
678
|
# @!method next_state(service = nil, skip_equal: false)
|
675
679
|
# Return the next state of the item
|
@@ -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
|
@@ -1059,7 +1059,11 @@ module OpenHAB
|
|
1059
1059
|
# {Core::Events::ThingStatusInfoChangedEvent} depending on if the
|
1060
1060
|
# triggering element was an item or a thing.
|
1061
1061
|
#
|
1062
|
-
# @param [Item, GroupItem::Members, Thing, ThingUID, Things::Registry] items
|
1062
|
+
# @param [Item, GroupItem::Members, Thing, ThingUID, Things::Registry, String] items
|
1063
|
+
# Objects to create trigger for.
|
1064
|
+
# When a String is provided, it is assumed to be an item or group name, unless when it
|
1065
|
+
# contains a colon, in which case it is assumed to be a thing UID.
|
1066
|
+
# The String may contain `*` and `?` wildcards since openHAB 5.0.
|
1063
1067
|
# @param [State, Array<State>, #===, nil] from
|
1064
1068
|
# Only execute rule if previous state matches `from` state(s).
|
1065
1069
|
# @param [State, Array<State>, #===, nil] to
|
@@ -1149,11 +1153,25 @@ module OpenHAB
|
|
1149
1153
|
# @example Trigger when any Thing changes status
|
1150
1154
|
# rule "Thing status monitoring" do
|
1151
1155
|
# changed things, to: :offline
|
1156
|
+
# # Alternatively, you can use the following:
|
1157
|
+
# # changed "*:*", to: :offline
|
1152
1158
|
# run do |event|
|
1153
1159
|
# Notification.send("Thing #{event.thing.uid} is offline")
|
1154
1160
|
# end
|
1155
1161
|
# end
|
1156
1162
|
#
|
1163
|
+
# @example Use Item wildcards (since openHAB 5.0)
|
1164
|
+
# rule "Execute rule when the state of a matching item changed" do
|
1165
|
+
# changed "*_Door", to: OPEN
|
1166
|
+
# run { |event| logger.info("Item #{event.item.name} changed to #{event.state}") }
|
1167
|
+
# end
|
1168
|
+
#
|
1169
|
+
# @example Use Thing wildcards (since openHAB 5.0)
|
1170
|
+
# rule "Execute rule when a matching thing changed status" do
|
1171
|
+
# changed "mqtt:topic:*light*", to: :online
|
1172
|
+
# run { |event| logger.info("Thing #{event.thing.uid} changed to #{event.status}") }
|
1173
|
+
# end
|
1174
|
+
#
|
1157
1175
|
# @example Real World Example
|
1158
1176
|
# rule "Log (or notify) when an exterior door is left open for more than 5 minutes" do
|
1159
1177
|
# changed ExteriorDoors.members, to: OPEN, for: 5.minutes
|
@@ -1175,11 +1193,12 @@ module OpenHAB
|
|
1175
1193
|
Core::Things::ThingUID,
|
1176
1194
|
Core::Things::Registry,
|
1177
1195
|
Core::Items::Item,
|
1178
|
-
Core::Items::GroupItem::Members
|
1196
|
+
Core::Items::GroupItem::Members,
|
1197
|
+
String
|
1179
1198
|
nil
|
1180
1199
|
else
|
1181
1200
|
raise ArgumentError,
|
1182
|
-
"items must be an Item, GroupItem::Members, Thing, ThingUID,
|
1201
|
+
"items must be an Item, GroupItem::Members, Thing, ThingUID, Things::Registry, or a String"
|
1183
1202
|
end
|
1184
1203
|
|
1185
1204
|
logger.trace { "Creating changed trigger for entity(#{item}), to(#{to.inspect}), from(#{from.inspect})" }
|
@@ -1531,7 +1550,10 @@ module OpenHAB
|
|
1531
1550
|
# The `event` passed to run blocks will be an
|
1532
1551
|
# {Core::Events::ItemCommandEvent}.
|
1533
1552
|
#
|
1534
|
-
# @param [Item, GroupItem::Members] items
|
1553
|
+
# @param [Item, GroupItem::Members, String] items
|
1554
|
+
# Items to create trigger for.
|
1555
|
+
# When a String is provided, it is assumed to be an item or group name.
|
1556
|
+
# The String may contain `*` and `?` wildcards since openHAB 5.0.
|
1535
1557
|
# @param [Core::Types::Command, Array<Core::Types::Command>, #===, nil] command commands to match for trigger
|
1536
1558
|
# @param [Array<Core::Types::Command>, #===, nil] commands Fluent alias for `command`
|
1537
1559
|
# @param [Object] attach object to be attached to the trigger
|
@@ -1597,6 +1619,12 @@ module OpenHAB
|
|
1597
1619
|
# run { |event| logger.info("Item received command: #{event.command}" ) }
|
1598
1620
|
# end
|
1599
1621
|
#
|
1622
|
+
# @example Use Item wildcards (since openHAB 5.0)
|
1623
|
+
# rule 'Execute rule when the matching item received command' do
|
1624
|
+
# received_command '*_Light', command: ON
|
1625
|
+
# run { |event| logger.info("Item received command: #{event.command}") }
|
1626
|
+
# end
|
1627
|
+
#
|
1600
1628
|
def received_command(*items, command: nil, commands: nil, attach: nil)
|
1601
1629
|
command_trigger = Command.new(rule_triggers: @rule_triggers)
|
1602
1630
|
|
@@ -1610,10 +1638,11 @@ module OpenHAB
|
|
1610
1638
|
items.each do |item|
|
1611
1639
|
case item
|
1612
1640
|
when Core::Items::Item,
|
1613
|
-
Core::Items::GroupItem::Members
|
1641
|
+
Core::Items::GroupItem::Members,
|
1642
|
+
String
|
1614
1643
|
nil
|
1615
1644
|
else
|
1616
|
-
raise ArgumentError, "items must be an Item
|
1645
|
+
raise ArgumentError, "items must be an Item, GroupItem::Members, or a String"
|
1617
1646
|
end
|
1618
1647
|
commands.each do |cmd|
|
1619
1648
|
logger.trace { "Creating received command trigger for items #{item.inspect} and commands #{cmd.inspect}" }
|
@@ -1888,8 +1917,11 @@ module OpenHAB
|
|
1888
1917
|
# {Core::Events::ThingStatusInfoEvent} depending on if the triggering
|
1889
1918
|
# element was an item or a thing.
|
1890
1919
|
#
|
1891
|
-
# @param [Item, GroupItem::Members, Thing] items
|
1920
|
+
# @param [Item, GroupItem::Members, Thing, String] items
|
1892
1921
|
# Objects to create trigger for.
|
1922
|
+
# When a String is provided, it is assumed to be an item or group name, unless when it
|
1923
|
+
# contains a colon, in which case it is assumed to be a thing UID.
|
1924
|
+
# The String may contain `*` and `?` wildcards since openHAB 5.0.
|
1893
1925
|
# @param [State, Array<State>, Symbol, String, #===, nil] to
|
1894
1926
|
# Only execute rule if the state matches `to` state(s). If the
|
1895
1927
|
# updated element is a {Core::Things::Thing}, the `to` accepts
|
@@ -1964,6 +1996,19 @@ module OpenHAB
|
|
1964
1996
|
# run { |event| logger.info("Thing #{event.uid} status <trigger> to #{event.status}") }
|
1965
1997
|
# end
|
1966
1998
|
#
|
1999
|
+
# @example Use Item wildcards (since openHAB 5.0)
|
2000
|
+
# rule 'Execute rule when the state of a matching item is updated' do
|
2001
|
+
# updated '*_Door', to: OPEN
|
2002
|
+
# run { |event| logger.info("Item #{event.item.name} updated to #{event.state}") }
|
2003
|
+
# end
|
2004
|
+
#
|
2005
|
+
# @example Use Thing wildcards (since openHAB 5.0)
|
2006
|
+
# rule 'Execute rule when the status of a matching thing is updated' do
|
2007
|
+
# updated 'mqtt:topic:*light*', to: :online
|
2008
|
+
# # to match all things, use "*:*" as the pattern
|
2009
|
+
# run { |event| logger.info("Thing #{event.thing.uid} updated to #{event.status}") }
|
2010
|
+
# end
|
2011
|
+
#
|
1967
2012
|
def updated(*items, to: nil, attach: nil)
|
1968
2013
|
updated = Updated.new(rule_triggers: @rule_triggers)
|
1969
2014
|
@ruby_triggers << [:updated, items, { to: }]
|
@@ -1972,10 +2017,11 @@ module OpenHAB
|
|
1972
2017
|
when Core::Things::Thing,
|
1973
2018
|
Core::Things::ThingUID,
|
1974
2019
|
Core::Items::Item,
|
1975
|
-
Core::Items::GroupItem::Members
|
2020
|
+
Core::Items::GroupItem::Members,
|
2021
|
+
String
|
1976
2022
|
nil
|
1977
2023
|
else
|
1978
|
-
raise ArgumentError, "items must be an Item, GroupItem::Members, Thing, or
|
2024
|
+
raise ArgumentError, "items must be an Item, GroupItem::Members, Thing, ThingUID, or a String"
|
1979
2025
|
end
|
1980
2026
|
|
1981
2027
|
logger.trace { "Creating updated trigger for item(#{item}) to(#{to})" }
|
@@ -82,8 +82,16 @@ module OpenHAB
|
|
82
82
|
thing(thing: item, from:, to:)
|
83
83
|
when Core::Things::Registry
|
84
84
|
thing(thing: "*", from:, to:)
|
85
|
-
|
85
|
+
when Core::Items::Item
|
86
86
|
item(item:, from:, to:)
|
87
|
+
when Core::Items::Registry
|
88
|
+
item(item: "*", from:, to:)
|
89
|
+
else
|
90
|
+
if item.to_s.include?(":")
|
91
|
+
thing(thing: item, from:, to:)
|
92
|
+
else
|
93
|
+
item(item:, from:, to:)
|
94
|
+
end
|
87
95
|
end
|
88
96
|
append_trigger(type:, config:, attach:, conditions:, label:)
|
89
97
|
end
|
@@ -113,7 +121,7 @@ module OpenHAB
|
|
113
121
|
# second element is a Hash configuring trigger
|
114
122
|
#
|
115
123
|
def item(item:, from:, to:)
|
116
|
-
config = { "itemName" => item.name }
|
124
|
+
config = { "itemName" => item.is_a?(Item) ? item.name : item.to_s }
|
117
125
|
config["state"] = to.to_s if to
|
118
126
|
config["previousState"] = from.to_s if from
|
119
127
|
[ITEM_STATE_CHANGE, config]
|
@@ -26,10 +26,13 @@ module OpenHAB
|
|
26
26
|
command = nil
|
27
27
|
end
|
28
28
|
|
29
|
-
type, config =
|
29
|
+
type, config = case item
|
30
|
+
when GroupItem::Members
|
30
31
|
[GROUP_COMMAND, { "groupName" => item.group.name }]
|
31
|
-
|
32
|
+
when Item
|
32
33
|
[ITEM_COMMAND, { "itemName" => item.name }]
|
34
|
+
else
|
35
|
+
[ITEM_COMMAND, { "itemName" => item.to_s }]
|
33
36
|
end
|
34
37
|
config["command"] = command.to_s unless command.nil?
|
35
38
|
append_trigger(type:, config:, attach:, conditions:)
|
@@ -29,11 +29,16 @@ module OpenHAB
|
|
29
29
|
type, config = case item
|
30
30
|
when GroupItem::Members
|
31
31
|
group_update(item:, to:)
|
32
|
-
when Core::Things::Thing,
|
33
|
-
Core::Things::ThingUID
|
32
|
+
when Core::Things::Thing, Core::Things::ThingUID
|
34
33
|
thing_update(thing: item, to:)
|
35
|
-
|
34
|
+
when Core::Items::Item
|
36
35
|
item_update(item:, to:)
|
36
|
+
else
|
37
|
+
if item.to_s.include?(":")
|
38
|
+
thing_update(thing: item, to:)
|
39
|
+
else
|
40
|
+
item_update(item:, to:)
|
41
|
+
end
|
37
42
|
end
|
38
43
|
append_trigger(type:, config:, attach:, conditions:)
|
39
44
|
end
|
@@ -62,7 +67,7 @@ module OpenHAB
|
|
62
67
|
# second element is a Hash configuring trigger
|
63
68
|
#
|
64
69
|
def item_update(item:, to:)
|
65
|
-
config = { "itemName" => item.name }
|
70
|
+
config = { "itemName" => item.is_a?(Item) ? item.name : item.to_s }
|
66
71
|
config["state"] = to.to_s unless to.nil?
|
67
72
|
[ITEM_STATE_UPDATE, config]
|
68
73
|
end
|
data/lib/openhab/dsl/version.rb
CHANGED
data/lib/openhab/dsl.rb
CHANGED
@@ -296,6 +296,19 @@ module OpenHAB
|
|
296
296
|
# own instance of the timers object, so you don't need to worry about collisions among
|
297
297
|
# different files.
|
298
298
|
#
|
299
|
+
# ### Sharing Timers with other scripts
|
300
|
+
#
|
301
|
+
# When a timer is stored in the {shared_cache}, it will automatically be converted into
|
302
|
+
# an openHAB Timer object. It can then be used in other scripts or UI rules,
|
303
|
+
# written in JRuby or other supported languages.
|
304
|
+
#
|
305
|
+
# Timers are normally managed by TimerManager, and are normally automatically cancelled
|
306
|
+
# when the script unloads/reloads.
|
307
|
+
# To disable this automatic timer cancellation at script unload, call {Core::Timer#unmanage}.
|
308
|
+
#
|
309
|
+
# openHAB will cancel the timer stored in the {OpenHAB::DSL.shared_cache shared_cache}
|
310
|
+
# and remove the cache entry when all the scripts that _had accessed_ it have been unloaded.
|
311
|
+
#
|
299
312
|
# @see timers
|
300
313
|
# @see Rules::BuilderDSL#changed
|
301
314
|
# @see Items::TimedCommand
|
@@ -377,6 +390,19 @@ module OpenHAB
|
|
377
390
|
# end
|
378
391
|
# end
|
379
392
|
#
|
393
|
+
# @example Timers can be shared with other scripts
|
394
|
+
# # script1.rb:
|
395
|
+
# timer = after(10.hours) { logger.warn "Timer created in script1.rb fired" }
|
396
|
+
# shared_cache[:script1_timer] = timer
|
397
|
+
#
|
398
|
+
# # inside a different JRuby UI rule or script:
|
399
|
+
# # This is an openHAB timer object, not a JRuby timer object
|
400
|
+
# # the reschedule method expects a ZonedDateTime
|
401
|
+
# shared_cache[:script1_timer]&.reschedule(10.seconds.from_now)
|
402
|
+
#
|
403
|
+
# # inside another JS script:
|
404
|
+
# cache.shared.get("script1_timer")?.cancel()
|
405
|
+
#
|
380
406
|
def after(duration, id: nil, reschedule: true, &block)
|
381
407
|
raise ArgumentError, "Block is required" unless block
|
382
408
|
|
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.38.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian O'Connell
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
- Jimmy Tanagra
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -433,6 +433,7 @@ files:
|
|
433
433
|
- lib/openhab/rspec/openhab/core/things/proxy.rb
|
434
434
|
- lib/openhab/rspec/shell.rb
|
435
435
|
- lib/openhab/rspec/suspend_rules.rb
|
436
|
+
- lib/openhab/scripting.rb
|
436
437
|
- lib/openhab/yard.rb
|
437
438
|
- lib/openhab/yard/base_helper.rb
|
438
439
|
- lib/openhab/yard/cli/stats.rb
|
@@ -478,7 +479,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
478
479
|
- !ruby/object:Gem::Version
|
479
480
|
version: '0'
|
480
481
|
requirements: []
|
481
|
-
rubygems_version: 3.6.
|
482
|
+
rubygems_version: 3.6.7
|
482
483
|
specification_version: 4
|
483
484
|
summary: JRuby Helper Libraries for openHAB Scripting
|
484
485
|
test_files: []
|