openhab-scripting 4.46.2 → 5.0.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.
Files changed (281) 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 +82 -0
  10. data/lib/openhab/core/dependency_tracking.rb +34 -0
  11. data/lib/openhab/core/dto/item_channel_link.rb +33 -0
  12. data/lib/openhab/core/dto/thing.rb +27 -0
  13. data/lib/openhab/core/dto.rb +11 -0
  14. data/lib/openhab/core/entity_lookup.rb +152 -70
  15. data/lib/openhab/core/events/abstract_event.rb +18 -0
  16. data/lib/openhab/core/events/abstract_item_registry_event.rb +36 -0
  17. data/lib/openhab/core/events/abstract_thing_registry_event.rb +40 -0
  18. data/lib/openhab/core/events/item_command_event.rb +78 -0
  19. data/lib/openhab/core/events/item_event.rb +22 -0
  20. data/lib/openhab/core/events/item_state_changed_event.rb +75 -0
  21. data/lib/openhab/core/events/item_state_event.rb +79 -0
  22. data/lib/openhab/core/events/thing_status_info_event.rb +55 -0
  23. data/lib/openhab/core/events.rb +10 -0
  24. data/lib/openhab/core/items/accepted_data_types.rb +29 -0
  25. data/lib/openhab/core/items/color_item.rb +52 -0
  26. data/lib/openhab/core/items/contact_item.rb +52 -0
  27. data/lib/openhab/core/items/date_time_item.rb +59 -0
  28. data/lib/openhab/core/items/dimmer_item.rb +148 -0
  29. data/lib/openhab/core/items/generic_item.rb +292 -0
  30. data/lib/openhab/core/items/group_item.rb +176 -0
  31. data/lib/openhab/{dsl → core}/items/image_item.rb +35 -29
  32. data/lib/openhab/core/items/item.rb +273 -0
  33. data/lib/openhab/core/items/location_item.rb +34 -0
  34. data/lib/openhab/core/items/metadata/hash.rb +433 -0
  35. data/lib/openhab/core/items/metadata/namespace_hash.rb +475 -0
  36. data/lib/openhab/core/items/metadata/provider.rb +48 -0
  37. data/lib/openhab/core/items/metadata.rb +11 -0
  38. data/lib/openhab/core/items/number_item.rb +62 -0
  39. data/lib/openhab/core/items/numeric_item.rb +22 -0
  40. data/lib/openhab/core/items/persistence.rb +416 -0
  41. data/lib/openhab/core/items/player_item.rb +66 -0
  42. data/lib/openhab/core/items/provider.rb +44 -0
  43. data/lib/openhab/core/items/proxy.rb +136 -0
  44. data/lib/openhab/core/items/registry.rb +86 -0
  45. data/lib/openhab/core/items/rollershutter_item.rb +68 -0
  46. data/lib/openhab/core/items/semantics/enumerable.rb +177 -0
  47. data/lib/openhab/core/items/semantics.rb +473 -0
  48. data/lib/openhab/core/items/state_storage.rb +53 -0
  49. data/lib/openhab/core/items/string_item.rb +28 -0
  50. data/lib/openhab/core/items/switch_item.rb +78 -0
  51. data/lib/openhab/core/items.rb +108 -0
  52. data/lib/openhab/{dsl → core}/lazy_array.rb +9 -3
  53. data/lib/openhab/core/profile_factory.rb +132 -0
  54. data/lib/openhab/core/provider.rb +230 -0
  55. data/lib/openhab/core/proxy.rb +130 -0
  56. data/lib/openhab/core/registry.rb +40 -0
  57. data/lib/openhab/core/rules/module.rb +26 -0
  58. data/lib/openhab/core/rules/provider.rb +25 -0
  59. data/lib/openhab/core/rules/registry.rb +76 -0
  60. data/lib/openhab/core/rules/rule.rb +150 -0
  61. data/lib/openhab/core/rules.rb +25 -0
  62. data/lib/openhab/core/script_handling.rb +78 -20
  63. data/lib/openhab/core/things/channel.rb +48 -0
  64. data/lib/openhab/core/things/channel_uid.rb +51 -0
  65. data/lib/openhab/core/things/item_channel_link.rb +33 -0
  66. data/lib/openhab/core/things/links/provider.rb +78 -0
  67. data/lib/openhab/core/things/profile_callback.rb +52 -0
  68. data/lib/openhab/core/things/provider.rb +29 -0
  69. data/lib/openhab/core/things/proxy.rb +87 -0
  70. data/lib/openhab/core/things/registry.rb +73 -0
  71. data/lib/openhab/core/things/thing.rb +194 -0
  72. data/lib/openhab/core/things.rb +22 -0
  73. data/lib/openhab/core/timer.rb +148 -0
  74. data/lib/openhab/{dsl → core}/types/comparable_type.rb +5 -3
  75. data/lib/openhab/{dsl → core}/types/date_time_type.rb +55 -127
  76. data/lib/openhab/{dsl → core}/types/decimal_type.rb +50 -48
  77. data/lib/openhab/{dsl → core}/types/hsb_type.rb +35 -83
  78. data/lib/openhab/core/types/increase_decrease_type.rb +34 -0
  79. data/lib/openhab/core/types/next_previous_type.rb +34 -0
  80. data/lib/openhab/{dsl → core}/types/numeric_type.rb +20 -7
  81. data/lib/openhab/core/types/on_off_type.rb +46 -0
  82. data/lib/openhab/core/types/open_closed_type.rb +41 -0
  83. data/lib/openhab/{dsl → core}/types/percent_type.rb +19 -20
  84. data/lib/openhab/core/types/play_pause_type.rb +38 -0
  85. data/lib/openhab/core/types/point_type.rb +117 -0
  86. data/lib/openhab/core/types/quantity_type.rb +325 -0
  87. data/lib/openhab/core/types/raw_type.rb +26 -0
  88. data/lib/openhab/core/types/refresh_type.rb +27 -0
  89. data/lib/openhab/core/types/rewind_fastforward_type.rb +38 -0
  90. data/lib/openhab/core/types/stop_move_type.rb +34 -0
  91. data/lib/openhab/{dsl → core}/types/string_type.rb +17 -28
  92. data/lib/openhab/{dsl → core}/types/type.rb +42 -40
  93. data/lib/openhab/core/types/un_def_type.rb +38 -0
  94. data/lib/openhab/core/types/up_down_type.rb +50 -0
  95. data/lib/openhab/core/types.rb +82 -0
  96. data/lib/openhab/{dsl → core}/uid.rb +4 -23
  97. data/lib/openhab/core/value_cache.rb +188 -0
  98. data/lib/openhab/core.rb +98 -0
  99. data/lib/openhab/core_ext/between.rb +32 -0
  100. data/lib/openhab/core_ext/ephemeris.rb +53 -0
  101. data/lib/openhab/core_ext/java/class.rb +34 -0
  102. data/lib/openhab/core_ext/java/duration.rb +142 -0
  103. data/lib/openhab/core_ext/java/list.rb +436 -0
  104. data/lib/openhab/core_ext/java/local_date.rb +104 -0
  105. data/lib/openhab/core_ext/java/local_time.rb +118 -0
  106. data/lib/openhab/core_ext/java/map.rb +66 -0
  107. data/lib/openhab/core_ext/java/month.rb +71 -0
  108. data/lib/openhab/core_ext/java/month_day.rb +119 -0
  109. data/lib/openhab/core_ext/java/period.rb +103 -0
  110. data/lib/openhab/core_ext/java/temporal_amount.rb +34 -0
  111. data/lib/openhab/core_ext/java/time.rb +62 -0
  112. data/lib/openhab/core_ext/java/unit.rb +15 -0
  113. data/lib/openhab/core_ext/java/zoned_date_time.rb +213 -0
  114. data/lib/openhab/core_ext/ruby/array.rb +21 -0
  115. data/lib/openhab/core_ext/ruby/date.rb +96 -0
  116. data/lib/openhab/core_ext/ruby/date_time.rb +55 -0
  117. data/lib/openhab/core_ext/ruby/module.rb +15 -0
  118. data/lib/openhab/core_ext/ruby/numeric.rb +195 -0
  119. data/lib/openhab/core_ext/ruby/range.rb +70 -0
  120. data/lib/openhab/core_ext/ruby/symbol.rb +7 -0
  121. data/lib/openhab/core_ext/ruby/time.rb +108 -0
  122. data/lib/openhab/core_ext.rb +18 -0
  123. data/lib/openhab/dsl/debouncer.rb +259 -0
  124. data/lib/openhab/dsl/events/watch_event.rb +18 -0
  125. data/lib/openhab/dsl/events.rb +9 -0
  126. data/lib/openhab/dsl/gems.rb +1 -1
  127. data/lib/openhab/dsl/items/builder.rb +578 -0
  128. data/lib/openhab/dsl/items/ensure.rb +73 -82
  129. data/lib/openhab/dsl/items/timed_command.rb +214 -159
  130. data/lib/openhab/dsl/rules/automation_rule.rb +126 -115
  131. data/lib/openhab/dsl/rules/builder.rb +1935 -0
  132. data/lib/openhab/dsl/rules/guard.rb +51 -114
  133. data/lib/openhab/dsl/rules/name_inference.rb +66 -25
  134. data/lib/openhab/dsl/rules/property.rb +48 -75
  135. data/lib/openhab/dsl/rules/rule_triggers.rb +22 -27
  136. data/lib/openhab/dsl/rules/terse.rb +58 -14
  137. data/lib/openhab/dsl/rules/triggers/changed.rb +48 -94
  138. data/lib/openhab/dsl/rules/triggers/channel.rb +9 -40
  139. data/lib/openhab/dsl/rules/triggers/command.rb +14 -63
  140. data/lib/openhab/dsl/rules/triggers/conditions/duration.rb +34 -69
  141. data/lib/openhab/dsl/rules/triggers/conditions/proc.rb +6 -14
  142. data/lib/openhab/dsl/rules/triggers/cron/cron.rb +48 -82
  143. data/lib/openhab/dsl/rules/triggers/cron/cron_handler.rb +30 -47
  144. data/lib/openhab/dsl/rules/triggers/trigger.rb +7 -28
  145. data/lib/openhab/dsl/rules/triggers/updated.rb +21 -45
  146. data/lib/openhab/dsl/rules/triggers/watch/watch_handler.rb +257 -102
  147. data/lib/openhab/dsl/rules/triggers.rb +12 -0
  148. data/lib/openhab/dsl/rules.rb +8 -0
  149. data/lib/openhab/dsl/things/builder.rb +299 -0
  150. data/lib/openhab/{core → dsl}/thread_local.rb +27 -17
  151. data/lib/openhab/dsl/timer_manager.rb +204 -0
  152. data/lib/openhab/dsl/version.rb +9 -0
  153. data/lib/openhab/dsl.rb +979 -0
  154. data/lib/openhab/log.rb +355 -0
  155. data/lib/openhab/osgi.rb +68 -0
  156. data/lib/openhab/rspec/configuration.rb +56 -0
  157. data/lib/openhab/rspec/example_group.rb +132 -0
  158. data/lib/openhab/rspec/helpers.rb +458 -0
  159. data/lib/openhab/rspec/hooks.rb +113 -0
  160. data/lib/openhab/rspec/jruby.rb +46 -0
  161. data/lib/openhab/rspec/karaf.rb +851 -0
  162. data/lib/openhab/rspec/mocks/bundle_install_support.rb +25 -0
  163. data/lib/openhab/rspec/mocks/bundle_resolver.rb +30 -0
  164. data/lib/openhab/rspec/mocks/event_admin.rb +146 -0
  165. data/lib/openhab/rspec/mocks/instance_method_stasher.rb +22 -0
  166. data/lib/openhab/rspec/mocks/persistence_service.rb +155 -0
  167. data/lib/openhab/rspec/mocks/safe_caller.rb +40 -0
  168. data/lib/openhab/rspec/mocks/space.rb +23 -0
  169. data/lib/openhab/rspec/mocks/synchronous_executor.rb +63 -0
  170. data/lib/openhab/rspec/mocks/thing_handler.rb +76 -0
  171. data/lib/openhab/rspec/mocks/timer.rb +134 -0
  172. data/lib/openhab/rspec/openhab/core/actions.rb +38 -0
  173. data/lib/openhab/rspec/openhab/core/items/proxy.rb +15 -0
  174. data/lib/openhab/rspec/openhab/core/things/proxy.rb +27 -0
  175. data/lib/openhab/rspec/shell.rb +31 -0
  176. data/lib/openhab/rspec/suspend_rules.rb +50 -0
  177. data/lib/openhab/rspec.rb +26 -0
  178. data/lib/openhab/yard/base_helper.rb +19 -0
  179. data/lib/openhab/yard/cli/stats.rb +23 -0
  180. data/lib/openhab/yard/code_objects/group_object.rb +23 -0
  181. data/lib/openhab/yard/code_objects/java/base.rb +31 -0
  182. data/lib/openhab/yard/code_objects/java/class_object.rb +11 -0
  183. data/lib/openhab/yard/code_objects/java/field_object.rb +15 -0
  184. data/lib/openhab/yard/code_objects/java/interface_object.rb +15 -0
  185. data/lib/openhab/yard/code_objects/java/package_object.rb +11 -0
  186. data/lib/openhab/yard/code_objects/java/proxy.rb +23 -0
  187. data/lib/openhab/yard/coderay.rb +17 -0
  188. data/lib/openhab/yard/handlers/jruby/base.rb +58 -0
  189. data/lib/openhab/yard/handlers/jruby/class_handler.rb +18 -0
  190. data/lib/openhab/yard/handlers/jruby/constant_handler.rb +18 -0
  191. data/lib/openhab/yard/handlers/jruby/java_import_handler.rb +30 -0
  192. data/lib/openhab/yard/handlers/jruby/mixin_handler.rb +23 -0
  193. data/lib/openhab/yard/html_helper.rb +78 -0
  194. data/lib/openhab/yard/markdown_helper.rb +148 -0
  195. data/lib/openhab/yard/tags/constant_directive.rb +20 -0
  196. data/lib/openhab/yard/tags/group_directive.rb +24 -0
  197. data/lib/openhab/yard/tags/library.rb +3 -0
  198. data/lib/openhab/yard.rb +38 -0
  199. metadata +475 -106
  200. data/lib/openhab/core/item_proxy.rb +0 -29
  201. data/lib/openhab/core/load_path.rb +0 -19
  202. data/lib/openhab/core/openhab_setup.rb +0 -29
  203. data/lib/openhab/core/osgi.rb +0 -58
  204. data/lib/openhab/core/services.rb +0 -24
  205. data/lib/openhab/dsl/actions.rb +0 -114
  206. data/lib/openhab/dsl/between.rb +0 -25
  207. data/lib/openhab/dsl/channel.rb +0 -43
  208. data/lib/openhab/dsl/dsl.rb +0 -59
  209. data/lib/openhab/dsl/group.rb +0 -54
  210. data/lib/openhab/dsl/imports.rb +0 -21
  211. data/lib/openhab/dsl/items/color_item.rb +0 -76
  212. data/lib/openhab/dsl/items/comparable_item.rb +0 -62
  213. data/lib/openhab/dsl/items/contact_item.rb +0 -41
  214. data/lib/openhab/dsl/items/date_time_item.rb +0 -65
  215. data/lib/openhab/dsl/items/dimmer_item.rb +0 -65
  216. data/lib/openhab/dsl/items/generic_item.rb +0 -229
  217. data/lib/openhab/dsl/items/group_item.rb +0 -127
  218. data/lib/openhab/dsl/items/item_equality.rb +0 -59
  219. data/lib/openhab/dsl/items/item_registry.rb +0 -54
  220. data/lib/openhab/dsl/items/items.rb +0 -109
  221. data/lib/openhab/dsl/items/location_item.rb +0 -59
  222. data/lib/openhab/dsl/items/metadata.rb +0 -326
  223. data/lib/openhab/dsl/items/number_item.rb +0 -17
  224. data/lib/openhab/dsl/items/numeric_item.rb +0 -87
  225. data/lib/openhab/dsl/items/persistence.rb +0 -307
  226. data/lib/openhab/dsl/items/player_item.rb +0 -58
  227. data/lib/openhab/dsl/items/rollershutter_item.rb +0 -51
  228. data/lib/openhab/dsl/items/semantics/enumerable.rb +0 -91
  229. data/lib/openhab/dsl/items/semantics.rb +0 -227
  230. data/lib/openhab/dsl/items/string_item.rb +0 -51
  231. data/lib/openhab/dsl/items/switch_item.rb +0 -70
  232. data/lib/openhab/dsl/monkey_patch/actions/actions.rb +0 -4
  233. data/lib/openhab/dsl/monkey_patch/actions/script_thing_actions.rb +0 -39
  234. data/lib/openhab/dsl/monkey_patch/events/events.rb +0 -7
  235. data/lib/openhab/dsl/monkey_patch/events/item_command.rb +0 -85
  236. data/lib/openhab/dsl/monkey_patch/events/item_event.rb +0 -28
  237. data/lib/openhab/dsl/monkey_patch/events/item_state.rb +0 -61
  238. data/lib/openhab/dsl/monkey_patch/events/item_state_changed.rb +0 -60
  239. data/lib/openhab/dsl/monkey_patch/events/thing_status_info.rb +0 -33
  240. data/lib/openhab/dsl/monkey_patch/java/java.rb +0 -4
  241. data/lib/openhab/dsl/monkey_patch/java/local_time.rb +0 -44
  242. data/lib/openhab/dsl/monkey_patch/java/time_extensions.rb +0 -50
  243. data/lib/openhab/dsl/monkey_patch/java/zoned_date_time.rb +0 -45
  244. data/lib/openhab/dsl/monkey_patch/ruby/number.rb +0 -104
  245. data/lib/openhab/dsl/monkey_patch/ruby/ruby.rb +0 -6
  246. data/lib/openhab/dsl/monkey_patch/ruby/string.rb +0 -47
  247. data/lib/openhab/dsl/monkey_patch/ruby/time.rb +0 -61
  248. data/lib/openhab/dsl/openhab.rb +0 -30
  249. data/lib/openhab/dsl/persistence.rb +0 -27
  250. data/lib/openhab/dsl/rules/item_event.rb +0 -19
  251. data/lib/openhab/dsl/rules/rule.rb +0 -160
  252. data/lib/openhab/dsl/rules/rule_config.rb +0 -147
  253. data/lib/openhab/dsl/rules/triggers/generic.rb +0 -31
  254. data/lib/openhab/dsl/rules/triggers/triggers.rb +0 -11
  255. data/lib/openhab/dsl/rules/triggers/watch/watch.rb +0 -81
  256. data/lib/openhab/dsl/states.rb +0 -89
  257. data/lib/openhab/dsl/things.rb +0 -147
  258. data/lib/openhab/dsl/time/month_day.rb +0 -180
  259. data/lib/openhab/dsl/time/time_of_day.rb +0 -235
  260. data/lib/openhab/dsl/timers/manager.rb +0 -119
  261. data/lib/openhab/dsl/timers/reentrant_timer.rb +0 -38
  262. data/lib/openhab/dsl/timers/timer.rb +0 -132
  263. data/lib/openhab/dsl/timers.rb +0 -77
  264. data/lib/openhab/dsl/types/increase_decrease_type.rb +0 -23
  265. data/lib/openhab/dsl/types/next_previous_type.rb +0 -23
  266. data/lib/openhab/dsl/types/on_off_type.rb +0 -28
  267. data/lib/openhab/dsl/types/open_closed_type.rb +0 -29
  268. data/lib/openhab/dsl/types/play_pause_type.rb +0 -27
  269. data/lib/openhab/dsl/types/point_type.rb +0 -180
  270. data/lib/openhab/dsl/types/quantity_type.rb +0 -265
  271. data/lib/openhab/dsl/types/refresh_type.rb +0 -18
  272. data/lib/openhab/dsl/types/rewind_fastforward_type.rb +0 -33
  273. data/lib/openhab/dsl/types/stop_move_type.rb +0 -23
  274. data/lib/openhab/dsl/types/types.rb +0 -83
  275. data/lib/openhab/dsl/types/un_def_type.rb +0 -22
  276. data/lib/openhab/dsl/types/up_down_type.rb +0 -32
  277. data/lib/openhab/dsl/units.rb +0 -45
  278. data/lib/openhab/log/configuration.rb +0 -21
  279. data/lib/openhab/log/logger.rb +0 -282
  280. data/lib/openhab/version.rb +0 -9
  281. data/lib/openhab.rb +0 -36
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "forwardable"
4
+
5
+ # Extensions to Time
6
+ class Time
7
+ extend Forwardable
8
+ include OpenHAB::CoreExt::Between
9
+ include OpenHAB::CoreExt::Ephemeris
10
+
11
+ #
12
+ # @!method +(other)
13
+ #
14
+ # Extends {#+} to allow adding a {java.time.temporal.TemporalAmount TemporalAmount}
15
+ #
16
+ # @param [java.time.temporal.TemporalAmount] other
17
+ # @return [ZonedDateTime] If other is a {java.time.temporal.TemporalAmount TemporalAmount}
18
+ # @return [Time] If other is a Numeric
19
+ #
20
+ def plus_with_temporal(other)
21
+ return to_zoned_date_time + other if other.is_a?(java.time.temporal.TemporalAmount)
22
+
23
+ plus_without_temporal(other)
24
+ end
25
+ alias_method :plus_without_temporal, :+
26
+ alias_method :+, :plus_with_temporal
27
+
28
+ #
29
+ # @!method -(other)
30
+ #
31
+ # Extends {#-} to allow subtracting a {java.time.temporal.TemporalAmount TemporalAmount}
32
+ # or any other date/time class that responds to #to_zoned_date_time.
33
+ #
34
+ # Subtractions with another object of the same class (e.g. Time - Other Time, or DateTime - Other DateTime)
35
+ # remains unchanged from its original behavior.
36
+ #
37
+ # @example Time - Duration -> ZonedDateTime
38
+ # zdt_one_hour_ago = Time.now - 1.hour
39
+ #
40
+ # @example Time - ZonedDateTime -> Duration
41
+ # java_duration = Time.now - 1.hour.ago
42
+ #
43
+ # @example Time - Numeric -> Time
44
+ # time_one_hour_ago = Time - 3600
45
+ #
46
+ # @example Time - Time -> Float
47
+ # one_day_in_secs = Time.new(2002, 10, 31) - Time.new(2002, 10, 30)
48
+ #
49
+ # @param [java.time.temporal.TemporalAmount, #to_zoned_date_time] other
50
+ # @return [ZonedDateTime] If other is a {java.time.temporal.TemporalAmount TemporalAmount}
51
+ # @return [Duration] If other responds to #to_zoned_date_time
52
+ # @return [Time] If other is a Numeric
53
+ # @return [Float] If other is a Time
54
+ #
55
+ def minus_with_temporal(other)
56
+ return to_zoned_date_time - other if other.is_a?(java.time.temporal.TemporalAmount)
57
+
58
+ # Exclude subtracting against the same class
59
+ if other.respond_to?(:to_zoned_date_time) && !other.is_a?(self.class)
60
+ return to_zoned_date_time - other.to_zoned_date_time
61
+ end
62
+
63
+ minus_without_temporal(other)
64
+ end
65
+ alias_method :minus_without_temporal, :-
66
+ alias_method :-, :minus_with_temporal
67
+
68
+ # @return [LocalDate]
69
+ def to_local_date(_context = nil)
70
+ java.time.LocalDate.of(year, month, day)
71
+ end
72
+
73
+ # @!method to_local_time
74
+ # @return [LocalTime]
75
+ def_delegator :to_zoned_date_time, :to_local_time
76
+
77
+ # @return [Month]
78
+ def to_month
79
+ java.time.Month.of(month)
80
+ end
81
+
82
+ # @return [MonthDay]
83
+ def to_month_day
84
+ java.time.MonthDay.of(month, day)
85
+ end
86
+
87
+ # @param [ZonedDateTime, nil] context
88
+ # A {ZonedDateTime} used to fill in missing fields
89
+ # during conversion. Not used in this class.
90
+ # @return [ZonedDateTime]
91
+ def to_zoned_date_time(context = nil) # rubocop:disable Lint/UnusedMethodArgument
92
+ to_java(java.time.ZonedDateTime)
93
+ end
94
+
95
+ #
96
+ # Converts to a {ZonedDateTime} if `other`
97
+ # is also convertible to a ZonedDateTime.
98
+ #
99
+ # @param [#to_zoned_date_time] other
100
+ # @return [Array, nil]
101
+ #
102
+ def coerce(other)
103
+ return unless other.respond_to?(:to_zoned_date_time)
104
+
105
+ zdt = to_zoned_date_time
106
+ [other.to_zoned_date_time(zdt), zdt]
107
+ end
108
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ Dir[File.expand_path("core_ext/**/*.rb", __dir__)].sort.each do |f|
4
+ require f
5
+ end
6
+
7
+ module OpenHAB
8
+ # Extensions to core classes
9
+ module CoreExt
10
+ # Extensions to core Java classes
11
+ module Java
12
+ end
13
+
14
+ # Extensions to core Ruby classes
15
+ module Ruby
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,259 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module DSL
5
+ #
6
+ # Provides the feature for debouncing calls to a given block.
7
+ #
8
+ # The debouncer can filter events and only allow the events on the leading or trailing edge
9
+ # of the given interval. Its behavior can be customized through settings passed to its
10
+ # {initialize constructor}.
11
+ #
12
+ # The following timing diagram illustrates the incoming triggers and the actual executions
13
+ # using various options.
14
+ #
15
+ # ```ruby
16
+ # 1 1 2 2 3 3 4 4
17
+ # 0 5 0 5 0 5 0 5 0 5
18
+ # Triggers : 'X.X...X...X..XX.X.X......XXXXXXXXXXX....X.....'
19
+ # leading: false
20
+ # for:5 : '|....X|....X |....X |....X|....X |....X'
21
+ # leading: true
22
+ # for:5 : 'X.....X......X....X......X....X....X....X.....'
23
+ #
24
+ # more options, leading: false
25
+ # Triggers : 'X.X...X...X..XX.X.X......XXXXXXXXXXX....X.....'
26
+ # for:5 idle:3 : '|....X|......X|......X...|............X.|....X'
27
+ # for:5 idle:5 : '|......................X.|..............X.....'
28
+ # for:5..5 idle:X : '|....X|....X.|....X......|....X|....X...|....X'
29
+ # for:5..6 idle:5 : '|.....X...|.....X.|....X.|.....X|.....X.|....X'
30
+ # for:5..7 idle:5 : '|......X..|......X|....X.|......X|......X.....'
31
+ # for:5..8 idle:5 : '|.......X.|.......X......|.......X|.....X.....'
32
+ # for:5..8 idle:3 : '|....X|......X|......X...|.......X|....X|....X'
33
+ # for:5..8 idle:2 : '|....X|.....X|......X....|.......X|....X|....X'
34
+ # ```
35
+ #
36
+ # Notes:
37
+ # - `|` indicates the start of the debounce period
38
+ # - With `for: 5..5` (a range with begin=end), the `idle_time` argument is irrelevant
39
+ # and be unset/set to any value as it will not alter the debouncer's behavior.
40
+ # - Without an `idle_time`, the range end in `for: X..Y` is irrelevant. It is equivalent to
41
+ # `for: X` without the end of the range.
42
+ #
43
+ class Debouncer
44
+ # @return [Range,nil] The range of accepted debounce period, or nil if debouncing is disabled.
45
+ attr_reader :interval
46
+
47
+ # @return [Duration, nil] The minimum idle time to stop debouncing.
48
+ attr_reader :idle_time
49
+
50
+ #
51
+ # Constructor to create a debouncer object.
52
+ #
53
+ # The constructor sets the options and behaviour of the debouncer when the {#call}
54
+ # method is called.
55
+ #
56
+ # Terminology:
57
+ # - `calls` are invocations of the {#call} method, i.e. the events that need to be throttled / debounced.
58
+ # - `executions` are the actual code executions of the given block. Executions usually occur
59
+ # less frequently than the call to the debounce method.
60
+ #
61
+ # @param [Duration,Range,nil] for The minimum and optional maximum execution interval.
62
+ # - {Duration}: The minimum interval between executions. The debouncer will not execute
63
+ # the given block more often than this.
64
+ # - {Range}: A range of {Duration}s for the minimum to maximum interval between executions.
65
+ # The range end defines the maximum duration from the initial trigger, at which
66
+ # the debouncer will execute the block, even when an `idle_time` argument was given and
67
+ # calls continue to occur at an interval less than `idle_time`.
68
+ # - `nil`: When `nil`, no debouncing is performed, all the other parameters are ignored,
69
+ # and every call will result in immediate execution of the given block.
70
+ #
71
+ # @param [true,false] leading
72
+ # - `true`: Perform leading edge "debouncing". Execute the first call then ignore
73
+ # subsequent calls that occur within the debounce period.
74
+ # - `false`: Perform trailing edge debouncing. Execute the last call at the end of
75
+ # the debounce period and ignore all the calls leading up to it.
76
+ #
77
+ # @param [Duration,nil] idle_time The minimum idle time between calls to stop debouncing.
78
+ # The debouncer will continue to hold until the interval between two calls is longer
79
+ # than the idle time or until the maximum interval between executions, when
80
+ # specified, is reached.
81
+ #
82
+ # @return [void]
83
+ #
84
+ def initialize(for:, leading: false, idle_time: nil)
85
+ @interval = binding.local_variable_get(:for)
86
+ return unless @interval
87
+
88
+ @interval = (@interval..) unless @interval.is_a?(Range)
89
+
90
+ @leading = leading
91
+ @idle_time = idle_time
92
+ @mutex = Mutex.new
93
+ @block = nil
94
+ @timer = nil
95
+ reset
96
+ end
97
+
98
+ #
99
+ # Debounces calls to the given block.
100
+ #
101
+ # This method is meant to be called repeatedly with the same given block.
102
+ # However, if no block is given, it will call and debounce the previously given block
103
+ #
104
+ # @yield Block to be debounced
105
+ #
106
+ # @return [void]
107
+ #
108
+ # @example Basic trailing edge debouncing
109
+ # debouncer = Debouncer.new(for: 1.minute)
110
+ # (1..100).each do
111
+ # debouncer.call { logger.info "I won't log more often than once a minute" }
112
+ # sleep 20 # call the debouncer every 20 seconds
113
+ # end
114
+ #
115
+ # @example Call the previous debounced block
116
+ # debouncer = Debouncer.new(for: 1.minute)
117
+ # debouncer.call { logger.info "Hello. It is #{Time.now}" } # First call to debounce
118
+ #
119
+ # after(20.seconds) do |timer|
120
+ # debouncer.call # Call the original block above
121
+ # timer.reschedule unless timer.cancelled?
122
+ # end
123
+ #
124
+ def call(&block)
125
+ @block = block if block
126
+ raise ArgumentError, "No block has been provided" unless @block
127
+
128
+ return call! unless @interval # passthrough mode, no debouncing when @interval is nil
129
+
130
+ now = ZonedDateTime.now
131
+ if leading?
132
+ leading_edge_debounce(now)
133
+ else
134
+ trailing_edge_debounce(now)
135
+ end
136
+ @mutex.synchronize { @last_timestamp = now }
137
+ end
138
+
139
+ #
140
+ # Executes the latest block passed to the {#debounce} call regardless of any debounce settings.
141
+ #
142
+ # @return [Object] The return value of the block
143
+ #
144
+ def call!
145
+ @block.call
146
+ end
147
+
148
+ #
149
+ # Resets the debounce period and cancels any outstanding block executions of a trailing edge debouncer.
150
+ #
151
+ # - A leading edge debouncer will execute its block on the next call and start a new debounce period.
152
+ # - A trailing edge debouncer will reset its debounce timer and the next call will become the start
153
+ # of a new debounce period.
154
+ #
155
+ # @return [Boolean] True if a pending execution was cancelled.
156
+ #
157
+ def reset
158
+ @mutex.synchronize do
159
+ @last_timestamp = @leading_timestamp = @interval.begin.ago - 1.second if leading?
160
+ @timer&.cancel
161
+ end
162
+ end
163
+
164
+ #
165
+ # Immediately executes any outstanding event of a trailing edge debounce.
166
+ # The next call will start a new period.
167
+ #
168
+ # It has no effect on a leading edge debouncer - use {#reset} instead.
169
+ #
170
+ # @return [Boolean] True if an existing debounce timer was rescheduled to run immediately.
171
+ # False if there were no outstanding executions.
172
+ #
173
+ def flush
174
+ @mutex.synchronize do
175
+ if @timer&.cancel
176
+ call!
177
+ true
178
+ end
179
+ end
180
+ end
181
+
182
+ #
183
+ # Returns true to indicate that this is a leading edge debouncer.
184
+ #
185
+ # @return [true,false] True if this object was created to be a leading edge debouncer. False otherwise.
186
+ #
187
+ def leading?
188
+ @leading
189
+ end
190
+
191
+ private
192
+
193
+ def too_soon?(now)
194
+ now < @leading_timestamp + @interval.begin
195
+ end
196
+
197
+ # @return [true,false] When max interval is not set/required, always returns false,
198
+ # because there is no maximum interval requirement.
199
+ # When it is set, return true if the max interval condition is met, or false otherwise
200
+ def max_interval?(now)
201
+ @interval.end && now >= @leading_timestamp + @interval.end
202
+ end
203
+
204
+ # @return [true,false] When idle_time is not set/required, always returns true,
205
+ # as if the idle time condition is met.
206
+ # When it is set, return true if the idle time condition is met, or false otherwise
207
+ def idle?(now)
208
+ @idle_time.nil? || now >= @last_timestamp + @idle_time
209
+ end
210
+
211
+ def leading_edge_debounce(now)
212
+ @mutex.synchronize do
213
+ next if too_soon?(now)
214
+ next unless idle?(now) || max_interval?(now)
215
+
216
+ @leading_timestamp = now
217
+ call!
218
+ end
219
+ end
220
+
221
+ def start_timer(now)
222
+ @leading_timestamp = now
223
+ @timer = DSL.after(@interval.begin) { @mutex.synchronize { call! } }
224
+ end
225
+
226
+ def handle_leading_event(now)
227
+ @leading_timestamp = now
228
+ @initial_wait ||= [@interval.begin, @idle_time].compact.max
229
+ @timer.reschedule(@initial_wait)
230
+ end
231
+
232
+ def handle_intermediate_event(now)
233
+ execution_time = @leading_timestamp + @interval.begin
234
+
235
+ execution_time = [execution_time, now + @idle_time].max if @idle_time && (@last_timestamp + @idle_time != now)
236
+ if @interval.end
237
+ max_execution_time = @leading_timestamp + @interval.end
238
+ execution_time = max_execution_time if max_execution_time < execution_time
239
+ end
240
+
241
+ if execution_time <= now
242
+ @timer.cancel
243
+ call!
244
+ elsif execution_time > @timer.execution_time
245
+ @timer.reschedule(execution_time)
246
+ end
247
+ end
248
+
249
+ def trailing_edge_debounce(now)
250
+ @mutex.synchronize do
251
+ next start_timer(now) unless @timer
252
+ next handle_intermediate_event(now) if @timer.active?
253
+
254
+ handle_leading_event(now)
255
+ end
256
+ end
257
+ end
258
+ end
259
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module DSL
5
+ module Events
6
+ #
7
+ # Event object passed by a {Rules::BuilderDSL#watch} trigger.
8
+ #
9
+ # @!attribute [r] path
10
+ # @return [Pathname] The path that had an event
11
+ # @!attribute [r] type
12
+ # @return [:created, :modified, :deleted] Type of change
13
+ # @!attribute [r] attachment
14
+ # @return [Object] The trigger's attachment
15
+ WatchEvent = Struct.new(:type, :path, :attachment)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module DSL
5
+ # Contains event classes for events defined by the DSL.
6
+ module Events
7
+ end
8
+ end
9
+ end
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'bundler/inline'
3
+ require "bundler/inline"