openhab-scripting 4.28.1 → 4.30.1
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/dsl/items/group_item.rb +7 -0
- data/lib/openhab/dsl/items/item_registry.rb +1 -1
- data/lib/openhab/dsl/rules/automation_rule.rb +8 -146
- data/lib/openhab/dsl/rules/rule.rb +0 -31
- data/lib/openhab/dsl/rules/rule_config.rb +4 -3
- data/lib/openhab/dsl/rules/triggers/changed.rb +51 -18
- data/lib/openhab/dsl/rules/triggers/conditions/duration.rb +158 -0
- data/lib/openhab/dsl/rules/triggers/conditions/proc.rb +150 -0
- data/lib/openhab/dsl/rules/triggers/cron.rb +118 -0
- data/lib/openhab/dsl/rules/triggers/trigger.rb +2 -1
- data/lib/openhab/dsl/rules/triggers/updated.rb +59 -16
- data/lib/openhab/dsl/rules/triggers/watch.rb +1 -3
- data/lib/openhab/dsl/types/date_time_type.rb +2 -2
- data/lib/openhab/dsl/types/hsb_type.rb +2 -2
- data/lib/openhab/dsl/types/percent_type.rb +2 -2
- data/lib/openhab/dsl/types/point_type.rb +2 -2
- data/lib/openhab/dsl/types/quantity_type.rb +10 -10
- data/lib/openhab/version.rb +1 -1
- metadata +4 -3
- data/lib/openhab/dsl/rules/cron_trigger_rule.rb +0 -42
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 10d0c23c8f73defd79189dd05ec00cd3ce3aa301b87f6c7c8dbcfef3a73071d1
|
4
|
+
data.tar.gz: 45699ef1e370be135a4237eae154739f3375a95a9e5921ab97d1a51eb0ae87d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1e711ed86c556564fb8265781893567ce842b4a920979825a9fda79a329855535745e30f9f95c2c2015e6b4caf38e303b616c665634bb55e144662f67f5a12a4
|
7
|
+
data.tar.gz: 7aa7ccb682c525857d0a9f39296c902f3b0396d7b19de5d76f5d06783daeb316be3f039f0c898301af69545849410a73be8b7261340154568062d71b6f30681b
|
@@ -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
|
-
@
|
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)
|
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
|
-
|
65
|
-
|
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
|
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
|
125
|
+
# @return [Array] Array of trigger conditions that match rule UID
|
132
126
|
#
|
133
|
-
def
|
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
|
-
@
|
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
|
#
|
@@ -5,7 +5,6 @@ require 'openhab/core/services'
|
|
5
5
|
require 'openhab/log/logger'
|
6
6
|
require_relative 'rule_config'
|
7
7
|
require_relative 'automation_rule'
|
8
|
-
require_relative 'cron_trigger_rule'
|
9
8
|
require_relative 'guard'
|
10
9
|
|
11
10
|
module OpenHAB
|
@@ -70,44 +69,14 @@ module OpenHAB
|
|
70
69
|
def process_rule_config(config)
|
71
70
|
return unless create_rule?(config)
|
72
71
|
|
73
|
-
cron_attach_triggers, other_triggers = partition_triggers(config)
|
74
|
-
logger.trace("Cron triggers: #{cron_attach_triggers} - Other triggers: #{other_triggers}")
|
75
|
-
config.triggers = other_triggers
|
76
|
-
|
77
72
|
rule = AutomationRule.new(config: config)
|
78
73
|
Rules.script_rules << rule
|
79
74
|
add_rule(rule)
|
80
75
|
|
81
|
-
process_cron_attach(cron_attach_triggers, config, rule)
|
82
|
-
|
83
76
|
rule.execute(nil, { 'event' => Struct.new(:attachment).new(config.start_attachment) }) if config.on_start?
|
84
77
|
rule
|
85
78
|
end
|
86
79
|
|
87
|
-
#
|
88
|
-
# Add cron triggers with attachments to rules
|
89
|
-
# @param [Array] cron_attach_triggers cron type triggers with attachments
|
90
|
-
#
|
91
|
-
def process_cron_attach(cron_attach_triggers, config, rule)
|
92
|
-
cron_attach_triggers&.map { |trigger| CronTriggerRule.new(rule_config: config, rule: rule, trigger: trigger) }
|
93
|
-
&.each { |trigger| add_rule(trigger) }
|
94
|
-
end
|
95
|
-
|
96
|
-
#
|
97
|
-
# Partitions triggers in a config, removing cron triggers with a corresponding attachment
|
98
|
-
# so they can be used with CronTriggerRules to support attachments
|
99
|
-
# @return [Array] Two element array the first element is cron triggers with attachments,
|
100
|
-
# second element is other triggers
|
101
|
-
#
|
102
|
-
def partition_triggers(config)
|
103
|
-
config
|
104
|
-
.triggers
|
105
|
-
.partition do |trigger|
|
106
|
-
trigger.typeUID == OpenHAB::DSL::Rules::Triggers::Trigger::CRON &&
|
107
|
-
config.attachments.key?(trigger.id)
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
80
|
#
|
112
81
|
# Should a rule be created based on rule configuration
|
113
82
|
#
|
@@ -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/proc'
|
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 :
|
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
|
-
@
|
90
|
+
@trigger_conditions = Hash.new(OpenHAB::DSL::Rules::Triggers::Conditions::Proc::ANY)
|
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
|
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/proc'
|
4
6
|
|
5
7
|
module OpenHAB
|
6
8
|
module DSL
|
7
9
|
module Rules
|
8
10
|
#
|
9
|
-
# Module
|
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
|
-
|
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
|
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,13 @@ module OpenHAB
|
|
75
69
|
#
|
76
70
|
# @return [Trigger] OpenHAB triggers
|
77
71
|
#
|
78
|
-
def
|
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)
|
77
|
+
elsif [to, from].grep(Proc).any?
|
78
|
+
create_changed_proc_trigger(item, from: from, to: to, attach: attach)
|
81
79
|
else
|
82
80
|
create_changed_trigger(item, from, to, attach)
|
83
81
|
end
|
@@ -90,13 +88,48 @@ module OpenHAB
|
|
90
88
|
# @param [OpenHAB::Core::Duration] duration to delay trigger for until condition is met
|
91
89
|
# @param [Item State] to OpenHAB Item State item or group needs to change to
|
92
90
|
# @param [Item State] from OpenHAB Item State item or group needs to be coming from
|
91
|
+
# @param [Object] attach to trigger
|
93
92
|
#
|
94
93
|
# @return [Trigger] OpenHAB trigger
|
95
94
|
#
|
96
95
|
def changed_wait(item, duration:, to: nil, from: nil, attach: nil)
|
97
|
-
|
98
|
-
logger.trace("Creating Changed Wait Change Trigger for #{
|
99
|
-
|
96
|
+
item_name = item.respond_to?(:name) ? item.name : item.to_s
|
97
|
+
logger.trace("Creating Changed Wait Change Trigger for Item(#{item_name}) Duration(#{duration}) "\
|
98
|
+
"To(#{to}) From(#{from}) Attach(#{attach})")
|
99
|
+
create_changed_trigger(item, nil, nil, attach).tap do |trigger|
|
100
|
+
@trigger_conditions[trigger.id] = Conditions::Duration.new(to: to, from: from, duration: duration)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
#
|
105
|
+
# Creates a trigger with a range condition on either 'from' or 'to' field
|
106
|
+
# @param [Object] item to create changed trigger on
|
107
|
+
# @param [Object] from state to restrict trigger to
|
108
|
+
# @param [Object] to state restrict trigger to
|
109
|
+
# @param [Object] attach to trigger
|
110
|
+
# @return [Trigger] OpenHAB trigger
|
111
|
+
#
|
112
|
+
def create_changed_range_trigger(item, from:, to:, attach:)
|
113
|
+
from, to = Conditions::Proc.range_procs(from, to)
|
114
|
+
create_changed_proc_trigger(item, from: from, to: to, attach: attach)
|
115
|
+
end
|
116
|
+
|
117
|
+
#
|
118
|
+
# Creates a trigger with a proc condition on either 'from' or 'to' field
|
119
|
+
# @param [Object] item to create changed trigger on
|
120
|
+
# @param [Object] from state to restrict trigger to
|
121
|
+
# @param [Object] to state restrict trigger to
|
122
|
+
# @param [Object] attach to trigger
|
123
|
+
# @return [Trigger] OpenHAB trigger
|
124
|
+
#
|
125
|
+
def create_changed_proc_trigger(item, from:, to:, attach:)
|
126
|
+
# swap from/to w/ nil if from/to is a proc
|
127
|
+
# rubocop:disable Style/ParallelAssignment
|
128
|
+
from_proc, from = from, nil if from.is_a? Proc
|
129
|
+
to_proc, to = to, nil if to.is_a? Proc
|
130
|
+
# rubocop:enable Style/ParallelAssignment
|
131
|
+
trigger = create_changed_trigger(item, from, to, attach)
|
132
|
+
@trigger_conditions[trigger.id] = Conditions::Proc.new(to: to_proc, from: from_proc)
|
100
133
|
trigger
|
101
134
|
end
|
102
135
|
|
@@ -104,8 +137,8 @@ module OpenHAB
|
|
104
137
|
# Create a changed trigger
|
105
138
|
#
|
106
139
|
# @param [Object] item to create changed trigger on
|
107
|
-
# @param [
|
108
|
-
# @param [
|
140
|
+
# @param [Object] from state to restrict trigger to
|
141
|
+
# @param [Object] to state restrict trigger to
|
109
142
|
#
|
110
143
|
#
|
111
144
|
def create_changed_trigger(item, from, to, attach)
|
@@ -0,0 +1,158 @@
|
|
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
|
+
class Duration
|
27
|
+
#
|
28
|
+
# Create a new duration condition
|
29
|
+
# @param [Object] to optional condition on to state
|
30
|
+
# @param [Object] from optional condition on from state
|
31
|
+
# @param [Duration] Duration to state must stay at specific value before triggering
|
32
|
+
#
|
33
|
+
def initialize(to:, from:, duration:)
|
34
|
+
to = Conditions::Proc.from_value(to)
|
35
|
+
from = Conditions::Proc.from_value(from)
|
36
|
+
@conditions = Conditions::Proc.new(to: to, from: from)
|
37
|
+
@duration = duration
|
38
|
+
logger.trace "Created Duration Condition To(#{to}) From(#{from}) "\
|
39
|
+
"Conditions(#{@conditions}) Duration(#{@duration})"
|
40
|
+
end
|
41
|
+
|
42
|
+
# Process rule
|
43
|
+
# @param [Hash] inputs inputs from trigger
|
44
|
+
#
|
45
|
+
def process(mod:, inputs:, &block)
|
46
|
+
process_trigger_delay(mod, inputs, &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
#
|
52
|
+
# Checks if there is an active timer
|
53
|
+
# @return [true, false] true if the timer exists and is active, false otherwise
|
54
|
+
def timer_active?
|
55
|
+
@timer&.is_active
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# Check if trigger guards prevent rule execution
|
60
|
+
#
|
61
|
+
# @param [Map] inputs OpenHAB map object describing rule trigger
|
62
|
+
#
|
63
|
+
# @return [Boolean] True if the rule should execute, false if trigger guard prevents execution
|
64
|
+
#
|
65
|
+
def check_trigger_guards(inputs)
|
66
|
+
new_state, old_state = retrieve_states(inputs)
|
67
|
+
@conditions.check_from(state: old_state) && @conditions.check_to(state: new_state)
|
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
|
+
new_state = inputs['newState'] || thing_status_to_sym(inputs['newStatus'])
|
80
|
+
old_state = inputs['oldState'] || thing_status_to_sym(inputs['oldStatus'])
|
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
|
+
# Process any matching trigger delays
|
98
|
+
#
|
99
|
+
# @param [Map] mod OpenHAB map object describing rule trigger
|
100
|
+
# @param [Map] inputs OpenHAB map object describing rule trigger
|
101
|
+
#
|
102
|
+
#
|
103
|
+
def process_trigger_delay(mod, inputs, &block)
|
104
|
+
if timer_active?
|
105
|
+
process_active_timer(inputs, mod, &block)
|
106
|
+
elsif check_trigger_guards(inputs)
|
107
|
+
logger.trace("Trigger Guards Matched for #{self}, delaying rule execution")
|
108
|
+
# Add timer and attach timer to delay object, and also state being tracked to so
|
109
|
+
# timer can be cancelled if state changes
|
110
|
+
# Also another timer should not be created if changed to same value again but instead rescheduled
|
111
|
+
create_trigger_delay_timer(inputs, mod, &block)
|
112
|
+
else
|
113
|
+
logger.trace("Trigger Guards did not match for #{self}, ignoring trigger.")
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
#
|
118
|
+
# Creates a timer for trigger delays
|
119
|
+
#
|
120
|
+
# @param [Hash] inputs rule trigger inputs
|
121
|
+
# @param [Hash] mod rule trigger mods
|
122
|
+
#
|
123
|
+
#
|
124
|
+
def create_trigger_delay_timer(inputs, _mod)
|
125
|
+
logger.trace("Creating timer for trigger delay #{self}")
|
126
|
+
@timer = after(@duration) do
|
127
|
+
logger.trace("Delay Complete for #{self}, executing rule")
|
128
|
+
@timer = nil
|
129
|
+
yield
|
130
|
+
end
|
131
|
+
@tracking_to, = retrieve_states(inputs)
|
132
|
+
end
|
133
|
+
|
134
|
+
#
|
135
|
+
# Process an active trigger timer
|
136
|
+
#
|
137
|
+
# @param [Hash] inputs rule trigger inputs
|
138
|
+
# @param [Hash] mod rule trigger mods
|
139
|
+
#
|
140
|
+
#
|
141
|
+
def process_active_timer(inputs, mod, &block)
|
142
|
+
state, = retrieve_states(inputs)
|
143
|
+
if state == @tracking_to
|
144
|
+
logger.trace("Item changed to #{state} for #{self}, rescheduling timer.")
|
145
|
+
@timer.reschedule(ZonedDateTime.now.plus(@duration))
|
146
|
+
else
|
147
|
+
logger.trace("Item changed to #{state} for #{self}, canceling timer.")
|
148
|
+
@timer.cancel
|
149
|
+
# Reprocess trigger delay after canceling to track new state (if guards matched, etc)
|
150
|
+
process_trigger_delay(mod, inputs, &block)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
@@ -0,0 +1,150 @@
|
|
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 procs
|
17
|
+
# @param [Proc] from Proc
|
18
|
+
# @param [Proc] to Proc
|
19
|
+
#
|
20
|
+
class Proc
|
21
|
+
include OpenHAB::Log
|
22
|
+
|
23
|
+
# Proc that doesn't check any fields
|
24
|
+
ANY = Proc.new.freeze
|
25
|
+
|
26
|
+
#
|
27
|
+
# Converts supplied ranges to procs that check range
|
28
|
+
# @param [Array] ranges objects to convert to range proc if they are ranges
|
29
|
+
# @return [Array] of procs or supplied arguments if argument was not of type Range
|
30
|
+
#
|
31
|
+
def self.range_procs(*ranges)
|
32
|
+
ranges.map { |range| range.is_a?(Range) ? range_proc(range) : range }
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# Create a range proc for the supplied range object
|
37
|
+
# @param [Range] range to build proc for
|
38
|
+
#
|
39
|
+
def self.range_proc(range)
|
40
|
+
logger.trace("Creating range proc for #{range}")
|
41
|
+
lambda do |state|
|
42
|
+
logger.trace("Range proc checking if #{state} is in #{range}")
|
43
|
+
range.include? state
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# Create a range proc for the supplied range object
|
49
|
+
# @param [Range] range to build proc for
|
50
|
+
#
|
51
|
+
def self.equality_proc(value)
|
52
|
+
logger.trace("Creating equality proc for #{value}")
|
53
|
+
lambda do |state|
|
54
|
+
logger.trace("Equality proc comparing #{value} against #{state}")
|
55
|
+
value == state
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# Constructs a proc for the specific value type
|
61
|
+
# if the value is a proc return the proc
|
62
|
+
# if the value is a range create a range proc
|
63
|
+
# if the value is nil, return nil
|
64
|
+
# otherwise create an equality proc
|
65
|
+
# @param [Object] value to construct proc from
|
66
|
+
def self.from_value(value)
|
67
|
+
logger.trace("Creating proc for Value(#{value})")
|
68
|
+
return value if value.nil?
|
69
|
+
return value if value.is_a? ::Proc
|
70
|
+
return range_proc(value) if value.is_a? Range
|
71
|
+
|
72
|
+
equality_proc(value)
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# Create a new Proc Condition that executes only if procs return true
|
77
|
+
# @param [Proc] from Proc to check against from value
|
78
|
+
# @param [Proc] to Proc to check against to value
|
79
|
+
#
|
80
|
+
def initialize(from: nil, to: nil)
|
81
|
+
@from = from
|
82
|
+
@to = to
|
83
|
+
end
|
84
|
+
|
85
|
+
#
|
86
|
+
# Process rule
|
87
|
+
# @param [Hash] inputs inputs from trigger
|
88
|
+
#
|
89
|
+
def process(mod:, inputs:) # rubocop:disable Lint/UnusedMethodArgument - mod is unused here but required
|
90
|
+
logger.trace("Checking #{inputs} against condition trigger #{self}")
|
91
|
+
yield if check_from(inputs: inputs) && check_to(inputs: inputs)
|
92
|
+
end
|
93
|
+
|
94
|
+
#
|
95
|
+
# Check if from condition match the proc
|
96
|
+
# @param [Hash] inputs from trigger must be supplied if state is not supplied
|
97
|
+
# @param [String] state if supplied proc will be passed state value for comparision
|
98
|
+
# @return [true/false] depending on if from is set and matches supplied conditions
|
99
|
+
#
|
100
|
+
def check_from(inputs: nil, state: nil)
|
101
|
+
state ||= input_state(inputs, 'oldState')
|
102
|
+
logger.trace "Checking from(#{@from}) against state(#{state})"
|
103
|
+
check_proc(proc: @from, state: state)
|
104
|
+
end
|
105
|
+
|
106
|
+
#
|
107
|
+
# Check if to conditions match the proc
|
108
|
+
# @param [Hash] inputs from trigger must be supplied if state is not supplied
|
109
|
+
# @param [String] state if supplied proc will be passed state value for comparision
|
110
|
+
# @return [true/false] depending on if from is set and matches supplied conditions
|
111
|
+
#
|
112
|
+
def check_to(inputs: nil, state: nil)
|
113
|
+
state ||= input_state(inputs, 'newState', 'state')
|
114
|
+
logger.trace "Checking to(#{@to}) against state(#{state})"
|
115
|
+
check_proc(proc: @to, state: state)
|
116
|
+
end
|
117
|
+
|
118
|
+
# Describe the Proc Condition as a string
|
119
|
+
# @return [String] string representation of proc condition
|
120
|
+
#
|
121
|
+
def to_s
|
122
|
+
"From:(#{@from}) To:(#{@to})"
|
123
|
+
end
|
124
|
+
|
125
|
+
private
|
126
|
+
|
127
|
+
# Check if a field matches the proc condition
|
128
|
+
# @param [Proc] proc to call
|
129
|
+
# @param [Hash] inputs containing fields
|
130
|
+
# @param [Array] fields array of fields to extract from inputs, first one found is passed to proc
|
131
|
+
# @return [true,false] true if proc is nil or proc.call returns true, false otherwise
|
132
|
+
def check_proc(proc:, state:)
|
133
|
+
return true if proc.nil? || proc.call(state)
|
134
|
+
|
135
|
+
logger.trace("Skipped execution of rule because state #{state} evalulated false for (#{proc})")
|
136
|
+
false
|
137
|
+
end
|
138
|
+
|
139
|
+
# Get the first field from supplied fields in inputs
|
140
|
+
# @param [Hash] inputs containing fields
|
141
|
+
# @param [Array] fields array of fields to extract from inputs, first one found is returned
|
142
|
+
def input_state(inputs, *fields)
|
143
|
+
fields.map { |f| inputs[f] }.compact.first
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
@@ -164,7 +164,125 @@ module OpenHAB
|
|
164
164
|
end
|
165
165
|
expression_map
|
166
166
|
end
|
167
|
+
|
168
|
+
#
|
169
|
+
# Cron trigger that provides trigger ID
|
170
|
+
#
|
171
|
+
module Cron
|
172
|
+
include OpenHAB::Log
|
173
|
+
|
174
|
+
#
|
175
|
+
# Creates trigger types and trigger type factories for OpenHAB
|
176
|
+
#
|
177
|
+
def self.add_script_cron_handler
|
178
|
+
java_import org.openhab.core.automation.type.TriggerType
|
179
|
+
OpenHAB::Core.automation_manager.add_trigger_handler(
|
180
|
+
OpenHAB::DSL::Rules::Triggers::Cron::CRON_TRIGGER_MODULE_ID,
|
181
|
+
OpenHAB::DSL::Rules::Triggers::Cron::CronTriggerHandlerFactory.new
|
182
|
+
)
|
183
|
+
|
184
|
+
OpenHAB::Core.automation_manager.add_trigger_type(cron_trigger_type)
|
185
|
+
OpenHAB::Log.logger(self).trace('Added script cron trigger handler')
|
186
|
+
end
|
187
|
+
|
188
|
+
#
|
189
|
+
# Creates trigger types and trigger type factories for OpenHAB
|
190
|
+
#
|
191
|
+
private_class_method def self.cron_trigger_type
|
192
|
+
TriggerType.new(
|
193
|
+
OpenHAB::DSL::Rules::Triggers::Cron::CRON_TRIGGER_MODULE_ID,
|
194
|
+
nil,
|
195
|
+
'A specific instant occurs',
|
196
|
+
'Triggers when the specified instant occurs',
|
197
|
+
nil,
|
198
|
+
org.openhab.core.automation.Visibility::VISIBLE,
|
199
|
+
nil
|
200
|
+
)
|
201
|
+
end
|
202
|
+
|
203
|
+
# Trigger ID for Watch Triggers
|
204
|
+
CRON_TRIGGER_MODULE_ID = 'jsr223.jruby.CronTrigger'
|
205
|
+
|
206
|
+
# Cron Trigger Handler that provides trigger IDs
|
207
|
+
# Unfortunatly because the CronTriggerHandler in OpenHAB core is marked internal
|
208
|
+
# the entire thing must be recreated here
|
209
|
+
class CronTriggerHandler < org.openhab.core.automation.handler.BaseTriggerModuleHandler
|
210
|
+
include OpenHAB::Log
|
211
|
+
include org.openhab.core.scheduler.SchedulerRunnable
|
212
|
+
include org.openhab.core.automation.handler.TimeBasedTriggerHandler
|
213
|
+
|
214
|
+
# Provides access to protected fields
|
215
|
+
field_accessor :callback
|
216
|
+
|
217
|
+
# Creates a new CronTriggerHandler
|
218
|
+
# @param [Trigger] OpenHAB trigger associated with handler
|
219
|
+
#
|
220
|
+
def initialize(trigger)
|
221
|
+
@trigger = trigger
|
222
|
+
@scheduler = OpenHAB::Core::OSGI.service('org.openhab.core.scheduler.CronScheduler')
|
223
|
+
@expression = trigger.configuration.get('cronExpression')
|
224
|
+
super(trigger)
|
225
|
+
end
|
226
|
+
|
227
|
+
#
|
228
|
+
# Set the callback to execute when cron trigger fires
|
229
|
+
# @param [Object] callback to run
|
230
|
+
#
|
231
|
+
def setCallback(callback) # rubocop:disable Naming/MethodName
|
232
|
+
synchronized do
|
233
|
+
super(callback)
|
234
|
+
@scheduler.schedule(self, @expression)
|
235
|
+
logger.trace("Scheduled cron job '#{@expression}' for trigger '#{@trigger.id}'.")
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
#
|
240
|
+
# Get the temporal adjuster
|
241
|
+
# @return [CronAdjuster]
|
242
|
+
#
|
243
|
+
def getTemporalAdjuster # rubocop:disable Naming/MethodName
|
244
|
+
org.openhab.core.scheduler.CronAdjuster.new(expression)
|
245
|
+
end
|
246
|
+
|
247
|
+
#
|
248
|
+
# Execute the callback
|
249
|
+
#
|
250
|
+
def run
|
251
|
+
callback&.triggered(@trigger, { 'module' => @trigger.id })
|
252
|
+
end
|
253
|
+
|
254
|
+
#
|
255
|
+
# Displose of the handler
|
256
|
+
# cancel the cron scheduled task
|
257
|
+
#
|
258
|
+
def dispose
|
259
|
+
synchronized do
|
260
|
+
super
|
261
|
+
return unless @schedule
|
262
|
+
|
263
|
+
@schedule&.cancel(true)
|
264
|
+
end
|
265
|
+
logger.trace("cancelled job for trigger '#{@trigger.id}'.")
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
# Implements the ScriptedTriggerHandlerFactory interface to create a new Cron Trigger Handler
|
270
|
+
class CronTriggerHandlerFactory
|
271
|
+
include org.openhab.core.automation.module.script.rulesupport.shared.factories.ScriptedTriggerHandlerFactory
|
272
|
+
|
273
|
+
# Invoked by the OpenHAB core to get a trigger handler for the supllied trigger
|
274
|
+
# @param [Trigger] OpenHAB trigger
|
275
|
+
#
|
276
|
+
# @return [WatchTriggerHandler] trigger handler for supplied trigger
|
277
|
+
def get(trigger)
|
278
|
+
CronTriggerHandler.new(trigger)
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
167
282
|
end
|
168
283
|
end
|
169
284
|
end
|
170
285
|
end
|
286
|
+
|
287
|
+
# Add the cron handler to OpenHAB
|
288
|
+
OpenHAB::DSL::Rules::Triggers::Cron.add_script_cron_handler
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'securerandom'
|
4
4
|
require 'java'
|
5
|
+
require_relative 'cron'
|
5
6
|
|
6
7
|
module OpenHAB
|
7
8
|
module DSL
|
@@ -111,7 +112,7 @@ module OpenHAB
|
|
111
112
|
TIME_OF_DAY = 'timer.TimeOfDayTrigger'
|
112
113
|
|
113
114
|
# @return [String] A cron trigger
|
114
|
-
CRON =
|
115
|
+
CRON = OpenHAB::DSL::Rules::Triggers::Cron::CRON_TRIGGER_MODULE_ID
|
115
116
|
|
116
117
|
#
|
117
118
|
# Create a trigger
|
@@ -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,71 @@ 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
|
-
|
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
|
+
case to
|
46
|
+
when Range then create_update_range_trigger(item: item, to: to, attach: attach)
|
47
|
+
when Proc then create_update_proc_trigger(item: item, to: to, attach: attach)
|
48
|
+
else 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
|
+
to, * = Conditions::Proc.range_procs(to)
|
61
|
+
create_update_proc_trigger(item: item, to: to, attach: attach)
|
62
|
+
end
|
63
|
+
|
64
|
+
#
|
65
|
+
# Creates a trigger with a proc condition on the 'to' field
|
66
|
+
# @param [Object] item to create changed trigger on
|
67
|
+
# @param [Object] to state restrict trigger to
|
68
|
+
# @param [Object] attach to trigger
|
69
|
+
# @return [Trigger] OpenHAB trigger
|
70
|
+
#
|
71
|
+
def create_update_proc_trigger(item:, to:, attach:)
|
72
|
+
create_update_trigger(item: item, to: nil, attach: attach).tap do |trigger|
|
73
|
+
@trigger_conditions[trigger.id] = Conditions::Proc.new(to: to)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
34
77
|
#
|
35
78
|
# Create a trigger for updates
|
36
79
|
#
|
37
80
|
# @param [Object] item Type of item [Group,Thing,Item] to create update trigger for
|
38
81
|
# @param [State] to_state state restriction on trigger
|
39
82
|
#
|
40
|
-
# @return [
|
41
|
-
# second element is a Hash configuring trigger
|
83
|
+
# @return [Trigger] OpenHAB triggers
|
42
84
|
#
|
43
|
-
def create_update_trigger(item
|
44
|
-
case item
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
85
|
+
def create_update_trigger(item:, to:, attach:)
|
86
|
+
trigger, config = case item
|
87
|
+
when OpenHAB::DSL::Items::GroupItem::GroupMembers then group_update(item: item, to: to)
|
88
|
+
when Thing then thing_update(thing: item, to: to)
|
89
|
+
else item_update(item: item, to: to)
|
90
|
+
end
|
91
|
+
append_trigger(trigger, config, attach: attach)
|
49
92
|
end
|
50
93
|
|
51
94
|
#
|
@@ -57,9 +100,9 @@ module OpenHAB
|
|
57
100
|
# @return [Array<Hash,String>] first element is a String specifying trigger type
|
58
101
|
# second element is a Hash configuring trigger
|
59
102
|
#
|
60
|
-
def item_update(item
|
103
|
+
def item_update(item:, to:)
|
61
104
|
config = { 'itemName' => item.name }
|
62
|
-
config['state'] =
|
105
|
+
config['state'] = to.to_s unless to.nil?
|
63
106
|
trigger = Trigger::ITEM_STATE_UPDATE
|
64
107
|
[trigger, config]
|
65
108
|
end
|
@@ -73,9 +116,9 @@ module OpenHAB
|
|
73
116
|
# @return [Array<Hash,String>] first element is a String specifying trigger type
|
74
117
|
# second element is a Hash configuring trigger
|
75
118
|
#
|
76
|
-
def group_update(item
|
119
|
+
def group_update(item:, to:)
|
77
120
|
config = { 'groupName' => item.group.name }
|
78
|
-
config['state'] =
|
121
|
+
config['state'] = to.to_s unless to.nil?
|
79
122
|
trigger = Trigger::GROUP_STATE_UPDATE
|
80
123
|
[trigger, config]
|
81
124
|
end
|
@@ -89,8 +132,8 @@ module OpenHAB
|
|
89
132
|
# @return [Array<Hash,String>] first element is a String specifying trigger type
|
90
133
|
# second element is a Hash configuring trigger
|
91
134
|
#
|
92
|
-
def thing_update(thing
|
93
|
-
trigger_for_thing(thing, Trigger::THING_UPDATE,
|
135
|
+
def thing_update(thing:, to:)
|
136
|
+
trigger_for_thing(thing, Trigger::THING_UPDATE, to)
|
94
137
|
end
|
95
138
|
end
|
96
139
|
end
|
@@ -138,11 +138,9 @@ module OpenHAB
|
|
138
138
|
|
139
139
|
# Called by OpenHAB to set the rule engine to invoke when triggered
|
140
140
|
# Must match java method name style
|
141
|
-
# rubocop:disable Naming/MethodName
|
142
|
-
def setCallback(callback)
|
141
|
+
def setCallback(callback) # rubocop:disable Naming/MethodName
|
143
142
|
@rule_engine_callback = callback
|
144
143
|
end
|
145
|
-
# rubocop:enable Naming/MethodName
|
146
144
|
|
147
145
|
#
|
148
146
|
# Dispose of handler which deactivates watcher
|
@@ -10,8 +10,8 @@ module OpenHAB
|
|
10
10
|
DateTimeType = org.openhab.core.library.types.DateTimeType
|
11
11
|
java_import java.time.ZonedDateTime # This is needed for the addon prior to ruby_class fix (OH 3.2.0)
|
12
12
|
|
13
|
-
# global alias
|
14
|
-
::DateTimeType = DateTimeType
|
13
|
+
# global alias - required for jrubyscripting addon <= OH3.2.0
|
14
|
+
::DateTimeType = DateTimeType if ::DateTimeType.is_a?(Java::JavaLang::Class)
|
15
15
|
|
16
16
|
# @deprecated
|
17
17
|
# Backwards-compatible alias
|
@@ -8,8 +8,8 @@ module OpenHAB
|
|
8
8
|
module Types
|
9
9
|
HSBType = org.openhab.core.library.types.HSBType
|
10
10
|
|
11
|
-
# global alias
|
12
|
-
::HSBType = HSBType
|
11
|
+
# global alias - required for jrubyscripting addon <= OH3.2.0
|
12
|
+
::HSBType = HSBType if ::HSBType.is_a?(Java::JavaLang::Class)
|
13
13
|
|
14
14
|
# Adds methods to core OpenHAB HSBType to make it more natural in Ruby
|
15
15
|
class HSBType < PercentType
|
@@ -7,8 +7,8 @@ module OpenHAB
|
|
7
7
|
module Types
|
8
8
|
PercentType = org.openhab.core.library.types.PercentType
|
9
9
|
|
10
|
-
# global alias
|
11
|
-
::PercentType = PercentType
|
10
|
+
# global alias - required for jrubyscripting addon <= OH3.2.0
|
11
|
+
::PercentType = PercentType if ::PercentType.is_a?(Java::JavaLang::Class)
|
12
12
|
|
13
13
|
# Adds methods to core OpenHAB PercentType to make it more natural in Ruby
|
14
14
|
class PercentType < DecimalType
|
@@ -5,9 +5,9 @@ module OpenHAB
|
|
5
5
|
module Types
|
6
6
|
PointType = org.openhab.core.library.types.PointType
|
7
7
|
|
8
|
-
# global scope
|
8
|
+
# global scope - required for jrubyscripting addon <= OH3.2.0
|
9
9
|
# @!visibility private
|
10
|
-
::PointType = PointType
|
10
|
+
::PointType = PointType if ::PointType.is_a?(Java::JavaLang::Class)
|
11
11
|
|
12
12
|
# Adds methods to core OpenHAB PointType to make it more natural in Ruby
|
13
13
|
class PointType
|
@@ -7,8 +7,8 @@ module OpenHAB
|
|
7
7
|
module Types
|
8
8
|
QuantityType = org.openhab.core.library.types.QuantityType
|
9
9
|
|
10
|
-
# global alias
|
11
|
-
::QuantityType = QuantityType
|
10
|
+
# global alias - required for jrubyscripting addon <= OH3.2.0
|
11
|
+
::QuantityType = QuantityType if ::QuantityType.is_a?(Java::JavaLang::Class)
|
12
12
|
|
13
13
|
# @deprecated
|
14
14
|
# Backwards-compatible alias
|
@@ -20,8 +20,8 @@ module OpenHAB
|
|
20
20
|
include NumericType
|
21
21
|
|
22
22
|
# private alias
|
23
|
-
|
24
|
-
private_constant :
|
23
|
+
ONE_UNIT = org.openhab.core.library.unit.Units::ONE
|
24
|
+
private_constant :ONE_UNIT
|
25
25
|
|
26
26
|
#
|
27
27
|
# Convert this quantity into a another unit
|
@@ -46,8 +46,8 @@ module OpenHAB
|
|
46
46
|
def <=>(other) # rubocop:disable Metrics
|
47
47
|
logger.trace("(#{self.class}) #{self} <=> #{other} (#{other.class})")
|
48
48
|
if other.is_a?(self.class)
|
49
|
-
return unitize(other.unit).compare_to(other) if unit ==
|
50
|
-
return compare_to(other.unitize(unit)) if other.unit ==
|
49
|
+
return unitize(other.unit).compare_to(other) if unit == ONE_UNIT
|
50
|
+
return compare_to(other.unitize(unit)) if other.unit == ONE_UNIT
|
51
51
|
|
52
52
|
compare_to(other)
|
53
53
|
elsif other.is_a?(Items::NumericItem) ||
|
@@ -88,7 +88,7 @@ module OpenHAB
|
|
88
88
|
elsif other.is_a?(Type)
|
89
89
|
[other, as(other.class)]
|
90
90
|
elsif other.respond_to?(:to_d)
|
91
|
-
[QuantityType.new(other.to_d.to_java,
|
91
|
+
[QuantityType.new(other.to_d.to_java, ONE_UNIT), self]
|
92
92
|
elsif other.is_a?(String)
|
93
93
|
[QuantityType.new(other), self]
|
94
94
|
end
|
@@ -215,7 +215,7 @@ module OpenHAB
|
|
215
215
|
logger.trace("Converting #{self} to #{other_unit}")
|
216
216
|
|
217
217
|
case unit
|
218
|
-
when
|
218
|
+
when ONE_UNIT
|
219
219
|
QuantityType.new(to_big_decimal, other_unit)
|
220
220
|
when other_unit
|
221
221
|
self
|
@@ -224,10 +224,10 @@ module OpenHAB
|
|
224
224
|
end
|
225
225
|
end
|
226
226
|
|
227
|
-
# if unit is +
|
227
|
+
# if unit is +ONE_UNIT+, return a plain Java BigDecimal
|
228
228
|
# @!visibility private
|
229
229
|
def deunitize
|
230
|
-
return to_big_decimal if unit ==
|
230
|
+
return to_big_decimal if unit == ONE_UNIT
|
231
231
|
|
232
232
|
self
|
233
233
|
end
|
data/lib/openhab/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openhab-scripting
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.30.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian O'Connell
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-01-
|
11
|
+
date: 2022-01-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -97,7 +97,6 @@ files:
|
|
97
97
|
- lib/openhab/dsl/openhab.rb
|
98
98
|
- lib/openhab/dsl/persistence.rb
|
99
99
|
- lib/openhab/dsl/rules/automation_rule.rb
|
100
|
-
- lib/openhab/dsl/rules/cron_trigger_rule.rb
|
101
100
|
- lib/openhab/dsl/rules/guard.rb
|
102
101
|
- lib/openhab/dsl/rules/item_event.rb
|
103
102
|
- lib/openhab/dsl/rules/property.rb
|
@@ -107,6 +106,8 @@ files:
|
|
107
106
|
- lib/openhab/dsl/rules/triggers/changed.rb
|
108
107
|
- lib/openhab/dsl/rules/triggers/channel.rb
|
109
108
|
- lib/openhab/dsl/rules/triggers/command.rb
|
109
|
+
- lib/openhab/dsl/rules/triggers/conditions/duration.rb
|
110
|
+
- lib/openhab/dsl/rules/triggers/conditions/proc.rb
|
110
111
|
- lib/openhab/dsl/rules/triggers/cron.rb
|
111
112
|
- lib/openhab/dsl/rules/triggers/generic.rb
|
112
113
|
- lib/openhab/dsl/rules/triggers/trigger.rb
|
@@ -1,42 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'java'
|
4
|
-
require 'openhab/log/logger'
|
5
|
-
|
6
|
-
module OpenHAB
|
7
|
-
module DSL
|
8
|
-
#
|
9
|
-
# Creates and manages OpenHAB Rules
|
10
|
-
#
|
11
|
-
module Rules
|
12
|
-
#
|
13
|
-
# Specialized rule for cron triggers with attachments because OpenHAB does not provide trigger UID for cron rules
|
14
|
-
#
|
15
|
-
class CronTriggerRule < Java::OrgOpenhabCoreAutomationModuleScriptRulesupportSharedSimple::SimpleRule
|
16
|
-
include OpenHAB::Log
|
17
|
-
|
18
|
-
def initialize(rule_config:, rule:, trigger:)
|
19
|
-
super()
|
20
|
-
set_name("#{rule_config.name}-cron-#{trigger.id}")
|
21
|
-
set_triggers([trigger])
|
22
|
-
@rule = rule
|
23
|
-
@trigger = trigger
|
24
|
-
logger.trace("Created Cron Trigger Rule for #{@trigger}")
|
25
|
-
end
|
26
|
-
|
27
|
-
#
|
28
|
-
# Execute the rule
|
29
|
-
#
|
30
|
-
# @param [Map] mod map provided by OpenHAB rules engine
|
31
|
-
# @param [Map] inputs map provided by OpenHAB rules engine containing event and other information
|
32
|
-
#
|
33
|
-
#
|
34
|
-
def execute(mod = nil, _inputs = nil)
|
35
|
-
logger.trace "Trigger #{@trigger} fired for base rule #{@rule.inspect}"
|
36
|
-
inputs = { 'module' => @trigger.id }
|
37
|
-
@rule.execute(mod, inputs)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|