openhab-scripting 4.30.3 → 4.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/openhab/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
|