openhab-scripting 4.30.3 → 4.32.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/openhab/dsl/items/timed_command.rb +4 -3
- data/lib/openhab/dsl/rules/automation_rule.rb +4 -6
- data/lib/openhab/dsl/rules/rule_config.rb +9 -22
- data/lib/openhab/dsl/rules/rule_triggers.rb +103 -0
- data/lib/openhab/dsl/rules/triggers/changed.rb +164 -152
- data/lib/openhab/dsl/rules/triggers/channel.rb +48 -20
- data/lib/openhab/dsl/rules/triggers/command.rb +114 -64
- data/lib/openhab/dsl/rules/triggers/conditions/proc.rb +32 -13
- data/lib/openhab/dsl/rules/triggers/cron/cron.rb +185 -0
- data/lib/openhab/dsl/rules/triggers/cron/cron_handler.rb +130 -0
- data/lib/openhab/dsl/rules/triggers/generic.rb +2 -1
- data/lib/openhab/dsl/rules/triggers/trigger.rb +44 -112
- data/lib/openhab/dsl/rules/triggers/triggers.rb +11 -0
- data/lib/openhab/dsl/rules/triggers/updated.rb +111 -97
- data/lib/openhab/dsl/rules/triggers/watch/watch.rb +76 -0
- data/lib/openhab/dsl/rules/triggers/{watch.rb → watch/watch_handler.rb} +14 -56
- data/lib/openhab/dsl/types/string_type.rb +1 -1
- data/lib/openhab/log/logger.rb +16 -0
- data/lib/openhab/version.rb +1 -1
- metadata +8 -4
- data/lib/openhab/dsl/rules/triggers/cron.rb +0 -288
@@ -1,7 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'openhab/log/logger'
|
4
|
-
require 'openhab/dsl/
|
4
|
+
require 'openhab/dsl/things'
|
5
|
+
require_relative 'trigger'
|
5
6
|
|
6
7
|
module OpenHAB
|
7
8
|
module DSL
|
@@ -22,32 +23,59 @@ module OpenHAB
|
|
22
23
|
# thing(s) to create trigger for if not specified with the channel
|
23
24
|
# @param [String, Array<String>] triggered specific triggering condition(s) to match for trigger
|
24
25
|
#
|
25
|
-
def channel(*channels, thing: nil, triggered: nil, attach: nil)
|
26
|
-
|
27
|
-
|
28
|
-
t = t.uid if t.is_a?(Thing)
|
29
|
-
channel = [t, channel].compact.join(':')
|
30
|
-
logger.trace("Creating channel trigger for channel(#{channel}), thing(#{t}), trigger(#{triggered})")
|
26
|
+
def channel(*channels, thing: nil, triggered: nil, attach: nil)
|
27
|
+
channel_trigger = Channel.new(rule_triggers: @rule_triggers)
|
28
|
+
Channel.channels(channels: channels, thing: thing).each do |channel|
|
31
29
|
[triggered].flatten.each do |trigger|
|
32
|
-
|
30
|
+
channel_trigger.trigger(channel: channel, trigger: trigger, attach: attach)
|
33
31
|
end
|
34
32
|
end
|
35
33
|
end
|
36
34
|
|
37
|
-
private
|
38
|
-
|
39
|
-
#
|
40
|
-
# Create a trigger for a channel
|
41
35
|
#
|
42
|
-
#
|
43
|
-
# @param [String] trigger specific channel trigger to match
|
36
|
+
# Creates channel triggers
|
44
37
|
#
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
38
|
+
class Channel < Trigger
|
39
|
+
include OpenHAB::Log
|
40
|
+
|
41
|
+
# @return [String] A channel event trigger
|
42
|
+
CHANNEL_EVENT = 'core.ChannelEventTrigger'
|
43
|
+
|
44
|
+
#
|
45
|
+
# Get an enumerator over the product of the channels and things and map them to a channel id
|
46
|
+
# @param [Object] channels to iterate over
|
47
|
+
# @param [Object] thing to combine with channels and iterate over
|
48
|
+
# @return [Enumerable] enumerable channel ids to trigger on
|
49
|
+
def self.channels(channels:, thing:)
|
50
|
+
logger.state 'Creating Channel/Thing Pairs', channels: channels, thing: thing
|
51
|
+
channels.flatten.product([thing].flatten)
|
52
|
+
.map { |channel_thing| channel_id(*channel_thing) }
|
53
|
+
end
|
54
|
+
|
55
|
+
#
|
56
|
+
# Get a channel id from a channel and thing
|
57
|
+
# @param [Object] channel part of channel id, get UID if object is a Channel
|
58
|
+
# @param [Object] thing part of channel id, get UID if object is a Thing
|
59
|
+
#
|
60
|
+
def self.channel_id(channel, thing)
|
61
|
+
channel = channel.uid if channel.is_a?(org.openhab.core.thing.Channel)
|
62
|
+
thing = thing.uid if thing.is_a?(Thing)
|
63
|
+
[thing, channel].compact.join(':')
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
# Create a trigger for a channel
|
68
|
+
#
|
69
|
+
# @param [String] channel to look for triggers
|
70
|
+
# @param [String] trigger specific channel trigger to match
|
71
|
+
#
|
72
|
+
#
|
73
|
+
def trigger(channel:, trigger:, attach:)
|
74
|
+
config = { 'channelUID' => channel }
|
75
|
+
config['event'] = trigger.to_s unless trigger.nil?
|
76
|
+
logger.state 'Creating Channel Trigger', channel: channel, config: config
|
77
|
+
append_trigger(type: CHANNEL_EVENT, config: config, attach: attach)
|
78
|
+
end
|
51
79
|
end
|
52
80
|
end
|
53
81
|
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
|
@@ -22,81 +23,130 @@ module OpenHAB
|
|
22
23
|
#
|
23
24
|
#
|
24
25
|
def received_command(*items, command: nil, commands: nil, attach: nil)
|
25
|
-
|
26
|
-
logger.trace("Creating received command trigger for item(#{item})"\
|
27
|
-
"command(#{command}) commands(#{commands})")
|
26
|
+
command_trigger = Command.new(rule_triggers: @rule_triggers)
|
28
27
|
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
# Combine command and commands, doing union so only a single nil will be in the combined array.
|
29
|
+
combined_commands = Command.combine_commands(command: command, commands: commands)
|
30
|
+
|
31
|
+
Command.flatten_items(items).map do |item|
|
32
|
+
combined_commands.map do |cmd|
|
33
|
+
logger.states 'Creating received command trigger', item: item, command: cmd
|
34
|
+
|
35
|
+
command_trigger.trigger(item: item, command: cmd, attach: attach)
|
36
|
+
end
|
32
37
|
end.flatten
|
33
38
|
end
|
34
39
|
|
35
|
-
private
|
36
|
-
|
37
|
-
#
|
38
|
-
# Create a received trigger based on item type
|
39
40
|
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
commands
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
41
|
+
# Creates command triggers
|
42
|
+
#
|
43
|
+
class Command < Trigger
|
44
|
+
# Combine command and commands into a single array
|
45
|
+
#
|
46
|
+
# @param [Array] command list of commands to trigger on
|
47
|
+
# @param [Array] commands list of commands to trigger on
|
48
|
+
#
|
49
|
+
# @return [Array] Combined flattened and compacted list of commands
|
50
|
+
#
|
51
|
+
def self.combine_commands(command:, commands:)
|
52
|
+
combined_commands = ([command] | [commands]).flatten
|
53
|
+
|
54
|
+
# If either command or commands has a value and one is nil, we need to remove nil from the array.
|
55
|
+
# If it is only now a single nil value, we leave the nil in place, so that we create a trigger
|
56
|
+
# That isn't looking for a specific command.
|
57
|
+
combined_commands = combined_commands.compact unless combined_commands.all?(&:nil?)
|
58
|
+
combined_commands
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# Create a received command trigger
|
63
|
+
#
|
64
|
+
# @param [Object] item item to create trigger for
|
65
|
+
# @param [Object] command to check against
|
66
|
+
# @param [Object] attach attachment
|
67
|
+
#
|
68
|
+
# @return [Trigger] OpenHAB triggers
|
69
|
+
#
|
70
|
+
def trigger(item:, command:, attach:)
|
71
|
+
case command
|
72
|
+
when Range then range_trigger(item: item, command: command, attach: attach)
|
73
|
+
when Proc then proc_trigger(item: item, command: command, attach: attach)
|
74
|
+
else command_trigger(item: item, command: command, attach: attach)
|
50
75
|
end
|
76
|
+
end
|
77
|
+
|
78
|
+
#
|
79
|
+
# Creates a trigger with a range condition on the 'command' field
|
80
|
+
# @param [Object] item to create changed trigger on
|
81
|
+
# @param [Object] command to restrict trigger to
|
82
|
+
# @param [Object] attach to trigger
|
83
|
+
# @return [Trigger] OpenHAB trigger
|
84
|
+
#
|
85
|
+
def range_trigger(item:, command:, attach:)
|
86
|
+
command_range, * = Conditions::Proc.range_procs(command)
|
87
|
+
proc_trigger(item: item, command: command_range, attach: attach)
|
88
|
+
end
|
89
|
+
|
90
|
+
#
|
91
|
+
# Creates a trigger with a proc condition on the 'command' field
|
92
|
+
# @param [Object] item to create changed trigger on
|
93
|
+
# @param [Object] command to restrict trigger to
|
94
|
+
# @param [Object] attach to trigger
|
95
|
+
# @return [Trigger] OpenHAB trigger
|
96
|
+
#
|
97
|
+
def proc_trigger(item:, command:, attach:)
|
98
|
+
conditions = Conditions::Proc.new(command: command)
|
99
|
+
command_trigger(item: item, command: nil, attach: attach, conditions: conditions)
|
100
|
+
end
|
101
|
+
|
102
|
+
#
|
103
|
+
# Create a received trigger based on item type
|
104
|
+
#
|
105
|
+
# @param [Array] commands to create trigger for
|
106
|
+
# @param [Object] item to create trigger for
|
107
|
+
#
|
108
|
+
#
|
109
|
+
def command_trigger(item:, command:, attach: nil, conditions: nil)
|
110
|
+
type, config = if item.is_a? OpenHAB::DSL::Items::GroupItem::GroupMembers
|
111
|
+
group(group: item)
|
112
|
+
else
|
113
|
+
item(item: item)
|
114
|
+
end
|
51
115
|
config['command'] = command.to_s unless command.nil?
|
52
|
-
append_trigger(
|
116
|
+
append_trigger(type: type, config: config, attach: attach, conditions: conditions)
|
53
117
|
end
|
54
|
-
end
|
55
118
|
|
56
|
-
|
57
|
-
# Create trigger for item commands
|
58
|
-
#
|
59
|
-
# @param [Item] item to create trigger for
|
60
|
-
#
|
61
|
-
# @return [Array<Hash,Trigger>] first element is hash of trigger config properties
|
62
|
-
# second element is trigger type
|
63
|
-
#
|
64
|
-
def create_item_command_trigger(item)
|
65
|
-
config = { 'itemName' => item.name }
|
66
|
-
trigger = Trigger::ITEM_COMMAND
|
67
|
-
[config, trigger]
|
68
|
-
end
|
119
|
+
private
|
69
120
|
|
70
|
-
|
71
|
-
|
72
|
-
#
|
73
|
-
# @param [Group] group to create trigger for
|
74
|
-
#
|
75
|
-
# @return [Array<Hash,Trigger>] first element is hash of trigger config properties
|
76
|
-
# second element is trigger type
|
77
|
-
#
|
78
|
-
def create_group_command_trigger(group)
|
79
|
-
config = { 'groupName' => group.group.name }
|
80
|
-
trigger = Trigger::GROUP_COMMAND
|
81
|
-
[config, trigger]
|
82
|
-
end
|
121
|
+
# @return [String] item command trigger
|
122
|
+
ITEM_COMMAND = 'core.ItemCommandTrigger'
|
83
123
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
124
|
+
# @return [String] A group command trigger for items in the group
|
125
|
+
GROUP_COMMAND = 'core.GroupCommandTrigger'
|
126
|
+
|
127
|
+
#
|
128
|
+
# Create trigger for item commands
|
129
|
+
#
|
130
|
+
# @param [Item] item to create trigger for
|
131
|
+
#
|
132
|
+
# @return [Array<Hash,Trigger>] first element is hash of trigger config properties
|
133
|
+
# second element is trigger type
|
134
|
+
#
|
135
|
+
def item(item:)
|
136
|
+
[ITEM_COMMAND, { 'itemName' => item.name }]
|
137
|
+
end
|
138
|
+
|
139
|
+
#
|
140
|
+
# Create trigger for group items
|
141
|
+
#
|
142
|
+
# @param [Group] group to create trigger for
|
143
|
+
#
|
144
|
+
# @return [Array<Hash,Trigger>] first element is hash of trigger config properties
|
145
|
+
# second element is trigger type
|
146
|
+
#
|
147
|
+
def group(group:)
|
148
|
+
[GROUP_COMMAND, { 'groupName' => group.group.name }]
|
149
|
+
end
|
100
150
|
end
|
101
151
|
end
|
102
152
|
end
|
@@ -38,9 +38,9 @@ module OpenHAB
|
|
38
38
|
#
|
39
39
|
def self.range_proc(range)
|
40
40
|
logger.trace("Creating range proc for #{range}")
|
41
|
-
lambda do |
|
42
|
-
logger.trace("Range proc checking if #{
|
43
|
-
range.
|
41
|
+
lambda do |val|
|
42
|
+
logger.trace("Range proc checking if #{val} is in #{range}")
|
43
|
+
range.cover? val
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
@@ -77,9 +77,10 @@ module OpenHAB
|
|
77
77
|
# @param [Proc] from Proc to check against from value
|
78
78
|
# @param [Proc] to Proc to check against to value
|
79
79
|
#
|
80
|
-
def initialize(from: nil, to: nil)
|
80
|
+
def initialize(from: nil, to: nil, command: nil)
|
81
81
|
@from = from
|
82
82
|
@to = to
|
83
|
+
@command = command
|
83
84
|
end
|
84
85
|
|
85
86
|
#
|
@@ -88,7 +89,18 @@ module OpenHAB
|
|
88
89
|
#
|
89
90
|
def process(mod:, inputs:) # rubocop:disable Lint/UnusedMethodArgument - mod is unused here but required
|
90
91
|
logger.trace("Checking #{inputs} against condition trigger #{self}")
|
91
|
-
yield if
|
92
|
+
yield if check_procs(inputs: inputs)
|
93
|
+
end
|
94
|
+
|
95
|
+
#
|
96
|
+
# Check if command condition match the proc
|
97
|
+
# @param [Hash] inputs from trigger must be supplied if state is not supplied
|
98
|
+
# @return [true/false] depending on if from is set and matches supplied conditions
|
99
|
+
#
|
100
|
+
def check_command(inputs: nil)
|
101
|
+
command = input_state(inputs, 'command')
|
102
|
+
logger.trace "Checking command(#{@command}) against command(#{command})"
|
103
|
+
check_proc(proc: @command, value: command)
|
92
104
|
end
|
93
105
|
|
94
106
|
#
|
@@ -100,7 +112,7 @@ module OpenHAB
|
|
100
112
|
def check_from(inputs: nil, state: nil)
|
101
113
|
state ||= input_state(inputs, 'oldState')
|
102
114
|
logger.trace "Checking from(#{@from}) against state(#{state})"
|
103
|
-
check_proc(proc: @from,
|
115
|
+
check_proc(proc: @from, value: state)
|
104
116
|
end
|
105
117
|
|
106
118
|
#
|
@@ -112,27 +124,34 @@ module OpenHAB
|
|
112
124
|
def check_to(inputs: nil, state: nil)
|
113
125
|
state ||= input_state(inputs, 'newState', 'state')
|
114
126
|
logger.trace "Checking to(#{@to}) against state(#{state})"
|
115
|
-
check_proc(proc: @to,
|
127
|
+
check_proc(proc: @to, value: state)
|
116
128
|
end
|
117
129
|
|
118
130
|
# Describe the Proc Condition as a string
|
119
131
|
# @return [String] string representation of proc condition
|
120
132
|
#
|
121
133
|
def to_s
|
122
|
-
"From:(#{@from}) To:(#{@to})"
|
134
|
+
"From:(#{@from}) To:(#{@to}) Command:(#{@command})"
|
123
135
|
end
|
124
136
|
|
125
137
|
private
|
126
138
|
|
139
|
+
#
|
140
|
+
# Check all procs
|
141
|
+
# @param [Hash] inputs from event
|
142
|
+
# @return [true/false] true if all procs return true, false otherwise
|
143
|
+
def check_procs(inputs:)
|
144
|
+
check_from(inputs: inputs) && check_to(inputs: inputs) && check_command(inputs: inputs)
|
145
|
+
end
|
146
|
+
|
127
147
|
# Check if a field matches the proc condition
|
128
148
|
# @param [Proc] proc to call
|
129
|
-
# @param [Hash]
|
130
|
-
# @param [Array] fields array of fields to extract from inputs, first one found is passed to proc
|
149
|
+
# @param [Hash] value to check
|
131
150
|
# @return [true,false] true if proc is nil or proc.call returns true, false otherwise
|
132
|
-
def check_proc(proc:,
|
133
|
-
return true if proc.nil? || proc.call(
|
151
|
+
def check_proc(proc:, value:)
|
152
|
+
return true if proc.nil? || proc.call(value)
|
134
153
|
|
135
|
-
logger.trace("Skipped execution of rule because
|
154
|
+
logger.trace("Skipped execution of rule because value #{value} evaluated false for (#{proc})")
|
136
155
|
false
|
137
156
|
end
|
138
157
|
|
@@ -0,0 +1,185 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'java'
|
4
|
+
require 'openhab/dsl/rules/triggers/trigger'
|
5
|
+
|
6
|
+
module OpenHAB
|
7
|
+
module DSL
|
8
|
+
module Rules
|
9
|
+
#
|
10
|
+
# Cron type rules
|
11
|
+
#
|
12
|
+
module Triggers
|
13
|
+
#
|
14
|
+
# Create a rule that executes at the specified interval
|
15
|
+
#
|
16
|
+
# @param [Object] value Symbol or Duration to execute this rule
|
17
|
+
# @param [Object] at TimeOfDay or String representing TimeOfDay in which to execute rule
|
18
|
+
#
|
19
|
+
#
|
20
|
+
def every(value, at: nil, attach: nil)
|
21
|
+
cron_expression = case value
|
22
|
+
when Symbol then Cron.from_symbol(value, at)
|
23
|
+
when Java::JavaTime::Duration then Cron.from_duration(value, at)
|
24
|
+
else raise ArgumentExpression, 'Unknown interval'
|
25
|
+
end
|
26
|
+
cron(cron_expression, attach: attach)
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# Create a OpenHAB Cron trigger
|
31
|
+
#
|
32
|
+
# @param [String] expression OpenHAB style cron expression
|
33
|
+
#
|
34
|
+
def cron(expression, attach: nil)
|
35
|
+
cron = Cron.new(rule_triggers: @rule_triggers)
|
36
|
+
cron.trigger(config: { 'cronExpression' => expression }, attach: attach)
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# Creates cron triggers
|
41
|
+
#
|
42
|
+
class Cron < Trigger
|
43
|
+
# Trigger ID for Watch Triggers
|
44
|
+
CRON_TRIGGER_MODULE_ID = 'jsr223.jruby.CronTrigger'
|
45
|
+
|
46
|
+
#
|
47
|
+
# Returns a default map for cron expressions that fires every second
|
48
|
+
# This map is usually updated via merge by other methods to refine cron type triggers.
|
49
|
+
#
|
50
|
+
# @return [Hash] Map with symbols for :seconds, :minute, :hour, :dom, :month, :dow
|
51
|
+
# configured to fire every second
|
52
|
+
#
|
53
|
+
CRON_EXPRESSION_MAP =
|
54
|
+
{
|
55
|
+
second: '*',
|
56
|
+
minute: '*',
|
57
|
+
hour: '*',
|
58
|
+
dom: '?',
|
59
|
+
month: '*',
|
60
|
+
dow: '?'
|
61
|
+
}.freeze
|
62
|
+
private_constant :CRON_EXPRESSION_MAP
|
63
|
+
|
64
|
+
# @return [Hash] Map of days of the week from symbols to to OpenHAB cron strings
|
65
|
+
DAY_OF_WEEK_MAP = {
|
66
|
+
monday: 'MON',
|
67
|
+
tuesday: 'TUE',
|
68
|
+
wednesday: 'WED',
|
69
|
+
thursday: 'THU',
|
70
|
+
friday: 'FRI',
|
71
|
+
saturday: 'SAT',
|
72
|
+
sunday: 'SUN'
|
73
|
+
}.freeze
|
74
|
+
private_constant :DAY_OF_WEEK_MAP
|
75
|
+
|
76
|
+
# @return [Hash] Converts the DAY_OF_WEEK_MAP to map used by Cron Expression
|
77
|
+
DAY_OF_WEEK_EXPRESSION_MAP = DAY_OF_WEEK_MAP.transform_values { |v| CRON_EXPRESSION_MAP.merge(dow: v) }
|
78
|
+
|
79
|
+
private_constant :DAY_OF_WEEK_EXPRESSION_MAP
|
80
|
+
|
81
|
+
# @return [Hash] Create a set of cron expressions based on different time intervals
|
82
|
+
EXPRESSION_MAP = {
|
83
|
+
second: CRON_EXPRESSION_MAP,
|
84
|
+
minute: CRON_EXPRESSION_MAP.merge(second: '0'),
|
85
|
+
hour: CRON_EXPRESSION_MAP.merge(second: '0', minute: '0'),
|
86
|
+
day: CRON_EXPRESSION_MAP.merge(second: '0', minute: '0', hour: '0'),
|
87
|
+
week: CRON_EXPRESSION_MAP.merge(second: '0', minute: '0', hour: '0', dow: 'MON'),
|
88
|
+
month: CRON_EXPRESSION_MAP.merge(second: '0', minute: '0', hour: '0', dom: '1'),
|
89
|
+
year: CRON_EXPRESSION_MAP.merge(second: '0', minute: '0', hour: '0', dom: '1', month: '1')
|
90
|
+
}.merge(DAY_OF_WEEK_EXPRESSION_MAP).freeze
|
91
|
+
|
92
|
+
private_constant :EXPRESSION_MAP
|
93
|
+
|
94
|
+
#
|
95
|
+
# Create a cron map from a duration
|
96
|
+
#
|
97
|
+
# @param [java::time::Duration] duration
|
98
|
+
# @param [Object] at TimeOfDay or String representing time of day
|
99
|
+
#
|
100
|
+
# @return [Hash] map describing cron expression
|
101
|
+
#
|
102
|
+
def self.from_duration(duration, at)
|
103
|
+
raise ArgumentError, '"at" cannot be used with duration' if at
|
104
|
+
|
105
|
+
map_to_cron(duration_to_map(duration))
|
106
|
+
end
|
107
|
+
|
108
|
+
#
|
109
|
+
# Create a cron map from a symbol
|
110
|
+
#
|
111
|
+
# @param [Symbol] symbol
|
112
|
+
# @param [Object] at TimeOfDay or String representing time of day
|
113
|
+
#
|
114
|
+
# @return [Hash] map describing cron expression created from symbol
|
115
|
+
#
|
116
|
+
def self.from_symbol(symbol, at)
|
117
|
+
expression_map = EXPRESSION_MAP[symbol]
|
118
|
+
expression_map = at_condition(expression_map, at) if at
|
119
|
+
map_to_cron(expression_map)
|
120
|
+
end
|
121
|
+
|
122
|
+
#
|
123
|
+
# Map cron expression to to cron string
|
124
|
+
#
|
125
|
+
# @param [Map] map of cron expression
|
126
|
+
#
|
127
|
+
# @return [String] OpenHAB cron string
|
128
|
+
#
|
129
|
+
def self.map_to_cron(map)
|
130
|
+
%i[second minute hour dom month dow].map { |field| map.fetch(field) }.join(' ')
|
131
|
+
end
|
132
|
+
|
133
|
+
#
|
134
|
+
# Convert a Java Duration to a map for the map_to_cron method
|
135
|
+
#
|
136
|
+
# @param duration [Java::JavaTime::Duration] The duration object
|
137
|
+
#
|
138
|
+
# @return [Hash] a map suitable for map_to_cron
|
139
|
+
#
|
140
|
+
def self.duration_to_map(duration)
|
141
|
+
if duration.to_millis_part.zero? && duration.to_nanos_part.zero? && duration.to_days.zero?
|
142
|
+
%i[second minute hour].each do |unit|
|
143
|
+
to_unit_part = duration.public_send("to_#{unit}s_part")
|
144
|
+
next unless to_unit_part.positive?
|
145
|
+
|
146
|
+
to_unit = duration.public_send("to_#{unit}s")
|
147
|
+
break unless to_unit_part == to_unit
|
148
|
+
|
149
|
+
return EXPRESSION_MAP[unit].merge(unit => "*/#{to_unit}")
|
150
|
+
end
|
151
|
+
end
|
152
|
+
raise ArgumentError, "Cron Expression not supported for duration: #{duration}"
|
153
|
+
end
|
154
|
+
|
155
|
+
#
|
156
|
+
# If an at time is provided, parse that and merge the new fields into the expression.
|
157
|
+
#
|
158
|
+
# @param [<Type>] expression_map <description>
|
159
|
+
# @param [<Type>] at_time <description>
|
160
|
+
#
|
161
|
+
# @return [<Type>] <description>
|
162
|
+
#
|
163
|
+
def self.at_condition(expression_map, at_time)
|
164
|
+
if at_time
|
165
|
+
tod = at_time.is_a?(TimeOfDay::TimeOfDay) ? at_time : TimeOfDay::TimeOfDay.parse(at_time)
|
166
|
+
expression_map = expression_map.merge(hour: tod.hour, minute: tod.minute, second: tod.second)
|
167
|
+
end
|
168
|
+
expression_map
|
169
|
+
end
|
170
|
+
|
171
|
+
#
|
172
|
+
# Create a cron trigger based on item type
|
173
|
+
#
|
174
|
+
# @param [Array] commands to create trigger for
|
175
|
+
# @param [Object] item to create trigger for
|
176
|
+
#
|
177
|
+
#
|
178
|
+
def trigger(config:, attach:)
|
179
|
+
append_trigger(type: CRON_TRIGGER_MODULE_ID, config: config, attach: attach)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|