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.
@@ -14,32 +14,15 @@ module OpenHAB
14
14
  #
15
15
  # Module for watching directories/files
16
16
  #
17
- module Watch
17
+ module WatchHandler
18
18
  include OpenHAB::Log
19
19
 
20
- # Characters in an fnmatch compatible glob
21
- GLOB_CHARS = ['**', '*', '?', '[', ']', '{', '}'].freeze
22
-
23
- #
24
- # Creates trigger types and trigger type factories for OpenHAB
25
- #
26
- def self.add_watch_handler
27
- java_import org.openhab.core.automation.type.TriggerType
28
- OpenHAB::Core.automation_manager.add_trigger_handler(
29
- OpenHAB::DSL::Rules::Triggers::Watch::WATCH_TRIGGER_MODULE_ID,
30
- OpenHAB::DSL::Rules::Triggers::Watch::WatchTriggerHandlerFactory.new
31
- )
32
-
33
- OpenHAB::Core.automation_manager.add_trigger_type(watch_trigger_type)
34
- OpenHAB::Log.logger(self).trace('Added watch trigger handler')
35
- end
36
-
37
20
  #
38
21
  # Creates trigger types and trigger type factories for OpenHAB
39
22
  #
40
23
  private_class_method def self.watch_trigger_type
41
24
  TriggerType.new(
42
- OpenHAB::DSL::Rules::Triggers::Watch::WATCH_TRIGGER_MODULE_ID,
25
+ WATCH_TRIGGER_MODULE_ID,
43
26
  nil,
44
27
  'A path change event is detected',
45
28
  'Triggers when a path change event is detected',
@@ -163,44 +146,19 @@ module OpenHAB
163
146
  WatchTriggerHandler.new(trigger)
164
147
  end
165
148
  end
166
- end
167
149
 
168
- #
169
- # Create a trigger to watch a path
170
- #
171
- # @param [String] path to watch
172
- #
173
- # @return [Trigger] Trigger object
174
- #
175
- def watch(path, glob: '*', for: %i[created deleted modified], attach: nil)
176
- glob, path = glob_for_path(Pathname.new(path), glob)
177
- types = [binding.local_variable_get(:for)].flatten
178
- conf = { path: path.to_s, types: types.map(&:to_s), glob: glob.to_s }
179
-
180
- logger.trace("Creating a watch trigger for path(#{path}) with glob(#{glob}) for types(#{types})")
181
- append_trigger(OpenHAB::DSL::Rules::Triggers::Watch::WATCH_TRIGGER_MODULE_ID,
182
- conf,
183
- attach: attach)
184
- end
185
-
186
- private
150
+ #
151
+ # Creates trigger types and trigger type factories for OpenHAB
152
+ #
153
+ def self.add_watch_handler
154
+ java_import org.openhab.core.automation.type.TriggerType
155
+ OpenHAB::Core.automation_manager.add_trigger_handler(
156
+ WATCH_TRIGGER_MODULE_ID,
157
+ WatchTriggerHandlerFactory.new
158
+ )
187
159
 
188
- #
189
- # Automatically creates globs for supplied paths if necessary
190
- # @param [Pathname] path to check
191
- # @param [String] specified glob
192
- #
193
- # @return [Pathname,String] Pathname to watch and glob to match
194
- def glob_for_path(path, glob)
195
- # Checks if the supplied pathname last element contains a glob char
196
- if OpenHAB::DSL::Rules::Triggers::Watch::GLOB_CHARS.any? { |char| path.basename.to_s.include? char }
197
- # Splits the supplied pathname into a glob string and parent path
198
- [path.basename.to_s, path.parent]
199
- elsif path.file? || !path.exist?
200
- # glob string matching end of Pathname and parent path
201
- ["*/#{path.basename}", path.parent]
202
- else
203
- [glob, path]
160
+ OpenHAB::Core.automation_manager.add_trigger_type(watch_trigger_type)
161
+ OpenHAB::Log.logger(self).trace('Added watch trigger handler')
204
162
  end
205
163
  end
206
164
  end
@@ -208,4 +166,4 @@ module OpenHAB
208
166
  end
209
167
  end
210
168
  # Add the watch handler to OpenHAB
211
- OpenHAB::DSL::Rules::Triggers::Watch.add_watch_handler
169
+ OpenHAB::DSL::Rules::Triggers::WatchHandler.add_watch_handler
@@ -80,7 +80,7 @@ module OpenHAB
80
80
  end
81
81
 
82
82
  # any method that exists on String gets forwarded to to_s
83
- delegate (String.instance_methods - instance_methods) => :to_s
83
+ delegate (String.instance_methods - instance_methods + %w[=~ inspect]) => :to_s
84
84
  end
85
85
  end
86
86
  end
@@ -61,6 +61,22 @@ module OpenHAB
61
61
  define_method("#{level}_enabled?") { @sl4fj_logger.send("is_#{level}_enabled") }
62
62
  end
63
63
 
64
+ #
65
+ # Logs a map of key(value) with an optional preamble at trace level
66
+ # @param [String] preamble to put at start of log message
67
+ # @param [Hash] key and values to log
68
+ def state(preamble = 'State:', **kwargs)
69
+ return unless trace_enabled?
70
+
71
+ states = kwargs.transform_keys(&:to_s)
72
+ .transform_keys(&:capitalize)
73
+ .transform_values { |v| v.nil? ? 'nil' : v }
74
+ .map { |k, v| "#{k}(#{v})" }
75
+ .join(' ')
76
+ trace "#{preamble} #{states}"
77
+ end
78
+ alias states state
79
+
64
80
  #
65
81
  # Cleans the backtrace of an error to remove internal calls. If logging is set
66
82
  # to debug or lower, the full backtrace is kept
@@ -5,5 +5,5 @@
5
5
  #
6
6
  module OpenHAB
7
7
  # @return [String] Version of OpenHAB helper libraries
8
- VERSION = '4.30.3'
8
+ VERSION = '4.32.0'
9
9
  end
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.30.3
4
+ version: 4.32.0
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-20 00:00:00.000000000 Z
11
+ date: 2022-01-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -102,17 +102,21 @@ files:
102
102
  - lib/openhab/dsl/rules/property.rb
103
103
  - lib/openhab/dsl/rules/rule.rb
104
104
  - lib/openhab/dsl/rules/rule_config.rb
105
+ - lib/openhab/dsl/rules/rule_triggers.rb
105
106
  - lib/openhab/dsl/rules/terse.rb
106
107
  - lib/openhab/dsl/rules/triggers/changed.rb
107
108
  - lib/openhab/dsl/rules/triggers/channel.rb
108
109
  - lib/openhab/dsl/rules/triggers/command.rb
109
110
  - lib/openhab/dsl/rules/triggers/conditions/duration.rb
110
111
  - lib/openhab/dsl/rules/triggers/conditions/proc.rb
111
- - lib/openhab/dsl/rules/triggers/cron.rb
112
+ - lib/openhab/dsl/rules/triggers/cron/cron.rb
113
+ - lib/openhab/dsl/rules/triggers/cron/cron_handler.rb
112
114
  - lib/openhab/dsl/rules/triggers/generic.rb
113
115
  - lib/openhab/dsl/rules/triggers/trigger.rb
116
+ - lib/openhab/dsl/rules/triggers/triggers.rb
114
117
  - lib/openhab/dsl/rules/triggers/updated.rb
115
- - lib/openhab/dsl/rules/triggers/watch.rb
118
+ - lib/openhab/dsl/rules/triggers/watch/watch.rb
119
+ - lib/openhab/dsl/rules/triggers/watch/watch_handler.rb
116
120
  - lib/openhab/dsl/states.rb
117
121
  - lib/openhab/dsl/things.rb
118
122
  - lib/openhab/dsl/time/month_day.rb
@@ -1,288 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'java'
4
-
5
- module OpenHAB
6
- module DSL
7
- module Rules
8
- #
9
- # Cron type rules
10
- #
11
- module Triggers
12
- #
13
- # Returns a default map for cron expressions that fires every second
14
- # This map is usually updated via merge by other methods to refine cron type triggers.
15
- #
16
- # @return [Hash] Map with symbols for :seconds, :minute, :hour, :dom, :month, :dow
17
- # configured to fire every second
18
- #
19
- def cron_expression_map
20
- {
21
- second: '*',
22
- minute: '*',
23
- hour: '*',
24
- dom: '?',
25
- month: '*',
26
- dow: '?'
27
- }
28
- end
29
-
30
- module_function :cron_expression_map
31
-
32
- # @return [Hash] Map of days of the week from symbols to to OpenHAB cron strings
33
- DAY_OF_WEEK_MAP = {
34
- monday: 'MON',
35
- tuesday: 'TUE',
36
- wednesday: 'WED',
37
- thursday: 'THU',
38
- friday: 'FRI',
39
- saturday: 'SAT',
40
- sunday: 'SUN'
41
- }.freeze
42
-
43
- private_constant :DAY_OF_WEEK_MAP
44
-
45
- # @return [Hash] Converts the DAY_OF_WEEK_MAP to map used by Cron Expression
46
- DAY_OF_WEEK_EXPRESSION_MAP = DAY_OF_WEEK_MAP.transform_values { |v| cron_expression_map.merge(dow: v) }
47
-
48
- private_constant :DAY_OF_WEEK_EXPRESSION_MAP
49
-
50
- # @return [Hash] Create a set of cron expressions based on different time intervals
51
- EXPRESSION_MAP = {
52
- second: cron_expression_map,
53
- minute: cron_expression_map.merge(second: '0'),
54
- hour: cron_expression_map.merge(second: '0', minute: '0'),
55
- day: cron_expression_map.merge(second: '0', minute: '0', hour: '0'),
56
- week: cron_expression_map.merge(second: '0', minute: '0', hour: '0', dow: 'MON'),
57
- month: cron_expression_map.merge(second: '0', minute: '0', hour: '0', dom: '1'),
58
- year: cron_expression_map.merge(second: '0', minute: '0', hour: '0', dom: '1', month: '1')
59
- }.merge(DAY_OF_WEEK_EXPRESSION_MAP)
60
- .freeze
61
-
62
- private_constant :EXPRESSION_MAP
63
-
64
- #
65
- # Create a rule that executes at the specified interval
66
- #
67
- # @param [Object] value Symbol or Duration to execute this rule
68
- # @param [Object] at TimeOfDay or String representing TimeOfDay in which to execute rule
69
- #
70
- #
71
- def every(value, at: nil, attach: nil)
72
- cron_expression = case value
73
- when Symbol then cron_from_symbol(value, at)
74
- when Java::JavaTime::Duration then cron_from_duration(value, at)
75
- else raise ArgumentExpression, 'Unknown interval'
76
- end
77
- cron(cron_expression, attach: attach)
78
- end
79
-
80
- #
81
- # Create a OpenHAB Cron trigger
82
- #
83
- # @param [String] expression OpenHAB style cron expression
84
- #
85
- def cron(expression, attach: nil)
86
- append_trigger(Trigger::CRON, { 'cronExpression' => expression }, attach: attach)
87
- end
88
-
89
- private
90
-
91
- #
92
- # Create a cron map from a duration
93
- #
94
- # @param [java::time::Duration] duration
95
- # @param [Object] at TimeOfDay or String representing time of day
96
- #
97
- # @return [Hash] map describing cron expression
98
- #
99
- def cron_from_duration(duration, at)
100
- raise ArgumentError, '"at" cannot be used with duration' if at
101
-
102
- map_to_cron(duration_to_map(duration))
103
- end
104
-
105
- #
106
- # Create a cron map from a symbol
107
- #
108
- # @param [Symbol] symbol
109
- # @param [Object] at TimeOfDay or String representing time of day
110
- #
111
- # @return [Hash] map describing cron expression created from symbol
112
- #
113
- def cron_from_symbol(symbol, at)
114
- expression_map = EXPRESSION_MAP[symbol]
115
- expression_map = at_condition(expression_map, at) if at
116
- map_to_cron(expression_map)
117
- end
118
-
119
- #
120
- # Map cron expression to to cron string
121
- #
122
- # @param [Map] map of cron expression
123
- #
124
- # @return [String] OpenHAB cron string
125
- #
126
- def map_to_cron(map)
127
- %i[second minute hour dom month dow].map { |field| map.fetch(field) }.join(' ')
128
- end
129
-
130
- #
131
- # Convert a Java Duration to a map for the map_to_cron method
132
- #
133
- # @param duration [Java::JavaTime::Duration] The duration object
134
- #
135
- # @return [Hash] a map suitable for map_to_cron
136
- #
137
- def duration_to_map(duration)
138
- if duration.to_millis_part.zero? && duration.to_nanos_part.zero? && duration.to_days.zero?
139
- %i[second minute hour].each do |unit|
140
- to_unit_part = duration.public_send("to_#{unit}s_part")
141
- next unless to_unit_part.positive?
142
-
143
- to_unit = duration.public_send("to_#{unit}s")
144
- break unless to_unit_part == to_unit
145
-
146
- return EXPRESSION_MAP[unit].merge(unit => "*/#{to_unit}")
147
- end
148
- end
149
- raise ArgumentError, "Cron Expression not supported for duration: #{duration}"
150
- end
151
-
152
- #
153
- # If an at time is provided, parse that and merge the new fields into the expression.
154
- #
155
- # @param [<Type>] expression_map <description>
156
- # @param [<Type>] at_time <description>
157
- #
158
- # @return [<Type>] <description>
159
- #
160
- def at_condition(expression_map, at_time)
161
- if at_time
162
- tod = at_time.is_a?(TimeOfDay::TimeOfDay) ? at_time : TimeOfDay::TimeOfDay.parse(at_time)
163
- expression_map = expression_map.merge(hour: tod.hour, minute: tod.minute, second: tod.second)
164
- end
165
- expression_map
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
282
- end
283
- end
284
- end
285
- end
286
-
287
- # Add the cron handler to OpenHAB
288
- OpenHAB::DSL::Rules::Triggers::Cron.add_script_cron_handler