openhab-jrubyscripting 5.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. checksums.yaml +7 -0
  2. data/lib/openhab/core/actions.rb +163 -0
  3. data/lib/openhab/core/entity_lookup.rb +144 -0
  4. data/lib/openhab/core/events/abstract_event.rb +17 -0
  5. data/lib/openhab/core/events/item_channel_link.rb +36 -0
  6. data/lib/openhab/core/events/item_command_event.rb +78 -0
  7. data/lib/openhab/core/events/item_event.rb +22 -0
  8. data/lib/openhab/core/events/item_state_changed_event.rb +52 -0
  9. data/lib/openhab/core/events/item_state_event.rb +51 -0
  10. data/lib/openhab/core/events/thing.rb +29 -0
  11. data/lib/openhab/core/events/thing_status_info_event.rb +53 -0
  12. data/lib/openhab/core/events.rb +10 -0
  13. data/lib/openhab/core/items/accepted_data_types.rb +29 -0
  14. data/lib/openhab/core/items/color_item.rb +52 -0
  15. data/lib/openhab/core/items/contact_item.rb +52 -0
  16. data/lib/openhab/core/items/date_time_item.rb +58 -0
  17. data/lib/openhab/core/items/dimmer_item.rb +148 -0
  18. data/lib/openhab/core/items/generic_item.rb +344 -0
  19. data/lib/openhab/core/items/group_item.rb +174 -0
  20. data/lib/openhab/core/items/image_item.rb +109 -0
  21. data/lib/openhab/core/items/location_item.rb +34 -0
  22. data/lib/openhab/core/items/metadata/hash.rb +390 -0
  23. data/lib/openhab/core/items/metadata/namespace_hash.rb +469 -0
  24. data/lib/openhab/core/items/metadata.rb +11 -0
  25. data/lib/openhab/core/items/number_item.rb +62 -0
  26. data/lib/openhab/core/items/numeric_item.rb +22 -0
  27. data/lib/openhab/core/items/persistence.rb +327 -0
  28. data/lib/openhab/core/items/player_item.rb +66 -0
  29. data/lib/openhab/core/items/proxy.rb +59 -0
  30. data/lib/openhab/core/items/registry.rb +66 -0
  31. data/lib/openhab/core/items/rollershutter_item.rb +68 -0
  32. data/lib/openhab/core/items/semantics/enumerable.rb +152 -0
  33. data/lib/openhab/core/items/semantics.rb +476 -0
  34. data/lib/openhab/core/items/state_storage.rb +53 -0
  35. data/lib/openhab/core/items/string_item.rb +28 -0
  36. data/lib/openhab/core/items/switch_item.rb +78 -0
  37. data/lib/openhab/core/items.rb +114 -0
  38. data/lib/openhab/core/lazy_array.rb +52 -0
  39. data/lib/openhab/core/profile_factory.rb +118 -0
  40. data/lib/openhab/core/script_handling.rb +55 -0
  41. data/lib/openhab/core/things/channel.rb +48 -0
  42. data/lib/openhab/core/things/channel_uid.rb +51 -0
  43. data/lib/openhab/core/things/item_channel_link.rb +33 -0
  44. data/lib/openhab/core/things/profile_callback.rb +52 -0
  45. data/lib/openhab/core/things/proxy.rb +69 -0
  46. data/lib/openhab/core/things/registry.rb +46 -0
  47. data/lib/openhab/core/things/thing.rb +194 -0
  48. data/lib/openhab/core/things.rb +22 -0
  49. data/lib/openhab/core/timer.rb +128 -0
  50. data/lib/openhab/core/types/comparable_type.rb +23 -0
  51. data/lib/openhab/core/types/date_time_type.rb +259 -0
  52. data/lib/openhab/core/types/decimal_type.rb +192 -0
  53. data/lib/openhab/core/types/hsb_type.rb +183 -0
  54. data/lib/openhab/core/types/increase_decrease_type.rb +34 -0
  55. data/lib/openhab/core/types/next_previous_type.rb +34 -0
  56. data/lib/openhab/core/types/numeric_type.rb +52 -0
  57. data/lib/openhab/core/types/on_off_type.rb +46 -0
  58. data/lib/openhab/core/types/open_closed_type.rb +41 -0
  59. data/lib/openhab/core/types/percent_type.rb +95 -0
  60. data/lib/openhab/core/types/play_pause_type.rb +38 -0
  61. data/lib/openhab/core/types/point_type.rb +117 -0
  62. data/lib/openhab/core/types/quantity_type.rb +327 -0
  63. data/lib/openhab/core/types/raw_type.rb +26 -0
  64. data/lib/openhab/core/types/refresh_type.rb +27 -0
  65. data/lib/openhab/core/types/rewind_fastforward_type.rb +38 -0
  66. data/lib/openhab/core/types/stop_move_type.rb +34 -0
  67. data/lib/openhab/core/types/string_type.rb +76 -0
  68. data/lib/openhab/core/types/type.rb +117 -0
  69. data/lib/openhab/core/types/un_def_type.rb +38 -0
  70. data/lib/openhab/core/types/up_down_type.rb +50 -0
  71. data/lib/openhab/core/types.rb +69 -0
  72. data/lib/openhab/core/uid.rb +36 -0
  73. data/lib/openhab/core.rb +85 -0
  74. data/lib/openhab/core_ext/java/duration.rb +115 -0
  75. data/lib/openhab/core_ext/java/local_date.rb +93 -0
  76. data/lib/openhab/core_ext/java/local_time.rb +106 -0
  77. data/lib/openhab/core_ext/java/month.rb +59 -0
  78. data/lib/openhab/core_ext/java/month_day.rb +105 -0
  79. data/lib/openhab/core_ext/java/period.rb +103 -0
  80. data/lib/openhab/core_ext/java/temporal_amount.rb +34 -0
  81. data/lib/openhab/core_ext/java/time.rb +58 -0
  82. data/lib/openhab/core_ext/java/unit.rb +15 -0
  83. data/lib/openhab/core_ext/java/zoned_date_time.rb +116 -0
  84. data/lib/openhab/core_ext/ruby/array.rb +21 -0
  85. data/lib/openhab/core_ext/ruby/class.rb +15 -0
  86. data/lib/openhab/core_ext/ruby/date.rb +89 -0
  87. data/lib/openhab/core_ext/ruby/numeric.rb +190 -0
  88. data/lib/openhab/core_ext/ruby/range.rb +70 -0
  89. data/lib/openhab/core_ext/ruby/time.rb +104 -0
  90. data/lib/openhab/core_ext.rb +18 -0
  91. data/lib/openhab/dsl/events/watch_event.rb +18 -0
  92. data/lib/openhab/dsl/events.rb +9 -0
  93. data/lib/openhab/dsl/gems.rb +3 -0
  94. data/lib/openhab/dsl/items/builder.rb +618 -0
  95. data/lib/openhab/dsl/items/ensure.rb +93 -0
  96. data/lib/openhab/dsl/items/timed_command.rb +236 -0
  97. data/lib/openhab/dsl/rules/automation_rule.rb +308 -0
  98. data/lib/openhab/dsl/rules/builder.rb +1373 -0
  99. data/lib/openhab/dsl/rules/guard.rb +115 -0
  100. data/lib/openhab/dsl/rules/name_inference.rb +160 -0
  101. data/lib/openhab/dsl/rules/property.rb +76 -0
  102. data/lib/openhab/dsl/rules/rule_triggers.rb +96 -0
  103. data/lib/openhab/dsl/rules/terse.rb +63 -0
  104. data/lib/openhab/dsl/rules/triggers/changed.rb +169 -0
  105. data/lib/openhab/dsl/rules/triggers/channel.rb +57 -0
  106. data/lib/openhab/dsl/rules/triggers/command.rb +107 -0
  107. data/lib/openhab/dsl/rules/triggers/conditions/duration.rb +161 -0
  108. data/lib/openhab/dsl/rules/triggers/conditions/proc.rb +164 -0
  109. data/lib/openhab/dsl/rules/triggers/cron/cron.rb +195 -0
  110. data/lib/openhab/dsl/rules/triggers/cron/cron_handler.rb +127 -0
  111. data/lib/openhab/dsl/rules/triggers/trigger.rb +56 -0
  112. data/lib/openhab/dsl/rules/triggers/updated.rb +130 -0
  113. data/lib/openhab/dsl/rules/triggers/watch/watch.rb +55 -0
  114. data/lib/openhab/dsl/rules/triggers/watch/watch_handler.rb +155 -0
  115. data/lib/openhab/dsl/rules/triggers.rb +12 -0
  116. data/lib/openhab/dsl/rules.rb +29 -0
  117. data/lib/openhab/dsl/script_handling.rb +55 -0
  118. data/lib/openhab/dsl/things/builder.rb +263 -0
  119. data/lib/openhab/dsl/thread_local.rb +48 -0
  120. data/lib/openhab/dsl/timer_manager.rb +191 -0
  121. data/lib/openhab/dsl/version.rb +9 -0
  122. data/lib/openhab/dsl.rb +686 -0
  123. data/lib/openhab/log.rb +348 -0
  124. data/lib/openhab/osgi.rb +70 -0
  125. data/lib/openhab/rspec/configuration.rb +56 -0
  126. data/lib/openhab/rspec/example_group.rb +90 -0
  127. data/lib/openhab/rspec/helpers.rb +439 -0
  128. data/lib/openhab/rspec/hooks.rb +93 -0
  129. data/lib/openhab/rspec/jruby.rb +46 -0
  130. data/lib/openhab/rspec/karaf.rb +811 -0
  131. data/lib/openhab/rspec/mocks/bundle_install_support.rb +25 -0
  132. data/lib/openhab/rspec/mocks/bundle_resolver.rb +30 -0
  133. data/lib/openhab/rspec/mocks/event_admin.rb +146 -0
  134. data/lib/openhab/rspec/mocks/metadata_provider.rb +75 -0
  135. data/lib/openhab/rspec/mocks/persistence_service.rb +140 -0
  136. data/lib/openhab/rspec/mocks/safe_caller.rb +40 -0
  137. data/lib/openhab/rspec/mocks/synchronous_executor.rb +56 -0
  138. data/lib/openhab/rspec/mocks/thing_handler.rb +76 -0
  139. data/lib/openhab/rspec/mocks/timer.rb +95 -0
  140. data/lib/openhab/rspec/openhab/core/actions.rb +26 -0
  141. data/lib/openhab/rspec/openhab/core/items/proxy.rb +27 -0
  142. data/lib/openhab/rspec/openhab/core/things/proxy.rb +27 -0
  143. data/lib/openhab/rspec/shell.rb +31 -0
  144. data/lib/openhab/rspec/suspend_rules.rb +60 -0
  145. data/lib/openhab/rspec.rb +17 -0
  146. data/lib/openhab/yard/cli/stats.rb +23 -0
  147. data/lib/openhab/yard/code_objects/group_object.rb +17 -0
  148. data/lib/openhab/yard/code_objects/java/base.rb +31 -0
  149. data/lib/openhab/yard/code_objects/java/class_object.rb +11 -0
  150. data/lib/openhab/yard/code_objects/java/field_object.rb +15 -0
  151. data/lib/openhab/yard/code_objects/java/interface_object.rb +15 -0
  152. data/lib/openhab/yard/code_objects/java/package_object.rb +11 -0
  153. data/lib/openhab/yard/code_objects/java/proxy.rb +23 -0
  154. data/lib/openhab/yard/handlers/jruby/base.rb +49 -0
  155. data/lib/openhab/yard/handlers/jruby/class_handler.rb +18 -0
  156. data/lib/openhab/yard/handlers/jruby/constant_handler.rb +18 -0
  157. data/lib/openhab/yard/handlers/jruby/java_import_handler.rb +27 -0
  158. data/lib/openhab/yard/handlers/jruby/mixin_handler.rb +23 -0
  159. data/lib/openhab/yard/html_helper.rb +44 -0
  160. data/lib/openhab/yard/tags/constant_directive.rb +20 -0
  161. data/lib/openhab/yard/tags/group_directive.rb +24 -0
  162. data/lib/openhab/yard/tags/library.rb +3 -0
  163. data/lib/openhab/yard.rb +32 -0
  164. metadata +504 -0
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "cron"
4
+
5
+ module OpenHAB
6
+ module DSL
7
+ module Rules
8
+ module Triggers
9
+ # @!visibility private
10
+ #
11
+ # Cron trigger handler that provides trigger ID
12
+ #
13
+ module CronHandler
14
+ # Cron Trigger Handler that provides trigger IDs
15
+ # Unfortunatly because the CronTriggerHandler in OpenHAB core is marked internal
16
+ # the entire thing must be recreated here
17
+ class CronTriggerHandler < org.openhab.core.automation.handler.BaseTriggerModuleHandler
18
+ include org.openhab.core.scheduler.SchedulerRunnable
19
+ include org.openhab.core.automation.handler.TimeBasedTriggerHandler
20
+
21
+ # Provides access to protected fields
22
+ field_accessor :callback
23
+
24
+ # Creates a new CronTriggerHandler
25
+ # @param [Trigger] trigger OpenHAB trigger associated with handler
26
+ #
27
+ def initialize(trigger)
28
+ @trigger = trigger
29
+ @scheduler = OSGi.service("org.openhab.core.scheduler.CronScheduler")
30
+ @schedule = nil
31
+ @expression = trigger.configuration.get("cronExpression")
32
+ super(trigger)
33
+ end
34
+
35
+ #
36
+ # Set the callback to execute when cron trigger fires
37
+ # @param [Object] callback to run
38
+ #
39
+ def setCallback(callback) # rubocop:disable Naming/MethodName
40
+ synchronized do
41
+ super(callback)
42
+ @schedule = @scheduler.schedule(self, @expression)
43
+ logger.trace("Scheduled cron job '#{@expression}' for trigger '#{@trigger.id}'.")
44
+ end
45
+ end
46
+
47
+ #
48
+ # Get the temporal adjuster
49
+ # @return [CronAdjuster]
50
+ #
51
+ def getTemporalAdjuster # rubocop:disable Naming/MethodName
52
+ org.openhab.core.scheduler.CronAdjuster.new(expression)
53
+ end
54
+
55
+ #
56
+ # Execute the callback
57
+ #
58
+ def run
59
+ callback&.triggered(@trigger, { "module" => @trigger.id })
60
+ end
61
+
62
+ #
63
+ # Displose of the handler
64
+ # cancel the cron scheduled task
65
+ #
66
+ def dispose
67
+ synchronized do
68
+ super
69
+ return unless @schedule
70
+
71
+ @schedule.cancel(true)
72
+ @schedule = nil
73
+ end
74
+ logger.trace("cancelled job for trigger '#{@trigger.id}'.")
75
+ end
76
+ end
77
+
78
+ # Implements the ScriptedTriggerHandlerFactory interface to create a new Cron Trigger Handler
79
+ class CronTriggerHandlerFactory
80
+ include org.openhab.core.automation.module.script.rulesupport.shared.factories.ScriptedTriggerHandlerFactory
81
+
82
+ # Invoked by the OpenHAB core to get a trigger handler for the supllied trigger
83
+ # @param [Trigger] trigger OpenHAB trigger
84
+ #
85
+ # @return [WatchTriggerHandler] trigger handler for supplied trigger
86
+ def get(trigger)
87
+ CronTriggerHandler.new(trigger)
88
+ end
89
+ end
90
+
91
+ class << self
92
+ private
93
+
94
+ #
95
+ # Creates trigger types and trigger type factories for OpenHAB
96
+ #
97
+ def add_script_cron_handler
98
+ Core.automation_manager.add_trigger_handler(
99
+ Cron::CRON_TRIGGER_MODULE_ID,
100
+ CronTriggerHandlerFactory.new
101
+ )
102
+
103
+ Core.automation_manager.add_trigger_type(cron_trigger_type)
104
+ logger.trace("Added script cron trigger handler")
105
+ end
106
+
107
+ #
108
+ # Creates trigger types and trigger type factories for OpenHAB
109
+ #
110
+ def cron_trigger_type
111
+ org.openhab.core.automation.type.TriggerType.new(
112
+ Cron::CRON_TRIGGER_MODULE_ID,
113
+ nil,
114
+ "A specific instant occurs",
115
+ "Triggers when the specified instant occurs",
116
+ nil,
117
+ org.openhab.core.automation.Visibility::VISIBLE,
118
+ nil
119
+ )
120
+ end
121
+ end
122
+ add_script_cron_handler
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "forwardable"
4
+
5
+ module OpenHAB
6
+ module DSL
7
+ module Rules
8
+ module Triggers
9
+ # @!visibility private
10
+ #
11
+ # Class for creating and managing triggers
12
+ #
13
+ class Trigger
14
+ extend Forwardable
15
+
16
+ delegate append_trigger: :@rule_triggers
17
+
18
+ #
19
+ # Creates a new Trigger
20
+ # @param [RuleTrigger] rule_triggers rule trigger information
21
+ def initialize(rule_triggers:)
22
+ @rule_triggers = rule_triggers
23
+ end
24
+
25
+ #
26
+ # Create a trigger for a thing
27
+ #
28
+ # @param [Thing] thing to create trigger for
29
+ # @param [Trigger] type trigger to map with thing
30
+ # @param [State] to for thing
31
+ # @param [State] from state of thing
32
+ #
33
+ # @return [Array] Trigger and config for thing
34
+ #
35
+ def trigger_for_thing(thing:, type:, to: nil, from: nil)
36
+ config = { "thingUID" => thing.uid.to_s }
37
+ config["status"] = trigger_state_from_symbol(to).to_s if to
38
+ config["previousStatus"] = trigger_state_from_symbol(from).to_s if from
39
+ [type, config]
40
+ end
41
+
42
+ #
43
+ # converts object to upcase string if its a symbol
44
+ #
45
+ # @param [sym] sym potential symbol to convert
46
+ #
47
+ # @return [String] Upcased symbol as string
48
+ #
49
+ def trigger_state_from_symbol(sym)
50
+ sym.to_s.upcase if sym.is_a?(Symbol) || sym
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "trigger"
4
+
5
+ module OpenHAB
6
+ module DSL
7
+ module Rules
8
+ module Triggers
9
+ # @!visibility private
10
+ #
11
+ # Creates updated triggers
12
+ #
13
+ class Updated < Trigger
14
+ #
15
+ # Create the trigger
16
+ #
17
+ # @param [Object] item item to create trigger for
18
+ # @param [Item State] to state to restrict trigger to
19
+ # @param [Object] attach object to be attached to the trigger
20
+ #
21
+ # @return [Trigger] OpenHAB triggers
22
+ #
23
+ def trigger(item:, to:, attach:)
24
+ case to
25
+ when Range then range_trigger(item: item, to: to, attach: attach)
26
+ when Proc then proc_trigger(item: item, to: to, attach: attach)
27
+ else update_trigger(item: item, to: to, attach: attach)
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ # @return [String] A thing status update trigger
34
+ THING_UPDATE = "core.ThingStatusUpdateTrigger"
35
+
36
+ # @return [String] An item state update trigger
37
+ ITEM_STATE_UPDATE = "core.ItemStateUpdateTrigger"
38
+
39
+ # @return [String] A group state update trigger for items in the group
40
+ GROUP_STATE_UPDATE = "core.GroupStateUpdateTrigger"
41
+
42
+ #
43
+ # Creates a trigger with a range condition on the 'to' field
44
+ # @param [Object] item to create changed trigger on
45
+ # @param [Object] to state restrict trigger to
46
+ # @param [Object] attach object to be attached to the trigger
47
+ # @return [Trigger] OpenHAB trigger
48
+ #
49
+ def range_trigger(item:, to:, attach:)
50
+ to, * = Conditions::Proc.range_procs(to)
51
+ proc_trigger(item: item, to: to, attach: attach)
52
+ end
53
+
54
+ #
55
+ # Creates a trigger with a proc condition on the 'to' field
56
+ # @param [Object] item to create changed trigger on
57
+ # @param [Object] to state restrict trigger to
58
+ # @param [Object] attach object to be attached to the trigger
59
+ # @return [Trigger] OpenHAB trigger
60
+ #
61
+ def proc_trigger(item:, to:, attach:)
62
+ conditions = Conditions::Proc.new(to: to)
63
+ update_trigger(item: item, to: nil, attach: attach, conditions: conditions)
64
+ end
65
+
66
+ #
67
+ # Create a trigger for updates
68
+ #
69
+ # @param [Object] item Type of item [Group,Thing,Item] to create update trigger for
70
+ # @param [State] to state restriction on trigger
71
+ # @param [Object] attach object to be attached to the trigger
72
+ #
73
+ # @return [Trigger] OpenHAB triggers
74
+ #
75
+ def update_trigger(item:, to:, attach: nil, conditions: nil)
76
+ type, config = case item
77
+ when GroupItem::Members then group_update(item: item, to: to)
78
+ when Core::Things::Thing then thing_update(thing: item, to: to)
79
+ else item_update(item: item, to: to)
80
+ end
81
+ append_trigger(type: type, config: config, attach: attach, conditions: conditions)
82
+ end
83
+
84
+ #
85
+ # Create an update trigger for an item
86
+ #
87
+ # @param [Item] item to create trigger for
88
+ # @param [State] to optional state restriction for target
89
+ #
90
+ # @return [Array<Hash,String>] first element is a String specifying trigger type
91
+ # second element is a Hash configuring trigger
92
+ #
93
+ def item_update(item:, to:)
94
+ config = { "itemName" => item.name }
95
+ config["state"] = to.to_s unless to.nil?
96
+ [ITEM_STATE_UPDATE, config]
97
+ end
98
+
99
+ #
100
+ # Create an update trigger for a group
101
+ #
102
+ # @param [Item] item to create trigger for
103
+ # @param [State] to optional state restriction for target
104
+ #
105
+ # @return [Array<Hash,String>] first element is a String specifying trigger type
106
+ # second element is a Hash configuring trigger
107
+ #
108
+ def group_update(item:, to:)
109
+ config = { "groupName" => item.group.name }
110
+ config["state"] = to.to_s unless to.nil?
111
+ [GROUP_STATE_UPDATE, config]
112
+ end
113
+
114
+ #
115
+ # Create an update trigger for a thing
116
+ #
117
+ # @param [Thing] thing to create trigger for
118
+ # @param [State] to optional state restriction for target
119
+ #
120
+ # @return [Array<Hash,String>] first element is a String specifying trigger type
121
+ # second element is a Hash configuring trigger
122
+ #
123
+ def thing_update(thing:, to:)
124
+ trigger_for_thing(thing: thing, type: THING_UPDATE, to: to)
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openhab/dsl/rules/triggers/trigger"
4
+
5
+ module OpenHAB
6
+ module DSL
7
+ module Rules
8
+ module Triggers
9
+ # @!visibility private
10
+ #
11
+ # Creates watch triggers
12
+ #
13
+ class Watch < Trigger
14
+ # Characters in an fnmatch compatible glob
15
+ GLOB_CHARS = ["**", "*", "?", "[", "]", "{", "}"].freeze
16
+ private_constant :GLOB_CHARS
17
+
18
+ #
19
+ # Automatically creates globs for supplied paths if necessary
20
+ #
21
+ # @param [Pathname] path to check
22
+ # @param [String] glob
23
+ #
24
+ # @return [Pathname,String] Pathname to watch and glob to match
25
+ #
26
+ def self.glob_for_path(path, glob)
27
+ # Checks if the supplied pathname last element contains a glob char
28
+ if GLOB_CHARS.any? { |char| path.basename.to_s.include? char }
29
+ # Splits the supplied pathname into a glob string and parent path
30
+ [path.basename.to_s, path.parent]
31
+ elsif path.file? || !path.exist?
32
+ # glob string matching end of Pathname and parent path
33
+ ["*/#{path.basename}", path.parent]
34
+ else
35
+ [glob, path]
36
+ end
37
+ end
38
+
39
+ #
40
+ # Create a watch trigger based on item type
41
+ #
42
+ # @param [Config] config Rule configuration
43
+ # @param [Object] attach object to be attached to the trigger
44
+ #
45
+ #
46
+ def trigger(config:, attach:)
47
+ append_trigger(type: WatchHandler::WATCH_TRIGGER_MODULE_ID,
48
+ config: config,
49
+ attach: attach)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,155 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module DSL
5
+ module Rules
6
+ module Triggers
7
+ # @!visibility private
8
+ #
9
+ # Module for watching directories/files
10
+ #
11
+ module WatchHandler
12
+ #
13
+ # Creates trigger types and trigger type factories for OpenHAB
14
+ #
15
+ private_class_method def self.watch_trigger_type
16
+ org.openhab.core.automation.type.TriggerType.new(
17
+ WATCH_TRIGGER_MODULE_ID,
18
+ nil,
19
+ "A path change event is detected",
20
+ "Triggers when a path change event is detected",
21
+ nil,
22
+ org.openhab.core.automation.Visibility::VISIBLE,
23
+ nil
24
+ )
25
+ end
26
+
27
+ # Trigger ID for Watch Triggers
28
+ WATCH_TRIGGER_MODULE_ID = "jsr223.jruby.WatchTrigger"
29
+
30
+ # Extends the OpenHAB watch service to watch directories
31
+ #
32
+ # Must match java method name style
33
+ # rubocop:disable Naming/MethodName
34
+ class Watcher < org.openhab.core.service.AbstractWatchService
35
+ java_import java.nio.file.StandardWatchEventKinds
36
+
37
+ # Hash of event symbols as strings to map to NIO events
38
+ STRING_TO_EVENT = {
39
+ created: StandardWatchEventKinds::ENTRY_CREATE,
40
+ deleted: StandardWatchEventKinds::ENTRY_DELETE,
41
+ modified: StandardWatchEventKinds::ENTRY_MODIFY
42
+ }.transform_keys(&:to_s).freeze
43
+
44
+ # Hash of NIO event kinds to ruby symbols
45
+ EVENT_TO_SYMBOL = STRING_TO_EVENT.invert.transform_values(&:to_sym).freeze
46
+
47
+ # Creates a new Watch Service
48
+ def initialize(path, types, &block)
49
+ super(path)
50
+ @types = types.map { |type| STRING_TO_EVENT[type] }
51
+ @block = block
52
+ end
53
+
54
+ # Invoked by java super class to get type of events to watch for
55
+ # @param [String] _path ignored
56
+ #
57
+ # @return [Array] array of NIO event kinds
58
+ def getWatchEventKinds(_path)
59
+ @types
60
+ end
61
+
62
+ # Invoked by java super class to check if sub directories should be watched
63
+ # @return [false] false
64
+ def watchSubDirectories
65
+ false
66
+ end
67
+
68
+ # Invoked by java super class when an watch event occurs
69
+ # @param [String] _event ignored
70
+ # @param [StandardWatchEventKind] kind NIO watch event kind
71
+ # @param [java.nio.Path] path that had an event
72
+ def processWatchEvent(_event, kind, path)
73
+ @block.call(Events::WatchEvent.new(EVENT_TO_SYMBOL[kind], Pathname.new(path.to_s)))
74
+ end
75
+ end
76
+ # rubocop:enable Naming/MethodName
77
+
78
+ # Implements the OpenHAB TriggerHandler interface to process Watch Triggers
79
+ class WatchTriggerHandler
80
+ include org.openhab.core.automation.handler.TriggerHandler
81
+
82
+ # Creates a new WatchTriggerHandler
83
+ # @param [Trigger] trigger OpenHAB trigger associated with handler
84
+ #
85
+ def initialize(trigger)
86
+ @trigger = trigger
87
+ config = trigger.configuration.properties.to_hash.transform_keys(&:to_sym)
88
+ @path = config[:path]
89
+ @watcher = Watcher.new(@path, config[:types], &watch_event_handler(config[:glob]))
90
+ @watcher.activate
91
+ logger.trace("Created watcher for #{@path}")
92
+ end
93
+
94
+ # Create a lambda to use to invoke rule engine when file watch notification happens
95
+ # @param [String] glob to match for notification events
96
+ #
97
+ # @return [Lambda] lambda to execute on notification events
98
+ #
99
+ def watch_event_handler(glob)
100
+ lambda { |watch_event|
101
+ logger.trace("Received event(#{watch_event})")
102
+ if watch_event.path.fnmatch?(glob)
103
+ @rule_engine_callback&.triggered(@trigger, { "event" => watch_event })
104
+ else
105
+ logger.trace("Event #{watch_event} did not match glob(#{glob})")
106
+ end
107
+ }
108
+ end
109
+
110
+ # Called by OpenHAB to set the rule engine to invoke when triggered
111
+ # Must match java method name style
112
+ def setCallback(callback) # rubocop:disable Naming/MethodName
113
+ @rule_engine_callback = callback
114
+ end
115
+
116
+ #
117
+ # Dispose of handler which deactivates watcher
118
+ #
119
+ def dispose
120
+ logger.trace("Deactivating watcher for #{@path}")
121
+ @watcher&.deactivate
122
+ end
123
+ end
124
+
125
+ # Implements the ScriptedTriggerHandlerFactory interface to create a new Trigger Handler
126
+ class WatchTriggerHandlerFactory
127
+ include org.openhab.core.automation.module.script.rulesupport.shared.factories.ScriptedTriggerHandlerFactory
128
+
129
+ # Invoked by the OpenHAB core to get a trigger handler for the supllied trigger
130
+ # @param [Trigger] trigger OpenHAB trigger
131
+ #
132
+ # @return [WatchTriggerHandler] trigger handler for supplied trigger
133
+ def get(trigger)
134
+ WatchTriggerHandler.new(trigger)
135
+ end
136
+ end
137
+
138
+ #
139
+ # Creates trigger types and trigger type factories for OpenHAB
140
+ #
141
+ def self.add_watch_handler
142
+ Core.automation_manager.add_trigger_handler(
143
+ WATCH_TRIGGER_MODULE_ID,
144
+ WatchTriggerHandlerFactory.new
145
+ )
146
+
147
+ Core.automation_manager.add_trigger_type(watch_trigger_type)
148
+ logger.trace("Added watch trigger handler")
149
+ end
150
+ add_watch_handler
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module DSL
5
+ module Rules
6
+ # Contains helper classes for implementing triggers.
7
+ # @!visibility private
8
+ module Triggers
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "script_handling"
4
+
5
+ module OpenHAB
6
+ module DSL
7
+ module Rules
8
+ @script_rules = {}
9
+
10
+ @scripted_rule_provider = OSGi.service(
11
+ "org.openhab.core.automation.module.script.rulesupport.shared.ScriptedRuleProvider"
12
+ )
13
+ class << self
14
+ # @!visibility private
15
+ attr_reader :script_rules, :scripted_rule_provider
16
+
17
+ #
18
+ # Cleanup rules in this script file
19
+ #
20
+ # @return [void]
21
+ #
22
+ def cleanup_rules
23
+ script_rules.each_value(&:cleanup)
24
+ end
25
+ end
26
+ ScriptHandling.script_unloaded { cleanup_rules }
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module DSL
5
+ #
6
+ # Provide callback mechanisms for script handling
7
+ #
8
+ module ScriptHandling
9
+ module_function
10
+
11
+ #
12
+ # Add a block of code to be executed once the rule script has finished loading.
13
+ #
14
+ # This can occur on OpenHAB start up, when the script is first created, or updated.
15
+ #
16
+ # Multiple hooks can be added by calling {#script_loaded} multiple times.
17
+ # They can be used to perform final initializations.
18
+ #
19
+ # @return [void]
20
+ #
21
+ # @example
22
+ # script_loaded do
23
+ # logger.info 'Hi, this script has just finished loading'
24
+ # end
25
+ #
26
+ # @example
27
+ # script_loaded do
28
+ # logger.info 'I will be called after the script finished loading too'
29
+ # end
30
+ #
31
+ def script_loaded(&block)
32
+ Core::ScriptHandlingCallbacks.script_loaded_hooks << block
33
+ end
34
+
35
+ #
36
+ # Add a block of code to be executed when the script is unloaded.
37
+ #
38
+ # This can occur when OpenHAB shuts down, or when the script is being reloaded.
39
+ #
40
+ # Multiple hooks can be added by calling {#script_unloaded} multiple times.
41
+ # They can be used to perform final cleanup.
42
+ #
43
+ # @return [void]
44
+ #
45
+ # @example
46
+ # script_unloaded do
47
+ # logger.info 'Hi, this script has been unloaded'
48
+ # end
49
+ #
50
+ def script_unloaded(&block)
51
+ Core::ScriptHandlingCallbacks.script_unloaded_hooks << block
52
+ end
53
+ end
54
+ end
55
+ end