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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3c7147931d90e0b4f5c7d16fb324ac46f6ddd579e25c32245c49fc1c4a770120
4
- data.tar.gz: 718a8d07104975de5fd75900ba97b743319e8a18ff4076dc811ae7b5b0ffbdc5
3
+ metadata.gz: dcf7591d994378fb216137014e04dae3321ba891e11f201336e1afc6f1b7226b
4
+ data.tar.gz: d9917f8c8f5ead81623e39b3c606ab0f4efe7da519f654b081498bd743ebc721
5
5
  SHA512:
6
- metadata.gz: '0998824497c882bc59e935f13a28aeda241c0f399428ab90403b817e4b4f664db37d2c2225b9ff356535e3cb2ae478f8b091ab09cfda1d091142ae7b0e6ccc85'
7
- data.tar.gz: 72037d1a9d371458716fbc88955858d6a615dfc089878226cbb0109706df7c7a9d77f9ebc9001581a0f379e8785a7f752d060369dacb152bdefb5be9bdcbbc89
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
- # A {ContactItem} can be used for sensors that return an "open" or
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
- # @example Update from a base 64 encode image string
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 [SemanticTag] point_or_property_types
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(*point_or_property_types)
553
- return members.points(*point_or_property_types) if equipment? || location?
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(*point_or_property_types) || []
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
- result.select! { |i| types.any? { |type| i.location_type <= type } } unless types.empty?
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
- result.select! { |i| types.any? { |type| i.equipment_type <= type } } unless types.empty?
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
- (tag < Semantics::Point && point.point_type&.<=(tag)) ||
656
- (tag < Semantics::Property && point.property_type&.<=(tag))
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
@@ -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
@@ -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.to_s)
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.to_s, &)
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.to_s, value)
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 Objects to create trigger for.
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, or Things::Registry"
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 Items to create trigger for
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 or GroupItem::Members"
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 ThingUID"
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
- else
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 = if item.is_a?(GroupItem::Members)
29
+ type, config = case item
30
+ when GroupItem::Members
30
31
  [GROUP_COMMAND, { "groupName" => item.group.name }]
31
- else
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
- else
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
@@ -4,6 +4,6 @@ module OpenHAB
4
4
  module DSL
5
5
  # Version of openHAB helper libraries
6
6
  # @return [String]
7
- VERSION = "5.37.0"
7
+ VERSION = "5.38.0"
8
8
  end
9
9
  end
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
 
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This is the default 'require' file in a Gemfile
4
+
5
+ return unless defined?(Java::OrgOpenhabCore::OpenHAB)
6
+
7
+ require_relative "dsl"
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.37.0
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: 2025-03-25 00:00:00.000000000 Z
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.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: []