openhab-scripting 4.25.0 → 4.26.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9311e047c09ea5409e82e4650a2ef22d26513e10a566445370772e568552e0bd
4
- data.tar.gz: c21b7970c72bf749d6403b212b8e84ab255b1dd07ef3d695c7881e5205edd72a
3
+ metadata.gz: 6e4ca97d24c3811cfeba0faba93e2cdafb9a55f1ed7001cac8789baaf6a7f92c
4
+ data.tar.gz: 5eaeee1232c3e4252ae6396513e2a654727af1fd7075cb6ef9386c4b5e7b4c9a
5
5
  SHA512:
6
- metadata.gz: 0f62960bbd5fc2e51064bc63c4a3cc7e2e9de322233a1f489311ca20c3df51381c04449a4af0dff455ceb998f4e43ab4ac2668101aa7838c3445e0c4093f6074
7
- data.tar.gz: df255a6f1e8a5b573d6b37b0ec6637cd7ccdea4e6abdd937f19b0f8f484713406133cb86fb2c080bdb132717a3efa313c626c4b4cd89ea62baf4bca31b26f58b
6
+ metadata.gz: 0ee0e18e0e4bb8818d405998d2209f24b8b03651195a18fa76e97e417a0696b178cf3dcb431f7c42b3895dc15c29f3fb24d77bc3580ef35e6d37131725cc4ae8
7
+ data.tar.gz: 17afc1eed167b1d0dca764c2962727b770eeab95d53413fc85e54694bace8866260445d73a58da817ff65a1388c81999cc42fc05a25d22d0cd72028312a4dd63
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'openhab/log/logger'
4
+ require 'openhab/core/services'
4
5
 
5
6
  module OpenHAB
6
7
  #
@@ -19,12 +20,10 @@ module OpenHAB
19
20
  #
20
21
  def self.wait_till_openhab_ready
21
22
  logger.trace('Checking readyness of OpenHAB')
22
- # rubocop: disable Style/GlobalVars
23
- until $scriptExtension.get('automationManager')
23
+ until OpenHAB::Core.automation_manager
24
24
  logger.trace("Automation manager not loaded, checking again in #{CHECK_DELAY} seconds.")
25
25
  sleep CHECK_DELAY
26
26
  end
27
- # rubocop: enable Style/GlobalVars
28
27
  logger.trace 'Automation manager instantiated, OpenHAB ready for rule processing.'
29
28
  end
30
29
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ #
5
+ # Core support for OpenHAB JRuby Library
6
+ #
7
+ module Core
8
+ #
9
+ # Access OpenHAB services
10
+ #
11
+
12
+ # Get the OpenHAB automation manager
13
+ # @return [AutomationManager] OpenHAB Automation manager
14
+ # rubocop:disable Style/GlobalVars
15
+ def self.automation_manager
16
+ $scriptExtension.get('automationManager')
17
+ end
18
+
19
+ # Get the OpenHAB rule registry
20
+ # @return [Registory] OpenHAB rule registry
21
+ def self.rule_registry
22
+ $scriptExtension.get('ruleRegistry')
23
+ end
24
+ # rubocop:enable Style/GlobalVars
25
+ end
26
+ end
@@ -11,17 +11,18 @@ require 'openhab/dsl/monkey_patch/events/events'
11
11
  require 'openhab/dsl/monkey_patch/actions/actions'
12
12
  require 'openhab/dsl/rules/rule'
13
13
  require 'openhab/dsl/rules/terse'
14
- require 'openhab/dsl/actions'
15
- require 'openhab/dsl/channel'
16
- require 'openhab/dsl/timers'
17
- require 'openhab/dsl/group'
18
- require 'openhab/dsl/things'
19
- require 'openhab/dsl/between'
20
- require 'openhab/dsl/gems'
21
- require 'openhab/dsl/persistence'
22
- require 'openhab/dsl/uid'
23
- require 'openhab/dsl/units'
24
- require 'openhab/dsl/states'
14
+ require_relative 'actions'
15
+ require_relative 'channel'
16
+ require_relative 'timers'
17
+ require_relative 'group'
18
+ require_relative 'things'
19
+ require_relative 'between'
20
+ require_relative 'gems'
21
+ require_relative 'persistence'
22
+ require_relative 'uid'
23
+ require_relative 'units'
24
+ require_relative 'states'
25
+ require_relative 'openhab'
25
26
 
26
27
  module OpenHAB
27
28
  #
@@ -34,6 +35,7 @@ module OpenHAB
34
35
  def self.extended(base)
35
36
  base.send :include, OpenHAB::DSL::Actions
36
37
  base.send :include, OpenHAB::DSL::Between
38
+ base.send :include, OpenHAB::DSL::Core
37
39
  base.send :include, OpenHAB::DSL::Groups
38
40
  base.send :include, OpenHAB::DSL::Items
39
41
  base.send :include, OpenHAB::DSL::Persistence
@@ -3,6 +3,7 @@
3
3
  require 'singleton'
4
4
 
5
5
  require 'openhab/dsl/lazy_array'
6
+ require 'openhab/core/entity_lookup'
6
7
 
7
8
  module OpenHAB
8
9
  module DSL
@@ -24,7 +25,7 @@ module OpenHAB
24
25
  # @return [Set] of OpenHAB Groups
25
26
  #
26
27
  def [](name)
27
- group = Core::EntityLookup.lookup_item(name)
28
+ group = OpenHAB::Core::EntityLookup.lookup_item(name)
28
29
  group.is_a?(Items::GroupItem) ? group : nil
29
30
  end
30
31
  alias include? []
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+
5
+ module OpenHAB
6
+ module DSL
7
+ #
8
+ # Provides access to OpenHAB attributes
9
+ #
10
+ module Core
11
+ include OpenHAB::Log
12
+
13
+ #
14
+ # Return the OpenHAB conf directory as a ruby pathname
15
+ #
16
+ # @return [Pathname] OpenHAB conf path
17
+ #
18
+ def __conf__
19
+ Pathname.new(ENV['OPENHAB_CONF'])
20
+ end
21
+ end
22
+ end
23
+ end
@@ -36,7 +36,8 @@ module OpenHAB
36
36
  # @param [Object] only_if Item or Proc to use as guard
37
37
  # @param [Object] not_if Item or Proc to use as guard
38
38
  #
39
- def initialize(only_if: nil, not_if: nil)
39
+ def initialize(run_context:, only_if: nil, not_if: nil)
40
+ @run_context = run_context
40
41
  @only_if = only_if
41
42
  @not_if = not_if
42
43
  end
@@ -106,27 +107,27 @@ module OpenHAB
106
107
  #
107
108
  # Check not_if guard
108
109
  #
109
- # @param [OpenHAB Event] event event to check if meets guard
110
+ # @param [OpenHAB Event] event to check if meets guard
110
111
  # @param [Array<Item>] items to check if satisfy criteria
111
112
  # @param [Array] procs to check if satisfy criteria
112
113
  #
113
114
  # @return [Boolean] True if criteria are satisfied, false otherwise
114
115
  #
115
116
  def process_not_if(event, items, procs)
116
- items.flatten.none?(&:truthy?) && procs.none? { |proc| proc.call(event) }
117
+ items.flatten.none?(&:truthy?) && procs.none? { |proc| @run_context.instance_exec(event, &proc) }
117
118
  end
118
119
 
119
120
  #
120
121
  # Check only_if guard
121
122
  #
122
- # @param [OpenHAB Event] event event to check if meets guard
123
+ # @param [OpenHAB Event] event to check if meets guard
123
124
  # @param [Array<Item>] items to check if satisfy criteria
124
125
  # @param [Array] procs to check if satisfy criteria
125
126
  #
126
127
  # @return [Boolean] True if criteria are satisfied, false otherwise
127
128
  #
128
129
  def process_only_if(event, items, procs)
129
- items.flatten.all?(&:truthy?) && procs.all? { |proc| proc.call(event) }
130
+ items.flatten.all?(&:truthy?) && procs.all? { |proc| @run_context.instance_exec(event, &proc) }
130
131
  end
131
132
  end
132
133
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'openhab/core/thread_local'
4
+ require 'openhab/core/services'
4
5
  require 'openhab/log/logger'
5
6
  require_relative 'rule_config'
6
7
  require_relative 'automation_rule'
@@ -21,14 +22,11 @@ module OpenHAB
21
22
 
22
23
  @script_rules = []
23
24
 
24
- # rubocop: disable Style/GlobalVars
25
- @automation_manager = $scriptExtension.get('automationManager')
26
- @registry = $scriptExtension.get('ruleRegistry')
27
- # rubocop: enable Style/GlobalVars
28
-
25
+ @automation_manager = OpenHAB::Core.automation_manager
26
+ @registry = OpenHAB::Core.rule_registry
29
27
  class << self
30
28
  attr_reader :script_rules, :automation_manager, :registry
31
- end
29
+ end
32
30
 
33
31
  #
34
32
  # Create a new rule
@@ -37,13 +35,13 @@ module OpenHAB
37
35
  # @yield [] Block executed in context of a RuleConfig
38
36
  #
39
37
  #
40
- # rubocop: disable Metrics/MethodLength
38
+ # rubocop: disable Metrics
41
39
  def rule(rule_name, &block)
42
40
  thread_local(RULE_NAME: rule_name) do
43
41
  @rule_name = rule_name
44
42
  config = RuleConfig.new(rule_name, block.binding)
45
43
  config.instance_exec(config, &block)
46
- config.guard = Guard::Guard.new(only_if: config.only_if, not_if: config.not_if)
44
+ config.guard = Guard::Guard.new(run_context: config.caller, only_if: config.only_if, not_if: config.not_if)
47
45
  logger.trace { config.inspect }
48
46
  process_rule_config(config)
49
47
  nil # Must return something other than the rule object. See https://github.com/boc-tothefuture/openhab-jruby/issues/438
@@ -52,7 +50,7 @@ module OpenHAB
52
50
  puts "#{e.class}: #{e.message}"
53
51
  re_raise_with_backtrace(e)
54
52
  end
55
- # rubocop: enable Metrics/MethodLength
53
+ # rubocop: enable Metrics
56
54
 
57
55
  #
58
56
  # Cleanup rules in this script file
@@ -2,14 +2,15 @@
2
2
 
3
3
  require 'java'
4
4
  require 'pp'
5
- require 'openhab/dsl/rules/property'
6
- require 'openhab/dsl/rules/triggers/cron'
7
- require 'openhab/dsl/rules/triggers/changed'
8
- require 'openhab/dsl/rules/triggers/channel'
9
- require 'openhab/dsl/rules/triggers/command'
10
- require 'openhab/dsl/rules/triggers/updated'
11
- require 'openhab/dsl/rules/triggers/generic'
12
- require 'openhab/dsl/rules/guard'
5
+ require_relative 'property'
6
+ require_relative 'triggers/cron'
7
+ require_relative 'triggers/changed'
8
+ require_relative 'triggers/channel'
9
+ require_relative 'triggers/command'
10
+ require_relative 'triggers/updated'
11
+ require_relative 'triggers/generic'
12
+ require_relative 'triggers/watch'
13
+ require_relative 'guard'
13
14
  require 'openhab/core/entity_lookup'
14
15
  require 'openhab/dsl/between'
15
16
  require 'openhab/dsl/dsl'
@@ -0,0 +1,213 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'java'
4
+ require 'openhab/log/logger'
5
+ require 'openhab/core/services'
6
+
7
+ module OpenHAB
8
+ module DSL
9
+ module Rules
10
+ #
11
+ # Module holds rule triggers
12
+ #
13
+ module Triggers
14
+ #
15
+ # Module for watching directories/files
16
+ #
17
+ module Watch
18
+ include OpenHAB::Log
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
+ #
38
+ # Creates trigger types and trigger type factories for OpenHAB
39
+ #
40
+ private_class_method def self.watch_trigger_type
41
+ TriggerType.new(
42
+ OpenHAB::DSL::Rules::Triggers::Watch::WATCH_TRIGGER_MODULE_ID,
43
+ nil,
44
+ 'A path change event is detected',
45
+ 'Triggers when a path change event is detected',
46
+ nil,
47
+ org.openhab.core.automation.Visibility::VISIBLE,
48
+ nil
49
+ )
50
+ end
51
+
52
+ # Struct for Watch Events
53
+ WatchEvent = Struct.new(:type, :path, :attachment)
54
+
55
+ # Trigger ID for Watch Triggers
56
+ WATCH_TRIGGER_MODULE_ID = 'jsr223.jruby.WatchTrigger'
57
+
58
+ # Extends the OpenHAB watch service to watch directories
59
+ #
60
+ # Must match java method name style
61
+ # rubocop:disable Naming/MethodName
62
+ class Watcher < org.openhab.core.service.AbstractWatchService
63
+ java_import java.nio.file.StandardWatchEventKinds
64
+
65
+ # Hash of event symbols as strings to map to NIO events
66
+ STRING_TO_EVENT = {
67
+ created: StandardWatchEventKinds::ENTRY_CREATE,
68
+ deleted: StandardWatchEventKinds::ENTRY_DELETE,
69
+ modified: StandardWatchEventKinds::ENTRY_MODIFY
70
+ }.transform_keys(&:to_s).freeze
71
+
72
+ # Hash of NIO event kinds to ruby symbols
73
+ EVENT_TO_SYMBOL = STRING_TO_EVENT.invert.transform_values(&:to_sym).freeze
74
+
75
+ # Creates a new Watch Service
76
+ def initialize(path, types, &block)
77
+ super(path)
78
+ @types = types.map { |type| STRING_TO_EVENT[type] }
79
+ @block = block
80
+ end
81
+
82
+ # Invoked by java super class to get type of events to watch for
83
+ # @param [String] _path ignored
84
+ #
85
+ # @return [Array] array of NIO event kinds
86
+ def getWatchEventKinds(_path)
87
+ @types
88
+ end
89
+
90
+ # Invoked by java super class to check if sub directories should be watched
91
+ # @return [false] false
92
+ def watchSubDirectories
93
+ false
94
+ end
95
+
96
+ # Invoked by java super class when an watch event occurs
97
+ # @param [String] _event ignored
98
+ # @param [StandardWatchEventKind] kind NIO watch event kind
99
+ # @param [java.nio.Path] Path that had an event
100
+ def processWatchEvent(_event, kind, path)
101
+ @block.call(WatchEvent.new(EVENT_TO_SYMBOL[kind], Pathname.new(path.to_s)))
102
+ end
103
+ end
104
+ # rubocop:enable Naming/MethodName
105
+
106
+ # Implements the OpenHAB TriggerHandler interface to process Watch Triggers
107
+ class WatchTriggerHandler
108
+ include OpenHAB::Log
109
+ include org.openhab.core.automation.handler.TriggerHandler
110
+
111
+ # Creates a new WatchTriggerHandler
112
+ # @param [Trigger] OpenHAB trigger associated with handler
113
+ #
114
+ def initialize(trigger)
115
+ @trigger = trigger
116
+ config = trigger.configuration.properties.to_hash.transform_keys(&:to_sym)
117
+ @path = config[:path]
118
+ @watcher = Watcher.new(@path, config[:types], &watch_event_handler(config[:glob]))
119
+ @watcher.activate
120
+ logger.trace("Created watcher for #{@path}")
121
+ end
122
+
123
+ # Create a lambda to use to invoke rule engine when file watch notification happens
124
+ # @param [String] glob to match for notification events
125
+ #
126
+ # @return [Lambda] lambda to execute on notification events
127
+ #
128
+ def watch_event_handler(glob)
129
+ lambda { |watch_event|
130
+ logger.trace("Received event(#{watch_event})")
131
+ if watch_event.path.fnmatch?(glob)
132
+ @rule_engine_callback&.triggered(@trigger, { 'event' => watch_event })
133
+ else
134
+ logger.trace("Event #{watch_event} did not match glob(#{glob})")
135
+ end
136
+ }
137
+ end
138
+
139
+ # Called by OpenHAB to set the rule engine to invoke when triggered
140
+ # Must match java method name style
141
+ # rubocop:disable Naming/MethodName
142
+ def setCallback(callback)
143
+ @rule_engine_callback = callback
144
+ end
145
+ # rubocop:enable Naming/MethodName
146
+
147
+ #
148
+ # Dispose of handler which deactivates watcher
149
+ #
150
+ def dispose
151
+ logger.trace("Deactivating watcher for #{@path}")
152
+ @watcher&.deactivate
153
+ end
154
+ end
155
+
156
+ # Implements the ScriptedTriggerHandlerFactory interface to create a new Trigger Handler
157
+ class WatchTriggerHandlerFactory
158
+ include org.openhab.core.automation.module.script.rulesupport.shared.factories.ScriptedTriggerHandlerFactory
159
+
160
+ # Invoked by the OpenHAB core to get a trigger handler for the supllied trigger
161
+ # @param [Trigger] OpenHAB trigger
162
+ #
163
+ # @return [WatchTriggerHandler] trigger handler for supplied trigger
164
+ def get(trigger)
165
+ WatchTriggerHandler.new(trigger)
166
+ end
167
+ end
168
+ end
169
+
170
+ #
171
+ # Create a trigger to watch a path
172
+ #
173
+ # @param [String] path to watch
174
+ #
175
+ # @return [Trigger] Trigger object
176
+ #
177
+ def watch(path, glob: '*', for: %i[created deleted modified], attach: nil)
178
+ glob, path = glob_for_path(Pathname.new(path), glob)
179
+ types = [binding.local_variable_get(:for)].flatten
180
+ conf = { path: path.to_s, types: types.map(&:to_s), glob: glob.to_s }
181
+
182
+ logger.trace("Creating a watch trigger for path(#{path}) with glob(#{glob}) for types(#{types})")
183
+ append_trigger(OpenHAB::DSL::Rules::Triggers::Watch::WATCH_TRIGGER_MODULE_ID,
184
+ conf,
185
+ attach: attach)
186
+ end
187
+
188
+ private
189
+
190
+ #
191
+ # Automatically creates globs for supplied paths if necessary
192
+ # @param [Pathname] path to check
193
+ # @param [String] specified glob
194
+ #
195
+ # @return [Pathname,String] Pathname to watch and glob to match
196
+ def glob_for_path(path, glob)
197
+ # Checks if the supplied pathname last element contains a glob char
198
+ if OpenHAB::DSL::Rules::Triggers::Watch::GLOB_CHARS.any? { |char| path.basename.to_s.include? char }
199
+ # Splits the supplied pathname into a glob string and parent path
200
+ [path.basename.to_s, path.parent]
201
+ elsif path.file? || !path.exist?
202
+ # glob string matching end of Pathname and parent path
203
+ ["*/#{path.basename}", path.parent]
204
+ else
205
+ [glob, path]
206
+ end
207
+ end
208
+ end
209
+ end
210
+ end
211
+ end
212
+ # Add the watch handler to OpenHAB
213
+ OpenHAB::DSL::Rules::Triggers::Watch.add_watch_handler
@@ -2,11 +2,13 @@
2
2
 
3
3
  require 'forwardable'
4
4
  require 'time'
5
+ require 'java'
5
6
 
6
7
  module OpenHAB
7
8
  module DSL
8
9
  module Types
9
10
  java_import org.openhab.core.library.types.DateTimeType
11
+ java_import java.time.ZonedDateTime
10
12
 
11
13
  # global alias
12
14
  ::DateTimeType = DateTimeType
@@ -5,5 +5,5 @@
5
5
  #
6
6
  module OpenHAB
7
7
  # @return [String] Version of OpenHAB helper libraries
8
- VERSION = '4.25.0'
8
+ VERSION = '4.26.0'
9
9
  end
data/lib/openhab.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'java'
3
4
  require 'openhab/core/load_path'
4
5
  require 'openhab/core/entity_lookup'
5
6
  require 'openhab/core/script_handling'
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.25.0
4
+ version: 4.26.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: 2021-12-21 00:00:00.000000000 Z
11
+ date: 2021-12-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -51,6 +51,7 @@ files:
51
51
  - lib/openhab/core/openhab_setup.rb
52
52
  - lib/openhab/core/osgi.rb
53
53
  - lib/openhab/core/script_handling.rb
54
+ - lib/openhab/core/services.rb
54
55
  - lib/openhab/core/thread_local.rb
55
56
  - lib/openhab/dsl/actions.rb
56
57
  - lib/openhab/dsl/between.rb
@@ -92,6 +93,7 @@ files:
92
93
  - lib/openhab/dsl/monkey_patch/ruby/number.rb
93
94
  - lib/openhab/dsl/monkey_patch/ruby/ruby.rb
94
95
  - lib/openhab/dsl/monkey_patch/ruby/string.rb
96
+ - lib/openhab/dsl/openhab.rb
95
97
  - lib/openhab/dsl/persistence.rb
96
98
  - lib/openhab/dsl/rules/automation_rule.rb
97
99
  - lib/openhab/dsl/rules/cron_trigger_rule.rb
@@ -108,6 +110,7 @@ files:
108
110
  - lib/openhab/dsl/rules/triggers/generic.rb
109
111
  - lib/openhab/dsl/rules/triggers/trigger.rb
110
112
  - lib/openhab/dsl/rules/triggers/updated.rb
113
+ - lib/openhab/dsl/rules/triggers/watch.rb
111
114
  - lib/openhab/dsl/states.rb
112
115
  - lib/openhab/dsl/things.rb
113
116
  - lib/openhab/dsl/time/month_day.rb