openhab-scripting 4.28.2 → 4.29.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: 7c9d9745b2590c4152baf18a82dbe0063ac4c73c94f6f452d9d848790d8eb06a
4
- data.tar.gz: 276152f1a79cf44fb539f4bb0c73618263db8d4a944cf367fa0ef1db167d989a
3
+ metadata.gz: 346933e8c00b9208f18ce61d4a87911cdc315a7b7ee1698aec1977dc47ba9bea
4
+ data.tar.gz: 5a94e6d5a1d43a4fd3e6586bd70a9f3286918bee1c300fe490d2460dbdce3494
5
5
  SHA512:
6
- metadata.gz: d66efa237735b6a754e97eb933a301cb5dd639fa7cc715fa7d36c3e6f7ed14c11a3da874ea707792cb0913bb9e57396b33532746b7a63b08acf50ff15d4fc9f0
7
- data.tar.gz: b2fcbb63e5e9da86909dd7b7b2bcb054b29aea1b80ae59fb26555a7aa678a7f4ebe04ee36dda69413c7cc8fbe08c7beeeaa5ad333e09d4bac08bbe2b769e85e7
6
+ metadata.gz: dcd2f7d6aa7b11074c059296b61b0fa22b691184915afe227ecf41d865690b6a81c8ea431c3b83407f05520aedca8238be4636f8da62217a0caf090d63bd8488
7
+ data.tar.gz: 1614e96cd679ebab6dfe811e7818e77e9e512603b126223f6a870f7b6550a2101cb86fe79f9856fe6559cc926cecf212afe15eb8a50892863c208b32d00f6386
@@ -45,7 +45,7 @@ module OpenHAB
45
45
  between = config.between&.yield_self { between(config.between) }
46
46
  @between = between || OpenHAB::DSL::Between::ALL_DAY
47
47
  # Convert between to correct range or nil if not set
48
- @trigger_delays = config.trigger_delays
48
+ @trigger_conditions = config.trigger_conditions
49
49
  @attachments = config.attachments
50
50
  end
51
51
  # rubocop:enable Metrics/MethodLength
@@ -57,18 +57,12 @@ module OpenHAB
57
57
  # @param [Map] inputs map provided by OpenHAB rules engine containing event and other information
58
58
  #
59
59
  #
60
- def execute(mod = nil, inputs = nil) # rubocop:disable Metrics/MethodLength
60
+ def execute(mod = nil, inputs = nil)
61
61
  thread_local(RULE_NAME: name) do
62
62
  logger.trace { "Execute called with mod (#{mod&.to_string}) and inputs (#{inputs&.pretty_inspect})" }
63
63
  logger.trace { "Event details #{inputs['event'].pretty_inspect}" } if inputs&.key?('event')
64
- if trigger_delay inputs
65
- trigger_delay = trigger_delay(inputs)
66
- process_trigger_delay(trigger_delay, mod, inputs)
67
- else
68
- # If guards are satisfied execute the run type blocks
69
- # If they are not satisfied, execute the Othewise blocks
70
- queue = create_queue(inputs)
71
- process_queue(queue, mod, inputs)
64
+ trigger_conditions(inputs).process(mod: mod, inputs: inputs) do
65
+ process_queue(create_queue(inputs), mod, inputs)
72
66
  end
73
67
  end
74
68
  end
@@ -124,18 +118,18 @@ module OpenHAB
124
118
  end
125
119
 
126
120
  #
127
- # Returns trigger delay from inputs if it exists
121
+ # Returns trigger conditions from inputs if it exists
128
122
  #
129
123
  # @param [Map] inputs map from OpenHAB containing UID
130
124
  #
131
- # @return [Array] Array of trigger delays that match rule UID
125
+ # @return [Array] Array of trigger conditions that match rule UID
132
126
  #
133
- def trigger_delay(inputs)
127
+ def trigger_conditions(inputs)
134
128
  # Parse this to get the trigger UID:
135
129
  # ["72698819-83cb-498a-8e61-5aab8b812623.event", "oldState", "module", \
136
130
  # "72698819-83cb-498a-8e61-5aab8b812623.oldState", "event", "newState",\
137
131
  # "72698819-83cb-498a-8e61-5aab8b812623.newState"]
138
- @trigger_delays[trigger_id(inputs)]
132
+ @trigger_conditions[trigger_id(inputs)]
139
133
  end
140
134
 
141
135
  # If an attachment exists for the trigger for this event add it to the event object
@@ -151,138 +145,6 @@ module OpenHAB
151
145
  event
152
146
  end
153
147
 
154
- #
155
- # Check if trigger guards prevent rule execution
156
- #
157
- # @param [Delay] trigger_delay rules delaying trigger because of
158
- # @param [Map] inputs OpenHAB map object describing rule trigger
159
- #
160
- # @return [Boolean] True if the rule should execute, false if trigger guard prevents execution
161
- #
162
- def check_trigger_guards(trigger_delay, inputs)
163
- new_state, old_state = retrieve_states(inputs)
164
- if check_from(trigger_delay, old_state)
165
- return true if check_to(trigger_delay, new_state)
166
-
167
- logger.trace("Skipped execution of rule '#{name}' because to state #{new_state}"\
168
- " does not equal specified state(#{trigger_delay.to})")
169
- else
170
- logger.trace("Skipped execution of rule '#{name}' because old state #{old_state}"\
171
- " does not equal specified state(#{trigger_delay.from})")
172
- end
173
- end
174
-
175
- #
176
- # Rerieve the newState and oldState, alternatively newStatus and oldStatus
177
- # from the input map
178
- #
179
- # @param [Map] inputs OpenHAB map object describing rule trigger
180
- #
181
- # @return [Array] An array of the values for [newState, oldState] or [newStatus, oldStatus]
182
- #
183
- def retrieve_states(inputs)
184
- old_state = inputs['oldState'] || thing_status_to_sym(inputs['oldStatus'])
185
- new_state = inputs['newState'] || thing_status_to_sym(inputs['newStatus'])
186
-
187
- [new_state, old_state]
188
- end
189
-
190
- #
191
- # Converts a ThingStatus object to a ruby Symbol
192
- #
193
- # @param [Java::OrgOpenhabCoreThing::ThingStatus] status A ThingStatus instance
194
- #
195
- # @return [Symbol] A corresponding symbol, in lower case
196
- #
197
- def thing_status_to_sym(status)
198
- status&.to_s&.downcase&.to_sym
199
- end
200
-
201
- #
202
- # Check the from state against the trigger delay
203
- #
204
- # @param [TriggerDelay] trigger_delay Information about the trigger delay
205
- # @param [Item State] state from state to check
206
- #
207
- # @return [Boolean] true if no from state is defined or defined state equals supplied state
208
- #
209
- def check_from(trigger_delay, state)
210
- trigger_delay.from.nil? || state == trigger_delay.from
211
- end
212
-
213
- #
214
- # Check the to state against the trigger delay
215
- #
216
- # @param [TriggerDelay] trigger_delay Information about the trigger delay
217
- # @param [Item State] state to-state to check
218
- #
219
- # @return [Boolean] true if no to state is defined or defined state equals supplied state
220
- #
221
- def check_to(trigger_delay, state)
222
- trigger_delay.to.nil? || state == trigger_delay.to
223
- end
224
-
225
- #
226
- # Process any matching trigger delays
227
- #
228
- # @param [Map] mod OpenHAB map object describing rule trigger
229
- # @param [Map] inputs OpenHAB map object describing rule trigger
230
- #
231
- #
232
- def process_trigger_delay(trigger_delay, mod, inputs)
233
- if trigger_delay.timer_active?
234
- process_active_timer(inputs, mod, trigger_delay)
235
- elsif check_trigger_guards(trigger_delay, inputs)
236
- logger.trace("Trigger Guards Matched for #{trigger_delay}, delaying rule execution")
237
- # Add timer and attach timer to delay object, and also state being tracked to so timer can be cancelled if
238
- # state changes
239
- # Also another timer should not be created if changed to same value again but instead rescheduled
240
- create_trigger_delay_timer(inputs, mod, trigger_delay)
241
- else
242
- logger.trace("Trigger Guards did not match for #{trigger_delay}, ignoring trigger.")
243
- end
244
- end
245
-
246
- #
247
- # Creatas a timer for trigger delays
248
- #
249
- # @param [Hash] inputs rule trigger inputs
250
- # @param [Hash] mod rule trigger mods
251
- # @param [TriggerDelay] trigger_delay specifications
252
- #
253
- #
254
- def create_trigger_delay_timer(inputs, mod, trigger_delay)
255
- logger.trace("Creating timer for rule #{name} and trigger delay #{trigger_delay}")
256
- trigger_delay.timer = after(trigger_delay.duration) do
257
- logger.trace("Delay Complete for #{trigger_delay}, executing rule")
258
- trigger_delay.timer = nil
259
- queue = create_queue(inputs)
260
- process_queue(queue, mod, inputs)
261
- end
262
- trigger_delay.tracking_to, = retrieve_states(inputs)
263
- end
264
-
265
- #
266
- # Process an active trigger timer
267
- #
268
- # @param [Hash] inputs rule trigger inputs
269
- # @param [Hash] mod rule trigger mods
270
- # @param [TriggerDelay] trigger_delay specifications
271
- #
272
- #
273
- def process_active_timer(inputs, mod, trigger_delay)
274
- state, = retrieve_states(inputs)
275
- if state == trigger_delay.tracking_to
276
- logger.trace("Item changed to #{state} for #{trigger_delay}, rescheduling timer.")
277
- trigger_delay.timer.reschedule(ZonedDateTime.now.plus(trigger_delay.duration))
278
- else
279
- logger.trace("Item changed to #{state} for #{trigger_delay}, canceling timer.")
280
- trigger_delay.timer.cancel
281
- # Reprocess trigger delay after canceling to track new state (if guards matched, etc)
282
- process_trigger_delay(trigger_delay, mod, inputs)
283
- end
284
- end
285
-
286
148
  #
287
149
  # Check if any guards prevent execution
288
150
  #
@@ -10,6 +10,7 @@ require_relative 'triggers/command'
10
10
  require_relative 'triggers/updated'
11
11
  require_relative 'triggers/generic'
12
12
  require_relative 'triggers/watch'
13
+ require_relative 'triggers/conditions/none'
13
14
  require_relative 'guard'
14
15
  require 'openhab/core/entity_lookup'
15
16
  require 'openhab/dsl/between'
@@ -37,7 +38,7 @@ module OpenHAB
37
38
  attr_accessor :triggers
38
39
 
39
40
  # @return [Array] Of trigger delays
40
- attr_reader :trigger_delays
41
+ attr_reader :trigger_conditions
41
42
 
42
43
  # @return [Hash] Hash of trigger UIDs to attachments
43
44
  attr_reader :attachments
@@ -86,7 +87,7 @@ module OpenHAB
86
87
  #
87
88
  def initialize(rule_name, caller_binding)
88
89
  @triggers = []
89
- @trigger_delays = {}
90
+ @trigger_conditions = Hash.new(OpenHAB::DSL::Rules::Triggers::Conditions::None.instance)
90
91
  @attachments = {}
91
92
  @caller = caller_binding.eval 'self'
92
93
  name(rule_name)
@@ -145,7 +146,7 @@ module OpenHAB
145
146
  "Triggers: (#{triggers}) " \
146
147
  "Run blocks: (#{run}) " \
147
148
  "on_start: (#{on_start?}) " \
148
- "Trigger Waits: #{trigger_delays} " \
149
+ "Trigger Conditions: #{trigger_conditions} " \
149
150
  "Trigger UIDs: #{triggers.map(&:id).join(', ')}" \
150
151
  "Attachments: #{attachments} "
151
152
  end
@@ -1,25 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'openhab/log/logger'
4
+ require_relative 'conditions/duration'
5
+ require_relative 'conditions/range'
4
6
 
5
7
  module OpenHAB
6
8
  module DSL
7
9
  module Rules
8
10
  #
9
- # Module holds rule triggers
11
+ # Module for changed triggers
10
12
  #
13
+
11
14
  module Triggers
12
15
  include OpenHAB::Log
13
16
 
14
- #
15
- # Struct capturing data necessary for a conditional trigger
16
- #
17
- TriggerDelay = Struct.new(:to, :from, :duration, :timer, :tracking_to, keyword_init: true) do
18
- def timer_active?
19
- timer&.is_active
20
- end
21
- end
22
-
23
17
  #
24
18
  # Creates a trigger item, group and thing changed
25
19
  #
@@ -38,7 +32,7 @@ module OpenHAB
38
32
  wait_duration = binding.local_variable_get(:for)
39
33
 
40
34
  each_state(from, to) do |from_state, to_state|
41
- changed_or_wait(item, from_state, to_state, wait_duration, attach)
35
+ changed_trigger(item, from_state, to_state, wait_duration, attach)
42
36
  end
43
37
  end.flatten
44
38
  end
@@ -65,7 +59,7 @@ module OpenHAB
65
59
  end
66
60
 
67
61
  #
68
- # Create regular or delayed trigger based on duration
62
+ # Create the trigger
69
63
  #
70
64
  # @param [Object] item item to create trigger for
71
65
  # @param [Item State] from state to restrict trigger to
@@ -75,9 +69,11 @@ module OpenHAB
75
69
  #
76
70
  # @return [Trigger] OpenHAB triggers
77
71
  #
78
- def changed_or_wait(item, from, to, duration, attach)
72
+ def changed_trigger(item, from, to, duration, attach)
79
73
  if duration
80
74
  changed_wait(item, from: from, to: to, duration: duration, attach: attach)
75
+ elsif [to, from].grep(Range).any?
76
+ create_changed_range_trigger(item, from: from, to: to, attach: attach)
81
77
  else
82
78
  create_changed_trigger(item, from, to, attach)
83
79
  end
@@ -90,13 +86,31 @@ module OpenHAB
90
86
  # @param [OpenHAB::Core::Duration] duration to delay trigger for until condition is met
91
87
  # @param [Item State] to OpenHAB Item State item or group needs to change to
92
88
  # @param [Item State] from OpenHAB Item State item or group needs to be coming from
89
+ # @param [Object] attach to trigger
93
90
  #
94
91
  # @return [Trigger] OpenHAB trigger
95
92
  #
96
93
  def changed_wait(item, duration:, to: nil, from: nil, attach: nil)
97
94
  trigger = create_changed_trigger(item, nil, nil, attach)
98
95
  logger.trace("Creating Changed Wait Change Trigger for #{item}")
99
- @trigger_delays[trigger.id] = TriggerDelay.new(to: to, from: from, duration: duration)
96
+ @trigger_conditions[trigger.id] = Conditions::Duration.new(to: to, from: from, duration: duration)
97
+ trigger
98
+ end
99
+
100
+ #
101
+ # Creates a trigger with a range condition on either 'from' or 'to' field
102
+ # @param [Object] item to create changed trigger on
103
+ # @param [Object] from state to restrict trigger to
104
+ # @param [Object] to state restrict trigger to
105
+ # @param [Object] attach to trigger
106
+ # @return [Trigger] OpenHAB trigger
107
+ #
108
+ def create_changed_range_trigger(item, from:, to:, attach:)
109
+ # swap range w/ nil if from or to is a range
110
+ from_range, from = from, from_range if from.is_a? Range
111
+ to_range, to = to, to_range if to.is_a? Range
112
+ trigger = create_changed_trigger(item, from, to, attach)
113
+ @trigger_conditions[trigger.id] = Conditions::Range.new(to: to_range, from: from_range)
100
114
  trigger
101
115
  end
102
116
 
@@ -104,8 +118,8 @@ module OpenHAB
104
118
  # Create a changed trigger
105
119
  #
106
120
  # @param [Object] item to create changed trigger on
107
- # @param [String] from state to restrict trigger to
108
- # @param [String] to state restrict trigger to
121
+ # @param [Object] from state to restrict trigger to
122
+ # @param [Object] to state restrict trigger to
109
123
  #
110
124
  #
111
125
  def create_changed_trigger(item, from, to, attach)
@@ -0,0 +1,184 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'openhab/log/logger'
4
+
5
+ module OpenHAB
6
+ module DSL
7
+ module Rules
8
+ module Triggers
9
+ #
10
+ # Module for conditions for triggers
11
+ #
12
+ module Conditions
13
+ include OpenHAB::Log
14
+ #
15
+ # this is a no-op condition which simply executes the provided block
16
+ #
17
+
18
+ #
19
+ # Struct capturing data necessary for a conditional trigger
20
+ #
21
+ # TriggerDelay = Struct.new(:to, :from, :duration, :timer, :tracking_to, keyword_init: true) do
22
+ # def timer_active?
23
+ # timer&.is_active
24
+ # end
25
+ # end
26
+
27
+ class Duration
28
+ def initialize(to:, from:, duration:)
29
+ @to = to
30
+ @from = from
31
+ @duration = duration
32
+ end
33
+
34
+ # Process rule
35
+ # @param [Hash] inputs inputs from trigger
36
+ #
37
+ def process(mod:, inputs:, &block)
38
+ process_trigger_delay(mod, inputs, &block)
39
+ end
40
+
41
+ private
42
+
43
+ #
44
+ # Checks if there is an active timer
45
+ # @return [true, false] true if the timer exists and is active, false otherwise
46
+ def timer_active?
47
+ @timer&.is_active
48
+ end
49
+
50
+ #
51
+ # Check if trigger guards prevent rule execution
52
+ #
53
+ # @param [Map] inputs OpenHAB map object describing rule trigger
54
+ #
55
+ # @return [Boolean] True if the rule should execute, false if trigger guard prevents execution
56
+ #
57
+ def check_trigger_guards(inputs)
58
+ new_state, old_state = retrieve_states(inputs)
59
+ if check_from(old_state)
60
+ return true if check_to(new_state)
61
+
62
+ logger.trace("Skipped execution of rule because to state #{new_state}"\
63
+ " does not equal specified state(#{@to})")
64
+ else
65
+ logger.trace("Skipped execution of rule because old state #{old_state}"\
66
+ " does not equal specified state(#{@from})")
67
+ end
68
+ end
69
+
70
+ #
71
+ # Rerieve the newState and oldState, alternatively newStatus and oldStatus
72
+ # from the input map
73
+ #
74
+ # @param [Map] inputs OpenHAB map object describing rule trigger
75
+ #
76
+ # @return [Array] An array of the values for [newState, oldState] or [newStatus, oldStatus]
77
+ #
78
+ def retrieve_states(inputs)
79
+ old_state = inputs['oldState'] || thing_status_to_sym(inputs['oldStatus'])
80
+ new_state = inputs['newState'] || thing_status_to_sym(inputs['newStatus'])
81
+
82
+ [new_state, old_state]
83
+ end
84
+
85
+ #
86
+ # Converts a ThingStatus object to a ruby Symbol
87
+ #
88
+ # @param [Java::OrgOpenhabCoreThing::ThingStatus] status A ThingStatus instance
89
+ #
90
+ # @return [Symbol] A corresponding symbol, in lower case
91
+ #
92
+ def thing_status_to_sym(status)
93
+ status&.to_s&.downcase&.to_sym
94
+ end
95
+
96
+ #
97
+ # Check the from state against the trigger delay
98
+ #
99
+ # @param [Item State] state from state to check
100
+ #
101
+ # @return [Boolean] true if no from state is defined or defined state equals supplied state
102
+ #
103
+ def check_from(state)
104
+ return @from.include?(state) if @from.is_a?(::Range)
105
+
106
+ @from.nil? || @from == state
107
+ end
108
+
109
+ #
110
+ # Check the to state against the trigger delay
111
+ #
112
+ # @param [Item State] state to-state to check
113
+ #
114
+ # @return [Boolean] true if no to state is defined or defined state equals supplied state
115
+ #
116
+ def check_to(state)
117
+ return @to.include?(state) if @to.is_a?(::Range)
118
+
119
+ @to.nil? || @to == state
120
+ end
121
+
122
+ #
123
+ # Process any matching trigger delays
124
+ #
125
+ # @param [Map] mod OpenHAB map object describing rule trigger
126
+ # @param [Map] inputs OpenHAB map object describing rule trigger
127
+ #
128
+ #
129
+ def process_trigger_delay(mod, inputs, &block)
130
+ if timer_active?
131
+ process_active_timer(inputs, mod, &block)
132
+ elsif check_trigger_guards(inputs)
133
+ logger.trace("Trigger Guards Matched for #{self}, delaying rule execution")
134
+ # Add timer and attach timer to delay object, and also state being tracked to so
135
+ # timer can be cancelled if state changes
136
+ # Also another timer should not be created if changed to same value again but instead rescheduled
137
+ create_trigger_delay_timer(inputs, mod, &block)
138
+ else
139
+ logger.trace("Trigger Guards did not match for #{self}, ignoring trigger.")
140
+ end
141
+ end
142
+
143
+ #
144
+ # Creates a timer for trigger delays
145
+ #
146
+ # @param [Hash] inputs rule trigger inputs
147
+ # @param [Hash] mod rule trigger mods
148
+ #
149
+ #
150
+ def create_trigger_delay_timer(inputs, _mod)
151
+ logger.trace("Creating timer for trigger delay #{self}")
152
+ @timer = after(@duration) do
153
+ logger.trace("Delay Complete for #{self}, executing rule")
154
+ @timer = nil
155
+ yield
156
+ end
157
+ @tracking_to, = retrieve_states(inputs)
158
+ end
159
+
160
+ #
161
+ # Process an active trigger timer
162
+ #
163
+ # @param [Hash] inputs rule trigger inputs
164
+ # @param [Hash] mod rule trigger mods
165
+ #
166
+ #
167
+ def process_active_timer(inputs, mod, &block)
168
+ state, = retrieve_states(inputs)
169
+ if state == @tracking_to
170
+ logger.trace("Item changed to #{state} for #{self}, rescheduling timer.")
171
+ @timer.reschedule(ZonedDateTime.now.plus(@duration))
172
+ else
173
+ logger.trace("Item changed to #{state} for #{self}, canceling timer.")
174
+ @timer.cancel
175
+ # Reprocess trigger delay after canceling to track new state (if guards matched, etc)
176
+ process_trigger_delay(mod, inputs, &block)
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'openhab/log/logger'
4
+ require 'singleton'
5
+
6
+ module OpenHAB
7
+ module DSL
8
+ module Rules
9
+ module Triggers
10
+ #
11
+ # Module for conditions for triggers
12
+ #
13
+ module Conditions
14
+ include OpenHAB::Log
15
+ #
16
+ # this is a no-op condition which simply executes the provided block
17
+ #
18
+ class None
19
+ include Singleton
20
+
21
+ # Process rule
22
+ # @param [Hash] inputs inputs from trigger
23
+ #
24
+ def process(*)
25
+ yield
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'openhab/log/logger'
4
+
5
+ module OpenHAB
6
+ module DSL
7
+ module Rules
8
+ module Triggers
9
+ #
10
+ # Module for conditions for triggers
11
+ #
12
+ module Conditions
13
+ include OpenHAB::Log
14
+
15
+ #
16
+ # This creates trigger conditions that work on ranges
17
+ # @param [Range:] From range
18
+ # @param [To:] To range
19
+ #
20
+ class Range
21
+ def initialize(from: nil, to: nil)
22
+ @from = from
23
+ @to = to
24
+ end
25
+
26
+ #
27
+ # Process rule
28
+ # @param [Hash] inputs inputs from trigger
29
+ #
30
+ def process(mod:, inputs:) # rubocop:disable Lint/UnusedMethodArgument - mod is unused here but required
31
+ logger.trace("Checking #{inputs} against condition trigger #{self}")
32
+ yield if check_from(inputs: inputs) && check_to(inputs: inputs)
33
+ end
34
+
35
+ #
36
+ # Check if from condition match the inputs
37
+ # @param [Hash] inputs inputs from trigger
38
+ # @return [true/false] depending on if from is set and matches supplied conditions
39
+ #
40
+ def check_from(inputs:)
41
+ old_state = inputs['oldState']
42
+ return true if @from.nil? || @from.include?(old_state)
43
+
44
+ logger.trace("Skipped execution of rule because old state #{old_state}"\
45
+ " does not equal specified range(#{@from})")
46
+ false
47
+ end
48
+
49
+ #
50
+ # Check if to conditions match the inputs
51
+ # @param [Hash] inputs inputs from trigger
52
+ # @return [true/false] depending on if from is set and matches supplied conditions
53
+ #
54
+ def check_to(inputs:)
55
+ new_state = inputs['newState'] || inputs['state'] # Get state for changed or update
56
+ return true if @to.nil? || @to.include?(new_state)
57
+
58
+ logger.trace("Skipped execution of rule because new state #{new_state}"\
59
+ " does not equal specified range(#{@to})")
60
+ false
61
+ end
62
+
63
+ # Describe the Range Condition as a string
64
+ # @return [String] string representation of range condition
65
+ #
66
+ def to_s
67
+ "From:(#{@from}) To:(#{@to})"
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'openhab/log/logger'
4
+ require_relative 'trigger'
4
5
 
5
6
  module OpenHAB
6
7
  module DSL
@@ -23,29 +24,59 @@ module OpenHAB
23
24
  separate_groups(items).map do |item|
24
25
  logger.trace("Creating updated trigger for item(#{item}) to(#{to})")
25
26
  [to].flatten.map do |to_state|
26
- trigger, config = create_update_trigger(item, to_state)
27
- append_trigger(trigger, config, attach: attach)
27
+ update_trigger(item: item, to: to_state, attach: attach)
28
28
  end
29
29
  end.flatten
30
30
  end
31
31
 
32
32
  private
33
33
 
34
+ #
35
+ # Create the trigger
36
+ #
37
+ # @param [Object] item item to create trigger for
38
+ # @param [Item State] from state to restrict trigger to
39
+ # @param [Item State] to state to restrict trigger to
40
+ # @param attach attachment
41
+ #
42
+ # @return [Trigger] OpenHAB triggers
43
+ #
44
+ def update_trigger(item:, to:, attach:)
45
+ if to.is_a? Range
46
+ create_update_range_trigger(item: item, to: to, attach: attach)
47
+ else
48
+ create_update_trigger(item: item, to: to, attach: attach)
49
+ end
50
+ end
51
+
52
+ #
53
+ # Creates a trigger with a range condition on the 'to' field
54
+ # @param [Object] item to create changed trigger on
55
+ # @param [Object] to state restrict trigger to
56
+ # @param [Object] attach to trigger
57
+ # @return [Trigger] OpenHAB trigger
58
+ #
59
+ def create_update_range_trigger(item:, to:, attach:)
60
+ trigger = create_update_trigger(item: item, to: nil, attach: attach)
61
+ @trigger_conditions[trigger.id] = Conditions::Range.new(to: to, from: nil)
62
+ trigger
63
+ end
64
+
34
65
  #
35
66
  # Create a trigger for updates
36
67
  #
37
68
  # @param [Object] item Type of item [Group,Thing,Item] to create update trigger for
38
69
  # @param [State] to_state state restriction on trigger
39
70
  #
40
- # @return [Array<Hash,String>] first element is a String specifying trigger type
41
- # second element is a Hash configuring trigger
71
+ # @return [Trigger] OpenHAB triggers
42
72
  #
43
- def create_update_trigger(item, to_state)
44
- case item
45
- when OpenHAB::DSL::Items::GroupItem::GroupMembers then group_update(item, to_state)
46
- when Thing then thing_update(item, to_state)
47
- else item_update(item, to_state)
48
- end
73
+ def create_update_trigger(item:, to:, attach:)
74
+ trigger, config = case item
75
+ when OpenHAB::DSL::Items::GroupItem::GroupMembers then group_update(item: item, to: to)
76
+ when Thing then thing_update(thing: item, to: to)
77
+ else item_update(item: item, to: to)
78
+ end
79
+ append_trigger(trigger, config, attach: attach)
49
80
  end
50
81
 
51
82
  #
@@ -57,9 +88,9 @@ module OpenHAB
57
88
  # @return [Array<Hash,String>] first element is a String specifying trigger type
58
89
  # second element is a Hash configuring trigger
59
90
  #
60
- def item_update(item, to_state)
91
+ def item_update(item:, to:)
61
92
  config = { 'itemName' => item.name }
62
- config['state'] = to_state.to_s unless to_state.nil?
93
+ config['state'] = to.to_s unless to.nil?
63
94
  trigger = Trigger::ITEM_STATE_UPDATE
64
95
  [trigger, config]
65
96
  end
@@ -73,9 +104,9 @@ module OpenHAB
73
104
  # @return [Array<Hash,String>] first element is a String specifying trigger type
74
105
  # second element is a Hash configuring trigger
75
106
  #
76
- def group_update(item, to_state)
107
+ def group_update(item:, to:)
77
108
  config = { 'groupName' => item.group.name }
78
- config['state'] = to_state.to_s unless to_state.nil?
109
+ config['state'] = to.to_s unless to.nil?
79
110
  trigger = Trigger::GROUP_STATE_UPDATE
80
111
  [trigger, config]
81
112
  end
@@ -89,8 +120,8 @@ module OpenHAB
89
120
  # @return [Array<Hash,String>] first element is a String specifying trigger type
90
121
  # second element is a Hash configuring trigger
91
122
  #
92
- def thing_update(thing, to_state)
93
- trigger_for_thing(thing, Trigger::THING_UPDATE, to_state)
123
+ def thing_update(thing:, to:)
124
+ trigger_for_thing(thing, Trigger::THING_UPDATE, to)
94
125
  end
95
126
  end
96
127
  end
@@ -5,5 +5,5 @@
5
5
  #
6
6
  module OpenHAB
7
7
  # @return [String] Version of OpenHAB helper libraries
8
- VERSION = '4.28.2'
8
+ VERSION = '4.29.0'
9
9
  end
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: 4.28.2
4
+ version: 4.29.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian O'Connell
@@ -106,6 +106,9 @@ files:
106
106
  - lib/openhab/dsl/rules/triggers/changed.rb
107
107
  - lib/openhab/dsl/rules/triggers/channel.rb
108
108
  - lib/openhab/dsl/rules/triggers/command.rb
109
+ - lib/openhab/dsl/rules/triggers/conditions/duration.rb
110
+ - lib/openhab/dsl/rules/triggers/conditions/none.rb
111
+ - lib/openhab/dsl/rules/triggers/conditions/range.rb
109
112
  - lib/openhab/dsl/rules/triggers/cron.rb
110
113
  - lib/openhab/dsl/rules/triggers/generic.rb
111
114
  - lib/openhab/dsl/rules/triggers/trigger.rb