openhab-jrubyscripting 5.0.0.rc10 → 5.0.0.rc12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/lib/openhab/core/actions/audio.rb +47 -0
  3. data/lib/openhab/core/actions/ephemeris.rb +39 -0
  4. data/lib/openhab/core/actions/exec.rb +51 -0
  5. data/lib/openhab/core/actions/http.rb +80 -0
  6. data/lib/openhab/core/actions/ping.rb +30 -0
  7. data/lib/openhab/core/actions/transformation.rb +32 -0
  8. data/lib/openhab/core/actions/voice.rb +36 -0
  9. data/lib/openhab/core/actions.rb +23 -120
  10. data/lib/openhab/core/{events → dto}/item_channel_link.rb +1 -4
  11. data/lib/openhab/core/{events → dto}/thing.rb +10 -12
  12. data/lib/openhab/core/dto.rb +11 -0
  13. data/lib/openhab/core/entity_lookup.rb +1 -1
  14. data/lib/openhab/core/events/abstract_event.rb +1 -0
  15. data/lib/openhab/core/events/abstract_item_registry_event.rb +36 -0
  16. data/lib/openhab/core/events/abstract_thing_registry_event.rb +40 -0
  17. data/lib/openhab/core/events/item_command_event.rb +1 -1
  18. data/lib/openhab/core/events/item_state_changed_event.rb +6 -6
  19. data/lib/openhab/core/events/item_state_event.rb +6 -6
  20. data/lib/openhab/core/events/thing_status_info_event.rb +8 -6
  21. data/lib/openhab/core/items/date_time_item.rb +3 -2
  22. data/lib/openhab/core/items/generic_item.rb +92 -1
  23. data/lib/openhab/core/items/item.rb +9 -8
  24. data/lib/openhab/core/items/metadata/hash.rb +1 -1
  25. data/lib/openhab/core/items/metadata/namespace_hash.rb +10 -2
  26. data/lib/openhab/core/items/metadata/provider.rb +2 -2
  27. data/lib/openhab/core/items/persistence.rb +99 -21
  28. data/lib/openhab/core/items/player_item.rb +1 -1
  29. data/lib/openhab/core/items/proxy.rb +20 -14
  30. data/lib/openhab/core/items/registry.rb +12 -1
  31. data/lib/openhab/core/items/state_storage.rb +2 -2
  32. data/lib/openhab/core/items.rb +3 -3
  33. data/lib/openhab/core/profile_factory.rb +3 -1
  34. data/lib/openhab/core/proxy.rb +130 -0
  35. data/lib/openhab/core/registry.rb +12 -2
  36. data/lib/openhab/core/rules.rb +1 -1
  37. data/lib/openhab/core/things/links/provider.rb +39 -1
  38. data/lib/openhab/core/things/proxy.rb +8 -0
  39. data/lib/openhab/core/things/registry.rb +4 -0
  40. data/lib/openhab/core/timer.rb +3 -19
  41. data/lib/openhab/core/types/date_time_type.rb +3 -2
  42. data/lib/openhab/core/types/decimal_type.rb +1 -1
  43. data/lib/openhab/core/types/un_def_type.rb +2 -2
  44. data/lib/openhab/core/value_cache.rb +1 -1
  45. data/lib/openhab/core.rb +3 -3
  46. data/lib/openhab/core_ext/ephemeris.rb +53 -0
  47. data/lib/openhab/core_ext/java/class.rb +1 -1
  48. data/lib/openhab/core_ext/java/duration.rb +27 -1
  49. data/lib/openhab/core_ext/java/local_date.rb +17 -7
  50. data/lib/openhab/core_ext/java/local_time.rb +13 -3
  51. data/lib/openhab/core_ext/java/month.rb +1 -1
  52. data/lib/openhab/core_ext/java/month_day.rb +15 -3
  53. data/lib/openhab/core_ext/java/period.rb +1 -1
  54. data/lib/openhab/core_ext/java/temporal_amount.rb +1 -1
  55. data/lib/openhab/core_ext/java/time.rb +5 -1
  56. data/lib/openhab/core_ext/java/zoned_date_time.rb +100 -2
  57. data/lib/openhab/core_ext/ruby/date.rb +4 -2
  58. data/lib/openhab/core_ext/ruby/date_time.rb +1 -0
  59. data/lib/openhab/core_ext/ruby/numeric.rb +6 -1
  60. data/lib/openhab/core_ext/ruby/time.rb +1 -0
  61. data/lib/openhab/dsl/debouncer.rb +259 -0
  62. data/lib/openhab/dsl/items/builder.rb +29 -14
  63. data/lib/openhab/dsl/items/timed_command.rb +31 -13
  64. data/lib/openhab/dsl/rules/automation_rule.rb +30 -44
  65. data/lib/openhab/dsl/rules/builder.rb +404 -39
  66. data/lib/openhab/dsl/rules/guard.rb +12 -54
  67. data/lib/openhab/dsl/rules/name_inference.rb +11 -0
  68. data/lib/openhab/dsl/rules/property.rb +3 -4
  69. data/lib/openhab/dsl/rules/terse.rb +4 -1
  70. data/lib/openhab/dsl/rules/triggers/conditions/duration.rb +5 -6
  71. data/lib/openhab/dsl/rules/triggers/cron/cron.rb +1 -0
  72. data/lib/openhab/dsl/rules/triggers/cron/cron_handler.rb +19 -31
  73. data/lib/openhab/dsl/rules/triggers/watch/watch.rb +1 -0
  74. data/lib/openhab/dsl/rules/triggers/watch/watch_handler.rb +22 -30
  75. data/lib/openhab/dsl/things/builder.rb +1 -1
  76. data/lib/openhab/dsl/thread_local.rb +1 -0
  77. data/lib/openhab/dsl/version.rb +1 -1
  78. data/lib/openhab/dsl.rb +251 -14
  79. data/lib/openhab/rspec/helpers.rb +3 -2
  80. data/lib/openhab/rspec/hooks.rb +6 -2
  81. data/lib/openhab/rspec/karaf.rb +7 -0
  82. data/lib/openhab/rspec/mocks/instance_method_stasher.rb +22 -0
  83. data/lib/openhab/rspec/mocks/space.rb +23 -0
  84. data/lib/openhab/rspec/mocks/timer.rb +33 -0
  85. data/lib/openhab/rspec/openhab/core/actions.rb +16 -4
  86. data/lib/openhab/rspec/openhab/core/items/proxy.rb +1 -13
  87. data/lib/openhab/rspec/suspend_rules.rb +1 -14
  88. data/lib/openhab/rspec.rb +9 -0
  89. data/lib/openhab/yard/base_helper.rb +19 -0
  90. data/lib/openhab/yard/code_objects/group_object.rb +9 -3
  91. data/lib/openhab/yard/coderay.rb +17 -0
  92. data/lib/openhab/yard/handlers/jruby/base.rb +10 -1
  93. data/lib/openhab/yard/handlers/jruby/java_import_handler.rb +3 -0
  94. data/lib/openhab/yard/html_helper.rb +49 -15
  95. data/lib/openhab/yard/markdown_helper.rb +135 -0
  96. data/lib/openhab/yard.rb +6 -0
  97. metadata +36 -4
@@ -17,10 +17,17 @@ module OpenHAB
17
17
  # command. This is available on both the 'command' method and any
18
18
  # command-specific methods, e.g. {SwitchItem#on}.
19
19
  #
20
- # Any update to the timed command state will result in the timer being
21
- # cancelled. For example, if you have a Switch on a timer and another
22
- # rule sends OFF or ON to that item the timer will be automatically
23
- # canceled. Sending a different duration (for:) value for the timed
20
+ # The timer will be cancelled, and the item's state will not be changed
21
+ # to the on_expire state if:
22
+ # - The item receives any command within the timed command duration.
23
+ # - The item is updated to a different state, even if it is then updated
24
+ # back to the same state.
25
+ #
26
+ # For example, if you have a Switch on a timer and another rule sends
27
+ # a command to that item, even when it's commanded to the same state,
28
+ # the timer will be automatically canceled.
29
+ #
30
+ # Sending a different duration (for:) value for the timed
24
31
  # command will reschedule the timed command for that new duration.
25
32
  #
26
33
  module TimedCommand
@@ -107,7 +114,7 @@ module OpenHAB
107
114
  # no prior timed command
108
115
  on_expire ||= default_on_expire(command)
109
116
  super(command)
110
- create_timed_command(duration: duration, on_expire: on_expire)
117
+ create_timed_command(command, duration: duration, on_expire: on_expire)
111
118
  else
112
119
  timed_command_details.mutex.synchronize do
113
120
  if timed_command_details.resolution
@@ -116,7 +123,7 @@ module OpenHAB
116
123
  # just create a new one
117
124
  on_expire ||= default_on_expire(command)
118
125
  super(command)
119
- create_timed_command(duration: duration, on_expire: on_expire)
126
+ create_timed_command(command, duration: duration, on_expire: on_expire)
120
127
  else
121
128
  # timed command still pending; reset it
122
129
  logger.trace "Outstanding Timed Command #{timed_command_details} encountered - rescheduling"
@@ -138,13 +145,13 @@ module OpenHAB
138
145
  private
139
146
 
140
147
  # Creates a new timed command and places it in the TimedCommand hash
141
- def create_timed_command(duration:, on_expire:)
148
+ def create_timed_command(command, duration:, on_expire:)
142
149
  timed_command_details = TimedCommandDetails.new(item: self,
143
150
  on_expire: on_expire,
144
151
  mutex: Mutex.new)
145
152
 
146
153
  timed_command_details.timer = timed_command_timer(timed_command_details, duration)
147
- cancel_rule = TimedCommandCancelRule.new(timed_command_details)
154
+ cancel_rule = TimedCommandCancelRule.new(command, timed_command_details)
148
155
  unmanaged_rule = Core.automation_manager.add_unmanaged_rule(cancel_rule)
149
156
  timed_command_details.rule_uid = unmanaged_rule.uid
150
157
  Core::Rules::Provider.current.add(unmanaged_rule)
@@ -189,16 +196,27 @@ module OpenHAB
189
196
  #
190
197
  # @!visibility private
191
198
  class TimedCommandCancelRule < org.openhab.core.automation.module.script.rulesupport.shared.simple.SimpleRule
192
- def initialize(timed_command_details)
199
+ def initialize(command, timed_command_details)
193
200
  super()
194
201
  @timed_command_details = timed_command_details
195
202
  # Capture rule name if known
196
203
  @thread_locals = ThreadLocal.persist
197
204
  self.name = "Cancel implicit timer for #{timed_command_details.item.name}"
198
- self.triggers = [Rules::RuleTriggers.trigger(
199
- type: Rules::Triggers::Changed::ITEM_STATE_CHANGE,
200
- config: { "itemName" => timed_command_details.item.name }
201
- )]
205
+ self.triggers = [
206
+ Rules::RuleTriggers.trigger(
207
+ type: Rules::Triggers::Changed::ITEM_STATE_CHANGE,
208
+ config: {
209
+ "itemName" => timed_command_details.item.name,
210
+ "previousState" => timed_command_details.item.format_command(command).to_s
211
+ }
212
+ ),
213
+ Rules::RuleTriggers.trigger(
214
+ type: Rules::Triggers::Command::ITEM_COMMAND,
215
+ config: {
216
+ "itemName" => timed_command_details.item.name
217
+ }
218
+ )
219
+ ]
202
220
  self.visibility = Core::Rules::Visibility::HIDDEN
203
221
  end
204
222
 
@@ -30,12 +30,13 @@ module OpenHAB
30
30
  # @param [Config] config Rule configuration
31
31
  #
32
32
  # Constructor sets a number of variables, no further decomposition necessary
33
+ #
33
34
  def initialize(config)
34
- # Metrics disabled because only setters are called or defaults set.
35
35
  super()
36
36
  set_name(config.name)
37
37
  set_description(config.description)
38
- set_tags(to_string_set(config.tags))
38
+ tags = DSL::Items::ItemBuilder.normalize_tags(*config.tags)
39
+ set_tags(tags.to_set)
39
40
  set_triggers(config.triggers)
40
41
  self.uid = config.uid
41
42
  @run_context = config.caller
@@ -50,6 +51,8 @@ module OpenHAB
50
51
  @thread_locals = ThreadLocal.persist
51
52
  @cleanup_hooks = Set.new
52
53
  @listener = nil
54
+ debounce_settings = config.debounce_settings || { for: nil }
55
+ @debouncer = Debouncer.new(**debounce_settings)
53
56
  end
54
57
 
55
58
  #
@@ -58,30 +61,34 @@ module OpenHAB
58
61
  # @param [java.util.Map] mod map provided by openHAB rules engine
59
62
  # @param [java.util.Map] inputs map provided by openHAB rules engine containing event and other information
60
63
  #
61
- #
62
64
  def execute(mod = nil, inputs = nil)
65
+ execute!(mod, inputs)
66
+ end
67
+
68
+ # @!visibility private
69
+ def on_removal(listener)
70
+ @cleanup_hooks << listener
71
+ listen_for_removal unless @listener
72
+ end
73
+
74
+ private
75
+
76
+ # This method gets called in rspec's SuspendRules as well
77
+ def execute!(mod, inputs)
63
78
  ThreadLocal.thread_local(**@thread_locals) do
64
79
  logger.trace { "Execute called with mod (#{mod&.to_string}) and inputs (#{inputs.inspect})" }
65
80
  logger.trace { "Event details #{inputs["event"].inspect}" } if inputs&.key?("event")
66
81
  trigger_conditions(inputs).process(mod: mod, inputs: inputs) do
67
82
  event = extract_event(inputs)
68
- process_queue(create_queue(event), mod, event)
83
+ @debouncer.call { process_queue(create_queue(event), mod, event) }
69
84
  end
70
85
  rescue Exception => e
71
- raise if defined?(::RSpec)
86
+ raise if defined?(::RSpec) && ::RSpec.current_example.example_group.propagate_exceptions?
72
87
 
73
88
  @run_context.send(:logger).log_exception(e)
74
89
  end
75
90
  end
76
91
 
77
- # @!visibility private
78
- def on_removal(listener)
79
- @cleanup_hooks << listener
80
- listen_for_removal unless @listener
81
- end
82
-
83
- private
84
-
85
92
  def cleanup
86
93
  @cleanup_hooks.each(&:cleanup)
87
94
  end
@@ -180,17 +187,18 @@ module OpenHAB
180
187
  def check_guards(event:)
181
188
  return true if @guard.nil?
182
189
 
183
- if @guard.should_run? event
184
- return true if @between.nil?
185
-
190
+ unless @between.nil?
186
191
  now = Time.now
187
- return true if @between.cover? now
188
-
189
- logger.trace("Skipped execution of rule '#{name}' because the current time #{now} " \
190
- "is not between #{@between.begin} and #{@between.end}")
191
- else
192
- logger.trace("Skipped execution of rule '#{name}' because of guard #{@guard}")
192
+ unless @between.cover?(now)
193
+ logger.trace("Skipped execution of rule '#{name}' because the current time #{now} " \
194
+ "is not between #{@between.begin} and #{@between.end}")
195
+ return false
196
+ end
193
197
  end
198
+
199
+ return true if @guard.should_run?(event)
200
+
201
+ logger.trace("Skipped execution of rule '#{name}' because of guard #{@guard}")
194
202
  false
195
203
  end
196
204
 
@@ -290,28 +298,6 @@ module OpenHAB
290
298
  @run_context.instance_exec(&task.block)
291
299
  end
292
300
 
293
- #
294
- # Convert the given array to a set of strings.
295
- # Convert Semantics classes to their simple name
296
- #
297
- # @example
298
- # to_string_set("tag1", Semantics::LivingRoom)
299
- #
300
- # @param tags [Array] An array of strings or Semantics classes
301
- #
302
- # @return [Set] A set of strings
303
- #
304
- def to_string_set(*tags)
305
- tags = tags.flatten.map do |tag|
306
- if tag.respond_to?(:java_class) && tag < org.openhab.core.semantics.Tag
307
- tag.java_class.simple_name
308
- else
309
- tag.to_s
310
- end
311
- end
312
- Set.new(tags)
313
- end
314
-
315
301
  #
316
302
  # Create a new hash in which all elements are converted to strings
317
303
  #