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.
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'java'
4
+ require_relative 'cron'
5
+
6
+ module OpenHAB
7
+ module DSL
8
+ module Rules
9
+ #
10
+ # Cron type rules
11
+ #
12
+ module Triggers
13
+ #
14
+ # Cron trigger handler that provides trigger ID
15
+ #
16
+ module CronHandler
17
+ include OpenHAB::Log
18
+
19
+ #
20
+ # Creates trigger types and trigger type factories for OpenHAB
21
+ #
22
+ def self.add_script_cron_handler
23
+ java_import org.openhab.core.automation.type.TriggerType
24
+ OpenHAB::Core.automation_manager.add_trigger_handler(
25
+ OpenHAB::DSL::Rules::Triggers::Cron::CRON_TRIGGER_MODULE_ID,
26
+ OpenHAB::DSL::Rules::Triggers::CronHandler::CronTriggerHandlerFactory.new
27
+ )
28
+
29
+ OpenHAB::Core.automation_manager.add_trigger_type(cron_trigger_type)
30
+ OpenHAB::Log.logger(self).trace('Added script cron trigger handler')
31
+ end
32
+
33
+ #
34
+ # Creates trigger types and trigger type factories for OpenHAB
35
+ #
36
+ private_class_method def self.cron_trigger_type
37
+ TriggerType.new(
38
+ OpenHAB::DSL::Rules::Triggers::Cron::CRON_TRIGGER_MODULE_ID,
39
+ nil,
40
+ 'A specific instant occurs',
41
+ 'Triggers when the specified instant occurs',
42
+ nil,
43
+ org.openhab.core.automation.Visibility::VISIBLE,
44
+ nil
45
+ )
46
+ end
47
+
48
+ # Cron Trigger Handler that provides trigger IDs
49
+ # Unfortunatly because the CronTriggerHandler in OpenHAB core is marked internal
50
+ # the entire thing must be recreated here
51
+ class CronTriggerHandler < org.openhab.core.automation.handler.BaseTriggerModuleHandler
52
+ include OpenHAB::Log
53
+ include org.openhab.core.scheduler.SchedulerRunnable
54
+ include org.openhab.core.automation.handler.TimeBasedTriggerHandler
55
+
56
+ # Provides access to protected fields
57
+ field_accessor :callback
58
+
59
+ # Creates a new CronTriggerHandler
60
+ # @param [Trigger] OpenHAB trigger associated with handler
61
+ #
62
+ def initialize(trigger)
63
+ @trigger = trigger
64
+ @scheduler = OpenHAB::Core::OSGI.service('org.openhab.core.scheduler.CronScheduler')
65
+ @expression = trigger.configuration.get('cronExpression')
66
+ super(trigger)
67
+ end
68
+
69
+ #
70
+ # Set the callback to execute when cron trigger fires
71
+ # @param [Object] callback to run
72
+ #
73
+ def setCallback(callback) # rubocop:disable Naming/MethodName
74
+ synchronized do
75
+ super(callback)
76
+ @scheduler.schedule(self, @expression)
77
+ logger.trace("Scheduled cron job '#{@expression}' for trigger '#{@trigger.id}'.")
78
+ end
79
+ end
80
+
81
+ #
82
+ # Get the temporal adjuster
83
+ # @return [CronAdjuster]
84
+ #
85
+ def getTemporalAdjuster # rubocop:disable Naming/MethodName
86
+ org.openhab.core.scheduler.CronAdjuster.new(expression)
87
+ end
88
+
89
+ #
90
+ # Execute the callback
91
+ #
92
+ def run
93
+ callback&.triggered(@trigger, { 'module' => @trigger.id })
94
+ end
95
+
96
+ #
97
+ # Displose of the handler
98
+ # cancel the cron scheduled task
99
+ #
100
+ def dispose
101
+ synchronized do
102
+ super
103
+ return unless @schedule
104
+
105
+ @schedule&.cancel(true)
106
+ end
107
+ logger.trace("cancelled job for trigger '#{@trigger.id}'.")
108
+ end
109
+ end
110
+
111
+ # Implements the ScriptedTriggerHandlerFactory interface to create a new Cron Trigger Handler
112
+ class CronTriggerHandlerFactory
113
+ include org.openhab.core.automation.module.script.rulesupport.shared.factories.ScriptedTriggerHandlerFactory
114
+
115
+ # Invoked by the OpenHAB core to get a trigger handler for the supllied trigger
116
+ # @param [Trigger] OpenHAB trigger
117
+ #
118
+ # @return [WatchTriggerHandler] trigger handler for supplied trigger
119
+ def get(trigger)
120
+ CronTriggerHandler.new(trigger)
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
128
+
129
+ # Add the cron handler to OpenHAB
130
+ OpenHAB::DSL::Rules::Triggers::CronHandler.add_script_cron_handler
@@ -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
@@ -21,7 +22,7 @@ module OpenHAB
21
22
  #
22
23
  def trigger(type, attach: nil, **configuration)
23
24
  logger.trace("Creating a generic trigger for type(#{type}) with configuration(#{configuration})")
24
- append_trigger(type, configuration, attach: attach)
25
+ Trigger.new(rule_triggers: @rule_triggers).append_trigger(type: type, config: configuration, attach: attach)
25
26
  end
26
27
  end
27
28
  end
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'securerandom'
4
- require 'java'
5
- require_relative 'cron'
3
+ require 'forwardable'
6
4
 
7
5
  module OpenHAB
8
6
  module DSL
@@ -11,132 +9,66 @@ module OpenHAB
11
9
  # Module holds rule triggers
12
10
  #
13
11
  module Triggers
14
- #
15
- # Create a trigger for a thing
16
- #
17
- # @param [Thing] thing to create trigger for
18
- # @param [Trigger] trigger to map with thing
19
- # @param [State] to for thing
20
- # @param [State] from state of thing
21
- #
22
- # @return [Array] Trigger and config for thing
23
- #
24
- def trigger_for_thing(thing, trigger, to = nil, from = nil)
25
- config = { 'thingUID' => thing.uid.to_s }
26
- config['status'] = trigger_state_from_symbol(to).to_s if to
27
- config['previousStatus'] = trigger_state_from_symbol(from).to_s if from
28
- [trigger, config]
29
- end
30
-
31
- #
32
- # converts object to upcase string if its a symbol
33
- #
34
- # @param [sym] sym potential symbol to convert
35
- #
36
- # @return [String] Upcased symbol as string
37
- #
38
- def trigger_state_from_symbol(sym)
39
- sym.to_s.upcase if (sym.is_a? Symbol) || sym
40
- end
41
-
42
- #
43
- # Append a trigger to the list of triggeres
44
- #
45
- # @param [String] type of trigger to create
46
- # @param [Map] config map describing trigger configuration
47
- #
48
- # @return [Trigger] OpenHAB trigger
49
- #
50
- def append_trigger(type, config, attach: nil)
51
- logger.trace("Creating trigger of type #{type} for #{config}")
52
- config.transform_keys!(&:to_s)
53
- trigger = Trigger.trigger(type: type, config: config)
54
- @attachments[trigger.id] = attach if attach
55
- @triggers << trigger
56
- trigger
57
- end
58
-
59
- #
60
- # Separates groups from items, and flattens any nested arrays of items
61
- #
62
- # @param [Array] item_array Array of items passed to a trigger
63
- #
64
- # @return [Array] A new flat array with any GroupMembers object left intact
65
- #
66
- def separate_groups(item_array)
67
- # we want to support anything that can be flattened... i.e. responds to to_ary
68
- # we want to be more lenient than only things that are currently Array,
69
- # but Enumerable is too lenient because Array#flatten won't traverse interior
70
- # Enumerables
71
- return item_array unless item_array.find { |item| item.respond_to?(:to_ary) }
72
-
73
- groups, items = item_array.partition { |item| item.is_a?(OpenHAB::DSL::Items::GroupItem::GroupMembers) }
74
- groups + separate_groups(items.flatten(1))
75
- end
76
-
77
12
  #
78
13
  # Class for creating and managing triggers
79
14
  #
80
15
  class Trigger
81
- java_import org.openhab.core.automation.util.TriggerBuilder
82
- java_import org.openhab.core.config.core.Configuration
83
-
84
- # @return [String] A channel event trigger
85
- CHANNEL_EVENT = 'core.ChannelEventTrigger'
86
-
87
- # @return [String] A thing status Change trigger
88
- THING_CHANGE = 'core.ThingStatusChangeTrigger'
89
-
90
- # @return [String] A thing status update trigger
91
- THING_UPDATE = 'core.ThingStatusUpdateTrigger'
92
-
93
- # @return [String] An item command trigger
94
- ITEM_COMMAND = 'core.ItemCommandTrigger'
95
-
96
- # @return [String] An item state update trigger
97
- ITEM_STATE_UPDATE = 'core.ItemStateUpdateTrigger'
98
-
99
- # @return [String] An item state change trigger
100
- ITEM_STATE_CHANGE = 'core.ItemStateChangeTrigger'
16
+ extend Forwardable
101
17
 
102
- # @return [String] A group state change trigger for items in the group
103
- GROUP_STATE_CHANGE = 'core.GroupStateChangeTrigger'
18
+ # Provide backwards compatibility for these fields
19
+ delegate :append_trigger => :@rule_triggers
104
20
 
105
- # @return [String] A group state update trigger for items in the group
106
- GROUP_STATE_UPDATE = 'core.GroupStateUpdateTrigger'
107
-
108
- # @return [String] A group command trigger for items in the group
109
- GROUP_COMMAND = 'core.GroupCommandTrigger'
110
-
111
- # @return [String] A time of day trigger
112
- TIME_OF_DAY = 'timer.TimeOfDayTrigger'
21
+ #
22
+ # Separates groups from items, and flattens any nested arrays of items
23
+ #
24
+ # @param [Array] item_array Array of items passed to a trigger
25
+ #
26
+ # @return [Array] A new flat array with any GroupMembers object left intact
27
+ #
28
+ def self.flatten_items(item_array)
29
+ # we want to support anything that can be flattened... i.e. responds to to_ary
30
+ # we want to be more lenient than only things that are currently Array,
31
+ # but Enumerable is too lenient because Array#flatten won't traverse interior
32
+ # Enumerables
33
+ return item_array unless item_array.find { |item| item.respond_to?(:to_ary) }
34
+
35
+ groups, items = item_array.partition { |item| item.is_a?(OpenHAB::DSL::Items::GroupItem::GroupMembers) }
36
+ groups + flatten_items(items.flatten(1))
37
+ end
113
38
 
114
- # @return [String] A cron trigger
115
- CRON = OpenHAB::DSL::Rules::Triggers::Cron::CRON_TRIGGER_MODULE_ID
39
+ #
40
+ # Creates a new Trigger
41
+ # @param [RuleTrigger] rule trigger information
42
+ def initialize(rule_triggers:)
43
+ @rule_triggers = rule_triggers
44
+ end
116
45
 
117
46
  #
118
- # Create a trigger
47
+ # Create a trigger for a thing
119
48
  #
120
- # @param [String] type of trigger
121
- # @param [Map] config map
49
+ # @param [Thing] thing to create trigger for
50
+ # @param [Trigger] trigger to map with thing
51
+ # @param [State] to for thing
52
+ # @param [State] from state of thing
122
53
  #
123
- # @return [OpenHAB Trigger] configured by type and supplied config
54
+ # @return [Array] Trigger and config for thing
124
55
  #
125
- def self.trigger(type:, config:)
126
- TriggerBuilder.create
127
- .with_id(uuid)
128
- .with_type_uid(type)
129
- .with_configuration(Configuration.new(config))
130
- .build
56
+ def trigger_for_thing(thing:, type:, to: nil, from: nil)
57
+ config = { 'thingUID' => thing.uid.to_s }
58
+ config['status'] = trigger_state_from_symbol(to).to_s if to
59
+ config['previousStatus'] = trigger_state_from_symbol(from).to_s if from
60
+ [type, config]
131
61
  end
132
62
 
133
63
  #
134
- # Generate a UUID for triggers
64
+ # converts object to upcase string if its a symbol
65
+ #
66
+ # @param [sym] sym potential symbol to convert
135
67
  #
136
- # @return [String] UUID
68
+ # @return [String] Upcased symbol as string
137
69
  #
138
- def self.uuid
139
- SecureRandom.uuid
70
+ def trigger_state_from_symbol(sym)
71
+ sym.to_s.upcase if (sym.is_a? Symbol) || sym
140
72
  end
141
73
  end
142
74
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'cron/cron'
4
+ require_relative 'cron/cron_handler'
5
+ require_relative 'changed'
6
+ require_relative 'channel'
7
+ require_relative 'command'
8
+ require_relative 'updated'
9
+ require_relative 'generic'
10
+ require_relative 'watch/watch'
11
+ require_relative 'watch/watch_handler'
@@ -21,119 +21,133 @@ module OpenHAB
21
21
  # @return [Trigger] Trigger for updated entity
22
22
  #
23
23
  def updated(*items, to: nil, attach: nil)
24
- separate_groups(items).map do |item|
24
+ updated = Updated.new(rule_triggers: @rule_triggers)
25
+ Updated.flatten_items(items).map do |item|
25
26
  logger.trace("Creating updated trigger for item(#{item}) to(#{to})")
26
27
  [to].flatten.map do |to_state|
27
- update_trigger(item: item, to: to_state, attach: attach)
28
+ updated.trigger(item: item, to: to_state, attach: attach)
28
29
  end
29
30
  end.flatten
30
31
  end
31
32
 
32
- private
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
33
  #
42
- # @return [Trigger] OpenHAB triggers
34
+ # Creates updated triggers
43
35
  #
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)
36
+ class Updated < Trigger
37
+ include OpenHAB::Log
38
+
39
+ #
40
+ # Create the trigger
41
+ #
42
+ # @param [Object] item item to create trigger for
43
+ # @param [Item State] from state to restrict trigger to
44
+ # @param [Item State] to state to restrict trigger to
45
+ # @param attach attachment
46
+ #
47
+ # @return [Trigger] OpenHAB triggers
48
+ #
49
+ def trigger(item:, to:, attach:)
50
+ case to
51
+ when Range then range_trigger(item: item, to: to, attach: attach)
52
+ when Proc then proc_trigger(item: item, to: to, attach: attach)
53
+ else update_trigger(item: item, to: to, attach: attach)
54
+ end
49
55
  end
50
- end
51
56
 
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
57
+ private
63
58
 
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)
59
+ # @return [String] A thing status update trigger
60
+ THING_UPDATE = 'core.ThingStatusUpdateTrigger'
61
+
62
+ # @return [String] An item state update trigger
63
+ ITEM_STATE_UPDATE = 'core.ItemStateUpdateTrigger'
64
+
65
+ # @return [String] A group state update trigger for items in the group
66
+ GROUP_STATE_UPDATE = 'core.GroupStateUpdateTrigger'
67
+
68
+ #
69
+ # Creates a trigger with a range condition on the 'to' field
70
+ # @param [Object] item to create changed trigger on
71
+ # @param [Object] to state restrict trigger to
72
+ # @param [Object] attach to trigger
73
+ # @return [Trigger] OpenHAB trigger
74
+ #
75
+ def range_trigger(item:, to:, attach:)
76
+ to, * = Conditions::Proc.range_procs(to)
77
+ proc_trigger(item: item, to: to, attach: attach)
74
78
  end
75
- end
76
79
 
77
- #
78
- # Create a trigger for updates
79
- #
80
- # @param [Object] item Type of item [Group,Thing,Item] to create update trigger for
81
- # @param [State] to_state state restriction on trigger
82
- #
83
- # @return [Trigger] OpenHAB triggers
84
- #
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)
92
- end
80
+ #
81
+ # Creates a trigger with a proc condition on the 'to' field
82
+ # @param [Object] item to create changed trigger on
83
+ # @param [Object] to state restrict trigger to
84
+ # @param [Object] attach to trigger
85
+ # @return [Trigger] OpenHAB trigger
86
+ #
87
+ def proc_trigger(item:, to:, attach:)
88
+ conditions = Conditions::Proc.new(to: to)
89
+ update_trigger(item: item, to: nil, attach: attach, conditions: conditions)
90
+ end
93
91
 
94
- #
95
- # Create an update trigger for an item
96
- #
97
- # @param [Item] item to create trigger for
98
- # @param [State] to_state optional state restriction for target
99
- #
100
- # @return [Array<Hash,String>] first element is a String specifying trigger type
101
- # second element is a Hash configuring trigger
102
- #
103
- def item_update(item:, to:)
104
- config = { 'itemName' => item.name }
105
- config['state'] = to.to_s unless to.nil?
106
- trigger = Trigger::ITEM_STATE_UPDATE
107
- [trigger, config]
108
- end
92
+ #
93
+ # Create a trigger for updates
94
+ #
95
+ # @param [Object] item Type of item [Group,Thing,Item] to create update trigger for
96
+ # @param [State] to_state state restriction on trigger
97
+ #
98
+ # @return [Trigger] OpenHAB triggers
99
+ #
100
+ def update_trigger(item:, to:, attach: nil, conditions: nil)
101
+ type, config = case item
102
+ when OpenHAB::DSL::Items::GroupItem::GroupMembers then group_update(item: item, to: to)
103
+ when Thing then thing_update(thing: item, to: to)
104
+ else item_update(item: item, to: to)
105
+ end
106
+ append_trigger(type: type, config: config, attach: attach, conditions: conditions)
107
+ end
109
108
 
110
- #
111
- # Create an update trigger for a group
112
- #
113
- # @param [Item] item to create trigger for
114
- # @param [State] to_state optional state restriction for target
115
- #
116
- # @return [Array<Hash,String>] first element is a String specifying trigger type
117
- # second element is a Hash configuring trigger
118
- #
119
- def group_update(item:, to:)
120
- config = { 'groupName' => item.group.name }
121
- config['state'] = to.to_s unless to.nil?
122
- trigger = Trigger::GROUP_STATE_UPDATE
123
- [trigger, config]
124
- end
109
+ #
110
+ # Create an update trigger for an item
111
+ #
112
+ # @param [Item] item to create trigger for
113
+ # @param [State] to_state optional state restriction for target
114
+ #
115
+ # @return [Array<Hash,String>] first element is a String specifying trigger type
116
+ # second element is a Hash configuring trigger
117
+ #
118
+ def item_update(item:, to:)
119
+ config = { 'itemName' => item.name }
120
+ config['state'] = to.to_s unless to.nil?
121
+ [ITEM_STATE_UPDATE, config]
122
+ end
125
123
 
126
- #
127
- # Create an update trigger for a thing
128
- #
129
- # @param [Thing] thing to create trigger for
130
- # @param [State] to_state optional state restriction for target
131
- #
132
- # @return [Array<Hash,String>] first element is a String specifying trigger type
133
- # second element is a Hash configuring trigger
134
- #
135
- def thing_update(thing:, to:)
136
- trigger_for_thing(thing, Trigger::THING_UPDATE, to)
124
+ #
125
+ # Create an update trigger for a group
126
+ #
127
+ # @param [Item] item to create trigger for
128
+ # @param [State] to_state optional state restriction for target
129
+ #
130
+ # @return [Array<Hash,String>] first element is a String specifying trigger type
131
+ # second element is a Hash configuring trigger
132
+ #
133
+ def group_update(item:, to:)
134
+ config = { 'groupName' => item.group.name }
135
+ config['state'] = to.to_s unless to.nil?
136
+ [GROUP_STATE_UPDATE, config]
137
+ end
138
+
139
+ #
140
+ # Create an update trigger for a thing
141
+ #
142
+ # @param [Thing] thing to create trigger for
143
+ # @param [State] to_state optional state restriction for target
144
+ #
145
+ # @return [Array<Hash,String>] first element is a String specifying trigger type
146
+ # second element is a Hash configuring trigger
147
+ #
148
+ def thing_update(thing:, to:)
149
+ trigger_for_thing(thing: thing, type: THING_UPDATE, to: to)
150
+ end
137
151
  end
138
152
  end
139
153
  end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'openhab/log/logger'
4
+ require 'openhab/dsl/rules/triggers/trigger'
5
+
6
+ module OpenHAB
7
+ module DSL
8
+ module Rules
9
+ #
10
+ # Module holds rule triggers
11
+ #
12
+ module Triggers
13
+ #
14
+ # Module for watching directories/files
15
+ #
16
+
17
+ #
18
+ # Create a trigger to watch a path
19
+ #
20
+ # @param [String] path to watch
21
+ #
22
+ # @return [Trigger] Trigger object
23
+ #
24
+ def watch(path, glob: '*', for: %i[created deleted modified], attach: nil)
25
+ glob, path = Watch.glob_for_path(Pathname.new(path), glob)
26
+ types = [binding.local_variable_get(:for)].flatten
27
+ config = { path: path.to_s, types: types.map(&:to_s), glob: glob.to_s }
28
+
29
+ logger.state 'Creating a watch trigger', path: path, glob: glob, types: types
30
+ Watch.new(rule_triggers: @rule_triggers).trigger(config: config, attach: attach)
31
+ end
32
+
33
+ #
34
+ # Creates watch triggers
35
+ #
36
+ class Watch < Trigger
37
+ # Characters in an fnmatch compatible glob
38
+ GLOB_CHARS = ['**', '*', '?', '[', ']', '{', '}'].freeze
39
+ private_constant :GLOB_CHARS
40
+
41
+ #
42
+ # Automatically creates globs for supplied paths if necessary
43
+ # @param [Pathname] path to check
44
+ # @param [String] specified glob
45
+ #
46
+ # @return [Pathname,String] Pathname to watch and glob to match
47
+ def self.glob_for_path(path, glob)
48
+ # Checks if the supplied pathname last element contains a glob char
49
+ if GLOB_CHARS.any? { |char| path.basename.to_s.include? char }
50
+ # Splits the supplied pathname into a glob string and parent path
51
+ [path.basename.to_s, path.parent]
52
+ elsif path.file? || !path.exist?
53
+ # glob string matching end of Pathname and parent path
54
+ ["*/#{path.basename}", path.parent]
55
+ else
56
+ [glob, path]
57
+ end
58
+ end
59
+
60
+ #
61
+ # Create a watch trigger based on item type
62
+ #
63
+ # @param [Array] commands to create trigger for
64
+ # @param [Object] item to create trigger for
65
+ #
66
+ #
67
+ def trigger(config:, attach:)
68
+ append_trigger(type: WatchHandler::WATCH_TRIGGER_MODULE_ID,
69
+ config: config,
70
+ attach: attach)
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end