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.
@@ -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